diff --git a/backend/internal/service/cn_provider_quota_service.go b/backend/internal/service/cn_provider_quota_service.go
index 271b18afe1..74c1f91fd6 100644
--- a/backend/internal/service/cn_provider_quota_service.go
+++ b/backend/internal/service/cn_provider_quota_service.go
@@ -142,6 +142,7 @@ func (s *CNProviderQuotaService) queryUsageForAccount(ctx context.Context, accou
var (
targetURL string
authHeader string
+ zhipuOrg string
)
switch provider {
case PlatformKimi:
@@ -150,6 +151,13 @@ func (s *CNProviderQuotaService) queryUsageForAccount(ctx context.Context, accou
case PlatformZhipu:
targetURL = zhipuQuotaURL(baseURL)
authHeader = apiKey // 智谱额度端点鉴权不加 Bearer 前缀
+ // 团队版 GLM Coding Plan:额度端点需 ?type=2 + 组织/项目请求头,
+ // 否则官方 API 回「当前用户不存在coding plan」。组织 ID 存在即视为
+ // 团队版(个人版凭据不含该字段,走原个人版查询路径)。
+ zhipuOrg = strings.TrimSpace(account.GetCredential("zhipu_organization"))
+ if zhipuOrg != "" {
+ targetURL += "?type=2"
+ }
}
// 探测发起前过出站 URL 安全策略(与网关转发/Grok 探测同一套校验):
@@ -172,6 +180,12 @@ func (s *CNProviderQuotaService) queryUsageForAccount(ctx context.Context, accou
if provider == PlatformZhipu {
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Accept-Language", "en-US,en")
+ if zhipuOrg != "" {
+ req.Header.Set("bigmodel-organization", zhipuOrg)
+ if project := strings.TrimSpace(account.GetCredential("zhipu_project")); project != "" {
+ req.Header.Set("bigmodel-project", project)
+ }
+ }
}
// 探测与真实转发保持同一套账号级请求头覆写,避免探测通过但转发失败。
account.ApplyHeaderOverrides(req.Header)
diff --git a/frontend/src/components/account/CreateAccountModal.vue b/frontend/src/components/account/CreateAccountModal.vue
index ba30abfdac..ae2efff8de 100644
--- a/frontend/src/components/account/CreateAccountModal.vue
+++ b/frontend/src/components/account/CreateAccountModal.vue
@@ -547,6 +547,36 @@
+
+
+
+
+
+ {{ t('admin.accounts.cnProviders.zhipuTeam.help.title') }}
+
+ - {{ t('admin.accounts.cnProviders.zhipuTeam.help.step1') }}
+ - {{ t('admin.accounts.cnProviders.zhipuTeam.help.step2') }}
+ - {{ t('admin.accounts.cnProviders.zhipuTeam.help.step3') }}
+ - {{ t('admin.accounts.cnProviders.zhipuTeam.help.step4') }}
+
+
+ {{ t('admin.accounts.cnProviders.zhipuTeam.help.example') }}
+
+
+
+
+
{{ t('admin.accounts.cnProviders.zhipuTeam.hint') }}
+
+
@@ -3764,6 +3794,7 @@ import type {
import BaseDialog from '@/components/common/BaseDialog.vue'
import ConfirmDialog from '@/components/common/ConfirmDialog.vue'
import Select from '@/components/common/Select.vue'
+import HelpTooltip from '@/components/common/HelpTooltip.vue'
import PlatformIcon from '@/components/common/PlatformIcon.vue'
import Icon from '@/components/icons/Icon.vue'
import ProxySelector from '@/components/common/ProxySelector.vue'
@@ -3969,6 +4000,9 @@ const accountMode = ref('payg')
// API 协议决定转发端点与格式:cc=现有转换链,anthropic=原生直通(Claude Code),
// responses=deepseek 原生 Responses 端点(Codex)。与账号类型正交。
const apiProtocol = ref('adaptive')
+// 智谱团队版 Coding Plan:组织/项目 ID,写入 credentials 供额度探测切换团队端点
+const zhipuOrganization = ref('')
+const zhipuProject = ref('')
const adaptiveBaseUrls = ref>({
chat_completions: '',
anthropic: '',
@@ -5544,6 +5578,11 @@ const handleSubmit = async () => {
if (apiProtocol.value !== 'adaptive' && resolvedCNBase) {
credentials.base_url = resolvedCNBase
}
+ // 智谱团队版 Coding Plan:组织/项目 ID 写入凭据(非空才写)
+ if (form.platform === 'zhipu' && accountMode.value === 'coding') {
+ if (zhipuOrganization.value.trim()) credentials.zhipu_organization = zhipuOrganization.value.trim()
+ if (zhipuProject.value.trim()) credentials.zhipu_project = zhipuProject.value.trim()
+ }
}
// Add model mapping if configured(OpenAI 开启自动透传时不应用)
diff --git a/frontend/src/components/account/EditAccountModal.vue b/frontend/src/components/account/EditAccountModal.vue
index b1a6d10e97..8676fc907b 100644
--- a/frontend/src/components/account/EditAccountModal.vue
+++ b/frontend/src/components/account/EditAccountModal.vue
@@ -118,6 +118,35 @@
{{ t(`admin.accounts.cnProviders.apiProtocol.${cnProtocolDescKey}Desc`) }}
+
+
+
+
+
+ {{ t('admin.accounts.cnProviders.zhipuTeam.help.title') }}
+
+ - {{ t('admin.accounts.cnProviders.zhipuTeam.help.step1') }}
+ - {{ t('admin.accounts.cnProviders.zhipuTeam.help.step2') }}
+ - {{ t('admin.accounts.cnProviders.zhipuTeam.help.step3') }}
+ - {{ t('admin.accounts.cnProviders.zhipuTeam.help.step4') }}
+
+
+ {{ t('admin.accounts.cnProviders.zhipuTeam.help.example') }}
+
+
+
+
+
{{ t('admin.accounts.cnProviders.zhipuTeam.hint') }}
+
(() => {
})
const editApiProtocol = ref('adaptive')
const editAccountMode = ref('payg')
+// 智谱团队版 Coding Plan:组织/项目 ID,写入 credentials 供额度探测切换团队端点
+const editZhipuOrganization = ref('')
+const editZhipuProject = ref('')
const editAdaptiveBaseUrls = ref>({
chat_completions: '',
anthropic: '',
@@ -3939,6 +3972,11 @@ const syncFormFromAccount = (newAccount: Account | null) => {
nextAdaptiveBaseUrls[legacyProtocol] = legacyBaseUrl
}
editAdaptiveBaseUrls.value = nextAdaptiveBaseUrls
+ // 智谱团队版 Coding Plan:回填组织/项目 ID
+ if (newAccount.platform === 'zhipu') {
+ editZhipuOrganization.value = typeof credentials.zhipu_organization === 'string' ? credentials.zhipu_organization : ''
+ editZhipuProject.value = typeof credentials.zhipu_project === 'string' ? credentials.zhipu_project : ''
+ }
}
const platformDefaultUrl =
newAccount.platform === 'openai'
@@ -4648,6 +4686,19 @@ const handleSubmit = async () => {
} else {
delete newCredentials.api_base_urls
}
+ // 智谱团队版 Coding Plan:组织/项目 ID 写入凭据(非空才写,清空即移除回落个人版路径)
+ if (props.account.platform === 'zhipu') {
+ const org = editZhipuOrganization.value.trim()
+ const project = editZhipuProject.value.trim()
+ if (org) {
+ newCredentials.zhipu_organization = org
+ if (project) newCredentials.zhipu_project = project
+ else delete newCredentials.zhipu_project
+ } else {
+ delete newCredentials.zhipu_organization
+ delete newCredentials.zhipu_project
+ }
+ }
}
// Handle API key
diff --git a/frontend/src/i18n/locales/en/admin/accounts.ts b/frontend/src/i18n/locales/en/admin/accounts.ts
index ae0867b9f1..5317941e2b 100644
--- a/frontend/src/i18n/locales/en/admin/accounts.ts
+++ b/frontend/src/i18n/locales/en/admin/accounts.ts
@@ -129,6 +129,22 @@ export default {
responses: 'Responses',
responsesDesc: 'Provider’s native Responses endpoint — ideal for Codex.',
},
+ zhipuTeam: {
+ title: 'Team Plan Organization / Project ID',
+ organization: 'Organization ID (team plan, optional)',
+ organizationPlaceholder: 'Organization ID of the team Coding Plan',
+ project: 'Project ID (team plan, optional)',
+ projectPlaceholder: 'Project ID of the team Coding Plan',
+ hint: 'Only required for the team GLM Coding Plan; when set, usage queries go through the team endpoint. Leave empty for personal plans. Click the question mark for how to obtain the IDs.',
+ help: {
+ title: 'How to get the Organization / Project ID',
+ step1: 'Sign in to the Zhipu open platform (bigmodel.cn) with your team account and open "Coding Plan → Team → My Plan".',
+ step2: 'Press F12 to open browser DevTools, switch to the Network tab, then reload the page.',
+ step3: 'Type /api/biz/v1/organization into the Network filter box and click the matched request (e.g. api_keys).',
+ step4: 'In the request URL, the org-… segment is the Organization ID and the proj_… segment is the Project ID (also visible as the bigmodel-organization / bigmodel-project request headers). Fill them into the fields above.',
+ example: 'Example: …/organization/org-0610bE2D…/projects/proj_0798F20…/api_keys → org-0610bE2D… goes into "Organization ID", proj_0798F20… into "Project ID"',
+ },
+ },
balance: 'Balance --',
window5h: '5-hour window',
windowWeekly: 'Weekly window',
diff --git a/frontend/src/i18n/locales/zh/admin/accounts.ts b/frontend/src/i18n/locales/zh/admin/accounts.ts
index c277eb7c2f..48ba2c5546 100644
--- a/frontend/src/i18n/locales/zh/admin/accounts.ts
+++ b/frontend/src/i18n/locales/zh/admin/accounts.ts
@@ -332,6 +332,22 @@ export default {
responses: 'Responses',
responsesDesc: '供应商原生 Responses 端点,适配 Codex。',
},
+ zhipuTeam: {
+ title: '团队版组织 / 项目 ID',
+ organization: '组织 ID(团队版可选)',
+ organizationPlaceholder: '团队版 Coding Plan 的组织 ID',
+ project: '项目 ID(团队版可选)',
+ projectPlaceholder: '团队版 Coding Plan 的项目 ID',
+ hint: '仅团队版 GLM Coding Plan 需要填写,填写后用量查询走团队版端点;个人版留空即可。获取方式点击左侧问号查看教程。',
+ help: {
+ title: '如何获取组织 / 项目 ID',
+ step1: '用团队版账号登录智谱开放平台(bigmodel.cn),进入「Coding Plan → 团队版 → 我的套餐」页面。',
+ step2: '按 F12 打开浏览器开发者工具,切换到「Network / 网络」标签,然后刷新页面。',
+ step3: '在 Network 的筛选框中输入 /api/biz/v1/organization,点击命中的请求(如 api_keys)。',
+ step4: '请求 URL 中 org- 开头的一段即组织 ID、proj_ 开头的一段即项目 ID(也可在 Request Headers 中查看 bigmodel-organization / bigmodel-project 的值),分别填入上方输入框。',
+ example: '示例:…/organization/org-0610bE2D…/projects/proj_0798F20…/api_keys → org-0610bE2D… 填「组织 ID」,proj_0798F20… 填「项目 ID」',
+ },
+ },
balance: '余额 --',
window5h: '5 小时窗口',
windowWeekly: '每周窗口',