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')
}
// 解析段落

View File

@@ -201,36 +201,56 @@ export const PARADIGMS = {
},
// 专家指令(质检依据)
// scope: 'paragraph' = 段落级规则, 'document' = 全文级规则
expertGuidelines: [
{
title: '典型案例单列',
description: '必须包含独立的"典型案例剖析"章节,使用"以案说德、以案说纪、以案说法、以案说责"逻辑',
checkKey: 'case_study',
scope: 'document', // 全文级:检查是否有独立章节
validationRule: '检查是否包含"典型案例"独立章节'
},
{
title: '时政文件引用',
description: '必须提及"十五五"规划、二十届四中全会精神和中办发202557号文',
checkKey: 'policy_citation',
scope: 'paragraph', // 段落级:检查段落是否引用了关键文件
validationRule: '检查是否包含关键时政文件引用'
},
{
title: '篇幅比例合规',
description: '问题查摆+原因剖析+典型案例分析的篇幅占比必须≥60%',
checkKey: 'content_ratio',
scope: 'document', // 全文级:需要计算全文占比
validationRule: '计算核心内容字数占比'
},
{
title: '意识形态与巡视整改',
description: '必须包含意识形态工作责任制和巡视巡察整改情况说明',
checkKey: 'special_sections',
scope: 'document', // 全文级:检查是否有独立章节
validationRule: '检查是否包含意识形态和巡视整改章节'
},
{
title: '五个方面全覆盖',
description: '对照检查必须覆盖:政治忠诚、党性修养、敬畏法纪、担当作为、管党治党',
checkKey: 'five_aspects',
scope: 'document', // 全文级:检查五个方面是否齐全
validationRule: '检查五个方面是否齐全'
},
{
title: '递进结构',
description: '每个问题采用"定性判断+具体表现+后果/例证"递进结构',
checkKey: 'structure',
scope: 'paragraph', // 段落级:检查段落结构
validationRule: '检查段落是否符合递进结构'
},
{
title: '党内术语规范',
description: '自然嵌入党内常用术语:学用脱节、好人主义、本领恐慌、红脸出汗等',
checkKey: 'terminology',
scope: 'paragraph', // 段落级:检查术语使用
validationRule: '检查是否使用规范党内术语'
}
],