chenhj
2025-08-08 1f29e50d81c9168a9d5b4e90dbaebc2b6d4a47e3
Merge branch 'dev_ai' of http://114.132.189.42:9002/r/product-inventory-management into dev_ai
已修改3个文件
已添加2个文件
578 ■■■■ 文件已修改
src/views/chatHome/chatHomeIndex/MobileChat.vue 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/chatHome/chatHomeIndex/ai-jz.js 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/chatHome/chatHomeIndex/ai-wd.js 393 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/chatHome/chatHomeIndex/home.vue 63 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/collaborativeApproval/approvalProcess/components/approvalDia.vue 79 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/chatHome/chatHomeIndex/MobileChat.vue
@@ -49,13 +49,13 @@
        </div>
      </div>
    </div>
<!--    <div class="chat-input-wrapper">-->
<!--      <div style="display: flex; align-items: center">-->
<!--          <input v-model="inputMsg" @change="sendText" class="input-text" autofocus placeholder="给DeepSeek发送消息" />-->
<!--          <img class="send-icon" src="@/assets/img/emoji/rocket.png" alt="" @click="sendText" />-->
    <div class="chat-input-wrapper">
      <div style="display: flex; align-items: center">
          <input v-model="inputMsg" @change="sendText" :disabled="loading" class="input-text" autofocus placeholder="给小智发送消息" />
          <img class="send-icon" src="@/assets/img/emoji/rocket.png" alt="" @click="sendText" />
<!--      </div>-->
<!--    </div>-->
      </div>
    </div>
  </div>
</template>
@@ -67,6 +67,7 @@
import headPortrait from '@/assets/img/head_portrait.jpg'
import FileCard from '@/components/FileCard.vue'
import { ElMessage } from "element-plus"
import {checking} from './ai-wd.js'
// å®šä¹‰å“åº”式数据
const route = useRoute()
@@ -86,7 +87,7 @@
const isSend = ref(false)
const fileList = ref([])
const isProcessing = ref(false)
const loading = ref(false)
const loading = ref(true)
const srcImgList = ref([])
// åˆ é™¤å›¾ç‰‡
@@ -137,20 +138,19 @@
      chatType: 0, //信息类型,0文字,1图片
      uid: '1001' //uid
    }
    sendMsg(chatMsg)
    chatList.value.push(chatMsg)
    let chatGPT = {
      headImg: headPortrait,
      name: 'DeepSeek',
      name: '小智',
      time: new Date().toLocaleTimeString(),
      msg: "",
      chatType: 0, //信息类型,0文字,1图片
      uid: '1002' //uid
    }
    chatList.value.push(chatGPT) // å°†æŽ¥æ”¶åˆ°çš„æ¶ˆæ¯å­˜å‚¨åˆ° messages æ•°ç»„
    simulateStreamingOutput(chatGPT, inputMsg.value)
    inputMsg.value = ''
    loading.value = true
    isSend.value = true
    websocketsend(chatMsg.msg)
  } else {
    ElMessage({
      message: '消息不能为空哦~',
@@ -206,21 +206,22 @@
  // å¦‚果有查询关键字,则模拟流式输出
  if (route.query.keyWord) {
    simulateStreamingOutput(replyMsg)
    simulateStreamingOutput(replyMsg, route.query.keyWord)
  }
})
// æ¨¡æ‹Ÿæµå¼è¾“出
const simulateStreamingOutput = (msgObj) => {
  // ç”Ÿæˆ0.8-1.8秒之间的随机延迟
  const delay = Math.random() * 1000 + 800
const simulateStreamingOutput = async (msgObj, keyWord) => {
  loading.value = true
  // ç”Ÿæˆ0.8-1.3秒之间的随机延迟
  const delay = Math.random() * 500 + 800
  // æ¨¡æ‹Ÿå›žå¤å†…容(实际应用中应从API获取)
  const responseText = `关于"${route.query.keyWord}"的问题,我来为您解答:\n\n这是一个示例回复内容,展示流式输出效果。在实际应用中,这里会是来自AI的真实回复内容。\n\n请稍等,我正在整理相关信息...`
  const responseText = `关于"${keyWord}"的问题,我来为您解答:\n` + checking(keyWord)
  isSend.value = true
  let index = 0
  setTimeout(() => {
  const interval = setInterval(() => {
    isSend.value = true
    if (index < responseText.length) {
@@ -231,8 +232,11 @@
    } else {
      clearInterval(interval)
      isSend.value = false
        loading.value = false
    }
  }, 50) // æ¯50ms输出一个字符,模拟流式效果
  }, delay)
}
</script>
src/views/chatHome/chatHomeIndex/ai-jz.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,3 @@
export function jam() {
    return ""
}
src/views/chatHome/chatHomeIndex/ai-wd.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,393 @@
export function gasLeaks() {
  return "1. è®¾è®¡ä¸Žè®¾å¤‡é€‰æ‹©\n" +
      "选用高质量材料:管道、阀门、储罐等设备应选用耐腐蚀、耐高压的材料,并符合安全标准(如ASME、API等)。\n" +
      "\n" +
      "安全设计:\n" +
      "\n" +
      "安装冗余的安全装置(如双重阀门、爆破片、安全阀等)。\n" +
      "\n" +
      "设置气体泄漏检测系统(如可燃气体报警器、有毒气体传感器)。\n" +
      "\n" +
      "采用封闭式系统设计,减少开放接口。\n" +
      "\n" +
      "通风系统:在可能泄漏的区域安装强制通风设备,防止气体聚集。\n" +
      "\n" +
      "2. å®‰è£…与维护\n" +
      "规范安装:由专业人员进行设备安装,确保管道焊接、密封等环节无缺陷。\n" +
      "\n" +
      "定期检查:\n" +
      "\n" +
      "对管道、阀门、连接处进行泄漏检测(如压力测试、超声波检测、肥皂水检漏)。\n" +
      "\n" +
      "更换老化或腐蚀的部件。\n" +
      "\n" +
      "预防性维护:制定维护计划,定期润滑阀门、更换密封件等。\n" +
      "\n" +
      "3. æ“ä½œç®¡ç†\n" +
      "严格操作规程:\n" +
      "\n" +
      "操作人员需培训上岗,熟悉气体特性和应急流程。\n" +
      "\n" +
      "避免超压、超温或错误操作。\n" +
      "\n" +
      "监控系统:\n" +
      "\n" +
      "实时监测压力、温度、流量等参数,设置自动报警和联锁停机装置。\n" +
      "\n" +
      "使用气体检测仪(如红外、电化学传感器)监测环境浓度。\n" +
      "\n" +
      "明确标识:在危险区域标明气体类型、风险等级及防护要求。\n" +
      "\n" +
      "4. æ³„漏应急措施\n" +
      "应急设备:\n" +
      "\n" +
      "配备防毒面具、呼吸器、防护服等个人防护装备(PPE)。\n" +
      "\n" +
      "就近放置泄漏应急包(如堵漏胶、密封带)。\n" +
      "\n" +
      "紧急响应:\n" +
      "\n" +
      "立即切断气源(关闭上游阀门或启动紧急切断系统)。\n" +
      "\n" +
      "启动通风设备稀释气体浓度。\n" +
      "\n" +
      "疏散人员并上报专业部门(如消防、环保)。\n" +
      "\n" +
      "应急预案:定期演练泄漏处置流程,确保人员熟悉分工。\n" +
      "\n" +
      "5. å‚¨å­˜ä¸Žè¿è¾“安全\n" +
      "储存要求:\n" +
      "\n" +
      "储罐远离火源、高温区,并设置围堰防止扩散。\n" +
      "\n" +
      "液化气体储罐需配备泄压装置。\n" +
      "\n" +
      "运输安全:\n" +
      "\n" +
      "使用合规的运输车辆,固定气瓶防止碰撞。\n" +
      "\n" +
      "运输途中监控车辆状态(如GPS、温度传感器)。\n" +
      "\n" +
      "6. äººå‘˜åŸ¹è®­ä¸Žæ–‡åŒ–\n" +
      "安全培训:定期开展气体危害、防护措施和应急处理的培训。\n" +
      "\n" +
      "安全文化:鼓励员工报告潜在风险,建立“零泄漏”管理目标。\n" +
      "\n" +
      "7. æ³•规与标准\n" +
      "遵守相关法规(如OSHA、GB 50493《石油化工可燃气体和有毒气体检测报警设计规范》)。\n" +
      "\n" +
      "定期进行安全审计,确保符合行业标准。\n" +
      "\n" +
      "常见危险气体泄漏的针对性措施\n" +
      "可燃气体(如甲烷、氢气):防爆电器、消除静电。\n" +
      "\n" +
      "有毒气体(如氯气、硫化氢):配备专用过滤式或供氧式呼吸器。\n" +
      "\n" +
      "窒息性气体(如氮气、二氧化碳):监测氧气浓度,避免密闭空间作业。\n" +
      "\n" +
      "通过以上措施的综合应用,可大幅降低气体泄漏风险,保障人员安全和环境健康。若发生泄漏,需优先确保人员撤离,再由专业人员处置。\n" +
      "\n" +
      "本回答由 AI ç”Ÿæˆï¼Œå†…容仅供参考,请仔细甄别。"
}
export function shipping() {
    return "一、立即应急响应\n" +
        "1. å‘现泄漏时的紧急行动\n" +
        "停车并隔离现场:\n" +
        "\n" +
        "运输车辆立即停靠在空旷、远离人群和火源的位置。\n" +
        "\n" +
        "设置警戒线(至少50~100米半径,根据气体性质调整),禁止无关人员进入。\n" +
        "\n" +
        "切断泄漏源:\n" +
        "\n" +
        "关闭容器阀门或封堵破损处(如使用应急堵漏工具)。\n" +
        "\n" +
        "若阀门损坏,尝试转移剩余气体至备用容器(需专业人员操作)。\n" +
        "\n" +
        "报警与上报:\n" +
        "\n" +
        "拨打应急电话(如消防119、环保部门),说明气体类型、泄漏量、位置等信息。\n" +
        "\n" +
        "联系运输公司及货主,获取技术支援(如MSDS安全数据表)。\n" +
        "\n" +
        "2. äººå‘˜é˜²æŠ¤ä¸Žç–æ•£\n" +
        "穿戴防护装备:\n" +
        "\n" +
        "可燃气体:防爆工具+防静电服;有毒气体:正压式呼吸器+防化服。\n" +
        "\n" +
        "无防护装备时,立即撤离至上风方向。\n" +
        "\n" +
        "疏散周边区域:\n" +
        "\n" +
        "根据气体扩散范围(参考应急响应指南ERG)疏散居民或作业人员。\n" +
        "\n" +
        "避免低洼处滞留(某些气体比空气重,如硫化氢)。\n" +
        "\n" +
        "3. æŽ§åˆ¶æ³„漏扩散\n" +
        "物理方法:\n" +
        "\n" +
        "覆盖泄漏口(如用浸水棉被减少挥发,但禁用于遇水反应气体如氯气)。\n" +
        "\n" +
        "筑堤围堵液体泄漏物,防止流入下水道或河流。\n" +
        "\n" +
        "化学方法:\n" +
        "\n" +
        "中和处理(如氨气泄漏喷洒稀盐酸,需专业人员操作)。\n" +
        "\n" +
        "使用吸附材料(如活性炭、沙土吸附有机气体)。"
}
export function operate(){
    return "一、操作不当发生后的应急处理\n" +
        "1. ç«‹å³æŽ§åˆ¶äº‹æ•…\n" +
        "停止操作:\n" +
        "\n" +
        "按下紧急停机按钮,关闭最近的上游阀门。\n" +
        "\n" +
        "启动应急预案:\n" +
        "\n" +
        "小型泄漏:使用应急堵漏工具(如密封胶、夹具)。\n" +
        "\n" +
        "大型泄漏:疏散人员,报警求助(119/环保部门)。\n" +
        "\n" +
        "2. äººå‘˜å®‰å…¨\n" +
        "撤离与隔离:\n" +
        "\n" +
        "逆风撤离至上风向安全区,避免低洼处(重气体积聚)。\n" +
        "\n" +
        "急救措施:\n" +
        "\n" +
        "吸入有毒气体:移至空气新鲜处,必要时人工呼吸。\n" +
        "\n" +
        "皮肤接触:立即用清水冲洗15分钟(腐蚀性气体)。\n" +
        "\n" +
        "3. äº‹æ•…调查与整改\n" +
        "根本原因分析(RCA):\n" +
        "\n" +
        "是操作失误、培训不足,还是设备缺陷?\n" +
        "\n" +
        "改进措施:\n" +
        "\n" +
        "修订操作规程,增加警示标识。\n" +
        "\n" +
        "对责任人再培训,必要时调岗。"
}
export function emergency(){
    return "一、优化应急响应的关键措施\n" +
        "1. å®Œå–„应急预案\n" +
        "针对性设计:\n" +
        "\n" +
        "基于HAZOP(危险与可操作性分析)识别所有潜在风险场景。\n" +
        "\n" +
        "制定分级响应机制(小泄漏现场处置、大泄漏全员疏散)。\n" +
        "\n" +
        "明确职责:\n" +
        "\n" +
        "设立应急指挥部,指定总指挥、通讯组、抢险组、医疗组等。\n" +
        "\n" +
        "确保24小时值班制度,联系方式实时更新。\n" +
        "\n" +
        "联动外部资源:\n" +
        "\n" +
        "与消防、环保、医院提前签订救援协议,明确协作流程。\n" +
        "\n" +
        "2. å¼ºåŒ–应急资源保障\n" +
        "装备与物资:\n" +
        "\n" +
        "配备足量且有效的应急设备,包括:\n" +
        "\n" +
        "个人防护装备(PPE):防毒面具、化学防护服。\n" +
        "\n" +
        "堵漏工具:密封胶、夹具、快速封堵器。\n" +
        "\n" +
        "吸附/中和材料:活性炭、沙土、稀碱液(用于酸性气体)。\n" +
        "\n" +
        "定期检查、维护和更换(如气瓶压力、传感器电池)。\n" +
        "\n" +
        "应急车辆与通道:\n" +
        "\n" +
        "确保救援车辆可快速抵达泄漏点(清除路障,标识应急路线)。\n" +
        "\n" +
        "关键区域设置应急洗眼器、喷淋系统。\n" +
        "\n" +
        "3. åŠ å¼ºäººå‘˜åŸ¹è®­ä¸Žèƒ½åŠ›å»ºè®¾\n" +
        "分层培训:\n" +
        "\n" +
        "基层人员:掌握基本应急处置(如关闭阀门、使用灭火器)。\n" +
        "\n" +
        "应急小组:专业堵漏、伤员急救、气体检测技能。\n" +
        "\n" +
        "管理层:指挥决策、媒体沟通、法律合规。\n" +
        "\n" +
        "实战化考核:\n" +
        "\n" +
        "通过模拟突发泄漏(如盲演)检验响应速度。\n" +
        "\n" +
        "不合格者需重新培训。\n" +
        "\n" +
        "4. å®šæœŸæ¼”练与持续改进\n" +
        "演练频率:\n" +
        "\n" +
        "每季度至少1次桌面推演,每年2次综合实战演练。\n" +
        "\n" +
        "场景设计:\n" +
        "\n" +
        "模拟复杂情况(如夜间停电、多人受伤)。\n" +
        "\n" +
        "引入“突发变量”(如风向突变、二次泄漏)。\n" +
        "\n" +
        "复盘与优化:\n" +
        "\n" +
        "记录演练中的问题(如通讯延迟、装备缺失)。\n" +
        "\n" +
        "更新预案并下发学习。\n" +
        "\n" +
        "5. æŠ€æœ¯å‡çº§ä¸Žæ™ºèƒ½åŒ–支持\n" +
        "实时监测与预警:\n" +
        "\n" +
        "部署物联网(IoT)传感器,监测气体浓度、设备状态。\n" +
        "\n" +
        "设置自动联锁控制(如泄漏时联动关闭阀门并启动通风)。\n" +
        "\n" +
        "应急通讯系统:\n" +
        "\n" +
        "使用防爆对讲机、卫星电话(保障信号覆盖)。\n" +
        "\n" +
        "建立应急广播系统(如厂区警报、短信群发)。\n" +
        "\n" +
        "数字化预案:\n" +
        "\n" +
        "将应急预案录入移动终端,实现一键调阅、步骤指引。"
}
export function compliance(){
    return "一、常见的合规性问题\n" +
        "1. è®¸å¯ä¸Žèµ„质缺失\n" +
        "问题:\n" +
        "\n" +
        "未取得危险化学品经营许可证或安全生产许可证。\n" +
        "\n" +
        "特种作业人员(如压力容器操作工)无证上岗。\n" +
        "\n" +
        "风险:\n" +
        "\n" +
        "监管部门处罚(如罚款、责令停产)。\n" +
        "\n" +
        "保险拒赔(事故发生时)。\n" +
        "\n" +
        "2. å®‰å…¨è®¾è®¡ä¸è¾¾æ ‡\n" +
        "问题:\n" +
        "\n" +
        "储罐、管道未按GB/T 150(压力容器标准)设计。\n" +
        "\n" +
        "未安装可燃/有毒气体报警器(违反GB 50493)。\n" +
        "\n" +
        "风险:\n" +
        "\n" +
        "设备失效导致泄漏或爆炸。\n" +
        "\n" +
        "不符合应急管理部或OSHA检查要求。\n" +
        "\n" +
        "3. æ“ä½œä¸Žç»´æŠ¤è¿è§„\n" +
        "问题:\n" +
        "\n" +
        "未执行作业票制度(如动火作业未审批)。\n" +
        "\n" +
        "未定期检验压力容器(违反TSG 21-2016)。\n" +
        "\n" +
        "风险:\n" +
        "\n" +
        "违规操作引发事故(如焊接引发可燃气体爆炸)。\n" +
        "\n" +
        "设备老化导致突发泄漏。\n" +
        "\n" +
        "4. åº”急管理不合规\n" +
        "问题:\n" +
        "\n" +
        "未制定应急预案或未备案(违反《生产安全事故应急条例》)。\n" +
        "\n" +
        "未配备应急物资(如防毒面具、堵漏工具)。\n" +
        "\n" +
        "风险:\n" +
        "\n" +
        "事故发生时无法有效控制,导致损失扩大。\n" +
        "\n" +
        "面临生态环境部追责(如化学品污染土壤/水体)。\n" +
        "\n" +
        "5. è®°å½•与报告缺失\n" +
        "问题:\n" +
        "\n" +
        "未保存安全检查记录或培训档案。\n" +
        "\n" +
        "未按规定上报泄漏事故(如瞒报、迟报)。\n" +
        "\n" +
        "风险:\n" +
        "\n" +
        "事故调查时无法自证合规,承担全责。\n" +
        "\n" +
        "被列入安全生产黑名单,影响企业信誉。"
}
export function monitoring(){
    return "一、固定式监测技术\n" +
        "1. å‚¬åŒ–燃烧式传感器\n" +
        "原理:可燃气体在铂丝表面燃烧导致电阻变化\n" +
        "\n" +
        "优势:成本低(¥500-2000/个)、响应快(<10s)\n" +
        "\n" +
        "局限:易中毒(硅/硫化合物)、寿命短(2-3年)\n" +
        "\n" +
        "适用:石化厂可燃气监测(甲烷、氢气等)\n" +
        "\n" +
        "2. ç”µåŒ–学传感器\n" +
        "原理:气体与电解液发生氧化还原反应产生电流\n" +
        "\n" +
        "优势:ppb级检测(如H2S检测下限0.1ppm)\n" +
        "\n" +
        "局限:受温湿度影响(需定期校准)\n" +
        "\n" +
        "适用:有毒气体(Cl₂、NH₃、CO等)\n" +
        "\n" +
        "3. çº¢å¤–吸收式(NDIR)\n" +
        "原理:气体对特定红外波段的吸收率检测\n" +
        "\n" +
        "优势:免校准(寿命5-10年)、抗中毒\n" +
        "\n" +
        "局限:高成本(¥5000+/个)\n" +
        "\n" +
        "适用:CO₂、CH₄等温室气体监测\n" +
        "\n" +
        "4. æ¿€å…‰å…‰è°±ï¼ˆTDLAS)\n" +
        "原理:可调谐激光二极管扫描气体吸收线\n" +
        "\n" +
        "优势:ppm级精度、响应ms级\n" +
        "\n" +
        "局限:需光学对准(安装复杂)\n" +
        "\n" +
        "适用:管道微泄漏检测(天然气长输管线)"
}
export function checking(keyWord){
    if(keyWord.includes("气体泄漏")){
        return gasLeaks();
    }
    if(keyWord.includes("容器失效")){
        return shipping();
    }
    if(keyWord.includes("操作不当")){
        return operate();
    }
    if(keyWord.includes("响应不足")){
        return emergency();
    }
    if(keyWord.includes("合规性")){
        return compliance();
    }
    if(keyWord.includes("监测技术")){
        return monitoring();
    }
    return "不好意思,小智还在成长过程中,您的问题已经超过小智的处理范围了。";
}
src/views/chatHome/chatHomeIndex/home.vue
@@ -3,10 +3,10 @@
    <div style="background: white;color: black;font-size: 30px;" class="logo">
        <div class="logo-one" style="font-weight: bold">
<!--            <img src="/src/assets/img/logo.png" style="width: 50px;height: 50px;margin: 0 10px" />-->
            <div><i>淮南东方医院集团DeepSeek应用平台</i></div>
            <div><i>大模型AI小智正在为您服务</i></div>
        </div>
        <div class="input">
            <input type="text" v-model="keyWord" class="input-text" placeholder="给DeepSeek发送消息"  @keyup.enter="sendMsg" />
            <input type="text" v-model="keyWord" class="input-text" placeholder="给小智发送消息"  @keyup.enter="sendMsg" />
            <div style="font-size: 13px;color: #808080;display: flex;justify-content: space-between;padding: 10px;">
                <div style="display: flex;justify-content: center;align-items: center;">
<!--                    <div style="display: flex;justify-content: center;align-items: center;">-->
@@ -29,43 +29,37 @@
            <div class="keywords">
                <div class="keywordss" @click="sendMsgDefault(keyWordOne)">
                    <p class="fontSize aaa">{{keyWordOne}}</p>
                    <p class="fontSize">选择科空:根据病情选择相应的科室(如内科、外科、儿科等)</p>
                    <p class="fontSize">挂号方式:现场挂号:在医院挂号窗口排队办理。线上挂号:通过医院官网、微</p>
                    <p class="fontSize">信公众号或第三方平台预约...</p>
                    <p class="fontSize">阀门、管道或容器密封失效导致气体泄漏(如氯气、氨气)。</p>
                    <p class="fontSize">后果:中毒、爆炸、环境污染。</p>
                </div>
                <div class="keywordss" @click="sendMsgDefault(keyWordTwo)">
                    <p class="fontSize aaa">{{keyWordTwo}}</p>
                    <p class="fontSize">普通病房:探视时问一般为每天上午10:00-12:00,下午14:00-20.00。每次探视人</p>
                    <p class="fontSize">数不超过2人,探视时间不超过30分钟。</p>
                    <p class="fontSize">重症监护室(1CU):探视时问较短,通常为每天15:00-16:00。探视人数.</p>
                    <p class="fontSize">钢瓶或罐体因材料疲劳、腐蚀或超压破裂</p>
                    <p class="fontSize">原因:未定期检测、违规充装或外部撞击。。</p>
                </div>
            </div>
            <div class="keywords">
                <div class="keywordss" @click="sendMsgDefault(keyWordFive)">
                    <p class="fontSize aaa">{{keyWordFive}}</p>
                    <p class="fontSize">选择体检套餐:根据个人需求选择基础套轻或专项检杏套。</p>
                    <p class="fontSize">预约方式:线上预约:通过医院官网、微信公众号或第三方平台预约。电话豫</p>
                    <p class="fontSize">约:拨打医院体检中心电话进行预约。现场预约:直接到体检中心</p>
                    <p class="fontSize">装卸过程中违规操作(如野蛮搬运、混装禁忌物质)。</p>
                    <p class="fontSize">运输途中未固定容器,导致碰撞或倾倒。</p>
                </div>
                <div class="keywordss" @click="sendMsgDefault(keyWordSix)">
                    <p class="fontSize aaa">{{keyWordSix}}</p>
                    <p class="fontSize">医生确认出院:主治医生评估患者病情后,开具出院。</p>
                    <p class="fontSize">结算费用:患者或家属携带住院押金单、医保卡等材料到出院结算窗口办理。核</p>
                    <p class="fontSize">对费用明细,支付自费部分或办理医保报销..</p>
                    <p class="fontSize">缺乏泄漏应急预案,人员培训不足。</p>
                    <p class="fontSize">救援设备(如防毒面具、堵漏工具)缺失或失效。</p>
                </div>
            </div>
            <div class="keywords">
                <div class="keywordss" @click="sendMsgDefault(keyWordServen)">
                    <p class="fontSize aaa">{{keyWordServen}}</p>
                    <p class="fontSize">院内投诉:直接向医院医务科或患者服务中心反映问题。填写投诉表,提供详细</p>
                    <p class="fontSize">情况和证据(如病历、录音等)。</p>
                    <p class="fontSize">上级部门投诉:向当地卫生能康委员会或医疗纠纷调解委员会投诉。拨打…</p>
                    <p class="fontSize">未取得运输资质(如ADR/RID等国际规范)。</p>
                    <p class="fontSize">路线规划不合规(如穿越人口密集区)。</p>
                </div>
                <div class="keywordss" @click="sendMsgDefault(keyWordEight)">
                    <p class="fontSize aaa">{{keyWordEight}}</p>
                    <p class="fontSize">申请转院:患者或家属向主治医生提出转院申请。医生评估病情,确认是否需要</p>
                    <p class="fontSize">转院。</p>
                    <p class="fontSize">开具转院证明:主治医生开具转院证明,说明转院原因和病情..…</p>
                    <p class="fontSize">传感器部署(如红外气体探测器、电化学传感器)。</p>
                    <p class="fontSize">实时数据传输至监控平台,触发报警。</p>
                </div>
            </div>
        </div>
@@ -81,22 +75,13 @@
const route = useRoute();
const router = useRouter();
const keyWord = ref('');
const keyWordOne = ref('医院挂号流程是怎样的?');
const keyWordTwo = ref('医院探视时问有哪些规定?');
const keyWordFive = ref('医院如何预约体检?');
const keyWordSix = ref('医院如何办理出院手续?');
const keyWordServen = ref('医院如何投诉医疗服务质量?');
const keyWordEight = ref('医院如何办理转院手续?');
const keyWordOne = ref('危险气体泄漏怎么办');
const keyWordTwo = ref('运输容器失效怎么办');
const keyWordFive = ref('操作不当怎么办');
const keyWordSix = ref('应急响应不足怎么办');
const keyWordServen = ref('合规性问题');
const keyWordEight = ref('泄漏监测技术有哪些');
onMounted(() => {
    // const script = document.createElement('script');
    // script.src = '/src/assets/js/index.js';
    // // script.type = 'module'
    // script.onload = () => {
    //     console.log('index.js å·²åŠ è½½');
    // };
    // document.head.appendChild(script);
});
const sendMsg = () => {
    router.push({ path: '/main/MobileChat',query:{ keyWord: keyWord.value} })
}
@@ -144,13 +129,13 @@
        .aaa {
          font-weight: bold;
          font-size: 12px;
          font-size: 15px !important;
        }
        .fontSize {
          font-size: 10px;
          height: 15px;
          line-height: 15px;
          font-size: 13px;
          height: 20px;
          line-height: 20px;
          margin: 6px;
        }
      }
src/views/collaborativeApproval/approvalProcess/components/approvalDia.vue
@@ -102,6 +102,10 @@
              <div v-if="!activity.isShen" class="node-reason">
                <span>审批意见:</span>{{ activity.approveNodeReason }}
              </div>
              <div v-if="!activity.isShen" class="node-reason">
                <span>签名:</span>
                                <img :src="activity.urlTem" class="signImg" alt="" v-if="activity.urlTem"/>
              </div>
              <div v-else-if="activity.isShen">
                <el-form-item
                  :prop="'activities.' + index + '.approveNodeReason'"
@@ -116,7 +120,7 @@
      </el-form>
      <template #footer v-if="operationType === 'approval'">
        <div class="dialog-footer">
          <el-button type="primary" @click="openSignatureDialog(2)">不通过</el-button>
          <el-button type="primary" @click="submitForm(2)">不通过</el-button>
          <el-button type="primary" @click="openSignatureDialog(1)">通过</el-button>
          <el-button @click="closeDia">取消</el-button>
        </div>
@@ -152,6 +156,7 @@
import useUserStore from "@/store/modules/user.js";
import {userListNoPageByTenantId} from "@/api/system/user.js";
import { WarningFilled, Edit, Check, MoreFilled } from '@element-plus/icons-vue'
import { getToken } from "@/utils/auth";
const emit = defineEmits(['close'])
const { proxy } = getCurrentInstance()
@@ -180,6 +185,14 @@
const esign = ref(null);
const lineWidth = ref(0);
const lineColor = ref("#000000");
// ä¸Šä¼ é…ç½®
const upload = reactive({
  // ä¸Šä¼ çš„地址
  url: import.meta.env.VITE_APP_BASE_API + "/file/upload",
  // è®¾ç½®ä¸Šä¼ çš„请求头部
  headers: { Authorization: "Bearer " + getToken() },
});
// èŠ‚ç‚¹æ ‡é¢˜
const getNodeTitle = (index, len) => {
@@ -215,6 +228,11 @@
    activities.value = res.data
    // å¢žåŠ isApproval字段
    activities.value.forEach(item => {
            if (item.url && item.url.includes('word')) {
                item.urlTem = item.url.replaceAll('word', 'img')
            } else {
                item.urlTem = item.url
            }
      if (item.approveNodeStatus === 2) {
        item.isApproval = '已驳回';
      } else if (item.approveNodeStatus === 1) {
@@ -243,23 +261,67 @@
const confirmSignature = () => {
    esign.value.generate().then((res) => {
        console.log(res);
        signatureImg.value = res;
        // å°†base64转换为二进制
        const base64Data = res.split(',')[1]; // ç§»é™¤data:image/png;base64,前缀
        const binaryString = atob(base64Data);
        const bytes = new Uint8Array(binaryString.length);
        for (let i = 0; i < binaryString.length; i++) {
            bytes[i] = binaryString.charCodeAt(i);
        }
        signatureImg.value = bytes;
        // åˆ›å»ºæ–‡ä»¶å¯¹è±¡ç”¨äºŽä¸Šä¼ 
        const blob = new Blob([bytes], { type: 'image/png' });
        const file = new File([blob], 'signature.png', { type: 'image/png' });
        // åˆ›å»ºFormData
        const formData = new FormData();
        formData.append('file', file);
        // ä¸Šä¼ ç­¾åå›¾ç‰‡
        fetch(upload.url, {
            method: 'POST',
            headers: upload.headers,
            body: formData
        })
        .then(response => response.json())
        .then(data => {
            if (data.code === 200) {
                console.log('data---', data)
                let tempFileIds = [];
                tempFileIds.push(data.data.tempId);
        signatureDialogVisible.value = false;
        clearSignature()
                clearSignature();
                // åªæœ‰é€šè¿‡æ—¶æ‰ä¼ é€’签名文件ID
                if (submitStatus === 1) {
                    submitForm(submitStatus, tempFileIds);
                } else {
        submitForm(submitStatus);
                }
            } else {
                proxy.$modal.msgError("签名图片上传失败:" + data.msg);
            }
        })
        .catch(error => {
            console.error('上传失败:', error);
            proxy.$modal.msgError("签名图片上传失败");
        });
    }).catch((err) => {
        console.log(err);
        proxy.$modal.msgWarning("请先签名!");
    })
};
// æäº¤å®¡æ‰¹
const submitForm = (status) => {
const submitForm = (status, tempFileIds) => {
  const filteredActivities = activities.value.filter(activity => activity.isShen);
  filteredActivities[0].approveNodeStatus = status;
  filteredActivities[0].signatureImg = signatureImg.value; // æ–°å¢žç­¾åå›¾ç‰‡å­—段
  // åªæœ‰é€šè¿‡æ—¶æ‰éœ€è¦ç­¾å
  if (status === 1 && tempFileIds) {
    filteredActivities[0].tempFileIds = tempFileIds;
  }
  // åˆ¤æ–­æ˜¯å¦ä¸ºæœ€åŽä¸€æ­¥
  const isLast = activities.value.findIndex(a => a.isShen) === activities.value.length-1;
  updateApproveNode({ ...filteredActivities[0], isLast, signatureImg: signatureImg.value }).then(() => {
  updateApproveNode({ ...filteredActivities[0], isLast }).then(() => {
    proxy.$modal.msgSuccess("提交成功");
    closeDia();
  });
@@ -301,4 +363,9 @@
    height: 30px;
    border-radius: 50px;
}
.signImg {
    cursor: pointer;
    width: 200px;
    height: 60px;
}
</style>