Browse Source

AI模块优化

master
xuhuajiao 3 months ago
parent
commit
9f130034f1
  1. 1
      package.json
  2. 1
      src/vendors/ofd/ofd.js
  3. 30
      src/vendors/ofd/utils/ofd_render.js
  4. 1
      src/vendors/ofd/utils/ofd_util.js
  5. 26
      src/views/AIAssistant/AICataloging/running/index.vue
  6. 19
      src/views/AIAssistant/AIIntelligentCoding/aiForm.vue
  7. 23
      src/views/AIAssistant/AIIntelligentCoding/index.vue
  8. 21
      src/views/AIAssistant/AIKeywords/module/editOcrContent.vue
  9. 112
      src/views/collectReorganizi/collectionLibrary/module/collectHeader.vue

1
package.json

@ -52,6 +52,7 @@
"fuse.js": "3.4.4",
"handsontable": "^14.1.0",
"highlight.js": "^11.11.1",
"html-docx-js": "^0.3.1",
"html2canvas": "^1.4.1",
"jquery": "^3.2.1",
"js-beautify": "^1.10.2",

1
src/vendors/ofd/ofd.js

@ -148,7 +148,6 @@ export const digestCheck = function(options) {
}
export const setPageScale = function(scale) {
console.log('setPageScale', scale)
setPageScal(scale)
}

30
src/vendors/ofd/utils/ofd_render.js

@ -396,7 +396,9 @@ const renderLayer = function(
isStampAnnot,
compositeObjectBoundary
)
pageDiv.appendChild(element)
if (element) {
pageDiv.appendChild(element);
}
}
}
const pathObjects = layer['ofd:PathObject']
@ -415,7 +417,9 @@ const renderLayer = function(
compositeObjectBoundary,
compositeObjectCTM
)
pageDiv.appendChild(svg)
if (svg) {
pageDiv.appendChild(svg);
}
}
}
const textObjects = layer['ofd:TextObject']
@ -429,7 +433,9 @@ const renderLayer = function(
fillColor,
strokeColor
)
pageDiv.appendChild(svg)
if (svg) {
pageDiv.appendChild(svg);
}
}
}
const compositeObjects = layer['ofd:CompositeObject']
@ -488,10 +494,17 @@ export const renderImageObject = function(
let boundary = parseStBox(imageObject['@_Boundary'])
boundary = converterBox(boundary)
const resId = imageObject['@_ResourceID']
if (multiMediaResObj[resId].format === 'gbig2') {
const img = multiMediaResObj[resId].img
const width = multiMediaResObj[resId].width
const height = multiMediaResObj[resId].height
const mediaObj = multiMediaResObj[resId];
if (!mediaObj) {
// 处理 mediaObj 为 undefined 的情况,例如返回 null 或者抛出一个更友好的错误
return null;
}
if (mediaObj.format === 'gbig2') {
const img =mediaObj.img
const width = mediaObj.width
const height = mediaObj.height
return renderImageOnCanvas(
img,
width,
@ -504,7 +517,7 @@ export const renderImageObject = function(
return renderImageOnDiv(
pageWidth,
pageHeight,
multiMediaResObj[resId].img,
mediaObj.img,
boundary,
false,
isStampAnnot,
@ -832,7 +845,6 @@ export const renderPathObject = function(
// path.setAttribute('stroke', `url(#${pathObject['@_ID']})`);
// }
}
console.log('defaultFillColor', defaultFillColor)
if (pathObject['@_Fill'] != 'false') {
path.setAttribute(
'fill',

1
src/vendors/ofd/utils/ofd_util.js

@ -174,7 +174,6 @@ export const setPageScal = function(scale) {
// scale = Math.ceil(scale);
Scale = scale > 1 ? scale : 1
Scale = Scale > 10 ? 10 : Scale
console.log('setPageScal', Scale)
}
export const getPageScal = function() {

26
src/views/AIAssistant/AICataloging/running/index.vue

@ -98,7 +98,11 @@
<Detail ref="aiCatalogingFile" :is-histroy="isHistroy" />
<!-- 文件上传 -->
<el-dialog class="fileUpload-dialog" title="文件上传" :close-on-click-modal="false" :modal-append-to-body="false" append-to-body :visible.sync="uploadVisible" :before-close="handleClose">
<el-dialog class="fileUpload-dialog" :close-on-click-modal="false" :modal-append-to-body="false" append-to-body :visible.sync="uploadVisible" :before-close="handleClose">
<template #title>
文件上传
<span style="color: red;font-size: 12px; ">单个文件超过10M请用大文件上传</span>
</template>
<div class="setting-dialog">
<div class="upload-container">
<i v-if="fileList.length === 0" class="iconfont icon-tianjiawenjian upload-icon" />
@ -125,7 +129,16 @@
<span class="dialog-left-bottom" />
<div class="setting-dialog">
<div class="dialog-delt">
<div style="font-size: 14px; color: #0C0E1E; line-height: 20px;">
<ul style="line-height: 24px; padding: 0 10px;">
<li>AI辅助著录可支持的文件格式包括</li>
<li style="margin-bottom: 10px;">1.文本文件<br><span style="font-weight: bold;">doc/docxtxt</span></li>
<li style="margin-bottom: 10px;">2.电子表格和演示文稿<br><span style="font-weight: bold;">xls/xlsxppt/pptx</span></li>
<li style="margin-bottom: 10px;">3.图像文件<br><span style="font-weight: bold;">jpge/jpgpng</span></li>
<li>4.其他文件<br> <span style="font-weight: bold;">pdfofd</span></li>
<li style="color: #0C0E1E; margin-top: 20px;">注意目前支持<span style="color: #ED4A41;">单次上传多个图像文件或1个非图像文件单个文件的大小不得超过10M</span>文件解析耗时根据文件的大小以及类型各有不同用户可在上传成功后手动点击刷新按钮更新文件解析状态</li>
</ul>
<!-- <div style="font-size: 14px; color: #0C0E1E; line-height: 20px;">
应盘 =
<span style="color: #12C37A;">已盘</span> +
<span style="color: #12C37A;">已借</span> +
@ -142,7 +155,7 @@
<li><span style="font-weight:bold;color: #ED4A41; border-color: #FBB5B5; background-color: #FCE9E9;">未盘</span><p>在当前盘点单中未被盘点到的档案文件或档案盒默认状态</p></li>
<li><span style="font-weight:bold;color: #ED4A41; border-color: #FBB5B5; background-color: #FCE9E9;">异常</span><p>在按件盘点时已借档案被盘点到盘点时自动变更状态在按盒盘点时盒内档案数量异常盘点时手动变更状态</p></li>
<li><span style="font-weight:bold;color: #8B43F0; border-color: #CAA4FF; background-color: #F4EDFF;">多盘</span><p>不在当前盘点单中但被盘点到的档案文件或档案盒</p></li>
</ul>
</ul> -->
</div>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click.native="tipContentVisible = false">确定</el-button>
@ -761,7 +774,6 @@ export default {
}
}
}
console.log('newFormData', newFormData)
this.$refs.previewForm.addOrUpdateForm = newFormData
}
@ -798,7 +810,11 @@ export default {
}
FetchHandleEnterAnalysis(params).then(data => {
console.log('data', data)
this.$message({ message: data, type: 'success', offset: 8 })
if (data.code !== 500) {
this.$message({ message: data, type: 'success', offset: 8 })
} else {
this.$message({ message: '新增档案失败', type: 'error', offset: 8 })
}
this.crud.toQuery()
this.handleClose()
})

19
src/views/AIAssistant/AIIntelligentCoding/aiForm.vue

@ -95,9 +95,19 @@
/>
<div class="ai-form-btn">
<div style="position: relative;">
<input ref="fileInput" type="file" style="display: block; width: 40px; position: absolute; top: 0; left: 0; opacity: 0;" @change="handleFileChange">
<i class="iconfont icon-attachment" />
</div>
<input ref="fileInput" type="file" style="display: block; width: 40px; position: absolute; top: 0; left: 0; opacity: 0; pointer-events: none;" @change="handleFileChange">
<el-popover
placement="top-start"
width="270"
trigger="hover"
>
<div>
此处可支持的文件格式包括<br>
<span style="display:inline-block; font-weight: bold; margin-bottom: 10px;">doc/docxtxtxls/xlsxppt/pptxpdfofd</span>
注意单次只可上传1个文件且文件的大小不得超过10M
</div>
<i slot="reference" class="iconfont icon-attachment" @click="openFileSelector" />
</el-popover></div>
<span class="line" />
<i class="iconfont icon-fasong-jiantou" @click="sendMessage" />
</div>
@ -192,6 +202,9 @@ export default {
console.log(err)
})
},
openFileSelector() {
this.$refs.fileInput.click()
},
async handleFileChange(event) {
const file = event.target.files[0]
const allowedExtensions = ['.xlsx', '.xls', '.docx', '.doc', '.pdf', '.ofd', '.pptx', '.txt']

23
src/views/AIAssistant/AIIntelligentCoding/index.vue

@ -68,11 +68,15 @@
<div class="setting-dialog">
<!-- overflow-y: scroll; -->
<div style="width: 100%;">
<div style="margin: 20px; line-height: 30px;">
<p>专题名称{{ currentResearch && currentResearch.researchTitle }}</p>
<p>编研类型{{ currentResearch && currentResearch.researchType }}</p>
<div style="display: flex; justify-content: space-between; align-items: center;">
<div style="margin: 20px; line-height: 30px;">
<p>专题名称{{ currentResearch && currentResearch.researchTitle }}</p>
<p>编研类型{{ currentResearch && currentResearch.researchType }}</p>
</div>
<el-button @click="exportToWord">导出为 Word</el-button>
</div>
<mavon-editor
ref="editorRef"
class="md"
:value="onlineContent"
:subfield="false"
@ -96,6 +100,9 @@ import crudOperation from '@crud/CRUD.operation'
import aiForm from './aiForm'
import { mapGetters } from 'vuex'
import { saveAs } from '@/utils/index'
import htmlDocx from 'html-docx-js/dist/html-docx'
export default {
name: 'AIIntelligentCoding',
components: { pagination, crudOperation, aiForm },
@ -143,6 +150,16 @@ export default {
mounted() {
},
methods: {
// word
exportToWord() {
if (this.onlineContent) {
const htmlContent = this.$refs.editorRef.markdownIt.render(this.onlineContent)
const wordBlob = htmlDocx.asBlob(htmlContent)
saveAs(wordBlob, this.currentResearch && this.currentResearch.researchTitle + '.docx')
} else {
this.$message({ message: '编研内容错误', type: 'error', offset: 8 })
}
},
initData() {
this.crud.refresh()
this.crud.selections = []

21
src/views/AIAssistant/AIKeywords/module/editOcrContent.vue

@ -246,6 +246,8 @@ export default {
console.log('output', output)
// dom
const node = document.createElement('div')
console.log('node', node)
console.log('this.last', this.last)
// vuedom
if (this.last) {
output.removeChild(this.last.$el)
@ -302,6 +304,16 @@ export default {
handleCloseDialog() {
this.ocrVisible = false
this.savingBtn = false
this.swiperImg = []
// // output
// const { output } = this.$refs
// if (output) {
// // output
// while (output.firstChild) {
// output.removeChild(output.firstChild)
// }
// }
},
handleComfiredAnalysised() {
this.savingBtn = true
@ -421,4 +433,13 @@ export default {
::v-deep .home_wrap .pdf_down{
display: none;
}
::v-deep .ofd_view {
position: relative;
.el-header{
position: absolute !important;
left: 0 !important;
top: 0 !important;
width: calc(100%) !important;
}
}
</style>

112
src/views/collectReorganizi/collectionLibrary/module/collectHeader.vue

@ -173,7 +173,7 @@
</el-dialog>
<!-- AI辅助著录未处理已解析的文件 -->
<el-dialog class="aiAssist-dialog" title="AI已解析文件" :close-on-click-modal="false" :modal-append-to-body="false" append-to-body :visible.sync="aIAssistEnterVisible">
<el-dialog class="aiAssist-dialog" title="AI已解析文件" :close-on-click-modal="false" :modal-append-to-body="false" append-to-body :visible.sync="aIAssistEnterVisible" :before-close="handleAIClose">
<div class="setting-dialog">
<!-- @select="crud.selectChange"
@select-all="crud.selectAllChange"
@ -185,9 +185,59 @@
class="archives-table"
:data="aiCategoryData"
row-key="id"
height="calc(100vh - 300px)"
:default-expanded-rows="expandedRows"
@expand-change="handleExpandChange"
>
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="任务编号" prop="id" />
<el-table-column type="expand">
<template slot-scope="{row }">
<el-table v-loading="row.childLoading" :data="row.children" class="child-table" :show-header="false">
<el-table-column width="100" align="center" />
<el-table-column prop="fileName" label="文件名称" show-overflow-tooltip min-width="200">
<template slot-scope="scope">
<i class="iconfont icon-attachment" />
<span style="margin-left: 10px">{{ scope.row.fileName }}</span>
</template>
</el-table-column>
<!-- <el-table-column prop="fileType" label="格式" min-width="60" align="center" /> -->
<el-table-column prop="fileSize" label="大小" min-width="85" align="center">
<template slot-scope="scope">
{{ getFileSize(scope.row.fileSize) }}
</template>
</el-table-column>
<el-table-column prop="fileThumbnail" label="缩略图" min-width="60" align="center">
<template slot-scope="scope">
<div v-if="scope.row.fileType === 'jpg' || scope.row.fileType === 'jpeg' || scope.row.fileType === 'png' || scope.row.fileType === 'bmp'|| scope.row.fileType === 'gif'">
<i class="fileIcon icon-image" />
</div>
<div v-else-if="scope.row.fileType === 'xlsx' || scope.row.fileType === 'xls'">
<i class="fileIcon icon-excel" />
</div>
<div v-else-if="scope.row.fileType === 'docx' || scope.row.fileType === 'doc'">
<i class="fileIcon icon-word" />
</div>
<div v-else-if="scope.row.fileType === 'pdf'">
<i class="fileIcon icon-pdf" />
</div>
<div v-else-if="scope.row.fileType === 'ppt' || scope.row.fileType === 'pptx'">
<i class="fileIcon icon-ppt" />
</div>
<div v-else-if="scope.row.fileType === 'zip' || scope.row.fileType === 'rar'">
<i class="fileIcon icon-zip" />
</div>
<div v-else-if="scope.row.fileType === 'txt'">
<i class="fileIcon icon-txt" />
</div>
<div v-else>
<i class="fileIcon icon-other" />
</div>
</template>
</el-table-column>
</el-table>
</template>
</el-table-column>
<el-table-column label="任务编号" prop="id" min-width="280" />
<el-table-column label="文件数量" prop="fileNum" />
<el-table-column label="创建人" prop="create_by" />
<el-table-column label="创建时间" prop="update_time" align="center" width="160">
@ -202,7 +252,7 @@
<div v-else>-</div>
</template>
</el-table-column>
<el-table-column label="状态" prop="status" align="center" width="140">
<el-table-column label="状态" prop="status" align="center" width="80">
<template slot-scope="scope">
<span v-if="!scope.row.isAnalysis" class="row-state row-warehousing state-active">解析中</span>
<span v-else class="row-state row-binding state-active">已解析</span>
@ -216,6 +266,7 @@
</el-button>
</template>
</el-table-column>
</el-table>
</div>
</el-dialog>
@ -283,7 +334,7 @@ import CRUD, { crud } from '@crud/crud'
import { collectionLibraryCrud } from '../mixins/index'
import { FetchInitCategoryInputFieldByPid, FetchCategoryMenu } from '@/api/system/category/category'
import { FetchDetailsById, collectDel, FetchRemoveArchivesSingle, FetchDeleteArchivesFile, FetchUpdateArchivesNo, FetchDisbandArchives, FetchReturnReDocument, FetchCompleteDelArchives, FetchRestoreArchives, FetchMaxItemNoByParentId } from '@/api/collect/collect'
import { FetchInitAssistEnter, FetchDoHandleEnterAnalysis } from '@/api/ai/ai'
import { FetchInitAssistEnter, FetchDoHandleEnterAnalysis, FetchInitAssistEnterTemp } from '@/api/ai/ai'
import { FetchArchivesClassTree } from '@/api/system/archivesClass'
import Treeselect from '@riophae/vue-treeselect'
import '@riophae/vue-treeselect/dist/vue-treeselect.css'
@ -365,6 +416,8 @@ export default {
aIAssistEnterVisible: false,
aiCategoryData: [],
aiCategoryloading: false,
childLoading: false,
expandedRows: [],
aiResultCaLoading: true, // ailoading
isDialogClosed: false, //
reader: null //
@ -1486,11 +1539,13 @@ export default {
'isHandle': 0
}
FetchInitAssistEnter(params).then(data => {
data.forEach(function(item, index) {
item.hasChildren = true
item.children = null
item.childLoading = false
})
this.aiCategoryData = data
this.aiCategoryloading = false
setTimeout(() => {
this.getDoHandleEnterAnalysis()
}, 1000)
})
},
//
@ -1499,13 +1554,48 @@ export default {
this.aIAssistEnterVisible = false
const params = {
'categoryId': this.selectedCategory.id,
'anId': null
'anId': row.id
}
FetchDoHandleEnterAnalysis(params).then(data => {
// const inputMessage = data.query + '' + data.context
this.sendMessage(data.query, data.context)
})
},
handleExpandChange(row, expandedRows) {
if (expandedRows.length > 0) {
//
this.loadFile(row)
} else {
//
row.children = null
}
},
loadFile(row) {
row.childLoading = true
const params = {
'anId': row ? row.id : null
}
FetchInitAssistEnterTemp(params).then(data => {
row.children = data
setTimeout(() => {
row.childLoading = false
}, 500)
}).catch(error => {
console.error('请求接口失败', error)
setTimeout(() => {
row.childLoading = false
}, 500)
})
},
handleAIClose() {
this.aiCategoryData = []
this.aIAssistEnterVisible = false
},
getFileSize(fileSize) {
const fileSizeInKB = (fileSize / 1024).toFixed(2) + 'kB'
const fileSizeInB = fileSize + 'B'
return (fileSize / 1024) <= 0.01 ? fileSizeInB : fileSizeInKB
},
// deepseek
async sendMessage(prompt, context) {
const linkSrc = process.env.NODE_ENV === 'production' ? window.g.AIDeepSeekUrl : process.env.VUE_APP_AIDEEPSEEK_API
@ -1644,7 +1734,7 @@ export default {
}
.aiAssist-dialog{
::v-deep .el-dialog{
width: 1000px !important;
width: 1160px !important;
}
}
@ -1659,5 +1749,7 @@ pre {
overflow: hidden;
overflow-y: auto;
}
::v-deep .el-table.child-table tr{
background-color: #f0f9eb;
}
</style>
Loading…
Cancel
Save