From 60be96bfaa249b20cd02807025104d1a36fb90a2 Mon Sep 17 00:00:00 2001 From: Hermes CI Fix Date: Wed, 26 Aug 2026 00:24:55 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20CMA=E7=9F=A5=E8=AF=86=E5=BA=93=E5=8A=A8?= =?UTF-8?q?=E6=80=81=E5=8A=A0=E8=BD=BD=20=E2=80=94=20=E5=89=8D=E7=AB=AF?= =?UTF-8?q?=E4=BB=8Eknowledge-articles=20API=E8=AF=BB=E5=8F=96(CMA?= =?UTF-8?q?=E6=A1=88=E4=BE=8B/=E7=A8=8E=E5=8A=A1=E5=90=88=E8=A7=84/?= =?UTF-8?q?=E6=96=B9=E6=B3=95=E8=AE=BA=E7=AD=8931=E7=AF=87=E5=8F=AF?= =?UTF-8?q?=E8=A7=81)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/views/CMAKnowledge.vue | 62 +++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/frontend/src/views/CMAKnowledge.vue b/frontend/src/views/CMAKnowledge.vue index b263704e..dfdce000 100644 --- a/frontend/src/views/CMAKnowledge.vue +++ b/frontend/src/views/CMAKnowledge.vue @@ -165,6 +165,7 @@ import { ref, computed } from "vue" import { ElMessage } from "element-plus" import { ethicsQuizApi } from "../api/index" +import api from "../api/index" // ── Tab ── const activeTab = ref("knowledge") @@ -475,6 +476,67 @@ const searchResults = computed(() => { return results }) +// ── 动态知识库:从API加载(2026-08-26新增,支持CMA案例/税务合规/方法论等) ── +const dynamicLoaded = ref(false) +const CAT_LABELS: Record = { + term: "术语解释", formula: "公式", practice: "实践", faq: "FAQ", + "CMA完整文档": "CMA完整文档", "管理会计方法": "管理会计方法", KPI设定: "KPI设定", + OKR: "OKR", "战略修正": "战略修正", 方法论: "方法论", "税务合规": "税务合规", + "CMA案例": "CMA案例", +} +const CAT_ICONS: Record = { + term: "📖", formula: "🧮", practice: "🛠️", faq: "❓", + "CMA完整文档": "📚", "管理会计方法": "📐", KPI设定: "🎯", + OKR: "⭕", "战略修正": "🎯", 方法论: "📊", "税务合规": "🧾", + "CMA案例": "📖", +} + +async function loadDynamicArticles() { + if (dynamicLoaded.value) return + try { + const r: any = await api.get('/knowledge-articles') + const list = Array.isArray(r.data) ? r.data : (r.data?.data || r.data?.items || []) + if (!Array.isArray(list) || list.length === 0) return + // 排除静态已有的基础分类(term/formula/practice/faq 保留静态内容) + const dynamic = list.filter((a: any) => !["term", "formula", "practice", "faq"].includes(a.category)) + if (dynamic.length === 0) return + // 按分类聚合 + const grouped: Record = {} + for (const a of dynamic) { + const key = a.category || "其他" + if (!grouped[key]) grouped[key] = [] + grouped[key].push({ + title: a.title, + summary: a.summary || "", + content: a.content || "", + id: a.id, + }) + } + // 合并到categories(已有分类追加,新分类新增) + const existingKeys = new Set(categories.value.map((c: any) => c.key)) + for (const [key, items] of Object.entries(grouped)) { + const existing = categories.value.find((c: any) => c.key === key) + if (existing) { + existing.items.push(...items) + } else { + categories.value.push({ + name: CAT_LABELS[key] || key, + icon: CAT_ICONS[key] || "📄", + key, + items, + }) + } + } + dynamicLoaded.value = true + } catch (e) { + console.error("加载动态知识库失败", e) + } +} + +// 页面加载时拉取动态知识库 +import { onMounted } from "vue" +onMounted(() => { loadDynamicArticles() }) + function catLabel(key: string) { const map: Record = { term: "术语", formula: "公式", practice: "实践", faq: "FAQ" } return map[key] || key