瀏覽代碼

ca签名优化

xiaochan 4 月之前
父節點
當前提交
ea66077e2e

+ 1 - 1
.env.production

@@ -8,7 +8,7 @@ VITE_SOCKET_V2 = 'ws://172.16.32.160:20922/websocket'
 
 VITE_DATA_BASE = 'http://172.16.32.167:9205'
 VITE_MAGIC_API_IFRAME = 'http://172.16.32.170:9207'
-
+VITE_CA_SCRIPT_ID = '2154eae0167611ef8717efceee160e36'
 
 VITE_HOSPITAL_NAME = '长沙泰和'
 VITE_SYSTEM_NAME = '工作集成平台'

+ 2 - 1
.env.show

@@ -4,5 +4,6 @@ VITE_BASE_URL = 'http://demo.hnthyy.cn:8706'
 VITE_SOCKET_URL = 'ws://demo.hnthyy.cn:8707/websocket/'
 
 VITE_DATA_BASE = 'http://172.16.30.61:9205'
+VITE_CA_SCRIPT_ID = '2154eae0167611ef8717efceee160e36'
 
-VITE_UPLOAD_TEMPLATE_THUMB = 'undefined'
+VITE_UPLOAD_TEMPLATE_THUMB = 'undefined'

+ 1 - 0
.env.tz

@@ -6,6 +6,7 @@ VITE_EMR_CONTROL_URL = '172.16.20.115:9227'
 VITE_DATA_BASE = 'http://172.16.20.115:9205'
 VITE_SOCKET_V2 = 'http://172.16.20.115:8707/socketApi'
 VITE_MAGIC_API_IFRAME = 'http://172.16.20.115:9206'
+VITE_CA_SCRIPT_ID = '2154eae0167611ef8717efceee160e36'
 
 VITE_HOSPITAL_NAME = '天资'
 VITE_SYSTEM_NAME = '工作集成平台'

+ 1 - 2
package.json

@@ -4,8 +4,7 @@
   "scripts": {
     "dev": "vite",
     "update:element": "npm install element-plus ./deps/element-plus.2.7.1.1.tar.gz",
-    "build:env": "vite build && node ./bin/inject-env-to-window.js",
-    "build:nodetest": "node ./bin/inject-env-to-window.js"
+    "build:env": "vite build && node ./bin/inject-env-to-window.js"
   },
   "type": "module",
   "dependencies": {

+ 49 - 8
src/api/ca/ca-api.ts

@@ -1,4 +1,6 @@
 import requestV2 from "@/utils/request-v2";
+import { ElMessageBox } from "element-plus";
+import { CyMessageBox } from "@/utils/cy-message-box";
 
 export type CaSendParams = {
   id: string;
@@ -43,7 +45,7 @@ export interface MoreEventSignData {
 
 export function sendByCode(data: CaSendParams) {
   return requestV2<CaResult>({
-    url: "/thyyca/sendByCode",
+    url: "/casign/sendByCode",
     method: "POST",
     data,
   });
@@ -51,7 +53,7 @@ export function sendByCode(data: CaSendParams) {
 
 export function sendBatchByCode(data: CaSendParams) {
   return requestV2<CaResult[]>({
-    url: "/thyyca/sendBatchByCode",
+    url: "/casign/sendBatchByCode",
     showLoading: false,
     method: "POST",
     data,
@@ -65,7 +67,7 @@ export function sendMoreEventSign(data: {
   sendCodeName: string;
 }) {
   return requestV2({
-    url: "/thyyca/sendMoreEventSign",
+    url: "/casign/sendMoreEventSign",
     method: "POST",
     data,
   });
@@ -73,7 +75,7 @@ export function sendMoreEventSign(data: {
 
 export function h5EventSign(data) {
   return requestV2({
-    url: "/thyyca/h5EventSign",
+    url: "/casign/h5EventSign",
     method: "POST",
     data,
   });
@@ -90,7 +92,7 @@ export function hBoardSignV2(data: {
   signOpinion: string;
 }) {
   return requestV2({
-    url: "/thyyca/hBoardSignV2",
+    url: "/casign/hBoardSignV2",
     method: "POST",
     data,
   });
@@ -98,7 +100,7 @@ export function hBoardSignV2(data: {
 
 export function downloadSealV2(id, documentId) {
   return requestV2({
-    url: "/thyyca/downloadSealV2",
+    url: "/casign/downloadSealV2",
     method: "get",
     params: {
       id,
@@ -110,7 +112,7 @@ export function downloadSealV2(id, documentId) {
 // 判断扫码是否完成以及回写扫码的数据
 export function scanCodeVerification(id, documentId, uuid) {
   return requestV2<boolean>({
-    url: "/thyyca/scanCodeVerification",
+    url: "/casign/scanCodeVerification",
     method: "get",
     params: {
       id,
@@ -122,8 +124,47 @@ export function scanCodeVerification(id, documentId, uuid) {
 
 export function completeQrCode(documentId) {
   return requestV2({
-    url: "/thyyca/completeQrCode",
+    url: "/casign/completeQrCode",
     method: "get",
     params: { documentId },
   });
 }
+
+export interface PatientIdCardType {
+  id: string;
+  idCard: string;
+  caType: number; // 使用枚举类型
+  name: string;
+  patNo: string;
+  caTypeName?: string;
+}
+
+export function getIdCardTypeList(patNo: string) {
+  return requestV2<PatientIdCardType[]>({
+    url: "/casign/getIdCardTypeList",
+    method: "get",
+    params: {
+      patNo,
+    },
+  });
+}
+
+export function savePatientIdCardType(
+  insert: PatientIdCardType[],
+  update: PatientIdCardType[],
+  patNo: string
+) {
+  return requestV2({
+    method: "POST",
+    url: "/casign/savePatientIdCardType",
+    data: { insert, update, patNo },
+  });
+}
+
+export function deletePatientIdCardType(id: string) {
+  return requestV2({
+    method: "get",
+    url: "/casign/deletePatientIdCardType",
+    params: { id },
+  });
+}

+ 18 - 0
src/utils/setting.ts

@@ -1,4 +1,22 @@
 const isProduction = import.meta.env.MODE === "production";
+
+type ImportMetaEnv = {
+  readonly VITE_BASE_URL: string;
+  readonly VITE_SOCKET_URL: string;
+  readonly VITE_EMR_CONTROL_URL: string;
+
+  readonly VITE_DATA_BASE: string;
+  readonly VITE_MAGIC_API_IFRAME: string;
+  readonly VITE_HOSPITAL_NAME: string;
+  readonly VITE_SYSTEM_NAME: string;
+  readonly VITE_HOSPITAL_CODE: string;
+  readonly VITE_UPLOAD_TEMPLATE_THUMB: string;
+  readonly VITE_SOCKET_V2: string;
+
+  // 电子病历医生签名的caid
+  readonly VITE_CA_SCRIPT_ID: string;
+};
+
 const env: ImportMetaEnv = isProduction
   ? window["__PRODUCTION____APP__CONF__"]
   : import.meta.env;

+ 5 - 0
src/utils/useCompRef.ts

@@ -1,4 +1,5 @@
 import { ref } from "vue";
+import { VxeTableInstance } from "vxe-table";
 
 /**
  * 获取组件的实例
@@ -16,4 +17,8 @@ export function useCompShallowRef<T extends abstract new (...args: any) => any>(
   return shallowRef<InstanceType<T>>();
 }
 
+export function useVxeTableRef<T = any>() {
+  return ref<VxeTableInstance<T>>();
+}
+
 export default useCompRef;

+ 73 - 3
src/views/hospitalization/zhu-yuan-yi-sheng/electronic-medical-record/emr-editor/plugins/ca/EmrCAComp.vue

@@ -11,7 +11,11 @@ import {
 } from "./emr-ca";
 import XEUtils from "xe-utils";
 import { BizException, ExceptionEnum } from "@/utils/BizException";
-import { sendMoreEventSign } from "@/api/ca/ca-api";
+import {
+  getIdCardTypeList,
+  PatientIdCardType,
+  sendMoreEventSign,
+} from "@/api/ca/ca-api";
 import { useDialog } from "@/components/cy/CyDialog/index";
 import EmrCaSign from "./EmrCaSign.vue";
 import { ElMessageBox } from "element-plus";
@@ -19,6 +23,9 @@ import XcElOption from "@/components/xiao-chan/xc-el-option/XcElOption.vue";
 import { useUserStore } from "@/pinia/user-store";
 import { patientInfo } from "@/views/hospitalization/zhu-yuan-yi-sheng/electronic-medical-record/emr-editor/emr-init";
 import { stringIsBlank } from "@/utils/blank-utils";
+import { isDev } from "@/utils/public";
+
+const SignIdCard = defineAsyncComponent(() => import("./SignIdCard.vue"));
 
 const root = inject(emrRootContextKey) as EmrStore;
 const selectList = ref<SignComp[]>([]);
@@ -28,6 +35,8 @@ const signTypeValue = ref(null);
 const idCardPublicKey =
   "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCgHPo86lSh7IzXcrgxi+7us2UeeY/O5ftBhk+P8hFfivGbS9RqCIDg+r7+nhINojsJeloeoavF0eHCMs1crzGd+XSMN6BjfPTm7bgoWu4CzplmFCBlZ5FAZCxXiHcHuBfG6tateaO2s7E1XpEsjSX/8J8VjKfIm7bzuNU/AyM2TwIDAQAB";
 
+const idCardTypeList = ref([]);
+
 const us = useUserStore().userInfo;
 
 const changeSignType = val => {
@@ -237,7 +246,6 @@ const signType = [
 ];
 
 const addCompByInternal = (name: string) => {
-  console.log(1);
   const editor = root.getEditor();
   editor.execute("insertContents", {
     value: [
@@ -268,6 +276,59 @@ const addAuthorizedSignatureDataElement = () => {
   });
 };
 
+function handleCardType() {
+  getIdCardTypeList(patientInfo.value.inpatientNo).then(res => {
+    res.forEach(item => {
+      const find = XEUtils.find(selectData, i => {
+        return i.code === item.caType;
+      });
+      item.caTypeName = find.name ?? "未知";
+    });
+    idCardTypeList.value = res;
+  });
+}
+
+function openSignIdCard() {
+  useDialog(SignIdCard, {
+    params: {
+      data: idCardTypeList.value,
+      patNo: patientInfo.value.inpatientNo,
+    },
+    dialogProps: {
+      title: "维护患者身份证",
+    },
+    confirmText: "保存",
+  }).then(() => {
+    handleCardType();
+  });
+}
+
+function handleSignType(val, index) {
+  const find = XEUtils.filter(idCardTypeList.value ?? [], i => {
+    return i.caType === val;
+  });
+
+  if (find.length === 0) {
+    return;
+  }
+
+  if (find.length === 1) {
+    setSelectListByIndex(index, find[0]);
+  }
+}
+
+function setSelectListByIndex(index, data: PatientIdCardType) {
+  selectList.value[index] = {
+    ...selectList.value[index],
+    idCard: data.idCard,
+    signName: data.name,
+  };
+}
+
+onMounted(() => {
+  handleCardType();
+});
+
 defineExpose({
   change,
 });
@@ -293,6 +354,11 @@ defineExpose({
       </el-button>
       <el-button @click="addCompByInternal('患者CA签名')">签名组件</el-button>
       <el-button @click="addCompByInternal('患者CA意见')">意见组件</el-button>
+
+      <hr />
+
+      <el-button @click="openSignIdCard"> 维护签名详情</el-button>
+
       <el-form label-position="top">
         <el-form-item label="签名方式">
           <el-select
@@ -336,7 +402,11 @@ defineExpose({
         </template>
         <el-form label-position="left">
           <el-form-item label="关系">
-            <el-select v-model="item.signType" style="width: 30%">
+            <el-select
+              v-model="item.signType"
+              style="width: 30%"
+              @change="val => handleSignType(val, index)"
+            >
               <xc-el-option :data="selectData" />
             </el-select>
             <el-input style="width: 70%" v-model="item.signTypeName">

+ 120 - 0
src/views/hospitalization/zhu-yuan-yi-sheng/electronic-medical-record/emr-editor/plugins/ca/SignIdCard.vue

@@ -0,0 +1,120 @@
+<script setup lang="ts">
+import XcElOption from "@/components/xiao-chan/xc-el-option/XcElOption.vue";
+import { selectData } from "./emr-ca";
+import type { UseDialogType } from "@/components/cy/CyDialog/index";
+import { useVxeTableRef } from "@/utils/useCompRef";
+import {
+  deletePatientIdCardType,
+  PatientIdCardType,
+  savePatientIdCardType,
+} from "@/api/ca/ca-api";
+import XEUtils from "xe-utils";
+import { BizException, ExceptionEnum } from "@/utils/BizException";
+import { Row } from "vxe-pc-ui";
+import { CyMessageBox } from "@/utils/cy-message-box";
+
+const props = defineProps<{ data: any[]; patNo: string }>();
+
+const tableRef = useVxeTableRef<PatientIdCardType>();
+
+async function handleAdd() {
+  const caType = selectData[2];
+
+  const { row } = await tableRef.value.insertAt(
+    {
+      name: "",
+      id: null,
+      idCard: "",
+      caType: caType.code,
+      caTypeName: caType.name,
+    } as PatientIdCardType,
+    -1
+  );
+  await tableRef.value.setEditRow(row, "name");
+}
+
+async function handleDel(row, index: number) {
+  console.log(row);
+  await CyMessageBox.confirm({
+    message: "删除后无法恢复",
+    type: "delete",
+  });
+  await deletePatientIdCardType(row.id);
+  tableRef.value.remove(row);
+}
+
+const validRules = {
+  name: [{ required: true, message: "必须填写" }],
+  idCard: [{ required: true, message: "必须填写" }],
+};
+
+const editorConfig = {
+  trigger: "click",
+  mode: "row",
+  autoClear: false,
+  showStatus: true,
+  beforeEditMethod({ row }) {
+    return row.id !== "temp";
+  },
+};
+
+function handleSelect(row, val) {
+  row.caTypeName =
+    XEUtils.find(selectData, item => item.code === val)?.name ?? "未知";
+}
+
+defineExpose<UseDialogType.Expose>({
+  async confirm() {
+    const insertRecords = tableRef.value.getInsertRecords();
+    const editRecord = tableRef.value.getUpdateRecords();
+
+    const errMap = await tableRef.value.validate(true);
+    if (errMap) {
+      BizException(ExceptionEnum.MESSAGE_ERROR, "校验不通过!");
+    }
+    await savePatientIdCardType(insertRecords, editRecord, props.patNo);
+    return true;
+  },
+});
+</script>
+
+<template>
+  <vxe-table
+    ref="tableRef"
+    keep-source
+    :data="data"
+    :edit-rules="validRules"
+    :edit-config="editorConfig"
+  >
+    <vxe-column :edit-render="{}" title="名字" field="name">
+      <template #edit="{ row }">
+        <el-input v-model="row.name" />
+      </template>
+    </vxe-column>
+
+    <vxe-column :edit-render="{}" title="关系" field="caTypeName">
+      <template #edit="{ row }">
+        <el-select v-model="row.caType" @change="val => handleSelect(row, val)">
+          <xc-el-option :data="selectData" />
+        </el-select>
+      </template>
+    </vxe-column>
+
+    <vxe-column :edit-render="{}" title="身份证" field="idCard">
+      <template #edit="{ row }">
+        <el-input v-model="row.idCard" />
+      </template>
+    </vxe-column>
+
+    <vxe-column title="操作">
+      <template #default="{ row, rowIndex }">
+        <el-button type="danger" @click="handleDel(row, rowIndex)"
+          >删除
+        </el-button>
+        <el-button type="success" @click="handleAdd">新增</el-button>
+      </template>
+    </vxe-column>
+  </vxe-table>
+</template>
+
+<style lang="scss"></style>

+ 3 - 2
src/views/hospitalization/zhu-yuan-yi-sheng/electronic-medical-record/emr-editor/plugins/ca/emr-ca.tsx

@@ -22,6 +22,7 @@ import { ElMessageBox } from "element-plus";
 import { parsingFragmentDataElements } from "@/utils/emr/emr-init-v2";
 import { Install } from "@/views/hospitalization/zhu-yuan-yi-sheng/electronic-medical-record/emr-editor/plugins";
 import { defineAsyncComponent } from "vue";
+import env from "@/utils/setting";
 
 const GenerateSignature = defineAsyncComponent(
   () =>
@@ -52,7 +53,7 @@ export const authorizedSignatureDataElement = () => {
     privacy: false,
     script: {
       content: null,
-      dynamicScript: "2154eae0167611ef8717efceee160e36",
+      dynamicScript: env.VITE_CA_SCRIPT_ID,
     },
     format: {
       dataType: null,
@@ -66,7 +67,7 @@ export const authorizedSignatureDataElement = () => {
       dictionary: null,
     },
     element: {
-      id: "ff105fe08f7a11ef865875b608250cef",
+      id: "",
       type: "element",
       name: "授权CA签名",
       code: {

+ 0 - 14
src/vite-env.d.ts

@@ -1,14 +0,0 @@
-/// <reference types="vite/client" />
-interface ImportMetaEnv {
-  readonly VITE_BASE_URL: string;
-  readonly VITE_SOCKET_URL: string;
-  readonly VITE_EMR_CONTROL_URL: string;
-
-  readonly VITE_DATA_BASE: string;
-  readonly VITE_MAGIC_API_IFRAME: string;
-  readonly VITE_HOSPITAL_NAME: string;
-  readonly VITE_SYSTEM_NAME: string;
-  readonly VITE_HOSPITAL_CODE: string;
-  readonly VITE_UPLOAD_TEMPLATE_THUMB: string;
-  readonly VITE_SOCKET_V2: string;
-}