feat: 添加文稿管理、素材库、设置页面及对照检查重写功能

- 新增 DocumentsPanel.vue 文稿管理页面
- 新增 MaterialsPanel.vue 素材库管理页面
- 新增 SettingsPanel.vue 设置页面
- 新增 DocumentSelectorModal.vue 文稿选择弹窗
- 新增 MaterialSelectorModal.vue 素材选择弹窗
- 集成 SQLite 数据库持久化 (sql.js)
- 对照检查页面支持从文稿库选取内容
- 对照检查页面新增一键重写及差异对比功能
- 修复对照检查页面布局问题
- MainContent 支持文稿编辑功能
This commit is contained in:
empty
2026-01-09 00:21:52 +08:00
parent a0faaf4157
commit 1a1d7dabdf
23 changed files with 5808 additions and 64 deletions

View File

@@ -20,7 +20,15 @@
<div class="flex-1 overflow-y-auto p-4 space-y-6 min-h-0">
<!-- 写作范式库 -->
<section>
<h3 class="text-sm font-medium text-slate-400 mb-4">📚 写作范式库</h3>
<div class="flex items-center justify-between mb-4">
<h3 class="text-sm font-medium text-slate-400">📚 写作范式库</h3>
<button
@click="openAddModal"
class="text-xs px-2 py-1 bg-green-600 text-white rounded hover:bg-green-500 transition flex items-center gap-1"
>
<span>+</span> 新增范式
</button>
</div>
<div class="space-y-3">
<div
@@ -38,14 +46,34 @@
<span v-if="paradigm.isNew" class="text-[10px] px-1.5 py-0.5 rounded bg-orange-500 text-white font-bold animate-pulse">
NEW
</span>
<span v-if="paradigm.isCustom" class="text-[10px] px-1.5 py-0.5 rounded bg-purple-500 text-white font-bold">
自定义
</span>
</h4>
<button
v-if="selectedParadigm?.id === paradigm.id"
@click.stop="applyParadigm(paradigm)"
class="text-xs px-2 py-1 bg-blue-600 text-white rounded hover:bg-blue-500 transition"
>
应用到写作
</button>
<div class="flex items-center gap-1">
<button
@click.stop="openEditModal(paradigm)"
class="text-xs px-2 py-1 bg-slate-600 text-white rounded hover:bg-slate-500 transition"
title="编辑范式"
>
</button>
<button
v-if="paradigm.isCustom"
@click.stop="deleteParadigm(paradigm)"
class="text-xs px-2 py-1 bg-red-600 text-white rounded hover:bg-red-500 transition"
title="删除范式"
>
🗑
</button>
<button
v-if="selectedParadigm?.id === paradigm.id"
@click.stop="applyParadigm(paradigm)"
class="text-xs px-2 py-1 bg-blue-600 text-white rounded hover:bg-blue-500 transition"
>
应用到写作
</button>
</div>
</div>
<p class="text-xs text-slate-400 mb-2">{{ paradigm.description }}</p>
<div class="flex flex-wrap gap-1">
@@ -105,27 +133,628 @@
</div>
</section>
</div>
<!-- 编辑/新增范式弹窗 -->
<div
v-if="showEditModal"
class="fixed inset-0 bg-black/60 flex items-center justify-center z-50"
@click.self="closeEditModal"
>
<div class="bg-slate-800 rounded-lg w-[500px] max-h-[80vh] overflow-y-auto border border-slate-600 shadow-xl">
<div class="p-4 border-b border-slate-700 flex items-center justify-between">
<h3 class="font-medium text-white">{{ isAddMode ? '新增写作范式' : '编辑写作范式' }}</h3>
<button @click="closeEditModal" class="text-slate-400 hover:text-white transition"></button>
</div>
<div class="p-4 space-y-4">
<!-- 图标选择 -->
<div>
<label class="block text-sm text-slate-400 mb-2">图标</label>
<div class="flex gap-2 flex-wrap">
<button
v-for="icon in iconOptions"
:key="icon"
@click="editForm.icon = icon"
:class="['w-10 h-10 rounded-lg text-xl flex items-center justify-center transition',
editForm.icon === icon ? 'bg-blue-600' : 'bg-slate-700 hover:bg-slate-600']"
>
{{ icon }}
</button>
</div>
</div>
<!-- 名称 -->
<div>
<label class="block text-sm text-slate-400 mb-2">范式名称</label>
<input
v-model="editForm.name"
class="w-full bg-slate-900 border border-slate-700 rounded-lg px-3 py-2 text-sm focus:ring-2 focus:ring-blue-500 focus:border-transparent outline-none transition"
placeholder="如:技术博客范式"
/>
</div>
<!-- 描述 -->
<div>
<label class="block text-sm text-slate-400 mb-2">描述</label>
<textarea
v-model="editForm.description"
rows="2"
class="w-full bg-slate-900 border border-slate-700 rounded-lg px-3 py-2 text-sm focus:ring-2 focus:ring-blue-500 focus:border-transparent outline-none transition resize-none"
placeholder="简要描述此范式的适用场景"
></textarea>
</div>
<!-- 标签 -->
<div>
<label class="block text-sm text-slate-400 mb-2">标签逗号分隔</label>
<input
v-model="editForm.tagsInput"
class="w-full bg-slate-900 border border-slate-700 rounded-lg px-3 py-2 text-sm focus:ring-2 focus:ring-blue-500 focus:border-transparent outline-none transition"
placeholder="如:问题引入,解决方案,代码示例"
/>
<div class="flex flex-wrap gap-1 mt-2" v-if="editForm.tagsInput">
<span
v-for="tag in editForm.tagsInput.split(',').map(t => t.trim()).filter(t => t)"
:key="tag"
:class="['text-xs px-2 py-1 rounded', editForm.tagClass]"
>
{{ tag }}
</span>
</div>
</div>
<!-- 标签颜色 -->
<div>
<label class="block text-sm text-slate-400 mb-2">标签颜色</label>
<div class="flex gap-2 flex-wrap">
<button
v-for="color in colorOptions"
:key="color.class"
@click="editForm.tagClass = color.class"
:class="['px-3 py-1 rounded text-xs transition', color.class,
editForm.tagClass === color.class ? 'ring-2 ring-white' : '']"
>
{{ color.label }}
</button>
</div>
</div>
<!-- 写作约束高级 -->
<div>
<label class="block text-sm text-slate-400 mb-2">写作约束每行一条</label>
<textarea
v-model="editForm.constraintsInput"
rows="4"
class="w-full bg-slate-900 border border-slate-700 rounded-lg px-3 py-2 text-sm focus:ring-2 focus:ring-blue-500 focus:border-transparent outline-none transition resize-none font-mono"
placeholder="如:&#10;开篇必须明确阐述问题&#10;结尾需总结核心要点"
></textarea>
</div>
<!-- 维度配置新架构 -->
<div class="border-t border-slate-700 pt-4 mt-4">
<div class="flex items-center justify-between mb-3">
<label class="text-sm text-slate-400 font-medium">📐 维度配置高级</label>
<button
@click="toggleDimensionEditor"
class="text-xs text-blue-400 hover:text-blue-300"
>
{{ showDimensionEditor ? '收起' : '展开' }}
</button>
</div>
<div v-if="showDimensionEditor" class="space-y-3">
<!-- 维度集选择 -->
<div>
<label class="block text-xs text-slate-500 mb-1">选择维度集模板</label>
<select
v-model="editForm.dimensionSetId"
@change="onDimensionSetChange"
class="w-full bg-slate-900 border border-slate-700 rounded-lg px-3 py-2 text-sm focus:ring-2 focus:ring-blue-500 outline-none"
>
<option :value="null">不使用维度集</option>
<option v-for="ds in dimensionSetOptions" :key="ds.id" :value="ds.id">
{{ ds.name }} - {{ ds.description }}
</option>
</select>
</div>
<!-- 维度列表编辑 -->
<div v-if="editForm.dimensions.length > 0">
<label class="block text-xs text-slate-500 mb-2">维度列表可编辑</label>
<div class="space-y-2 max-h-60 overflow-y-auto">
<div
v-for="(dim, index) in editForm.dimensions"
:key="dim.id || index"
class="bg-slate-900/50 rounded p-2 border border-slate-700"
>
<div class="flex items-center gap-2 mb-1">
<input
v-model="dim.name"
class="flex-1 bg-slate-800 border border-slate-600 rounded px-2 py-1 text-xs"
placeholder="维度名称"
/>
<button
@click="removeDimension(index)"
class="text-red-400 hover:text-red-300 text-xs px-1"
>
</button>
</div>
<input
v-model="dim.focus"
class="w-full bg-slate-800 border border-slate-600 rounded px-2 py-1 text-xs text-slate-400"
placeholder="关注重点(如:理想信念、宗旨意识)"
/>
</div>
</div>
<button
@click="addDimension"
class="mt-2 text-xs text-green-400 hover:text-green-300 flex items-center gap-1"
>
<span>+</span> 添加维度
</button>
</div>
<!-- 快速添加维度 -->
<div v-else class="text-center py-4 text-slate-500 text-xs">
<p>选择一个维度集模板或手动添加维度</p>
<button
@click="addDimension"
class="mt-2 text-green-400 hover:text-green-300"
>
+ 添加自定义维度
</button>
</div>
</div>
</div>
<!-- 素材库配置新增 -->
<div class="border-t border-slate-700 pt-4 mt-4">
<div class="flex items-center justify-between mb-3">
<label class="text-sm text-slate-400 font-medium">📚 素材库配置</label>
<button
@click="toggleReferenceEditor"
class="text-xs text-blue-400 hover:text-blue-300"
>
{{ showReferenceEditor ? '收起' : '展开' }}
</button>
</div>
<div v-if="showReferenceEditor" class="space-y-3">
<!-- 自动匹配开关 -->
<div class="flex items-center justify-between">
<span class="text-xs text-slate-500">自动匹配相关素材</span>
<label class="relative inline-flex items-center cursor-pointer">
<input type="checkbox" v-model="editForm.autoMatchRefs" class="sr-only peer">
<div class="w-9 h-5 bg-slate-600 peer-focus:ring-2 peer-focus:ring-blue-500 rounded-full peer peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-4 after:w-4 after:transition-all peer-checked:bg-blue-600"></div>
</label>
</div>
<!-- 素材类型筛选 -->
<div>
<label class="block text-xs text-slate-500 mb-2">手动选择素材按类型</label>
<div class="flex flex-wrap gap-1 mb-2">
<button
v-for="type in referenceTypes"
:key="type.id"
@click="filterReferencesByType(type.id)"
:class="['text-xs px-2 py-1 rounded transition',
selectedRefType === type.id
? 'bg-blue-600 text-white'
: 'bg-slate-700 text-slate-300 hover:bg-slate-600']"
>
{{ type.icon }} {{ type.name }}
</button>
</div>
</div>
<!-- 素材列表 -->
<div class="max-h-40 overflow-y-auto space-y-1">
<div
v-for="ref in filteredReferences"
:key="ref.id"
@click="toggleReference(ref.id)"
:class="['p-2 rounded cursor-pointer border transition text-xs',
editForm.selectedRefs.includes(ref.id)
? 'bg-blue-900/30 border-blue-500'
: 'bg-slate-900/50 border-slate-700 hover:border-slate-500']"
>
<div class="flex items-center justify-between">
<span class="font-medium text-white">{{ ref.title }}</span>
<span v-if="editForm.selectedRefs.includes(ref.id)" class="text-green-400"></span>
</div>
<div class="text-slate-500 text-[10px] mt-1">{{ ref.excerptCount }} 条可引用内容</div>
</div>
</div>
<!-- 已选素材摘要 -->
<div v-if="editForm.selectedRefs.length > 0" class="text-xs text-slate-400">
已选择 {{ editForm.selectedRefs.length }} 个素材
</div>
</div>
</div>
</div>
<div class="p-4 border-t border-slate-700 flex justify-end gap-2">
<button
@click="closeEditModal"
class="px-4 py-2 bg-slate-700 text-white rounded-lg text-sm hover:bg-slate-600 transition"
>
取消
</button>
<button
@click="saveParadigm"
:disabled="!editForm.name"
class="px-4 py-2 bg-blue-600 text-white rounded-lg text-sm hover:bg-blue-500 transition disabled:opacity-50 disabled:cursor-not-allowed"
>
{{ isAddMode ? '添加' : '保存' }}
</button>
</div>
</div>
</div>
</aside>
</template>
<script setup>
import { ref, onMounted } from 'vue'
import { ref, reactive, onMounted, computed, watch } from 'vue'
import { storeToRefs } from 'pinia'
import { useAppStore } from '../stores/app'
import { useDatabaseStore } from '../stores/database.js'
import DeepSeekAPI from '../api/deepseek.js'
import { getParadigmList } from '../config/paradigms.js'
import { getParadigmList, getParadigmDimensions } from '../config/paradigms.js'
import { getDimensionSetList, getDimensionSetById } from '../config/dimensionSets.js'
import { getLogicParadigmList } from '../config/logicParadigms.js'
import { REFERENCE_TYPES } from '../config/references.js'
const appStore = useAppStore()
const { analysisText, isAnalyzing } = storeToRefs(appStore)
// 数据库 Store
const dbStore = useDatabaseStore()
const { references: dbReferences, isInitialized: dbInitialized } = storeToRefs(dbStore)
// 选中的范式
const selectedParadigm = ref(null)
// 分析历史
const analysisHistory = ref([])
// 从配置文件获取范式列表
const paradigms = getParadigmList()
// 范式列表(响应式,支持编辑)
const paradigms = ref([])
// 编辑弹窗状态
const showEditModal = ref(false)
const isAddMode = ref(false)
const editingParadigmId = ref(null)
// 编辑表单
const editForm = reactive({
icon: '📝',
name: '',
description: '',
tagsInput: '',
tagClass: 'bg-blue-900/30 text-blue-300',
constraintsInput: '',
// 新架构:维度配置
dimensionSetId: null,
dimensions: [],
// 素材库配置
autoMatchRefs: true,
selectedRefs: []
})
// 维度编辑器状态
const showDimensionEditor = ref(false)
// 素材编辑器状态
const showReferenceEditor = ref(false)
const selectedRefType = ref('all')
// 使用数据库中的素材数据
const allReferences = computed(() => {
return dbReferences.value.map(ref => ({
id: ref.id,
type: ref.type,
title: ref.title,
source: ref.source,
tags: ref.tags,
excerptCount: ref.excerpts?.length || 0
}))
})
const filteredReferences = computed(() => {
if (selectedRefType.value === 'all') {
return allReferences.value
}
return allReferences.value.filter(ref => ref.type === selectedRefType.value)
})
// 素材类型选项
const referenceTypes = [
{ id: 'all', name: '全部', icon: '📚' },
{ id: REFERENCE_TYPES.POLICY, name: '政策文件', icon: '📄' },
{ id: REFERENCE_TYPES.SPEECH, name: '领导讲话', icon: '🎙️' },
{ id: REFERENCE_TYPES.CASE, name: '典型案例', icon: '📌' },
{ id: REFERENCE_TYPES.QUOTE, name: '金句警句', icon: '✨' },
{ id: REFERENCE_TYPES.REGULATION, name: '党规党纪', icon: '📖' }
]
// 维度集选项
const dimensionSetOptions = getDimensionSetList()
// 图标选项
const iconOptions = ['📝', '💻', '📊', '🚀', '📚', '🏛️', '🔥', '🏢', '💡', '🎯', '📋', '✨']
// 颜色选项
const colorOptions = [
{ label: '蓝色', class: 'bg-blue-900/30 text-blue-300' },
{ label: '绿色', class: 'bg-green-900/30 text-green-300' },
{ label: '红色', class: 'bg-red-900/30 text-red-300' },
{ label: '紫色', class: 'bg-purple-900/30 text-purple-300' },
{ label: '橙色', class: 'bg-orange-900/30 text-orange-300' },
{ label: '青色', class: 'bg-cyan-900/30 text-cyan-300' }
]
// 初始化范式列表
const initParadigms = () => {
// 先加载默认范式
const defaultParadigms = getParadigmList()
// 从本地存储加载自定义修改
const savedCustomizations = localStorage.getItem('paradigmCustomizations')
const customizations = savedCustomizations ? JSON.parse(savedCustomizations) : {}
// 从本地存储加载自定义范式
const savedCustomParadigms = localStorage.getItem('customParadigms')
const customParadigms = savedCustomParadigms ? JSON.parse(savedCustomParadigms) : []
// 合并默认范式和自定义修改
const mergedParadigms = defaultParadigms.map(p => {
if (customizations[p.id]) {
return { ...p, ...customizations[p.id] }
}
return p
})
// 添加自定义范式
paradigms.value = [...mergedParadigms, ...customParadigms]
}
// 打开新增弹窗
const openAddModal = () => {
isAddMode.value = true
editingParadigmId.value = null
resetEditForm()
showEditModal.value = true
}
// 打开编辑弹窗
const openEditModal = (paradigm) => {
isAddMode.value = false
editingParadigmId.value = paradigm.id
editForm.icon = paradigm.icon || '📝'
editForm.name = paradigm.name || ''
editForm.description = paradigm.description || ''
editForm.tagsInput = (paradigm.tags || []).join(', ')
editForm.tagClass = paradigm.tagClass || 'bg-blue-900/30 text-blue-300'
editForm.constraintsInput = (paradigm.systemConstraints || []).join('\n')
// 加载维度配置
editForm.dimensionSetId = paradigm.dimensionSetId || null
if (paradigm.dimensionSetId) {
const dimSet = getDimensionSetById(paradigm.dimensionSetId)
editForm.dimensions = dimSet ? JSON.parse(JSON.stringify(dimSet.dimensions)) : []
} else if (paradigm.customDimensions) {
editForm.dimensions = JSON.parse(JSON.stringify(paradigm.customDimensions))
} else {
editForm.dimensions = []
}
// 加载素材配置
editForm.autoMatchRefs = paradigm.autoMatchRefs !== false // 默认为true
editForm.selectedRefs = paradigm.selectedRefs ? [...paradigm.selectedRefs] : []
showDimensionEditor.value = false
showReferenceEditor.value = false
showEditModal.value = true
}
// 关闭弹窗
const closeEditModal = () => {
showEditModal.value = false
resetEditForm()
}
// 重置表单
const resetEditForm = () => {
editForm.icon = '📝'
editForm.name = ''
editForm.description = ''
editForm.tagsInput = ''
editForm.tagClass = 'bg-blue-900/30 text-blue-300'
editForm.constraintsInput = ''
editForm.dimensionSetId = null
editForm.dimensions = []
// 素材配置重置
editForm.autoMatchRefs = true
editForm.selectedRefs = []
showDimensionEditor.value = false
showReferenceEditor.value = false
}
// 切换维度编辑器显示
const toggleDimensionEditor = () => {
showDimensionEditor.value = !showDimensionEditor.value
}
// 维度集变更时更新维度列表
const onDimensionSetChange = () => {
if (editForm.dimensionSetId) {
const dimSet = getDimensionSetById(editForm.dimensionSetId)
if (dimSet) {
// 深拷贝维度列表,允许用户编辑
editForm.dimensions = JSON.parse(JSON.stringify(dimSet.dimensions))
}
} else {
editForm.dimensions = []
}
}
// 添加自定义维度
const addDimension = () => {
editForm.dimensions.push({
id: `custom-dim-${Date.now()}`,
name: '',
focus: ''
})
}
// 删除维度
const removeDimension = (index) => {
editForm.dimensions.splice(index, 1)
}
// 切换素材编辑器显示
const toggleReferenceEditor = () => {
showReferenceEditor.value = !showReferenceEditor.value
}
// 按类型筛选素材通过修改selectedRefType触发computed重新计算
const filterReferencesByType = (typeId) => {
selectedRefType.value = typeId
}
// 切换素材选中状态
const toggleReference = (refId) => {
const index = editForm.selectedRefs.indexOf(refId)
if (index === -1) {
editForm.selectedRefs.push(refId)
} else {
editForm.selectedRefs.splice(index, 1)
}
}
// 保存范式
const saveParadigm = () => {
const tags = editForm.tagsInput.split(',').map(t => t.trim()).filter(t => t)
const constraints = editForm.constraintsInput.split('\n').map(c => c.trim()).filter(c => c)
// 处理维度配置
const dimensionConfig = {
dimensionSetId: editForm.dimensionSetId,
customDimensions: editForm.dimensions.length > 0 ? editForm.dimensions : null
}
// 处理素材配置
const referenceConfig = {
autoMatchRefs: editForm.autoMatchRefs,
selectedRefs: editForm.selectedRefs
}
if (isAddMode.value) {
// 新增自定义范式
const newParadigm = {
id: `custom-${Date.now()}`,
icon: editForm.icon,
name: editForm.name,
description: editForm.description,
tags,
tagClass: editForm.tagClass,
systemConstraints: constraints,
isCustom: true,
// 新架构:维度配置
...dimensionConfig,
// 素材配置
...referenceConfig,
logicParadigms: {
problemSection: 'progressive-problem',
analysisSection: 'deep-attribution',
remediationSection: 'remediation'
}
}
paradigms.value.push(newParadigm)
// 保存到本地存储
const savedCustomParadigms = localStorage.getItem('customParadigms')
const customParadigms = savedCustomParadigms ? JSON.parse(savedCustomParadigms) : []
customParadigms.push(newParadigm)
localStorage.setItem('customParadigms', JSON.stringify(customParadigms))
} else {
// 编辑现有范式
const index = paradigms.value.findIndex(p => p.id === editingParadigmId.value)
if (index !== -1) {
const updatedParadigm = {
...paradigms.value[index],
icon: editForm.icon,
name: editForm.name,
description: editForm.description,
tags,
tagClass: editForm.tagClass,
systemConstraints: constraints,
// 新架构:维度配置
...dimensionConfig,
// 素材配置
...referenceConfig
}
paradigms.value[index] = updatedParadigm
// 根据是否是自定义范式决定存储位置
if (updatedParadigm.isCustom) {
// 更新自定义范式
const savedCustomParadigms = localStorage.getItem('customParadigms')
const customParadigms = savedCustomParadigms ? JSON.parse(savedCustomParadigms) : []
const customIndex = customParadigms.findIndex(p => p.id === editingParadigmId.value)
if (customIndex !== -1) {
customParadigms[customIndex] = updatedParadigm
localStorage.setItem('customParadigms', JSON.stringify(customParadigms))
}
} else {
// 保存对默认范式的自定义修改
const savedCustomizations = localStorage.getItem('paradigmCustomizations')
const customizations = savedCustomizations ? JSON.parse(savedCustomizations) : {}
customizations[editingParadigmId.value] = {
icon: editForm.icon,
name: editForm.name,
description: editForm.description,
tags,
tagClass: editForm.tagClass,
systemConstraints: constraints,
// 新架构:维度配置
...dimensionConfig,
// 素材配置
...referenceConfig
}
localStorage.setItem('paradigmCustomizations', JSON.stringify(customizations))
}
}
}
closeEditModal()
}
// 删除自定义范式
const deleteParadigm = (paradigm) => {
if (!paradigm.isCustom) return
if (!confirm(`确定要删除"${paradigm.name}"吗?`)) return
// 从列表中移除
paradigms.value = paradigms.value.filter(p => p.id !== paradigm.id)
// 从本地存储中移除
const savedCustomParadigms = localStorage.getItem('customParadigms')
const customParadigms = savedCustomParadigms ? JSON.parse(savedCustomParadigms) : []
const filtered = customParadigms.filter(p => p.id !== paradigm.id)
localStorage.setItem('customParadigms', JSON.stringify(filtered))
// 如果正在选中该范式,清除选中状态
if (selectedParadigm.value?.id === paradigm.id) {
selectedParadigm.value = null
}
}
// 选择范式
const selectParadigm = (paradigm) => {
@@ -154,22 +783,26 @@ const analyzeArticle = async () => {
// 检测文章范式
const detectParadigm = (analysis) => {
const text = analysis.toLowerCase()
const list = paradigms.value
// 根据 id 查找范式
const findById = (id) => list.find(p => p.id === id)
if (text.includes('民主生活会') || text.includes('对照检查') || text.includes('整改') || text.includes('党性')) {
return paradigms[4] // 民主生活会对照检查
return findById('party-review') || list[0]
} else if (text.includes('政府') || text.includes('工作报告') || text.includes('述职')) {
return paradigms[5] // 政府工作报告
return findById('gov-report') || list[0]
} else if (text.includes('技术') || text.includes('代码') || text.includes('编程')) {
return paradigms[0] // 技术博客
return findById('tech') || list[0]
} else if (text.includes('商业') || text.includes('市场') || text.includes('数据分析')) {
return paradigms[1] // 商业分析
return findById('business') || list[0]
} else if (text.includes('产品') || text.includes('营销') || text.includes('用户')) {
return paradigms[2] // 产品文案
return findById('marketing') || list[0]
} else if (text.includes('学术') || text.includes('研究') || text.includes('文献')) {
return paradigms[3] // 学术论文
return findById('academic') || list[0]
}
return paradigms[0] // 默认技术博客
return list[0] // 默认第一个范式
}
// 添加到历史记录
@@ -225,8 +858,12 @@ const formatDate = (date) => {
return new Date(date).toLocaleDateString()
}
// 组件挂载时加载历史记录
// 组件挂载时加载历史记录和范式列表
onMounted(() => {
// 初始化范式列表
initParadigms()
// 加载分析历史
const saved = localStorage.getItem('analysisHistory')
if (saved) {
analysisHistory.value = JSON.parse(saved)