This commit is contained in:
rgrgogu
2026-05-07 23:35:22 +08:00
parent 09660d7503
commit 58ccecd28a
10 changed files with 370 additions and 53 deletions
+41 -6
View File
@@ -80,7 +80,8 @@ async function paginate(model, req, {
jsonbSchemas = {},
jsonbColumn = null,
findOptions = {},
auditOptions = null, // ← { mdl_Users, parentAlias }
auditOptions = null, // ← { mdl_Users, parentAlias },
computedAttributes = []
} = {}) {
const page = Math.max(PAGE_START, parseInt(req.query.page, 10) || PAGE_START);
const limit = Math.min(parseInt(req.query.limit, 10) || PAGE_SIZE, MAX_LIMIT);
@@ -104,7 +105,18 @@ async function paginate(model, req, {
? auditInclude(auditOptions.mdl_Users, auditOptions.parentAlias).attributes
: [];
const extraIncludes = findOptions.attributes?.include ?? [];
const mergedAttributeIncludes = [...baseIncludes, ...auditAttrs, ...extraIncludes];
// ← Convert { key, literal } objects into Sequelize [literal, alias] tuples
const computedIncludes = computedAttributes
.filter((c) => c.literal)
.map((c) => [Sequelize.literal(c.literal), c.key]);
const mergedAttributeIncludes = [
...baseIncludes,
...auditAttrs,
...extraIncludes,
...computedIncludes, // ← now proper tuples
];
const { attributes: _attr, ...restFindOptions } = findOptions;
@@ -122,12 +134,35 @@ async function paginate(model, req, {
const data = rows
.map((row) => row.toJSON?.() ?? row)
.map(auditIdToName);
.map(auditIdToName)
.map((row) => {
// ← Coerce computed types after toJSON
const result = { ...row };
for (const { key, type } of computedAttributes) {
if (result[key] !== undefined && result[key] !== null) {
if (type === 'number') result[key] = parseInt(result[key], 10);
if (type === 'float') result[key] = parseFloat(result[key]);
}
}
return result;
});
// ─── Flatten JSONB columns into dot-notation keys ──────────────────────────
const jsonbCols = jsonbColumn ? [jsonbColumn] : [];
const totalPages = Math.ceil(count / limit);
// ← Append computed metadata
const computedMeta = computedAttributes.map(({ key, label, type, order: ord }) => ({
name: label ?? key,
type: type ?? 'text',
field: key,
order: ord ?? Infinity,
options: {},
}));
// ← Merge, sort, THEN strip order
const mergedAttributes = [...attributes, ...computedMeta]
.sort((a, b) => (a.order ?? Infinity) - (b.order ?? Infinity))
.map(({ order: _, ...rest }) => rest);
return {
data,
pagination: {
@@ -138,7 +173,7 @@ async function paginate(model, req, {
hasPrevPage: page > PAGE_START,
hasNextPage: page < totalPages,
},
attributes,
attributes: mergedAttributes,
};
}