@@ -95,9 +100,12 @@ import { getCurrentTime } from '@/utils/index'
import { archivesUpload } from '@/utils/upload'
import { mapGetters } from 'vuex'
+import Chat from './Chat.vue'
+import DeepSeekChat from './deepSeekChat.vue'
+
export default {
name: 'AICataloging',
- components: { PreviewForm },
+ components: { PreviewForm, DeepSeekChat, Chat },
cruds() {
return [
CRUD({
diff --git a/src/views/AIAssistant/AICataloging/running/index.vue b/src/views/AIAssistant/AICataloging/running/index.vue
index 20c39c3..b74af55 100644
--- a/src/views/AIAssistant/AICataloging/running/index.vue
+++ b/src/views/AIAssistant/AICataloging/running/index.vue
@@ -1,16 +1,38 @@
-
-
-
- AI著录文件上传
-
+
-
-
-
+
+
- 解析中
-
+ 解析中
+ 已解析
- 已处理
+ 已处理
-
-
-
-
-
+
+
+
新增档案
+
+
+ {{ scope.row.handleTime | parseTime }}
+ -
+
+
+
+
+
+
+
+
+
+
+
+
+ 应盘 =
+ 已盘 +
+ 已借 +
+ 错位 +
+ 未盘 +
+ 异常
+ 多盘为非本盘点单计数
+
+
+ - 应盘
当前盘点单中涉及到的全部档案文件或档案盒的数量
+ - 已盘
正确的档案文件或档案盒在正确的位置被盘点到
+ - 已借
在当前盘点单中,已经借出的档案文件(按盒盘点时,无已借数量)
+ - 错位
在当前盘点单中,盘点到不属于当前位置的档案文件或档案盒
+ - 未盘
在当前盘点单中,未被盘点到的档案文件或档案盒(默认状态)
+ - 异常
在按件盘点时,已借档案被盘点到,盘点时自动变更状态;在按盒盘点时,盒内档案数量异常,盘点时手动变更状态
+ - 多盘
不在当前盘点单中但被盘点到的档案文件或档案盒
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ data.label }}
+
+
+ {{ data.label }}
+
+
+ {{ data.label }}
+
+
+ {{ data.label }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -79,17 +204,21 @@
import CRUD, { presenter, header, crud } from '@crud/crud'
import pagination from '@crud/Pagination'
import Detail from './module/detail'
+import PreviewForm from '@/views/components/category/PreviewForm'
-import { archivesUpload } from '@/utils/upload'
+import { aiUpload } from '@/utils/upload'
import { getCurrentTime } from '@/utils/index'
import { mapGetters } from 'vuex'
-import { FetchAIResultZhulu } from '@/api/collect/collect'
+// import { FetchAIResultZhulu } from '@/api/collect/collect'
+import { FetchInitCategoryInputFieldByPid, FetchCategoryMenu } from '@/api/system/category/category'
+import { getfondMenu } from '@/api/category/category'
+import { FetchDoHandleEnterAnalysis } from '@/api/ai/ai'
export default {
name: 'Running',
- components: { pagination, Detail },
+ components: { pagination, Detail, PreviewForm },
cruds() {
- return CRUD({ title: '处理中', url: 'api/flowable/getFlowList', crudMethod: {},
+ return CRUD({ title: 'AI著录', url: 'api/ai/initAssistEnter', crudMethod: {},
optShow: {
add: false,
edit: false,
@@ -107,8 +236,24 @@ export default {
default: false
}
},
+ provide() {
+ return {
+ parentsData: this
+ }
+ },
data() {
return {
+ selectStatus: null,
+ stateOptions: [
+ {
+ value: 1,
+ label: '已解析'
+ },
+ {
+ value: 0,
+ label: '未解析'
+ }
+ ],
aiLoading: false,
permission: {},
uploadVisible: false,
@@ -119,23 +264,69 @@ export default {
typingInterval: null,
typingFinished: false,
currentLineIndex: 0,
- shouldContinueFetching: true
+ shouldContinueFetching: true,
+ tipContentVisible: false,
+ categoryVisible: false,
+ defaultProps: {
+ children: 'children',
+ label: 'label'
+ },
+ currentAnId: {},
+ categoryMenu: [],
+ fondsMenu: [],
+ aiAddArchiveCategory: {},
+ formVisible: false,
+ formTitle: '新增档案',
+ formPreviewData: [],
+ isDesFormType: 'arcives',
+ arcId: null,
+ isTitleType: 2,
+ aiResultCaLoading: true,
+ messages: []
}
},
computed: {
...mapGetters([
'baseApi'
- ])
+ ]),
+ collectLevel() {
+ if (this.isTitleType === 2) {
+ return 1
+ } else if (this.isTitleType === 3) {
+ if (this.aiAddArchiveCategory.arrangeType === 1) {
+ return 3
+ } else {
+ return 2
+ }
+ } else if (this.isTitleType === 4) {
+ return 3
+ } else if (this.isTitleType === 6) {
+ return 4
+ }
+ return null
+ }
},
mounted() {
+ this.getCategoryDataTree()
},
methods: {
+ getCategoryDataTree() {
+ FetchCategoryMenu().then(res => {
+ this.categoryMenu = res
+ })
+ },
[CRUD.HOOK.beforeRefresh]() {
if (this.isHistroy) {
- this.crud.query.isEnd = true
+ this.crud.query.isHandle = 1
} else {
- this.crud.query.isEnd = false
+ this.crud.query.isHandle = 0
}
+ this.crud.query.isAnalysis = this.selectStatus
+ },
+ resetQuery() {
+ this.selectStatus = null
+ this.crud.query = {}
+ this.crud.toQuery()
},
// table - 双击查看详情
tableDoubleClick(row) {
@@ -143,15 +334,12 @@ export default {
this.$refs.aiCatalogingFile.getFileList()
},
async changeAiFile(e) {
- // 替换文件时清空 aiJsonData
+ // 替换文件时清空 aiJsonData
this.aiJsonData = null
this.currentLineIndex = 0
this.displayedText = ''
this.typingFinished = false
this.typingInterval = null
- // if (this.typingInterval) {
- // clearInterval(this.typingInterval);
- // }
const selectedFiles = Array.from(e.target.files)
const imageFiles = selectedFiles.filter(file => file.type.startsWith('image/'))
@@ -160,6 +348,7 @@ export default {
// 不允许同时选择图片和非图片文件
if (imageFiles.length > 0 && nonImageFiles.length > 0) {
this.$message.error('不能同时选择图片和其他类型文件,请重新选择')
+ e.target.value = '' // 清空文件选择框
return
}
@@ -167,21 +356,25 @@ export default {
const existingNonImageFiles = this.fileList.filter(item => item.formatType !== 'image')
if (imageFiles.length > 0) {
- // if (existingImageFiles.length > 0) {
- // if (existingImageFiles.length + imageFiles.length > 3) {
- // // 若加入新图片会超过 3 张,清空已有图片
- // this.fileList = this.fileList.filter(item => item.formatType !== 'image')
- // }
- // } else if (existingNonImageFiles.length > 0) {
- // // 若已有非图片文件,清空已有非图片文件
- // this.fileList = this.fileList.filter(item => item.formatType === 'image')
- // }
-
- // // 检查图片文件数量
- // if (imageFiles.length > 3) {
- // this.$message.error('图片文件最多只能选择 3 个,请重新选择')
- // return
- // }
+ const maxSize = 10 * 1024 * 1024 // 10M
+ let totalImageSize = 0
+
+ // 计算已有图片文件的总大小
+ for (const existingFile of existingImageFiles) {
+ totalImageSize += existingFile.size
+ }
+
+ // 统计所选图片文件的总大小
+ for (const file of imageFiles) {
+ totalImageSize += file.size
+ }
+
+ if (totalImageSize > maxSize) {
+ this.$message.error('所选图片文件总大小超过 10M,请重新选择')
+ e.target.value = '' // 清空文件选择框
+ return
+ }
+
if (existingNonImageFiles.length > 0) {
// 若已有非图片文件,清空已有非图片文件
this.fileList = this.fileList.filter(item => item.formatType === 'image')
@@ -212,8 +405,16 @@ export default {
this.fileList.push(fileInfo)
}
- this.FetchAiFileUplaod(this.fileList)
} else if (nonImageFiles.length > 0) {
+ const maxSingleNonImageSize = 10 * 1024 * 1024 // 单个非图片文件最大 10M
+ for (const file of nonImageFiles) {
+ if (file.size > maxSingleNonImageSize) {
+ this.$message.error(`文件 ${file.name} 大小超过 10M,请重新选择`)
+ e.target.value = '' // 清空文件选择框
+ return
+ }
+ }
+
if (existingNonImageFiles.length > 0) {
// 若已有非图片文件,直接替换
this.fileList = this.fileList.filter(item => item.formatType === 'image')
@@ -225,6 +426,7 @@ export default {
// 检查非图片文件数量
if (nonImageFiles.length > 1) {
this.$message.error('非图片文件最多只能选择 1 个,请重新选择')
+ e.target.value = '' // 清空文件选择框
return
}
@@ -272,41 +474,49 @@ export default {
})
console.log('promiseArray', promiseArray)
const fileDefault = files.map(item => item.file)
+ console.log('fileDefault', fileDefault)
+
// this.selectedCategory.id,
// this.arcId,
Promise.all(promiseArray)
.then((arrayUpload) => {
- archivesUpload(this.baseApi + '/api/collect/uploadAssistEnterFiles',
+ console.log('arrayUpload', arrayUpload)
+ aiUpload(this.baseApi + '/api/ai/uploadAssistEnterFiles',
fileDefault,
JSON.stringify(arrayUpload)
).then(res => {
+ console.log('eee', res)
if (res.data.data !== null) {
- const params = {
- 'code': res.data.data.code,
- 'id': res.data.data.id
- }
- const fetchAiZhuluResult = () => {
- // 检查是否应该继续请求
- if (!this.shouldContinueFetching) return
-
- FetchAIResultZhulu(params).then((res) => {
- const data = JSON.parse(res)
- console.log('data', data)
- if (data.result !== null && data.status === 'success') {
- this.$message({ message: '解析著录附件成功', type: 'success', offset: 8 })
- this.aiJsonData = data.result
- this.startTypingEffect()
- } else {
- setTimeout(fetchAiZhuluResult, 3000)
- }
- }).catch(err => {
- console.log(err)
- })
- }
- fetchAiZhuluResult()
+ console.log(res.data.data)
+ this.$message({ message: '著录附件传输成功', type: 'success', offset: 8 })
+ this.crud.toQuery()
+ // const params = {
+ // 'code': res.data.data.code,
+ // 'id': res.data.data.id
+ // }
+ // const fetchAiZhuluResult = () => {
+ // // 检查是否应该继续请求
+ // if (!this.shouldContinueFetching) return
+
+ // FetchAIResultZhulu(params).then((res) => {
+ // const data = JSON.parse(res)
+ // console.log('data', data)
+ // if (data.result !== null && data.status === 'success') {
+ // this.$message({ message: '解析著录附件成功', type: 'success', offset: 8 })
+ // this.aiJsonData = data.result
+ // this.startTypingEffect()
+ // } else {
+ // setTimeout(fetchAiZhuluResult, 3000)
+ // }
+ // }).catch(err => {
+ // console.log(err)
+ // })
+ // }
+ // fetchAiZhuluResult()
} else {
this.$message({ message: '著录附件传输失败', type: 'error', offset: 8 })
}
+ this.handleClose()
})
})
.catch((error) => {
@@ -348,7 +558,7 @@ export default {
const index = this.fileList.indexOf(file)
this.fileList.splice(index, 1)
if (this.fileList.length !== 0) {
- // archivesUpload(this.baseApi + '/api/collect/uploadFiles', this.fileList, this.selectedCategory.id).then(res => {
+ // aiUpload(this.baseApi + '/api/collect/uploadFiles', this.fileList, this.selectedCategory.id).then(res => {
// if (res.data.code === 200) {
// this.filePath = res.data.data
// }
@@ -378,10 +588,226 @@ export default {
resolve({ width, height })
}
})
+ },
+ handleClose() {
+ this.uploadVisible = false
+ this.fileList = []
+ this.aiLoading = false
+ this.categoryVisible = false
+ this.aiAddArchiveCategory = {}
+ this.tipContentVisible = false
+ this.formVisible = false
+ },
+ onClickAddArchive(row) {
+ console.log('row', row)
+ this.categoryVisible = true
+ this.currentAnId = row
+ this.getfondMenu()
+ },
+ getfondMenu() {
+ getfondMenu().then(res => {
+ this.fondsMenu = this.filterData(this.transformData(res))
+ })
+ },
+ filterData(data) {
+ return data.filter(node => {
+ if (node.children && node.children.length > 0) {
+ node.children = this.filterData(node.children) // 递归处理子节点
+ }
+ return node.isType !== 3 // 过滤掉isType为3的节点
+ })
+ },
+ handleNodeClick(val) {
+ this.aiAddArchiveCategory = val
+ console.log('val', val)
+ if (this.aiAddArchiveCategory.arrangeType === 3) {
+ this.isTitleType = 2
+ } else if (this.aiAddArchiveCategory.arrangeType === 2) {
+ this.isTitleType = 3
+ } else if (this.aiAddArchiveCategory.arrangeType === 1) {
+ this.isTitleType = 3
+ }
+ },
+ handleCategoryForm() {
+ this.formTitle = '新增档案 - ' + this.aiAddArchiveCategory.cnName
+ this.formVisible = true
+ const params = {
+ 'categoryId': this.aiAddArchiveCategory.id,
+ 'categoryLevel': this.collectLevel
+ }
+ FetchInitCategoryInputFieldByPid(params).then(data => {
+ this.formPreviewData = data
+ this.isDesFormType = 'arcives'
+ this.$nextTick(() => {
+ this.$refs.previewForm.archivesType = 'add'
+ this.$refs.previewForm.FetchNoFormatField(this.aiAddArchiveCategory.id)
+ })
+ this.getDoHandleEnterAnalysis()
+ })
+ },
+ getDoHandleEnterAnalysis() {
+ const params = {
+ 'categoryId': this.aiAddArchiveCategory.id,
+ 'anId': this.currentAnId.id
+ }
+ FetchDoHandleEnterAnalysis(params).then(data => {
+ console.log(data)
+ const inputMessage = data.query + '需要提取得内容部分是' + data.context
+ this.sendMessage(inputMessage)
+ })
+ },
+ handlerArchivesSubmit() {
+
+ },
+ handleTipContent() {
+ this.tipContentVisible = true
+ },
+ transformData(rawData) {
+ return rawData.map(item => {
+ return {
+ label: item.fondName,
+ isType: 0,
+ id: item.fondsId,
+ fondsNo: item.fondsNo,
+ children: item.categoryList.map(category => {
+ return {
+ label: category.cnName,
+ cnName: category.cnName,
+ id: category.id,
+ arrangeType: category.arrangeType,
+ isType: category.isType,
+ fondsId: item.fondsId,
+ fondName: item.fondName,
+ fondsNo: item.fondsNo,
+ children: this.transformChildren(category.children, item.fondsId, item.fondName, item.fondsNo)
+ }
+ })
+ }
+ })
+ },
+ // 递归函数,用于处理数据的子节点
+ transformChildren(children, fondsId, fondName, fondsNo) {
+ return children.map(child => {
+ return {
+ label: child.cnName,
+ cnName: child.cnName,
+ id: child.id,
+ isType: child.isType,
+ pid: child.pid,
+ code: child.code,
+ arrangeType: child.arrangeType,
+ fondsId: fondsId,
+ fondName: fondName,
+ fondsNo: fondsNo,
+ children: child.children.length ? this.transformChildren(child.children, fondsId, fondName, fondsNo) : []
+ }
+ })
+ },
+ async sendMessage(inputMessage) {
+ this.displayedText = ''
+ try {
+ const response = await fetch('http://192.168.99.86:11434/api/generate', {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json'
+ },
+ body: JSON.stringify({
+ model: 'deepseek-r1:14b',
+ // model: 'qwen:7b',
+ prompt: inputMessage,
+ stream: true
+ })
+ })
+
+ if (!response.ok) {
+ throw new Error(`HTTP error! status: ${response.status}`)
+ }
+
+ const reader = response.body.getReader()
+ const decoder = new TextDecoder('utf-8')
+ let done = false
+
+ while (!done) {
+ this.aiResultCaLoading = false
+ const { done: isDone, value } = await reader.read()
+ done = isDone
+ if (done) break
+
+ const chunk = decoder.decode(value)
+ const lines = chunk.split('\n')
+
+ lines.forEach(line => {
+ if (line.trim() !== '') {
+ try {
+ const data = JSON.parse(line)
+ if (data.response) {
+ this.displayedText += data.response
+ }
+ } catch (error) {
+ console.error('解析JSON数据出错:', error)
+ }
+ }
+ })
+
+ // 滚动条始终保持在底部
+ const container = this.$refs.typingContainer
+ if (container) {
+ container.scrollTop = container.scrollHeight
+ }
+ }
+ } catch (error) {
+ console.error('请求出错:', error)
+ this.displayedText = '请求出错,请稍后再试。'
+ this.aiResultCaLoading = false
+ } finally {
+ this.aiResultCaLoading = false
+ console.log('this.displayedText.', this.displayedText)
+ // 提取 JSON 部分
+ const startIndex = this.displayedText.indexOf('{')
+ const endIndex = this.displayedText.lastIndexOf('}')
+ if (startIndex !== -1 && endIndex !== -1 && endIndex > startIndex) {
+ const jsonStr = this.displayedText.slice(startIndex, endIndex + 1)
+ console.log('jsonStr', jsonStr)
+ const jsonData = JSON.parse(jsonStr)
+ // // 过滤掉值为空的字段
+ // const filteredJsonData = Object.fromEntries(
+ // Object.entries(jsonData).filter(([_, value]) => {
+ // // 这里假设空字符串、null、undefined 是需要过滤的情况
+ // return value !== '' && value !== null && value !== undefined
+ // })
+ // )
+ console.log('提取并过滤后的 JSON 数据:', jsonData)
+ jsonData.fonds_no = this.aiAddArchiveCategory.fondsNo
+ jsonData.archival_category_code = this.aiAddArchiveCategory.code
+ console.log('jsonData', jsonData)
+ this.$refs.previewForm.addOrUpdateForm = jsonData
+ }
+ }
}
}
}