From 38430c92448c5862927af8b1a25bbda23cec68f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=A0=E6=88=90?= Date: Wed, 1 Apr 2026 14:47:34 +0800 Subject: [PATCH] 1 --- _docs/sql/biz_api_token_key.sql | 3 +++ admin/src/views/subscription/tokens.vue | 5 ++++- api/controller_admin/biz_token.js | 1 + api/controller_custom/proxy_api.js | 5 ++++- api/model/biz_api_token.js | 6 +++++- api/service/biz_auth_verify.js | 1 + api/service/biz_token_logic.js | 3 ++- 7 files changed, 20 insertions(+), 4 deletions(-) create mode 100644 _docs/sql/biz_api_token_key.sql diff --git a/_docs/sql/biz_api_token_key.sql b/_docs/sql/biz_api_token_key.sql new file mode 100644 index 0000000..b8cf6ec --- /dev/null +++ b/_docs/sql/biz_api_token_key.sql @@ -0,0 +1,3 @@ +-- token 绑定账号唯一标识 key(供转发时自动拼到 query.key) +ALTER TABLE biz_api_token + ADD COLUMN `key` VARCHAR(128) NULL COMMENT '账号唯一标识' AFTER token_name; diff --git a/admin/src/views/subscription/tokens.vue b/admin/src/views/subscription/tokens.vue index 4385274..d23daec 100644 --- a/admin/src/views/subscription/tokens.vue +++ b/admin/src/views/subscription/tokens.vue @@ -59,6 +59,7 @@ + @@ -104,6 +105,7 @@ export default { { title: 'ID', key: 'id', width: 70 }, { title: '用户', key: 'user_id', width: 90 }, { title: '套餐', key: 'plan_id', width: 90 }, + { title: 'Key', key: 'key', minWidth: 140 }, { title: '名称', key: 'token_name', width: 120 }, { title: '状态', key: 'status', width: 90 }, { title: '过期', key: 'expire_at', minWidth: 150 }, @@ -176,7 +178,7 @@ export default { 2, '0' )} 23:59:59` - this.createForm = { user_id: undefined, token_name: 'default', expire_at: fmt } + this.createForm = { user_id: undefined, key: '', token_name: 'default', expire_at: fmt } this.createModal = true }, submitCreate() { @@ -194,6 +196,7 @@ export default { try { const res = await tokenServer.create({ user_id: Number(uid), + key: this.createForm.key || null, token_name: this.createForm.token_name || 'default', expire_at: this.createForm.expire_at, }) diff --git a/api/controller_admin/biz_token.js b/api/controller_admin/biz_token.js index dfc4192..b1490b8 100644 --- a/api/controller_admin/biz_token.js +++ b/api/controller_admin/biz_token.js @@ -38,6 +38,7 @@ module.exports = { id: result.row.id, user_id: result.row.user_id, plan_id: result.row.plan_id, + key: result.row.key, token_name: result.row.token_name, expire_at: result.row.expire_at, plain_token: result.plain_token, diff --git a/api/controller_custom/proxy_api.js b/api/controller_custom/proxy_api.js index 7c17c5e..9d3876d 100644 --- a/api/controller_custom/proxy_api.js +++ b/api/controller_custom/proxy_api.js @@ -65,8 +65,11 @@ function buildProxyRoutes() { ctx.fail(authResult.message || "鉴权失败"); return; } - // 3. 组装 query + // 3. 组装 query,并注入 token 对应 key(上游要求参数名为 key) const query = { ...ctx.query }; + if (!query.key && authResult.context && authResult.context.token_key) { + query.key = authResult.context.token_key; + } // 4. 转发到上游 const result = await proxy.forwardRequest({ diff --git a/api/model/biz_api_token.js b/api/model/biz_api_token.js index 20232a4..7e78965 100644 --- a/api/model/biz_api_token.js +++ b/api/model/biz_api_token.js @@ -18,6 +18,10 @@ module.exports = (db) => { allowNull: false, defaultValue: "", }, + key: { + type: Sequelize.STRING(128), + allowNull: true, + }, token_hash: { type: Sequelize.STRING(64), allowNull: false, @@ -42,6 +46,6 @@ module.exports = (db) => { underscored: true, } ); - // biz_api_token.sync({ force: true }); + //biz_api_token.sync({ force: true }); return biz_api_token; }; diff --git a/api/service/biz_auth_verify.js b/api/service/biz_auth_verify.js index 1df1646..c67aff6 100644 --- a/api/service/biz_auth_verify.js +++ b/api/service/biz_auth_verify.js @@ -109,6 +109,7 @@ async function verifyRequest(body) { plan_id: sub.plan_id, subscription_id: sub.id, token_id: row.id, + token_key: row.key || "", stat_month: statMonth, usage_snapshot: { msg_count: usageSvc.num(usageRow.msg_count), diff --git a/api/service/biz_token_logic.js b/api/service/biz_token_logic.js index 553ebf9..5a6d7b1 100644 --- a/api/service/biz_token_logic.js +++ b/api/service/biz_token_logic.js @@ -36,7 +36,7 @@ async function findActiveSubscriptionForUser(userId) { } async function createToken(body) { - const { user_id, token_name, expire_at } = body; + const { user_id, token_name, expire_at, key } = body; if (!user_id || !expire_at) throw new Error("缺少 user_id 或 expire_at"); const u = await baseModel.biz_user.findByPk(user_id); if (!u) throw new Error("用户不存在"); @@ -60,6 +60,7 @@ async function createToken(body) { user_id, plan_id, token_name: token_name || "default", + key: key || null, token_hash, secret_cipher, status: "active",