129 lines
3.3 KiB
JavaScript
129 lines
3.3 KiB
JavaScript
/**
|
||
* 管理端列表筛选、导出、写入字段裁剪(供 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,
|
||
};
|