Files
wechatWeb/api/controller_admin/biz_user.js
张成 1d22fb28e2 1
2026-04-01 13:40:27 +08:00

212 lines
6.7 KiB
JavaScript

const Sequelize = require("sequelize");
const { normalize_for_write, build_search_where } = require("../utils/query_helpers");
const baseModel = require("../../middleware/baseModel");
const tokenLogic = require("../service/biz_token_logic");
const audit = require("../utils/biz_audit");
module.exports = {
"POST /biz_user/page": async (ctx) => {
const body = ctx.getBody();
const param = body.param || body;
const pageOption = param.pageOption || {};
const seachOption = param.seachOption || {};
const pageNum = parseInt(pageOption.page, 10) || 1;
const pageSize = parseInt(pageOption.pageSize, 10) || 20;
const offset = (pageNum - 1) * pageSize;
const biz_user = baseModel.biz_user;
const where = build_search_where(biz_user, seachOption);
const { count, rows } = await biz_user.findAndCountAll({
where,
offset,
limit: pageSize,
order: [["id", "DESC"]],
attributes: {
include: [
[
Sequelize.literal(
`(SELECT COUNT(*) FROM biz_api_token WHERE biz_api_token.user_id = biz_user.id)`
),
"token_count",
],
],
},
});
ctx.success({ rows, count });
},
"POST /biz_user/add": async (ctx) => {
const body = ctx.getBody();
const biz_user = baseModel.biz_user;
const payload = normalize_for_write(biz_user, body, { for_create: true });
const row = await biz_user.create(payload);
await audit.logAudit({
admin_user_id: audit.pickAdminId(ctx),
biz_user_id: row.id,
action: "biz_user.add",
resource_type: "biz_user",
resource_id: row.id,
detail: { name: row.name },
});
const out = row.get({ plain: true });
let plain_token = null;
let token_warn = null;
let token_error = null;
const auto_token = body.auto_create_token !== false;
if (auto_token && row.status === "active") {
try {
const result = await tokenLogic.createToken({
user_id: row.id,
token_name: body.initial_token_name || "default",
expire_at: body.initial_token_expire_at || tokenLogic.defaultTokenExpireAt(),
});
await audit.logAudit({
admin_user_id: audit.pickAdminId(ctx),
biz_user_id: row.id,
action: "biz_token.create",
resource_type: "biz_api_token",
resource_id: result.row.id,
detail: { token_name: result.row.token_name, via: "biz_user.add" },
});
plain_token = result.plain_token;
token_warn = result.warn;
} catch (e) {
token_error = e.message || String(e);
}
}
ctx.success({
...out,
plain_token,
token_warn,
token_error,
});
},
"POST /biz_user/edit": async (ctx) => {
const body = ctx.getBody();
const id = body.id;
if (id === undefined || id === null || id === "") throw new Error("缺少 id");
const biz_user = baseModel.biz_user;
const payload = normalize_for_write(biz_user, body, { for_create: false });
delete payload.id;
await biz_user.update(payload, { where: { id } });
await audit.logAudit({
admin_user_id: audit.pickAdminId(ctx),
biz_user_id: body.id,
action: "biz_user.edit",
resource_type: "biz_user",
resource_id: body.id,
});
ctx.success({});
},
"POST /biz_user/del": async (ctx) => {
const body = ctx.getBody();
const id = body.id !== undefined ? body.id : body;
if (id === undefined || id === null || id === "") throw new Error("缺少 id");
const biz_user = baseModel.biz_user;
await biz_user.destroy({ where: { id } });
await audit.logAudit({
admin_user_id: audit.pickAdminId(ctx),
biz_user_id: body.id,
action: "biz_user.del",
resource_type: "biz_user",
resource_id: body.id,
});
ctx.success({});
},
"GET /biz_user/detail": async (ctx) => {
const q = ctx.query || {};
const id = q.id || q.ID;
if (id === undefined || id === null || id === "") throw new Error("缺少 id");
const biz_user = baseModel.biz_user;
const user = await biz_user.findByPk(id);
if (!user) {
return ctx.fail("用户不存在");
}
const subscriptions = await baseModel.biz_subscription.findAll({
where: { user_id: id },
order: [["id", "DESC"]],
limit: 10,
});
const tokenCount = await baseModel.biz_api_token.count({
where: { user_id: id },
});
const tokens = await baseModel.biz_api_token.findAll({
where: { user_id: id },
order: [["id", "DESC"]],
limit: 200,
attributes: ["id", "user_id", "plan_id", "token_name", "status", "expire_at", "last_used_at"],
});
ctx.success({
user,
subscriptions,
tokenCount,
tokens,
});
},
"GET /biz_user/all": async (ctx) => {
const biz_user = baseModel.biz_user;
const rows = await biz_user.findAll({
limit: 2000,
order: [["id", "DESC"]],
});
ctx.success(rows);
},
"POST /biz_user/disable": async (ctx) => {
const body = ctx.getBody();
const id = body.id;
if (id == null) return ctx.fail("缺少 id");
const biz_user = baseModel.biz_user;
await biz_user.update({ status: "disabled" }, { where: { id } });
await audit.logAudit({
admin_user_id: audit.pickAdminId(ctx),
biz_user_id: id,
action: "biz_user.disable",
resource_type: "biz_user",
resource_id: id,
});
ctx.success({});
},
"POST /biz_user/enable": async (ctx) => {
const body = ctx.getBody();
const id = body.id;
if (id == null) return ctx.fail("缺少 id");
const biz_user = baseModel.biz_user;
await biz_user.update({ status: "active" }, { where: { id } });
await audit.logAudit({
admin_user_id: audit.pickAdminId(ctx),
biz_user_id: id,
action: "biz_user.enable",
resource_type: "biz_user",
resource_id: id,
});
ctx.success({});
},
"POST /biz_user/export": async (ctx) => {
const body = ctx.getBody();
const param = body.param || body;
const biz_user = baseModel.biz_user;
const where = build_search_where(biz_user, param.seachOption || {});
const rows = await biz_user.findAll({
where,
limit: 10000,
order: [["id", "DESC"]],
});
ctx.success({ rows });
},
"POST /biz_user/revoke_all_tokens": async (ctx) => {
const body = ctx.getBody();
const userId = body.user_id != null ? body.user_id : body.id;
if (userId == null) return ctx.fail("缺少 user_id");
const n = await tokenLogic.revokeAllForUser(userId);
await audit.logAudit({
admin_user_id: audit.pickAdminId(ctx),
biz_user_id: userId,
action: "biz_token.revoke_all",
resource_type: "biz_user",
resource_id: userId,
detail: { affected: n },
});
ctx.success({ revoked: n });
},
};