Browse Source

AI智能编研/AI知识图谱

master
xuhuajiao 4 months ago
parent
commit
070aaf7714
  1. 10
      src/api/ai/ai.js
  2. 596
      src/views/AIAssistant/AIIntelligentCoding/aiForm copy.vue
  3. 341
      src/views/AIAssistant/AIIntelligentCoding/aiForm.vue
  4. 5
      src/views/AIAssistant/AIKeywords/module/keywordMark.vue
  5. 136
      src/views/AIAssistant/AIknowledgeGraph/index.vue
  6. 4
      src/views/archivesStatistics/customDefinedStatistics/index.vue
  7. 124
      src/views/components/echarts/graph.vue

10
src/api/ai/ai.js

@ -36,4 +36,12 @@ export function FetchHandleEnterAnalysis(data) {
})
}
export default { FetchDoHandleEnterAnalysis, FetchInitAssistEnterTemp, FetchDelAssistEnter, FetchHandleEnterAnalysis }
// 根据门类初始化知识图谱
export function FetchInitShowByCategory(params) {
return request({
url: 'api/aineo/initShowByCategory' + '?' + qs.stringify(params, { indices: false }),
method: 'get'
})
}
export default { FetchDoHandleEnterAnalysis, FetchInitAssistEnterTemp, FetchDelAssistEnter, FetchHandleEnterAnalysis, FetchInitShowByCategory }

596
src/views/AIAssistant/AIIntelligentCoding/aiForm copy.vue

@ -1,370 +1,294 @@
<template>
<el-row :gutter="12" class="demo-radius">
<div
class="radius"
:style="{
borderRadius: 'base'
}"
>
<div id="messgebox" ref="scrollDiv" class="messge">
<ul>
<li
v-for="(item, index) in message"
:key="index"
style="list-style-type:none;"
>
<div
v-if="item.user == username"
class="mymsginfo"
style="float:right"
>
<div>
<el-dialog class="editingDialog" :title="formTitle" :visible="formVisible" append-to-body :close-on-click-modal="false" :modal-append-to-body="false" :before-close="handleCloseForm">
<span class="dialog-right-top" />
<span class="dialog-left-bottom" />
<div class="setting-dialog">
<div style="display: flex; justify-content: flex-start; align-items: flex-start;">
<div class="upload-input" style="margin-top: 0;">
<input
ref="file"
multiple
type="file"
@change="previewFiles"
<el-avatar
style="float: right;margin-right: 30px;background: #01bd7e;"
>
<div class="upload-zip"><i class="iconfont icon-shangchuan2" />上传文件</div>
<!-- {{ item.user.substring(0, 2) }} -->
<img :alt="item.user.substring(0, 2)" :src="userphoto">
</el-avatar>
</div>
<div v-if="selectedFiles.length > 0" style="flex: 1; max-height: 120px; overflow-y: auto; margin-left: 20px; line-height: 24px;">
<p v-for="(file, index) in selectedFiles" :key="index">{{ file.name }}</p>
<div
style="float: right;margin-right: 10px;margin-top:10px;width:80%;text-align: right;"
>
{{ item.msg }}
</div>
</div>
<div style="display: flex; justify-content: flex-start; align-items: flex-end; margin: 20px 0; ">
<el-input
v-model="textarea"
placeholder="请输入提问"
/>
<el-button style="margin-left: 20px;" :loading="loading" @click="handleAIEditing">AI智能编研</el-button>
<div v-else class="chatmsginfo">
<div>
<el-avatar style="float: left;margin-right: 10px;">
{{ item.user }}
</el-avatar>
</div>
<mavon-editor
ref="typingContainer"
class="md"
:value="editorContent"
:subfield="false"
:default-open="'preview'"
:toolbars-flag="false"
:editable="false"
:scroll-style="true"
:ishljs="true"
<div style="float: left;margin-top:10px;width:80%;">
<img
v-if="item.msg == ''"
alt="loading"
class="loading"
src=""
>
<MdPreview
style="margin-top:-20px;"
:auto-fold-threshold="9999"
:editor-id="id"
:model-value="item.msg + item.dot"
/>
<div slot="footer" class="dialog-footer">
<el-button type="text" @click="handleCloseForm">取消</el-button>
<el-button :loading="crud.status.cu === 2" type="primary" @click="handleComfiredEditing">确定</el-button>
<!-- {{ item.msg }} -->
</div>
</div>
</li>
</ul>
</div>
<div class="inputmsg">
<el-form :model="form">
<el-form-item>
<el-avatar
style="float: left;background: #01bd7e;margin-bottom: -44px;margin-left: 4px;z-index: 999;width: 30px;height: 30px;"
>
<img alt="jin" :src="userphoto">
</el-avatar>
<el-input
id="txt_suiwen"
v-model="form.desc"
:prefix-icon="userphoto"
resize="none"
autofocus="true"
:autosize="{ minRows: 1, maxRows: 2 }"
placeholder="说说你想问点啥....按Enter键可直接发送"
type="textarea"
@keydown.enter.native.prevent="startStreaming($event)"
/>
</el-form-item>
</el-form>
</div>
</el-dialog>
</div>
</el-row>
</template>
<script setup>
// import { MdPreview, MdCatalog } from 'md-editor-v3'
// import 'md-editor-v3/lib/preview.css'
// const id = 'preview-only'
</script>
<script>
import { form } from '@crud/crud'
import { mapGetters } from 'vuex'
// import editor from '@/components/quillEditor/index'
// import strJson from './str.json'
const defaultForm = { id: null, title: null, researchType: null, editor1: null, editor2: null, startTime: null, endTime: null, remarks: null }
export default {
name: 'Form',
components: { },
mixins: [
form(function() {
return Object.assign({}, defaultForm)
})
],
data() {
return {
formType: 1,
formTitle: '',
formVisible: false,
selectedFiles: [],
textarea: '帮我写一篇AI赋能档案管理的报告',
editorRef: 'test',
editorContent: '',
mockResponse: `## 一、引言
### 1.1 研究背景与意义
随着科技的飞速发展人工智能AI技术已逐渐渗透到各个行业成为推动创新和发展的重要力量AI 技术以其强大的数据分析模式识别和自动化处理能力正在重塑许多传统行业的运作方式在档案管理领域传统的管理模式面临着诸多挑战如档案数量的快速增长信息检索的效率低下档案利用的局限性等 AI 技术引入档案管理为解决这些问题提供了新的思路和方法
传统档案管理主要依赖人工操作从档案的收集整理分类到存储和检索都需要大量的人力和时间这种方式不仅效率低下而且容易出现人为错误随着数字化时代的到来电子档案的数量呈爆炸式增长传统的管理方式越发难以应对AI 技术的出现为档案管理带来了新的机遇它能够自动处理大量的档案数据实现档案的智能分类快速检索和精准推荐大大提高了档案管理的效率和准确性
AI 赋能档案管理具有重要的现实意义它可以显著提升档案管理的效率通过自动化的分类和索引AI 能够快速处理海量的档案信息使档案管理人员从繁琐的重复性工作中解放出来将更多的精力投入到更有价值的工作中AI 技术可以实现档案的精准检索和智能推荐提高档案的利用效率更好地满足用户的需求这有助于充分挖掘档案的价值为决策提供更有力的支持
AI 技术的应用还将推动档案管理行业的变革它促使档案管理从传统的人工模式向智能化数字化模式转变引领行业进入一个新的发展阶段这种变革不仅有助于提升档案管理机构的竞争力也为整个社会的信息资源管理和利用带来了新的契机通过 AI 技术档案管理机构可以更好地整合和利用档案资源为社会提供更优质的信息服务
### 1.2 研究方法与创新点
本研究采用了多种研究方法以确保研究的全面性和深入性通过广泛收集和分析国内外相关文献了解 AI 技术在档案管理领域的研究现状应用进展和发展趋势为研究提供理论基础和参考依据对国内外多个档案管理机构应用 AI 技术的实际案例进行深入分析总结其成功经验和存在的问题探索 AI 技术在档案管理中的最佳应用模式还与档案管理领域的专家从业人员进行交流和访谈获取他们对 AI 技术应用的看法和建议进一步丰富研究内容
本研究的创新点在于从多个维度对 AI 赋能档案管理进行分析不仅关注 AI 技术在档案管理中的应用效果还深入探讨其对档案管理流程组织架构和服务模式的影响结合实际案例 AI 技术在不同类型档案管理中的应用进行详细分析为档案管理机构提供具有针对性的实践指导此外本研究还前瞻性地探讨了 AI 技术在档案管理中的未来发展趋势为行业的长远发展提供参考
## AI 赋能档案管理的技术基础
### 2.1 AI 技术概述
AI 技术是一门综合性的技术领域旨在让计算机系统模拟人类的智能行为实现对复杂问题的理解推理学习和决策它涵盖了多个子领域其中机器学习深度学习自然语言处理计算机视觉等技术在档案管理中具有重要的应用价值
机器学习是 AI 的核心技术之一它通过让计算机从大量的数据中学习模式和规律从而实现对未知数据的预测和决策机器学习主要分为监督学习无监督学习和强化学习监督学习使用标记好的数据进行训练模型通过学习数据中的特征和标签之间的关系来预测新数据的标签在档案分类中可以使用监督学习算法将已分类的档案作为训练数据让模型学习不同类别档案的特征从而对新的档案进行自动分类无监督学习则处理未标记的数据通过聚类降维等方法发现数据中的内在结构和模式在档案管理中无监督学习可以用于对档案进行主题建模发现档案中的潜在主题帮助用户更好地理解档案内容强化学习通过智能体与环境的交互根据环境反馈的奖励信号来学习最优策略在档案检索中强化学习可以根据用户的反馈不断优化检索策略提高检索结果的准确性
深度学习是机器学习的一个分支它基于深度神经网络通过构建多层神经元来自动学习数据的高级特征深度学习在图像识别语音识别自然语言处理等领域取得了显著的成果在档案管理中深度学习可以用于图像识别如对档案中的图像进行文字识别图像分类等也可以用于语音识别将档案中的语音内容转换为文本方便进行检索和管理
自然语言处理致力于让计算机理解和处理人类语言它包括文本分类情感分析机器翻译问答系统等多个任务在档案管理中自然语言处理可以用于对档案文本进行关键词提取摘要生成帮助用户快速了解档案内容还可以用于构建智能问答系统用户可以通过自然语言提问获取所需的档案信息
计算机视觉主要研究如何让计算机理解和解释图像和视频信息它包括图像识别目标检测图像分割等技术在档案管理中计算机视觉可以用于对档案图像进行数字化处理如去噪增强修复等提高图像的质量和可读性还可以用于对档案中的图像进行内容分析识别图像中的人物场景等信息为档案的分类和检索提供支持
这些 AI 技术在档案管理中具有很强的适用性档案管理涉及大量的数据处理和信息分析工作传统的人工方式效率低下且容易出错AI 技术的自动化和智能化特点可以有效地提高档案管理的效率和准确性通过机器学习和深度学习算法可以实现档案的自动分类检索和推荐大大节省了人力和时间成本自然语言处理和计算机视觉技术可以让计算机更好地理解和处理档案中的文本和图像信息为用户提供更加便捷和智能的服务
### 2.2 与档案管理相关的 AI 技术应用
#### 图像识别技术在档案数字化中的应用
图像识别技术在档案数字化过程中发挥着关键作用在纸质档案数字化时通过高精度扫描仪将纸质档案转化为数字图像后图像识别技术可对这些图像进行处理如在某大型企业的档案数字化项目中利用先进的卷积神经网络CNN算法能准确识别档案图像中的文字图表等元素该技术可自动去除图像中的噪声划痕校正图像的倾斜角度增强文字的清晰度极大提高了图像质量为后续的文字识别和信息提取奠定了良好基础通过图像识别技术实现自动边界检测与切割能准确识别文档的边缘截取文件中的文字区域过滤掉空白边缘或杂物避免误识别和多余信息干扰提高了识别效率和准确性在处理包含多个内容区域的文档如表格多栏文本等时算法还能准确识别并分别处理每个区域通过布局分析识别图像中的文本区域非文本区域以及文本的结构信息如列标题段落表格等有效提升了复杂档案图像的处理能力
#### 语音识别技术在档案检索中的应用
语音识别技术为档案检索带来了新的便利在一些档案管理系统中用户只需说出检索关键词系统就能快速定位到相关档案以某政府档案管理部门为例其引入了基于深度学习的语音识别技术该技术采用了循环神经网络RNN及其变体长短时记忆网络LSTM能够有效处理语音中的时序信息准确识别各种口音和语速的语音指令用户在检索档案时无需手动输入关键词直接通过语音提问系统即可将语音转换为文本并在档案数据库中进行检索迅速返回相关档案信息这一应用不仅提高了检索效率还降低了用户的操作门槛特别适用于不熟悉键盘输入或需要快速获取信息的用户提升了档案服务的便捷性和用户体验
#### 自然语言处理技术在档案内容分析中的应用
自然语言处理技术在档案内容分析方面具有重要价值它可以对档案文本进行深度挖掘和分析实现关键词提取主题建模情感分析等功能在某高校的科研档案管理中利用自然语言处理技术对科研成果档案进行关键词提取能够准确提炼出档案中的核心概念和关键信息方便用户快速了解档案内容通过主题建模可将大量的科研档案按照不同的研究主题进行分类和归纳帮助科研人员快速找到相关领域的研究资料自然语言处理技术还能对档案中的文本进行情感分析了解科研人员对特定研究方向或项目的态度和情感倾向为科研管理和决策提供有价值的参考
## AI 在档案管理中的应用场景与案例分析
### 3.1 档案资源建设
#### 3.1.1 智能采集与整理
在档案资源建设过程中智能采集与整理是重要的基础环节以某大型综合性档案馆为例该馆负责收集和整理大量的历史文献政府文件企业资料等各类档案随着信息时代的发展档案来源日益广泛包括各类网站数据库社交媒体等传统的人工采集和整理方式难以满足需求为此该档案馆引入了 AI 技术利用智能采集工具从网页爬取信息并结合自然语言处理和机器学习算法对采集到的信息进行自动分类和整理
通过配置专门的网络爬虫程序档案馆能够按照设定的规则自动从指定的网站和数据库中获取相关的档案信息在采集过程中利用自然语言处理技术对网页内容进行分析提取关键信息如文件标题发布时间作者主题等并自动生成元数据机器学习算法则用于对档案信息进行分类根据已有的分类标准和训练数据将新采集到的档案信息自动归类到相应的类别中如历史文献类政策法规类企业档案类等这一过程大大提高了档案采集的效率和准确性每天能够处理数千条信息相比传统人工采集方式效率提升了数倍同时通过自动分类和整理减少了人工分类的主观性和误差提高了档案资源的质量和可用性
#### 3.1.2 档案数字化处理
档案数字化是档案管理现代化的关键步骤AI 技术在这一过程中发挥了重要作用北京中烟创新科技有限公司推出的数字档案管理系统充分展示了 AI 在档案数字化处理中的应用该系统利用先进的 OCR光学字符识别技术能够高效准确地识别并转换纸质档案中的文字图像等信息为数字格式在处理大量纸质档案时OCR 技术可快速将纸质文件转化为可编辑的电子文本大大减少了人工录入成本提高了数字化转换效率
在对档案进行数字化处理后还需要对电子档案的 四性即真实性完整性可用性和安全性进行检测中烟创新数字档案管理系统通过数字签名访问记录等技术确保文件的真实性和可信度防止文件被篡改或伪造通过记录和管理文件的版本和修改历史确保文件的完整性和版本的追溯性通过提供随时随地的网络访问功能提高了档案信息的可用性和可访问性通过访问控制权限管理加密传输等安全机制保护档案信息不被未授权人员访问或泄露确保档案数据的安全性这些功能的实现离不开 AI 技术的支持如利用人工智能算法对数字签名进行验证通过机器学习模型对文件的完整性进行评估利用加密算法保障数据传输和存储的安全等通过 AI 技术的应用中烟创新数字档案管理系统实现了档案数字化处理的高效性准确性和安全性为企业的档案管理提供了有力支持
### 3.2 档案开放利用
#### 3.2.1 档案开放审核
档案开放审核是保障档案信息安全合理利用的重要环节某综合档案馆在档案开放审核工作中应用了海泰智能档案开放系统借助 AI 技术优化审核流程提升审核效率该系统利用自然语言处理的文本向量化文本分类关键信息提取文本摘要文本纠错等技术建立档案开放审核模型通过对大量已审核档案数据的学习和训练模型能够自动分析新档案的内容提取关键信息判断档案是否符合开放条件并给出开放审核建议
在实际应用中档案管理人员只需将待审核的档案录入系统系统即可快速进行分析处理对于一些内容较为简单明显符合开放条件的档案系统能够直接给出开放建议大大缩短了审核时间对于复杂的档案系统提供的分析结果和建议也能帮助档案鉴定人员更高效地开展审核工作据统计引入该系统后该档案馆的档案开放审核效率提升了 50% 以上有效加快了档案开放的进程使更多的档案资源能够及时为社会公众所用同时通过 AI 技术的辅助审核的准确性也得到了提高减少了因人工判断失误导致的档案开放不当问题
#### 3.2.2 档案智能检索
档案智能检索是提高档案利用效率的关键范德比尔特电视新闻档案馆在档案管理中充分利用 AI 技术实现了智能检索功能该档案馆自 1968 年以来致力于记录和保存美国国家电视网的新闻拥有海量的视频新闻档案随着档案数量的不断增加传统的检索方式难以满足用户快速准确获取信息的需求为此档案馆引入了自动语音识别ASR和命名实体识别NER AI 技术
首先利用 ASR 技术为新闻播报生成转录文本将视频中的语音内容转化为文字形成可检索的文本数据库接着通过 NER 技术从转录文本中提取命名实体如人名地名组织机构名等并自动生成新闻标题这些技术的应用使得用户可以通过输入自然语言关键词 2020 年美国总统大选相关新闻系统就能快速定位到相关的新闻档案大大提高了检索的准确性和效率与传统的基于关键词匹配的检索方式相比智能检索能够理解用户的语义需求提供更精准的检索结果满足了研究人员媒体工作者等不同用户对档案信息的多样化需求
#### 3.2.3 辅助档案编研
档案编研是对档案信息进行深度加工和开发利用的重要工作AI 技术在这一领域也发挥着重要作用海泰方圆在某军工企业的档案管理应用中利用自然语言处理技术服务于档案编研工作在编研素材的收集阶段自然语言处理技术通过智能检索引擎能够迅速准确地定位到与编研主题高度相关的档案极大提高检索的效率和准确性例如当编研人员确定了 某型号武器装备研发历程 的编研主题后系统能够根据主题关键词在海量的档案库中快速筛选出相关的研发报告试验记录技术文档等档案资料
通过文本挖掘技术海泰方圆深入挖掘档案中隐含信息揭示档案之间的内在联系和规律通过对档案内容的语义分析发现不同档案之间的关联如人物关系事件关联等为编研人员提供更全面的信息视角利用知识图谱技术构建档案知识网络将档案中的各种信息以图形化的方式展示出来使编研人员能够直观地了解档案之间的关联性和层次性为编写高质量的编研成果提供有力支持通过 AI 技术的应用该军工企业的档案编研工作效率得到了显著提升编研成果的质量和深度也得到了提高为企业的技术研发经验总结和历史传承提供了重要的参考依据
### 3.3 档案安全管理
#### 3.3.1 库房安全管理
档案库房的安全管理是档案管理工作的重要保障江苏省太仓市智慧档案馆将 AI 技术应用于库房安全管理实现了对库房环境的实时监控和智能安防该档案馆利用物联网技术在库房内布置了大量的传感器如温湿度传感器烟雾传感器门禁传感器等实时采集库房的环境数据和设备状态信息AI 智能管理系统对这些感知数据进行分析处理根据预设的规则和阈值判断库房环境是否正常设备是否运行良好
当库房内的温湿度超出适宜范围时系统会自动发出警报并联动空调除湿机等设备进行调节确保档案保存环境的稳定在安防方面利用人脸识别视频监控等 AI 技术对进入库房的人员进行身份识别和行为监测只有通过授权的人员才能进入库房并且系统会实时记录人员的进出时间行为轨迹等信息一旦发现异常行为如非法闯入长时间逗留等系统会立即触发警报并通知安保人员进行处理通过这些 AI 技术的应用太仓市智慧档案馆实现了库房安全管理的智能化自动化有效提高了档案库房的安全性保障了档案实体的安全
#### 3.3.2 数据安全与隐私保护
在数字化时代档案数据的安全与隐私保护至关重要AI 技术在数据加密访问控制等方面的应用为档案数据安全提供了有力保障在数据加密方面利用 AI 算法生成高强度的加密密钥对档案数据进行加密存储和传输通过机器学习算法不断优化加密策略提高加密的安全性和效率防止数据被窃取或篡改在访问控制方面AI 技术可以根据用户的身份权限和行为模式实现智能的访问控制通过对用户行为数据的分析建立用户行为模型实时监测用户的访问行为当发现异常访问行为如频繁尝试登录大量下载敏感数据等系统会自动进行拦截并要求用户进行身份验证确保只有授权用户能够访问相应的档案数据
AI 技术还可以用于检测和防范网络攻击通过对网络流量的实时监测和分析利用机器学习算法识别潜在的攻击行为 DDoS 攻击SQL 注入攻击等并及时采取防护措施保障档案管理系统的网络安全在隐私保护方面AI 技术可以对档案中的敏感信息进行自动识别和脱敏处理如个人身份证号银行卡号医疗记录等在保护用户隐私的同时确保档案数据的可用性通过这些 AI 技术的综合应用有效地保障了档案数据的安全和用户的隐私为档案管理的数字化转型提供了安全可靠的环境
## AI 赋能档案管理的优势与挑战
### 4.1 优势分析
#### 4.1.1 提高管理效率
AI 技术在档案管理的多个环节显著提高了管理效率在档案分类环节传统的人工分类方式需要档案管理人员逐份阅读档案内容依据经验和既定规则进行分类这一过程耗时费力且容易因人为因素导致分类不准确以某大型企业的档案管理为例该企业每年产生的各类档案数量多达数十万份包括合同档案财务档案人事档案等在引入 AI 分类系统之前档案管理人员需要花费大量时间进行分类工作且分类错误率较高这给后续的档案检索和利用带来了很大困难引入基于机器学习算法的 AI 分类系统后该系统通过对大量已分类档案数据的学习能够自动识别档案的关键信息和特征快速准确地将新的档案归入相应类别经过实际应用档案分类的效率提高了数倍错误率也大幅降低从原来的 10% 左右降低到了 2% 以内
在档案检索方面AI 技术同样展现出巨大优势传统的检索方式主要依赖关键词匹配当用户输入关键词时系统在档案库中进行简单的文本匹配这种方式往往无法准确理解用户的真实需求导致检索结果不准确不全面某高校的图书馆档案管理系统在采用 AI 智能检索技术之前学生和教师在检索相关资料时常常因为检索结果不理想而浪费大量时间引入 AI 智能检索系统后该系统利用自然语言处理技术能够理解用户输入的自然语言问题分析其语义和语境从而在海量的档案中精准定位到用户所需信息同时通过建立知识图谱系统可以挖掘档案之间的关联关系为用户提供更全面更相关的检索结果据统计采用 AI 智能检索技术后检索效率提高了 50% 以上用户对检索结果的满意度也从原来的 60% 提升到了 85% 以上
在档案审核环节AI 技术的应用也大大节省了人力和时间如北京神舟航天软件技术股份有限公司申请的文书档案开放审核专利技术通过获取待审核文书档案利用机器学习和自然语言处理等技术识别个性化信息并运用审查准则自动判断文书档案是否开放在某政府部门的档案审核工作中引入该技术后原本需要人工花费数周时间才能完成的大量文书档案审核工作现在通过自动化系统仅需几天甚至几小时就能完成审核效率大幅提升同时减少了人工判断的误判率提高了审核的准确性
#### 4.1.2 提升服务质量
AI 技术能够实现精准检索和个性化服务从而有效提升档案服务质量满足用户多元化需求在精准检索方面AI 技术通过自然语言处理和深度学习算法能够理解用户的复杂查询意图提供更准确的检索结果以范德比尔特电视新闻档案馆为例该馆利用自动语音识别ASR和命名实体识别NER技术为新闻播报生成转录文本并提取命名实体用户可以通过输入自然语言关键词 2020 年美国总统大选相关新闻系统就能快速准确地定位到相关新闻档案大大提高了检索的精准度与传统的基于关键词匹配的检索方式相比AI 精准检索能够理解语义避免了因关键词匹配不准确而导致的漏检和误检问题为用户节省了大量时间和精力
在个性化服务方面AI 技术可以根据用户的历史检索记录浏览行为等数据分析用户的兴趣偏好和需求特点为用户提供个性化的档案推荐服务某企业的档案管理系统通过 AI 技术对用户的使用数据进行分析当用户登录系统时系统会根据用户的个性化需求主动推荐相关的档案资源如行业报告市场分析资料等这种个性化推荐服务不仅提高了用户获取所需信息的效率还能帮助用户发现潜在的有价值信息提升了用户对档案服务的满意度同时AI 技术还可以根据不同用户的身份和权限提供差异化的服务如为企业高管提供更高级别的决策支持信息为普通员工提供与工作相关的基础档案资料满足了不同用户的多元化需求
#### 4.1.3 挖掘数据价值
AI 技术通过强大的数据分析能力能够深入挖掘档案中的潜在价值为决策提供有力支持通过对档案数据的分析AI 可以发现数据之间的关联和规律揭示出隐藏在档案中的信息某城市的规划部门对历年的城市建设档案进行分析利用 AI 技术挖掘出城市发展过程中不同区域的功能演变人口流动趋势以及基础设施建设需求等信息通过对这些信息的分析规划部门可以更好地制定城市未来的发展规划合理布局基础设施优化城市功能分区为城市的可持续发展提供决策依据
在企业领域AI 技术对档案数据的分析也具有重要价值某企业通过对历年销售档案客户档案和市场档案的分析利用 AI 技术预测市场趋势客户需求和产品销售情况通过对销售数据的时间序列分析和市场趋势预测企业可以提前调整生产计划优化产品库存合理安排资源提高企业的运营效率和市场竞争力AI 还可以对客户档案进行分析了解客户的购买行为和偏好为企业的市场营销策略提供数据支持实现精准营销提高客户满意度和忠诚度
在科研领域AI 技术对档案数据的挖掘也为科研工作提供了新的思路和方法某科研机构对大量的科研文献档案进行分析利用 AI 技术发现不同研究领域之间的潜在联系和交叉点为科研人员提供新的研究方向和创新点通过对科研文献的主题建模和知识图谱构建AI 可以帮助科研人员快速了解相关领域的研究现状和发展趋势避免重复研究提高科研效率
### 4.2 挑战分析
#### 4.2.1 数据质量问题
档案数据来源多样包括纸质档案数字化电子文档数据库导入网络采集等这导致数据格式不统一如文本文件有.doc.txt.pdf 等多种格式图像文件有.jpg.png.tif 等格式不同格式的数据在处理和分析时需要不同的技术和工具增加了数据处理的复杂性档案数据还存在质量参差不齐的问题如纸质档案数字化过程中可能出现文字模糊图像变形信息缺失等情况电子文档可能存在数据错误格式混乱元数据不完整等问题这些问题会影响 AI 算法的训练和模型的准确性导致分类错误检索结果不准确等问题
为解决这些问题需要建立完善的数据质量管理机制在数据采集阶段制定严格的数据采集标准和规范确保采集的数据准确完整格式统一在数据预处理阶段采用数据清洗去噪修复等技术对数据进行标准化处理去除错误数据和噪声数据补充缺失数据提高数据质量利用数据质量评估工具定期对档案数据进行质量评估及时发现和解决数据质量问题通过建立数据质量管理体系从数据的产生采集存储处理到应用的全过程进行监控和管理确保数据的质量和可靠性 AI 技术在档案管理中的应用提供坚实的数据基础
#### 4.2.2 技术适应性与安全性
档案信息种类繁多包括文本图像音频视频等多种类型每种类型的信息都有其独特的结构和特征这对 AI 技术的适应性提出了很高的要求不同类型的档案数据需要不同的 AI 算法和模型进行处理如文本数据需要自然语言处理技术图像数据需要计算机视觉技术音频数据需要语音识别技术等如何针对不同类型的档案数据选择合适的 AI 技术并将这些技术有效地集成到档案管理系统中是一个需要解决的问题
档案信息包含大量的敏感信息如个人隐私商业机密国家秘密等保障档案信息的安全和隐私至关重要AI 技术在处理和存储档案信息时可能面临数据泄露篡改非法访问等安全风险在数据传输过程中可能被黑客截获和篡改在数据存储过程中可能因系统漏洞被非法访问为保障档案信息安全需要采用多种安全技术如数据加密技术对档案数据进行加密存储和传输防止数据被窃取和篡改访问控制技术根据用户的身份和权限对档案信息的访问进行严格控制确保只有授权用户能够访问相应的档案信息安全监测技术实时监测档案管理系统的运行状态及时发现和防范安全威胁还需要建立健全安全管理制度加强对档案管理人员和用户的安全培训提高安全意识确保档案信息的安全和隐私
#### 4.2.3 伦理与法律法规问题
AI 应用中数据使用的合法性和合规性是一个重要问题档案数据的收集存储处理和共享需要遵循相关的法律法规如个人信息保护法数据安全法等在收集和使用用户的个人档案数据时需要获得用户的明确授权确保数据使用的目的合法正当防止数据滥用和泄露AI 算法可能存在偏见这是由于训练数据的偏差或算法设计的缺陷导致的在档案分类和检索中如果算法存在偏见可能会导致某些类型的档案被错误分类或检索不到影响档案管理的公平性和准确性算法的透明度和可解释性也是一个伦理问题由于 AI 算法的复杂性其决策过程往往难以理解这使得用户难以信任算法的结果在涉及重要决策时如档案开放审核机密档案处理等算法的不可解释性可能会引发伦理争议
为应对这些伦理和法律法规问题需要加强法律法规建设制定专门针对 AI 在档案管理中应用的法律法规明确数据使用算法开发和应用等方面的规则和责任建立伦理审查机制 AI 系统的设计开发和应用进行伦理审查确保 AI 技术的应用符合伦理道德标准提高 AI 算法的透明度和可解释性通过技术手段和可视化方法让用户能够理解算法的决策过程和依据增强用户对 AI 系统的信任加强对 AI 技术应用的监管建立监管机构 AI 在档案管理中的应用进行监督和管理确保其合法合规符合伦理要求
#### 4.2.4 人才短缺问题
AI 时代对档案管理人员的技能提出了新的挑战传统的档案管理人员主要具备档案管理的专业知识和技能如档案整理分类保管等而在 AI 赋能的档案管理环境下档案管理人员需要掌握 AI 技术相关的知识和技能如机器学习自然语言处理数据分析等以便能够有效地运用 AI 技术进行档案管理工作他们还需要具备一定的信息技术素养能够熟练使用档案管理系统和相关软件工具目前具备这些综合技能的档案管理人才相对短缺这限制了 AI 技术在档案管理中的广泛应用和深入发展
为解决人才短缺问题需要加强人才培养在高校教育中优化档案管理相关专业的课程设置增加 AI 技术信息技术等相关课程培养具备跨学科知识和技能的专业人才开展在职培训针对现有的档案管理人员提供定期的 AI 技术培训和继续教育课程帮助他们更新知识结构提升技能水平鼓励档案管理机构与科研机构高校等合作建立人才培养基地共同培养适应 AI 时代需求的档案管理人才还可以通过引进外部人才吸引具有 AI 技术背景和经验的专业人才加入档案管理队伍提高档案管理团队的整体素质和能力
## 应对策略与未来发展趋势
### 5.1 应对策略
#### 5.1.1 数据质量管理
建立完善的数据质量管理机制是确保档案数据质量和一致性的关键在数据采集环节制定严格的数据采集标准和规范明确数据的来源格式内容要求等确保采集到的数据准确完整格式统一对于纸质档案数字化要保证扫描图像的清晰度完整性对图像进行预处理去除噪声倾斜校正等确保后续的文字识别和信息提取准确无误在数据录入过程中采用数据校验和审核机制对录入的数据进行实时校验及时发现和纠正错误数据
在数据存储和管理方面建立数据仓库和数据湖对档案数据进行集中存储和管理确保数据的一致性和可访问性利用数据清洗和去重技术定期对档案数据进行清洗去除重复数据错误数据和无效数据提高数据的质量建立数据质量评估体系制定数据质量指标和评估方法定期对档案数据进行质量评估及时发现和解决数据质量问题通过数据质量评估对数据的准确性完整性一致性时效性等方面进行量化评估为数据质量管理提供数据支持
#### 5.1.2 技术研发与应用
鼓励加大对适应档案管理的 AI 技术的研发投入推动技术创新针对档案数据的特点研发专门的 AI 算法和模型提高 AI 技术在档案管理中的适应性和准确性研发针对档案图像识别的深度学习模型提高对档案图像中文字图表等元素的识别准确率研发适合档案文本分析的自然语言处理模型增强对档案文本的理解和分析能力加强与高校科研机构的合作共同开展 AI 技术在档案管理中的应用研究促进技术成果的转化和应用
在技术应用方面加强 AI 技术与档案管理系统的集成实现 AI 技术在档案管理全流程的应用在档案采集环节利用 AI 技术实现自动化采集和分类在档案整理环节借助 AI 技术进行智能分类和编目在档案检索环节运用 AI 技术提供智能检索和推荐服务不断优化 AI 技术在档案管理中的应用效果根据实际应用情况 AI 模型和算法进行调整和优化提高档案管理的效率和质量
#### 5.1.3 人才培养与团队建设
加强档案人员的 AI 技术培训是提升档案管理水平的重要举措定期组织档案人员参加 AI 技术培训课程邀请专家学者进行授课系统学习机器学习自然语言处理数据分析等 AI 技术知识了解 AI 技术在档案管理中的应用案例和实践经验鼓励档案人员参加相关的学术交流活动和研讨会拓宽视野掌握最新的技术动态和发展趋势
通过培训使档案人员具备运用 AI 技术进行档案管理的能力能够熟练操作档案管理系统中的 AI 功能模块如智能检索自动分类等培养档案人员的数据思维和创新意识让他们能够充分利用 AI 技术挖掘档案数据的价值为档案管理工作提供创新思路和方法除了技术培训还应注重培养档案人员的综合素质包括沟通能力团队协作能力问题解决能力等提高档案管理团队的整体战斗力
引进具有 AI 技术背景的专业人才充实档案管理团队优化团队的知识结构和技能水平建立人才激励机制为人才提供良好的发展空间和待遇吸引和留住优秀人才通过人才的引进和培养打造一支既懂档案管理又懂 AI 技术的复合型人才队伍 AI 赋能档案管理提供人才保障
#### 5.1.4 伦理与法律规范
制定相关的伦理准则和法律法规是规范 AI 在档案管理中应用的重要保障明确 AI 在档案管理中的数据使用规则确保数据的收集存储处理和共享符合法律法规和伦理道德要求在收集用户个人档案数据时必须获得用户的明确授权遵循最小必要原则仅收集与档案管理相关的必要数据保护用户的隐私和个人信息安全
建立 AI 算法的审查机制对用于档案管理的 AI 算法进行伦理审查确保算法的公正性和透明度审查算法是否存在偏见是否会对特定群体造成不公平的影响对于可能影响档案管理决策的 AI 算法要求算法开发者提供详细的算法说明和解释提高算法的可解释性增强用户对算法结果的信任加强对 AI 技术应用的监管建立专门的监管机构制定监管标准和流程 AI 在档案管理中的应用进行监督和管理确保其合法合规符合伦理要求对违反伦理准则和法律法规的行为要依法进行惩处维护档案管理的良好秩序
### 5.2 未来发展趋势
#### 5.2.1 AI 技术与档案管理的深度融合
未来AI 技术将在档案管理的全流程实现更深入的融合和应用在档案资源建设方面AI 技术将实现更智能化的采集和整理通过智能传感器和网络爬虫技术能够自动从各种数据源采集档案信息包括网页社交媒体数据库等实现档案信息的全面收集利用更先进的机器学习算法对采集到的信息进行自动分类标引和编目提高档案资源建设的效率和准确性在档案数字化处理中AI 技术将进一步提升数字化的质量和速度通过深度学习算法实现对档案图像和文字的更精准识别和转换提高数字化的准确率利用 AI 技术对数字化后的档案进行智能修复和优化恢复受损档案的内容提高档案的可读性和可用性
在档案开放利用方面AI 技术将为用户提供更个性化智能化的服务通过对用户行为数据的分析和挖掘AI 能够深入了解用户的需求和兴趣偏好为用户提供定制化的档案推荐服务当用户搜索档案时AI 不仅能够根据关键词提供相关档案还能根据用户的历史搜索记录和行为模式推荐更符合用户需求的档案资源AI 技术还将实现更智能的档案编研通过自然语言处理和知识图谱技术能够对档案内容进行深度分析和挖掘发现档案之间的关联和潜在知识为档案编研人员提供更丰富的素材和思路提高编研成果的质量和深度
在档案安全管理方面AI 技术将发挥更重要的作用利用 AI 技术实现对档案库房环境的实时监测和智能调控确保档案保存环境的稳定和安全通过对库房内温湿度空气质量光照等环境参数的实时监测AI 系统能够自动调整空调除湿机通风设备等保持适宜的保存环境在档案数据安全方面AI 技术将提供更强大的防护能力通过机器学习算法能够实时监测档案数据的访问和传输情况及时发现和防范数据泄露篡改等安全威胁利用 AI 技术对档案数据进行加密和备份确保数据的安全性和完整性
#### 5.2.2 智能化与自动化的发展方向
随着 AI 技术的不断发展档案管理将朝着更加智能化和自动化的方向发展AI 将实现档案管理的自动化决策通过对大量档案数据的分析和学习AI 系统能够自动判断档案的价值重要性和保存期限为档案管理决策提供依据在档案鉴定环节AI 可以根据预设的标准和模型自动评估档案的保存价值决定哪些档案需要永久保存哪些可以定期销毁减少人工鉴定的主观性和工作量
AI 还将实现档案管理的自主服务通过智能客服和聊天机器人技术用户可以与档案管理系统进行自然语言交互获取所需的档案信息和服务用户只需通过语音或文字提问系统就能自动理解用户的需求提供准确的答案和相关档案资源档案管理系统还能根据用户的需求自动生成档案报告统计分析等为用户提供更便捷高效的服务未来档案管理将实现无人化管理通过自动化设备和 AI 技术实现档案的自动上架下架盘点等操作减少人工干预提高管理效率和准确性利用机器人技术实现档案库房的自动巡逻和安全检查及时发现和处理安全隐患
#### 5.2.3 跨领域合作与创新
档案管理将与其他领域展开更广泛的合作与创新推动 AI 技术的应用和发展与大数据云计算等技术领域的合作将更加紧密通过与大数据技术的结合能够对海量的档案数据进行更深入的分析和挖掘发现数据背后的潜在价值和规律为档案管理决策提供更有力的数据支持借助云计算技术实现档案数据的分布式存储和计算提高数据处理的效率和可靠性降低档案管理的成本
与文化教育科研等领域的合作也将不断加强在文化领域与博物馆图书馆等文化机构合作整合档案资源和文化资源打造综合性的文化信息服务平台为公众提供更丰富的文化体验在教育领域与学校合作将档案资源作为教学素材开展档案教育和研究培养学生的历史文化素养和信息素养在科研领域与科研机构合作利用档案数据开展学术研究为科研工作提供数据支持和历史借鉴通过跨领域合作能够拓展档案管理的应用场景和服务范围推动档案管理的创新发展为社会提供更优质的档案信息服务
## 结论与展望
### 6.1 研究总结
本研究深入探讨了 AI 赋能档案管理的相关内容AI 技术包括机器学习深度学习自然语言处理和计算机视觉等为档案管理提供了强大的技术支持使其在多个方面实现了创新和变革
在应用场景方面AI 在档案资源建设中实现了智能采集与整理以及高效的档案数字化处理在档案开放利用中助力档案开放审核提供智能检索服务并辅助档案编研工作在档案安全管理中实现了库房安全的智能监控和数据安全与隐私的有效保护通过多个实际案例分析如范德比尔特电视新闻档案馆利用 AI 实现智能检索海泰方圆在档案编研中应用自然语言处理技术等充分展示了 AI 在档案管理各环节的应用效果和价值
AI 赋能档案管理具有显著优势它极大地提高了管理效率在档案分类检索和审核等工作中节省了大量的人力和时间成本提高了工作的准确性通过精准检索和个性化服务提升了档案服务质量满足了用户的多元化需求AI 技术还能够深入挖掘档案数据的价值为决策提供有力支持在城市规划企业运营和科研等领域发挥了重要作用
AI 在档案管理中的应用也面临诸多挑战数据质量问题如数据格式不统一质量参差不齐影响了 AI 算法的训练和模型的准确性技术适应性与安全性方面不同类型档案数据对 AI 技术的适应性要求高同时保障档案信息安全和隐私至关重要伦理与法律法规问题包括数据使用的合法性算法偏见以及算法的透明度和可解释性等人才短缺问题传统档案管理人员难以满足 AI 时代对综合技能的要求针对这些挑战本研究提出了相应的应对策略包括建立完善的数据质量管理机制加大技术研发与应用力度加强人才培养与团队建设以及制定伦理与法律规范等
### 6.2 未来展望
未来AI 在档案管理领域将展现出更广阔的发展前景AI 技术与档案管理的融合将更加深入贯穿档案管理的全流程在档案资源建设中实现更智能化的采集和整理提升数字化处理的质量和速度在档案开放利用中提供更个性化智能化的服务实现更智能的档案编研在档案安全管理中发挥更重要的作用保障档案实体和数据的安全
档案管理将朝着智能化与自动化的方向加速发展AI 将实现档案管理的自动化决策如自动判断档案的价值重要性和保存期限实现档案管理的自主服务通过智能客服和聊天机器人为用户提供便捷的服务甚至实现无人化管理借助自动化设备和机器人完成档案的日常管理工作
跨领域合作与创新将成为档案管理发展的重要趋势与大数据云计算等技术领域的紧密合作将为档案管理提供更强大的数据处理和分析能力与文化教育科研等领域的合作将拓展档案管理的应用场景和服务范围推动档案管理的创新发展为社会提供更优质的档案信息服务为了充分发挥 AI 在档案管理中的优势我们需要持续关注技术发展动态积极应对各种挑战不断探索和创新推动档案管理行业向更高水平迈进`,
loading: false,
intervalId: null
form: {
desc: ""
},
message: [],
username: sessionStorage.name,
userphoto: sessionStorage.photo,
loadingtype: false,
controller: null,
arequestData: {
model: "qwen2", //"llama3.1",
messages: []
}
};
},
computed: {
...mapGetters([
'user'
])
mounted() {},
methods: {
scrollToBottom() {
let elscroll = this.$refs["scrollDiv"];
elscroll.scrollTop = elscroll.scrollHeight + 30;
},
created() {
clearForm(formName) {
this.form.desc = "";
},
methods: {
previewFiles() {
const files = this.$refs.file.files
this.selectedFiles = []
for (let i = 0; i < files.length; i++) {
this.selectedFiles.push(files[i])
async startStreaming(e) {
if (e.ctrkey && e.keyCode == 13) {
this.form.desc += "\n";
}
document.getElementById("txt_suiwen").disabled = "true";
//
if (this.controller) {
this.controller.abort();
}
setTimeout(() => {
this.scrollToBottom();
}, 50);
var mymsg = this.form.desc.trim();
if (mymsg.length > 0) {
this.form.desc = "";
this.message.push({
user: this.username,
msg: mymsg
});
this.message.push({
user: "GPT",
msg: "",
dot: ""
});
// AbortController
this.controller = new AbortController();
const signal = this.controller.signal;
this.arequestData.messages.push({ role: "user", content: mymsg });
try {
const response = await fetch("http://127.0.0.1:11434/api/chat", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
handleAIEditing() {
if (this.selectedFiles.length === 0) {
this.$message({ message: '请上传要编研的文件', type: 'error', offset: 8 })
return
body: JSON.stringify(this.arequestData),
signal
});
if (!response.body) {
this.message[this.message.length - 1].msg =
"ReadableStream not yet supported in this browser.";
throw new Error(
"ReadableStream not yet supported in this browser."
);
}
const reader = response.body.getReader();
const decoder = new TextDecoder();
let result = "";
this.message[this.message.length - 1].dot = "⚪";
while (true) {
const { done, value } = await reader.read();
if (done) {
break;
}
result += decoder.decode(value, { stream: true });
// JSON
const jsonChunks = result.split("\n").filter(line => line.trim());
//console.log(result)
for (const chunk of jsonChunks) {
try {
const data = JSON.parse(chunk);
//console.log(data.message.content)
this.message[this.message.length - 1].msg +=
data.message.content;
setTimeout(() => {
this.scrollToBottom();
}, 50);
} catch (e) {
//this.message[this.message.length-1].msg=e;
// JSON
//console.error('Failed to parse JSON:', e);
}
if (this.textarea === '') {
this.$message({ message: '请输入提问要求', type: 'error', offset: 8 })
return
}
this.loading = true
this.editorContent = ''
const lines = this.mockResponse.split('\n')
let index = 0
this.intervalId = setInterval(() => {
if (index < lines.length) {
this.editorContent += (index > 0 ? '\n' : '') + lines[index]
index++
// result 便
result = "";
}
} catch (error) {
if (error.name === "AbortError") {
console.log("Stream aborted");
this.message[this.message.length - 1].msg = "Stream aborted";
} else {
clearInterval(this.intervalId)
this.loading = false
console.error("Streaming error:", error);
this.message[this.message.length - 1].msg = "Stream error" + error;
}
}
this.message[this.message.length - 1].dot = "";
this.arequestData.messages.push({
role: "assistant", //this.message[this.message.length-1].user,//"GPT",
content: this.message[this.message.length - 1].msg
});
setTimeout(() => {
this.scrollToBottom();
}, 50);
} else {
this.form.desc = "";
}
document.getElementById("txt_suiwen").disabled = "";
document.getElementById("txt_suiwen").focus();
}
// this.$nextTick(() => {
// const container = this.$refs.typingContainer.$el.querySelector('.markdown-body')
// if (container) {
// container.scrollTop = container.scrollHeight
// }
// })
}, 200) // 500
},
handleCloseForm() {
this.selectedFiles = []
this.textarea = ''
this.editorContent = ''
this.formVisible = false
clearInterval(this.intervalId)
this.loading = false
},
handleComfiredEditing() {
this.handleCloseForm()
beforeDestroy() {
//
if (this.controller) {
this.controller.abort();
}
}
}
};
</script>
<style lang="scss" scoped>
.editingDialog{
::v-deep .el-dialog{
width: 1000px;
}
<style scoped>
.radius {
margin: 0 auto;
}
.demo-radius .title {
color: var(--el-text-color-regular);
font-size: 18px;
margin: 10px 0;
}
.demo-radius .value {
color: var(--el-text-color-primary);
font-size: 16px;
margin: 10px 0;
}
::v-deep .markdown-body{
height: 500px !important;
.demo-radius .radius {
min-height: 580px;
height: 85vh;
width: 70%;
border: 1px solid var(--el-border-color);
border-radius: 14px;
margin-top: 10px;
}
.messge {
width: 96%;
height: 84%;
/* border:1px solid red; */
margin: 6px auto;
overflow: hidden;
overflow-y: auto;
}
.inputmsg {
width: 96%;
height: 12%;
/* border:1px solid blue; */
border-top: 2px solid #ccc;
margin: 4px auto;
padding-top: 10px;
}
.mymsginfo {
width: 100%;
height: auto;
min-height: 50px;
}
::-webkit-scrollbar {
width: 6px;
height: 5px;
}
::-webkit-scrollbar-track {
background-color: rgba(0, 0, 0, 0.2);
border-radius: 10px;
}
::-webkit-scrollbar-thumb {
background-color: rgba(0, 0, 0, 0.5);
border-radius: 10px;
}
::-webkit-scrollbar-button {
background-color: #7c2929;
height: 0;
width: 0px;
}
::-webkit-scrollbar-corner {
background-color: black;
}
</style>
<style>
.el-textarea__inner {
padding-left: 45px;
padding-top: 0.75rem;
padding-bottom: 0.75rem;
}
</style>

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

@ -14,23 +14,43 @@
<el-option v-for="item in options" :key="item.id" :label="item.dictionaryName" :value="item.dictionaryName" />
</el-select>
</el-form-item>
<el-button :loading="crud.status.cu === 2" type="primary" @click="handleComfiredEditing">保存</el-button>
<el-button class="check-btn" :loading="crud.status.cu === 2" type="primary" @click="handleComfiredEditing">保存</el-button>
</el-row>
</el-form>
<div class="content-container">
<div class="left-panel" :class="{ 'collapsed': isCollapsed }">
<div class="ai-talk">
<div class="ai-talk-content">对话框</div>
<div ref="talkContent" class="ai-talk-content">
<div v-for="(item, index) in message" :key="index" class="message">
<div v-if="item.role == 'user'" class="user-box">
<p>{{ item.content }}</p>
<el-avatar icon="el-icon-user-solid" />
</div>
<div v-else class="ai-box">
<div class="return-data">
<el-avatar> AI </el-avatar>
<p>{{ item.content }}</p>
</div>
<div v-if="item.showMarkdown">
<mavon-editor
class="md"
:value="item.markDownText"
:subfield="false"
:default-open="'preview'"
:toolbars-flag="false"
:editable="false"
:scroll-style="true"
:ishljs="true"
/>
<span class="get-content-style" @click="onClickContent(item.markDownText)"><i class="iconfont icon-wenjianjiexi" /></span>
</div>
</div>
</div>
</div>
<div class="ai-talk-form">
<!-- 选择的文件 -->
<div class="upload-use-file">
<div v-if="imageUrl" class="file-content">
<img :src="imageUrl" alt="Selected Image">
<p>{{ fileName }}</p>
<span class="delt-file" @click="deleteFile"> <i class="el-icon-close" /></span>
</div>
<div v-else-if="fileName" class="file-content">
<div v-if="fileName" class="file-content">
<span class="delt-file" @click="deleteFile"> <i class="el-icon-close" /></span>
<div v-if="fileType === 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' || fileType === 'application/vnd.ms-excel'">
<i class="fileIcon icon-excel" />
@ -61,6 +81,7 @@
type="textarea"
:autosize="{ minRows:1 , maxRows: 4 }"
placeholder="请输入内容"
@keydown.enter.native.prevent="handleMessage($event)"
/>
<div class="ai-form-btn">
<div style="position: relative;">
@ -68,7 +89,7 @@
<i class="iconfont icon-attachment" />
</div>
<span class="line" />
<i class="iconfont icon-fasong-jiantou" />
<i class="iconfont icon-fasong-jiantou" @click="sendMessage" />
</div>
</div>
</div>
@ -77,18 +98,15 @@
<span class="closed-btn" />
</div>
<div class="right-panel">
<!-- <div class="rich-text">富文本框</div> -->
<editor
v-model="editorContent"
:editor-content="editorContent"
:editor-ref="editorRef"
<mavon-editor
:value="editorContent"
:subfield="true"
:default-open="['edit', 'preview']"
:editable="true"
:ishljs="true"
/>
</div>
</div>
<!-- <div slot="footer" class="dialog-footer">
<el-button type="text" @click="handleCloseForm">取消</el-button>
<el-button :loading="crud.status.cu === 2" type="primary" @click="handleComfiredEditing">确定</el-button>
</div> -->
</div>
</el-dialog>
</div>
@ -98,13 +116,11 @@
import { form } from '@crud/crud'
import { mapGetters } from 'vuex'
import { FetchDictionaryTree } from '@/api/system/dict'
import editor from '@/components/quillEditor/index'
// import strJson from './str.json'
const defaultForm = { id: null, title: null, researchType: null }
export default {
name: 'Form',
components: { editor },
components: { },
mixins: [
form(function() {
return Object.assign({}, defaultForm)
@ -112,16 +128,10 @@ export default {
],
data() {
return {
formType: 1,
formTitle: '',
formVisible: false,
selectedFiles: [],
textarea: '帮我写一篇AI赋能档案管理的报告',
editorRef: 'test',
editorContent: '',
mockResponse: '',
loading: false,
intervalId: null,
options: [],
rules: {
@ -133,7 +143,13 @@ export default {
imageUrl: '',
fileName: '',
isImage: false,
fileType: ''
fileType: '',
message: [],
controller: null,
arequestData: {
model: 'deepseek-r1:14b',
messages: []
}
}
},
computed: {
@ -154,87 +170,180 @@ export default {
console.log(err)
})
},
handleFileChange(event) {
async handleFileChange(event) {
const file = event.target.files[0]
const allowedExtensions = ['.xlsx', '.xls', '.docx', '.doc', '.pdf', '.ofd', '.pptx', '.txt']
const maxSize = 10 * 1024 * 1024
if (file) {
this.fileType = file.type
console.log('this.fileType ', this.fileType)
const fileExtension = '.' + file.name.split('.').pop().toLowerCase()
if (file.type.indexOf('image') !== -1) {
this.isImage = true
const reader = new FileReader()
reader.onload = (e) => {
this.imageUrl = e.target.result
this.fileName = file.name
this.$message.error('不允许上传图片文件!')
return
}
reader.readAsDataURL(file)
} else {
if (!allowedExtensions.includes(fileExtension)) {
this.$message.error('仅允许上传以下格式的文件:.xlsx, .xls, .docx, .doc, .pdf, .ofd, .pptx, .txt')
return
}
if (file.size > maxSize) {
this.$message.error('文件大小不能超过 10MB!')
return
}
this.fileType = file.type
this.isImage = false
this.fileName = file.name
this.imageUrl = ''
//
}
}
},
deleteFile() {
this.imageUrl = ''
this.fileName = ''
this.fileType = ''
this.isImage = false
},
previewFiles() {
const files = this.$refs.file.files
this.selectedFiles = []
for (let i = 0; i < files.length; i++) {
this.selectedFiles.push(files[i])
async handleMessage(e) {
if (e) { //
if (e.keyCode === 13) {
if (e.ctrlKey) { // Ctrl+Enter
this.sendMessage()
} else { // Enter
this.inputValue += '\n'
this.scrollToBottom()
return
}
}
} else {
this.sendMessage()
}
},
handleAIEditing() {
if (this.selectedFiles.length === 0) {
this.$message({ message: '请上传要编研的文件', type: 'error', offset: 8 })
async sendMessage(e) {
if (!this.inputValue) {
this.$message.error('请输入问题')
return
}
if (this.textarea === '') {
this.$message({ message: '请输入提问要求', type: 'error', offset: 8 })
return
//
if (this.controller) {
this.controller.abort()
}
this.loading = true
this.editorContent = ''
const lines = this.mockResponse.split('\n')
let index = 0
setTimeout(() => {
this.scrollToBottom()
}, 50)
this.intervalId = setInterval(() => {
if (index < lines.length) {
this.editorContent += (index > 0 ? '\n' : '') + lines[index]
index++
} else {
clearInterval(this.intervalId)
this.loading = false
this.message.push({
role: 'user',
content: this.inputValue
})
this.message.push({
role: 'ai',
content: '',
markDownText: '',
showMarkdown: false
})
try {
this.controller = new AbortController()
const signal = this.controller.signal
this.arequestData.messages.push({ role: 'user', content: this.inputValue })
const linkSrc = process.env.NODE_ENV === 'production' ? window.g.AIDeepSeekUrl : process.env.VUE_APP_AIDEEPSEEK_API
const response = await fetch(linkSrc + '/api/chat', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(this.arequestData),
signal
})
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`)
}
const reader = response.body.getReader()
const decoder = new TextDecoder()
let result = ''
let done = false
while (!done) {
const { done: isDone, value } = await reader.read()
done = isDone
if (done) break
result += decoder.decode(value, { stream: true })
const jsonChunks = result.split('\n').filter(line => line.trim())
for (const chunk of jsonChunks) {
try {
const data = JSON.parse(chunk)
this.message[this.message.length - 1].content += data.message.content
setTimeout(() => {
this.scrollToBottom()
}, 50)
} catch (e) {
// JSON
}
}
// this.$nextTick(() => {
// const container = this.$refs.typingContainer.$el.querySelector('.markdown-body')
// if (container) {
// container.scrollTop = container.scrollHeight
// }
// })
}, 200) // 500
// <think> </think>
const cleanText = this.message[this.message.length - 1].content.replace(/<think>[^]*?<\/think>/g, '')
console.log('cleanText', cleanText)
this.message[this.message.length - 1].markDownText = cleanText
result = ''
}
} catch (error) {
if (error.name === 'AbortError') {
console.log('Stream aborted')
this.message[this.message.length - 1].content = 'Stream aborted'
this.message[this.message.length - 1].markDownText = 'Stream aborted'
} else {
console.error('Streaming error:', error)
this.message[this.message.length - 1].content = 'Stream error' + error
this.message[this.message.length - 1].markDownText = 'Stream error' + error
}
} finally {
this.arequestData.messages.push({
role: 'assistant',
content: this.message[this.message.length - 1].content
})
this.message[this.message.length - 1].showMarkdown = true
setTimeout(() => {
this.scrollToBottom()
}, 50)
this.inputValue = ''
}
},
scrollToBottom() {
const talkContent = this.$refs.talkContent
if (talkContent) {
talkContent.scrollTop = talkContent.scrollHeight
}
},
beforeDestroy() {
//
if (this.controller) {
this.controller.abort()
}
},
onClickContent(talkContent) {
this.editorContent = ''
this.editorContent = talkContent
},
deleteFile() {
this.imageUrl = ''
this.fileName = ''
this.fileType = ''
this.isImage = false
},
handleCloseForm() {
this.selectedFiles = []
this.textarea = ''
this.inputValue = ''
this.editorContent = ''
this.message = []
this.formVisible = false
clearInterval(this.intervalId)
this.loading = false
},
handleComfiredEditing() {
// this.$refs.form.validate(valid => {
// if (valid) {
// console.log('', this.form);
// }
// });
this.$refs.form.validate(valid => {
if (valid) {
console.log('保存数据', this.form)
this.handleCloseForm()
}
})
},
toggleCollapse() {
this.isCollapsed = !this.isCollapsed
@ -246,7 +355,7 @@ export default {
<style lang="scss" scoped>
.editingDialog{
::v-deep .el-dialog{
width: 1200px;
width: 1400px;
.el-form-item {
.el-form-item__content{
width: auto !important;
@ -278,6 +387,9 @@ export default {
display: none;
}
}
.ai-talk-content{
padding: 0;
}
}
.toggle-btn {
display: flex;
@ -294,8 +406,8 @@ export default {
flex: 1;
margin-left: 10px;
color: #606266;
::v-deep .ql-editor{
height: 630px;
::v-deep .v-note-wrapper{
height: 698px;
}
}
.content-container.collapsed .right-panel {
@ -309,8 +421,42 @@ export default {
height: 100%;
.ai-talk-content{
flex: 1;
background-color: oldlace;
// background-color: oldlace;
overflow-y: auto;
padding: 12px;
.message{
// display: flex;
// justify-content: flex-end;
margin-bottom: 10px;
}
.message p{
padding: 8px 12px;
border-radius: 10px;
line-height: 22px;
max-width: 70%;
word-wrap: break-word;
}
.user-box {
display: flex;
justify-content: flex-end;
align-items: flex-start;
p{
background-color: #e3f2fd;
margin-right: 10px;
}
}
.ai-box {
div.return-data{
display: flex;
justify-content: flex-start;
align-items: flex-start;
margin-bottom: 10px;
p{
background-color: #f5f5f5;
margin-left: 10px;
}
}
}
}
.upload-use-file{
width: 200px;
@ -399,4 +545,23 @@ export default {
}
}
.get-content-style{
display: block;
width: 30px;
height: 30px;
line-height: 30px;
margin-top: 10px;
border: 1px solid rgba(0,0,0,.6);
border-radius: 50%;
text-align: center;
.iconfont::before{
margin: 0 !important;
}
&:hover{
// color: #fff;
background-color: rgba(0,0,0,.2);
border: 1px solid rgba(0,0,0,.2);
cursor: pointer;
}
}
</style>

5
src/views/AIAssistant/AIKeywords/module/keywordMark.vue

@ -138,7 +138,7 @@ export default {
context = resultJson.data.map(item => item.content).join('\n\n')
console.log('多张图片,用swiper')
}
const prompt = '帮我提取5-10个关键词,关键词包含时间名称、地点名称、人名、部门机构名称以及档案学专用名称,按词频降序排列,用json格式带{}形式输出,其中只有一个关键字keywords数组字段,然后所有的关键字都放到这个keywords数组字段中'
const prompt = '帮我提取5-10个关键词,关键词包含地点名称、人名、部门机构名称以及档案学专用名称,按词频降序排列,用json格式带{}形式输出,其中只有一个关键字keywords数组字段,然后所有的关键字都放到这个keywords数组字段中'
this.sendMessage(prompt, context)
}).catch(err => {
console.log(err)
@ -201,9 +201,6 @@ export default {
}
}
})
// ... ...
//
const container = this.$refs.typingContainer
if (container) {

136
src/views/AIAssistant/AIknowledgeGraph/index.vue

@ -36,7 +36,7 @@
<span class="right-top-line" />
<span class="left-bottom-line" />
<!-- <img style="display: block; height: calc(100vh - 184px);" src="@/assets/images/graph-img.png" alt=" "> -->
<graph />
<graph :graph-data="graphData" />
</div>
</div>
</div>
@ -44,6 +44,7 @@
</template>
<script>
import crudCategory from '@/api/system/category/category'
import { FetchInitShowByCategory } from '@/api/ai/ai'
import CRUD, { presenter, header } from '@crud/crud'
import graph from '@/views/components/echarts/graph.vue'
@ -72,8 +73,8 @@ export default {
children: 'children',
label: 'label'
},
selectedCategory: {}
selectedCategory: {},
graphData: { 'nodes': [], 'lines': [] }
}
},
computed: {
@ -83,6 +84,77 @@ export default {
mounted() {
},
methods: {
[CRUD.HOOK.afterRefresh]() {
this.crud.data = this.filterData(this.transformData(this.crud.data))
this.$nextTick(() => {
let currentKey
if (localStorage.getItem('currentArchivesKey') !== null) {
currentKey = JSON.parse(localStorage.getItem('currentArchivesKey'))
//
if (this.$refs.categroyTree.getCurrentKey(currentKey.id) == null) {
localStorage.removeItem('currentArchivesKey')
}
this.topLevelNode = this.findTopLevelNode(this.crud.data, currentKey.fondsId)
//
if (this.topLevelNode) {
if (currentKey) {
//
if (currentKey.isType === 1) {
currentKey = this.findNode(this.crud.data[0].children, (node) => {
return node.isType !== 1
})
}
this.expandAllChildren(this.$refs.categroyTree.getNode(this.topLevelNode), currentKey)
} else {
this.defaultSetting(currentKey)
}
} else {
this.defaultSetting(currentKey)
}
} else {
this.defaultSetting(currentKey)
}
if (currentKey && currentKey.id) {
this.$nextTick(() => {
//
this.handleNodeClick(currentKey)
})
}
})
},
defaultSetting(currentKey) {
if (this.crud.data[0].isType === 0) {
currentKey = this.findNode(this.crud.data[0].children, (node) => {
return node.isType !== 1
})
this.expandAllChildren(this.$refs.categroyTree.getNode(this.crud.data[0]), currentKey)
} else {
currentKey = this.crud.data[0]
this.expandAllChildren(this.$refs.categroyTree.getNode(this.crud.data[0]), currentKey)
}
},
//
handleNodeClick(val) {
if (val) {
localStorage.setItem('currentArchivesKey', JSON.stringify(val))
this.selectedCategory = val
// this.selectedCategory.cnName
const parmas = {
'searchKey': 'id', // id / title
'searchValue': 'E0B3627CBED49E53609245',
'tableName': 'Category' //
}
FetchInitShowByCategory(parmas).then((res) => {
console.log(res)
this.graphData = res
}).catch(err => {
console.log(err)
})
// this.$nextTick(() => {
// })
}
},
filterData(data) {
return data.filter(node => {
if (node.children && node.children.length > 0) {
@ -165,64 +237,6 @@ export default {
}
}
return null
},
[CRUD.HOOK.afterRefresh]() {
this.crud.data = this.filterData(this.transformData(this.crud.data))
this.$nextTick(() => {
let currentKey
if (localStorage.getItem('currentArchivesKey') !== null) {
currentKey = JSON.parse(localStorage.getItem('currentArchivesKey'))
//
if (this.$refs.categroyTree.getCurrentKey(currentKey.id) == null) {
localStorage.removeItem('currentArchivesKey')
}
this.topLevelNode = this.findTopLevelNode(this.crud.data, currentKey.fondsId)
//
if (this.topLevelNode) {
if (currentKey) {
//
if (currentKey.isType === 1) {
currentKey = this.findNode(this.crud.data[0].children, (node) => {
return node.isType !== 1
})
}
this.expandAllChildren(this.$refs.categroyTree.getNode(this.topLevelNode), currentKey)
} else {
this.defaultSetting(currentKey)
}
} else {
this.defaultSetting(currentKey)
}
} else {
this.defaultSetting(currentKey)
}
if (currentKey && currentKey.id) {
this.$nextTick(() => {
//
this.handleNodeClick(currentKey)
})
}
})
},
defaultSetting(currentKey) {
if (this.crud.data[0].isType === 0) {
currentKey = this.findNode(this.crud.data[0].children, (node) => {
return node.isType !== 1
})
this.expandAllChildren(this.$refs.categroyTree.getNode(this.crud.data[0]), currentKey)
} else {
currentKey = this.crud.data[0]
this.expandAllChildren(this.$refs.categroyTree.getNode(this.crud.data[0]), currentKey)
}
},
//
handleNodeClick(val) {
if (val) {
localStorage.setItem('currentArchivesKey', JSON.stringify(val))
this.selectedCategory = val
this.$nextTick(() => {
})
}
}
}

4
src/views/archivesStatistics/customDefinedStatistics/index.vue

@ -26,7 +26,7 @@
<!-- <div v-katex:auto class="mdTextBox" v-html="renderMdText(markDownText)" /> -->
<!-- <mavon-editor
<mavon-editor
class="md"
:value="markDownText"
:subfield="false"
@ -35,7 +35,7 @@
:editable="false"
:scroll-style="true"
:ishljs="true"
/> -->
/>
</div>
</div>

124
src/views/components/echarts/graph.vue

@ -36,9 +36,17 @@ import RelationGraph from 'relation-graph'
export default {
name: 'Demo',
components: { RelationGraph },
props: {
graphData: {
type: Object,
require: true,
default: function() {
return {}
}
}
},
data() {
return {
allData: { 'nodes': [], 'lines': [] },
isShowCodePanel: false,
isShowNodeTipsPanel: false,
nodeMenuPanelPosition: { x: 0, y: 0 },
@ -66,23 +74,118 @@ export default {
isLoading: false,
errorMessage: '',
nodes: [],
edges: []
edges: [],
allData: { 'nodes': [], 'lines': [] }
}
},
watch: {
'graphData': {
handler(val) {
setTimeout(() => {
this.setData()
}, 100)
},
immediate: true,
deep: true
}
},
mounted() {
console.log('graphData', this.graphData)
this.resizeTimer = setInterval(async() => {
// const graphInstance = this.$refs.graphRef.getInstance();
// await graphInstance.zoomToFit();
}, 3000)
this.allData.nodes = []
this.allData.lines = []
const query = "MATCH path = (target:Archives {id: '0047B3542CE88B895E41DE'})-[rels:HAS_KEYWORD*1..4]-(related:Archives) WHERE target <> related UNWIND relationships(path) AS r WITH startNode(r) AS n, r, endNode(r) AS m, length(path)/2 AS depth RETURN DISTINCT n, r, m;"
this.fetchData(query)
// this.allData.nodes = []
// this.allData.lines = []
// const query = "MATCH path = (target:Archives {id: '0047B3542CE88B895E41DE'})-[rels:HAS_KEYWORD*1..4]-(related:Archives) WHERE target <> related UNWIND relationships(path) AS r WITH startNode(r) AS n, r, endNode(r) AS m, length(path)/2 AS depth RETURN DISTINCT n, r, m;"
// this.fetchData(query)
// this.showGraph()
this.setData()
},
beforeDestroy() {
clearInterval(this.resizeTimer)
},
methods: {
setData(selectedNodeId = null) {
const { nodes, lines } = this.graphData
// ArchivesCategoryCategoryClassFondsKeywordsRetentionSecrecyPeriodSecurityClass
const newNodes = nodes.map(item => {
const newItem = { ...item, id: String(item.id), text: item.properties.title, type: item.labels[0] }
const typeToColorMap = {
Archives: '#0348F3',
Category: '#14C9C9',
CategoryClass: '#F8B722',
Fonds: '#722ED1',
Keywords: '#F4647B',
Retention: '#018BFF',
SecrecyPeriod: '#FEBD98',
SecurityClass: '#B1EBDF'
}
const defaultColor = '#000000' //
console.log('item.labels[0]', item.labels[0])
console.log('typeToColorMap[item.labels[0]]', typeToColorMap[item.labels[0]])
if (typeToColorMap[item.labels[0]]) {
newItem.color = typeToColorMap[item.labels[0]]
newItem.borderColor = typeToColorMap[item.labels[0]]
} else {
newItem.color = defaultColor
newItem.borderColor = defaultColor
}
return newItem
})
const newEdges = lines.map(item => {
return {
...item,
from: String(item.source),
to: String(item.target),
text: item.type
}
})
const existingNodeIds = new Set(this.allData.nodes.map(node => node.id))
const allNodesExist = newNodes.every(node => existingNodeIds.has(node.id))
let validNewEdges = []
let uniqueNewNodes = []
if (!allNodesExist) {
uniqueNewNodes = newNodes.filter(node => !existingNodeIds.has(node.id))
const existingLineKeys = new Set(this.allData.lines.map(line => `${line.from}-${line.to}-${line.text}`))
// to
if (selectedNodeId) {
const relatedNodeIds = [selectedNodeId, ...this.getRelatedNodeIds(selectedNodeId)]
validNewEdges = newEdges.filter(edge => {
return !relatedNodeIds.includes(edge.to) && !existingLineKeys.has(`${edge.from}-${edge.to}-${edge.text}`)
})
} else {
validNewEdges = newEdges.filter(edge => !existingLineKeys.has(`${edge.from}-${edge.to}-${edge.text}`))
}
}
// const originalNodesLength = this.allData.nodes.length
// const originalLinesLength = this.allData.lines.length
this.allData.nodes = [...this.allData.nodes, ...uniqueNewNodes]
this.allData.lines = [...this.allData.lines, ...validNewEdges]
this.allData.nodes.sort((a, b) => {
return parseInt(a.id) - parseInt(b.id)
})
console.log('this.allData', this.allData)
this.showGraph()
//
// if (this.allData.nodes.length > originalNodesLength || this.allData.lines.length > originalLinesLength) {
// console.log('this.allData', this.allData)
// this.showGraph()
// } else {
// console.log('')
// }
},
async fetchData(query, selectedNodeId = null) {
this.isLoading = true
this.errorMessage = ''
@ -172,6 +275,7 @@ export default {
.map(line => line.from === nodeId ? line.to : line.from)
},
async showGraph() {
console.log('this.allData', this.allData)
const rootId = this.allData.nodes[0].id
this.allData.rootId = rootId
@ -201,10 +305,10 @@ export default {
},
onNodeClick(nodeObject, $event) {
console.log('节点数据:', nodeObject)
const nodeId = nodeObject.id
const query = `MATCH (n) WHERE id(n) = ${nodeId} MATCH (n)-[r]-(m) RETURN n, r,m;`
this.fetchData(query, nodeId)
console.log('query', query)
// const nodeId = nodeObject.id
// const query = `MATCH (n) WHERE id(n) = ${nodeId} MATCH (n)-[r]-(m) RETURN n, r,m;`
// this.fetchData(query, nodeId)
// console.log('query', query)
// const _all_nodes = this.$refs.graphRef.getInstance().getNodes()
// const { lot } = nodeObject

Loading…
Cancel
Save