+
+
+
{{ selectedLeftIdxs.length }} 段
-
-
对应
-
+
+
对照
+
+
{{ selectedRightIdxs.length }} 段
- 请选中
两侧段落
+ 点击选中
多个段落
@@ -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'
]"
>
-
{{ idx + 1 }}.
+
+ {{ selectedRightIdxs.includes(idx) ? '✓' : (idx + 1) }}
+
{{ para }}
@@ -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}
# 输出要求