main
parent
0c4f22e6cc
commit
979b1295a5
@ -0,0 +1,781 @@
|
||||
---
|
||||
description:
|
||||
globs:
|
||||
alwaysApply: true
|
||||
---
|
||||
# 项目实施指南
|
||||
|
||||
## 1. 关键依赖包安装
|
||||
|
||||
### 基础框架
|
||||
```bash
|
||||
# 核心依赖
|
||||
npm install vue@2.6.14
|
||||
npm install vuex@3.6.2
|
||||
npm install vue-router@3.5.3
|
||||
```
|
||||
|
||||
### UI组件
|
||||
```bash
|
||||
# Element UI
|
||||
npm install element-ui@2.15.10
|
||||
|
||||
# 按需引入插件
|
||||
npm install babel-plugin-component -D
|
||||
```
|
||||
|
||||
### 数据可视化
|
||||
```bash
|
||||
# ECharts
|
||||
npm install echarts@5.4.0
|
||||
npm install vue-echarts@6.2.3
|
||||
|
||||
# 词云
|
||||
npm install echarts-wordcloud@2.1.0
|
||||
|
||||
# 或者 D3 词云
|
||||
npm install d3@7.8.0
|
||||
npm install d3-cloud@1.2.5
|
||||
```
|
||||
|
||||
### 数据处理
|
||||
```bash
|
||||
# Excel/CSV处理
|
||||
npm install xlsx@0.18.5
|
||||
npm install papaparse@5.3.2
|
||||
|
||||
# HTTP请求
|
||||
npm install axios@1.2.0
|
||||
```
|
||||
|
||||
### 开发工具
|
||||
```bash
|
||||
# Mock数据
|
||||
npm install mockjs@1.1.0
|
||||
```
|
||||
|
||||
## 2. 项目目录结构建立
|
||||
|
||||
按照以下步骤创建项目基本结构:
|
||||
|
||||
```bash
|
||||
# 创建视图目录
|
||||
mkdir -p src/views
|
||||
touch src/views/Process.vue
|
||||
touch src/views/Analysis.vue
|
||||
|
||||
# 创建组件目录
|
||||
mkdir -p src/components/{base,layout,process,analysis}
|
||||
touch src/components/layout/Header.vue
|
||||
touch src/components/layout/Footer.vue
|
||||
|
||||
# 创建路由目录
|
||||
mkdir -p src/router
|
||||
touch src/router/index.js
|
||||
|
||||
# 创建状态管理目录
|
||||
mkdir -p src/store/modules
|
||||
touch src/store/index.js
|
||||
touch src/store/modules/{app.js,process.js,analysis.js}
|
||||
|
||||
# 创建API交互目录
|
||||
mkdir -p src/api
|
||||
touch src/api/index.js
|
||||
touch src/api/{process.js,analysis.js}
|
||||
|
||||
# 创建工具函数目录
|
||||
mkdir -p src/utils
|
||||
touch src/utils/{file.js,format.js,mock.js}
|
||||
|
||||
# 创建资源目录
|
||||
mkdir -p src/assets/{css,fonts,images}
|
||||
touch src/assets/css/main.css
|
||||
```
|
||||
|
||||
## 3. 核心配置文件设置
|
||||
|
||||
### 路由配置 (`src/router/index.js`)
|
||||
|
||||
```js
|
||||
import Vue from 'vue'
|
||||
import VueRouter from 'vue-router'
|
||||
import Process from '../views/Process.vue'
|
||||
import Analysis from '../views/Analysis.vue'
|
||||
|
||||
Vue.use(VueRouter)
|
||||
|
||||
const routes = [
|
||||
{
|
||||
path: '/',
|
||||
redirect: '/process'
|
||||
},
|
||||
{
|
||||
path: '/process',
|
||||
name: 'Process',
|
||||
component: Process,
|
||||
meta: { title: '文档处理' }
|
||||
},
|
||||
{
|
||||
path: '/analysis',
|
||||
name: 'Analysis',
|
||||
component: Analysis,
|
||||
meta: { title: '数据分析' }
|
||||
}
|
||||
]
|
||||
|
||||
const router = new VueRouter({
|
||||
mode: 'history',
|
||||
base: process.env.BASE_URL,
|
||||
routes
|
||||
})
|
||||
|
||||
router.beforeEach((to, from, next) => {
|
||||
document.title = to.meta.title || '文档智能处理平台'
|
||||
next()
|
||||
})
|
||||
|
||||
export default router
|
||||
```
|
||||
|
||||
### Vuex状态管理 (`src/store/index.js`)
|
||||
|
||||
```js
|
||||
import Vue from 'vue'
|
||||
import Vuex from 'vuex'
|
||||
import app from './modules/app'
|
||||
import process from './modules/process'
|
||||
import analysis from './modules/analysis'
|
||||
|
||||
Vue.use(Vuex)
|
||||
|
||||
export default new Vuex.Store({
|
||||
modules: {
|
||||
app,
|
||||
process,
|
||||
analysis
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
### Element UI引入 (`src/main.js`)
|
||||
|
||||
```js
|
||||
import Vue from 'vue'
|
||||
import App from './App.vue'
|
||||
import router from './router'
|
||||
import store from './store'
|
||||
import './utils/mock'
|
||||
|
||||
// Element UI
|
||||
import {
|
||||
Button, Steps, Step, Upload, Table, TableColumn, Dialog,
|
||||
Card, Loading, Tabs, TabPane, Message, Notification, Alert
|
||||
} from 'element-ui'
|
||||
import 'element-ui/lib/theme-chalk/index.css'
|
||||
|
||||
// 注册Element UI组件
|
||||
Vue.use(Button)
|
||||
Vue.use(Steps)
|
||||
Vue.use(Step)
|
||||
Vue.use(Upload)
|
||||
Vue.use(Table)
|
||||
Vue.use(TableColumn)
|
||||
Vue.use(Dialog)
|
||||
Vue.use(Card)
|
||||
Vue.use(Loading)
|
||||
Vue.use(Tabs)
|
||||
Vue.use(TabPane)
|
||||
Vue.use(Alert)
|
||||
|
||||
// 挂载Element UI消息组件
|
||||
Vue.prototype.$message = Message
|
||||
Vue.prototype.$notify = Notification
|
||||
|
||||
Vue.config.productionTip = false
|
||||
|
||||
new Vue({
|
||||
router,
|
||||
store,
|
||||
render: h => h(App)
|
||||
}).$mount('#app')
|
||||
```
|
||||
|
||||
### API请求封装 (`src/api/index.js`)
|
||||
|
||||
```js
|
||||
import axios from 'axios'
|
||||
import { Message } from 'element-ui'
|
||||
|
||||
// 创建axios实例
|
||||
const service = axios.create({
|
||||
baseURL: process.env.VUE_APP_BASE_API || '/api',
|
||||
timeout: 15000
|
||||
})
|
||||
|
||||
// 请求拦截器
|
||||
service.interceptors.request.use(
|
||||
config => {
|
||||
// 可添加token等认证信息
|
||||
return config
|
||||
},
|
||||
error => {
|
||||
console.error('请求错误:', error)
|
||||
return Promise.reject(error)
|
||||
}
|
||||
)
|
||||
|
||||
// 响应拦截器
|
||||
service.interceptors.response.use(
|
||||
response => {
|
||||
const res = response.data
|
||||
|
||||
// 根据实际API返回格式调整
|
||||
if (res.code === 0) {
|
||||
return res.data
|
||||
}
|
||||
|
||||
Message({
|
||||
message: res.message || '请求错误',
|
||||
type: 'error',
|
||||
duration: 5 * 1000
|
||||
})
|
||||
|
||||
return Promise.reject(new Error(res.message || '请求错误'))
|
||||
},
|
||||
error => {
|
||||
console.error('响应错误:', error)
|
||||
Message({
|
||||
message: error.message || '网络错误',
|
||||
type: 'error',
|
||||
duration: 5 * 1000
|
||||
})
|
||||
return Promise.reject(error)
|
||||
}
|
||||
)
|
||||
|
||||
export default service
|
||||
```
|
||||
|
||||
## 4. 核心Vuex模块实现示例
|
||||
|
||||
### `src/store/modules/process.js`
|
||||
|
||||
```js
|
||||
import { uploadFile, preprocessData, mergeFormat, correctWords, analyzeData } from '@/api/process'
|
||||
|
||||
const state = {
|
||||
currentStep: 1,
|
||||
uploadedFiles: [],
|
||||
fileData: null,
|
||||
preprocessResults: null,
|
||||
mergeResults: null,
|
||||
correctionResults: null,
|
||||
analysisResults: null,
|
||||
stepStatus: {
|
||||
upload: 'pending',
|
||||
preprocess: 'pending',
|
||||
merge: 'pending',
|
||||
correction: 'pending',
|
||||
analysis: 'pending'
|
||||
}
|
||||
}
|
||||
|
||||
const mutations = {
|
||||
SET_CURRENT_STEP(state, step) {
|
||||
state.currentStep = step
|
||||
},
|
||||
ADD_UPLOADED_FILE(state, file) {
|
||||
state.uploadedFiles.push(file)
|
||||
},
|
||||
REMOVE_UPLOADED_FILE(state, fileId) {
|
||||
state.uploadedFiles = state.uploadedFiles.filter(file => file.id !== fileId)
|
||||
},
|
||||
SET_FILE_DATA(state, data) {
|
||||
state.fileData = data
|
||||
},
|
||||
SET_PREPROCESS_RESULTS(state, results) {
|
||||
state.preprocessResults = results
|
||||
state.stepStatus.preprocess = 'completed'
|
||||
},
|
||||
SET_MERGE_RESULTS(state, results) {
|
||||
state.mergeResults = results
|
||||
state.stepStatus.merge = 'completed'
|
||||
},
|
||||
SET_CORRECTION_RESULTS(state, results) {
|
||||
state.correctionResults = results
|
||||
state.stepStatus.correction = 'completed'
|
||||
},
|
||||
SET_ANALYSIS_RESULTS(state, results) {
|
||||
state.analysisResults = results
|
||||
state.stepStatus.analysis = 'completed'
|
||||
},
|
||||
UPDATE_STEP_STATUS(state, { step, status }) {
|
||||
state.stepStatus[step] = status
|
||||
}
|
||||
}
|
||||
|
||||
const actions = {
|
||||
// 上传文件
|
||||
async uploadFile({ commit }, file) {
|
||||
commit('UPDATE_STEP_STATUS', { step: 'upload', status: 'processing' })
|
||||
try {
|
||||
const response = await uploadFile(file)
|
||||
commit('ADD_UPLOADED_FILE', { id: Date.now(), file, response })
|
||||
commit('UPDATE_STEP_STATUS', { step: 'upload', status: 'completed' })
|
||||
return response
|
||||
} catch (error) {
|
||||
commit('UPDATE_STEP_STATUS', { step: 'upload', status: 'error' })
|
||||
throw error
|
||||
}
|
||||
},
|
||||
|
||||
// 保存编辑后的数据
|
||||
saveFileData({ commit }, data) {
|
||||
commit('SET_FILE_DATA', data)
|
||||
},
|
||||
|
||||
// 预处理数据
|
||||
async preprocessData({ commit, state }) {
|
||||
if (!state.fileData) return Promise.reject(new Error('没有数据可处理'))
|
||||
|
||||
commit('UPDATE_STEP_STATUS', { step: 'preprocess', status: 'processing' })
|
||||
try {
|
||||
const results = await preprocessData(state.fileData)
|
||||
commit('SET_PREPROCESS_RESULTS', results)
|
||||
return results
|
||||
} catch (error) {
|
||||
commit('UPDATE_STEP_STATUS', { step: 'preprocess', status: 'error' })
|
||||
throw error
|
||||
}
|
||||
},
|
||||
|
||||
// 合并格式
|
||||
async mergeFormat({ commit, state }) {
|
||||
if (!state.preprocessResults) return Promise.reject(new Error('请先进行预处理'))
|
||||
|
||||
commit('UPDATE_STEP_STATUS', { step: 'merge', status: 'processing' })
|
||||
try {
|
||||
const results = await mergeFormat(state.preprocessResults)
|
||||
commit('SET_MERGE_RESULTS', results)
|
||||
return results
|
||||
} catch (error) {
|
||||
commit('UPDATE_STEP_STATUS', { step: 'merge', status: 'error' })
|
||||
throw error
|
||||
}
|
||||
},
|
||||
|
||||
// 单词纠错
|
||||
async correctWords({ commit, state }) {
|
||||
if (!state.mergeResults) return Promise.reject(new Error('请先进行格式合并'))
|
||||
|
||||
commit('UPDATE_STEP_STATUS', { step: 'correction', status: 'processing' })
|
||||
try {
|
||||
const results = await correctWords(state.mergeResults)
|
||||
commit('SET_CORRECTION_RESULTS', results)
|
||||
return results
|
||||
} catch (error) {
|
||||
commit('UPDATE_STEP_STATUS', { step: 'correction', status: 'error' })
|
||||
throw error
|
||||
}
|
||||
},
|
||||
|
||||
// 大模型分析
|
||||
async analyzeData({ commit, state }) {
|
||||
if (!state.correctionResults) return Promise.reject(new Error('请先进行单词纠错'))
|
||||
|
||||
commit('UPDATE_STEP_STATUS', { step: 'analysis', status: 'processing' })
|
||||
try {
|
||||
const results = await analyzeData(state.correctionResults)
|
||||
commit('SET_ANALYSIS_RESULTS', results)
|
||||
return results
|
||||
} catch (error) {
|
||||
commit('UPDATE_STEP_STATUS', { step: 'analysis', status: 'error' })
|
||||
throw error
|
||||
}
|
||||
},
|
||||
|
||||
// 前进到下一步
|
||||
nextStep({ commit, state }) {
|
||||
if (state.currentStep < 5) {
|
||||
commit('SET_CURRENT_STEP', state.currentStep + 1)
|
||||
}
|
||||
},
|
||||
|
||||
// 返回上一步
|
||||
prevStep({ commit, state }) {
|
||||
if (state.currentStep > 1) {
|
||||
commit('SET_CURRENT_STEP', state.currentStep - 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const getters = {
|
||||
canProceedToNextStep: state => {
|
||||
switch (state.currentStep) {
|
||||
case 1: return state.stepStatus.upload === 'completed' && state.fileData !== null
|
||||
case 2: return state.stepStatus.preprocess === 'completed'
|
||||
case 3: return state.stepStatus.merge === 'completed'
|
||||
case 4: return state.stepStatus.correction === 'completed'
|
||||
case 5: return state.stepStatus.analysis === 'completed'
|
||||
default: return false
|
||||
}
|
||||
},
|
||||
isCurrentStepProcessing: state => {
|
||||
const stepMap = {
|
||||
1: 'upload',
|
||||
2: 'preprocess',
|
||||
3: 'merge',
|
||||
4: 'correction',
|
||||
5: 'analysis'
|
||||
}
|
||||
const currentStepKey = stepMap[state.currentStep]
|
||||
return state.stepStatus[currentStepKey] === 'processing'
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
namespaced: true,
|
||||
state,
|
||||
mutations,
|
||||
actions,
|
||||
getters
|
||||
}
|
||||
```
|
||||
|
||||
## 5. 组件实现建议
|
||||
|
||||
### Process.vue基本结构
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<div class="process-container">
|
||||
<!-- 页面头部 -->
|
||||
<div class="process-header">
|
||||
<h1 class="process-title">文档智能处理流程</h1>
|
||||
<p class="process-subtitle">上传、预处理、分析您的 Excel/CSV 数据</p>
|
||||
<div class="process-icon">
|
||||
<!-- 中央处理图标 -->
|
||||
<img src="@/assets/images/process-icon.svg" alt="处理流程" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 步骤条 -->
|
||||
<div class="process-steps">
|
||||
<el-steps :active="currentStep" finish-status="success" align-center>
|
||||
<el-step title="上传文件"></el-step>
|
||||
<el-step title="预处理"></el-step>
|
||||
<el-step title="合并格式"></el-step>
|
||||
<el-step title="单词纠错"></el-step>
|
||||
<el-step title="模型分析"></el-step>
|
||||
</el-steps>
|
||||
</div>
|
||||
|
||||
<!-- 步骤内容区域 -->
|
||||
<div class="step-content">
|
||||
<!-- 根据currentStep显示对应的组件 -->
|
||||
<file-upload v-if="currentStep === 1" />
|
||||
<processing-step
|
||||
v-else-if="currentStep === 2"
|
||||
title="数据预处理"
|
||||
:status="stepStatus.preprocess"
|
||||
@process="handlePreprocess"
|
||||
/>
|
||||
<processing-step
|
||||
v-else-if="currentStep === 3"
|
||||
title="合并格式"
|
||||
:status="stepStatus.merge"
|
||||
@process="handleMergeFormat"
|
||||
/>
|
||||
<processing-step
|
||||
v-else-if="currentStep === 4"
|
||||
title="单词纠错"
|
||||
:status="stepStatus.correction"
|
||||
@process="handleWordCorrection"
|
||||
/>
|
||||
<processing-step
|
||||
v-else-if="currentStep === 5"
|
||||
title="大模型分析"
|
||||
:status="stepStatus.analysis"
|
||||
@process="handleAnalysis"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- 辅助信息区域 -->
|
||||
<div class="process-footer">
|
||||
<a href="#" class="privacy-link">如何保护我的文件?</a>
|
||||
<div class="notification-option">
|
||||
<el-checkbox v-model="notifyWhenDone">处理完成后通知我</el-checkbox>
|
||||
<el-input
|
||||
v-if="notifyWhenDone"
|
||||
v-model="notifyEmail"
|
||||
placeholder="请输入您的邮箱"
|
||||
size="small"
|
||||
style="width: 200px; margin-left: 10px;"
|
||||
></el-input>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapState, mapGetters, mapActions } from 'vuex'
|
||||
import FileUpload from '@/components/process/FileUpload.vue'
|
||||
import ProcessingStep from '@/components/process/ProcessingStep.vue'
|
||||
|
||||
export default {
|
||||
name: 'Process',
|
||||
components: {
|
||||
FileUpload,
|
||||
ProcessingStep
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
notifyWhenDone: false,
|
||||
notifyEmail: ''
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState('process', ['currentStep', 'stepStatus']),
|
||||
...mapGetters('process', ['canProceedToNextStep', 'isCurrentStepProcessing'])
|
||||
},
|
||||
methods: {
|
||||
...mapActions('process', [
|
||||
'preprocessData',
|
||||
'mergeFormat',
|
||||
'correctWords',
|
||||
'analyzeData',
|
||||
'nextStep'
|
||||
]),
|
||||
async handlePreprocess() {
|
||||
try {
|
||||
await this.preprocessData()
|
||||
this.$message.success('预处理完成')
|
||||
} catch (error) {
|
||||
this.$message.error(`预处理失败: ${error.message}`)
|
||||
}
|
||||
},
|
||||
async handleMergeFormat() {
|
||||
try {
|
||||
await this.mergeFormat()
|
||||
this.$message.success('格式合并完成')
|
||||
} catch (error) {
|
||||
this.$message.error(`格式合并失败: ${error.message}`)
|
||||
}
|
||||
},
|
||||
async handleWordCorrection() {
|
||||
try {
|
||||
await this.correctWords()
|
||||
this.$message.success('单词纠错完成')
|
||||
} catch (error) {
|
||||
this.$message.error(`单词纠错失败: ${error.message}`)
|
||||
}
|
||||
},
|
||||
async handleAnalysis() {
|
||||
try {
|
||||
await this.analyzeData()
|
||||
this.$message.success('分析完成')
|
||||
this.$notify({
|
||||
title: '分析完成',
|
||||
message: '文档分析已完成,点击"查看分析结果"按钮查看详细分析。',
|
||||
type: 'success',
|
||||
duration: 5000
|
||||
})
|
||||
} catch (error) {
|
||||
this.$message.error(`分析失败: ${error.message}`)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.process-container {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.process-header {
|
||||
text-align: center;
|
||||
margin-bottom: 40px;
|
||||
}
|
||||
|
||||
.process-title {
|
||||
font-size: 36px;
|
||||
font-weight: bold;
|
||||
margin-bottom: 10px;
|
||||
color: #262626;
|
||||
}
|
||||
|
||||
.process-subtitle {
|
||||
font-size: 18px;
|
||||
color: #666;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.process-icon {
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
.process-icon img {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
}
|
||||
|
||||
.process-steps {
|
||||
margin-bottom: 40px;
|
||||
}
|
||||
|
||||
.step-content {
|
||||
background-color: #fff;
|
||||
border-radius: 8px;
|
||||
padding: 30px;
|
||||
box-shadow: 0 2px 12px 0 rgba(0,0,0,0.1);
|
||||
min-height: 300px;
|
||||
}
|
||||
|
||||
.process-footer {
|
||||
margin-top: 30px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
font-size: 14px;
|
||||
color: #8c8c8c;
|
||||
}
|
||||
|
||||
.privacy-link {
|
||||
color: #1890ff;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.notification-option {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
</style>
|
||||
```
|
||||
|
||||
## 6. 模拟数据设置
|
||||
|
||||
### `src/utils/mock.js`
|
||||
|
||||
```js
|
||||
import Mock from 'mockjs'
|
||||
|
||||
// 上传文件响应
|
||||
Mock.mock('/api/upload', 'post', {
|
||||
code: 0,
|
||||
data: {
|
||||
fileName: '@name',
|
||||
fileId: '@guid',
|
||||
rowCount: '@integer(100, 1000)',
|
||||
columnCount: '@integer(5, 20)',
|
||||
previewData: Array(5).fill().map(() => ({
|
||||
id: '@id',
|
||||
name: '@cname',
|
||||
content: '@sentence(5, 15)',
|
||||
date: '@date',
|
||||
value: '@float(0, 100, 2, 2)'
|
||||
}))
|
||||
}
|
||||
})
|
||||
|
||||
// 预处理响应
|
||||
Mock.mock('/api/preprocess', 'post', {
|
||||
code: 0,
|
||||
data: {
|
||||
processedRows: '@integer(80, 90)',
|
||||
totalRows: '@integer(90, 100)',
|
||||
duration: '@float(1, 5, 2)',
|
||||
summary: '预处理已完成,共处理 @integer(80, 100) 行数据,清洗了 @integer(10, 30) 个异常值,标准化了 @integer(5, 15) 个格式不一致的字段。',
|
||||
sampleData: Array(3).fill().map(() => ({
|
||||
id: '@id',
|
||||
original: '@sentence(5, 15)',
|
||||
processed: '@sentence(5, 15)',
|
||||
changes: '@integer(1, 5)'
|
||||
}))
|
||||
}
|
||||
})
|
||||
|
||||
// 合并格式响应
|
||||
Mock.mock('/api/merge', 'post', {
|
||||
code: 0,
|
||||
data: {
|
||||
mergedFormats: '@integer(3, 10)',
|
||||
consistencyScore: '@float(80, 99, 2)',
|
||||
duration: '@float(0.5, 3, 2)',
|
||||
summary: '合并格式已完成,统一了 @integer(3, 10) 种不同的数据格式,数据一致性得分达到 @float(80, 99, 2)%。',
|
||||
sampleData: Array(3).fill().map(() => ({
|
||||
id: '@id',
|
||||
beforeMerge: '@sentence(5, 15)',
|
||||
afterMerge: '@sentence(5, 15)',
|
||||
formatType: '@word(4, 8)'
|
||||
}))
|
||||
}
|
||||
})
|
||||
|
||||
// 单词纠错响应
|
||||
Mock.mock('/api/correct', 'post', {
|
||||
code: 0,
|
||||
data: {
|
||||
totalWords: '@integer(1000, 5000)',
|
||||
correctedWords: '@integer(10, 100)',
|
||||
accuracyRate: '@float(95, 99, 2)',
|
||||
duration: '@float(1, 4, 2)',
|
||||
summary: '单词纠错已完成,检查了 @integer(1000, 5000) 个单词,纠正了 @integer(10, 100) 个拼写错误,准确率达到 @float(95, 99, 2)%。',
|
||||
corrections: Array(5).fill().map(() => ({
|
||||
id: '@id',
|
||||
original: '@word(3, 8)',
|
||||
corrected: '@word(3, 8)',
|
||||
confidence: '@float(60, 100, 2)'
|
||||
}))
|
||||
}
|
||||
})
|
||||
|
||||
// 大模型分析响应
|
||||
Mock.mock('/api/analyze', 'post', {
|
||||
code: 0,
|
||||
data: {
|
||||
documentId: '@guid',
|
||||
analysisDate: '@datetime',
|
||||
duration: '@float(3, 10, 2)',
|
||||
summary: '文档分析已完成,提取了关键词、词频、文本共现关系等信息。可以在分析页面查看详细结果。',
|
||||
// 词频数据
|
||||
termFrequencies: Array(50).fill().map(() => ({
|
||||
term: '@word(2, 8)',
|
||||
frequency: '@integer(1, 300)',
|
||||
isHighlighted: '@boolean'
|
||||
})),
|
||||
// 文档段落分析数据,用于趋势图
|
||||
documentSegments: Array(10).fill().map((_, index) => ({
|
||||
segmentId: index + 1,
|
||||
segmentName: `段落${index + 1}`,
|
||||
termFrequencies: Array(20).fill().map(() => ({
|
||||
term: '@word(2, 8)',
|
||||
frequency: '@float(0, 0.1, 4)'
|
||||
}))
|
||||
})),
|
||||
// 上下文数据
|
||||
contexts: Array(20).fill().map(() => ({
|
||||
term: '@word(2, 8)',
|
||||
instances: Array('@integer(1, 10)').fill().map(() => ({
|
||||
leftContext: '@sentence(3, 8)',
|
||||
keyword: '@word(2, 8)',
|
||||
rightContext: '@sentence(3, 8)',
|
||||
sourceParagraph: '@integer(1, 10)'
|
||||
}))
|
||||
})),
|
||||
// 搭配词数据
|
||||
collocates: Array(20).fill().map(() => ({
|
||||
term: '@word(2, 8)',
|
||||
cooccurrences: Array('@integer(3, 15)').fill().map(() => ({
|
||||
word: '@word(2, 8)',
|
||||
frequency: '@integer(1, 50)',
|
||||
position: '@pick(["left", "right"])',
|
||||
distance: '@integer(1, 5)'
|
||||
}))
|
||||
}))
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
以上实施指南提供了项目的核心结构、配置和几个关键组件的实现示例,可作为项目实施的起点。后续可根据具体需求继续扩展和完善各个组件和功能。
|
@ -0,0 +1,80 @@
|
||||
---
|
||||
description:
|
||||
globs:
|
||||
alwaysApply: true
|
||||
---
|
||||
# Project Overview: Vue 2 Text Analysis Application
|
||||
|
||||
## 1. Project Goal
|
||||
|
||||
Develop a Vue 2 frontend application with two main views:
|
||||
* A multi-step file processing interface (`/process`).
|
||||
* A results analysis and visualization interface (`/analysis`), inspired by Voyant Tools.
|
||||
|
||||
## 2. Core Technology Stack
|
||||
|
||||
* **Framework:** Vue 2 (Options API preferred)
|
||||
* **Build Tool:** Vue CLI ([vue.config.js](mdc:vue2/vue.config.js))
|
||||
* **Language:** JavaScript (ES6+) or TypeScript
|
||||
* **State Management:** Vuex (Expected in `src/store/`)
|
||||
* **Routing:** Vue Router (Expected in `src/router/`)
|
||||
* **UI Library:** Element UI (Recommended)
|
||||
* **Charting:** ECharts or Chart.js
|
||||
* **Word Cloud:** D3-Cloud or ECharts Wordcloud
|
||||
|
||||
## 3. Application Structure
|
||||
|
||||
The application is divided into two main views/routes:
|
||||
|
||||
* **`/process`**: Handles the file processing workflow.
|
||||
* **`/analysis`**: Displays the analysis results visually.
|
||||
|
||||
Router configuration is expected in `src/router/index.js` (or similar).
|
||||
Vuex store configuration is expected in `src/store/index.js` (or similar).
|
||||
The main application entry point is likely `[src/main.js](mdc:vue2/src/main.js)`.
|
||||
|
||||
## 4. Key Features
|
||||
|
||||
### `/process` View (File Processing)
|
||||
|
||||
* **UI Style:** Inspired by a specific visual design (blue background, clear steps).
|
||||
* **Workflow:** A 5-step process guided by an `el-steps` component:
|
||||
1. **File Upload:** Supports Excel/CSV, drag-and-drop, includes a modal (`el-dialog` with `el-table`) for viewing/editing uploaded data.
|
||||
2. **Preprocessing:** Calls backend API, displays intermediate results.
|
||||
3. **Merge Format:** Calls backend API, displays intermediate results.
|
||||
4. **Word Correction:** Calls backend API, displays intermediate results.
|
||||
5. **LLM Analysis:** Calls backend API, stores final results in Vuex, navigates to `/analysis`.
|
||||
* **User Interaction:** Step-by-step progression, loading indicators, error handling.
|
||||
|
||||
### `/analysis` View (Results Analysis)
|
||||
|
||||
* **UI Layout:** Multi-panel design resembling Voyant Tools.
|
||||
* **Components:**
|
||||
* **Terms Panel (Left):** `el-table` showing keyword frequencies, sortable, interactive.
|
||||
* **TermsBerry Panel (Center):** Word cloud visualization (ECharts/D3).
|
||||
* **Trends Panel (Top Right):** Line chart (ECharts) showing keyword frequency trends across document segments.
|
||||
* **Details Panel (Bottom):** `el-tabs` for switching between:
|
||||
* Summary: Basic text stats.
|
||||
* Contexts (KWIC): Keyword in context view.
|
||||
* Collocates: Words frequently appearing near the selected term.
|
||||
* (Optional) Documents, Phrases.
|
||||
* **Data Source:** Relies on analysis results stored in the Vuex store.
|
||||
* **Interactivity:** Panels are linked; selecting a term updates other panels.
|
||||
|
||||
## 5. State Management (Vuex)
|
||||
|
||||
* Manages analysis results passed from the `/process` view.
|
||||
* Handles interactive state for the `/analysis` view (e.g., selected terms).
|
||||
* Components interact with the store using standard Vuex helpers (`mapState`, `mapActions`, etc.).
|
||||
|
||||
## 6. Backend Interaction
|
||||
|
||||
* Frontend primarily handles UI, state management, and user interaction.
|
||||
* Assumes backend APIs handle the heavy lifting for file parsing, preprocessing, analysis, and correction steps.
|
||||
|
||||
## 7. Code Requirements
|
||||
|
||||
* Follow Vue 2 best practices.
|
||||
* Maintain clear component structure.
|
||||
* Implement robust error handling and loading states.
|
||||
* Focus on clean UI presentation using Element UI.
|
Loading…
Reference in new issue