Files
wechatWeb/_docs/merge_biz_into_swagger.js
张成 09368d2a95 1
2026-04-01 14:16:06 +08:00

379 lines
14 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* 将管理端 / 开放鉴权接口合并进 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 不需 idedit 需 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: "上传图片到 OSSmultipart",
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");