fix(admin): 修复选手管理「激活状态」「注册日期」筛选被静默丢弃
现象(人工测试反馈):选手管理页「激活状态」下拉选择后列表无变化。
根因 —— 两层都在丢参且零报错:
- controller/admin.js 只解构 group/keyword/page/pageSize,
前端已发出的 activated 从未透传给 service
- service/admin.js 即使收到也未解构 activated,where 中根本没有该条件
- 同族缺陷:前端还发了 startDate/endDate(注册日期范围),
controller 同样未转发 => 该筛选同样失效(此前无人报告)
修复:
- controller:将 activated/startDate/endDate 整体透传给 service
- service:解构 activated,并对 BOOLEAN 列做白名单归一化
前端 el-select 传的是字符串 'true'/'false',直接入 where 会被
MySQL 隐式转为 0,导致「已激活」错查出「未激活」(比不筛选更难察觉);
白名单之外的值(含 undefined/'')一律视为未指定忽略,
避免畸形入参被当作 false 而静默缩窄结果集
验证(scripts/verify_accounts_filter.py,9/9 PASS,真实 HTTP + 独立 DB 真值):
A1 无筛选 total=26 == DB 26
A2 activated=true -> 10 == DB 已激活数
A3 activated=false -> 16
A4 分区性 10 + 16 == 26(关键判别器)
D1 日期限定 DB 实际存在那天 -> 20 == DB 当日
D2 负向对照(范围早于最早记录)-> 0
变异自证:拆掉 where.activated 分支重跑 -> A2/A2b/A3/A3b/A4 全红 EXIT=1,
失败信息精确复现原现象(total=26 != 10);还原后 diff 空、md5 一致、无标记残留
同族扫描:全后端 ctx.query 仅 11 处,逐点核对 => 仅 getAccounts 一对丢参
部署(生产 back-end):
线上 md5 与本地逐文件一致(controller ad0e60f8 / service 93eb3dbb)
MainPID 3341710 -> 3343212;8023 监听正常;err 级日志 -- No entries --
路由探针:health 200 / admin-login 错误口令 HTTP200+code4004 / 不存在路由 404 /
未授权 accounts 401
This commit is contained in:
@@ -109,12 +109,12 @@ class AdminService extends Service {
|
||||
|
||||
/**
|
||||
* 获取分页账号列表
|
||||
* @param {Object} options - 查询选项 { group, keyword, page, pageSize, startDate, endDate }
|
||||
* @param {Object} options - 查询选项 { group, keyword, activated, page, pageSize, startDate, endDate }
|
||||
* @returns {Promise<Object>} { list, total, page, pageSize }
|
||||
*/
|
||||
async getAccounts(options = {}) {
|
||||
const { ctx } = this;
|
||||
const { group, keyword, startDate, endDate } = options;
|
||||
const { group, keyword, activated, startDate, endDate } = options;
|
||||
const page = parseInt(options.page, 10) || 1;
|
||||
const pageSize = parseInt(options.pageSize, 10) || 20;
|
||||
const offset = (page - 1) * pageSize;
|
||||
@@ -124,6 +124,18 @@ class AdminService extends Service {
|
||||
if (group) {
|
||||
where.group = group;
|
||||
}
|
||||
// 激活状态筛选(2026-10-08 修复:此前 controller 未透传、本函数也未解构该参数,
|
||||
// ⇒ 选手管理页「激活状态」下拉完全失效且不报错)。
|
||||
// ⚠️ 前端 el-select 传的是字符串 'true'/'false',**不能直接塞进 where**:
|
||||
// activated 是 BOOLEAN(TINYINT(1)) 列,MySQL 会把 'true' 隐式转成 0,
|
||||
// 结果「已激活」错查出「未激活」。必须显式归一化为布尔。
|
||||
// 白名单之外的值(含 undefined/'' 等)一律视为「未指定」忽略,
|
||||
// 避免畸形入参被当成 false 而静默缩窄结果集。
|
||||
if ([true, 1, '1', 'true'].includes(activated)) {
|
||||
where.activated = true;
|
||||
} else if ([false, 0, '0', 'false'].includes(activated)) {
|
||||
where.activated = false;
|
||||
}
|
||||
if (keyword) {
|
||||
where[ctx.model.Sequelize.Op.or] = [
|
||||
{ name: { [ctx.model.Sequelize.Op.like]: `%${keyword}%` } },
|
||||
|
||||
Reference in New Issue
Block a user