feat: 范式规则支持 scope 粒度区分

1. 为范式规则添加 scope 字段:paragraph(段落级)/ document(全文级)
2. 对照检查新增模式切换:逐段检查 / 全文检查
3. 根据检查模式过滤适用规则
4. 规则展示区显示粒度标签(段/文)
5. 当前模式规则高亮,非当前模式规则灰显
This commit is contained in:
empty
2026-01-08 16:33:17 +08:00
parent bf79eb59a5
commit a0faaf4157
2 changed files with 65 additions and 23 deletions

View File

@@ -18,10 +18,21 @@
<!-- 范式上下文提示条 -->
<div v-if="hasParadigmRules" class="px-4 py-2 bg-indigo-900/30 border-b border-indigo-700/50 flex items-center justify-between shrink-0">
<div class="flex items-center gap-2">
<div class="flex items-center gap-3">
<span class="text-indigo-400 text-sm">📚 当前写作范式</span>
<span class="text-white text-sm font-medium">{{ activeParadigmName }}</span>
<span class="text-xs text-indigo-300/70">{{ paradigmRulesCount }} 条专家规则将自动纳入对照依据</span>
<!-- 检查模式切换 -->
<div class="flex bg-slate-900/50 rounded p-0.5 border border-indigo-700/50">
<button
@click="checkMode = 'paragraph'"
:class="['text-xs px-2 py-0.5 rounded transition', checkMode === 'paragraph' ? 'bg-indigo-600 text-white' : 'text-indigo-300 hover:text-white']"
>逐段检查</button>
<button
@click="checkMode = 'document'"
:class="['text-xs px-2 py-0.5 rounded transition', checkMode === 'document' ? 'bg-indigo-600 text-white' : 'text-indigo-300 hover:text-white']"
>全文检查</button>
</div>
<span class="text-xs text-indigo-300/70">{{ currentScopeRulesCount }} {{ checkMode === 'paragraph' ? '段落级' : '全文级' }}规则生效</span>
</div>
<button
@click="showParadigmRules = !showParadigmRules"
@@ -34,8 +45,14 @@
<!-- 范式规则展开区 -->
<div v-if="showParadigmRules && hasParadigmRules" class="px-4 py-3 bg-indigo-950/50 border-b border-indigo-800/30 max-h-48 overflow-y-auto shrink-0">
<div class="grid grid-cols-2 gap-2">
<div v-for="(rule, idx) in paradigmRulesList" :key="idx" class="text-xs text-indigo-200/80 bg-indigo-900/30 px-2 py-1 rounded">
{{ rule }}
<div v-for="(rule, idx) in getFilteredRules(null)" :key="idx"
:class="['text-xs px-2 py-1 rounded flex items-start gap-1',
rule.scope === checkMode ? 'bg-indigo-800/50 text-indigo-100' : 'bg-slate-800/50 text-slate-400'
]">
<span :class="['shrink-0 px-1 rounded text-[10px]',
rule.scope === 'paragraph' ? 'bg-amber-600/50 text-amber-200' : 'bg-blue-600/50 text-blue-200'
]">{{ rule.scope === 'paragraph' ? '段' : '文' }}</span>
<span>{{ rule.text }}</span>
</div>
</div>
</div>
@@ -238,6 +255,7 @@ const checkResults = ref({})
// 范式相关
const showParadigmRules = ref(false)
const checkMode = ref('paragraph') // 'paragraph' | 'document'
const hasParadigmRules = computed(() => {
const p = activeParadigm.value
@@ -248,42 +266,46 @@ const activeParadigmName = computed(() => {
return activeParadigm.value?.name || ''
})
// 提取范式规则列表
const paradigmRulesList = computed(() => {
// 提取范式规则列表(根据 scope 过滤)
const getFilteredRules = (scope) => {
const paradigm = activeParadigm.value
if (!paradigm) return []
const rules = []
if (paradigm.expertGuidelines) {
paradigm.expertGuidelines.forEach(g => {
rules.push(`${g.title}${g.description}`)
})
paradigm.expertGuidelines
.filter(g => !scope || g.scope === scope || !g.scope) // 无 scope 的规则默认都包含
.forEach(g => {
rules.push({ text: `${g.title}${g.description}`, scope: g.scope || 'both' })
})
}
if (paradigm.systemConstraints) {
// systemConstraints 默认为全文级
if (paradigm.systemConstraints && (scope === 'document' || !scope)) {
paradigm.systemConstraints.forEach(c => {
rules.push(c)
})
}
if (paradigm.validationRules) {
Object.values(paradigm.validationRules).forEach(rule => {
if (rule.name && rule.failMessage) {
rules.push(`${rule.name}${rule.failMessage}`)
}
rules.push({ text: c, scope: 'document' })
})
}
return rules
})
}
// 当前模式下的规则列表
const paradigmRulesList = computed(() => getFilteredRules(null).map(r => r.text))
const paragraphRules = computed(() => getFilteredRules('paragraph'))
const documentRules = computed(() => getFilteredRules('document'))
const paradigmRulesCount = computed(() => paradigmRulesList.value.length)
const currentScopeRulesCount = computed(() =>
checkMode.value === 'paragraph' ? paragraphRules.value.length : documentRules.value.length
)
// 获取范式规则文本(用于 Prompt 构建
// 获取范式规则文本(根据当前检查模式过滤
const getParadigmRulesText = () => {
if (paradigmRulesList.value.length === 0) return ''
return paradigmRulesList.value.join('\n')
const rules = checkMode.value === 'paragraph' ? paragraphRules.value : documentRules.value
if (rules.length === 0) return ''
return rules.map(r => r.text).join('\n')
}
// 解析段落