| 12345678910111213141516171819 |
- async function contentPage(input, publicOnly = false) {
- const paging = pageInput(input); const values = [DEFAULT_COMPANY_ID]; const clauses = ['c."company" = $1'];
- if (input.__publishedOnly === true) clauses.push('CAST(COALESCE(c."status",99) AS text) = \'99\'');
- if (input.objectId) { values.push(String(input.objectId)); clauses.push('c."objectId" = $' + values.length); }
- if (input.generalId) { values.push(String(input.generalId)); clauses.push('CAST(c."generalId" AS text) = $' + values.length); }
- const nodeIds = String(input.nodeid || input.nid || input.nodes || '').split(',').map((value) => String(number(value))).filter((value) => value !== '0');
- if (nodeIds.length) { values.push(nodeIds); clauses.push('CAST(c."nodeId" AS text) = ANY($' + values.length + '::text[])'); }
- const modelId = contentModel(input, nodeIds); const config = CONTENT_ADDONS[modelId] || null; if(modelId===56)clauses.push("COALESCE(to_jsonb(a)->>'recordScope','')<>'lesson-alias'"); if(modelId===58)clauses.push("a.\"enrollmentStatus\"='active'"); if (modelId) { values.push(String(modelId)); clauses.push('CAST(c."modelId" AS text) = $' + values.length); }
- if (modelId === 52 && input.excludeWordIds) { const excluded = [...new Set(String(input.excludeWordIds).split(',').filter(id => /^[0-9]+$/.test(id)))]; if(excluded.length>3000)fail(400,'排除词表过长'); values.push(excluded); clauses.push('c."generalId"::text <> ALL($' + values.length + '::text[])'); }
- if (publicOnly && !modelId) { values.push([...PRIVATE_CONTENT_MODELS].map(String)); clauses.push('CAST(c."modelId" AS text) <> ALL($' + values.length + '::text[])'); }
- const filters = legacyFilterPairs(input); if (filters.length && !config) fail(501, '该内容模型的 addon 联表尚未映射');
- for (const filter of filters) { const field = addonField(config, filter.name); if (!field) fail(501, 'addon 字段尚未映射: ' + filter.name); values.push(String(filter.value)); clauses.push('CAST(a."' + field + '" AS text) = $' + values.length); }
- if (input.skey) { values.push('%' + String(input.skey).replace(/[%_]/g, '') + '%'); clauses.push('c."title" ILIKE $' + values.length); }
- const join = config ? ' LEFT JOIN "' + config.className + '" a ON a."company" = $1 AND CAST(a."id" AS text) = CAST(c."itemId" AS text)' : ''; const where = clauses.join(' AND ');
- const countRow = await Psql.one('SELECT COUNT(*)::int AS total FROM "CommonModel" c' + join + ' WHERE ' + where, values); const rowValues = values.concat([paging.size, (paging.index - 1) * paging.size]);
- const select = config ? 'c.*, row_to_json(a) AS "__addon"' : 'c.*'; const rows = await Psql.query('SELECT ' + select + ' FROM "CommonModel" c' + join + ' WHERE ' + where + ' ORDER BY ' + contentOrder(input, config) + ' LIMIT $' + (values.length + 1) + ' OFFSET $' + (values.length + 2), rowValues);
- const normalized = rows.filter(isVisible).map((source) => { const addon = source.__addon || {}; const row = { ...source, ...addon }; delete row.__addon; if (source.objectId) row.objectId = source.objectId;if(modelId===58)row.bindingId=addon.objectId; return legacyAliases(row, 'CommonModel'); }); const total = number(countRow.total);
- return { rows: normalized, page: { itemCount: total, pageCount: Math.ceil(total / paging.size), pageIndex: paging.index, pageSize: paging.size } };
- }
|