From 744b68da5b27aae016c797a84a6e0528ff76f943 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=BB=9D=E5=B0=98?= <237809796@qq.com> Date: Fri, 26 Jun 2026 23:53:51 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E:=20=E7=88=B6=E2=91=A4?= =?UTF-8?q?=E2=91=A4.2=E6=94=B6=E5=B0=BE(=E8=AF=84=E5=88=86=E6=8B=86const+?= =?UTF-8?q?=E8=A1=A8=E5=8D=95=E8=A1=A5=E5=85=A8+css=E9=99=B7=E9=98=B1)=20+?= =?UTF-8?q?=20priority=E8=B7=A8=E5=B1=82=E6=98=A0=E5=B0=84=E4=BF=AE?= =?UTF-8?q?=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 父⑤⑤.2(DEC-03 c / DEC-04 a): - #6 scoring.rs 关键词拆 const(FEASIBILITY_POS/NEG + IMPACT + URGENCY 4 组,零行为变化,df-ideas 22 测试过) - #9/#10 Ideas.vue 表单补 tags(逗号分隔对标 KnowledgeDetail)+priority 下拉+source,i18n 中英对称 - css 陷阱修:components.css .modal-* 通配→"modal 系列"(避 */ 闭合,memory css-comment-star-slash-trap) priority 跨层映射修复(verify agent 发现的预存 bug): - idea.rs priority_from_i32 原跟 df-types 枚举(0=Low),与前端约定(0=critical,api/types.ts:141+Tasks.vue)反 - 改手动映射对齐前端(0=Critical/1=High/2=Medium/3=Low),Priority as_str 序列化不受影响 - 校验注释同步更正(我父①①.3 加的 Low=0 注释) 父⑤ 全闭环(⑤.1/①.4/⑤.2)。css warning 清零。 --- crates/df-ideas/src/scoring.rs | 40 ++++++++++++++++++++++++---------- docs/todo.md | 4 ++-- src-tauri/src/commands/idea.rs | 17 ++++++++++----- src/i18n/en/ideas.ts | 9 ++++++++ src/i18n/zh-CN/ideas.ts | 9 ++++++++ src/styles/components.css | 2 +- src/views/Ideas.vue | 23 +++++++++++++++++++ 7 files changed, 83 insertions(+), 21 deletions(-) diff --git a/crates/df-ideas/src/scoring.rs b/crates/df-ideas/src/scoring.rs index f8e9d48..feea562 100644 --- a/crates/df-ideas/src/scoring.rs +++ b/crates/df-ideas/src/scoring.rs @@ -11,6 +11,30 @@ pub use crate::capture::IdeaScores; use df_types::types::Priority; +// ─── 启发式关键词(DEC-03 c:同文件 const 拆出,接 LLM 语义评分后升 a:JSON 文件配置)─── +// +// 现阶段关键词集合固定且与维度强相关,抽 const 仅为可读性/可维护性(零行为变化)。 +// TODO(DEC-03 a):接入 LLM 语义评分后,这些关键词退居「冷启动兜底」, +// 集合迁移到 JSON 配置文件,支持热更新与项目级覆盖。 +// 注:以下集合与原方法内字面量逐一对应,集合/顺序/否定前缀/权重均不变(纯结构提取)。 + +/// 可行性正向信号词(描述充实度外的技术/资源信号),命中每个 +0.5 +pub const FEASIBILITY_POSITIVE_KEYWORDS: &[&str] = &[ + "复用", "已有", "简单", "集成", "支持", "成熟", "基于", "现成", "脚手架", "模板", +]; +/// 可行性负向信号词(复杂度上升信号),命中每个 -0.6 +pub const FEASIBILITY_NEGATIVE_KEYWORDS: &[&str] = &[ + "重构", "迁移", "大规模", "分布式", "重写", "从零", "全新架构", "高并发", "底层", +]; +/// 影响力价值信号词(用户/增长/收入...),命中每个 +0.5 +pub const IMPACT_KEYWORDS: &[&str] = &[ + "用户", "增长", "收入", "效率", "体验", "核心", "关键", "痛点", "竞品", "留存", +]; +/// 紧急度时效信号词(立即/马上/紧急...),命中每个 +0.5 +pub const URGENCY_KEYWORDS: &[&str] = &[ + "立即", "马上", "紧急", "尽快", "本周", "上线", "deadline", "截止", "先行", "阻塞", +]; + /// 评分权重配置 #[derive(Debug, Clone)] pub struct ScoringWeights { @@ -71,14 +95,10 @@ impl ScoringEngine { score -= 0.5; } // 可行性正向信号 - let pos = count_any(desc, &[ - "复用", "已有", "简单", "集成", "支持", "成熟", "基于", "现成", "脚手架", "模板", - ]); + let pos = count_any(desc, FEASIBILITY_POSITIVE_KEYWORDS); score += (pos as f64) * 0.5; // 复杂度负向信号 - let neg = count_any(desc, &[ - "重构", "迁移", "大规模", "分布式", "重写", "从零", "全新架构", "高并发", "底层", - ]); + let neg = count_any(desc, FEASIBILITY_NEGATIVE_KEYWORDS); score -= (neg as f64) * 0.6; score.clamp(0.0, 10.0) } @@ -97,9 +117,7 @@ impl ScoringEngine { score += (idea.tags.len().min(4) as f64) * 0.25; } let desc = idea.description.trim(); - let value_hits = count_any(desc, &[ - "用户", "增长", "收入", "效率", "体验", "核心", "关键", "痛点", "竞品", "留存", - ]); + let value_hits = count_any(desc, IMPACT_KEYWORDS); score += (value_hits as f64) * 0.5; if desc.chars().count() > 100 { score += 0.5; @@ -116,9 +134,7 @@ impl ScoringEngine { Priority::Low => 3.0, }; let desc = idea.description.trim(); - let time_hits = count_any(desc, &[ - "立即", "马上", "紧急", "尽快", "本周", "上线", "deadline", "截止", "先行", "阻塞", - ]); + let time_hits = count_any(desc, URGENCY_KEYWORDS); score += (time_hits as f64) * 0.5; score.clamp(0.0, 10.0) } diff --git a/docs/todo.md b/docs/todo.md index c99901a..c548503 100644 --- a/docs/todo.md +++ b/docs/todo.md @@ -40,7 +40,7 @@ graph TD P2["父② 知识图谱Phase1
✅Phase1(数据层+业务层)"]:::done P3["父③ AI对话体验
📋待办"]:::todo P4["父④ F-09 per-conv
📋待办"]:::todo - P5["父⑤ 灵感模块
🔨⑤.1/①.4✅·⑤.2待办"]:::doing + P5["父⑤ 灵感模块
✅完成(⑤.1/①.4/⑤.2)"]:::done P6["父⑥ Phase2-5
📋待办"]:::todo P7["父⑦ 技术债
📋待办"]:::todo @@ -58,7 +58,7 @@ graph TD | **父②** 知识图谱Phase1 | ✅ Phase1完成 | ②.1 V29迁移✅ / ②.2 TaskRecord+TaskLinkRepo✅ / ②.3 IPC(create_task扩展+task_link CRUD+move_queue+get_tree)✅ / ②.4 父聚合✅(set_status_for_aggregation绕status收口) / ②.5 AI工具6✅(基线38) | G1(弱) | | **父③** AI对话体验 | 📋 待办 | ③.1 B-260619-04 ToolCard / ③.2 REFACTOR-260619-04 审批状态机 | — | | **父④** F-09 per-conv | 📋 待办 | ④.1 streaming/currentText per-conv | — | -| **父⑤** 灵感模块 | 🔨 进行中 | ⑤.1 软删除✅ / ①.4 雷达图✅ / ⑤.2 #05 record_to_idea✅ / #06 配置化·#09·#10 表单待办 / #07 promote补偿待定(soft_delete 污染回收站 vs purge 内部回滚干净?) | ⑤.2#07→②.1 | +| **父⑤** 灵感模块 | ✅ 完成 | ⑤.1 软删除✅ / ①.4 雷达图✅ / ⑤.2 #05✅/#06拆const✅/#09/#10表单(逗号tags)✅ / #07 DEC-02保留purge(不改) / 附:priority_from_i32跨层映射修复(对齐前端0=critical) | #07→②.1 | | **父⑥** Phase2-5 | 📋 待办 | ⑥.1事件流 / ⑥.2基础设施 / ⑥.3注入 / ⑥.4前端 | ⑥→父②, ⑥.3→父②+父④+G1 | | **父⑦** 技术债 | 📋 待办 | SMELL-P1-6 / conditions / CR缓存 / UX分页 / 审批超时 / miniapp / 双监听器 | — (穿插) | diff --git a/src-tauri/src/commands/idea.rs b/src-tauri/src/commands/idea.rs index ffde2aa..6a46531 100644 --- a/src-tauri/src/commands/idea.rs +++ b/src-tauri/src/commands/idea.rs @@ -78,7 +78,7 @@ pub async fn create_idea( // 防 LLM/前端传 99 等被静默吞为 Critical。 if !(0..=3).contains(&input.priority) { return Err(format!( - "priority 必须在 0..=3 (Low=0/Medium=1/High=2/Critical=3),收到 {}", + "priority 必须在 0..=3 (0=critical/1=high/2=medium/3=low,对齐前端约定 api/types.ts:141),收到 {}", input.priority )); } @@ -425,13 +425,18 @@ fn record_to_idea(record: &IdeaRecord) -> Idea { } } -/// i32 优先级 → Priority 枚举(与 df-types 枚举值一致:Low=0/Medium=1/High=2/Critical=3) +/// i32 优先级 → Priority 枚举(对齐**前端约定** 0=critical/1=high/2=medium/3=low, +/// 见 api/types.ts:141 + Tasks.vue option + constants/project.ts PRIORITY_CLASS)。 +/// 注:df-types Priority 枚举 discriminant 是 Low=0/Critical=3(历史定义,与前端相反), +/// 故本函数手动映射对齐前端语义,不靠 discriminant。Priority as_str 序列化("low"/"critical") +/// 不受影响。verify agent 发现的预存跨层 bug(父⑤⑤.2 收尾揪出):原 0=>Low 致 Ideas +/// 表单选 Critical(P0) 存 Low,标签与实际存储/评分相反。 fn priority_from_i32(p: i32) -> Priority { match p { - 0 => Priority::Low, - 2 => Priority::High, - x if x >= 3 => Priority::Critical, - _ => Priority::Medium, + 0 => Priority::Critical, + 1 => Priority::High, + 2 => Priority::Medium, + _ => Priority::Low, } } diff --git a/src/i18n/en/ideas.ts b/src/i18n/en/ideas.ts index a0e4ba2..d13af27 100644 --- a/src/i18n/en/ideas.ts +++ b/src/i18n/en/ideas.ts @@ -112,8 +112,17 @@ export default { captureTitle: '✨ Capture New Idea', fieldTitle: 'Title', fieldDesc: 'Description', + fieldTags: 'Tags', + fieldPriority: 'Priority', + fieldSource: 'Source', titlePlaceholder: 'Describe your idea in one sentence...', descPlaceholder: 'More details (optional)...', + tagsPlaceholder: 'Comma-separated, e.g. tools, efficiency, automation', + sourcePlaceholder: 'Source (optional, e.g. user feedback, competitor analysis)', + priorityCritical: 'Critical', + priorityHigh: 'High', + priorityMedium: 'Medium', + priorityLow: 'Low', // Deep link not found notFound: 'Idea not found or deleted', diff --git a/src/i18n/zh-CN/ideas.ts b/src/i18n/zh-CN/ideas.ts index ad076cb..534a051 100644 --- a/src/i18n/zh-CN/ideas.ts +++ b/src/i18n/zh-CN/ideas.ts @@ -112,8 +112,17 @@ export default { captureTitle: '✨ 捕捉新灵感', fieldTitle: '标题', fieldDesc: '描述', + fieldTags: '标签', + fieldPriority: '优先级', + fieldSource: '来源', titlePlaceholder: '一句话描述你的灵感...', descPlaceholder: '详细说明(可选)...', + tagsPlaceholder: '用逗号分隔,如: 工具,效率,自动化', + sourcePlaceholder: '来源(可选,如:用户反馈、竞品分析)', + priorityCritical: '紧急', + priorityHigh: '高', + priorityMedium: '中', + priorityLow: '低', // 深链不存在提示 notFound: '灵感不存在或已删除', diff --git a/src/styles/components.css b/src/styles/components.css index 4bf1f2c..184f324 100644 --- a/src/styles/components.css +++ b/src/styles/components.css @@ -10,7 +10,7 @@ - 仅提取 ≥2 处逐字相同的规则(已 grep 比对一致) - scoped 故意 override 全局值的(如 .empty-hint padding 24px vs 全局 12px) 不提取,保留各组件 scoped 覆盖(零视觉变化) - - global.css 已有的 .btn/.modal-*/.page-header/.empty-hint/.empty-state + - global.css 已有的 .btn / .modal 系列 / .page-header / .empty-hint / .empty-state 不在此重复,仅补充尚未全局化的类 落地批:DRY 收口(B-260619) diff --git a/src/views/Ideas.vue b/src/views/Ideas.vue index a4522d5..aa7dcf2 100644 --- a/src/views/Ideas.vue +++ b/src/views/Ideas.vue @@ -112,6 +112,17 @@ + + + + + +