taxonomy.js 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. /* taxonomy.js —— 阶段、层、优先级、证据强度的枚举与展示规则。
  2. * 需求变化时只需要动这里;页面其余部分都从这里读标签与排序。 */
  3. (function () {
  4. "use strict";
  5. /* 五个阶段。stage 字段无论存 "S1品类分析" 还是 "1"/"S1",都归一到这里 */
  6. const STAGES = [
  7. { code: "S1", no: 1, name: "品类市场分析", label: "S1 品类市场分析" },
  8. { code: "S2", no: 2, name: "用户需求与痛点", label: "S2 用户需求与痛点" },
  9. { code: "S3", no: 3, name: "机会点识别", label: "S3 机会点识别" },
  10. { code: "S4", no: 4, name: "机会验证评估", label: "S4 机会验证评估" },
  11. { code: "S5", no: 5, name: "场景与卖点设计", label: "S5 场景与卖点设计" }
  12. ];
  13. /* 四层。同一库,靠 layer 字段区分 */
  14. const LAYERS = [
  15. { key: "raw", label: "原材料", en: "raw", desc: "调研整理的事实,必须带出处" },
  16. { key: "process", label: "过程", en: "process", desc: "学员与分身产生的成果,观点,质量参差" },
  17. { key: "sediment", label: "沉淀", en: "sediment", desc: "归纳后够格回灌的见解,已校准" },
  18. { key: "record", label: "记录", en: "record", desc: "不合格/纯推测/重复的,只留档不进知识" }
  19. ];
  20. const PRIORITIES = ["S", "A", "B"];
  21. /* 证据强度:verified 必须有真实原文;没有原文的成果在页面上会显示"证据未对齐" */
  22. const EVIDENCE = [
  23. { key: "verified", label: "有原文", rank: 3 },
  24. { key: "supported", label: "有佐证", rank: 2 },
  25. { key: "speculative", label: "模型推测", rank: 1 },
  26. { key: "none", label: "无证据", rank: 0 }
  27. ];
  28. const STATUS = {
  29. active: "进行中",
  30. submitted: "已提交",
  31. draft: "草稿",
  32. parked: "已搁置"
  33. };
  34. /* 机会卡:池子里的生命周期。状态只认这三种,其余历史值归为 candidate 并在 UI 标出 */
  35. const OPP_STATUS = [
  36. { key: "candidate", label: "候选", desc: "在池子里,等待评分与决策" },
  37. { key: "approved", label: "已立项", desc: "已拍板进入下一步,进入研发储备" },
  38. { key: "rejected", label: "已否决", desc: "留档,不进储备;理由必须写" }
  39. ];
  40. const OPP_STATUS_KEYS = OPP_STATUS.map((s) => s.key);
  41. /* 决策类型:卡片底部那行「决策:…」 */
  42. const DECISIONS = {
  43. concept: "进入概念验证",
  44. approve: "立项",
  45. reject: "否决",
  46. hold: "暂缓",
  47. merge: "并入其他机会"
  48. };
  49. /* 上传方式:客户要看「哪个 Agent 用什么方式上传的」 */
  50. const UPLOAD_METHODS = {
  51. session: "会话上传",
  52. skill: "Skill 上传",
  53. manual: "手工录入"
  54. };
  55. /* 证据强度(机会卡自己的三档,与成果的 evidences 不是一套:卡上回答"这个判断站不站得住") */
  56. const OPP_EVIDENCE = [
  57. { key: "high", label: "高", rank: 3 },
  58. { key: "medium", label: "中", rank: 2 },
  59. { key: "low", label: "低", rank: 1 },
  60. { key: "none", label: "待补", rank: 0 }
  61. ];
  62. /* 成果类型:只做展示名,不做业务定义 */
  63. const ARTIFACT_TYPES = {
  64. opportunity_card: "机会卡",
  65. pain_list: "痛点清单",
  66. competitor_report: "竞品报告",
  67. voc_report: "VOC 报告",
  68. concept: "概念提案"
  69. };
  70. const SOURCE_TYPES = {
  71. category: "品类",
  72. competitor: "竞品",
  73. process: "工艺",
  74. audience: "人群",
  75. opportunity: "机会",
  76. probe: "探针"
  77. };
  78. function stageOf(value) {
  79. if (value == null || value === "") return null;
  80. const s = String(value).toUpperCase();
  81. return STAGES.find((x) => s.startsWith(x.code)) || null;
  82. }
  83. const stageLabel = (v) => (stageOf(v) ? stageOf(v).label : v || "—");
  84. const layerOf = (key) => LAYERS.find((l) => l.key === key) || null;
  85. function evidenceOf(level, hasQuotes) {
  86. if (level === "verified" && hasQuotes) return EVIDENCE[0];
  87. if (level === "verified" || level === "supported") return EVIDENCE[1];
  88. if (level === "speculative") return EVIDENCE[2];
  89. return EVIDENCE[3];
  90. }
  91. window.KF_TAXONOMY = {
  92. STAGES, LAYERS, PRIORITIES, EVIDENCE, STATUS, ARTIFACT_TYPES, SOURCE_TYPES,
  93. OPP_STATUS, OPP_STATUS_KEYS, DECISIONS, UPLOAD_METHODS, OPP_EVIDENCE,
  94. oppStatusOf: (k) => OPP_STATUS.find((s) => s.key === k) || null,
  95. oppEvidenceOf: (k) => OPP_EVIDENCE.find((e) => e.key === k) || OPP_EVIDENCE[3],
  96. stageOf, stageLabel, layerOf, evidenceOf
  97. };
  98. })();