diff --git a/_docs/merge_biz_into_swagger.js b/_docs/merge_biz_into_swagger.js new file mode 100644 index 0000000..b7afd18 --- /dev/null +++ b/_docs/merge_biz_into_swagger.js @@ -0,0 +1,378 @@ +/** + * 将管理端 / 开放鉴权接口合并进 swagger.json(运行: node _docs/merge_biz_into_swagger.js) + */ +const fs = require("fs"); +const path = require("path"); + +const swaggerPath = path.join(__dirname, "swagger.json"); +const doc = JSON.parse(fs.readFileSync(swaggerPath, "utf8")); + +const TAG_ADMIN = ["管理端-业务订阅"]; +const TAG_OPEN_AUTH = ["开放接口-鉴权"]; + +function res200() { + return { 200: { description: "框架统一包装;成功时 code=0,业务数据在 data" } }; +} + +function post(summary, ref, tags = TAG_ADMIN) { + const params = [ + { + in: "body", + name: "body", + schema: ref ? { $ref: `#/definitions/${ref}` } : { type: "object", description: "JSON 请求体" }, + }, + ]; + return { post: { tags, summary, parameters: params, responses: res200() } }; +} + +function postEmpty(summary, tags = TAG_ADMIN) { + return { post: { tags, summary, parameters: [], responses: res200() } }; +} + +function get(summary, queryList, tags = TAG_ADMIN) { + return { + get: { + tags, + summary, + parameters: queryList.map((q) => ({ + in: "query", + name: q.n, + type: q.t || "string", + required: q.req !== false, + description: q.d || "", + })), + responses: res200(), + }, + }; +} + +const definitions = { + BizAdminPageRequest: { + type: "object", + title: "BizAdminPageRequest", + description: + "通用分页/筛选:body 可直接为 param,或形如 { param: { pageOption, seachOption } }", + properties: { + param: { + type: "object", + properties: { + pageOption: { + type: "object", + properties: { + page: { type: "integer", example: 1 }, + pageSize: { type: "integer", example: 20 }, + }, + }, + seachOption: { + type: "object", + properties: { + key: { type: "string", description: "与模型字段名一致,如 user_id、status" }, + value: { type: "string" }, + }, + }, + }, + }, + }, + }, + BizIdRequest: { + type: "object", + title: "BizIdRequest", + properties: { id: { type: "integer", format: "int64" } }, + }, + BizUserRevokeTokensRequest: { + type: "object", + title: "BizUserRevokeTokensRequest", + properties: { + user_id: { type: "integer", format: "int64", description: "与 id 二选一" }, + id: { type: "integer", format: "int64" }, + }, + }, + BizUserAddRequest: { + type: "object", + title: "BizUserAddRequest", + description: "写入字段见 biz_user 模型;可选自动创建 Token", + properties: { + name: { type: "string" }, + mobile: { type: "string" }, + email: { type: "string" }, + company_name: { type: "string" }, + status: { type: "string", enum: ["active", "disabled"] }, + auto_create_token: { type: "boolean", default: true }, + initial_token_name: { type: "string" }, + initial_token_expire_at: { type: "string", description: "如 2026-12-31 23:59:59" }, + }, + }, + BizUserEditRequest: { + type: "object", + title: "BizUserEditRequest", + properties: { + id: { type: "integer", format: "int64" }, + name: { type: "string" }, + mobile: { type: "string" }, + email: { type: "string" }, + company_name: { type: "string" }, + status: { type: "string", enum: ["active", "disabled"] }, + }, + required: ["id"], + }, + BizSubscriptionOpenRequest: { + type: "object", + title: "BizSubscriptionOpenRequest", + required: ["user_id", "plan_id", "start_time", "end_time"], + properties: { + user_id: { type: "integer", format: "int64" }, + plan_id: { type: "integer", format: "int64" }, + start_time: { type: "string" }, + end_time: { type: "string" }, + status: { type: "string", enum: ["pending", "active", "expired", "cancelled"] }, + renew_mode: { type: "string", enum: ["manual", "auto"] }, + payment_channel: { type: "string", enum: ["offline", "pay_link"] }, + payment_ref: { type: "string" }, + }, + }, + BizSubscriptionUpgradeRequest: { + type: "object", + title: "BizSubscriptionUpgradeRequest", + required: ["subscription_id", "new_plan_id"], + properties: { + subscription_id: { type: "integer", format: "int64" }, + new_plan_id: { type: "integer", format: "int64" }, + start_time: { type: "string" }, + end_time: { type: "string" }, + }, + }, + BizSubscriptionRenewRequest: { + type: "object", + title: "BizSubscriptionRenewRequest", + required: ["subscription_id", "end_time"], + properties: { + subscription_id: { type: "integer", format: "int64" }, + end_time: { type: "string" }, + }, + }, + BizSubscriptionCancelRequest: { + type: "object", + title: "BizSubscriptionCancelRequest", + required: ["subscription_id"], + properties: { subscription_id: { type: "integer", format: "int64" } }, + }, + BizPaymentConfirmRequest: { + type: "object", + title: "BizPaymentConfirmRequest", + required: ["subscription_id"], + properties: { + subscription_id: { type: "integer", format: "int64" }, + payment_ref: { type: "string" }, + }, + }, + BizTokenCreateRequest: { + type: "object", + title: "BizTokenCreateRequest", + required: ["user_id", "expire_at"], + properties: { + user_id: { type: "integer", format: "int64" }, + token_name: { type: "string" }, + expire_at: { type: "string" }, + }, + }, + BizTokenIdRequest: { + type: "object", + title: "BizTokenIdRequest", + required: ["id"], + properties: { id: { type: "integer", format: "int64" } }, + }, + BizApiStatsByUserRequest: { + type: "object", + title: "BizApiStatsByUserRequest", + required: ["user_id"], + properties: { + user_id: { type: "integer", format: "int64" }, + start_date: { type: "string", description: "DATEONLY YYYY-MM-DD" }, + end_date: { type: "string" }, + }, + }, + BizApiStatsByApiRequest: { + type: "object", + title: "BizApiStatsByApiRequest", + required: ["api_path"], + properties: { + api_path: { type: "string" }, + start_date: { type: "string" }, + end_date: { type: "string" }, + }, + }, + BizApiStatsSummaryRequest: { + type: "object", + title: "BizApiStatsSummaryRequest", + properties: { + start_date: { type: "string" }, + end_date: { type: "string" }, + top_limit: { type: "integer", example: 10 }, + }, + }, + BizUsageWriteRequest: { + type: "object", + title: "BizUsageWriteRequest", + description: "月度用量 biz_usage_monthly 字段", + properties: { + id: { type: "integer", format: "int64", description: "edit 必填" }, + user_id: { type: "integer", format: "int64" }, + plan_id: { type: "integer", format: "int64" }, + stat_month: { type: "string", example: "2026-04" }, + msg_count: { type: "integer" }, + mass_count: { type: "integer" }, + friend_count: { type: "integer" }, + sns_count: { type: "integer" }, + active_user_count: { type: "integer" }, + api_call_count: { type: "integer" }, + }, + }, + BizAuthVerifyRequest: { + type: "object", + title: "BizAuthVerifyRequest", + required: ["token"], + properties: { + token: { type: "string", description: "明文 API Token" }, + feature: { type: "string", description: "swagger 路径对应 tags[0],用于套餐功能点" }, + api_path: { type: "string", description: "请求的接口 path,用于 allowed_apis 校验" }, + usage_delta: { + type: "object", + description: "可选用量上报", + properties: { + msg: { type: "integer" }, + mass: { type: "integer" }, + friend: { type: "integer" }, + sns: { type: "integer" }, + active_user: { type: "integer" }, + }, + }, + }, + }, + BizPlanWriteRequest: { + type: "object", + title: "BizPlanWriteRequest", + description: "biz_plan 表字段;add 不需 id,edit 需 id", + properties: { + id: { type: "integer", format: "int64" }, + plan_code: { type: "string" }, + plan_name: { type: "string" }, + monthly_price: { type: "number" }, + auth_fee: { type: "number" }, + account_limit: { type: "integer" }, + active_user_limit: { type: "integer" }, + msg_quota: { type: "integer" }, + mass_quota: { type: "integer" }, + friend_quota: { type: "integer" }, + sns_quota: { type: "integer" }, + allowed_apis: { description: "JSON:路径字符串数组", type: "array", items: { type: "string" } }, + api_call_quota: { type: "integer" }, + enabled_features: { type: "object", description: "JSON 功能点开关" }, + status: { type: "string", enum: ["active", "inactive"] }, + }, + }, +}; + +const paths = {}; +paths["/admin_api/biz_api_call_log/page"] = post("API 调用明细分页", "BizAdminPageRequest"); +paths["/admin_api/biz_api_stats/by_user"] = post("按用户统计接口调用", "BizApiStatsByUserRequest"); +paths["/admin_api/biz_api_stats/by_api"] = post("按接口路径统计调用", "BizApiStatsByApiRequest"); +paths["/admin_api/biz_api_stats/summary"] = post("调用量汇总与趋势", "BizApiStatsSummaryRequest"); +paths["/admin_api/biz_audit_log/page"] = post("审计日志分页", "BizAdminPageRequest"); +paths["/admin_api/biz_audit_log/export"] = post("审计日志导出", "BizAdminPageRequest"); +paths["/admin_api/biz_dashboard/summary"] = get("订阅/用户/Token 看板汇总", [], TAG_ADMIN); +paths["/admin_api/biz_payment/confirm-offline"] = post("确认线下支付(订阅置 active)", "BizPaymentConfirmRequest"); +paths["/admin_api/biz_payment/confirm-link"] = post("确认链接支付", "BizPaymentConfirmRequest"); +paths["/admin_api/biz_plan/page"] = post("套餐分页", "BizAdminPageRequest"); +paths["/admin_api/biz_plan/add"] = post("新增套餐", "BizPlanWriteRequest"); +paths["/admin_api/biz_plan/edit"] = post("编辑套餐", "BizPlanWriteRequest"); +paths["/admin_api/biz_plan/del"] = post("删除套餐", "BizIdRequest"); +paths["/admin_api/biz_plan/detail"] = get("套餐详情", [{ n: "id", req: true, d: "套餐 id" }]); +paths["/admin_api/biz_plan/all"] = get("套餐列表(下拉,最多 2000 条)", []); +paths["/admin_api/biz_plan/toggle"] = post("上下线切换", "BizIdRequest"); +paths["/admin_api/biz_plan/export"] = post("套餐导出", "BizAdminPageRequest"); +paths["/admin_api/biz_plan/proxy_api_catalog"] = postEmpty("转发接口目录(配置 allowed_apis)"); + +paths["/admin_api/biz_subscription/page"] = post("订阅分页(含 user_name、plan_name)", "BizAdminPageRequest"); +paths["/admin_api/biz_subscription/detail"] = get("订阅详情", [{ n: "id", req: true }]); +paths["/admin_api/biz_subscription/by_user"] = get("某用户订阅列表", [ + { n: "user_id", req: true, d: "业务用户 id" }, +]); +paths["/admin_api/biz_subscription/open"] = post("开通订阅", "BizSubscriptionOpenRequest"); +paths["/admin_api/biz_subscription/upgrade"] = post("变更套餐/时间", "BizSubscriptionUpgradeRequest"); +paths["/admin_api/biz_subscription/renew"] = post("续费(更新结束时间)", "BizSubscriptionRenewRequest"); +paths["/admin_api/biz_subscription/cancel"] = post("取消订阅", "BizSubscriptionCancelRequest"); +paths["/admin_api/biz_subscription/export"] = post("订阅导出 CSV 数据", "BizAdminPageRequest"); + +paths["/admin_api/biz_token/page"] = post("API Token 分页(不含 secret_cipher)", "BizAdminPageRequest"); +paths["/admin_api/biz_token/create"] = post("创建 Token,返回 plain_token", "BizTokenCreateRequest"); +paths["/admin_api/biz_token/revoke"] = post("吊销 Token", "BizTokenIdRequest"); +paths["/admin_api/biz_token/regenerate"] = post("重新生成密钥(返回新 plain_token)", "BizTokenIdRequest"); +paths["/admin_api/biz_token/export"] = post("Token 导出", "BizAdminPageRequest"); + +paths["/admin_api/biz_usage/page"] = post("月度用量分页", "BizAdminPageRequest"); +paths["/admin_api/biz_usage/add"] = post("新增用量记录", "BizUsageWriteRequest"); +paths["/admin_api/biz_usage/edit"] = post("编辑用量记录", "BizUsageWriteRequest"); +paths["/admin_api/biz_usage/del"] = post("删除用量记录", "BizIdRequest"); +paths["/admin_api/biz_usage/detail"] = get("用量详情", [{ n: "id", req: true }]); +paths["/admin_api/biz_usage/export"] = post("用量导出", "BizAdminPageRequest"); + +paths["/admin_api/biz_user/page"] = post("业务用户分页(含 token_count)", "BizAdminPageRequest"); +paths["/admin_api/biz_user/add"] = post("新增用户(可选自动创建 Token)", "BizUserAddRequest"); +paths["/admin_api/biz_user/edit"] = post("编辑用户", "BizUserEditRequest"); +paths["/admin_api/biz_user/del"] = post("删除用户", "BizIdRequest"); +paths["/admin_api/biz_user/detail"] = get("用户详情(含 subscriptions、tokens[].plain_token)", [{ n: "id", req: true }]); +paths["/admin_api/biz_user/all"] = get("全部用户(下拉)", []); +paths["/admin_api/biz_user/disable"] = post("禁用用户", "BizIdRequest"); +paths["/admin_api/biz_user/enable"] = post("启用用户", "BizIdRequest"); +paths["/admin_api/biz_user/export"] = post("用户导出", "BizAdminPageRequest"); +paths["/admin_api/biz_user/revoke_all_tokens"] = post("吊销用户下全部 Token", "BizUserRevokeTokensRequest"); + +paths["/admin_api/sys_file/upload_img"] = { + post: { + tags: TAG_ADMIN, + summary: "本地上传图片(multipart/form-data)", + consumes: ["multipart/form-data"], + parameters: [], + responses: res200(), + }, +}; +paths["/admin_api/sys_file/upload_oos_img"] = { + post: { + tags: TAG_ADMIN, + summary: "上传图片到 OSS(multipart)", + consumes: ["multipart/form-data"], + parameters: [], + responses: res200(), + }, +}; + +paths["/api/auth/verify"] = { + post: { + tags: TAG_OPEN_AUTH, + summary: "对外开放:Token 鉴权校验(含订阅/套餐/用量等)", + parameters: [ + { + in: "body", + name: "body", + schema: { $ref: "#/definitions/BizAuthVerifyRequest" }, + }, + ], + responses: res200(), + }, +}; + +Object.assign(doc.definitions, definitions); +Object.assign(doc.paths, paths); + +const extraTags = [ + { name: "管理端-业务订阅", description: "Base URL + /admin_api,需管理端登录" }, + { name: "开放接口-鉴权", description: "Base URL + /api,如 /api/auth/verify" }, +]; +for (const t of extraTags) { + if (!doc.tags.some((x) => x.name === t.name)) { + doc.tags.push(t); + } +} + +fs.writeFileSync(swaggerPath, JSON.stringify(doc, null, 4) + "\n", "utf8"); +console.log("merged admin biz paths + definitions into swagger.json"); diff --git a/_docs/swagger.json b/_docs/swagger.json index 00ec88a..15a6981 100644 --- a/_docs/swagger.json +++ b/_docs/swagger.json @@ -3446,7 +3446,7 @@ "type": "integer" }, "Scene": { - "description": " 添加来源, 同意添加好友时传回调消息xml中的scene值.\u003cbr/\u003e添加好友时的枚举值如下: \u003cbr/\u003e1(QQ) 2(邮箱) 3(微信号) 4(QQ好友) 8(来自群聊) 13(通讯录)\u003cbr/\u003e14(群聊) 15(手机号) 18(附近的人) 25(漂流瓶) 29(摇一摇) 30(二维码)", + "description": " 添加来源, 同意添加好友时传回调消息xml中的scene值.
添加好友时的枚举值如下:
1(QQ) 2(邮箱) 3(微信号) 4(QQ好友) 8(来自群聊) 13(通讯录)
14(群聊) 15(手机号) 18(附近的人) 25(漂流瓶) 29(摇一摇) 30(二维码)", "example": "3", "format": "int", "type": "integer" @@ -3599,6 +3599,492 @@ }, "title": "baseinfo.UserLabelInfoItem", "type": "object" + }, + "BizAdminPageRequest": { + "type": "object", + "title": "BizAdminPageRequest", + "description": "通用分页/筛选:body 可直接为 param,或形如 { param: { pageOption, seachOption } }", + "properties": { + "param": { + "type": "object", + "properties": { + "pageOption": { + "type": "object", + "properties": { + "page": { + "type": "integer", + "example": 1 + }, + "pageSize": { + "type": "integer", + "example": 20 + } + } + }, + "seachOption": { + "type": "object", + "properties": { + "key": { + "type": "string", + "description": "与模型字段名一致,如 user_id、status" + }, + "value": { + "type": "string" + } + } + } + } + } + } + }, + "BizIdRequest": { + "type": "object", + "title": "BizIdRequest", + "properties": { + "id": { + "type": "integer", + "format": "int64" + } + } + }, + "BizUserRevokeTokensRequest": { + "type": "object", + "title": "BizUserRevokeTokensRequest", + "properties": { + "user_id": { + "type": "integer", + "format": "int64", + "description": "与 id 二选一" + }, + "id": { + "type": "integer", + "format": "int64" + } + } + }, + "BizUserAddRequest": { + "type": "object", + "title": "BizUserAddRequest", + "description": "写入字段见 biz_user 模型;可选自动创建 Token", + "properties": { + "name": { + "type": "string" + }, + "mobile": { + "type": "string" + }, + "email": { + "type": "string" + }, + "company_name": { + "type": "string" + }, + "status": { + "type": "string", + "enum": [ + "active", + "disabled" + ] + }, + "auto_create_token": { + "type": "boolean", + "default": true + }, + "initial_token_name": { + "type": "string" + }, + "initial_token_expire_at": { + "type": "string", + "description": "如 2026-12-31 23:59:59" + } + } + }, + "BizUserEditRequest": { + "type": "object", + "title": "BizUserEditRequest", + "properties": { + "id": { + "type": "integer", + "format": "int64" + }, + "name": { + "type": "string" + }, + "mobile": { + "type": "string" + }, + "email": { + "type": "string" + }, + "company_name": { + "type": "string" + }, + "status": { + "type": "string", + "enum": [ + "active", + "disabled" + ] + } + }, + "required": [ + "id" + ] + }, + "BizSubscriptionOpenRequest": { + "type": "object", + "title": "BizSubscriptionOpenRequest", + "required": [ + "user_id", + "plan_id", + "start_time", + "end_time" + ], + "properties": { + "user_id": { + "type": "integer", + "format": "int64" + }, + "plan_id": { + "type": "integer", + "format": "int64" + }, + "start_time": { + "type": "string" + }, + "end_time": { + "type": "string" + }, + "status": { + "type": "string", + "enum": [ + "pending", + "active", + "expired", + "cancelled" + ] + }, + "renew_mode": { + "type": "string", + "enum": [ + "manual", + "auto" + ] + }, + "payment_channel": { + "type": "string", + "enum": [ + "offline", + "pay_link" + ] + }, + "payment_ref": { + "type": "string" + } + } + }, + "BizSubscriptionUpgradeRequest": { + "type": "object", + "title": "BizSubscriptionUpgradeRequest", + "required": [ + "subscription_id", + "new_plan_id" + ], + "properties": { + "subscription_id": { + "type": "integer", + "format": "int64" + }, + "new_plan_id": { + "type": "integer", + "format": "int64" + }, + "start_time": { + "type": "string" + }, + "end_time": { + "type": "string" + } + } + }, + "BizSubscriptionRenewRequest": { + "type": "object", + "title": "BizSubscriptionRenewRequest", + "required": [ + "subscription_id", + "end_time" + ], + "properties": { + "subscription_id": { + "type": "integer", + "format": "int64" + }, + "end_time": { + "type": "string" + } + } + }, + "BizSubscriptionCancelRequest": { + "type": "object", + "title": "BizSubscriptionCancelRequest", + "required": [ + "subscription_id" + ], + "properties": { + "subscription_id": { + "type": "integer", + "format": "int64" + } + } + }, + "BizPaymentConfirmRequest": { + "type": "object", + "title": "BizPaymentConfirmRequest", + "required": [ + "subscription_id" + ], + "properties": { + "subscription_id": { + "type": "integer", + "format": "int64" + }, + "payment_ref": { + "type": "string" + } + } + }, + "BizTokenCreateRequest": { + "type": "object", + "title": "BizTokenCreateRequest", + "required": [ + "user_id", + "expire_at" + ], + "properties": { + "user_id": { + "type": "integer", + "format": "int64" + }, + "token_name": { + "type": "string" + }, + "expire_at": { + "type": "string" + } + } + }, + "BizTokenIdRequest": { + "type": "object", + "title": "BizTokenIdRequest", + "required": [ + "id" + ], + "properties": { + "id": { + "type": "integer", + "format": "int64" + } + } + }, + "BizApiStatsByUserRequest": { + "type": "object", + "title": "BizApiStatsByUserRequest", + "required": [ + "user_id" + ], + "properties": { + "user_id": { + "type": "integer", + "format": "int64" + }, + "start_date": { + "type": "string", + "description": "DATEONLY YYYY-MM-DD" + }, + "end_date": { + "type": "string" + } + } + }, + "BizApiStatsByApiRequest": { + "type": "object", + "title": "BizApiStatsByApiRequest", + "required": [ + "api_path" + ], + "properties": { + "api_path": { + "type": "string" + }, + "start_date": { + "type": "string" + }, + "end_date": { + "type": "string" + } + } + }, + "BizApiStatsSummaryRequest": { + "type": "object", + "title": "BizApiStatsSummaryRequest", + "properties": { + "start_date": { + "type": "string" + }, + "end_date": { + "type": "string" + }, + "top_limit": { + "type": "integer", + "example": 10 + } + } + }, + "BizUsageWriteRequest": { + "type": "object", + "title": "BizUsageWriteRequest", + "description": "月度用量 biz_usage_monthly 字段", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "edit 必填" + }, + "user_id": { + "type": "integer", + "format": "int64" + }, + "plan_id": { + "type": "integer", + "format": "int64" + }, + "stat_month": { + "type": "string", + "example": "2026-04" + }, + "msg_count": { + "type": "integer" + }, + "mass_count": { + "type": "integer" + }, + "friend_count": { + "type": "integer" + }, + "sns_count": { + "type": "integer" + }, + "active_user_count": { + "type": "integer" + }, + "api_call_count": { + "type": "integer" + } + } + }, + "BizAuthVerifyRequest": { + "type": "object", + "title": "BizAuthVerifyRequest", + "required": [ + "token" + ], + "properties": { + "token": { + "type": "string", + "description": "明文 API Token" + }, + "feature": { + "type": "string", + "description": "swagger 路径对应 tags[0],用于套餐功能点" + }, + "api_path": { + "type": "string", + "description": "请求的接口 path,用于 allowed_apis 校验" + }, + "usage_delta": { + "type": "object", + "description": "可选用量上报", + "properties": { + "msg": { + "type": "integer" + }, + "mass": { + "type": "integer" + }, + "friend": { + "type": "integer" + }, + "sns": { + "type": "integer" + }, + "active_user": { + "type": "integer" + } + } + } + } + }, + "BizPlanWriteRequest": { + "type": "object", + "title": "BizPlanWriteRequest", + "description": "biz_plan 表字段;add 不需 id,edit 需 id", + "properties": { + "id": { + "type": "integer", + "format": "int64" + }, + "plan_code": { + "type": "string" + }, + "plan_name": { + "type": "string" + }, + "monthly_price": { + "type": "number" + }, + "auth_fee": { + "type": "number" + }, + "account_limit": { + "type": "integer" + }, + "active_user_limit": { + "type": "integer" + }, + "msg_quota": { + "type": "integer" + }, + "mass_quota": { + "type": "integer" + }, + "friend_quota": { + "type": "integer" + }, + "sns_quota": { + "type": "integer" + }, + "allowed_apis": { + "description": "JSON:路径字符串数组", + "type": "array", + "items": { + "type": "string" + } + }, + "api_call_quota": { + "type": "integer" + }, + "enabled_features": { + "type": "object", + "description": "JSON 功能点开关" + }, + "status": { + "type": "string", + "enum": [ + "active", + "inactive" + ] + } + } } }, "info": { @@ -8948,6 +9434,1064 @@ "同步消息" ] } + }, + "/admin_api/biz_api_call_log/page": { + "post": { + "tags": [ + "管理端-业务订阅" + ], + "summary": "API 调用明细分页", + "parameters": [ + { + "in": "body", + "name": "body", + "schema": { + "$ref": "#/definitions/BizAdminPageRequest" + } + } + ], + "responses": { + "200": { + "description": "框架统一包装;成功时 code=0,业务数据在 data" + } + } + } + }, + "/admin_api/biz_api_stats/by_user": { + "post": { + "tags": [ + "管理端-业务订阅" + ], + "summary": "按用户统计接口调用", + "parameters": [ + { + "in": "body", + "name": "body", + "schema": { + "$ref": "#/definitions/BizApiStatsByUserRequest" + } + } + ], + "responses": { + "200": { + "description": "框架统一包装;成功时 code=0,业务数据在 data" + } + } + } + }, + "/admin_api/biz_api_stats/by_api": { + "post": { + "tags": [ + "管理端-业务订阅" + ], + "summary": "按接口路径统计调用", + "parameters": [ + { + "in": "body", + "name": "body", + "schema": { + "$ref": "#/definitions/BizApiStatsByApiRequest" + } + } + ], + "responses": { + "200": { + "description": "框架统一包装;成功时 code=0,业务数据在 data" + } + } + } + }, + "/admin_api/biz_api_stats/summary": { + "post": { + "tags": [ + "管理端-业务订阅" + ], + "summary": "调用量汇总与趋势", + "parameters": [ + { + "in": "body", + "name": "body", + "schema": { + "$ref": "#/definitions/BizApiStatsSummaryRequest" + } + } + ], + "responses": { + "200": { + "description": "框架统一包装;成功时 code=0,业务数据在 data" + } + } + } + }, + "/admin_api/biz_audit_log/page": { + "post": { + "tags": [ + "管理端-业务订阅" + ], + "summary": "审计日志分页", + "parameters": [ + { + "in": "body", + "name": "body", + "schema": { + "$ref": "#/definitions/BizAdminPageRequest" + } + } + ], + "responses": { + "200": { + "description": "框架统一包装;成功时 code=0,业务数据在 data" + } + } + } + }, + "/admin_api/biz_audit_log/export": { + "post": { + "tags": [ + "管理端-业务订阅" + ], + "summary": "审计日志导出", + "parameters": [ + { + "in": "body", + "name": "body", + "schema": { + "$ref": "#/definitions/BizAdminPageRequest" + } + } + ], + "responses": { + "200": { + "description": "框架统一包装;成功时 code=0,业务数据在 data" + } + } + } + }, + "/admin_api/biz_dashboard/summary": { + "get": { + "tags": [ + "管理端-业务订阅" + ], + "summary": "订阅/用户/Token 看板汇总", + "parameters": [], + "responses": { + "200": { + "description": "框架统一包装;成功时 code=0,业务数据在 data" + } + } + } + }, + "/admin_api/biz_payment/confirm-offline": { + "post": { + "tags": [ + "管理端-业务订阅" + ], + "summary": "确认线下支付(订阅置 active)", + "parameters": [ + { + "in": "body", + "name": "body", + "schema": { + "$ref": "#/definitions/BizPaymentConfirmRequest" + } + } + ], + "responses": { + "200": { + "description": "框架统一包装;成功时 code=0,业务数据在 data" + } + } + } + }, + "/admin_api/biz_payment/confirm-link": { + "post": { + "tags": [ + "管理端-业务订阅" + ], + "summary": "确认链接支付", + "parameters": [ + { + "in": "body", + "name": "body", + "schema": { + "$ref": "#/definitions/BizPaymentConfirmRequest" + } + } + ], + "responses": { + "200": { + "description": "框架统一包装;成功时 code=0,业务数据在 data" + } + } + } + }, + "/admin_api/biz_plan/page": { + "post": { + "tags": [ + "管理端-业务订阅" + ], + "summary": "套餐分页", + "parameters": [ + { + "in": "body", + "name": "body", + "schema": { + "$ref": "#/definitions/BizAdminPageRequest" + } + } + ], + "responses": { + "200": { + "description": "框架统一包装;成功时 code=0,业务数据在 data" + } + } + } + }, + "/admin_api/biz_plan/add": { + "post": { + "tags": [ + "管理端-业务订阅" + ], + "summary": "新增套餐", + "parameters": [ + { + "in": "body", + "name": "body", + "schema": { + "$ref": "#/definitions/BizPlanWriteRequest" + } + } + ], + "responses": { + "200": { + "description": "框架统一包装;成功时 code=0,业务数据在 data" + } + } + } + }, + "/admin_api/biz_plan/edit": { + "post": { + "tags": [ + "管理端-业务订阅" + ], + "summary": "编辑套餐", + "parameters": [ + { + "in": "body", + "name": "body", + "schema": { + "$ref": "#/definitions/BizPlanWriteRequest" + } + } + ], + "responses": { + "200": { + "description": "框架统一包装;成功时 code=0,业务数据在 data" + } + } + } + }, + "/admin_api/biz_plan/del": { + "post": { + "tags": [ + "管理端-业务订阅" + ], + "summary": "删除套餐", + "parameters": [ + { + "in": "body", + "name": "body", + "schema": { + "$ref": "#/definitions/BizIdRequest" + } + } + ], + "responses": { + "200": { + "description": "框架统一包装;成功时 code=0,业务数据在 data" + } + } + } + }, + "/admin_api/biz_plan/detail": { + "get": { + "tags": [ + "管理端-业务订阅" + ], + "summary": "套餐详情", + "parameters": [ + { + "in": "query", + "name": "id", + "type": "string", + "required": true, + "description": "套餐 id" + } + ], + "responses": { + "200": { + "description": "框架统一包装;成功时 code=0,业务数据在 data" + } + } + } + }, + "/admin_api/biz_plan/all": { + "get": { + "tags": [ + "管理端-业务订阅" + ], + "summary": "套餐列表(下拉,最多 2000 条)", + "parameters": [], + "responses": { + "200": { + "description": "框架统一包装;成功时 code=0,业务数据在 data" + } + } + } + }, + "/admin_api/biz_plan/toggle": { + "post": { + "tags": [ + "管理端-业务订阅" + ], + "summary": "上下线切换", + "parameters": [ + { + "in": "body", + "name": "body", + "schema": { + "$ref": "#/definitions/BizIdRequest" + } + } + ], + "responses": { + "200": { + "description": "框架统一包装;成功时 code=0,业务数据在 data" + } + } + } + }, + "/admin_api/biz_plan/export": { + "post": { + "tags": [ + "管理端-业务订阅" + ], + "summary": "套餐导出", + "parameters": [ + { + "in": "body", + "name": "body", + "schema": { + "$ref": "#/definitions/BizAdminPageRequest" + } + } + ], + "responses": { + "200": { + "description": "框架统一包装;成功时 code=0,业务数据在 data" + } + } + } + }, + "/admin_api/biz_plan/proxy_api_catalog": { + "post": { + "tags": [ + "管理端-业务订阅" + ], + "summary": "转发接口目录(配置 allowed_apis)", + "parameters": [], + "responses": { + "200": { + "description": "框架统一包装;成功时 code=0,业务数据在 data" + } + } + } + }, + "/admin_api/biz_subscription/page": { + "post": { + "tags": [ + "管理端-业务订阅" + ], + "summary": "订阅分页(含 user_name、plan_name)", + "parameters": [ + { + "in": "body", + "name": "body", + "schema": { + "$ref": "#/definitions/BizAdminPageRequest" + } + } + ], + "responses": { + "200": { + "description": "框架统一包装;成功时 code=0,业务数据在 data" + } + } + } + }, + "/admin_api/biz_subscription/detail": { + "get": { + "tags": [ + "管理端-业务订阅" + ], + "summary": "订阅详情", + "parameters": [ + { + "in": "query", + "name": "id", + "type": "string", + "required": true, + "description": "" + } + ], + "responses": { + "200": { + "description": "框架统一包装;成功时 code=0,业务数据在 data" + } + } + } + }, + "/admin_api/biz_subscription/by_user": { + "get": { + "tags": [ + "管理端-业务订阅" + ], + "summary": "某用户订阅列表", + "parameters": [ + { + "in": "query", + "name": "user_id", + "type": "string", + "required": true, + "description": "业务用户 id" + } + ], + "responses": { + "200": { + "description": "框架统一包装;成功时 code=0,业务数据在 data" + } + } + } + }, + "/admin_api/biz_subscription/open": { + "post": { + "tags": [ + "管理端-业务订阅" + ], + "summary": "开通订阅", + "parameters": [ + { + "in": "body", + "name": "body", + "schema": { + "$ref": "#/definitions/BizSubscriptionOpenRequest" + } + } + ], + "responses": { + "200": { + "description": "框架统一包装;成功时 code=0,业务数据在 data" + } + } + } + }, + "/admin_api/biz_subscription/upgrade": { + "post": { + "tags": [ + "管理端-业务订阅" + ], + "summary": "变更套餐/时间", + "parameters": [ + { + "in": "body", + "name": "body", + "schema": { + "$ref": "#/definitions/BizSubscriptionUpgradeRequest" + } + } + ], + "responses": { + "200": { + "description": "框架统一包装;成功时 code=0,业务数据在 data" + } + } + } + }, + "/admin_api/biz_subscription/renew": { + "post": { + "tags": [ + "管理端-业务订阅" + ], + "summary": "续费(更新结束时间)", + "parameters": [ + { + "in": "body", + "name": "body", + "schema": { + "$ref": "#/definitions/BizSubscriptionRenewRequest" + } + } + ], + "responses": { + "200": { + "description": "框架统一包装;成功时 code=0,业务数据在 data" + } + } + } + }, + "/admin_api/biz_subscription/cancel": { + "post": { + "tags": [ + "管理端-业务订阅" + ], + "summary": "取消订阅", + "parameters": [ + { + "in": "body", + "name": "body", + "schema": { + "$ref": "#/definitions/BizSubscriptionCancelRequest" + } + } + ], + "responses": { + "200": { + "description": "框架统一包装;成功时 code=0,业务数据在 data" + } + } + } + }, + "/admin_api/biz_subscription/export": { + "post": { + "tags": [ + "管理端-业务订阅" + ], + "summary": "订阅导出 CSV 数据", + "parameters": [ + { + "in": "body", + "name": "body", + "schema": { + "$ref": "#/definitions/BizAdminPageRequest" + } + } + ], + "responses": { + "200": { + "description": "框架统一包装;成功时 code=0,业务数据在 data" + } + } + } + }, + "/admin_api/biz_token/page": { + "post": { + "tags": [ + "管理端-业务订阅" + ], + "summary": "API Token 分页(不含 secret_cipher)", + "parameters": [ + { + "in": "body", + "name": "body", + "schema": { + "$ref": "#/definitions/BizAdminPageRequest" + } + } + ], + "responses": { + "200": { + "description": "框架统一包装;成功时 code=0,业务数据在 data" + } + } + } + }, + "/admin_api/biz_token/create": { + "post": { + "tags": [ + "管理端-业务订阅" + ], + "summary": "创建 Token,返回 plain_token", + "parameters": [ + { + "in": "body", + "name": "body", + "schema": { + "$ref": "#/definitions/BizTokenCreateRequest" + } + } + ], + "responses": { + "200": { + "description": "框架统一包装;成功时 code=0,业务数据在 data" + } + } + } + }, + "/admin_api/biz_token/revoke": { + "post": { + "tags": [ + "管理端-业务订阅" + ], + "summary": "吊销 Token", + "parameters": [ + { + "in": "body", + "name": "body", + "schema": { + "$ref": "#/definitions/BizTokenIdRequest" + } + } + ], + "responses": { + "200": { + "description": "框架统一包装;成功时 code=0,业务数据在 data" + } + } + } + }, + "/admin_api/biz_token/regenerate": { + "post": { + "tags": [ + "管理端-业务订阅" + ], + "summary": "重新生成密钥(返回新 plain_token)", + "parameters": [ + { + "in": "body", + "name": "body", + "schema": { + "$ref": "#/definitions/BizTokenIdRequest" + } + } + ], + "responses": { + "200": { + "description": "框架统一包装;成功时 code=0,业务数据在 data" + } + } + } + }, + "/admin_api/biz_token/export": { + "post": { + "tags": [ + "管理端-业务订阅" + ], + "summary": "Token 导出", + "parameters": [ + { + "in": "body", + "name": "body", + "schema": { + "$ref": "#/definitions/BizAdminPageRequest" + } + } + ], + "responses": { + "200": { + "description": "框架统一包装;成功时 code=0,业务数据在 data" + } + } + } + }, + "/admin_api/biz_usage/page": { + "post": { + "tags": [ + "管理端-业务订阅" + ], + "summary": "月度用量分页", + "parameters": [ + { + "in": "body", + "name": "body", + "schema": { + "$ref": "#/definitions/BizAdminPageRequest" + } + } + ], + "responses": { + "200": { + "description": "框架统一包装;成功时 code=0,业务数据在 data" + } + } + } + }, + "/admin_api/biz_usage/add": { + "post": { + "tags": [ + "管理端-业务订阅" + ], + "summary": "新增用量记录", + "parameters": [ + { + "in": "body", + "name": "body", + "schema": { + "$ref": "#/definitions/BizUsageWriteRequest" + } + } + ], + "responses": { + "200": { + "description": "框架统一包装;成功时 code=0,业务数据在 data" + } + } + } + }, + "/admin_api/biz_usage/edit": { + "post": { + "tags": [ + "管理端-业务订阅" + ], + "summary": "编辑用量记录", + "parameters": [ + { + "in": "body", + "name": "body", + "schema": { + "$ref": "#/definitions/BizUsageWriteRequest" + } + } + ], + "responses": { + "200": { + "description": "框架统一包装;成功时 code=0,业务数据在 data" + } + } + } + }, + "/admin_api/biz_usage/del": { + "post": { + "tags": [ + "管理端-业务订阅" + ], + "summary": "删除用量记录", + "parameters": [ + { + "in": "body", + "name": "body", + "schema": { + "$ref": "#/definitions/BizIdRequest" + } + } + ], + "responses": { + "200": { + "description": "框架统一包装;成功时 code=0,业务数据在 data" + } + } + } + }, + "/admin_api/biz_usage/detail": { + "get": { + "tags": [ + "管理端-业务订阅" + ], + "summary": "用量详情", + "parameters": [ + { + "in": "query", + "name": "id", + "type": "string", + "required": true, + "description": "" + } + ], + "responses": { + "200": { + "description": "框架统一包装;成功时 code=0,业务数据在 data" + } + } + } + }, + "/admin_api/biz_usage/export": { + "post": { + "tags": [ + "管理端-业务订阅" + ], + "summary": "用量导出", + "parameters": [ + { + "in": "body", + "name": "body", + "schema": { + "$ref": "#/definitions/BizAdminPageRequest" + } + } + ], + "responses": { + "200": { + "description": "框架统一包装;成功时 code=0,业务数据在 data" + } + } + } + }, + "/admin_api/biz_user/page": { + "post": { + "tags": [ + "管理端-业务订阅" + ], + "summary": "业务用户分页(含 token_count)", + "parameters": [ + { + "in": "body", + "name": "body", + "schema": { + "$ref": "#/definitions/BizAdminPageRequest" + } + } + ], + "responses": { + "200": { + "description": "框架统一包装;成功时 code=0,业务数据在 data" + } + } + } + }, + "/admin_api/biz_user/add": { + "post": { + "tags": [ + "管理端-业务订阅" + ], + "summary": "新增用户(可选自动创建 Token)", + "parameters": [ + { + "in": "body", + "name": "body", + "schema": { + "$ref": "#/definitions/BizUserAddRequest" + } + } + ], + "responses": { + "200": { + "description": "框架统一包装;成功时 code=0,业务数据在 data" + } + } + } + }, + "/admin_api/biz_user/edit": { + "post": { + "tags": [ + "管理端-业务订阅" + ], + "summary": "编辑用户", + "parameters": [ + { + "in": "body", + "name": "body", + "schema": { + "$ref": "#/definitions/BizUserEditRequest" + } + } + ], + "responses": { + "200": { + "description": "框架统一包装;成功时 code=0,业务数据在 data" + } + } + } + }, + "/admin_api/biz_user/del": { + "post": { + "tags": [ + "管理端-业务订阅" + ], + "summary": "删除用户", + "parameters": [ + { + "in": "body", + "name": "body", + "schema": { + "$ref": "#/definitions/BizIdRequest" + } + } + ], + "responses": { + "200": { + "description": "框架统一包装;成功时 code=0,业务数据在 data" + } + } + } + }, + "/admin_api/biz_user/detail": { + "get": { + "tags": [ + "管理端-业务订阅" + ], + "summary": "用户详情(含 subscriptions、tokens[].plain_token)", + "parameters": [ + { + "in": "query", + "name": "id", + "type": "string", + "required": true, + "description": "" + } + ], + "responses": { + "200": { + "description": "框架统一包装;成功时 code=0,业务数据在 data" + } + } + } + }, + "/admin_api/biz_user/all": { + "get": { + "tags": [ + "管理端-业务订阅" + ], + "summary": "全部用户(下拉)", + "parameters": [], + "responses": { + "200": { + "description": "框架统一包装;成功时 code=0,业务数据在 data" + } + } + } + }, + "/admin_api/biz_user/disable": { + "post": { + "tags": [ + "管理端-业务订阅" + ], + "summary": "禁用用户", + "parameters": [ + { + "in": "body", + "name": "body", + "schema": { + "$ref": "#/definitions/BizIdRequest" + } + } + ], + "responses": { + "200": { + "description": "框架统一包装;成功时 code=0,业务数据在 data" + } + } + } + }, + "/admin_api/biz_user/enable": { + "post": { + "tags": [ + "管理端-业务订阅" + ], + "summary": "启用用户", + "parameters": [ + { + "in": "body", + "name": "body", + "schema": { + "$ref": "#/definitions/BizIdRequest" + } + } + ], + "responses": { + "200": { + "description": "框架统一包装;成功时 code=0,业务数据在 data" + } + } + } + }, + "/admin_api/biz_user/export": { + "post": { + "tags": [ + "管理端-业务订阅" + ], + "summary": "用户导出", + "parameters": [ + { + "in": "body", + "name": "body", + "schema": { + "$ref": "#/definitions/BizAdminPageRequest" + } + } + ], + "responses": { + "200": { + "description": "框架统一包装;成功时 code=0,业务数据在 data" + } + } + } + }, + "/admin_api/biz_user/revoke_all_tokens": { + "post": { + "tags": [ + "管理端-业务订阅" + ], + "summary": "吊销用户下全部 Token", + "parameters": [ + { + "in": "body", + "name": "body", + "schema": { + "$ref": "#/definitions/BizUserRevokeTokensRequest" + } + } + ], + "responses": { + "200": { + "description": "框架统一包装;成功时 code=0,业务数据在 data" + } + } + } + }, + "/admin_api/sys_file/upload_img": { + "post": { + "tags": [ + "管理端-业务订阅" + ], + "summary": "本地上传图片(multipart/form-data)", + "consumes": [ + "multipart/form-data" + ], + "parameters": [], + "responses": { + "200": { + "description": "框架统一包装;成功时 code=0,业务数据在 data" + } + } + } + }, + "/admin_api/sys_file/upload_oos_img": { + "post": { + "tags": [ + "管理端-业务订阅" + ], + "summary": "上传图片到 OSS(multipart)", + "consumes": [ + "multipart/form-data" + ], + "parameters": [], + "responses": { + "200": { + "description": "框架统一包装;成功时 code=0,业务数据在 data" + } + } + } + }, + "/api/auth/verify": { + "post": { + "tags": [ + "开放接口-鉴权" + ], + "summary": "对外开放:Token 鉴权校验(含订阅/套餐/用量等)", + "parameters": [ + { + "in": "body", + "name": "body", + "schema": { + "$ref": "#/definitions/BizAuthVerifyRequest" + } + } + ], + "responses": { + "200": { + "description": "框架统一包装;成功时 code=0,业务数据在 data" + } + } + } } }, "swagger": "2.0", @@ -9023,6 +10567,14 @@ { "description": "/shop", "name": "/shop" + }, + { + "name": "管理端-业务订阅", + "description": "Base URL + /admin_api,需管理端登录" + }, + { + "name": "开放接口-鉴权", + "description": "Base URL + /api,如 /api/auth/verify" } ] -} \ No newline at end of file +} diff --git a/api/controller_custom/proxy_api.js b/api/controller_custom/proxy_api.js index 0c51ce3..7c17c5e 100644 --- a/api/controller_custom/proxy_api.js +++ b/api/controller_custom/proxy_api.js @@ -5,15 +5,18 @@ const proxy = require("../service/biz_proxy_service"); /** - * 从请求中提取 Token - * 支持 Authorization: Bearer xxx 和 query ?token=xxx + * 从 ctx 请求头中提取 Token(不含 query) + * - Authorization: Bearer + * - Authorization: (无 Bearer 前缀时整段作为 token) + * - X-Api-Token / X-Token */ function extractToken(ctx) { - const authHeader = ctx.get("Authorization") || ""; - if (authHeader.startsWith("Bearer ")) { - return authHeader.slice(7).trim(); + + let x_token = ctx.headers['authorization'] || '' + if (x_token.startsWith("Bearer ")) { + x_token = x_token.slice(7).trim(); } - return ctx.query.token || ""; + return x_token; } /** @@ -26,6 +29,14 @@ function pickFeature(spec) { return null; } +/** 不参与转发的文档路径(与 framework 实际路由重叠或仅为说明) */ +function should_skip_proxy_path(route_path) { + return ( + route_path.startsWith("/admin_api") || + route_path.startsWith("/api/auth") + ); +} + /** * 构建转发路由表(供 framework.addRoutes 注册) */ @@ -33,6 +44,9 @@ function buildProxyRoutes() { const routes = {}; for (const [path, methods] of Object.entries(swagger.paths)) { + if (should_skip_proxy_path(path)) { + continue; + } for (const [method, spec] of Object.entries(methods)) { const routeKey = `${method.toUpperCase()} ${path}`; @@ -51,10 +65,8 @@ function buildProxyRoutes() { ctx.fail(authResult.message || "鉴权失败"); return; } - - // 3. 组装 query(去掉 token 参数,避免泄露) + // 3. 组装 query const query = { ...ctx.query }; - delete query.token; // 4. 转发到上游 const result = await proxy.forwardRequest({ @@ -68,7 +80,7 @@ function buildProxyRoutes() { // 5. 根据上游 Success 字段决定响应方式 const upstream = result.data; - if (upstream && upstream.Success === true) { + if (upstream && upstream.Code === 200) { ctx.success(upstream); } else { ctx.fail(upstream && upstream.Text ? upstream.Text : "上游请求失败", upstream); diff --git a/api/model/biz_api_call_log.js b/api/model/biz_api_call_log.js index e161e7a..d116991 100644 --- a/api/model/biz_api_call_log.js +++ b/api/model/biz_api_call_log.js @@ -49,5 +49,7 @@ module.exports = (db) => { underscored: true, } ); + + //biz_api_call_log.sync({ force: true }); return biz_api_call_log; };