/** * 管理端列表筛选、导出、写入字段裁剪(供 controller_admin 配合 baseModel) */ const Sequelize = require("sequelize"); const { Op } = Sequelize; function build_search_where(model, seach_option) { const key = seach_option && seach_option.key; const raw = seach_option && seach_option.value; if (!key || raw === undefined || raw === null) return {}; const str = String(raw).trim(); if (str === "") return {}; const attr = model.rawAttributes[key]; if (!attr) { return { [key]: { [Op.like]: `%${str}%` } }; } const type_key = attr.type && attr.type.key; if (type_key === "BOOLEAN") { if (str === "true" || str === "1" || str === "是") return { [key]: true }; if (str === "false" || str === "0" || str === "否") return { [key]: false }; return {}; } if (type_key === "ENUM") { return { [key]: str }; } if ( type_key === "INTEGER" || type_key === "BIGINT" || type_key === "FLOAT" || type_key === "DOUBLE" || type_key === "DECIMAL" ) { const n = Number(str); if (!Number.isNaN(n)) return { [key]: n }; return {}; } if (type_key === "DATE" || type_key === "DATEONLY") { return { [key]: str }; } return { [key]: { [Op.like]: `%${str}%` } }; } function normalize_for_write(model, data, { for_create } = {}) { const attrs = model.rawAttributes; const out = {}; for (const k of Object.keys(data || {})) { if (!attrs[k]) continue; let v = data[k]; if (v === "") { if (k === "id" && for_create) continue; if (k.endsWith("_id") || k === "id") { v = null; } else if (attrs[k].allowNull) { v = null; } } if (k === "enabled_features" && typeof v === "string" && v.trim() !== "") { try { v = JSON.parse(v); } catch (e) { /* 保持原字符串 */ } } out[k] = v; } if (for_create && out.id !== undefined && (out.id === "" || out.id === null)) { delete out.id; } return out; } function list_query_extra(model_name, model) { if (model_name === "biz_audit_log") { const tn = model.tableName; return { attributes: { include: [[model.sequelize.col(`${tn}.created_at`), "created_at"]], }, }; } return {}; } async function find_page(model, model_name, body, extra_find_options = {}) { const param = body.param || body; const page_option = param.pageOption || {}; const seach_option = param.seachOption || {}; const page_num = parseInt(page_option.page, 10) || 1; const page_size = parseInt(page_option.pageSize, 10) || 20; const offset = (page_num - 1) * page_size; const where = build_search_where(model, seach_option); return model.findAndCountAll({ where, offset, limit: page_size, order: [["id", "DESC"]], ...list_query_extra(model_name, model), ...extra_find_options, }); } async function find_for_export(model, model_name, body, extra_find_options = {}) { const param = body.param || body; const where = build_search_where(model, param.seachOption || {}); const rows = await model.findAll({ where, limit: 10000, order: [["id", "DESC"]], ...list_query_extra(model_name, model), ...extra_find_options, }); return { rows }; } module.exports = { build_search_where, normalize_for_write, list_query_extra, find_page, find_for_export, };