fix: 修复对照检查页面多项问题
1. 修复「导入范式要求」按钮不显示 - activeParadigm 是对象而非 ID 2. 左右两侧支持多选段落 - 点击切换选中状态 3. 中间指示器显示选中段落数量 4. 多选段落合并后一起发送给 AI 分析
This commit is contained in:
@@ -55,13 +55,16 @@
|
||||
@click="selectLeftParagraph(idx)"
|
||||
:class="[
|
||||
'p-3 rounded-lg border cursor-pointer transition-all',
|
||||
selectedLeftIdx === idx
|
||||
selectedLeftIdxs.includes(idx)
|
||||
? 'bg-amber-900/30 border-amber-500 ring-2 ring-amber-500/30'
|
||||
: 'bg-slate-800/50 border-slate-700 hover:border-amber-500/50'
|
||||
]"
|
||||
>
|
||||
<div class="flex items-start gap-2">
|
||||
<span class="text-xs text-amber-500/70 shrink-0 mt-0.5">{{ idx + 1 }}.</span>
|
||||
<span :class="['text-xs shrink-0 mt-0.5 w-5 h-5 rounded flex items-center justify-center',
|
||||
selectedLeftIdxs.includes(idx) ? 'bg-amber-500 text-white' : 'text-amber-500/70']">
|
||||
{{ selectedLeftIdxs.includes(idx) ? '✓' : (idx + 1) }}
|
||||
</span>
|
||||
<p class="text-sm text-slate-300 whitespace-pre-wrap">{{ para }}</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -76,16 +79,18 @@
|
||||
</div>
|
||||
|
||||
<!-- 中间:对应关系指示器 -->
|
||||
<div class="w-16 flex flex-col items-center justify-center bg-slate-800/50 shrink-0">
|
||||
<div v-if="selectedLeftIdx !== null && selectedRightIdx !== null" class="flex flex-col items-center gap-2">
|
||||
<div class="w-20 flex flex-col items-center justify-center bg-slate-800/50 shrink-0">
|
||||
<div v-if="selectedLeftIdxs.length > 0 && selectedRightIdxs.length > 0" class="flex flex-col items-center gap-2">
|
||||
<div class="text-xs text-amber-400 font-medium">{{ selectedLeftIdxs.length }} 段</div>
|
||||
<div class="w-3 h-3 rounded-full bg-amber-500"></div>
|
||||
<div class="w-0.5 h-8 bg-gradient-to-b from-amber-500 to-blue-500"></div>
|
||||
<span class="text-xs text-slate-500 writing-mode-vertical">对应</span>
|
||||
<div class="w-0.5 h-8 bg-gradient-to-b from-blue-500 to-blue-500"></div>
|
||||
<div class="w-0.5 h-6 bg-gradient-to-b from-amber-500 to-blue-500"></div>
|
||||
<span class="text-xs text-slate-400 px-1 py-0.5 bg-slate-700 rounded">对照</span>
|
||||
<div class="w-0.5 h-6 bg-gradient-to-b from-blue-500 to-blue-500"></div>
|
||||
<div class="w-3 h-3 rounded-full bg-blue-500"></div>
|
||||
<div class="text-xs text-blue-400 font-medium">{{ selectedRightIdxs.length }} 段</div>
|
||||
</div>
|
||||
<div v-else class="text-center px-2">
|
||||
<span class="text-xs text-slate-600">请选中<br/>两侧段落</span>
|
||||
<span class="text-xs text-slate-600">点击选中<br/>多个段落</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -110,13 +115,16 @@
|
||||
@click="selectRightParagraph(idx)"
|
||||
:class="[
|
||||
'p-3 rounded-lg border cursor-pointer transition-all',
|
||||
selectedRightIdx === idx
|
||||
selectedRightIdxs.includes(idx)
|
||||
? 'bg-blue-900/30 border-blue-500 ring-2 ring-blue-500/30'
|
||||
: 'bg-slate-800/50 border-slate-700 hover:border-blue-500/50'
|
||||
]"
|
||||
>
|
||||
<div class="flex items-start gap-2">
|
||||
<span class="text-xs text-blue-500/70 shrink-0 mt-0.5">{{ idx + 1 }}.</span>
|
||||
<span :class="['text-xs shrink-0 mt-0.5 w-5 h-5 rounded flex items-center justify-center',
|
||||
selectedRightIdxs.includes(idx) ? 'bg-blue-500 text-white' : 'text-blue-500/70']">
|
||||
{{ selectedRightIdxs.includes(idx) ? '✓' : (idx + 1) }}
|
||||
</span>
|
||||
<p class="text-sm text-slate-300 whitespace-pre-wrap">{{ para }}</p>
|
||||
</div>
|
||||
<!-- 检查结果标记 -->
|
||||
@@ -202,7 +210,6 @@
|
||||
import { ref, computed } from 'vue'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { useAppStore } from '../stores/app'
|
||||
import { PARADIGMS } from '../config/paradigms'
|
||||
|
||||
const appStore = useAppStore()
|
||||
const { activeParadigm } = storeToRefs(appStore)
|
||||
@@ -211,32 +218,28 @@ const { activeParadigm } = storeToRefs(appStore)
|
||||
const leftContent = ref('')
|
||||
const rightContent = ref('')
|
||||
|
||||
// 选中状态
|
||||
const selectedLeftIdx = ref(null)
|
||||
const selectedRightIdx = ref(null)
|
||||
// 选中状态(改为数组支持多选)
|
||||
const selectedLeftIdxs = ref([])
|
||||
const selectedRightIdxs = ref([])
|
||||
|
||||
// 检查状态
|
||||
const isComparing = ref(false)
|
||||
const lastCheckResult = ref(null)
|
||||
const checkResults = ref({})
|
||||
|
||||
// 范式相关
|
||||
// 范式相关(activeParadigm 是对象,不是 ID)
|
||||
const hasParadigmRules = computed(() => {
|
||||
if (!activeParadigm.value) return false
|
||||
const paradigm = PARADIGMS[activeParadigm.value]
|
||||
return paradigm && (paradigm.expertGuidelines || paradigm.systemConstraints)
|
||||
const p = activeParadigm.value
|
||||
return p && (p.expertGuidelines || p.systemConstraints || p.validationRules)
|
||||
})
|
||||
|
||||
const activeParadigmName = computed(() => {
|
||||
if (!activeParadigm.value) return ''
|
||||
const paradigm = PARADIGMS[activeParadigm.value]
|
||||
return paradigm?.name || ''
|
||||
return activeParadigm.value?.name || ''
|
||||
})
|
||||
|
||||
// 导入范式写作要求
|
||||
const importParadigmRules = () => {
|
||||
if (!activeParadigm.value) return
|
||||
const paradigm = PARADIGMS[activeParadigm.value]
|
||||
const paradigm = activeParadigm.value
|
||||
if (!paradigm) return
|
||||
|
||||
const rules = []
|
||||
@@ -282,24 +285,49 @@ const rightParagraphs = computed(() => {
|
||||
.filter(p => p.length > 0)
|
||||
})
|
||||
|
||||
// 是否可以检查
|
||||
// 是否可以检查(两侧都至少选中一段)
|
||||
const canCompare = computed(() => {
|
||||
return selectedLeftIdx.value !== null && selectedRightIdx.value !== null
|
||||
return selectedLeftIdxs.value.length > 0 && selectedRightIdxs.value.length > 0
|
||||
})
|
||||
|
||||
// 选择段落
|
||||
// 选择段落(多选切换)
|
||||
const selectLeftParagraph = (idx) => {
|
||||
selectedLeftIdx.value = selectedLeftIdx.value === idx ? null : idx
|
||||
const i = selectedLeftIdxs.value.indexOf(idx)
|
||||
if (i === -1) {
|
||||
selectedLeftIdxs.value.push(idx)
|
||||
} else {
|
||||
selectedLeftIdxs.value.splice(i, 1)
|
||||
}
|
||||
}
|
||||
|
||||
const selectRightParagraph = (idx) => {
|
||||
selectedRightIdx.value = selectedRightIdx.value === idx ? null : idx
|
||||
const i = selectedRightIdxs.value.indexOf(idx)
|
||||
if (i === -1) {
|
||||
selectedRightIdxs.value.push(idx)
|
||||
} else {
|
||||
selectedRightIdxs.value.splice(i, 1)
|
||||
}
|
||||
}
|
||||
|
||||
// 获取选中的段落文本(多选合并)
|
||||
const getSelectedLeftText = () => {
|
||||
return selectedLeftIdxs.value
|
||||
.sort((a, b) => a - b)
|
||||
.map(i => leftParagraphs.value[i])
|
||||
.join('\n\n')
|
||||
}
|
||||
|
||||
const getSelectedRightText = () => {
|
||||
return selectedRightIdxs.value
|
||||
.sort((a, b) => a - b)
|
||||
.map(i => rightParagraphs.value[i])
|
||||
.join('\n\n')
|
||||
}
|
||||
|
||||
// 清除选择
|
||||
const clearSelection = () => {
|
||||
selectedLeftIdx.value = null
|
||||
selectedRightIdx.value = null
|
||||
selectedLeftIdxs.value = []
|
||||
selectedRightIdxs.value = []
|
||||
lastCheckResult.value = null
|
||||
}
|
||||
|
||||
@@ -312,8 +340,8 @@ const goBack = () => {
|
||||
const runCompare = async () => {
|
||||
if (!canCompare.value) return
|
||||
|
||||
const requirement = leftParagraphs.value[selectedLeftIdx.value]
|
||||
const content = rightParagraphs.value[selectedRightIdx.value]
|
||||
const requirement = getSelectedLeftText()
|
||||
const content = getSelectedRightText()
|
||||
|
||||
isComparing.value = true
|
||||
lastCheckResult.value = null
|
||||
@@ -321,10 +349,10 @@ const runCompare = async () => {
|
||||
try {
|
||||
const prompt = `你是一个严格的写作质检专家。请对比以下"写作要求"和"写作内容",判断内容是否符合要求。
|
||||
|
||||
# 写作要求
|
||||
# 写作要求(共 ${selectedLeftIdxs.value.length} 段)
|
||||
${requirement}
|
||||
|
||||
# 写作内容
|
||||
# 写作内容(共 ${selectedRightIdxs.value.length} 段)
|
||||
${content}
|
||||
|
||||
# 输出要求
|
||||
|
||||
Reference in New Issue
Block a user