xiaochan преди 10 месеца
родител
ревизия
4f4e1e3a12

+ 55 - 0
src/api/ca/ca-api.ts

@@ -21,6 +21,24 @@ export type CaResult = {
   bizSn: string;
 };
 
+export interface MoreEventSignData {
+  content: string;
+  /**
+   * 签署人身份类型。例如患者本人、亲属、朋友
+   * 、伴侣。进行 URLEncode 编码的数据,并且中
+   * 文长度不得大于 8
+   */
+  signType: string;
+  /**
+   * 签署人身份:
+   * 1:患者本人
+   * 2:亲属
+   * 3:朋友
+   * 4:伴侣
+   */
+  relation: number;
+}
+
 export function sendByCode(data: CaSendParams) {
   return requestV2<CaResult>({
     url: "/thyyca/sendByCode",
@@ -37,3 +55,40 @@ export function sendBatchByCode(data: CaSendParams) {
     data,
   });
 }
+
+export function sendMoreEventSign(data: {
+  data: MoreEventSignData[];
+  documentId: string;
+  code: string;
+  codeRs: string;
+}) {
+  return requestV2({
+    url: "/thyyca/sendMoreEventSign",
+    method: "POST",
+    data,
+  });
+}
+
+export function h5EventSign(data) {
+  return requestV2({
+    url: "/thyyca/h5EventSign",
+    method: "POST",
+    data,
+  });
+}
+
+export function hBoardSignV2(data) {
+  return requestV2({
+    url: "/thyyca/hBoardSignV2",
+    method: "POST",
+    data,
+  });
+}
+
+export function downloadSealV2(id) {
+  return requestV2({
+    url: "/thyyca/downloadSealV2",
+    method: "get",
+    params: { id },
+  });
+}

+ 7 - 2
src/components/cy/CyDialog/index.vue

@@ -75,12 +75,17 @@ function setRef(el, item) {
       "
     />
 
-    <template v-if="item.showCancel || item.showConfirm" #footer>
-      <el-button size="default" @click="handleCancel(item)">
+    <template #footer>
+      <el-button
+        size="default"
+        v-if="item.showCancel"
+        @click="handleCancel(item)"
+      >
         {{ item.cancelText || "取消" }}
       </el-button>
 
       <el-button
+        v-if="item.showConfirm"
         type="primary"
         size="default"
         color="hsl(240 5.9% 10%)"

+ 1 - 1
src/utils/emr/edit.ts

@@ -28,7 +28,7 @@ export type DataElementItem = {
     id: string;
     type: string;
     name: string;
-    code: { internal: string; dataElement: string };
+    code: { internal: string; dataElement: string; business: string };
     labels: null;
     attributes: [];
   };

+ 2 - 0
src/utils/emr/emr-init-v2.ts

@@ -4,6 +4,7 @@ import { UnwrapRef } from "vue";
 import { BizException, ExceptionEnum } from "../BizException";
 import { ElMessageBox } from "element-plus";
 import XEUtils from "xe-utils";
+import { getEmrToken } from "@/api/zhu-yuan-yi-sheng/emr-patient";
 
 type AppContext =
   | any
@@ -112,6 +113,7 @@ export function useEmrInit(
   options?: Options
 ): Promise<UseEmrInitReturn> {
   return new Promise((resolve, reject) => {
+    getEmrToken().then(XEUtils.noop);
     // @ts-ignore
     if (div["emr"]) {
       // @ts-ignore

+ 211 - 190
src/views/data-base/page-editor-help-v2/page-help-v2.ts

@@ -1,227 +1,248 @@
 import Mitt from "../../../utils/mitt";
-import {PageHeader, PageJsonObject, ReportForms} from "@/api/reports/report-query-center";
-import {Ref, ref} from 'vue'
+import {
+  PageHeader,
+  PageJsonObject,
+  ReportForms,
+} from "@/api/reports/report-query-center";
+import { Ref, ref } from "vue";
 import XEUtils from "xe-utils";
-import {reportQueryCenterApi, saveTheFile} from "@/api/base-data/report-center";
+import {
+  reportQueryCenterApi,
+  saveTheFile,
+} from "@/api/base-data/report-center";
 import * as ElementPlus from "element-plus";
-import {copyStrFunc} from "@/utils/public";
-import {xcMessage} from "@/utils/xiaochan-element-plus";
-import {CyJsonEditorDialog} from "@/components/cy/cy-monaco-editor/CyMonacoEditor";
+import { copyStrFunc } from "@/utils/public";
+import { xcMessage } from "@/utils/xiaochan-element-plus";
+import { CyJsonEditorDialog } from "@/components/cy/cy-monaco-editor/CyMonacoEditor";
 
 interface TableData {
-    data: any[],
-    columns: any[]
+  data: any[];
+  columns: any[];
 }
 
-
 export const ElAndXc = {
-    ...ElementPlus,
-    XcComboGridV2: defineAsyncComponent(() => import('../../../components/xiao-chan/combo-grid/XcComboGridV2.vue')),
-    CyComboGrid: defineAsyncComponent(() => import('@/components/cy/combo-grid/src/CyComboGrid.vue')),
-    SystemDeptSelect: defineAsyncComponent(() => import('@/components/system/dept-select/SystemDeptSelect.vue')),
-    SystemStaffSelect: defineAsyncComponent(() => import('@/components/system/staff-select/SystemStaffSelect.vue')),
-    SystemItemDrug: defineAsyncComponent(() => import('@/components/system/item-drug/SystemItemDrug.vue')),
-    CyDateRange: defineAsyncComponent(() => import('@/components/cy/date-range/CyDateRange.vue'))
-} as const
+  ...ElementPlus,
+  XcComboGridV2: defineAsyncComponent(
+    () => import("../../../components/xiao-chan/combo-grid/XcComboGridV2.vue")
+  ),
+  CyComboGrid: defineAsyncComponent(
+    () => import("@/components/cy/combo-grid/src/CyComboGrid.vue")
+  ),
+  SystemDeptSelect: defineAsyncComponent(
+    () => import("@/components/system/dept-select/SystemDeptSelect.vue")
+  ),
+  SystemStaffSelect: defineAsyncComponent(
+    () => import("@/components/system/staff-select/SystemStaffSelect.vue")
+  ),
+  SystemItemDrug: defineAsyncComponent(
+    () => import("@/components/system/item-drug/SystemItemDrug.vue")
+  ),
+  CyDateRange: defineAsyncComponent(
+    () => import("@/components/cy/date-range/CyDateRange.vue")
+  ),
+} as const;
 
 export const createFile = () => {
-    const data: PageJsonObject = {
-        header: [],
-        submitUrl: '',
-        params: {},
-        fromConfig: {
-            labelWidth: '80px',
-            inline: true
-        },
-        paramsDefaultValue: {}
-    }
-    return JSON.stringify(data)
-}
+  const data: PageJsonObject = {
+    header: [],
+    submitUrl: "",
+    params: {},
+    fromConfig: {
+      labelWidth: "80px",
+      inline: true,
+    },
+    paramsDefaultValue: {},
+  };
+  return JSON.stringify(data);
+};
 
 export interface PageHelpV2Mitt {
-    changePageJson: (data: ReportForms) => void;
-    componentReady: (data: any) => void
-    doTest: (id: string, queryParam: any) => void;
-    openMagic: () => void
-    doTestResult: (data: any, id: string, url: string) => void;
-    getCurrentPageData: () => any
+  changePageJson: (data: ReportForms) => void;
+  componentReady: (data: any) => void;
+  doTest: (id: string, queryParam: any) => void;
+  openMagic: () => void;
+  doTestResult: (data: any, id: string, url: string) => void;
+  getCurrentPageData: () => any;
 
-    queryTree: () => void
+  queryTree: () => void;
 
-    [key: string]: (...args: any[]) => any;
+  [key: string]: (...args: any[]) => any;
 }
 
-export type PageHelpTableName = 'mainTableRef' | 'dialogTableRef'
+export type PageHelpTableName = "mainTableRef" | "dialogTableRef";
 
 export interface ComponentBind {
-    renderName: 'select' | 'boolean' | 'input' | 'number' | 'json',
-    label: string,
-    selectData?: string[],
-    defaultValue: string | number | boolean,
-    on?: {
-        [key: string]: string
-    },
-    jsonType?: string
+  renderName: "select" | "boolean" | "input" | "number" | "json";
+  label: string;
+  selectData?: string[];
+  defaultValue: string | number | boolean;
+  on?: {
+    [key: string]: string;
+  };
+  jsonType?: string;
 }
 
 export const pageHelpV2Mitt = new Mitt<PageHelpV2Mitt>();
 
-export function capitalizeFirstLetter(str: string, prefix: string = '') {
-    return prefix + str.charAt(0).toUpperCase() + str.slice(1);
+export function capitalizeFirstLetter(str: string, prefix: string = "") {
+  return prefix + str.charAt(0).toUpperCase() + str.slice(1);
 }
 
-export const REPORT_FOLDER = "8283a0956dd9455cbf77c6246306ec98"
+export const REPORT_FOLDER = "8283a0956dd9455cbf77c6246306ec98";
 
 export function usePageStore(props: any) {
-    const currentClickIndex = ref(-1)
-    const pageData = ref<PageJsonObject>({
-        header: [],
-        params: {},
-        submitUrl: '',
-        fromConfig: {
-            inline: true,
-            labelWidth: '120px'
-        },
-        paramsDefaultValue: {}
-    })
-
-    const tableBind = ref({
-        data: [],
-        columns: [],
-        tableBind: {}
-    })
-
-    function clearOnAndFunc() {
-        XEUtils.arrayEach(pageData.value.header, (item: PageHeader) => {
-            if (item.on) {
-                for (let onKey in item.on) {
-                    const key = capitalizeFirstLetter(onKey, 'on')
-                    delete item.bind[key]
-                }
-            }
-            if (item.func) {
-                for (let funcKey in item.func) {
-                    delete item.bind[funcKey]
-                }
-            }
-        })
-    }
-
-    function handleSavaData() {
-        const clone: PageJsonObject = XEUtils.clone(pageData.value, true)
-
-        for (let i = 0; i < clone.header.length; i++) {
-            const item = clone.header[i]
-            if (!XEUtils.has(clone.paramsDefaultValue, item.key)) {
-                defaultValue()
-                xcMessage.error('请设置默认值。')
-                return
-            }
-
-        }
-        clone.params = {}
-        clone.header.forEach(item => {
-            if (item.name === 'ElSelectV2') {
-                item.bind.options = []
-            }
-            if (item.name === 'CyComboGrid') {
-                item.bind.data = []
-            }
-        })
-        const data = pageHelpV2Mitt.emit('getCurrentPageData')
-        data.pageJson = JSON.stringify(clone)
-        saveTheFile(data).then(r => {
-            pageHelpV2Mitt.emit('queryTree')
-        })
-    }
-
-    const bindData = ref()
-    let changeCurrentBind: (item: any) => Promise<any> | null = () => null
-
-    function getColumns(data: Ref<TableData>, tableName: PageHelpTableName = 'mainTableRef', copy = true) {
-        if (data.value.columns.length === 0 && data.value.data.length > 0) {
-            for (let key in data.value.data[0]) {
-                if (key === '_X_ROW_KEY') {
-                    continue;
-                }
-                data.value.columns.push({
-                    title: key,
-                    field: key,
-                    width: 120,
-                })
-            }
-        } else if (data.value.columns.length > 0) {
-            const table = {
-                mainTableRef: mainTableRef,
-                dialogTableRef: dialogTableRef
-            }
-
-            const temp = XEUtils.eachAndReturnList(data.value.columns, (item) => {
-                return {
-                    ...item,
-                    width: table[tableName].value.getColumnWidth(item.field)
-                }
-            })
-            copy && copyStrFunc(temp)
+  const currentClickIndex = ref(-1);
+  const pageData = ref<PageJsonObject>({
+    header: [],
+    params: {},
+    submitUrl: "",
+    fromConfig: {
+      inline: true,
+      labelWidth: "120px",
+    },
+    paramsDefaultValue: {},
+  });
+
+  const tableBind = ref({
+    data: [],
+    columns: [],
+    tableBind: {},
+  });
+
+  function clearOnAndFunc() {
+    XEUtils.arrayEach(pageData.value.header, (item: PageHeader) => {
+      if (item.on) {
+        for (let onKey in item.on) {
+          const key = capitalizeFirstLetter(onKey, "on");
+          delete item.bind[key];
         }
-    }
-
-    const mainTableRef = ref()
-    const dialogTableRef = ref()
-
-    const compData = ref([])
-
-    async function addComponentRefresh() {
-        compData.value = await reportQueryCenterApi('/reportCenterOption/components/addComponents')
-    }
-
-    const mutation = {
-        setPageData: (data: PageJsonObject, currentIndex = -1) => {
+      }
+      if (item.func) {
+        for (let funcKey in item.func) {
+          delete item.bind[funcKey];
         }
+      }
+    });
+  }
+
+  function handleSavaData() {
+    const clone: PageJsonObject = XEUtils.clone(pageData.value, true);
+
+    for (let i = 0; i < clone.header.length; i++) {
+      const item = clone.header[i];
+      if (!XEUtils.has(clone.paramsDefaultValue, item.key)) {
+        defaultValue();
+        xcMessage.error("请设置默认值。");
+        return;
+      }
     }
-
-
-    function defaultValue() {
-        let temp: {};
-        const headerParams = {}
-        pageData.value.header.forEach(item => {
-            // @ts-ignore
-            headerParams[item.key] = ""
-        })
-        if (XEUtils.isEmpty(pageData.value.paramsDefaultValue)) {
-            temp = headerParams
-        } else {
-            temp = {...headerParams, ...pageData.value.paramsDefaultValue};
+    clone.params = {};
+    clone.header.forEach(item => {
+      if (item.name === "ElSelectV2") {
+        item.bind.options = [];
+      }
+      if (item.name === "CyComboGrid") {
+        item.bind.data = [];
+      }
+    });
+    const data = pageHelpV2Mitt.emit("getCurrentPageData");
+    data.pageJson = JSON.stringify(clone);
+    saveTheFile(data).then(r => {
+      pageHelpV2Mitt.emit("queryTree");
+    });
+  }
+
+  const bindData = ref();
+  let changeCurrentBind: (item: any) => Promise<any> | null = () => null;
+
+  function getColumns(
+    data: Ref<TableData>,
+    tableName: PageHelpTableName = "mainTableRef",
+    copy = true
+  ) {
+    if (data.value.columns.length === 0 && data.value.data.length > 0) {
+      for (let key in data.value.data[0]) {
+        if (key === "_X_ROW_KEY") {
+          continue;
         }
-        // @ts-ignore
-        CyJsonEditorDialog(temp, {bodyWidth: '60%'}).then(res => {
-            pageData.value.paramsDefaultValue = res.json
-        })
+        data.value.columns.push({
+          title: key,
+          field: key,
+          width: 120,
+        });
+      }
+    } else if (data.value.columns.length > 0) {
+      const table = {
+        mainTableRef: mainTableRef,
+        dialogTableRef: dialogTableRef,
+      };
+
+      const temp = XEUtils.eachAndReturnList(data.value.columns, item => {
+        return {
+          ...item,
+          width: table[tableName].value.getColumnWidth(item.field),
+        };
+      });
+      copy && copyStrFunc(temp);
     }
-
-    return {
-        currentClickIndex,
-        pageData,
-        clearOnAndFunc,
-        handleSavaData,
-        tableBind,
-
-        bindData,
-        changeCurrentBind,
-        mainTableRef,
-        props,
-        getColumns,
-        dialogTableRef,
-        compData,
-        addComponentRefresh,
-        defaultValue,
-        mutation
+  }
+
+  const mainTableRef = ref();
+  const dialogTableRef = ref();
+
+  const compData = ref([]);
+
+  async function addComponentRefresh() {
+    compData.value = await reportQueryCenterApi(
+      "/reportCenterOption/components/addComponents"
+    );
+  }
+
+  const mutation = {
+    setPageData: (data: PageJsonObject, currentIndex = -1) => {},
+  };
+
+  function defaultValue() {
+    let temp: {};
+    const headerParams = {};
+    pageData.value.header.forEach(item => {
+      // @ts-ignore
+      headerParams[item.key] = "";
+    });
+    if (XEUtils.isEmpty(pageData.value.paramsDefaultValue)) {
+      temp = headerParams;
+    } else {
+      temp = { ...headerParams, ...pageData.value.paramsDefaultValue };
     }
+    // @ts-ignore
+    CyJsonEditorDialog(temp, { bodyWidth: "60%" }).then(res => {
+      pageData.value.paramsDefaultValue = res.json;
+    });
+  }
+
+  return {
+    currentClickIndex,
+    pageData,
+    clearOnAndFunc,
+    handleSavaData,
+    tableBind,
+
+    bindData,
+    changeCurrentBind,
+    mainTableRef,
+    props,
+    getColumns,
+    dialogTableRef,
+    compData,
+    addComponentRefresh,
+    defaultValue,
+    mutation,
+  };
 }
 
 class HelperStore {
-    Return = usePageStore({})
+  Return = usePageStore({});
 }
 
-type PageStore = HelperStore['Return']
-export type {PageStore}
+type PageStore = HelperStore["Return"];
+export type { PageStore };

+ 43 - 21
src/views/hospitalization/zhu-yuan-yi-sheng/electronic-medical-record/emr-editor/EmrMain.vue

@@ -163,7 +163,6 @@ import { getServerDateApi, getUuid } from "@/api/public-api";
 import {
   audit,
   deletePatientEmrByDocumentId,
-  getEmrToken,
   hotSearchSorting,
   insertEmrData,
   submitMedicalRecord,
@@ -199,7 +198,7 @@ import { infectiousDiseasesAreRequired } from "@/api/zhu-yuan-yi-sheng/infectiou
 import setDialogToJs from "@/components/js-dialog-comp/useDialogToJs";
 import {
   emrRootContextKey,
-  PageStore,
+  EmrStore,
   useEmrStore,
 } from "@/views/hospitalization/zhu-yuan-yi-sheng/electronic-medical-record/emr-func/useEmrStore";
 import useEmrScript from "@/views/hospitalization/zhu-yuan-yi-sheng/electronic-medical-record/emr-editor/useEmrScript";
@@ -209,7 +208,7 @@ import useCompRef from "@/utils/useCompRef";
 import { useHistoricalData } from "@/views/hospitalization/zhu-yuan-yi-sheng/electronic-medical-record/emr-editor/components/emr-function/useEmrFunction";
 import PatientInfoView from "@/components/zhu-yuan-yi-sheng/public/PatientInfoView.vue";
 import { useSystemStore } from "@/pinia/system-store";
-import { emrCa } from "@/views/hospitalization/zhu-yuan-yi-sheng/electronic-medical-record/emr-func/emr-ca";
+import { emrCa } from "@/views/hospitalization/zhu-yuan-yi-sheng/electronic-medical-record/emr-func/ca/emr-ca";
 import {
   setEmrComponentClick,
   useComponentClick,
@@ -289,7 +288,7 @@ let runtime: Runtime | null = null;
 let editMain: UseEmrInitReturn | null = null;
 let extractData = {};
 
-const emrStore: PageStore = useEmrStore(
+const emrStore: EmrStore = useEmrStore(
   patientInfo.value.inpatientNo + "_" + patientInfo.value.admissTimes
 );
 
@@ -313,7 +312,7 @@ const { magicScript, triggerScript } = useEmrScript({
 });
 
 const emrSocketRef = useCompRef(EmrWebSocket);
-const useEmrCa = emrCa();
+const useEmrCa = emrCa(emrStore);
 setEmrComponentClick(useEmrCa.componentClick);
 
 const categoryCode = ref("");
@@ -419,7 +418,7 @@ const emrEvent = {
         editor?.setValues(patientData.value, true, true);
       }
     }
-    useEmrCa.testFunc(editor);
+    useEmrCa.loaded(editor);
   },
   contentchange: (e, op) => {
     triggerScript("contentchange", e, op);
@@ -481,11 +480,16 @@ const emrEvent = {
     }
     return copy;
   },
-  componentClick: (evt, comp) =>
-    useComponentClick(evt, comp, {
-      patientInfo: patientInfo.value,
-      emrName: templateName.value,
-    }),
+  componentClick: (evt, view) => {
+    const eleInfo = view.getAttribute("element");
+    if (eleInfo) {
+      !isDev && console.log(eleInfo);
+      useComponentClick(evt, view, eleInfo, {
+        patientInfo: patientInfo.value,
+        emrName: templateName.value,
+      });
+    }
+  },
   beforeRevisionAccept: (evt, data) => {
     try {
       return beforeRevisionAccept(evt, data);
@@ -1072,6 +1076,11 @@ function generalMedicalRecords() {
 
 // 设置编辑器的模式
 const setEditorModeFun = () => {
+  if (XEUtils.has(editor.documentData.properties, "thyysign")) {
+    setEditorModel("readonly");
+    return;
+  }
+
   // 判断是不是编辑模式
   if (!emrConfig.value.editor) {
     setEditorModel("readonly");
@@ -1493,7 +1502,12 @@ const restoreDefaultSettings = () => {
   } catch {}
 };
 
+/**
+ * 加载电子病历
+ * @param param
+ */
 const loadDocument = (param: EmrParam): Promise<void> => {
+  console.log(param);
   return new Promise(async (resolve, reject) => {
     const { loadDocument: load } = editMain;
     if (!showIframeIsList(IframeTabs.正在编辑, IframeTabs.同时打开)) {
@@ -1570,6 +1584,9 @@ const loadDocument = (param: EmrParam): Promise<void> => {
   });
 };
 
+/**
+ * 电子病历mitt初始化
+ */
 const emrMittInit = () => {
   // @ts-ignore
   emrMitt.on("editor", () => {
@@ -1655,7 +1672,6 @@ const initEdit = () => {
       app: "http://172.16.32.160:9205/thyy/api/dataEmr/comp",
       his: import.meta.env.VITE_BASE_URL,
     },
-    enableSignData: true,
     input: {
       user: userInfo.code,
       name: userInfo.name,
@@ -1687,13 +1703,21 @@ const initEdit = () => {
       await sleep(500);
       // @ts-ignore
       loadDocument({
-        categoryCode: "ruyuanjiluzhuanyong",
-        categoryId: "e6723e80ed6511ed85a9691047891ea7",
-        patientId: "019699_51",
-        templateName: "入院记录",
-        createId: null,
-        parent: "4959e2c054fd11edb28ac955a5f5cad1",
+        categoryCode: "c8aff620580111eda93f1fd7ab32baa6",
+        patientId: "0432510_1",
+        templateName: "授权委托书",
+        createId: "02896",
+        documentId: "924629067488102400",
       });
+      // loadDocument({
+      //   categoryCode: "c8aff620580111eda93f1fd7ab32baa6",
+      //   categoryId: "c08278b05e6411ed86a443e5c87b4eb5",
+      //   patientId: "0432510_1",
+      //   templateName: "授权委托书",
+      //   createId: null,
+      //   parent: "73d696605e4911edbb0eab416e27b81a",
+      //   documentId: "924629067488102400"
+      // });
       // emrStore.mutation.installPlugins(res);
     }
   });
@@ -1734,7 +1758,6 @@ onMounted(async () => {
   doctorLevelFunc();
   await queryingBasicPatientInformation();
   await nextTick();
-  await getEmrToken();
   initEdit();
   window.addEventListener("beforeunload", monitorPageRefresh, {
     capture: true,
@@ -1875,8 +1898,7 @@ const 循环病程返回数据元 = callback => {
  */
 async function getOutline() {
   try {
-    await Promise.resolve();
-    emrStore.mutation.setOutline(editor!.getOutline());
+    emrStore.mutation.setOutline();
   } catch (e) {}
 }
 

+ 60 - 57
src/views/hospitalization/zhu-yuan-yi-sheng/electronic-medical-record/emr-editor/components/emr-right/EmrOutline.vue

@@ -1,91 +1,96 @@
 <script setup lang="ts">
-import {ref} from "vue";
-import {Outline} from "@/utils/emr/edit";
-import {emrMitt} from "@/views/hospitalization/zhu-yuan-yi-sheng/electronic-medical-record/emr-editor/emr-init";
-import {useCompRef} from "@/utils/useCompRef";
-import {ElTree} from "element-plus";
-import {isContain} from "@/utils/public";
-import {Folder, ScaleToOriginal} from "@element-plus/icons-vue";
+import { ref } from "vue";
+import { Outline } from "@/utils/emr/edit";
+import { emrMitt } from "@/views/hospitalization/zhu-yuan-yi-sheng/electronic-medical-record/emr-editor/emr-init";
+import { useCompRef } from "@/utils/useCompRef";
+import { ElTree } from "element-plus";
+import { isContain } from "@/utils/public";
+import { Folder, ScaleToOriginal } from "@element-plus/icons-vue";
 import CyFlex from "@/components/cy/flex/src/CyFlex.vue";
-import {
-  emrRootContextKey
-} from "@/views/hospitalization/zhu-yuan-yi-sheng/electronic-medical-record/emr-func/useEmrStore";
+import { emrRootContextKey } from "@/views/hospitalization/zhu-yuan-yi-sheng/electronic-medical-record/emr-func/useEmrStore";
 
-const inputVal = ref('')
-const root = inject(emrRootContextKey)
-
-const defaultProps = {
-  children: 'children',
-  label: 'typeName',
-  value: 'id',
-}
+const inputVal = ref("");
+const root = inject(emrRootContextKey);
 
 const nodeClick = (val: Outline) => {
   if (val.parent) {
-    emrMitt.emit('jumpDataElementById', val.id)
+    emrMitt.emit("jumpDataElementById", val.id);
   }
-}
+};
 
-const elTreeRef = useCompRef(ElTree)
+const elTreeRef = useCompRef(ElTree);
 
-const handelInput = (val) => {
-  elTreeRef.value!.filter(val)
-}
+const handelInput = val => {
+  elTreeRef.value!.filter(val);
+};
 
 const handelFilter = (value, data: Outline) => {
-  if (!value) return true
+  if (!value) return true;
   if (data.business) {
-    return data.business.includes(value)
+    return data.business.includes(value);
   }
-  return data.text.includes(value)
-}
+  return data.text.includes(value);
+};
 
-const currentId = ref('')
+const currentId = ref("");
 
 function changeElementById(id: string) {
-  currentId.value = id
-  const element = document.getElementById(id)
+  currentId.value = id;
+  const element = document.getElementById(id);
   if (!isContain(element)) {
     element.scrollIntoView({
-      block: 'center',
-      inline: 'nearest',
-      behavior: 'smooth'
-    })
+      block: "center",
+      inline: "nearest",
+      behavior: "smooth",
+    });
   }
 }
 
-onMounted(() => {
-  emrMitt.on('changeElementById', changeElementById)
-})
+function refreshClick() {
+  root.store.mutation.setOutline();
+}
 
+onMounted(() => {
+  emrMitt.on("changeElementById", changeElementById);
+});
 </script>
 
 <template>
   <CyFlex>
     <template #header>
-      <el-input v-model="inputVal"
-                placeholder="节点过滤"
-                @input="handelInput"
-                clearable/>
+      <el-input
+        v-model="inputVal"
+        placeholder="节点过滤"
+        @input="handelInput"
+        clearable
+      >
+        <template #append>
+          <el-button icon="RefreshRight" @click="refreshClick" />
+        </template>
+      </el-input>
     </template>
     <template #content>
       <el-tree
-          class="down-tree"
-          node-key="id"
-          :style="{'--el-tree-text-color': '#000', '--el-color-primary-light-9' : '#409EFF' }"
-          :current-node-key="currentId"
-          ref="elTreeRef"
-          default-expand-all
-          highlight-current
-          :filter-node-method="handelFilter"
-          :data="root!.store.outline.value"
-          @nodeClick="nodeClick"
-          :expand-on-click-node="false">
+        class="down-tree"
+        node-key="id"
+        :style="{
+          '--el-tree-text-color': '#000',
+          '--el-color-primary-light-9': '#409EFF',
+        }"
+        :current-node-key="currentId"
+        ref="elTreeRef"
+        default-expand-all
+        highlight-current
+        :filter-node-method="handelFilter"
+        :data="root!.store.outline.value"
+        @nodeClick="nodeClick"
+        :expand-on-click-node="false"
+      >
         <template #default="{ node, data }">
           <div :id="data.id">
             <el-icon>
-              <ScaleToOriginal v-if="data.parent"/>
-              <Folder v-else/>
+              <ScaleToOriginal v-if="data.parent" />
+              <Folder v-else />
             </el-icon>
             {{ data.business || data.text }}
           </div>
@@ -94,5 +99,3 @@ onMounted(() => {
     </template>
   </CyFlex>
 </template>
-
-

+ 8 - 1
src/views/hospitalization/zhu-yuan-yi-sheng/electronic-medical-record/emr-editor/components/emr-right/EmrRightComp.vue

@@ -3,7 +3,7 @@
     v-model="store.store.right"
     tab-position="right"
     height="100%"
-    width="220"
+    :width="store.store.rightWidth"
     foldable
   >
     <CyTabPane label="片段" name="fragment">
@@ -33,6 +33,13 @@
     <CyTabPane label="辅助工具" name="auxiliaryTools">
       <slot name="auxiliaryTools" />
     </CyTabPane>
+    <CyTabPane
+      v-for="item in store.store.rightComp"
+      :label="item.name"
+      :name="item.name"
+    >
+      <Component :is="item.comp" :ref="el => (item.refValue = el)" />
+    </CyTabPane>
   </CyTabs>
 </template>
 

+ 1 - 0
src/views/hospitalization/zhu-yuan-yi-sheng/electronic-medical-record/emr-editor/emr-init.ts

@@ -614,6 +614,7 @@ export enum EmrRightTabs {
   fragment = "fragment",
   outline = "outline",
   kindReminder = "kindReminder",
+  ca = "电子签名",
 }
 
 export interface AuditV2 {

+ 124 - 0
src/views/hospitalization/zhu-yuan-yi-sheng/electronic-medical-record/emr-func/ca/EmrCAComp.vue

@@ -0,0 +1,124 @@
+<script setup lang="tsx">
+import { emrRootContextKey } from "@/views/hospitalization/zhu-yuan-yi-sheng/electronic-medical-record/emr-func/useEmrStore";
+import { getInternalByCode } from "@/views/hospitalization/zhu-yuan-yi-sheng/electronic-medical-record/emr-func/ca/emr-ca";
+import XEUtils from "xe-utils";
+import { BizException, ExceptionEnum } from "@/utils/BizException";
+import { hBoardSignV2 } from "@/api/ca/ca-api";
+import { useDialog } from "@/components/cy/CyDialog/index";
+import EmrCaSign from "@/views/hospitalization/zhu-yuan-yi-sheng/electronic-medical-record/emr-func/ca/EmrCaSign.vue";
+
+const { store } = inject(emrRootContextKey);
+
+const selectList = ref<SignComp[]>([]);
+
+type SignComp = {
+  value: number;
+  name: string;
+  id: string;
+  complete: boolean;
+};
+
+function change() {
+  const editor = store.store.editor;
+  const data = getInternalByCode(editor, "患者CA签名", false);
+  if (!data) return;
+  selectList.value = data.map((item, index) => {
+    const value = XEUtils.toInteger(item.element.code.dataElement);
+    const { view } = store.editFun.getViewById(item.id);
+    const name = "CA签名" + (index + 1);
+
+    const complete = view.getAttribute("thyySign.complete") ?? false;
+
+    view.setValue([
+      {
+        name,
+      },
+    ]);
+
+    return {
+      value,
+      name,
+      id: item.id,
+      complete,
+    };
+  });
+}
+
+function handleClick(id) {
+  store.editFun.jumpById(id);
+}
+
+const 发送签名 = async (value: SignComp) => {
+  const editor = store.store.editor;
+  const documentId = editor.documentData._id;
+  if (!documentId) {
+    BizException(ExceptionEnum.MESSAGE_ERROR, "请先保存病历。");
+  }
+  editor.documentData.properties.thyysign = "签名中";
+  editor.setEditorMode("readonly");
+  const rst = await hBoardSignV2({
+    documentId,
+    content: value.name,
+  });
+  const { view } = store.editFun.getViewById(value.id);
+  view.setAttribute("thyySign", { rst });
+
+  useDialog(EmrCaSign, {
+    dialogProps: {
+      title: "签名",
+      showClose: false,
+      fullscreen: true,
+    },
+    params: {
+      url: rst.result,
+      id: rst.id,
+    },
+    showCancel: false,
+  }).then(res => {
+    view.sign([
+      {
+        name: "签名",
+        signature: `data:image/png;base64,${res.hand_sign}`,
+        thyySign: true,
+      },
+    ]);
+
+    view.setAttribute("thyySign", { ...rst, complete: true });
+    value.complete = true;
+  });
+};
+
+const completeSignature = () => {};
+
+defineExpose({
+  change,
+});
+</script>
+
+<template>
+  <div class="layout_container">
+    <header>
+      <span style="color: red"
+        >注意:一旦发送患者电子签名后,患者签字了,那么这份病历就无法修改以及删除</span
+      >
+      <el-divider />
+      <el-button @click="change">刷新</el-button>
+    </header>
+    <div class="layout_main">
+      <div v-for="item in selectList" style="margin: 5px 0">
+        <el-button @click="handleClick(item.id)">{{ item.name }}</el-button>
+        <el-button @click="发送签名(item)" v-if="!item.complete"
+          >发送
+        </el-button>
+      </div>
+      <el-divider />
+      <el-button @click="completeSignature">完成签名</el-button>
+    </div>
+  </div>
+</template>
+
+<style lang="scss">
+.ca-select {
+  margin: 5px 0;
+}
+</style>

+ 20 - 0
src/views/hospitalization/zhu-yuan-yi-sheng/electronic-medical-record/emr-func/ca/EmrCaSign.vue

@@ -0,0 +1,20 @@
+<script setup lang="ts">
+import { downloadSealV2 } from "@/api/ca/ca-api";
+
+const props = defineProps<{
+  url: string;
+  id: string;
+}>();
+
+defineExpose({
+  async confirm() {
+    return await downloadSealV2(props.id);
+  },
+});
+</script>
+
+<template>
+  <iframe :src="url" class="layout_full_iframe" />
+</template>
+
+<style lang="scss"></style>

+ 2049 - 0
src/views/hospitalization/zhu-yuan-yi-sheng/electronic-medical-record/emr-func/ca/emr-ca.tsx

@@ -0,0 +1,2049 @@
+import { DataElementItem, EditType } from "@/utils/emr/edit";
+import { CaSendParams, sendBatchByCode, sendByCode } from "@/api/ca/ca-api";
+import { isDev } from "@/utils/public";
+import { useUserStore } from "@/pinia/user-store";
+import XEUtils from "xe-utils";
+import { useDialog } from "@/components/cy/CyDialog/index";
+import { EmrStore } from "@/views/hospitalization/zhu-yuan-yi-sheng/electronic-medical-record/emr-func/useEmrStore";
+import { EmrRightTabs } from "@/views/hospitalization/zhu-yuan-yi-sheng/electronic-medical-record/emr-editor/emr-init";
+import { stringNotBlank } from "@/utils/blank-utils";
+
+const GenerateSignature = defineAsyncComponent(
+  () =>
+    import(
+      "@/views/hospitalization/zhu-yuan-yi-sheng/electronic-medical-record/emr-editor/components/GenerateSignature.vue"
+    )
+);
+
+const testInput = {
+  required: false,
+  readonly: false,
+  deletable: true,
+  privacy: false,
+  script: {
+    content: null,
+    dynamicScript: "2154eae0167611ef8717efceee160e36",
+  },
+  format: {
+    dataType: null,
+    showType: null,
+    minLength: null,
+    maxLength: null,
+    minRows: null,
+    maxRows: null,
+    scale: null,
+    enums: null,
+    dictionary: null,
+  },
+  element: {
+    id: "552c4a60167711ef8717efceee160e36",
+    type: "element",
+    name: "医生签名",
+    code: {
+      business: "自动签名",
+      internal: "编辑者CA签名",
+      dataElement: "",
+    },
+  },
+  tips: "医生签名",
+  borderStyle: "none",
+  style: {
+    id: "e6aRxaE7OLt",
+  },
+  picker: {
+    type: null,
+    propertiesConfig: {
+      signCount: {
+        name: "签名数量",
+        code: "signCount",
+        category: "extend",
+        categoryName: "扩展",
+        value: 1,
+        editor: {
+          type: "numberfield",
+          minvalue: 1,
+        },
+      },
+      maxHeight: {
+        name: "最大高度",
+        code: "maxHeight",
+        category: "extend",
+        categoryName: "扩展",
+        editor: {
+          type: "numberfield",
+        },
+      },
+      valign: {
+        name: "对齐方式",
+        code: "valign",
+        category: "extend",
+        categoryName: "扩展",
+        editor: {
+          type: "select",
+          valueField: "code",
+          displayField: "name",
+          store: {
+            type: "store",
+            fields: ["code", "name"],
+            data: [
+              {
+                code: "top",
+                name: "上对齐",
+              },
+              {
+                code: "middle",
+                name: "中对齐",
+              },
+              {
+                code: "bottom",
+                name: "下对齐",
+              },
+            ],
+          },
+        },
+      },
+    },
+  },
+  editable: false,
+  contentWrap: true,
+  signCount: 1,
+  type: "smarttext",
+};
+
+export const selectData = [
+  {
+    code: 1,
+    name: "患者本人",
+  },
+  {
+    code: 2,
+    name: "亲属",
+  },
+  {
+    code: 3,
+    name: "朋友",
+  },
+  {
+    code: 4,
+    name: "伴侣",
+  },
+];
+
+function getTestContent(editor: EditType, internal = "", dataElement = "") {
+  editor.setCursor("DOCUMENT_START");
+  const tmp = XEUtils.cloneDeep(testInput);
+  tmp.element.code.internal = internal;
+  tmp.element.code.dataElement = dataElement;
+  editor.execute("insertContents", {
+    value: [tmp],
+  });
+}
+
+function testFunc(editor: EditType) {
+  if (!isDev) return;
+  getTestContent(editor, "患者CA签名", "1");
+  getTestContent(editor, "患者CA签名", "2");
+  getTestContent(editor, "患者CA签名", "3");
+  getTestContent(editor, "患者CA签名", "4");
+  getTestContent(editor, "编辑者CA签名");
+}
+
+type saveType =
+  | {
+      // 病历的名称
+      emrName: string;
+      // 患者名称
+      patientName: string;
+      // 患者年龄
+      age: string;
+    }
+  | any;
+
+export function getInternalByCode(
+  editor: EditType,
+  name: string,
+  removeNotNull = true
+): DataElementItem[] {
+  const signatureControl = editor.getDataElements("internal", false, true);
+  let data = signatureControl[name] as DataElementItem[];
+  if (!data) {
+    return null;
+  }
+  if (!XEUtils.isArray(data)) {
+    data = [data];
+  }
+  if (removeNotNull) {
+    // 移出不为空的数据
+    XEUtils.remove(data, item => {
+      return stringNotBlank(item.value);
+    });
+  }
+  return data;
+}
+
+function getViewById(editor: EditType, id: string) {
+  const find = editor.view.container.find(`#${id}`);
+  if (XEUtils.isEmpty(find)) {
+    return;
+  }
+  return find[0];
+}
+
+function dialog() {
+  let tmpClose = (_value, _data) => {};
+
+  useDialog(<div>正在生成您的签名请稍后。。。</div>, {
+    dialogProps: {
+      title: "生成签名中",
+    },
+    manuallyClose: cb => {
+      tmpClose = cb;
+    },
+  }).then(XEUtils.noop);
+
+  return {
+    closed() {
+      tmpClose("confirm", null);
+    },
+  };
+}
+
+const testChange = XEUtils.once((editor: EditType) => {
+  const data = {
+    valid: 1,
+    categoryId: "c08278b05e6411ed86a443e5c87b4eb5",
+    properties: {
+      version: "v1.0.33",
+      editorVersion: "v5.1.317",
+      creator: "",
+      createTime: "",
+      reviewer: "root",
+      reviewTime: "2024-10-02 15:26:57",
+      modifier: "",
+      modifyTime: "",
+      categoryCode: "c8aff620580111eda93f1fd7ab32baa6",
+    },
+    styles: {
+      text: {
+        jw05EoQz0km: {
+          fontFamily: "SimSun",
+          fontSize: "22pt",
+          fontWeight: "bold",
+        },
+        e6o7aJHlExV1: {
+          fontFamily: "SimSun",
+          fontSize: "18pt",
+          fontWeight: "bold",
+        },
+        VPvz6PfU4: {
+          fontFamily: "SimSun",
+          fontSize: "10.5pt",
+        },
+        HiMU5YM3cM: {
+          fontFamily: "SimSun",
+          fontSize: "10.5pt",
+          borderBottomStyle: "none",
+          borderBottomWidth: "1px",
+        },
+        wRN6Tib_nc: {
+          fontFamily: "SimSun",
+          fontSize: "10.5pt",
+          textDecorationLine: "underline",
+          textDecorationStyle: "initial",
+          textDecorationColor: "initial",
+        },
+        LIR4sDw0bR: {
+          fontFamily: "SimSun",
+          fontSize: "10.5pt",
+          borderBottomStyle: "none",
+        },
+        EPfXKAvUZx3: {
+          fontFamily: "SimSun",
+          fontSize: "10.5pt",
+          borderBottomStyle: "none",
+          borderBottomWidth: "1px",
+          fontWeight: "normal",
+        },
+        RjNfj7mob3Z: {
+          fontFamily: "SimSun",
+          fontSize: "10.5pt",
+          borderBottomStyle: "none",
+          fontWeight: "normal",
+        },
+        QHd94VJo6SF: {
+          fontFamily: "SimSun",
+          fontSize: "10.5pt",
+          fontWeight: "normal",
+        },
+        e8UPwIgBmpi: {
+          fontFamily: "SimSun",
+          fontSize: "10.5pt",
+          borderBottomWidth: "1px",
+          fontWeight: "normal",
+        },
+        zJpp4slEdJ: {
+          fontFamily: "SimSun",
+          fontSize: "10.5pt",
+          borderBottomWidth: "1px",
+        },
+      },
+      table: {},
+      paragraph: {
+        A0jTsp1FaNj: {
+          textAlign: "center",
+        },
+        CeXtzd7C1F: {
+          textAlign: "right",
+        },
+        PaRNStosO: {
+          lineHeight: {
+            type: "多倍行距",
+            value: 1.25,
+          },
+          paragraphSpacing: {
+            before: 0,
+            after: 0,
+          },
+          paragraphIndent: {
+            left: 0,
+            right: 0,
+          },
+          specialIndent: {
+            type: "无",
+            value: 0,
+          },
+        },
+      },
+    },
+    layout: {
+      margins: {
+        left: 25,
+        right: 15,
+        top: 10,
+        bottom: 20,
+      },
+      paper: {
+        type: "A4",
+        orientation: "portrait",
+        width: "210mm",
+        height: "297mm",
+        watermark: {
+          content: "",
+          type: "",
+        },
+      },
+    },
+    document: {
+      header: {
+        id: "tAYhToaX9a",
+        showSplitLine: true,
+        type: "$root",
+        children: [
+          {
+            defaultStyleId: "global_style_text",
+            style: {
+              id: "A0jTsp1FaNj",
+            },
+            id: "s0nhfebMK",
+            type: "paragraph",
+            children: [
+              {
+                style: {
+                  id: "jw05EoQz0km",
+                },
+                id: "_gJ36kq-TQ",
+                data: "",
+                type: "text",
+              },
+            ],
+          },
+          {
+            defaultStyleId: "global_style_text",
+            style: {
+              id: "A0jTsp1FaNj",
+            },
+            id: "VDZ5bdmmb",
+            type: "paragraph",
+            children: [
+              {
+                style: {
+                  id: "jw05EoQz0km",
+                },
+                id: "e2aiDxgM66r",
+                data: "泰  和  医  院",
+                type: "text",
+              },
+            ],
+          },
+          {
+            defaultStyleId: "global_style_text",
+            style: {
+              id: "A0jTsp1FaNj",
+            },
+            id: "Kmlf3H_yIm",
+            type: "paragraph",
+            children: [
+              {
+                style: {
+                  id: "e6o7aJHlExV1",
+                },
+                id: "uKXUM4O1X",
+                data: "授权委托书",
+                type: "text",
+              },
+            ],
+          },
+          {
+            defaultStyleId: "global_style_text",
+            style: {
+              id: "CeXtzd7C1F",
+            },
+            id: "e-ZWTf9v9n",
+            type: "paragraph",
+            children: [
+              {
+                required: false,
+                readonly: false,
+                deletable: true,
+                privacy: false,
+                label: "住院号:",
+                format: {
+                  minLength: 6,
+                  maxLength: 8,
+                  scale: 0,
+                  enums: {},
+                },
+                element: {
+                  id: "35bedfb0575d11ed891bd723b0984537",
+                  type: "element",
+                  name: "住院号",
+                  code: {
+                    business: "住院号",
+                    internal: "",
+                    dataElement: "",
+                  },
+                  labels: [""],
+                },
+                tips: "住院号",
+                borderStyle: "none",
+                style: {
+                  id: "EPfXKAvUZx3",
+                },
+                editable: true,
+                contentStyle: "display:inline",
+                id: "b73jAlu3WH",
+                code: "b73jAlu3WH",
+                contentWrap: true,
+                value: "0432510",
+                type: "smarttext",
+                children: [
+                  {
+                    style: {
+                      id: "e8UPwIgBmpi",
+                    },
+                    id: "e0Fkf2DW9sk",
+                    data: "0432510",
+                    type: "text",
+                  },
+                ],
+              },
+            ],
+          },
+          {
+            defaultStyleId: "global_style_text",
+            style: {
+              id: "A0jTsp1FaNj",
+            },
+            id: "e2DwY7B8zmS",
+            type: "paragraph",
+            children: [
+              {
+                required: false,
+                readonly: false,
+                deletable: true,
+                privacy: false,
+                label: "姓名:",
+                element: {
+                  id: "499618900d5811ed9df371afd668b4b0",
+                  type: "element",
+                  name: "患者姓名",
+                  code: {
+                    business: "患者姓名",
+                    internal: "",
+                    dataElement: "",
+                  },
+                  labels: [""],
+                },
+                tips: "姓名",
+                borderStyle: "none",
+                style: {
+                  id: "RjNfj7mob3Z",
+                },
+                editable: true,
+                contentStyle: "display:inline",
+                id: "Y_-CVCU1jo",
+                code: "Y_-CVCU1jo",
+                contentWrap: true,
+                value: "舒秀玲",
+                type: "smarttext",
+                children: [
+                  {
+                    style: {
+                      id: "QHd94VJo6SF",
+                    },
+                    id: "vohcDU-jdC",
+                    data: "舒秀玲",
+                    type: "text",
+                  },
+                ],
+              },
+              {
+                style: {
+                  id: "VPvz6PfU4",
+                },
+                id: "EB4O62nq7t",
+                data: "  ",
+                type: "text",
+              },
+              {
+                required: false,
+                readonly: false,
+                deletable: true,
+                privacy: false,
+                label: "性别:",
+                element: {
+                  id: "902e4580575d11ed891bd723b0984537",
+                  type: "element",
+                  name: "患者性别",
+                  code: {
+                    business: "性别名称",
+                    internal: "",
+                    dataElement: "",
+                  },
+                  labels: [""],
+                },
+                tips: "性别",
+                borderStyle: "none",
+                style: {
+                  id: "RjNfj7mob3Z",
+                },
+                editable: true,
+                contentStyle: "display:inline",
+                id: "e24JSImvn8X",
+                code: "e24JSImvn8X",
+                contentWrap: true,
+                value: "女",
+                type: "smarttext",
+                children: [
+                  {
+                    style: {
+                      id: "QHd94VJo6SF",
+                    },
+                    id: "En5zDyVgoI",
+                    data: "女",
+                    type: "text",
+                  },
+                ],
+              },
+              {
+                style: {
+                  id: "QHd94VJo6SF",
+                },
+                id: "ROZVzGAhI4",
+                data: "  ",
+                type: "text",
+              },
+              {
+                required: false,
+                readonly: false,
+                deletable: true,
+                privacy: false,
+                label: "年龄:",
+                element: {
+                  id: "d0a4f500575d11ed891bd723b0984537",
+                  type: "element",
+                  name: "患者年龄",
+                  code: {
+                    business: "患者年龄",
+                    internal: "",
+                    dataElement: "",
+                  },
+                  labels: [""],
+                },
+                tips: "年龄",
+                borderStyle: "none",
+                style: {
+                  id: "RjNfj7mob3Z",
+                },
+                editable: true,
+                contentStyle: "display:inline",
+                id: "qf9OP-SRKs",
+                code: "qf9OP-SRKs",
+                contentWrap: true,
+                value: "72岁",
+                type: "smarttext",
+                children: [
+                  {
+                    style: {
+                      id: "QHd94VJo6SF",
+                    },
+                    id: "e-GlXR5GRn_",
+                    data: "72岁",
+                    type: "text",
+                  },
+                ],
+              },
+              {
+                style: {
+                  id: "QHd94VJo6SF",
+                },
+                id: "VJKa_TuPZQ",
+                data: "  ",
+                type: "text",
+              },
+              {
+                required: false,
+                readonly: false,
+                deletable: true,
+                privacy: false,
+                label: "科室:",
+                element: {
+                  id: "fb6c82c059a211edbd84659f80638fc2",
+                  type: "element",
+                  name: "所在科室名称",
+                  code: {
+                    business: "所在科室名称",
+                    internal: "",
+                    dataElement: "",
+                  },
+                  labels: [""],
+                },
+                tips: "所在科室",
+                borderStyle: "none",
+                style: {
+                  id: "RjNfj7mob3Z",
+                },
+                editable: true,
+                contentStyle: "display:inline",
+                pickerSimpleConfig: {
+                  displayField: "name",
+                },
+                id: "IU4znvjIZ6",
+                code: "IU4znvjIZ6",
+                contentWrap: true,
+                value: "神经内科",
+                type: "smarttext",
+                children: [
+                  {
+                    style: {
+                      id: "QHd94VJo6SF",
+                    },
+                    id: "ykw0MMDk_c",
+                    data: "神经内科",
+                    type: "text",
+                  },
+                ],
+              },
+              {
+                style: {
+                  id: "QHd94VJo6SF",
+                },
+                id: "izkYrPZKVo",
+                data: "  ",
+                type: "text",
+              },
+              {
+                required: false,
+                readonly: false,
+                deletable: true,
+                privacy: false,
+                label: "病室:",
+                element: {
+                  id: "972d4d90576711ed891bd723b0984537",
+                  type: "element",
+                  name: "所在病室名称",
+                  code: {
+                    business: "所在病室名称",
+                    internal: "",
+                    dataElement: "",
+                  },
+                  labels: [""],
+                },
+                tips: "所在病室",
+                borderStyle: "none",
+                style: {
+                  id: "RjNfj7mob3Z",
+                },
+                editable: true,
+                contentStyle: "display:inline",
+                id: "sK4gyPGluy",
+                code: "sK4gyPGluy",
+                contentWrap: true,
+                value: "一(1区)病室",
+                type: "smarttext",
+                children: [
+                  {
+                    style: {
+                      id: "QHd94VJo6SF",
+                    },
+                    id: "k-Ll92aKA9",
+                    data: "一(1区)病室",
+                    type: "text",
+                  },
+                ],
+              },
+              {
+                style: {
+                  id: "QHd94VJo6SF",
+                },
+                id: "e58kkdnrMJB",
+                data: "  ",
+                type: "text",
+              },
+              {
+                required: false,
+                readonly: false,
+                deletable: true,
+                privacy: false,
+                label: "床号:",
+                element: {
+                  id: "d1c68610576711ed891bd723b0984537",
+                  type: "element",
+                  name: "床号",
+                  code: {
+                    business: "床号",
+                    internal: "",
+                    dataElement: "",
+                  },
+                  labels: [""],
+                },
+                tips: "床号",
+                borderStyle: "none",
+                style: {
+                  id: "RjNfj7mob3Z",
+                },
+                editable: true,
+                contentStyle: "display:inline",
+                id: "KueHQpM0g_",
+                code: "KueHQpM0g_",
+                contentWrap: true,
+                value: "1",
+                type: "smarttext",
+                children: [
+                  {
+                    style: {
+                      id: "QHd94VJo6SF",
+                    },
+                    id: "UWlKgwdITJ",
+                    data: "1",
+                    type: "text",
+                  },
+                ],
+              },
+            ],
+          },
+        ],
+      },
+      footer: {
+        id: "Mg1qBgQ-nO",
+        type: "$root",
+        children: [
+          {
+            defaultStyleId: "global_style_text",
+            id: "E4Gomovyqa",
+            type: "paragraph",
+            children: [
+              {
+                style: {
+                  id: "VPvz6PfU4",
+                },
+                id: "r2PdNQCxot",
+                data: "",
+                type: "text",
+              },
+            ],
+          },
+        ],
+      },
+      body: {
+        id: "cUygzPJD7",
+        type: "$root",
+        children: [
+          {
+            defaultStyleId: "global_style_text",
+            id: "e3-F7Y31bP",
+            style: {
+              id: "PaRNStosO",
+            },
+            type: "paragraph",
+            children: [
+              {
+                style: {
+                  id: "VPvz6PfU4",
+                },
+                id: "ssoI5go2Vg",
+                data: "委托人(患者本人):",
+                type: "text",
+              },
+              {
+                required: false,
+                readonly: false,
+                deletable: true,
+                privacy: false,
+                element: {
+                  id: "499618900d5811ed9df371afd668b4b0",
+                  type: "element",
+                  name: "患者姓名",
+                  code: {
+                    business: "患者姓名",
+                    internal: "",
+                    dataElement: "",
+                  },
+                  labels: [""],
+                },
+                tips: "姓名",
+                borderStyle: "none",
+                style: {
+                  id: "HiMU5YM3cM",
+                },
+                editable: true,
+                contentStyle: "display:inline-block;min-width:28px",
+                id: "cJcuubcnl-",
+                code: "cJcuubcnl-",
+                minWidth: "42",
+                contentWrap: true,
+                value: "舒秀玲",
+                type: "smarttext",
+                children: [
+                  {
+                    style: {
+                      id: "zJpp4slEdJ",
+                    },
+                    id: "B_tq94kSuO",
+                    data: "舒秀玲",
+                    type: "text",
+                  },
+                ],
+              },
+              {
+                style: {
+                  id: "VPvz6PfU4",
+                },
+                id: "ymBcAfLG1-",
+                data: "        ",
+                type: "text",
+              },
+              {
+                required: false,
+                readonly: true,
+                deletable: true,
+                privacy: false,
+                label: "性别:",
+                element: {
+                  id: "902e4580575d11ed891bd723b0984537",
+                  type: "element",
+                  name: "患者性别",
+                  code: {
+                    business: "性别名称",
+                    internal: "",
+                    dataElement: "",
+                  },
+                  labels: [""],
+                },
+                tips: "性别",
+                borderStyle: "none",
+                style: {
+                  id: "HiMU5YM3cM",
+                },
+                editable: true,
+                contentStyle: "display:inline-block;min-width:28px",
+                id: "KifurKpxFf",
+                code: "KifurKpxFf",
+                minWidth: "84",
+                contentWrap: true,
+                value: "女",
+                type: "smarttext",
+                children: [
+                  {
+                    style: {
+                      id: "zJpp4slEdJ",
+                    },
+                    id: "rSUj7LcW_j",
+                    data: "女",
+                    type: "text",
+                  },
+                ],
+              },
+              {
+                style: {
+                  id: "VPvz6PfU4",
+                },
+                id: "HIjxDPp_4K",
+                data: "          ",
+                type: "text",
+              },
+              {
+                required: false,
+                readonly: true,
+                deletable: true,
+                privacy: false,
+                label: "年龄:",
+                element: {
+                  id: "d0a4f500575d11ed891bd723b0984537",
+                  type: "element",
+                  name: "患者年龄",
+                  code: {
+                    business: "患者年龄",
+                    internal: "",
+                    dataElement: "",
+                  },
+                  labels: [""],
+                },
+                tips: "年龄",
+                borderStyle: "none",
+                style: {
+                  id: "HiMU5YM3cM",
+                },
+                editable: true,
+                contentStyle: "display:inline-block;min-width:28px",
+                id: "LqhWG1cjRW",
+                code: "LqhWG1cjRW",
+                minWidth: "84",
+                contentWrap: true,
+                value: "72岁",
+                type: "smarttext",
+                children: [
+                  {
+                    style: {
+                      id: "zJpp4slEdJ",
+                    },
+                    id: "oxKK-D2IE1",
+                    data: "72岁",
+                    type: "text",
+                  },
+                ],
+              },
+              {
+                style: {
+                  id: "VPvz6PfU4",
+                },
+                id: "ouiRzxEV3j",
+                data: " ",
+                type: "text",
+              },
+            ],
+          },
+          {
+            defaultStyleId: "global_style_text",
+            id: "h_gCQJluWs",
+            style: {
+              id: "PaRNStosO",
+            },
+            type: "paragraph",
+            children: [
+              {
+                style: {
+                  id: "VPvz6PfU4",
+                },
+                id: "Go9gD8oYW",
+                data: "有效证件号码:",
+                type: "text",
+              },
+              {
+                code: "aY2SWtcD24",
+                required: false,
+                readonly: false,
+                deletable: true,
+                privacy: false,
+                element: {
+                  id: "302da4f0580211eda93f1fd7ab32baa6",
+                  type: "element",
+                  name: "身份证号码",
+                  code: {
+                    business: "身份证号码",
+                    internal: "",
+                    dataElement: "",
+                  },
+                  labels: [""],
+                },
+                tips: "身份证号码",
+                borderStyle: "none",
+                minWidth: "84",
+                id: "aY2SWtcD24",
+                style: {
+                  id: "HiMU5YM3cM",
+                },
+                editable: true,
+                contentStyle: "display:inline-block;min-width:70px",
+                contentWrap: true,
+                value: "430121195201189429",
+                type: "smarttext",
+                children: [
+                  {
+                    style: {
+                      id: "zJpp4slEdJ",
+                    },
+                    id: "e92mCnfONUS",
+                    data: "430121195201189429",
+                    type: "text",
+                  },
+                ],
+              },
+              {
+                style: {
+                  id: "VPvz6PfU4",
+                },
+                id: "o_zv5noaJ",
+                data: " ",
+                type: "text",
+              },
+            ],
+          },
+          {
+            defaultStyleId: "global_style_text",
+            id: "XSMGqJF5F",
+            style: {
+              id: "PaRNStosO",
+            },
+            type: "paragraph",
+            children: [
+              {
+                code: "w07vl4AGS",
+                required: false,
+                readonly: false,
+                deletable: true,
+                privacy: false,
+                label: "住址:",
+                element: {
+                  id: "8aa6e0f0576111ed891bd723b0984537",
+                  type: "element",
+                  name: "患者住址",
+                  code: {
+                    business: "患者住址",
+                    internal: "",
+                    dataElement: "",
+                  },
+                  labels: [""],
+                },
+                tips: "住址",
+                borderStyle: "none",
+                minWidth: "85",
+                id: "w07vl4AGS",
+                style: {
+                  id: "HiMU5YM3cM",
+                },
+                editable: true,
+                contentStyle: "display:inline-block;min-width:29px",
+                contentWrap: true,
+                value: "长沙市开福区捞刀河镇罗汉庄村大坡",
+                type: "smarttext",
+                children: [
+                  {
+                    style: {
+                      id: "zJpp4slEdJ",
+                    },
+                    id: "XKGW0yK2vj",
+                    data: "长沙市开福区捞刀河镇罗汉庄村大坡",
+                    type: "text",
+                  },
+                ],
+              },
+            ],
+          },
+          {
+            defaultStyleId: "global_style_text",
+            style: {
+              id: "PaRNStosO",
+            },
+            id: "e37-OT6hjn",
+            type: "paragraph",
+            children: [
+              {
+                style: {
+                  id: "VPvz6PfU4",
+                },
+                id: "NmeuXBSqer",
+                data: "",
+                type: "text",
+              },
+            ],
+          },
+          {
+            defaultStyleId: "global_style_text",
+            id: "e5G6YfTugjd",
+            style: {
+              id: "PaRNStosO",
+            },
+            type: "paragraph",
+            children: [
+              {
+                style: {
+                  id: "VPvz6PfU4",
+                },
+                id: "rF0WKyp_g",
+                data: "受托人:______",
+                type: "text",
+              },
+              {
+                required: false,
+                readonly: false,
+                deletable: true,
+                privacy: false,
+                script: {
+                  dynamicScript: "2154eae0167611ef8717efceee160e36",
+                },
+                element: {
+                  id: "552c4a60167711ef8717efceee160e36",
+                  type: "element",
+                  name: "医生签名",
+                  code: {
+                    business: "自动签名",
+                    internal: "患者CA签名",
+                    dataElement: "2",
+                  },
+                },
+                tips: "医生签名",
+                borderStyle: "none",
+                style: {
+                  id: "VPvz6PfU4",
+                },
+                editable: false,
+                contentWrap: true,
+                signCount: 1,
+                fitWidth: false,
+                valign: "bottom",
+                id: "N11RvOPZ05",
+                code: "N11RvOPZ05",
+                type: "smarttext",
+              },
+              {
+                style: {
+                  id: "VPvz6PfU4",
+                },
+                id: "qtx7shS_0",
+                data: "_______ 性别:",
+                type: "text",
+              },
+              {
+                style: {
+                  id: "wRN6Tib_nc",
+                },
+                id: "Ls0g7s6Nz",
+                data: "        ",
+                type: "text",
+              },
+              {
+                style: {
+                  id: "VPvz6PfU4",
+                },
+                id: "o3Zp-EThw7",
+                data: " 年龄:",
+                type: "text",
+              },
+              {
+                style: {
+                  id: "wRN6Tib_nc",
+                },
+                id: "Nom7d5qiO",
+                data: "        ",
+                type: "text",
+              },
+              {
+                style: {
+                  id: "VPvz6PfU4",
+                },
+                id: "MJcT7NIOy",
+                data: "  联系电话:",
+                type: "text",
+              },
+              {
+                style: {
+                  id: "wRN6Tib_nc",
+                },
+                id: "Uwnf944SU",
+                data: "                ",
+                type: "text",
+              },
+            ],
+          },
+          {
+            defaultStyleId: "global_style_text",
+            style: {
+              id: "PaRNStosO",
+            },
+            id: "K8VXrU9rM",
+            type: "paragraph",
+            children: [
+              {
+                style: {
+                  id: "VPvz6PfU4",
+                },
+                id: "EK_f7pzYUi",
+                data: "",
+                type: "text",
+              },
+            ],
+          },
+          {
+            defaultStyleId: "global_style_text",
+            id: "DPyIlVY3Q9",
+            style: {
+              id: "PaRNStosO",
+            },
+            type: "paragraph",
+            children: [
+              {
+                style: {
+                  id: "VPvz6PfU4",
+                },
+                id: "SVri_U2PPh",
+                data: "有效证件号码:",
+                type: "text",
+              },
+              {
+                style: {
+                  id: "wRN6Tib_nc",
+                },
+                id: "K_OA61xys",
+                data: "_____________           _             ",
+                type: "text",
+              },
+              {
+                style: {
+                  id: "VPvz6PfU4",
+                },
+                id: "t0IJRP2sih",
+                data: "住址:_______________________",
+                type: "text",
+              },
+            ],
+          },
+          {
+            defaultStyleId: "global_style_text",
+            style: {
+              id: "PaRNStosO",
+            },
+            id: "e4uwmzxipp",
+            type: "paragraph",
+            children: [
+              {
+                style: {
+                  id: "VPvz6PfU4",
+                },
+                id: "dxmydm5_3I",
+                data: "",
+                type: "text",
+              },
+            ],
+          },
+          {
+            defaultStyleId: "global_style_text",
+            id: "e1aq-PiOvZ3",
+            style: {
+              id: "PaRNStosO",
+            },
+            type: "paragraph",
+            children: [
+              {
+                style: {
+                  id: "VPvz6PfU4",
+                },
+                id: "jRaE-KpFI",
+                data: "与患者关系:□配偶      □子女     □父母    □同事    □朋友    □其他",
+                type: "text",
+              },
+            ],
+          },
+          {
+            defaultStyleId: "global_style_text",
+            id: "e-9RT_i65jJ",
+            style: {
+              id: "PaRNStosO",
+            },
+            type: "paragraph",
+            children: [
+              {
+                style: {
+                  id: "VPvz6PfU4",
+                },
+                id: "e3x8ReYhRDR",
+                data: "",
+                type: "text",
+              },
+            ],
+          },
+          {
+            defaultStyleId: "global_style_text",
+            id: "tdkdzJAfUY",
+            style: {
+              id: "PaRNStosO",
+            },
+            type: "paragraph",
+            children: [
+              {
+                style: {
+                  id: "VPvz6PfU4",
+                },
+                id: "LRKh27B5R",
+                data: "     本人于",
+                type: "text",
+              },
+              {
+                code: "igdq9av_zr",
+                required: false,
+                readonly: false,
+                deletable: true,
+                privacy: false,
+                format: {
+                  dataType: "DT",
+                  showType: "CDT13",
+                  enums: {},
+                },
+                element: {
+                  id: "a9d9f070576111ed891bd723b0984537",
+                  type: "element",
+                  name: "入院时间",
+                  code: {
+                    business: "入院时间",
+                    internal: "",
+                    dataElement: "",
+                  },
+                  labels: [""],
+                },
+                tips: "入院时间",
+                borderStyle: "none",
+                id: "igdq9av_zr",
+                style: {
+                  id: "LIR4sDw0bR",
+                },
+                editable: false,
+                contentStyle: "display:inline",
+                contentWrap: true,
+                value: "2024-10-21 11:37:01",
+                type: "smarttext",
+                children: [
+                  {
+                    style: {
+                      id: "VPvz6PfU4",
+                      class: "edl-form-item",
+                    },
+                    id: "e3PNF1L80a_",
+                    data: "2024年10月21日 11时37分",
+                    type: "text",
+                  },
+                ],
+              },
+              {
+                style: {
+                  id: "VPvz6PfU4",
+                },
+                id: "OPGl8SYOj",
+                data: "因病住院,本人在住院期间,有关病情的告知以及在诊断过程中需要签署的一切知情同意书,本人郑重委托由___",
+                type: "text",
+              },
+              {
+                required: false,
+                readonly: false,
+                deletable: true,
+                privacy: false,
+                script: {
+                  dynamicScript: "2154eae0167611ef8717efceee160e36",
+                },
+                element: {
+                  id: "552c4a60167711ef8717efceee160e36",
+                  type: "element",
+                  name: "医生签名",
+                  code: {
+                    business: "自动签名",
+                    internal: "患者CA签名",
+                    dataElement: "2",
+                  },
+                },
+                tips: "医生签名",
+                borderStyle: "none",
+                style: {
+                  id: "VPvz6PfU4",
+                },
+                editable: false,
+                contentWrap: true,
+                signCount: 1,
+                fitWidth: false,
+                valign: "bottom",
+                id: "uB1Y355lTk",
+                code: "uB1Y355lTk",
+                type: "smarttext",
+              },
+              {
+                style: {
+                  id: "VPvz6PfU4",
+                },
+                id: "NymJes-V9",
+                data: "_________作为我的代理人,代为行使住院期间的知情同意权利,并履行相应的签字手续,全权代表本人签字,被委托人的签字视同本人的签字。",
+                type: "text",
+              },
+            ],
+          },
+          {
+            defaultStyleId: "global_style_text",
+            id: "jnQX_T4hrh",
+            style: {
+              id: "PaRNStosO",
+            },
+            type: "paragraph",
+            children: [
+              {
+                style: {
+                  id: "VPvz6PfU4",
+                },
+                id: "e0XiqSEz9nf",
+                data: "",
+                type: "text",
+              },
+            ],
+          },
+          {
+            defaultStyleId: "global_style_text",
+            id: "rKxBODV7O",
+            style: {
+              id: "PaRNStosO",
+            },
+            type: "paragraph",
+            children: [
+              {
+                style: {
+                  id: "VPvz6PfU4",
+                },
+                id: "vnppUiun-",
+                data: "      受委托人签署同意书后所产生的后果,由患者本人承担。",
+                type: "text",
+              },
+            ],
+          },
+          {
+            defaultStyleId: "global_style_text",
+            id: "MuM1jM9X7",
+            style: {
+              id: "PaRNStosO",
+            },
+            type: "paragraph",
+            children: [
+              {
+                style: {
+                  id: "VPvz6PfU4",
+                },
+                id: "hHQ12Jfh1u",
+                data: "",
+                type: "text",
+              },
+            ],
+          },
+          {
+            defaultStyleId: "global_style_text",
+            id: "e6WniuTxLnB",
+            style: {
+              id: "PaRNStosO",
+            },
+            type: "paragraph",
+            children: [
+              {
+                style: {
+                  id: "VPvz6PfU4",
+                },
+                id: "e3mUASTD7t",
+                data: "患者签名:",
+                type: "text",
+              },
+              {
+                style: {
+                  id: "wRN6Tib_nc",
+                },
+                id: "Mh5Jh0fKi",
+                data: "_______",
+                type: "text",
+              },
+              {
+                required: false,
+                readonly: false,
+                deletable: true,
+                privacy: false,
+                script: {
+                  dynamicScript: "2154eae0167611ef8717efceee160e36",
+                },
+                element: {
+                  id: "552c4a60167711ef8717efceee160e36",
+                  type: "element",
+                  name: "医生签名",
+                  code: {
+                    business: "自动签名",
+                    internal: "患者CA签名",
+                    dataElement: "1",
+                  },
+                },
+                tips: "医生签名",
+                borderStyle: "none",
+                style: {
+                  id: "VPvz6PfU4",
+                },
+                editable: false,
+                contentWrap: true,
+                signCount: 1,
+                fitWidth: false,
+                valign: "bottom",
+                id: "GdLN8XGrgh",
+                code: "GdLN8XGrgh",
+                type: "smarttext",
+              },
+              {
+                style: {
+                  id: "wRN6Tib_nc",
+                },
+                id: "xrXMEwWQt",
+                data: "_     ____",
+                type: "text",
+              },
+              {
+                style: {
+                  id: "VPvz6PfU4",
+                },
+                id: "QIUDp8Hvnp",
+                data: "(或手印)           ",
+                type: "text",
+              },
+            ],
+          },
+          {
+            defaultStyleId: "global_style_text",
+            id: "BS-308uhr",
+            style: {
+              id: "PaRNStosO",
+            },
+            type: "paragraph",
+            children: [
+              {
+                style: {
+                  id: "VPvz6PfU4",
+                },
+                id: "e43YJw4s7eh",
+                data: "",
+                type: "text",
+              },
+            ],
+          },
+          {
+            defaultStyleId: "global_style_text",
+            id: "D0-KnWvBNP",
+            style: {
+              id: "PaRNStosO",
+            },
+            type: "paragraph",
+            children: [
+              {
+                style: {
+                  id: "VPvz6PfU4",
+                },
+                id: "TxDluxAOF",
+                data: "受托人签名:",
+                type: "text",
+              },
+              {
+                style: {
+                  id: "wRN6Tib_nc",
+                },
+                id: "m0y_xm5dX",
+                data: "______  ",
+                type: "text",
+              },
+              {
+                required: false,
+                readonly: false,
+                deletable: true,
+                privacy: false,
+                script: {
+                  dynamicScript: "2154eae0167611ef8717efceee160e36",
+                },
+                element: {
+                  id: "552c4a60167711ef8717efceee160e36",
+                  type: "element",
+                  name: "医生签名",
+                  code: {
+                    business: "自动签名",
+                    internal: "患者CA签名",
+                    dataElement: "2",
+                  },
+                },
+                tips: "医生签名",
+                borderStyle: "none",
+                style: {
+                  id: "VPvz6PfU4",
+                },
+                editable: false,
+                contentWrap: true,
+                signCount: 1,
+                fitWidth: false,
+                valign: "bottom",
+                id: "MMCckv-XGK",
+                code: "MMCckv-XGK",
+                type: "smarttext",
+              },
+              {
+                style: {
+                  id: "wRN6Tib_nc",
+                },
+                id: "nsAUZH2Rt",
+                data: "   ____",
+                type: "text",
+              },
+              {
+                style: {
+                  id: "VPvz6PfU4",
+                },
+                id: "HwwYWR85FM",
+                data: "(或手印)           ",
+                type: "text",
+              },
+            ],
+          },
+          {
+            defaultStyleId: "global_style_text",
+            id: "e9CEMwErPl",
+            style: {
+              id: "PaRNStosO",
+            },
+            type: "paragraph",
+            children: [
+              {
+                style: {
+                  id: "VPvz6PfU4",
+                },
+                id: "e7CKtmjoaD7",
+                data: "",
+                type: "text",
+              },
+            ],
+          },
+          {
+            defaultStyleId: "global_style_text",
+            id: "TY6ZadatD_",
+            style: {
+              id: "PaRNStosO",
+            },
+            type: "paragraph",
+            children: [
+              {
+                style: {
+                  id: "VPvz6PfU4",
+                },
+                id: "SDAMw9RnAp",
+                data: "医师签名:__",
+                type: "text",
+              },
+              {
+                style: {
+                  id: "VPvz6PfU4",
+                },
+                id: "VTQtRKfgOP",
+                data: "___",
+                type: "text",
+              },
+              {
+                style: {
+                  id: "VPvz6PfU4",
+                },
+                id: "VKUTrgDcP",
+                data: "_",
+                type: "text",
+              },
+              {
+                code: "QQLBQsfpj",
+                required: false,
+                readonly: false,
+                deletable: false,
+                privacy: false,
+                script: {
+                  dynamicScript: "2154eae0167611ef8717efceee160e36",
+                },
+                element: {
+                  id: "552c4a60167711ef8717efceee160e36",
+                  type: "element",
+                  name: "医生签名",
+                  code: {
+                    business: "自动签名",
+                    internal: "",
+                    dataElement: "",
+                  },
+                },
+                tips: "医生签名",
+                borderStyle: "none",
+                id: "QQLBQsfpj",
+                style: {
+                  id: "VPvz6PfU4",
+                },
+                editable: false,
+                contentWrap: true,
+                signCount: 1,
+                fitWidth: false,
+                valign: "bottom",
+                value: [
+                  {
+                    id: "02896",
+                    code: "02896",
+                    name: "肖蟾",
+                    signature:
+                      "http://172.16.32.167:8077/doctorSignatureImage/02896.png",
+                  },
+                ],
+                type: "smarttext",
+                children: [
+                  {
+                    src: "http://172.16.32.167:8077/doctorSignatureImage/02896.png",
+                    "data-id": "02896",
+                    text: "肖蟾",
+                    fitWidth: false,
+                    valign: "bottom",
+                    style: {
+                      id: "VPvz6PfU4",
+                    },
+                    id: "p6LhbXhLZbe",
+                    type: "sign",
+                  },
+                ],
+              },
+              {
+                style: {
+                  id: "VPvz6PfU4",
+                },
+                id: "NYwh5y018",
+                data: "________",
+                type: "text",
+              },
+            ],
+          },
+          {
+            defaultStyleId: "global_style_text",
+            id: "nfj51fM0S",
+            style: {
+              id: "PaRNStosO",
+            },
+            type: "paragraph",
+            children: [
+              {
+                style: {
+                  id: "VPvz6PfU4",
+                },
+                id: "CohmcKWrQe",
+                data: "",
+                type: "text",
+              },
+            ],
+          },
+          {
+            defaultStyleId: "global_style_text",
+            id: "e3yewSeHEd7",
+            style: {
+              id: "PaRNStosO",
+            },
+            type: "paragraph",
+            children: [
+              {
+                style: {
+                  id: "VPvz6PfU4",
+                },
+                id: "uJKN8oWNs",
+                data: "谈话地点:_______医生办公室______           时间:",
+                type: "text",
+              },
+              {
+                code: "F9HSq6z69",
+                required: false,
+                readonly: false,
+                deletable: true,
+                privacy: false,
+                format: {
+                  dataType: "DT",
+                  showType: "CDT13",
+                },
+                element: {
+                  id: "aaa85910598711ed860ddf3f2d3a5ebd",
+                  type: "element",
+                  name: "创建时间",
+                  code: {
+                    business: "创建时间",
+                    internal: "",
+                    dataElement: "",
+                  },
+                },
+                tips: "创建时间",
+                borderStyle: "none",
+                id: "F9HSq6z69",
+                style: {
+                  id: "VPvz6PfU4",
+                },
+                editable: false,
+                contentWrap: true,
+                isNow: true,
+                value: "2024-10-24 08:52:08",
+                type: "smarttext",
+                children: [
+                  {
+                    style: {
+                      id: "VPvz6PfU4",
+                      class: "edl-form-item",
+                    },
+                    id: "DNWV6aMi_",
+                    data: "2024年10月24日 08时52分",
+                    type: "text",
+                  },
+                ],
+              },
+            ],
+          },
+          {
+            defaultStyleId: "global_style_text",
+            style: {
+              id: "PaRNStosO",
+            },
+            id: "e6Pi0HAYj2",
+            type: "paragraph",
+            children: [
+              {
+                code: "rN_GsGNio",
+                required: false,
+                readonly: false,
+                deletable: true,
+                privacy: false,
+                tips: "昏迷等丧失民事行为能力者,无需签署授权委托书,请陪同人员填写本表的相关信息、留档即可。",
+                borderStyle: "none",
+                minWidth: "429",
+                id: "rN_GsGNio",
+                style: {
+                  id: "VPvz6PfU4",
+                },
+                editable: true,
+                contentWrap: true,
+                contentStyle: "display:inline-block;min-width:415px",
+                type: "smarttext",
+              },
+            ],
+          },
+          {
+            defaultStyleId: "global_style_text",
+            id: "e4yD3Yw1QT",
+            style: {
+              id: "PaRNStosO",
+            },
+            type: "paragraph",
+            children: [
+              {
+                style: {
+                  id: "VPvz6PfU4",
+                },
+                id: "T0i1ajoon",
+                data: "",
+                type: "text",
+              },
+            ],
+          },
+        ],
+      },
+    },
+    globalStyles: [
+      {
+        code: "global_style_text",
+        name: "正文",
+        rpr: {
+          fontFamily: "SimSun",
+          fontSize: "10.5pt",
+          fontWeight: "normal",
+        },
+        styles: "font-family:SimSun; font-size: 10.5pt; font-weight: normal;",
+        ppr: {},
+        id: "extModel391-17",
+      },
+      {
+        code: "global_style_title",
+        name: "标题",
+        rpr: {
+          fontFamily: "SimSun",
+          fontSize: "22pt",
+          fontWeight: "normal",
+        },
+        styles: "font-family:SimSun; font-size: 22pt; font-weight: normal;",
+        ppr: {},
+        id: "extModel391-18",
+      },
+      {
+        code: "global_style_subtitle",
+        name: "副标题",
+        rpr: {
+          fontFamily: "SimSun",
+          fontSize: "20pt",
+          fontWeight: "normal",
+        },
+        styles: "font-family:SimSun; font-size: 20pt; font-weight: normal;",
+        ppr: {},
+        id: "extModel391-19",
+      },
+      {
+        code: "global_style_title_1",
+        name: "标题1",
+        rpr: {
+          fontFamily: "SimSun",
+          fontSize: "18pt",
+          fontWeight: "normal",
+        },
+        styles: "font-family:SimSun; font-size: 18pt; font-weight: normal;",
+        ppr: {},
+        id: "extModel391-20",
+      },
+      {
+        code: "global_style_title_2",
+        name: "标题2",
+        rpr: {
+          fontFamily: "SimSun",
+          fontSize: "16pt",
+          fontWeight: "normal",
+        },
+        styles: "font-family:SimSun; font-size: 16pt; font-weight: normal;",
+        ppr: {},
+        id: "extModel391-21",
+      },
+      {
+        code: "global_style_title_3",
+        name: "标题3",
+        rpr: {
+          fontFamily: "SimSun",
+          fontSize: "14pt",
+          fontWeight: "normal",
+        },
+        styles: "font-family:SimSun; font-size: 14pt; font-weight: normal;",
+        ppr: {},
+        id: "extModel391-22",
+      },
+      {
+        code: "global_style_title_4",
+        name: "标题4",
+        rpr: {
+          fontFamily: "SimSun",
+          fontSize: "12pt",
+          fontWeight: "normal",
+        },
+        styles: "font-family:SimSun; font-size: 12pt; font-weight: normal;",
+        ppr: {},
+        id: "extModel391-23",
+      },
+      {
+        code: "global_style_title_5",
+        name: "标题5",
+        rpr: {
+          fontFamily: "SimSun",
+          fontSize: "11pt",
+          fontWeight: "normal",
+        },
+        styles:
+          "font-family:[object Object]; font-size: 11pt; font-weight: normal;",
+        ppr: {},
+        id: "extModel391-24",
+      },
+    ],
+  };
+  editor.setDocument(data, true, true);
+});
+
+export function emrCa(store: EmrStore) {
+  async function 授权CA签名(_evt, view, eleInfo, { patientInfo, emrName }) {
+    if (eleInfo?.code?.internal !== "授权CA签名") {
+      return;
+    }
+    const us = useUserStore().userInfo;
+    const res = await useDialog(GenerateSignature, {
+      dialogProps: {
+        title: "授权签名",
+      },
+      // @ts-ignore
+      params: {
+        currentCode: us.code,
+        patientInfo,
+      },
+    });
+    const code = res.code;
+    const caData = await sendByCode({
+      id: isDev ? "00026" : code,
+      msg: "电子病历系统签名",
+      desc: `由${us.name}发起签名,患者:【${patientInfo.name}】,性别:【${patientInfo.sexName}】,病区:【${patientInfo.zkWardName}】,签名病历【${emrName}】`,
+    });
+    view.sign([caData]);
+  }
+
+  function 患者CA签名(_evt, _view, eleInfo, value) {
+    if (eleInfo?.code?.internal !== "患者CA签名") {
+      return;
+    }
+    store.store.right = EmrRightTabs.ca;
+  }
+
+  onMounted(() => {
+    store.store.rightComp[0] = {
+      name: EmrRightTabs.ca,
+      comp: shallowRef(defineAsyncComponent(() => import("./EmrCAComp.vue"))),
+    };
+  });
+
+  return {
+    pushSign(editor: EditType, value: saveType) {
+      return new Promise<number>(async (resolve, reject) => {
+        const signatureControl = getInternalByCode(editor, "编辑者CA签名");
+        // 如果没有这个数据源就不
+        if (
+          !XEUtils.isArray(signatureControl) ||
+          (signatureControl as any[]).length === 0
+        ) {
+          return resolve(0);
+        }
+
+        const tmpDialog = dialog();
+
+        const data: CaSendParams = {
+          msg: "电子病历系统签名",
+          desc: `该信息由病历系统发送,患者:【${value.name}】,性别:【${value.sexName}】,病区:【${value.zkWardName}】,签名病历【${value.emrName}】`,
+          id: isDev ? "00026" : useUserStore().userInfo.code,
+          count: signatureControl?.length ?? 0,
+        };
+
+        const result = await sendBatchByCode(data)
+          .catch(() => {
+            resolve(0);
+            return [];
+          })
+          .finally(() => {
+            tmpDialog.closed();
+          });
+
+        if (result.length === 0) {
+          return resolve(0);
+        }
+
+        signatureControl.forEach((signature, index) => {
+          const element = getViewById(editor, signature.id);
+          const emrData = result[index];
+          element.view.sign([emrData]);
+        });
+        return resolve(0);
+      });
+    },
+
+    async componentClick(evt, view, eleInfo, value) {
+      授权CA签名(evt, view, eleInfo, value).then(XEUtils.noop);
+      患者CA签名(evt, view, eleInfo, value);
+    },
+    testFunc,
+    loaded(editor: EditType) {
+      store.store.rightComp[0].refValue.change();
+      if (isDev) {
+        // sleep(1000).then(() => {
+        //   testChange(editor);
+        // });
+        // this.testFunc(editor);
+      }
+    },
+  };
+}

+ 0 - 251
src/views/hospitalization/zhu-yuan-yi-sheng/electronic-medical-record/emr-func/emr-ca.tsx

@@ -1,251 +0,0 @@
-import { DataElementItem, EditType } from "@/utils/emr/edit";
-import { CaSendParams, sendBatchByCode, sendByCode } from "@/api/ca/ca-api";
-import { isDev } from "@/utils/public";
-import { useUserStore } from "@/pinia/user-store";
-import XEUtils from "xe-utils";
-import { useDialog } from "@/components/cy/CyDialog/index";
-
-const GenerateSignature = defineAsyncComponent(
-  () =>
-    import(
-      "@/views/hospitalization/zhu-yuan-yi-sheng/electronic-medical-record/emr-editor/components/GenerateSignature.vue"
-    )
-);
-
-const testInput = {
-  required: false,
-  readonly: false,
-  deletable: true,
-  privacy: false,
-  script: {
-    content: null,
-    dynamicScript: "2154eae0167611ef8717efceee160e36",
-  },
-  format: {
-    dataType: null,
-    showType: null,
-    minLength: null,
-    maxLength: null,
-    minRows: null,
-    maxRows: null,
-    scale: null,
-    enums: null,
-    dictionary: null,
-  },
-  element: {
-    id: "552c4a60167711ef8717efceee160e36",
-    type: "element",
-    name: "医生签名",
-    code: {
-      business: "自动签名",
-      internal: "编辑者CA签名",
-      dataElement: "",
-    },
-  },
-  tips: "医生签名",
-  borderStyle: "none",
-  style: {
-    id: "e6aRxaE7OLt",
-  },
-  picker: {
-    type: null,
-    propertiesConfig: {
-      signCount: {
-        name: "签名数量",
-        code: "signCount",
-        category: "extend",
-        categoryName: "扩展",
-        value: 1,
-        editor: {
-          type: "numberfield",
-          minvalue: 1,
-        },
-      },
-      maxHeight: {
-        name: "最大高度",
-        code: "maxHeight",
-        category: "extend",
-        categoryName: "扩展",
-        editor: {
-          type: "numberfield",
-        },
-      },
-      valign: {
-        name: "对齐方式",
-        code: "valign",
-        category: "extend",
-        categoryName: "扩展",
-        editor: {
-          type: "select",
-          valueField: "code",
-          displayField: "name",
-          store: {
-            type: "store",
-            fields: ["code", "name"],
-            data: [
-              {
-                code: "top",
-                name: "上对齐",
-              },
-              {
-                code: "middle",
-                name: "中对齐",
-              },
-              {
-                code: "bottom",
-                name: "下对齐",
-              },
-            ],
-          },
-        },
-      },
-    },
-  },
-  editable: false,
-  contentWrap: true,
-  signCount: 1,
-  type: "smarttext",
-};
-
-function testFunc(editor: EditType) {
-  if (!isDev) return;
-  editor.setCursor("DOCUMENT_START");
-  editor.execute("insertContents", {
-    value: [XEUtils.cloneDeep(testInput)],
-  });
-  editor.setCursor("DOCUMENT_START");
-  editor.execute("insertContents", {
-    value: [XEUtils.cloneDeep(testInput)],
-  });
-  editor.setCursor("DOCUMENT_START");
-  const tmp = XEUtils.cloneDeep(testInput);
-  tmp.element.code.internal = "授权CA签名";
-  editor.execute("insertContents", {
-    value: [tmp],
-  });
-}
-
-type saveType =
-  | {
-      // 病历的名称
-      emrName: string;
-      // 患者名称
-      patientName: string;
-      // 患者年龄
-      age: string;
-    }
-  | any;
-
-function getInternalByCode(editor: EditType, name: string): DataElementItem[] {
-  const signatureControl = editor.getDataElements("internal", false, true);
-  // @ts-ignore
-  let data: DataElementItem[] = signatureControl[name];
-  if (!data) {
-    return null;
-  }
-  if (!XEUtils.isArray(data)) {
-    data = [data];
-  }
-  XEUtils.remove(data, item => {
-    return item.value != null;
-  });
-
-  return data;
-}
-
-function getViewById(editor: EditType, id: string) {
-  const find = editor.view.container.find(`#${id}`);
-  if (XEUtils.isEmpty(find)) {
-    return;
-  }
-  return find[0];
-}
-
-function dialog() {
-  let tmpClose = (value, data) => {};
-
-  useDialog(<div>正在生成您的签名请稍后。。。</div>, {
-    dialogProps: {
-      title: "生成签名中",
-    },
-    manuallyClose: cb => {
-      tmpClose = cb;
-    },
-  }).then(XEUtils.noop);
-
-  return {
-    closed() {
-      tmpClose("confirm", null);
-    },
-  };
-}
-
-export function emrCa() {
-  return {
-    pushSign(editor: EditType, value: saveType) {
-      return new Promise<number>(async (resolve, reject) => {
-        const signatureControl = getInternalByCode(editor, "编辑者CA签名");
-        // 如果没有这个数据源就不
-        if (
-          !XEUtils.isArray(signatureControl) ||
-          (signatureControl as any[]).length === 0
-        ) {
-          return resolve(0);
-        }
-
-        const tmpDialog = dialog();
-
-        const data: CaSendParams = {
-          msg: "电子病历系统签名",
-          desc: `该信息由病历系统发送,患者:【${value.name}】,性别:【${value.sexName}】,病区:【${value.zkWardName}】,签名病历【${value.emrName}】`,
-          id: isDev ? "00026" : useUserStore().userInfo.code,
-          count: signatureControl?.length ?? 0,
-        };
-
-        const result = await sendBatchByCode(data)
-          .catch(() => {
-            resolve(0);
-            return [];
-          })
-          .finally(() => {
-            tmpDialog.closed();
-          });
-
-        if (result.length === 0) {
-          return resolve(0);
-        }
-
-        signatureControl.forEach((signature, index) => {
-          const element = getViewById(editor, signature.id);
-          const emrData = result[index];
-          element.view.sign([emrData]);
-        });
-        return resolve(0);
-      });
-    },
-    async componentClick(evt, view, eleInfo, { patientInfo, emrName }) {
-      if (eleInfo?.code?.internal !== "授权CA签名") {
-        return;
-      }
-      const us = useUserStore().userInfo;
-      console.log(patientInfo);
-      const res = await useDialog(GenerateSignature, {
-        dialogProps: {
-          title: "授权签名",
-        },
-        params: {
-          currentCode: us.code,
-          patientInfo,
-        },
-      });
-      const code = res.code;
-      const caData = await sendByCode({
-        id: isDev ? "00026" : code,
-        msg: "电子病历系统签名",
-        desc: `由${us.name}发起签名,患者:【${patientInfo.name}】,性别:【${patientInfo.sexName}】,病区:【${patientInfo.zkWardName}】,签名病历【${emrName}】`,
-      });
-      view.sign([caData]);
-    },
-    testFunc,
-  };
-}

+ 1 - 2
src/views/hospitalization/zhu-yuan-yi-sheng/electronic-medical-record/emr-func/emr-component-click.ts

@@ -9,9 +9,8 @@ export function setEmrComponentClick(cb) {
   click.push(cb);
 }
 
-export function useComponentClick(evt, view, data) {
+export function useComponentClick(evt, view, eleInfo, data) {
   click.forEach(item => {
-    const eleInfo = view.getAttribute("element");
     item(evt, view, eleInfo, data);
   });
 }

+ 37 - 5
src/views/hospitalization/zhu-yuan-yi-sheng/electronic-medical-record/emr-func/useEmrStore.ts

@@ -9,6 +9,7 @@ import * as utilsPlugins from "@/utils/emr/plugins";
 import { ReturnPlugins } from "@/utils/emr/plugins";
 import { UseEmrInitReturn } from "@/utils/emr/emr-init-v2";
 import { EmrRightTabs } from "@/views/hospitalization/zhu-yuan-yi-sheng/electronic-medical-record/emr-editor/emr-init";
+import sleep from "@/utils/sleep";
 
 type Pl<D> = {
   [K in keyof D]: D[K] extends (...args: any[]) => infer R ? R : any;
@@ -38,8 +39,14 @@ export const useEmrStore = (patId: string) => {
     currentPlugins: {} as ReturnPlugins,
     plugins: [] as ReturnPlugins[],
     right: EmrRightTabs.fragment,
+    rightWidth: 220,
     courseJumpId: null,
     editor: null as EditType,
+    rightComp: [] as {
+      name: string;
+      comp: any;
+      refValue?: any;
+    }[],
   });
 
   const plugins = getPlugins();
@@ -52,8 +59,9 @@ export const useEmrStore = (patId: string) => {
       editor = value;
       store.editor = editor;
     },
-    setOutline(value: Outline[]) {
-      outline.value = value;
+    async setOutline() {
+      await sleep(500);
+      outline.value = editor.getOutline();
     },
     installPlugins(value: UseEmrInitReturn) {
       for (let key in plugins) {
@@ -72,6 +80,29 @@ export const useEmrStore = (patId: string) => {
     },
   };
 
+  const editFun = {
+    getViewById(id: string) {
+      const find = editor.view.container.find(`#${id}`);
+      if (XEUtils.isEmpty(find)) {
+        return null;
+      }
+      return find[0];
+    },
+    jumpById(id: string) {
+      const find = editor?.view?.container?.find(`#${id}`);
+      if (XEUtils.isEmpty(find)) {
+        return;
+      }
+      const element = find[0];
+      if (element) {
+        element.view.focusEnter();
+        editor.scrollToCursor();
+        editor.highlight(element.view, 1500);
+        editor.scrollToCursor(true);
+      }
+    },
+  };
+
   const cache = {
     open() {
       if (window.indexedDB) {
@@ -177,15 +208,16 @@ export const useEmrStore = (patId: string) => {
     plugins,
     store,
     emrTemplate,
+    editFun,
   };
 };
 
-type PageStore = ReturnType<typeof useEmrStore>;
+type EmrStore = ReturnType<typeof useEmrStore>;
 
-export type { PageStore };
+export type { EmrStore };
 
 interface EmrRootContext {
-  store: PageStore;
+  store: EmrStore;
 }
 
 export const emrRootContextKey: InjectionKey<EmrRootContext> =