feat(frontend): refresh account setup defaults and copy

Co-authored-by: Codex <noreply@openai.com>
This commit is contained in:
Zyy
2026-08-15 01:09:31 +08:00
co-authored by Codex
parent 2dd60c08b6
commit 0b8a1add18
6 changed files with 26 additions and 34 deletions
@@ -116,18 +116,13 @@ const modalTitle = computed(() => {
const oauthPanelTitle = computed(() => {
if (props.reauthorizing)
return accountName.value
return isXai.value ? '使用 xAI OAuth 完成账号接入' : '使用 OpenAI OAuth 完成账号接入'
return isXai.value ? 'xAI OAuth 授权' : 'OpenAI OAuth 授权'
})
const oauthPanelDescription = computed(() => {
if (props.reauthorizing) {
return isXai.value
? '生成新的授权链接,完成后粘贴回调地址、含 code 和 state 的查询字符串或授权码更新账号凭据'
: '生成新的授权链接,完成后粘贴回调地址更新账号凭据'
}
return isXai.value
? '复制授权链接到浏览器打开,完成后粘贴回调地址、含 code 和 state 的查询字符串或授权码即可导入'
: '复制授权链接到浏览器打开,完成后把回调地址粘贴到下方即可导入'
? '生成并打开授权链接 → 完成浏览器授权 → 粘贴回调地址、查询字符串或授权码'
: '生成并打开授权链接 → 完成浏览器授权 → 粘贴回调地址'
})
const canGenerateOauth = computed(() =>
@@ -152,21 +147,21 @@ const description = computed<string | undefined>(() => {
return undefined
if (props.reauthorizing) {
return isXai.value
? '完成授权后粘贴回调地址、含 code 和 state 的查询字符串或授权码,系统会更新账号凭据'
: '完成授权后粘贴回调地址,系统会更新账号凭据'
? '完成新的 xAI 授权并替换此账号凭据'
: '完成新的 OpenAI 授权并替换此账号凭据'
}
if (isBatch.value)
return '导入 CPR 多平台账号包,系统会按文档中的平台自动分流'
return '粘贴或上传 CPR 账号包,一次导入多个平台账号'
if (isXai.value) {
return mode.value === 'oauth'
? '复制 xAI 授权链接,完成后粘贴回调地址、含 code 和 state 的查询字符串或授权码,不使用 xAI API Key'
: '导入 xAI 账号文件,已存在账号会更新'
? '通过浏览器授权导入 xAI 账号'
: '粘贴或上传 xAI 账号文件,匹配已有账号时更新凭据'
}
if (mode.value === 'oauth')
return '复制 OpenAI 授权链接,完成后粘贴回调地址,系统会自动写入或更新账号'
return '通过浏览器授权导入 OpenAI 账号'
if (mode.value === 'agent_identity')
return '导入 Agent 身份文件,系统会按身份信息写入或更新账号'
return '导入 CPR、Sub2API 或 CPA 账号文件,已存在账号会更新'
return '粘贴或上传 Agent 身份文件,匹配已有账号时更新凭据'
return '粘贴或上传 CPR、Sub2API 或 CPA 账号文件,匹配已有账号时更新凭据'
})
function selectProvider(value: 'openai' | 'xai' | 'batch') {
@@ -288,7 +283,7 @@ async function copyText(value: string, successText: string) {
v-model="oauthCallback"
:aria-label="isXai ? '回调地址或授权码' : '回调地址'"
size="sm"
:placeholder="isXai ? '粘贴完整回调地址、?code=...&state=... 或裸授权码' : 'http://localhost:1455/auth/callback?code=...&state=...'"
:placeholder="isXai ? '回调地址、?code=...&state=... 或授权码' : 'http://localhost:1455/auth/callback?code=...&state=...'"
:disabled="saving"
/>
</BaseFormItem>
@@ -103,7 +103,7 @@ export function useAccountConnectionTest(options: { reload: () => Promise<unknow
if (connectionTestStatus.value === 'running') {
return {
label: '正在测试',
description: '正在发送一条真实 Responses 流式请求',
description: '正在向所选模型发送请求并接收流式响应',
icon: Clock3,
badge: 'bg-(--cp-info-bg) text-(--cp-info-text)',
iconClass: 'text-(--cp-info)',
@@ -112,7 +112,7 @@ export function useAccountConnectionTest(options: { reload: () => Promise<unknow
if (connectionTestStatus.value === 'success') {
return {
label: '连接正常',
description: '账号凭据可用,已完成 Responses 流式验证',
description: '请求已完成,可在下方查看模型、耗时和事件轨迹',
icon: CheckCircle2,
badge: 'bg-(--cp-success-bg) text-(--cp-success-text)',
iconClass: 'text-(--cp-success)',
@@ -121,7 +121,7 @@ export function useAccountConnectionTest(options: { reload: () => Promise<unknow
if (connectionTestStatus.value === 'error') {
return {
label: '测试失败',
description: '真实请求未完成,优先检查令牌状态、账号权限或上游网络',
description: '请求未完成,请在下方查看上游错误与事件轨迹',
icon: XCircle,
badge: 'bg-(--cp-danger-bg) text-(--cp-danger-text)',
iconClass: 'text-(--cp-danger)',
@@ -129,7 +129,7 @@ export function useAccountConnectionTest(options: { reload: () => Promise<unknow
}
return {
label: '准备测试',
description: '点击开始后发送一条轻量 Responses 流式请求',
description: '选择模型后,点击“开始测试”发送真实请求',
icon: Wifi,
badge: 'bg-(--cp-bg-subtle) text-(--cp-text-secondary)',
iconClass: 'text-(--cp-text-muted)',
@@ -189,11 +189,11 @@ export function useAccountOnboarding(options: {
}
if (importedCount === 0) {
throw new Error(failures.length > 0 ? `批量导入失败:${failures.join(';')}` : '批量文件没有可导入的账号')
throw new Error(failures.length > 0 ? `批量导入失败:${failures.join('、')}` : '批量文件没有可导入的账号')
}
if (failures.length > 0) {
return `已导入 ${importedCount} 个账号,${failures.length} 个文档失败:${failures.join(';')}`
return `已导入 ${importedCount} 个账号,${failures.length} 个文档失败:${failures.join('、')}`
}
return `已导入 ${importedCount} 个账号`
}
@@ -21,7 +21,7 @@ export function parseAccountSchedulingForm(
|| parsedLimit < 1
|| parsedLimit > MAX_ACCOUNT_CONCURRENCY)
) {
return { valid: false, message: `并发限制必须留空或填写 1 到 ${MAX_ACCOUNT_CONCURRENCY} 的整数` }
return { valid: false, message: `并发限制必须留空,或为 1 到 ${MAX_ACCOUNT_CONCURRENCY} 的整数` }
}
const parsedWeight = Number(weight.trim())
@@ -27,16 +27,13 @@ const open = defineModel<boolean>({ default: false })
const createdOpen = defineModel<boolean>('createdOpen', { default: false })
const form = defineModel<ApiKeyFormValue>('form', { required: true })
const title = computed(() => props.editing ? '编辑 API Key' : '创建 API Key')
const description = computed(() => props.editing
? '调整访问范围与调度限制,分组替换原子生效。'
: '为调用方选择一个或多个账号分组。')
</script>
<template>
<BaseModal
v-model="open"
:title="title"
:description="description"
description="设置调用方可用的账号分组、并发和每分钟请求上限"
variant="info"
width="680px"
body-max-height="min(680px, calc(100dvh - 190px))"
@@ -47,7 +44,7 @@ const description = computed(() => props.editing
<BaseInput
v-model="form.name"
aria-label="名称"
placeholder="例如:生产环境、测试调用方..."
placeholder="例如:生产环境"
:disabled="saving"
/>
</BaseFormItem>
@@ -56,7 +53,7 @@ const description = computed(() => props.editing
<BaseInput
v-model="form.label"
aria-label="标签(可选)"
placeholder="备注信息..."
placeholder="例如:后端服务"
:disabled="saving"
/>
</BaseFormItem>
@@ -108,7 +105,7 @@ const description = computed(() => props.editing
<BaseModal
v-model="createdOpen"
title="API Key 已创建"
description="可以立即复制或导入 CCSwitch,之后也可从密钥列表再次操作"
description="复制密钥,或直接导入 CCSwitch"
variant="success"
width="540px"
>
@@ -38,13 +38,13 @@ const authPath = computed(() =>
activePlatform.value === 'windows' ? '%userprofile%\\.codex\\auth.json' : '~/.codex/auth.json',
)
const codexAuthJson = computed(() => JSON.stringify({ OPENAI_API_KEY: keyValue.value }, null, 2))
const defaultModel = 'gpt-5.5'
const defaultModel = 'gpt-5.6-terra'
const codexConfigToml = computed(
() => `model_provider = "OpenAI"
model = "${defaultModel}"
review_model = "${defaultModel}"
model_reasoning_effort = "xhigh"
model_reasoning_effort = "max"
service_tier = "default"
disable_response_storage = true
network_access = "enabled"
@@ -70,7 +70,7 @@ const visibleFiles = computed(() => [
<BaseModal
v-model="open"
title="使用密钥"
description="将以下配置文件添加到 Codex CLI 配置目录中"
description="将下方内容分别保存到显示的 Codex CLI 配置文件"
width="760px"
>
<div class="flex flex-col gap-5">