新增: 父⑤⑤.2收尾(评分拆const+表单补全+css陷阱) + priority跨层映射修复

父⑤⑤.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 清零。
This commit is contained in:
2026-06-26 23:53:51 +08:00
parent 40b74e11bf
commit 744b68da5b
7 changed files with 83 additions and 21 deletions

View File

@@ -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',

View File

@@ -112,8 +112,17 @@ export default {
captureTitle: '✨ 捕捉新灵感',
fieldTitle: '标题',
fieldDesc: '描述',
fieldTags: '标签',
fieldPriority: '优先级',
fieldSource: '来源',
titlePlaceholder: '一句话描述你的灵感...',
descPlaceholder: '详细说明(可选)...',
tagsPlaceholder: '用逗号分隔,如: 工具,效率,自动化',
sourcePlaceholder: '来源(可选,如:用户反馈、竞品分析)',
priorityCritical: '紧急',
priorityHigh: '高',
priorityMedium: '中',
priorityLow: '低',
// 深链不存在提示
notFound: '灵感不存在或已删除',

View File

@@ -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)

View File

@@ -112,6 +112,17 @@
<input v-model="newIdeaTitle" :placeholder="$t('ideas.titlePlaceholder')" @keyup.enter="confirmCapture" />
<label style="font-size:12px;color:var(--df-text-secondary);margin-bottom:4px;display:block">{{ $t('ideas.fieldDesc') }}</label>
<textarea v-model="newIdeaDesc" :placeholder="$t('ideas.descPlaceholder')" rows="3" style="resize:vertical"></textarea>
<label style="font-size:12px;color:var(--df-text-secondary);margin-bottom:4px;display:block">{{ $t('ideas.fieldTags') }}</label>
<input v-model="newIdeaTags" :placeholder="$t('ideas.tagsPlaceholder')" />
<label style="font-size:12px;color:var(--df-text-secondary);margin-bottom:4px;display:block">{{ $t('ideas.fieldPriority') }}</label>
<select v-model.number="newIdeaPriority" class="modal-select">
<option :value="0">{{ $t('ideas.priorityCritical') }} (P0)</option>
<option :value="1">{{ $t('ideas.priorityHigh') }} (P1)</option>
<option :value="2">{{ $t('ideas.priorityMedium') }} (P2)</option>
<option :value="3">{{ $t('ideas.priorityLow') }} (P3)</option>
</select>
<label style="font-size:12px;color:var(--df-text-secondary);margin-bottom:4px;display:block">{{ $t('ideas.fieldSource') }}</label>
<input v-model="newIdeaSource" :placeholder="$t('ideas.sourcePlaceholder')" />
<div class="modal-actions">
<button class="btn-cancel" @click="showCaptureModal = false">{{ $t('common.cancel') }}</button>
<button class="btn-confirm" :disabled="creating" @click="confirmCapture">
@@ -164,6 +175,9 @@ const pageSize = ref(0)
const showCaptureModal = ref(false)
const newIdeaTitle = ref('')
const newIdeaDesc = ref('')
const newIdeaTags = ref('') // 逗号分隔输入(对标 KnowledgeDetail.vue tagsInput)
const newIdeaPriority = ref(2) // 默认 medium,对标 CreateIdeaInput 0-3
const newIdeaSource = ref('')
// ── 异步按钮禁用态(防双击重复提交,对齐 ProviderPanel.vue saving ref) ──
const creating = ref(false)
@@ -274,6 +288,9 @@ function scoreClass(score: number | null) {
function openCaptureModal() {
newIdeaTitle.value = ''
newIdeaDesc.value = ''
newIdeaTags.value = ''
newIdeaPriority.value = 2
newIdeaSource.value = ''
showCaptureModal.value = true
}
@@ -281,9 +298,14 @@ async function confirmCapture() {
if (!newIdeaTitle.value.trim() || creating.value) return
creating.value = true
try {
// tags 逗号分隔 → JSON 字符串(对标 KnowledgeDetail.vue saveEdit split+trim+filter 模式)
const tags = newIdeaTags.value.split(',').map(t => t.trim()).filter(Boolean)
await store.createIdea({
title: newIdeaTitle.value.trim(),
description: newIdeaDesc.value.trim() || undefined,
priority: newIdeaPriority.value,
tags: JSON.stringify(tags),
source: newIdeaSource.value.trim() || undefined,
})
showCaptureModal.value = false
} finally {
@@ -566,6 +588,7 @@ watch(() => route.params.id, (id) => {
.modal-box { background: var(--df-bg-card); border: 0.5px solid var(--df-border); border-radius: var(--df-radius-lg); padding: 24px; min-width: 360px; max-width: 90vw; }
.modal-box h3 { color: var(--df-text); margin-bottom: var(--df-gap-head); }
.modal-box input, .modal-box textarea { width: 100%; padding: 8px 12px; border: 0.5px solid var(--df-border); border-radius: var(--df-radius-sm); background: var(--df-bg); color: var(--df-text); font-size: 13px; margin-bottom: 12px; box-sizing: border-box; font-family: inherit; }
.modal-box .modal-select { width: 100%; padding: 8px 12px; border: 0.5px solid var(--df-border); border-radius: var(--df-radius-sm); background: var(--df-bg); color: var(--df-text); font-size: 13px; margin-bottom: 12px; box-sizing: border-box; font-family: inherit; }
.modal-box .modal-actions { display: flex; gap: 8px; justify-content: flex-end; }
.modal-box .btn-cancel { padding: 6px 16px; border: 0.5px solid var(--df-border); border-radius: var(--df-radius-sm); background: transparent; color: var(--df-text-secondary); cursor: pointer; }
.modal-box .btn-confirm { padding: 6px 16px; border: none; border-radius: var(--df-radius-sm); background: var(--df-accent); color: #fff; cursor: pointer; }