Compare commits

...

4 Commits

Author SHA1 Message Date
Sisyphus
fa1f075c0a fix(merge): 闪退修复 - 业务级 code:401 不再清 token 跳登录 (仅 HTTP 401 才跳) 2026-07-11 09:27:50 +08:00
Sisyphus
cf00136340 feat(F006): APIKey申请结果+详情弹窗显示MCP地址
后端 apply/detail 返回 mcpEndpoint (从 -Dmcp.endpoint 注入),
前端申请弹窗加 MCP地址列, 详情弹窗加 MCP地址行,
用户复制 appId/appSecret/MCP地址 三值到平台助手配置
2026-07-10 11:54:04 +08:00
Sisyphus
44fd765aa7 fix(F006): 重置密钥弹窗复制按钮显示不全
el-input append插槽被长密钥挤压, 改flex布局按钮独立放置 flex-shrink:0
2026-07-10 11:41:08 +08:00
Sisyphus
34e3c7cd71 fix(F006): 申请APIKey弹窗删除ConnectCode/过期时间列
无用字段清理, 弹窗结果表只保留公司名/AppID/AppSecret
2026-07-10 11:22:04 +08:00
3 changed files with 22 additions and 25 deletions

View File

@ -32,9 +32,8 @@ interface ApplyResult {
customerName: string customerName: string
customerCode: string customerCode: string
appId: string appId: string
connectCode: string
appSecret: string appSecret: string
expireAt: string mcpEndpoint: string
} }
const props = defineProps<{ modelValue: boolean }>() const props = defineProps<{ modelValue: boolean }>()
@ -344,14 +343,14 @@ function notifyContact() {
<el-descriptions-item label="备注">{{ form.remark || '—' }}</el-descriptions-item> <el-descriptions-item label="备注">{{ form.remark || '—' }}</el-descriptions-item>
</el-descriptions> </el-descriptions>
<el-alert type="info" :closable="false" style="margin-top: 16px;"> <el-alert type="info" :closable="false" style="margin-top: 16px;">
后端将自动创建公司账号 + 生成 connect_code(2h 有效) 后端将自动创建公司账号 + 生成 APIKey
</el-alert> </el-alert>
</div> </div>
<!-- Step 3: 生成结果 --> <!-- Step 3: 生成结果 -->
<div v-if="step === 3 && result"> <div v-if="step === 3 && result">
<el-alert type="warning" :closable="false" style="margin-bottom: 16px;"> <el-alert type="warning" :closable="false" style="margin-bottom: 16px;">
请立即复制 connectCode 和 appSecret!关弹窗后无法再次查看 请立即复制 MCP地址、appId 和 appSecret!关弹窗后 appSecret 无法再次查看
</el-alert> </el-alert>
<p>已为 {{ result.length }} 个客户生成 APIKey:</p> <p>已为 {{ result.length }} 个客户生成 APIKey:</p>
<el-table :data="result" border class="rr-apply-table rr-result-table" size="small"> <el-table :data="result" border class="rr-apply-table rr-result-table" size="small">
@ -361,12 +360,11 @@ function notifyContact() {
<code class="rr-cell-code">{{ row.appId }}</code> <code class="rr-cell-code">{{ row.appId }}</code>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="connectCode" label="ConnectCode" min-width="160" show-overflow-tooltip> <el-table-column prop="mcpEndpoint" label="MCP地址" min-width="220" show-overflow-tooltip>
<template #default="{ row }"> <template #default="{ row }">
<code class="rr-cell-code rr-code-accent">{{ row.connectCode }}</code> <code class="rr-cell-code">{{ row.mcpEndpoint || '—' }}</code>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="expireAt" label="过期时间" width="100" show-overflow-tooltip />
<el-table-column label="AppSecret" min-width="200"> <el-table-column label="AppSecret" min-width="200">
<template #default="{ row }"> <template #default="{ row }">
<div class="rr-secret-cell"> <div class="rr-secret-cell">

View File

@ -362,6 +362,9 @@ onMounted(() => { load(); loadCustomers() })
> >
<el-descriptions v-if="currentRow" :column="1" border> <el-descriptions v-if="currentRow" :column="1" border>
<el-descriptions-item label="AppID">{{ currentRow.appId }}</el-descriptions-item> <el-descriptions-item label="AppID">{{ currentRow.appId }}</el-descriptions-item>
<el-descriptions-item label="MCP地址">
<code>{{ (currentRow as any).mcpEndpoint || '—' }}</code>
</el-descriptions-item>
<el-descriptions-item label="应用名称">{{ currentRow.appName }}</el-descriptions-item> <el-descriptions-item label="应用名称">{{ currentRow.appName }}</el-descriptions-item>
<el-descriptions-item label="客户名称">{{ currentRow.customerName || currentRow.customerCode || '—' }}</el-descriptions-item> <el-descriptions-item label="客户名称">{{ currentRow.customerName || currentRow.customerCode || '—' }}</el-descriptions-item>
<el-descriptions-item label="客户标识">{{ currentRow.customerCode }}</el-descriptions-item> <el-descriptions-item label="客户标识">{{ currentRow.customerCode }}</el-descriptions-item>
@ -425,18 +428,17 @@ onMounted(() => { load(); loadCustomers() })
<p style="margin-bottom: 6px; font-size: 13px; color: var(--ink-2);"> <p style="margin-bottom: 6px; font-size: 13px; color: var(--ink-2);">
新的 AppSecret: <span style="color: var(--ink-3); font-size: 12px;">(明文, 可直接选中复制)</span> 新的 AppSecret: <span style="color: var(--ink-3); font-size: 12px;">(明文, 可直接选中复制)</span>
</p> </p>
<el-input <div style="display: flex; gap: 8px; align-items: center;">
v-model="newSecret" <el-input
readonly v-model="newSecret"
type="text" readonly
size="default" type="text"
style="font-family: ui-monospace, monospace;" size="default"
@focus="onSecretInputFocus" style="flex: 1; font-family: ui-monospace, monospace;"
> @focus="onSecretInputFocus"
<template #append> />
<el-button type="primary" @click="copyText(newSecret, 'AppSecret 已复制')">复制</el-button> <el-button type="primary" style="flex-shrink: 0;" @click="copyText(newSecret, 'AppSecret 已复制')">复制</el-button>
</template> </div>
</el-input>
</div> </div>
<template #footer> <template #footer>
<el-button v-if="!newSecret" @click="resetSecretVisible = false">取消</el-button> <el-button v-if="!newSecret" @click="resetSecretVisible = false">取消</el-button>

View File

@ -39,12 +39,9 @@ http.interceptors.response.use(
const body = response.data as ApiEnvelope | undefined const body = response.data as ApiEnvelope | undefined
if (body && typeof body === 'object' && 'code' in body) { if (body && typeof body === 'object' && 'code' in body) {
if (body.code === 0) return response if (body.code === 0) return response
// 业务错:401 token 过期 / 其它业务错 // 业务级 code:401 (如 /openapi/** 带 token 时 Spring Security 返未授权)
if (body.code === 401 || body.code === 401000) { // 不清 token 不跳登录,只 reject 给调用方处理
handleAuthExpired() // 真正的 token 过期走 error 拦截器 (HTTP status 401)
return Promise.reject(body)
}
// 业务错(不弹 toast,留给调用方决定)
return Promise.reject(body) return Promise.reject(body)
} }
return response return response