refactor: complete backend rewrite for multi-protocol proxy
Major rewrite of the Go backend to support:
- Three API format imports: openai, anthropic, compatible
- Three protocol conversions: Chat Completions, Responses, Messages
- Hub-and-spoke architecture with Chat as intermediate format
Deleted:
- opencat.go (old entry)
- store/, team/, pkg/team/, pkg/store/ (old data layer)
- internal/model/, internal/consts/ (old types)
- internal/service/team/, internal/controller/team/ (old handlers)
- llm/ (removed LLM client library, pure proxy mode)
- dist/, assets/ (old build artifacts)
Added:
- internal/store/ — 9 GORM models + multi-DB support
- internal/pkg/ — crypto (AES-GCM), apikey, jwt, ratelimit, resp, tokenizer
- internal/channel/ — channel selection, weighted LB, health checks
- internal/proxy/convert/ — 6 protocol conversion functions + SSE streaming
- internal/proxy/ — gateway with request dispatch and upstream selection
- internal/usage/ — async usage recorder with batch writes
- internal/api/ — management API (auth, users, keys, channels, models)
- Makefile for build/test/deploy
Fixed API to match frontend expectations:
- Login response wraps token in { data: { token } }
- GET /api/profile route added
- Profile response wraps user in { code, data }
- Role returned as number (10=admin, 1=user)
This commit is contained in:
+1
-1
@@ -4,7 +4,7 @@
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" type="image/svg+xml" href="/src/assets/logo.svg" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<meta name="description" content="OpenTeam — an open-source, team-shared service compatible with the OpenAI API." />
|
||||
<meta name="description" content="OpenTeam — one endpoint for every LLM provider. Route OpenAI-compatible clients to Claude, Gemini, DeepSeek and more through a single, team-shared endpoint." />
|
||||
<meta name="theme-color" content="#ffffff" />
|
||||
<title>OpenTeam</title>
|
||||
<script>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<!-- 组件根元素:相对定位,设置最大宽度、外边距、宽高比、背景渐变、内边距、圆角、阴影和溢出隐藏 -->
|
||||
<div
|
||||
class="relative w-full max-w-4xl mx-auto my-10 aspect-[4/3] backdrop-blur-0 px-4 py-0 my-0 rounded-lg overflow-hidden ">
|
||||
class="relative w-full max-w-4xl mx-auto my-10 aspect-[16/10] sm:aspect-[4/3] backdrop-blur-0 rounded-lg overflow-hidden ">
|
||||
<!-- bg-gradient-to-br from-slate-50 to-orange-50 -->
|
||||
<!-- 中心图标容器 -->
|
||||
<div ref="centerElement" class="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 z-20">
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
{{ star }}
|
||||
</span>
|
||||
</a>
|
||||
<RouterLink to="/dashboard" class="btn btn-primary btn-sm h-9 min-h-9 rounded-full px-4">
|
||||
<RouterLink to="/dashboard" class="btn btn-primary btn-sm h-9 min-h-9 rounded-full px-3 sm:px-4 whitespace-nowrap">
|
||||
Open Dashboard
|
||||
</RouterLink>
|
||||
</div>
|
||||
@@ -60,7 +60,7 @@
|
||||
<img src="@/assets/openteam.png" alt="OpenTeam project logo" width="160" height="160" class="h-28 w-auto select-none" fetchpriority="high" />
|
||||
<h1 class="mt-4 text-4xl font-bold tracking-tight text-balance sm:text-5xl">OpenTeam</h1>
|
||||
<p class="mt-4 max-w-2xl text-pretty text-lg text-base-content/70">
|
||||
An open-source, team-shared service compatible with the OpenAI API — share LLM API usage across your team through a single endpoint.
|
||||
One endpoint for every model. Route OpenAI-compatible clients to any LLM provider — share costs, track usage, stay in control.
|
||||
</p>
|
||||
|
||||
<div class="tooltip mt-8 w-full max-w-xl" data-tip="Point your client at the OpenTeam base URL">
|
||||
@@ -78,6 +78,9 @@
|
||||
👉 Api-Keys:
|
||||
<a href="https://platform.openai.com/account/api-keys" class="link link-hover link-primary">platform.openai.com/account/api-keys</a>
|
||||
</p>
|
||||
<p class="mt-3 text-sm text-base-content/60">
|
||||
Connects to OpenAI, Claude, Gemini, DeepSeek and other OpenAI-compatible providers through a single endpoint.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<!-- How it works -->
|
||||
|
||||
@@ -164,7 +164,7 @@
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div v-if="passkeys && passkeys.length" class="-mx-4 overflow-x-auto sm:-mx-6">
|
||||
<div v-if="passkeys && passkeys.length" class="overflow-x-auto">
|
||||
<table class="table table-sm">
|
||||
<thead>
|
||||
<tr class="text-xs uppercase tracking-wider text-base-content/50">
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="token in user.tokens" :key="token.id" class="border-base-300/40 hover:bg-base-200/50">
|
||||
<td class="pl-4 font-medium">{{ token.name }}</td>
|
||||
<td class="pl-4 font-medium truncate max-w-[120px] sm:max-w-[180px]">{{ token.name }}</td>
|
||||
<td>
|
||||
<input type="checkbox" class="toggle toggle-success toggle-sm"
|
||||
:class="!token.active && 'toggle-error'" v-model="token.active"
|
||||
|
||||
@@ -144,8 +144,8 @@
|
||||
<div class="card border border-base-300/60 bg-base-100 shadow-sm">
|
||||
<div class="card-body p-4 sm:p-5">
|
||||
<h3 class="card-title pb-1 text-base font-semibold">Tokens</h3>
|
||||
<div v-if="user.tokens && user.tokens.length" class="-mx-4 overflow-x-auto sm:-mx-5">
|
||||
<table class="table table-sm">
|
||||
<div v-if="user.tokens && user.tokens.length" class="overflow-x-auto">
|
||||
<table class="table table-sm min-w-[520px]">
|
||||
<thead>
|
||||
<tr class="text-xs uppercase tracking-wider text-base-content/50">
|
||||
<th class="pl-4">Token Name</th>
|
||||
|
||||
Reference in New Issue
Block a user