/* views/artifacts.js —— 成果列表:四层归属、出身、证据、筛选叠加、排序。 * 既用于"成果"页,也被"记录层"页复用(固定 layer=record)。 */ (function () { "use strict"; const T = window.KF_TAXONOMY; const U = window.KF_UTIL; const Q = window.KF_QUERY; const UI = window.KF_UI; const esc = U.esc; function rowOf(a, ctx) { const p = ctx.db.projectById[a.projectId]; return { ...a, priority: p ? p.priority : "", category: p ? p.category : "", projectTitle: p ? p.title : "", evidenceKey: a.evidenceLevel }; } function rowsFor(db, filterLayer) { const base = filterLayer ? db.artifacts.filter((a) => a.layer === filterLayer) : db.artifacts; const ctx = { db }; return base.map((a) => rowOf(a, ctx)); } /* 排序:数字/日期维度按方向,文本维度固定方向 */ const SORTS = { newest: { label: "最新提交", fn: (a, b) => new Date(b.createdAt) - new Date(a.createdAt) }, evidence: { label: "证据强度", fn: (a, b) => b.evidenceRank - a.evidenceRank || new Date(b.createdAt) - new Date(a.createdAt) }, owner: { label: "按成员", fn: (a, b) => a.ownerName.localeCompare(b.ownerName, "zh") }, stage: { label: "按阶段", fn: (a, b) => (b.stageObj ? b.stageObj.no : 0) - (a.stageObj ? a.stageObj.no : 0) } }; function buildFacets(db, rows, c, opts) { const P = T.PRIORITIES; const dims = []; if (!opts.priorityLocked) { const pc = Q.facetCounts(rows, c, "priority", (r) => r.priority); dims.push({ key: "priority", label: "优先级", options: P.map((v) => ({ value: v, label: v, count: pc.get(v) || 0 })) }); } const sc = Q.facetCounts(rows, c, "stage", (r) => (r.stageObj ? r.stageObj.code : null)); dims.push({ key: "stage", label: "阶段", options: T.STAGES.map((s) => ({ value: s.code, label: s.code, count: sc.get(s.code) || 0 })) }); const cats = [...new Set(rows.map((r) => r.category).filter(Boolean))].sort((a, b) => a.localeCompare(b, "zh")); const cc = Q.facetCounts(rows, c, "category", (r) => r.category); dims.push({ key: "category", label: "品类", options: cats.map((v) => ({ value: v, label: v, count: cc.get(v) || 0 })) }); const ec = Q.facetCounts(rows, c, "evidence", (r) => r.evidenceKey); dims.push({ key: "evidence", label: "证据", options: T.EVIDENCE.slice(0, 3).map((e) => ({ value: e.key, label: e.label, count: ec.get(e.key) || 0 })) }); if (!opts.layerLocked) { const lc = Q.facetCounts(rows, c, "layer", (r) => r.layer); dims.push({ key: "layer", label: "层", multi: true, options: T.LAYERS.map((l) => ({ value: l.key, label: l.en, count: lc.get(l.key) || 0 })) }); } const mc = Q.facetCounts(rows, c, "member", (r) => r.ownerName); const members = [...mc.entries()].sort((a, b) => b[1] - a[1] || a[0].localeCompare(b[0], "zh")); dims.push({ key: "member", label: "成员", multi: true, options: members.map(([v, n]) => ({ value: v, label: v, count: n })) }); /* 每个维度的当前选中值,供筛选条回显 */ dims.forEach((d) => { d.active = c[d.key] || []; }); return dims; } /* 单行。带报告的成果在标题上直接给入口——不点进抽屉也能翻开读 */ function row(r) { const ttl = r.report ? `${esc(r.shortTitle)}` : `${esc(r.title)}`; return `
| 成果 | 成员 | ${th("stage", "阶段")}优先级 | 层 | ${th("evidence", "证据")}${th("newest", "提交时间")}
|---|
${opts.lede}