xiaochan 11 ماه پیش
والد
کامیت
7c5527a35b

+ 160 - 30
package-lock.json

@@ -37,7 +37,7 @@
         "pinia": "2.1.7",
         "qrcanvas": "3.1.2",
         "sortablejs": "1.15.2",
-        "vue": "3.4.27",
+        "vue": "^3.5.6",
         "vue-cropper": "^1.1.2",
         "vue-router": "4.0.16",
         "vue3-json-viewer": "2.2.2",
@@ -3604,6 +3604,7 @@
       "version": "3.4.27",
       "resolved": "https://registry.npmmirror.com/@vue/compiler-core/-/compiler-core-3.4.27.tgz",
       "integrity": "sha512-E+RyqY24KnyDXsCuQrI+mlcdW3ALND6U7Gqa/+bVwbcpcR3BRRIckFoz7Qyd4TTlnugtwuI7YgjbvsLmxb+yvg==",
+      "dev": true,
       "dependencies": {
         "@babel/parser": "^7.24.4",
         "@vue/shared": "3.4.27",
@@ -3616,6 +3617,7 @@
       "version": "4.5.0",
       "resolved": "https://registry.npmmirror.com/entities/-/entities-4.5.0.tgz",
       "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
+      "dev": true,
       "engines": {
         "node": ">=0.12"
       }
@@ -3624,6 +3626,7 @@
       "version": "3.4.27",
       "resolved": "https://registry.npmmirror.com/@vue/compiler-dom/-/compiler-dom-3.4.27.tgz",
       "integrity": "sha512-kUTvochG/oVgE1w5ViSr3KUBh9X7CWirebA3bezTbB5ZKBQZwR2Mwj9uoSKRMFcz4gSMzzLXBPD6KpCLb9nvWw==",
+      "dev": true,
       "dependencies": {
         "@vue/compiler-core": "3.4.27",
         "@vue/shared": "3.4.27"
@@ -3633,6 +3636,7 @@
       "version": "3.4.27",
       "resolved": "https://registry.npmmirror.com/@vue/compiler-sfc/-/compiler-sfc-3.4.27.tgz",
       "integrity": "sha512-nDwntUEADssW8e0rrmE0+OrONwmRlegDA1pD6QhVeXxjIytV03yDqTey9SBDiALsvAd5U4ZrEKbMyVXhX6mCGA==",
+      "dev": true,
       "dependencies": {
         "@babel/parser": "^7.24.4",
         "@vue/compiler-core": "3.4.27",
@@ -3649,6 +3653,7 @@
       "version": "3.4.27",
       "resolved": "https://registry.npmmirror.com/@vue/compiler-ssr/-/compiler-ssr-3.4.27.tgz",
       "integrity": "sha512-CVRzSJIltzMG5FcidsW0jKNQnNRYC8bT21VegyMMtHmhW3UOI7knmUehzswXLrExDLE6lQCZdrhD4ogI7c+vuw==",
+      "dev": true,
       "dependencies": {
         "@vue/compiler-dom": "3.4.27",
         "@vue/shared": "3.4.27"
@@ -3780,48 +3785,111 @@
       }
     },
     "node_modules/@vue/reactivity": {
-      "version": "3.4.27",
-      "resolved": "https://registry.npmmirror.com/@vue/reactivity/-/reactivity-3.4.27.tgz",
-      "integrity": "sha512-kK0g4NknW6JX2yySLpsm2jlunZJl2/RJGZ0H9ddHdfBVHcNzxmQ0sS0b09ipmBoQpY8JM2KmUw+a6sO8Zo+zIA==",
+      "version": "3.5.6",
+      "resolved": "https://registry.npmmirror.com/@vue/reactivity/-/reactivity-3.5.6.tgz",
+      "integrity": "sha512-shZ+KtBoHna5GyUxWfoFVBCVd7k56m6lGhk5e+J9AKjheHF6yob5eukssHRI+rzvHBiU1sWs/1ZhNbLExc5oYQ==",
       "dependencies": {
-        "@vue/shared": "3.4.27"
+        "@vue/shared": "3.5.6"
       }
     },
+    "node_modules/@vue/reactivity/node_modules/@vue/shared": {
+      "version": "3.5.6",
+      "resolved": "https://registry.npmmirror.com/@vue/shared/-/shared-3.5.6.tgz",
+      "integrity": "sha512-eidH0HInnL39z6wAt6SFIwBrvGOpDWsDxlw3rCgo1B+CQ1781WzQUSU3YjxgdkcJo9Q8S6LmXTkvI+cLHGkQfA=="
+    },
     "node_modules/@vue/runtime-core": {
-      "version": "3.4.27",
-      "resolved": "https://registry.npmmirror.com/@vue/runtime-core/-/runtime-core-3.4.27.tgz",
-      "integrity": "sha512-7aYA9GEbOOdviqVvcuweTLe5Za4qBZkUY7SvET6vE8kyypxVgaT1ixHLg4urtOlrApdgcdgHoTZCUuTGap/5WA==",
+      "version": "3.5.6",
+      "resolved": "https://registry.npmmirror.com/@vue/runtime-core/-/runtime-core-3.5.6.tgz",
+      "integrity": "sha512-FpFULR6+c2lI+m1fIGONLDqPQO34jxV8g6A4wBOgne8eSRHP6PQL27+kWFIx5wNhhjkO7B4rgtsHAmWv7qKvbg==",
       "dependencies": {
-        "@vue/reactivity": "3.4.27",
-        "@vue/shared": "3.4.27"
+        "@vue/reactivity": "3.5.6",
+        "@vue/shared": "3.5.6"
       }
     },
+    "node_modules/@vue/runtime-core/node_modules/@vue/shared": {
+      "version": "3.5.6",
+      "resolved": "https://registry.npmmirror.com/@vue/shared/-/shared-3.5.6.tgz",
+      "integrity": "sha512-eidH0HInnL39z6wAt6SFIwBrvGOpDWsDxlw3rCgo1B+CQ1781WzQUSU3YjxgdkcJo9Q8S6LmXTkvI+cLHGkQfA=="
+    },
     "node_modules/@vue/runtime-dom": {
-      "version": "3.4.27",
-      "resolved": "https://registry.npmmirror.com/@vue/runtime-dom/-/runtime-dom-3.4.27.tgz",
-      "integrity": "sha512-ScOmP70/3NPM+TW9hvVAz6VWWtZJqkbdf7w6ySsws+EsqtHvkhxaWLecrTorFxsawelM5Ys9FnDEMt6BPBDS0Q==",
+      "version": "3.5.6",
+      "resolved": "https://registry.npmmirror.com/@vue/runtime-dom/-/runtime-dom-3.5.6.tgz",
+      "integrity": "sha512-SDPseWre45G38ENH2zXRAHL1dw/rr5qp91lS4lt/nHvMr0MhsbCbihGAWLXNB/6VfFOJe2O+RBRkXU+CJF7/sw==",
       "dependencies": {
-        "@vue/runtime-core": "3.4.27",
-        "@vue/shared": "3.4.27",
+        "@vue/reactivity": "3.5.6",
+        "@vue/runtime-core": "3.5.6",
+        "@vue/shared": "3.5.6",
         "csstype": "^3.1.3"
       }
     },
+    "node_modules/@vue/runtime-dom/node_modules/@vue/shared": {
+      "version": "3.5.6",
+      "resolved": "https://registry.npmmirror.com/@vue/shared/-/shared-3.5.6.tgz",
+      "integrity": "sha512-eidH0HInnL39z6wAt6SFIwBrvGOpDWsDxlw3rCgo1B+CQ1781WzQUSU3YjxgdkcJo9Q8S6LmXTkvI+cLHGkQfA=="
+    },
     "node_modules/@vue/server-renderer": {
-      "version": "3.4.27",
-      "resolved": "https://registry.npmmirror.com/@vue/server-renderer/-/server-renderer-3.4.27.tgz",
-      "integrity": "sha512-dlAMEuvmeA3rJsOMJ2J1kXU7o7pOxgsNHVr9K8hB3ImIkSuBrIdy0vF66h8gf8Tuinf1TK3mPAz2+2sqyf3KzA==",
+      "version": "3.5.6",
+      "resolved": "https://registry.npmmirror.com/@vue/server-renderer/-/server-renderer-3.5.6.tgz",
+      "integrity": "sha512-zivnxQnOnwEXVaT9CstJ64rZFXMS5ZkKxCjDQKiMSvUhXRzFLWZVbaBiNF4HGDqGNNsTgmjcCSmU6TB/0OOxLA==",
       "dependencies": {
-        "@vue/compiler-ssr": "3.4.27",
-        "@vue/shared": "3.4.27"
+        "@vue/compiler-ssr": "3.5.6",
+        "@vue/shared": "3.5.6"
       },
       "peerDependencies": {
-        "vue": "3.4.27"
+        "vue": "3.5.6"
+      }
+    },
+    "node_modules/@vue/server-renderer/node_modules/@vue/compiler-core": {
+      "version": "3.5.6",
+      "resolved": "https://registry.npmmirror.com/@vue/compiler-core/-/compiler-core-3.5.6.tgz",
+      "integrity": "sha512-r+gNu6K4lrvaQLQGmf+1gc41p3FO2OUJyWmNqaIITaJU6YFiV5PtQSFZt8jfztYyARwqhoCayjprC7KMvT3nRA==",
+      "dependencies": {
+        "@babel/parser": "^7.25.3",
+        "@vue/shared": "3.5.6",
+        "entities": "^4.5.0",
+        "estree-walker": "^2.0.2",
+        "source-map-js": "^1.2.0"
+      }
+    },
+    "node_modules/@vue/server-renderer/node_modules/@vue/compiler-dom": {
+      "version": "3.5.6",
+      "resolved": "https://registry.npmmirror.com/@vue/compiler-dom/-/compiler-dom-3.5.6.tgz",
+      "integrity": "sha512-xRXqxDrIqK8v8sSScpistyYH0qYqxakpsIvqMD2e5sV/PXQ1mTwtXp4k42yHK06KXxKSmitop9e45Ui/3BrTEw==",
+      "dependencies": {
+        "@vue/compiler-core": "3.5.6",
+        "@vue/shared": "3.5.6"
+      }
+    },
+    "node_modules/@vue/server-renderer/node_modules/@vue/compiler-ssr": {
+      "version": "3.5.6",
+      "resolved": "https://registry.npmmirror.com/@vue/compiler-ssr/-/compiler-ssr-3.5.6.tgz",
+      "integrity": "sha512-VpWbaZrEOCqnmqjE83xdwegtr5qO/2OPUC6veWgvNqTJ3bYysz6vY3VqMuOijubuUYPRpG3OOKIh9TD0Stxb9A==",
+      "dependencies": {
+        "@vue/compiler-dom": "3.5.6",
+        "@vue/shared": "3.5.6"
+      }
+    },
+    "node_modules/@vue/server-renderer/node_modules/@vue/shared": {
+      "version": "3.5.6",
+      "resolved": "https://registry.npmmirror.com/@vue/shared/-/shared-3.5.6.tgz",
+      "integrity": "sha512-eidH0HInnL39z6wAt6SFIwBrvGOpDWsDxlw3rCgo1B+CQ1781WzQUSU3YjxgdkcJo9Q8S6LmXTkvI+cLHGkQfA=="
+    },
+    "node_modules/@vue/server-renderer/node_modules/entities": {
+      "version": "4.5.0",
+      "resolved": "https://registry.npmmirror.com/entities/-/entities-4.5.0.tgz",
+      "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
+      "engines": {
+        "node": ">=0.12"
+      },
+      "funding": {
+        "url": "https://github.com/fb55/entities?sponsor=1"
       }
     },
     "node_modules/@vue/shared": {
       "version": "3.4.27",
       "resolved": "https://registry.npmmirror.com/@vue/shared/-/shared-3.4.27.tgz",
-      "integrity": "sha512-DL3NmY2OFlqmYYrzp39yi3LDkKxa5vZVwxWdQ3rG0ekuWscHraeIbnI8t+aZK7qhYqEqWKTUdijadunb9pnrgA=="
+      "integrity": "sha512-DL3NmY2OFlqmYYrzp39yi3LDkKxa5vZVwxWdQ3rG0ekuWscHraeIbnI8t+aZK7qhYqEqWKTUdijadunb9pnrgA==",
+      "dev": true
     },
     "node_modules/@vue/vue-loader-v15": {
       "name": "vue-loader",
@@ -12334,15 +12402,15 @@
       }
     },
     "node_modules/vue": {
-      "version": "3.4.27",
-      "resolved": "https://registry.npmmirror.com/vue/-/vue-3.4.27.tgz",
-      "integrity": "sha512-8s/56uK6r01r1icG/aEOHqyMVxd1bkYcSe9j8HcKtr/xTOFWvnzIVTehNW+5Yt89f+DLBe4A569pnZLS5HzAMA==",
+      "version": "3.5.6",
+      "resolved": "https://registry.npmmirror.com/vue/-/vue-3.5.6.tgz",
+      "integrity": "sha512-zv+20E2VIYbcJOzJPUWp03NOGFhMmpCKOfSxVTmCYyYFFko48H9tmuQFzYj7tu4qX1AeXlp9DmhIP89/sSxxhw==",
       "dependencies": {
-        "@vue/compiler-dom": "3.4.27",
-        "@vue/compiler-sfc": "3.4.27",
-        "@vue/runtime-dom": "3.4.27",
-        "@vue/server-renderer": "3.4.27",
-        "@vue/shared": "3.4.27"
+        "@vue/compiler-dom": "3.5.6",
+        "@vue/compiler-sfc": "3.5.6",
+        "@vue/runtime-dom": "3.5.6",
+        "@vue/server-renderer": "3.5.6",
+        "@vue/shared": "3.5.6"
       },
       "peerDependencies": {
         "typescript": "*"
@@ -12471,6 +12539,68 @@
         "node": ">=10"
       }
     },
+    "node_modules/vue/node_modules/@vue/compiler-core": {
+      "version": "3.5.6",
+      "resolved": "https://registry.npmmirror.com/@vue/compiler-core/-/compiler-core-3.5.6.tgz",
+      "integrity": "sha512-r+gNu6K4lrvaQLQGmf+1gc41p3FO2OUJyWmNqaIITaJU6YFiV5PtQSFZt8jfztYyARwqhoCayjprC7KMvT3nRA==",
+      "dependencies": {
+        "@babel/parser": "^7.25.3",
+        "@vue/shared": "3.5.6",
+        "entities": "^4.5.0",
+        "estree-walker": "^2.0.2",
+        "source-map-js": "^1.2.0"
+      }
+    },
+    "node_modules/vue/node_modules/@vue/compiler-dom": {
+      "version": "3.5.6",
+      "resolved": "https://registry.npmmirror.com/@vue/compiler-dom/-/compiler-dom-3.5.6.tgz",
+      "integrity": "sha512-xRXqxDrIqK8v8sSScpistyYH0qYqxakpsIvqMD2e5sV/PXQ1mTwtXp4k42yHK06KXxKSmitop9e45Ui/3BrTEw==",
+      "dependencies": {
+        "@vue/compiler-core": "3.5.6",
+        "@vue/shared": "3.5.6"
+      }
+    },
+    "node_modules/vue/node_modules/@vue/compiler-sfc": {
+      "version": "3.5.6",
+      "resolved": "https://registry.npmmirror.com/@vue/compiler-sfc/-/compiler-sfc-3.5.6.tgz",
+      "integrity": "sha512-pjWJ8Kj9TDHlbF5LywjVso+BIxCY5wVOLhkEXRhuCHDxPFIeX1zaFefKs8RYoHvkSMqRWt93a0f2gNJVJixHwg==",
+      "dependencies": {
+        "@babel/parser": "^7.25.3",
+        "@vue/compiler-core": "3.5.6",
+        "@vue/compiler-dom": "3.5.6",
+        "@vue/compiler-ssr": "3.5.6",
+        "@vue/shared": "3.5.6",
+        "estree-walker": "^2.0.2",
+        "magic-string": "^0.30.11",
+        "postcss": "^8.4.47",
+        "source-map-js": "^1.2.0"
+      }
+    },
+    "node_modules/vue/node_modules/@vue/compiler-ssr": {
+      "version": "3.5.6",
+      "resolved": "https://registry.npmmirror.com/@vue/compiler-ssr/-/compiler-ssr-3.5.6.tgz",
+      "integrity": "sha512-VpWbaZrEOCqnmqjE83xdwegtr5qO/2OPUC6veWgvNqTJ3bYysz6vY3VqMuOijubuUYPRpG3OOKIh9TD0Stxb9A==",
+      "dependencies": {
+        "@vue/compiler-dom": "3.5.6",
+        "@vue/shared": "3.5.6"
+      }
+    },
+    "node_modules/vue/node_modules/@vue/shared": {
+      "version": "3.5.6",
+      "resolved": "https://registry.npmmirror.com/@vue/shared/-/shared-3.5.6.tgz",
+      "integrity": "sha512-eidH0HInnL39z6wAt6SFIwBrvGOpDWsDxlw3rCgo1B+CQ1781WzQUSU3YjxgdkcJo9Q8S6LmXTkvI+cLHGkQfA=="
+    },
+    "node_modules/vue/node_modules/entities": {
+      "version": "4.5.0",
+      "resolved": "https://registry.npmmirror.com/entities/-/entities-4.5.0.tgz",
+      "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
+      "engines": {
+        "node": ">=0.12"
+      },
+      "funding": {
+        "url": "https://github.com/fb55/entities?sponsor=1"
+      }
+    },
     "node_modules/vue3-json-viewer": {
       "version": "2.2.2",
       "resolved": "https://registry.npmmirror.com/vue3-json-viewer/-/vue3-json-viewer-2.2.2.tgz",

+ 4 - 4
package.json

@@ -37,7 +37,7 @@
     "pinia": "2.1.7",
     "qrcanvas": "3.1.2",
     "sortablejs": "1.15.2",
-    "vue": "3.4.27",
+    "vue": "^3.5.6",
     "vue-cropper": "^1.1.2",
     "vue-router": "4.0.16",
     "vue3-json-viewer": "2.2.2",
@@ -52,16 +52,16 @@
     "@types/node": "20.11.0",
     "@types/sortablejs": "^1.15.8",
     "@vitejs/plugin-vue": "5.0.4",
+    "@vitejs/plugin-vue-jsx": "^4.0.1",
     "@vue/cli-service": "5.0.8",
     "@vue/compiler-sfc": "3.4.27",
+    "prettier": "^3.3.3",
     "sass": "1.77.1",
     "unplugin-auto-import": "0.17.6",
     "unplugin-icons": "0.19.0",
     "vite": "5.2.11",
     "vite-plugin-mock": "3.0.2",
     "vite-plugin-vue-setup-extend": "0.4.0",
-    "vue-tsc": "2.0.17",
-    "@vitejs/plugin-vue-jsx": "^4.0.1",
-    "prettier": "^3.3.3"
+    "vue-tsc": "2.0.17"
   }
 }

+ 77 - 73
src/api/jian-yan-jie-kou/jian-yan-jie-kou.ts

@@ -1,89 +1,93 @@
 import requestV2 from "../../utils/request-v2";
 
-const URL = '/jianYanJieKou'
+const URL = "/jianYanJieKou";
 
 export interface SidebarData {
-    reportId: string;
-    // 检验名称
-    examPurpose: string;
-    trscDate: string;
-    reportType: string
+  reportId: string;
+  // 检验名称
+  examPurpose: string;
+  trscDate: string;
+  reportType: string;
 }
 
 export interface InspectionHeader {
-    ordr_usr_name: string;
-    ptnt_sex: string;
-    ptnt_age: string;
-    ptnt_age_unit: string;
-    ptnt_no: string;
-    dept_name: string;
-    ptnt_bed_no: string;
-    smpl_name: string;
-    aply_cntn: string;
-    aply_date: string;
-    ordr_create_date: string;
-    audt_time: string;
-    test_usr_name: string;
-    audt_usr_name: string;
-    ptnt_name: string
+  ordr_usr_name: string;
+  ptnt_sex: string;
+  ptnt_age: string;
+  ptnt_age_unit: string;
+  ptnt_no: string;
+  dept_name: string;
+  ptnt_bed_no: string;
+  smpl_name: string;
+  aply_cntn: string;
+  aply_date: string;
+  ordr_create_date: string;
+  audt_time: string;
+  test_usr_name: string;
+  audt_usr_name: string;
+  ptnt_name: string;
+  dvce_name: string;
 }
 
-
 export interface Measurement {
-    critical_exec_info: string;
-    critical_low: string;
-    critical_exec_flag: number;
-    range: string;
-    itm_src_value: string;
-    item_src_flow_id: number;
-    itm_name: string;
-    calc_fomula: string;
-    range_str: string;
-    rslt_list_id: number;
-    itm_id: number;
-    critical_exec_time: string;
-    prnt_grup: number;
-    is_num: number;
-    map_pis_code: string;
-    rslt_name: string;
-    itm_unit: string;
-    mthd_name: string;
-    defl_rslt_id: number;
-    is_null: number;
-    range_low: string;
-    itm_str_src_value: string;
-    range_high: string;
-    calc_type: number;
-    calc_fomula_items: string;
-    res_type: number;
-    itm_ordr: number;
-    itm_str_value: string;
-    critical_alert: string;
-    critical_high: string;
-    itm_alert: string;
-    dec_bit: number;
-    rslt_id: number;
-    range_rslt_id: number;
-    other_flag_a: number;
-    itm_code: string;
-    itm_value: string;
-    other_flag_c: number;
-    other_flag_b: number;
-    anti_list?: any[]
+  critical_exec_info: string;
+  critical_low: string;
+  critical_exec_flag: number;
+  range: string;
+  itm_src_value: string;
+  item_src_flow_id: number;
+  itm_name: string;
+  calc_fomula: string;
+  range_str: string;
+  rslt_list_id: number;
+  itm_id: number;
+  critical_exec_time: string;
+  prnt_grup: number;
+  is_num: number;
+  map_pis_code: string;
+  rslt_name: string;
+  itm_unit: string;
+  mthd_name: string;
+  defl_rslt_id: number;
+  is_null: number;
+  range_low: string;
+  itm_str_src_value: string;
+  range_high: string;
+  calc_type: number;
+  calc_fomula_items: string;
+  res_type: number;
+  itm_ordr: number;
+  itm_str_value: string;
+  critical_alert: string;
+  critical_high: string;
+  itm_alert: string;
+  dec_bit: number;
+  rslt_id: number;
+  range_rslt_id: number;
+  other_flag_a: number;
+  itm_code: string;
+  itm_value: string;
+  other_flag_c: number;
+  other_flag_b: number;
+  anti_list?: any[];
 }
 
-export function getNormal(data: { patientNum: string, startDate: string, endDate: string }) {
-    return requestV2<SidebarData[]>({
-        url: URL + '/getNormal',
-        method: 'post',
-        data,
-    })
+export function getNormal(data: {
+  patientNum: string;
+  startDate: string;
+  endDate: string;
+}) {
+  return requestV2<SidebarData[]>({
+    url: URL + "/getNormal",
+    method: "post",
+    data,
+  });
 }
 
 export function getDetail(reportId: string) {
-    return requestV2<{ order: InspectionHeader, items: Measurement[] }>({
-        url: URL + '/getDetail',
-        method: 'get',
-        params: {reportId}
-    })
+  return requestV2<{ order: InspectionHeader; items: Measurement[] }>({
+    url: URL + "/getDetail",
+    method: "get",
+    params: { reportId },
+  });
 }

+ 9 - 9
src/components/cy/CyDialog/index.ts

@@ -17,7 +17,6 @@ export interface DialogExpose {
   cancel: () => any | Promise<any>;
 }
 
-// eslint-disable-next-line @typescript-eslint/no-namespace
 export namespace UseDialog {
   export interface Expose extends DialogExpose {}
 
@@ -26,8 +25,10 @@ export namespace UseDialog {
   }
 }
 
-export interface DialogOptions {
+export interface DialogOptions<P = any> {
   dialogProps: DialogProps;
+  // @ts-ignore
+  params?: Parameters<P>[0];
   showCancel?: boolean;
   showConfirm?: boolean;
   cancelText?: string;
@@ -35,10 +36,6 @@ export interface DialogOptions {
   visible?: boolean;
   component?: any;
   componentRef?: DialogExpose;
-
-  propsData?: {
-    [key: string]: any;
-  };
 }
 
 export interface DialogState extends DialogOptions {
@@ -52,14 +49,17 @@ export interface DialogState extends DialogOptions {
 export const dialogStore = ref<DialogState[]>([]);
 export const dialogKey = ref(1);
 
-export function useDialog(component: any, props: DialogOptions) {
+export function useDialog<C = Component>(
+  component: C,
+  props: DialogOptions<C>
+) {
   return new Promise<any>((resolve, reject) => {
     props = {
       visible: true,
       component: shallowRef(component),
       showCancel: true,
       showConfirm: true,
-      ...props
+      ...props,
     };
     dialogKey.value++;
     dialogStore.value.push({
@@ -71,7 +71,7 @@ export function useDialog(component: any, props: DialogOptions) {
         reject(value);
       }),
       dialogKey: dialogKey.value,
-      closeValue: "close"
+      closeValue: "close",
     });
   });
 }

+ 22 - 24
src/components/cy/CyDialog/index.vue

@@ -1,15 +1,15 @@
 <script setup lang="ts">
-import {DialogState, dialogStore} from "./index";
-import {ElButton} from "element-plus";
+import { DialogState, dialogStore } from "./index";
+import { ElButton } from "element-plus";
 import XEUtils from "xe-utils";
 import sleep from "@/utils/sleep";
-import {nextTick} from "vue";
+import { nextTick } from "vue";
 
 function next(item: DialogState, data: any) {
   if (item.closeValue === "confirm") {
     item.resolve(data);
   } else {
-    item.reject({value: item.closeValue, data});
+    item.reject({ value: item.closeValue, data });
   }
   item.visible = false;
 }
@@ -25,8 +25,7 @@ async function handleCancel(item: DialogState, emits = false, value = null) {
     const data = await fn();
     item.closeValue = "cancel";
     next(item, data);
-  } catch {
-  }
+  } catch {}
 }
 
 async function handleConfirm(item: DialogState, emits = false, value = null) {
@@ -40,12 +39,11 @@ async function handleConfirm(item: DialogState, emits = false, value = null) {
     const data = await fn();
     item.closeValue = "confirm";
     next(item, data);
-  } catch {
-  }
+  } catch {}
 }
 
 async function closed(item: DialogState, index: number) {
-  item.reject({value: item.closeValue, data: null});
+  item.reject({ value: item.closeValue, data: null });
   await nextTick();
   await sleep();
   dialogStore.value.splice(index, 1);
@@ -58,19 +56,19 @@ function setRef(el, item) {
 
 <template>
   <el-dialog
-      v-for="(item, index) in dialogStore"
-      :key="`Cy-dialog_${item.dialogKey}`"
-      v-model="item.visible"
-      draggable
-      v-bind="item.dialogProps"
-      @closed="closed(item, index)"
+    v-for="(item, index) in dialogStore"
+    :key="`Cy-dialog_${item.dialogKey}`"
+    v-model="item.visible"
+    draggable
+    v-bind="item.dialogProps"
+    @closed="closed(item, index)"
   >
     <component
-        :is="item.component"
-        :ref="el => setRef(el, item)"
-        v-bind="item.propsData"
-        @cyDialogCancel="value => handleCancel(item, true, value)"
-        @cyDialogConfirm="value => handleConfirm(item, true, value)"
+      :is="item.component"
+      :ref="el => setRef(el, item)"
+      v-bind="item.params"
+      @cyDialogCancel="value => handleCancel(item, true, value)"
+      @cyDialogConfirm="value => handleConfirm(item, true, value)"
     />
 
     <template v-if="item.showCancel || item.showConfirm" #footer>
@@ -79,10 +77,10 @@ function setRef(el, item) {
       </el-button>
 
       <el-button
-          type="primary"
-          size="default"
-          color="hsl(240 5.9% 10%)"
-          @click="handleConfirm(item)"
+        type="primary"
+        size="default"
+        color="hsl(240 5.9% 10%)"
+        @click="handleConfirm(item)"
       >
         {{ item.confirmText || "确认" }}
       </el-button>

+ 223 - 215
src/components/cy/cy-monaco-editor/CyMonacoEditor.tsx

@@ -1,248 +1,256 @@
-import {defineComponent, nextTick, onMounted, PropType, ref} from "vue";
-import useCreateMonaco, {XcIStandaloneCodeEditor} from "@/utils/monaco-utlis/useCreateMonaco";
+import { defineComponent, nextTick, onMounted, PropType, ref } from "vue";
+import useCreateMonaco, {
+  XcIStandaloneCodeEditor,
+} from "@/utils/monaco-utlis/useCreateMonaco";
 import sleep from "@/utils/sleep";
 import setDialogToJs from "@/components/js-dialog-comp/useDialogToJs";
 import CyDialog from "@/components/cy/dialog/src/CyDialog.vue";
 import XEUtils from "xe-utils";
-import {BizException, ExceptionEnum} from "@/utils/BizException";
+import { BizException, ExceptionEnum } from "@/utils/BizException";
 import CyFlex from "@/components/cy/flex/src/CyFlex.vue";
-import {ElButton} from "element-plus";
+import { ElButton } from "element-plus";
 import * as monaco from "monaco-editor";
-import {IsCyDialog} from "@/components/cy/dialog/src/useCyDialog";
-import {tryOnBeforeUnmount} from "@vueuse/core";
+import { IsCyDialog } from "@/components/cy/dialog/src/useCyDialog";
+import { tryOnBeforeUnmount } from "@vueuse/core";
 
 export const JsonEditor = defineComponent({
-    name: 'JsonEditor',
-    props: {
-        data: [Object, String],
-        options: {
-            type: Object as PropType<monaco.editor.IStandaloneEditorConstructionOptions>
-        }
+  name: "JsonEditor",
+  props: {
+    data: [Object, String],
+    options: {
+      type: Object as PropType<monaco.editor.IStandaloneEditorConstructionOptions>,
     },
-    setup(props, {expose}) {
-        const divRef = ref<HTMLDivElement | null>(null)
-        let monacoEditor: XcIStandaloneCodeEditor
+  },
+  setup(props, { expose }) {
+    const divRef = ref<HTMLDivElement | null>(null);
+    let monacoEditor: XcIStandaloneCodeEditor;
 
-        function dispose() {
-            monacoEditor?.dispose()
-        }
+    function dispose() {
+      monacoEditor?.dispose();
+    }
 
-        onMounted(async () => {
-            await nextTick()
-            const tmpData = props.data == null ? "" : XEUtils.isString(props.data) ? props.data : JSON.stringify(props.data)
-
-            monacoEditor = useCreateMonaco(divRef.value, {
-                value: tmpData,
-                language: 'json',
-                ...props.options
-            })
-            await nextTick()
-            await sleep(200)
-            monacoEditor?.focus()
-            monacoEditor?.formatDocument()
-        })
-
-        tryOnBeforeUnmount(() => {
-            dispose()
-        })
-
-        expose({
-            getData() {
-                const data = monacoEditor?.getValue()
-                let json;
-                try {
-                    if (typeof data === "string" && data === "") {
-                        json = null
-                    } else {
-                        json = JSON.parse(typeof data === "string" ? data : "")
-                    }
-                } catch (e) {
-                    BizException(ExceptionEnum.MESSAGE_ERROR, `json格式错误请检查`)
-                }
-                return {
-                    jsonStr: data,
-                    json: json
-                };
-            },
-            dispose: dispose
-        })
-
-        return () => (
-            <div ref={divRef}
-                 style="height: 100%; width: 100%">
-            </div>
-        )
-    },
-})
+    onMounted(async () => {
+      await nextTick();
+      const tmpData =
+        props.data == null
+          ? ""
+          : XEUtils.isString(props.data)
+            ? props.data
+            : JSON.stringify(props.data);
 
-export const CodeEditor = defineComponent({
-    name: 'CodeEditor',
-    props: {
-        code: [Object, String],
-        type: String,
-        prompt: String,
-        testClick: Function
-    },
-    setup(props, {expose}) {
-        const FILE_PATH = 'file:///myLibrary.d.ts';
+      monacoEditor = useCreateMonaco(divRef.value, {
+        value: tmpData,
+        language: "json",
+        ...props.options,
+      });
+      await nextTick();
+      await sleep(200);
+      monacoEditor?.focus();
+      monacoEditor?.formatDocument();
+    });
 
-        const simulatedParametersRef = ref()
-        const simulatedParametersData = {
-            val: ""
+    tryOnBeforeUnmount(() => {
+      dispose();
+    });
+
+    expose({
+      getData() {
+        const data = monacoEditor?.getValue();
+        let json;
+        try {
+          if (typeof data === "string" && data === "") {
+            json = null;
+          } else {
+            json = JSON.parse(typeof data === "string" ? data : "");
+          }
+        } catch (e) {
+          BizException(ExceptionEnum.MESSAGE_ERROR, `json格式错误请检查`);
         }
+        return {
+          jsonStr: data,
+          json: json,
+        };
+      },
+      dispose: dispose,
+    });
 
-        const codeDivRef = ref()
-        let monacoEditor: XcIStandaloneCodeEditor = null
+    return () => <div ref={divRef} style="height: 100%; width: 100%"></div>;
+  },
+});
 
-        function clickText() {
-            // @ts-ignore
-            return props?.testClick(simulatedParametersRef.value.getData(false).json, monacoEditor!.getValue())
-        }
+export const CodeEditor = defineComponent({
+  name: "CodeEditor",
+  props: {
+    code: [Object, String],
+    type: String,
+    prompt: String,
+    testClick: Function,
+  },
+  setup(props, { expose }) {
+    const FILE_PATH = "file:///myLibrary.d.ts";
 
-        function dispose() {
-            monacoEditor?.dispose()
-        }
+    const simulatedParametersRef = ref();
+    const simulatedParametersData = {
+      val: "",
+    };
 
-        tryOnBeforeUnmount(() => {
-            dispose()
-        })
-
-        onMounted(async () => {
-            await nextTick()
-            monacoEditor = useCreateMonaco(codeDivRef.value, {
-                value: XEUtils.isString(props.code) ? props.code : JSON.stringify(props.code),
-                language: 'javascript',
-            })
-            await nextTick()
-            await sleep(200)
-            monaco.languages.typescript.javascriptDefaults.addExtraLib(props.type as string, FILE_PATH);
-            monacoEditor!.focus()
-        })
-
-        expose({
-            getData() {
-                return monacoEditor?.getValue()
-            },
-            dispose: dispose,
-            clickText: clickText
-        })
-
-        return () => {
-            return (
-                <div class="layout_h-w_max layout_display_flex">
-                    <div style="width: 35%; padding: 0 10px">
-                        <CyFlex>
-                            {{
-                                header() {
-                                    return [
-                                        <ElButton onClick={clickText}>
-                                            {{
-                                                default() {
-                                                    return '测试'
-                                                },
-                                            }}
-                                        </ElButton>,
-                                        <pre>{props.prompt}</pre>
-                                    ]
-                                },
-                                default() {
-                                    return <JsonEditor
-                                        options={{lineNumbers: 'off'}}
-                                        data={simulatedParametersData}
-                                        ref={simulatedParametersRef}
-                                    />
-                                },
-                            }}
-                        </CyFlex>
-                    </div>
-                    <div class="layout_flex_1-x" ref={codeDivRef}/>
-                </div>
-            )
-        }
+    const codeDivRef = ref();
+    let monacoEditor: XcIStandaloneCodeEditor = null;
+
+    function clickText() {
+      // @ts-ignore
+      return props?.testClick(
+        simulatedParametersRef.value.getData(false).json,
+        monacoEditor!.getValue()
+      );
     }
-})
+
+    function dispose() {
+      monacoEditor?.dispose();
+    }
+
+    tryOnBeforeUnmount(() => {
+      dispose();
+    });
+
+    onMounted(async () => {
+      await nextTick();
+      monacoEditor = useCreateMonaco(codeDivRef.value, {
+        value: XEUtils.isString(props.code)
+          ? props.code
+          : JSON.stringify(props.code),
+        language: "javascript",
+      });
+      await nextTick();
+      await sleep(200);
+      monaco.languages.typescript.javascriptDefaults.addExtraLib(
+        props.type as string,
+        FILE_PATH
+      );
+      monacoEditor!.focus();
+    });
+
+    expose({
+      getData() {
+        return monacoEditor?.getValue();
+      },
+      dispose: dispose,
+      clickText: clickText,
+    });
+
+    return () => {
+      return (
+        <div class="layout_h-w_max layout_display_flex">
+          <div style="width: 35%; padding: 0 10px">
+            <CyFlex>
+              {{
+                header() {
+                  return [
+                    <ElButton onClick={clickText}>
+                      {{
+                        default() {
+                          return "测试";
+                        },
+                      }}
+                    </ElButton>,
+                    <pre>{props.prompt}</pre>,
+                  ];
+                },
+                default() {
+                  return (
+                    <JsonEditor
+                      options={{ lineNumbers: "off" }}
+                      data={simulatedParametersData}
+                      ref={simulatedParametersRef}
+                    />
+                  );
+                },
+              }}
+            </CyFlex>
+          </div>
+          <div class="layout_flex_1-x" ref={codeDivRef} />
+        </div>
+      );
+    };
+  },
+});
 
 interface CodeProps {
-    code: string | object,
-    type?: string,
-    prompt?: string,
-    testClick: (value: any, code: string) => boolean
+  code: string | object;
+  type?: string;
+  prompt?: string;
+  testClick: (value: any, code: string) => boolean;
 }
 
-export function CyCodeEditorDialog(props: CodeProps, dialogProps?: Partial<IsCyDialog>): Promise<string> {
-    const codeRef = ref()
+export function CyCodeEditorDialog(
+  props: CodeProps,
+  dialogProps?: Partial<IsCyDialog>
+): Promise<string> {
+  const codeRef = ref();
 
-    function confirmClick(next: (arg0: any) => void) {
-        if (codeRef.value.clickText()) {
-            next(codeRef.value.getData())
-        }
+  function confirmClick(next: (arg0: any) => void) {
+    if (codeRef.value.clickText()) {
+      next(codeRef.value.getData());
     }
+  }
+
+  const Dialog = (
+    <CyDialog
+      bodyWidth="90%"
+      bodyHeight="calc(100vh - 300px)"
+      title="代码编辑"
+      {...dialogProps}
+      confirmClick={confirmClick}
+    >
+      {{
+        default: () => <CodeEditor ref={codeRef} {...props} />,
+      }}
+    </CyDialog>
+  );
 
-    const Dialog = (
-        <CyDialog
-            bodyWidth='90%'
-            bodyHeight='calc(100vh - 300px)'
-            title="代码编辑"
-            {...dialogProps}
-            confirmClick={confirmClick}
-        >
-            {{
-                default: () =>
-                    <CodeEditor
-                        ref={codeRef}
-                        {...props}/>
-                ,
-            }}
-        </CyDialog>
-    )
-
-    return new Promise<string>(resolve => {
-        setDialogToJs(Dialog, {}).then(res => {
-            resolve(res)
-        }).catch(() => {
-
-        })
-    })
+  return new Promise<string>(resolve => {
+    setDialogToJs(Dialog, {})
+      .then(res => {
+        resolve(res);
+      })
+      .catch(() => {});
+  });
 }
 
-export function CyJsonEditorDialog<T extends object>(json: T | string,
-                                                     dialogProps: IsCyDialog)
-    : Promise<{ jsonStr: string, json: T }> {
+export function CyJsonEditorDialog<T extends object>(
+  json: T | string,
+  dialogProps: IsCyDialog
+): Promise<{ jsonStr: string; json: T }> {
+  const defaultProps = {
+    bodyWidth: "60%",
+    ...dialogProps,
+  };
 
-    const defaultProps = {
-        bodyWidth: '60%',
-        ...dialogProps
-    }
+  const cyJsonEditorRef = ref();
 
-    const cyJsonEditorRef = ref()
+  function confirmClick(next: (data: any) => void) {
+    const data = cyJsonEditorRef.value.getData(false);
+    next(data);
+  }
 
-    function confirmClick(next: (data: any) => void) {
-        const data = cyJsonEditorRef.value.getData(false)
-        next(data)
-    }
+  const Dialog = (
+    <CyDialog
+      title="json编辑"
+      bodyHeight="50vh"
+      {...defaultProps}
+      confirmClick={confirmClick}
+    >
+      {{
+        default: () => <JsonEditor ref={cyJsonEditorRef} data={json} />,
+      }}
+    </CyDialog>
+  );
 
-    const Dialog = (
-        <CyDialog title='json编辑'
-                  bodyHeight='50vh'
-                  {...defaultProps}
-                  confirmClick={confirmClick}
-        >
-            {{
-                default: () => <JsonEditor
-                    ref={cyJsonEditorRef}
-                    data={json}
-                />
-            }}
-
-        </CyDialog>
-    )
-
-    return new Promise(resolve => {
-        setDialogToJs(Dialog, {data: json}).then((res) => {
-            resolve(res)
-        }).catch(() => {
-
-        })
-    })
+  return new Promise(resolve => {
+    setDialogToJs(Dialog, { data: json })
+      .then(res => {
+        resolve(res);
+      })
+      .catch(() => {});
+  });
 }
-

+ 6 - 12
src/components/cy/dialog/CyDialogTest.vue

@@ -1,22 +1,16 @@
 <script setup lang="ts">
-import {openDrugManual} from "@/views/hospitalization/zhu-yuan-yi-sheng/public-js/zhu-yuan-yi-sheng";
+import { openDrugManual } from "@/views/hospitalization/zhu-yuan-yi-sheng/public-js/zhu-yuan-yi-sheng";
 import CyDialog from "@/components/cy/dialog/src/CyDialog.vue";
 
 function open() {
-  openDrugManual('01195', '01').then(res => {
-  }).catch(res => {
-  })
+  openDrugManual("01195", "01")
+    .then(res => {})
+    .catch(res => {});
 }
 </script>
 
 <template>
-  <el-button @click="open">
-    打开
-  </el-button>
-
-
+  <el-button @click="open"> 打开 </el-button>
 </template>
 
-<style scoped lang="scss">
-
-</style>
+<style scoped lang="scss"></style>

+ 49 - 39
src/components/js-dialog-comp/useDialogToJs.ts

@@ -1,52 +1,62 @@
-import {h, ref} from 'vue';
-import {generateRandomString} from "@/utils/getUuid";
+import { h, ref } from "vue";
+import { generateRandomString } from "@/utils/getUuid";
 
 export enum ClosingMethod {
-    CONFIRM = 'confirm',
-    CANCEL = 'cancel'
+  CONFIRM = "confirm",
+  CANCEL = "cancel",
 }
 
 export const dialogEmits = {
-    ['closed']: (closingMethod: ClosingMethod, ...val: any[]) => closingMethod && val
-}
+  ["closed"]: (closingMethod: ClosingMethod, ...val: any[]) =>
+    closingMethod && val,
+};
 
 export const compList = ref<{
-    [key: string]: {
-        onClosed(closingMethod: ClosingMethod, val: any): unknown;
-        comp: any
-    }
-}>({})
+  [key: string]: {
+    onClosed(closingMethod: ClosingMethod, val: any): unknown;
+    comp: any;
+  };
+}>({});
 
-function setDialogToJs<T extends abstract new(...args: any) => any>(comp: T, data: InstanceType<T>['$props']) {
-    return new Promise<any>((resolve, reject) => {
-        const id = "cy-dialog_js__" + generateRandomString(5)
+/**
+ * @deprecated 请使用 useDialog 方法
+ * @see useDialog
+ * @param comp 组件
+ * @param data 数据
+ */
+function setDialogToJs<T extends abstract new (...args: any) => any>(
+  comp: T | any,
+  data: InstanceType<T>["$props"]
+) {
+  return new Promise<any>((resolve, reject) => {
+    const id = "cy-dialog_js__" + generateRandomString(5);
 
-        function del() {
-            delete compList.value[id]
-        }
+    function del() {
+      delete compList.value[id];
+    }
 
-        const props = {
-            onClosed: (closingMethod: ClosingMethod, val: any) => {
-                if (closingMethod === ClosingMethod.CONFIRM) {
-                    resolve(val)
-                } else if (closingMethod === ClosingMethod.CANCEL) {
-                    reject(val)
-                } else {
-                    reject('使用该功能第一个参数需要为 ClosingMethod 枚举')
-                    console.error('使用该功能第一个参数需要为 ClosingMethod 枚举')
-                }
-                del()
-            },
-            id,
-            ...data
-        }
-        compList.value[id] = {
-            // @ts-ignore
-            comp: h(comp, props),
-            // @ts-ignore
-            onClosed: props.onClosed
+    const props = {
+      onClosed: (closingMethod: ClosingMethod, val: any) => {
+        if (closingMethod === ClosingMethod.CONFIRM) {
+          resolve(val);
+        } else if (closingMethod === ClosingMethod.CANCEL) {
+          reject(val);
+        } else {
+          reject("使用该功能第一个参数需要为 ClosingMethod 枚举");
+          console.error("使用该功能第一个参数需要为 ClosingMethod 枚举");
         }
-    })
+        del();
+      },
+      id,
+      ...data,
+    };
+    compList.value[id] = {
+      // @ts-ignore
+      comp: h(comp, props),
+      // @ts-ignore
+      onClosed: props.onClosed,
+    };
+  });
 }
 
-export default setDialogToJs
+export default setDialogToJs;

+ 109 - 103
src/layout/MenuV2/MenuV2.vue

@@ -1,30 +1,31 @@
 <template>
   <div class="floating">
-    <div
-        style="height: 30px; padding: 0 8px 8px 8px"
-        @click="expandMenu">
+    <div style="height: 30px; padding: 0 8px 8px 8px" @click="expandMenu">
       <el-input
-          ref="searchRef"
-          v-model="menuText"
-          prefix-icon="Search"
-          clearable
-          @input="searchInput"
-          placeholder="菜单太难找?在这里搜索。"/>
+        ref="searchRef"
+        v-model="menuText"
+        prefix-icon="Search"
+        clearable
+        @input="searchInput"
+        placeholder="菜单太难找?在这里搜索。"
+      />
     </div>
 
     <div class="layout_flex_1-y">
       <el-scrollbar>
         <el-menu
-            ref="menuRef"
-            :collapse-transition="false"
-            :collapse="isCollapse"
-            :default-active="isSearch ? '' : activeMenu"
-            :unique-opened="isSearch ? false : expandOneMenu">
+          ref="menuRef"
+          :collapse-transition="false"
+          :collapse="isCollapse"
+          :default-active="isSearch ? '' : activeMenu"
+          :unique-opened="isSearch ? false : expandOneMenu"
+        >
           <template v-for="item in isSearch ? searchData : menuData">
             <menu-item-v2
-                :data="item"
-                v-if="item?.metaShowMenu"
-                :menuText="menuText"/>
+              :data="item"
+              v-if="item?.metaShowMenu"
+              :menuText="menuText"
+            />
           </template>
         </el-menu>
       </el-scrollbar>
@@ -34,127 +35,133 @@
 
 <script setup lang="ts">
 import MenuItemV2 from "./MenuItemV2.vue";
-import {computed, nextTick, onMounted, Ref, ref, watch} from "vue";
-import {useRoute} from "vue-router";
+import { computed, nextTick, onMounted, Ref, ref, watch } from "vue";
+import { useRoute } from "vue-router";
 import XEUtils from "xe-utils";
-import router, {routerMenus} from '@/router'
+import router, { routerMenus } from "@/router";
 import sleep from "@/utils/sleep";
-import {useCompRef} from "@/utils/useCompRef";
-import {ElMenu} from "element-plus";
-import {useSystemStore} from "@/pinia/system-store";
-import {stringNotBlank} from "@/utils/blank-utils";
+import { useCompRef } from "@/utils/useCompRef";
+import { ElMenu } from "element-plus";
+import { useSystemStore } from "@/pinia/system-store";
+import { stringNotBlank } from "@/utils/blank-utils";
 
 defineProps<{
-  type: 'default' | 'fillet'
-}>()
+  type: "default" | "fillet";
+}>();
 
-const menuText: Ref<string> = ref('')
-const menuRef = useCompRef(ElMenu)
+const menuText: Ref<string> = ref("");
+const menuRef = useCompRef(ElMenu);
 const menuData = computed(() => {
-  return routerMenus.value
-})
-const isSearch = ref<boolean>(false)
-const searchData = ref([])
-const searchActives = new Set()
-
-const searchInput: (val: string) => void = XEUtils.debounce(async (val: string) => {
-  menuText.value = val;
-  searchActives.clear();
-
-  if (val) {
-    searchData.value = XEUtils.treeSearch(menuData.value, (item) => {
-      const {metaTitle} = item
-      if (stringNotBlank(metaTitle)) {
-        return metaTitle.includes(val);
-      }
-      return false
-    });
-    isSearch.value = true
-    await nextTick()
-    expandNodes(searchData.value)
-  } else {
-    searchData.value = []
-    await nextTick()
-    isSearch.value = false
-    smoothScrolling()
-  }
-}, 500)
+  return routerMenus.value;
+});
+const isSearch = ref<boolean>(false);
+const searchData = ref([]);
+const searchActives = new Set();
+
+const searchInput: (val: string) => void = XEUtils.debounce(
+  async (val: string) => {
+    menuText.value = val;
+    searchActives.clear();
+
+    if (val) {
+      searchData.value = XEUtils.treeSearch(menuData.value, item => {
+        const { metaTitle } = item;
+        if (stringNotBlank(metaTitle)) {
+          return metaTitle.includes(val);
+        }
+        return false;
+      });
+      isSearch.value = true;
+      await nextTick();
+      expandNodes(searchData.value);
+    } else {
+      searchData.value = [];
+      await nextTick();
+      isSearch.value = false;
+      smoothScrolling();
+    }
+  },
+  500
+);
 
-const expandNodes = (treeData) => {
+const expandNodes = treeData => {
   const traverse = tempData => {
-    XEUtils.arrayEach(tempData, (item) => {
+    XEUtils.arrayEach(tempData, item => {
       if (item.children !== null && item.children.length > 0) {
-        menuLaunch(item.name)
+        menuLaunch(item.name);
         traverse(item.children);
       }
-    })
-  }
-  traverse(treeData)
-}
+    });
+  };
+  traverse(treeData);
+};
 
 const menuLaunch = async (path: string) => {
   await nextTick();
   const li = document.getElementById(path);
   const div = li!.children[0];
-  const icon = div.getElementsByClassName('el-icon el-sub-menu__icon-arrow');
+  const icon = div.getElementsByClassName("el-icon el-sub-menu__icon-arrow");
   // @ts-ignore
-  if (icon.item(0).style.transform === 'none') {
+  if (icon.item(0).style.transform === "none") {
     try {
       // @ts-ignore
       div!.click();
-    } catch (e) {
-    }
+    } catch (e) {}
   }
-}
+};
 
-const systemStore = useSystemStore()
-const expandOneMenu = computed<boolean>(() => systemStore.expandOneMenu)
-const route = useRoute()
-const isCollapse = computed<boolean>(() => systemStore.getCollapse)
+const systemStore = useSystemStore();
+const expandOneMenu = computed<boolean>(() => systemStore.expandOneMenu);
+const route = useRoute();
+const isCollapse = computed<boolean>(() => systemStore.getCollapse);
 
 const expandMenu = () => {
   if (isCollapse.value) {
-    systemStore.setCollapse(false)
+    systemStore.setCollapse(false);
     setTimeout(() => {
-      searchRef.value!.focus()
-    }, 100)
+      searchRef.value!.focus();
+    }, 100);
   }
-}
+};
 
-const searchRef: Ref<HTMLHeadElement | null> = ref(null)
+const searchRef: Ref<HTMLHeadElement | null> = ref(null);
 
 const activeMenu = computed<string>(() => {
-  const {meta, path} = route
-  if (meta['activeMenu']) {
-    return meta['activeMenu'] as string
+  const { meta, path } = route;
+  if (meta["activeMenu"]) {
+    return meta["activeMenu"] as string;
   }
-  return path
-})
+  return path;
+});
 
 const smoothScrolling = () => {
-  const routerPath = document.getElementById(<string>router.currentRoute.value.name)
-  if (!routerPath) return
+  const routerPath = document.getElementById(
+    <string>router.currentRoute.value.name
+  );
+  if (!routerPath) return;
   routerPath.scrollIntoView({
-    block: 'center',
-    inline: 'nearest',
-    behavior: 'smooth'
-  })
-}
-
-watch(() => router.currentRoute.value, async () => {
-  menuText.value = ''
-  isSearch.value = false
-  await nextTick()
-  await sleep(200)
-  smoothScrolling()
-})
-
+    block: "center",
+    inline: "nearest",
+    behavior: "smooth",
+  });
+};
+
+watch(
+  () => router.currentRoute.value,
+  async () => {
+    menuText.value = "";
+    isSearch.value = false;
+    await nextTick();
+    await sleep(200);
+    smoothScrolling();
+  }
+);
 
 onMounted(async () => {
-  await nextTick()
-  await sleep(500)
-  smoothScrolling()
-})
+  await nextTick();
+  await sleep(500);
+  smoothScrolling();
+});
 </script>
 
 <style scoped lang="scss">
@@ -173,7 +180,6 @@ onMounted(async () => {
   .menu {
     overflow: auto;
   }
-
 }
 
 :deep(.el-sub-menu__title) {

+ 312 - 265
src/utils/emr/edit.ts

@@ -1,312 +1,359 @@
 interface Document {
-    categoryId: string;
-    _id: string;
-    valid: number;
-    properties: any;
-    styles: any;
-    scripts: any;
-    layout: any;
-    document: any;
+  categoryId: string;
+  _id: string;
+  valid: number;
+  properties: any;
+  styles: any;
+  scripts: any;
+  layout: any;
+  document: any;
 }
 
 interface Validator {
-    name: string;
-    level: string;
-    message: string;
+  name: string;
+  level: string;
+  message: string;
 }
 
-export type EditorMode = 'form' | 'free' | 'readonly' | 'design';
+export type EditorMode = "form" | "free" | "readonly" | "design";
 
 export interface DataElements {
-    [key: string]: {
-        id: string;
-        value: any | null;
-        element: {
-            id: string;
-            type: string;
-            name: string;
-            code: { internal: string, dataElement: string };
-            labels: null;
-            attributes: [];
-        },
-    }
+  [key: string]: {
+    id: string;
+    value: any | null;
+    element: {
+      id: string;
+      type: string;
+      name: string;
+      code: { internal: string; dataElement: string };
+      labels: null;
+      attributes: [];
+    };
+  };
 }
 
-type CursorPlace = 'PARAGRAPH_START' | 'PARAGRAPH_END' | 'DOCUMENT_START' | 'DOCUMENT_END';
+type CursorPlace =
+  | "PARAGRAPH_START"
+  | "PARAGRAPH_END"
+  | "DOCUMENT_START"
+  | "DOCUMENT_END";
 
 interface MenuItem {
-    global: {
-        text: string;
-        menu?: {
-            items: MenuItem[];
-        };
-        handler?: (menu?: any) => void;
-    }[]
+  global: {
+    text: string;
+    menu?: {
+      items: MenuItem[];
+    };
+    handler?: (menu?: any) => void;
+  }[];
 }
 
 interface NodesByCode {
-    target: {
-        setReadonly: (val: boolean) => void;
-        setDeletable: (val: boolean) => void;
-    }
+  target: {
+    setReadonly: (val: boolean) => void;
+    setDeletable: (val: boolean) => void;
+  };
 }
 
 interface ElementByValue extends HTMLElement {
-
-    /**
-     * 元素聚焦
-     */
-    focusEnter: () => void
+  /**
+   * 元素聚焦
+   */
+  focusEnter: () => void;
 }
 
 export declare type EditType = {
-
-    isRevisionMode: boolean;
-
-    documentData: {
-        _id: string,
-        categoryId: string
-    }
-
-    _cacheDB: IDBTransaction;
-
-    loadCacheData: (val: string) => any
-    delCacheData: (val: string) => any
-
-    setCacheData: (val: string) => any
-
-    openCache: () => void
-
-    _cacheDBIsOpen: boolean;
-
-    on: (name: string, callback: (...args: any[]) => void) => void
-
-    /**
-     * 用于获取当前病历完整数据 该方法通常用于保存病历数据时调用
-     *
-     * 参数:无
-     * 返回值:返回json结构,参见:文档结构。
-     * 业务系统可在保存前对其内容进行修改。
-     */
-    getDocument: () => Document;
-
-    getEditorMode: () => EditorMode;
-
-    highlight: (comp: HTMLElement, time: number) => void;
-
-    getElementsData: () => {
-        [key: string]: any;
-    }
-
-    getElementByValue: (id: string, value?: any) => ElementByValue;
-
-    view: HTMLElement;
-
-    ModelService: {
-        setWalkerRoot: (walker: any, node: any) => any;
-        createTreeWalker: (node: any) => any;
-        getDataElementsFromWalker: (walker: any, name: string, value: string) => any
-        getElementsDataFromWalker: (walker: any, name?: string) => any
-    };
-
-    setEditorMode: (val: EditorMode) => void;
-
-    getValidator: () => {
-
-        /**
-         *
-         * @param val 是否显示节点信息 , 默认值 false
-         */
-        valid: (val: boolean) => Validator[]
+  EMR: {
+    getDocument(): {
+      getTablesByCode: (id: string) => any[];
     };
+  };
 
-    /**
-     * {Boolean} includeEmptyValue 是否获取非必填并且不是数据元 值为空的元素 默认 false
-     * @param val type 要获取的编码类型 默认 code。  code|business|internal|dataElement, 一般不用dataElement,当指定的编码类型不存在时返回 code
-     */
-    getDataElements: (val: 'code' | 'business' | 'internal' | 'dataElement', a?: boolean, b?: boolean) => DataElements;
+  isRevisionMode: boolean;
 
-    /**
-     * 批量设置组件值
-     *
-     * 适用组件:智能文本框(smarttext)、复选框(checkfield)
-     * 参数:
-     * {Object}      data  要设置的key/value对象 同getAppContext中的data节点
-     * {Boolean}    overwrite 是否覆盖原来的值 默认true
-     * {Boolean}.   commandStack 是否进入撤销命令栈 默认true。当setValues在一个操作命令中调用的时候commandStack设置为false和合并父操作的命令栈 例如插入片段事件/或设置值后出发的change事件
-     * {DocumentFragment} documdentFragment插入的文档片段模型,为空时将值填充到整个文档,不为空时将值填充到文档片段
-     * 返回值 无
-     * @param val
-     */
-    setValues: (val: object, overwrite?: boolean, commandStack?: boolean, documentFragment?: object) => void;
+  documentData: {
+    _id: string;
+    categoryId: string;
+  };
 
-    getComponents: () => any[]
+  _cacheDB: IDBTransaction;
 
-    /**
-     * editor.execute(commandName,[...args])
-     *
-     * 执行编辑器命令
-     *
-     * 参数
-     * @param name commandName 命令名称
-     * @param value args 执行命令携带的参数
-     */
-    execute: (name: string | 'insertContents', ...value: any[]) => void;
+  loadCacheData: (val: string) => any;
+  delCacheData: (val: string) => any;
 
-    /**
-     * 移动光标到place 指定位置
-     *
-     * 参数:
-     * {string} place   PARAGRAPH_START | PARAGRAPH_END | DOCUMENT_START | DOCUMENT_END
-     * PARAGRAPH_START:移动光标到当前段落开头
-     * PARAGRAPH_END:移动光标到当前段落结尾
-     * DOCUMENT_START:移动光标到文档开头
-     * DOCUMENT_END:移动光标到文档结尾
-     * 返回值:undefined
-     * @param place
-     */
-    setCursor: (place: CursorPlace) => void;
+  setCacheData: (val: string) => any;
 
-    /**
-     *  滚动到当前光标所在位置
-     *
-     *   editor.scrollToCursor([middle])
-     *
-     * @param middle middle 当光标在可视区域后方时,是否滚动到屏幕中间 默认false
-     */
-    scrollToCursor: (...middle: boolean[]) => void;
-
-    model: {
-        document: {
-            getRoot: () => {
-                getChild: (val: number) => {
-                    view: any
-                },
-                childCount: number,
-                getChildren: any
-            }
-        }
-    }
+  openCache: () => void;
 
-    /**
-     * 设置审阅模式
-     *
-     * 参数
-     * {String} mode 接收 on:开启审阅模式,off:关闭审阅模式
-     * 开启审阅模式后,病历上的修改会被记录下来,默认开启后,页面上没有任何表现,需要通过调用editor.setRevisionShowMode(flag) 展示修改
-     */
-    setRevisionMode: (val: 'on' | 'off') => void;
+  _cacheDBIsOpen: boolean;
 
-    /**
-     * 设置审阅模式的展现方式
-     * @param val flag可接受的值如下
-     * 0: 页面上不显示修改记录
-     * 1: 病历右侧会以列表的形式显示 添加,删除,更新的记录
-     * 2: 嵌入病历显示修改记录,新增的记录会用背景颜色标记,删除的记录 通过画删除线标记
-     */
-    setRevisionShowMode: (val: 0 | 1 | 2 | number) => void;
+  on: (name: string, callback: (...args: any[]) => void) => void;
 
-    getScriptRuntime: () => {
-        EMR: {
-            getDocument: () => {
-                getNodesByCode: (val: any, name: string) => NodesByCode[],
-                getComponentsByCode: (name: string) => any[]
-            };
-        }
-    }
+  /**
+   * 用于获取当前病历完整数据 该方法通常用于保存病历数据时调用
+   *
+   * 参数:无
+   * 返回值:返回json结构,参见:文档结构。
+   * 业务系统可在保存前对其内容进行修改。
+   */
+  getDocument: () => Document;
 
-    getViewByElType: (value: any, name: string) => any
+  getEditorMode: () => EditorMode;
 
-    /**
-     * 自定义编辑器快捷键
-     *
-     * 参数
-     * {Function} callback
-     * @param keyName 绑定快捷键
-     * @param callback 快捷键触发函数 该函数接受3个参数  evt:事件
-     * view: 当前光标或者选区开始所在位置的组件view
-     * position: {x ,y} 光标或者选区开始位置坐标(相对于文档,内部通过getBoundingClientRect()方法获取)
-     */
-    setShortcutKey: (keyName: string, callback: (e: Event, view: any, position: {
-        x: number,
-        y: number
-    }) => void) => void;
+  highlight: (comp: HTMLElement, time: number) => void;
 
-    /**
-     * 注册右键菜单
-     * @param menuItem 数据
-     */
-    regCtxMenu: (menuItem: MenuItem) => void;
+  getElementsData: () => {
+    [key: string]: any;
+  };
 
-    /**
-     * 获取鼠标位置
-     */
-    getCursorPosition: () => { x: number, y: number }
+  getElementByValue: (id: string, value?: any) => ElementByValue;
 
+  view: HTMLElement & {
+    container: {
+      find: (id: string) => any[];
+    };
+  };
+
+  ModelService: {
+    setWalkerRoot: (walker: any, node: any) => any;
+    createTreeWalker: (node: any) => any;
+    getDataElementsFromWalker: (
+      walker: any,
+      name: string,
+      value: string
+    ) => any;
+    getElementsDataFromWalker: (walker: any, name?: string) => any;
+  };
+
+  setEditorMode: (val: EditorMode) => void;
+
+  getValidator: () => {
     /**
-     * 用于设置当前病历文档完整数据
      *
-     * 参数
-     * @param data 完整的病历文档结构。
-     * @param isRender 是否根据文档结构进行立即渲染页面,如果为false 则只设置文档数据不进行渲染操作
-     * @param clearUndoStack 是否清空撤销栈
-     */
-    setDocument: (data: any, isRender?: boolean, clearUndoStack?: boolean) => void;
-
-    /**
-     * 设置实时分页
-     * @param isPaginate true:开启实时分页  false:关闭实时分页
-     */
-    setPaginate: (isPaginate: boolean) => void;
-
-    renderer: {
-        pageView: {
-            marginTopWithPaging: number
-            /**
-             * 重新绘制页面布局
-             */
-            attachLayout: () => void
-        }
-    }
-
-    /**
-     * 获取大纲的树状图
-     */
-    getOutline: () => Outline[];
-
-
-    /**
-     * 设置 setApplicatioinContext
-     * @param data 数据
-     * @param filling 是否填充
-     * @param forcedReplacement 是否强制替换
+     * @param val 是否显示节点信息 , 默认值 false
      */
-    setApplicationContext: (data: any, filling: boolean, forcedReplacement: boolean) => void
-}
+    valid: (val: boolean) => Validator[];
+  };
+
+  /**
+   * {Boolean} includeEmptyValue 是否获取非必填并且不是数据元 值为空的元素 默认 false
+   * @param val type 要获取的编码类型 默认 code。  code|business|internal|dataElement, 一般不用dataElement,当指定的编码类型不存在时返回 code
+   */
+  getDataElements: (
+    val: "code" | "business" | "internal" | "dataElement",
+    a?: boolean,
+    b?: boolean
+  ) => DataElements;
+
+  /**
+   * 批量设置组件值
+   *
+   * 适用组件:智能文本框(smarttext)、复选框(checkfield)
+   * 参数:
+   * {Object}      data  要设置的key/value对象 同getAppContext中的data节点
+   * {Boolean}    overwrite 是否覆盖原来的值 默认true
+   * {Boolean}.   commandStack 是否进入撤销命令栈 默认true。当setValues在一个操作命令中调用的时候commandStack设置为false和合并父操作的命令栈 例如插入片段事件/或设置值后出发的change事件
+   * {DocumentFragment} documdentFragment插入的文档片段模型,为空时将值填充到整个文档,不为空时将值填充到文档片段
+   * 返回值 无
+   * @param val
+   */
+  setValues: (
+    val: object,
+    overwrite?: boolean,
+    commandStack?: boolean,
+    documentFragment?: object
+  ) => void;
+
+  getComponents: () => any[];
+
+  /**
+   * editor.execute(commandName,[...args])
+   *
+   * 执行编辑器命令
+   *
+   * 参数
+   * @param name commandName 命令名称
+   * @param value args 执行命令携带的参数
+   */
+  execute: (name: string | "insertContents", ...value: any[]) => void;
+
+  /**
+   * 移动光标到place 指定位置
+   *
+   * 参数:
+   * {string} place   PARAGRAPH_START | PARAGRAPH_END | DOCUMENT_START | DOCUMENT_END
+   * PARAGRAPH_START:移动光标到当前段落开头
+   * PARAGRAPH_END:移动光标到当前段落结尾
+   * DOCUMENT_START:移动光标到文档开头
+   * DOCUMENT_END:移动光标到文档结尾
+   * 返回值:undefined
+   * @param place
+   */
+  setCursor: (place: CursorPlace) => void;
+
+  /**
+   *  滚动到当前光标所在位置
+   *
+   *   editor.scrollToCursor([middle])
+   *
+   * @param middle middle 当光标在可视区域后方时,是否滚动到屏幕中间 默认false
+   */
+  scrollToCursor: (...middle: boolean[]) => void;
+
+  model: {
+    document: {
+      getRoot: () => {
+        getChild: (val: number) => {
+          view: any;
+        };
+        childCount: number;
+        getChildren: any;
+      };
+    };
+  };
+
+  /**
+   * 设置审阅模式
+   *
+   * 参数
+   * {String} mode 接收 on:开启审阅模式,off:关闭审阅模式
+   * 开启审阅模式后,病历上的修改会被记录下来,默认开启后,页面上没有任何表现,需要通过调用editor.setRevisionShowMode(flag) 展示修改
+   */
+  setRevisionMode: (val: "on" | "off") => void;
+
+  /**
+   * 设置审阅模式的展现方式
+   * @param val flag可接受的值如下
+   * 0: 页面上不显示修改记录
+   * 1: 病历右侧会以列表的形式显示 添加,删除,更新的记录
+   * 2: 嵌入病历显示修改记录,新增的记录会用背景颜色标记,删除的记录 通过画删除线标记
+   */
+  setRevisionShowMode: (val: 0 | 1 | 2 | number) => void;
+
+  getScriptRuntime: () => {
+    EMR: {
+      getDocument: () => {
+        getNodesByCode: (val: any, name: string) => NodesByCode[];
+        getComponentsByCode: (name: string) => any[];
+      };
+    };
+  };
+
+  getViewByElType: (value: any, name: string) => any;
+
+  /**
+   * 自定义编辑器快捷键
+   *
+   * 参数
+   * {Function} callback
+   * @param keyName 绑定快捷键
+   * @param callback 快捷键触发函数 该函数接受3个参数  evt:事件
+   * view: 当前光标或者选区开始所在位置的组件view
+   * position: {x ,y} 光标或者选区开始位置坐标(相对于文档,内部通过getBoundingClientRect()方法获取)
+   */
+  setShortcutKey: (
+    keyName: string,
+    callback: (
+      e: Event,
+      view: any,
+      position: {
+        x: number;
+        y: number;
+      }
+    ) => void
+  ) => void;
+
+  /**
+   * 注册右键菜单
+   * @param menuItem 数据
+   */
+  regCtxMenu: (menuItem: MenuItem) => void;
+
+  /**
+   * 获取鼠标位置
+   */
+  getCursorPosition: () => { x: number; y: number };
+
+  /**
+   * 用于设置当前病历文档完整数据
+   *
+   * 参数
+   * @param data 完整的病历文档结构。
+   * @param isRender 是否根据文档结构进行立即渲染页面,如果为false 则只设置文档数据不进行渲染操作
+   * @param clearUndoStack 是否清空撤销栈
+   */
+  setDocument: (
+    data: any,
+    isRender?: boolean,
+    clearUndoStack?: boolean
+  ) => void;
+
+  /**
+   * 设置实时分页
+   * @param isPaginate true:开启实时分页  false:关闭实时分页
+   */
+  setPaginate: (isPaginate: boolean) => void;
+
+  renderer: {
+    pageView: {
+      marginTopWithPaging: number;
+      /**
+       * 重新绘制页面布局
+       */
+      attachLayout: () => void;
+
+      fixEmpty: () => void;
+    };
+  };
+
+  /**
+   * 获取大纲的树状图
+   */
+  getOutline: () => Outline[];
+
+  /**
+   * 设置 setApplicatioinContext
+   * @param data 数据
+   * @param filling 是否填充
+   * @param forcedReplacement 是否强制替换
+   */
+  setApplicationContext: (
+    data: any,
+    filling: boolean,
+    forcedReplacement: boolean
+  ) => void;
+};
 
 export declare type Runtime = {
-    saveDocument: (document: any, success: (res?: any) => void, error: (err?: any) => void) => void;
-    loadDocument: (success: (res?: any) => void, error: (err?: any) => void, param: any) => void;
-}
-
+  saveDocument: (
+    document: any,
+    success: (res?: any) => void,
+    error: (err?: any) => void
+  ) => void;
+  loadDocument: (
+    success: (res?: any) => void,
+    error: (err?: any) => void,
+    param: any
+  ) => void;
+};
 
 export interface Outline {
+  id: string;
+  type: string;
+  typeName: string;
+  text: string;
+  parent: string;
+  business: string;
+  children: {
+    business: string;
+    code: string;
+    dataElement: string;
     id: string;
+    internal: string;
+    leaf: boolean;
+    parent: string;
+    text: string;
     type: string;
     typeName: string;
-    text: string;
-    parent: string
-    business: string
-    children: {
-        business: string;
-        code: string;
-        dataElement: string;
-        id: string;
-        internal: string;
-        leaf: boolean
-        parent: string;
-        text: string
-        type: string
-        typeName: string
-    }[]
+  }[];
 }

+ 901 - 0
src/utils/emr/use/useEmrJianYan.ts

@@ -0,0 +1,901 @@
+import { EditType } from "@/utils/emr/edit";
+import type {
+  InspectionHeader,
+  Measurement,
+} from "@/api/jian-yan-jie-kou/jian-yan-jie-kou";
+import XEUtils from "xe-utils";
+
+type CreateData = {
+  data: {
+    order: InspectionHeader;
+    items: Measurement[];
+  };
+  id: string;
+};
+
+type CreateState = "UPDATE" | "INSERT";
+
+function getItemStr(val, strValue, value) {
+  if (strValue !== "" || value === "") return "";
+  switch (val) {
+    case "L":
+      return "↓";
+    case "H":
+      return "↑";
+  }
+  return "";
+}
+
+function dataConversion(value: CreateData) {
+  const { data, id } = value;
+  const order = data.order;
+
+  function inspectionResults() {
+    return XEUtils.map(data.items, item => {
+      return [
+        item.itm_name,
+        `${item.itm_value}${item.itm_str_value}`,
+        item.itm_unit,
+        getItemStr(item.itm_alert, item.itm_str_value, item.itm_value),
+        item.range,
+      ];
+    });
+  }
+
+  return [
+    {
+      dataIndex: "样本信息",
+      value: [
+        [
+          order.aply_date,
+          "名称:" + order.aply_cntn,
+          "标本:" + order.smpl_name,
+          "单号:" + id,
+          "",
+        ],
+      ],
+    },
+    {
+      dataIndex: "检验结果",
+      value: inspectionResults(),
+    },
+    {
+      dataIndex: "审核信息",
+      value: [
+        ["检验人:" + order.ordr_usr_name, "审核人:" + order.audt_usr_name],
+      ],
+    },
+  ];
+}
+
+export function useEmrJianYan() {
+  let editor: EditType;
+
+  function doesItExist(id: string) {
+    const tablesByCode = editor.EMR.getDocument().getTablesByCode(id);
+    return tablesByCode.length > 0;
+  }
+
+  return {
+    install(value: EditType) {
+      editor = value;
+    },
+    create(value: CreateData): CreateState {
+      const { id } = value;
+      const tmpContent = XEUtils.cloneDeep(fragment.content[0]);
+      tmpContent.code = id;
+      const tmpData = {
+        [id]: dataConversion(value),
+      };
+      if (doesItExist(id)) {
+        editor.setValues(
+          {
+            [id]: [
+              {
+                dataIndex: "样本信息",
+                value: [],
+              },
+              {
+                dataIndex: "检验结果",
+                value: [],
+              },
+              {
+                dataIndex: "审核信息",
+                value: [],
+              },
+            ],
+          },
+          true,
+          true
+        );
+        editor.setValues(tmpData, true, true);
+        return "UPDATE";
+      }
+
+      const contents = [];
+      contents.push(tmpContent);
+      contents.push({
+        type: "paragraph",
+        deletable: false,
+        editable: false,
+        children: [{ type: "text", data: "" }],
+      }); //最好插入一个空段落定位光标
+      editor.renderer.pageView.fixEmpty();
+      editor.setCursor("DOCUMENT_END"); //设置光标到文档最后
+      editor.execute("insertContents", {
+        value: contents,
+        defaultData: tmpData,
+        styles: fragment.styles,
+      });
+      return "INSERT";
+    },
+    sort() {
+      const tableViews = [];
+      const tableEls = editor.view.container.find(".edl-table");
+      tableEls?.each((_index, tb) => {
+        tableViews.push({
+          date: tb.querySelector("td").textContent,
+          view: tb.view,
+        });
+      });
+      editor.execute("execFn", {
+        //清空文档原有内容
+        value: {
+          params: [],
+          fn: function (editor) {
+            let last = editor.renderer.pageView.el.lastElementChild;
+            tableViews
+              .sort((a, b) => {
+                return new Date(a.date).getTime() - new Date(b.date).getTime();
+              })
+              .map(item => {
+                last.insertAdjacentElement("beforebegin", item.view.el);
+              });
+          },
+          persist: true,
+        },
+      });
+    },
+  };
+}
+
+export const fragment = {
+  content: [
+    {
+      tableType: "normal",
+      code: "Oymt-z4JHZ",
+      readonly: false,
+      headerRows: 0,
+      type: "table",
+      children: [
+        {
+          id: "nDFR-IAXwA",
+          type: "colgroup",
+          children: [
+            {
+              style: {
+                css: {
+                  width: "26.9638%",
+                },
+              },
+              id: "JY4izqZes6",
+              type: "col",
+            },
+            {
+              style: {
+                css: {
+                  width: "20.4178%",
+                },
+              },
+              id: "fGrB5nmQHy",
+              type: "col",
+            },
+            {
+              style: {
+                css: {
+                  width: "19.0251%",
+                },
+              },
+              id: "zJ8BQ_XDRx",
+              type: "col",
+            },
+            {
+              style: {
+                css: {
+                  width: "13.5933%",
+                },
+              },
+              id: "rwFj6GoU2v",
+              type: "col",
+            },
+            {
+              style: {
+                css: {
+                  width: "20%",
+                },
+              },
+              id: "e5kRwLqYE1L",
+              type: "col",
+            },
+          ],
+        },
+        {
+          id: "ebMeu-U_xw",
+          type: "tablebody",
+          children: [
+            {
+              style: {
+                css: {
+                  height: "20.109px",
+                },
+              },
+              id: "JJhPKX7_p7n",
+              dataIndex: "样本信息",
+              dataExpandType: "keepData",
+              fillRanger: "1:1-5",
+              type: "tablerow",
+              children: [
+                {
+                  height: "20px",
+                  style: {
+                    css: {
+                      verticalAlign: "top",
+                    },
+                    id: null,
+                  },
+                  id: "U8-Piq1UPnX",
+                  type: "tablecell",
+                  children: [
+                    {
+                      defaultStyleId: "global_style_text",
+                      id: "Gpu_zRxxoLo",
+                      type: "paragraph",
+                      children: [
+                        {
+                          style: {
+                            id: "e6aRxaE7OLt",
+                          },
+                          id: "iOrC7hcSs",
+                          data: "",
+                          type: "text",
+                        },
+                      ],
+                    },
+                  ],
+                },
+                {
+                  height: "20px",
+                  style: {
+                    css: {
+                      verticalAlign: "top",
+                    },
+                    id: "rTiYqDaP3P",
+                    class: "edl-cs ",
+                  },
+                  id: "BQJkke2kptj",
+                  colspan: "2",
+                  type: "tablecell",
+                  children: [
+                    {
+                      defaultStyleId: "global_style_text",
+                      id: "p2oqGJa9NhG",
+                      type: "paragraph",
+                      children: [
+                        {
+                          style: {
+                            id: "e6aRxaE7OLt",
+                          },
+                          id: "NOD5BPoE-",
+                          data: "",
+                          type: "text",
+                        },
+                      ],
+                    },
+                  ],
+                },
+                {
+                  height: "20px",
+                  style: {
+                    css: {
+                      verticalAlign: "top",
+                      display: "none",
+                    },
+                    id: "RDbIbsoGh",
+                    class: "edl-cs ",
+                  },
+                  id: "gFy8tEJCF7K",
+                  type: "tablecell",
+                  children: [
+                    {
+                      defaultStyleId: "global_style_text",
+                      id: "fX8ru3eN5iI",
+                      type: "paragraph",
+                      children: [
+                        {
+                          style: {
+                            id: "e6aRxaE7OLt",
+                          },
+                          id: "IDTkGxnzr",
+                          data: "",
+                          type: "text",
+                        },
+                      ],
+                    },
+                  ],
+                },
+                {
+                  height: "20px",
+                  style: {
+                    css: {
+                      verticalAlign: "top",
+                    },
+                    id: null,
+                  },
+                  id: "e782NxYP5StN",
+                  type: "tablecell",
+                  children: [
+                    {
+                      defaultStyleId: "global_style_text",
+                      id: "NFaCeOsmSE5",
+                      type: "paragraph",
+                      children: [
+                        {
+                          style: {
+                            id: "e6aRxaE7OLt",
+                          },
+                          id: "kxBbZDsbB",
+                          data: "",
+                          type: "text",
+                        },
+                      ],
+                    },
+                  ],
+                },
+                {
+                  height: "20px",
+                  style: {
+                    css: {
+                      verticalAlign: "top",
+                    },
+                    id: null,
+                  },
+                  id: "e3aR4PW5hEma",
+                  type: "tablecell",
+                  children: [
+                    {
+                      defaultStyleId: "global_style_text",
+                      id: "KJhAqHM1ckj",
+                      type: "paragraph",
+                      children: [
+                        {
+                          style: {
+                            id: "e6aRxaE7OLt",
+                          },
+                          id: "W7oLecWE3Ck",
+                          data: "",
+                          type: "text",
+                        },
+                      ],
+                    },
+                  ],
+                },
+              ],
+            },
+            {
+              style: {
+                css: {
+                  height: "20.109px",
+                },
+              },
+              id: "IlCdF4Ca5hF",
+              dataExpandType: "keepData",
+              type: "tablerow",
+              children: [
+                {
+                  height: "20px",
+                  style: {
+                    css: {
+                      verticalAlign: "top",
+                    },
+                  },
+                  id: "QD4ClCeB1Kc",
+                  type: "tablecell",
+                  children: [
+                    {
+                      defaultStyleId: "global_style_text",
+                      id: "QvnB6uFPDxA",
+                      style: {
+                        id: "e8rQDCl9ier",
+                      },
+                      type: "paragraph",
+                      children: [
+                        {
+                          style: {
+                            id: "e6aRxaE7OLt",
+                          },
+                          id: "e5oHRwtBMc",
+                          data: "项目名称",
+                          type: "text",
+                        },
+                      ],
+                    },
+                  ],
+                },
+                {
+                  height: "20px",
+                  style: {
+                    css: {
+                      verticalAlign: "top",
+                    },
+                  },
+                  id: "bPgK9z494vT",
+                  type: "tablecell",
+                  children: [
+                    {
+                      defaultStyleId: "global_style_text",
+                      id: "GNrGascsaaQ",
+                      style: {
+                        id: "e8rQDCl9ier",
+                      },
+                      type: "paragraph",
+                      children: [
+                        {
+                          style: {
+                            id: "e6aRxaE7OLt",
+                          },
+                          id: "f82F7WbPI",
+                          data: "结果",
+                          type: "text",
+                        },
+                      ],
+                    },
+                  ],
+                },
+                {
+                  height: "20px",
+                  style: {
+                    css: {
+                      verticalAlign: "top",
+                    },
+                  },
+                  id: "iVBau8eqIdA",
+                  type: "tablecell",
+                  children: [
+                    {
+                      defaultStyleId: "global_style_text",
+                      id: "cQNYbmE79Xe",
+                      style: {
+                        id: "e8rQDCl9ier",
+                      },
+                      type: "paragraph",
+                      children: [
+                        {
+                          style: {
+                            id: "e6aRxaE7OLt",
+                          },
+                          id: "cEf_D3WMS",
+                          data: "单位",
+                          type: "text",
+                        },
+                      ],
+                    },
+                  ],
+                },
+                {
+                  height: "20px",
+                  style: {
+                    css: {
+                      verticalAlign: "top",
+                    },
+                  },
+                  id: "Uo-6nbXjo9g",
+                  type: "tablecell",
+                  children: [
+                    {
+                      defaultStyleId: "global_style_text",
+                      id: "wD-HOrHs1Dn",
+                      style: {
+                        id: "e8rQDCl9ier",
+                      },
+                      type: "paragraph",
+                      children: [
+                        {
+                          style: {
+                            id: "e6aRxaE7OLt",
+                          },
+                          id: "UvwQmQx1a",
+                          data: "标志",
+                          type: "text",
+                        },
+                      ],
+                    },
+                  ],
+                },
+                {
+                  height: "20px",
+                  style: {
+                    css: {
+                      verticalAlign: "top",
+                    },
+                  },
+                  id: "Yly_-UT6Obl",
+                  type: "tablecell",
+                  children: [
+                    {
+                      defaultStyleId: "global_style_text",
+                      id: "e9U2o8FZ45sl",
+                      style: {
+                        id: "e8rQDCl9ier",
+                      },
+                      type: "paragraph",
+                      children: [
+                        {
+                          style: {
+                            id: "e6aRxaE7OLt",
+                          },
+                          id: "mF7FIMOFl",
+                          data: "参考范围",
+                          type: "text",
+                        },
+                      ],
+                    },
+                  ],
+                },
+              ],
+            },
+            {
+              style: {
+                css: {
+                  height: "20.109px",
+                },
+              },
+              id: "LebD9ia_0ve",
+              dataIndex: "检验结果",
+              fillRanger: "1:1-5",
+              dataExpandType: "keepData",
+              type: "tablerow",
+              children: [
+                {
+                  height: "20px",
+                  style: {
+                    css: {
+                      verticalAlign: "top",
+                    },
+                  },
+                  id: "nWhvoewuuux",
+                  type: "tablecell",
+                  children: [
+                    {
+                      defaultStyleId: "global_style_text",
+                      id: "e2gIXEr7KH9K",
+                      style: {
+                        id: "e8rQDCl9ier",
+                      },
+                      type: "paragraph",
+                      children: [
+                        {
+                          style: {
+                            id: "e6aRxaE7OLt",
+                          },
+                          id: "eHg5PnVIQPL",
+                          data: "",
+                          type: "text",
+                        },
+                      ],
+                    },
+                  ],
+                },
+                {
+                  height: "20px",
+                  style: {
+                    css: {
+                      verticalAlign: "top",
+                    },
+                  },
+                  id: "JFy9JxkpuQ4",
+                  type: "tablecell",
+                  children: [
+                    {
+                      defaultStyleId: "global_style_text",
+                      id: "f6JPPsGfdZd",
+                      style: {
+                        id: "e8rQDCl9ier",
+                      },
+                      type: "paragraph",
+                      children: [
+                        {
+                          style: {
+                            id: "e6aRxaE7OLt",
+                          },
+                          id: "e4UFttSwKo_3",
+                          data: "",
+                          type: "text",
+                        },
+                      ],
+                    },
+                  ],
+                },
+                {
+                  height: "20px",
+                  style: {
+                    css: {
+                      verticalAlign: "top",
+                    },
+                  },
+                  id: "m2zie2p_Yrj",
+                  type: "tablecell",
+                  children: [
+                    {
+                      defaultStyleId: "global_style_text",
+                      id: "IsPaTTzbk6J",
+                      style: {
+                        id: "e8rQDCl9ier",
+                      },
+                      type: "paragraph",
+                      children: [
+                        {
+                          style: {
+                            id: "e6aRxaE7OLt",
+                          },
+                          id: "wkUARfnyznq",
+                          data: "",
+                          type: "text",
+                        },
+                      ],
+                    },
+                  ],
+                },
+                {
+                  height: "20px",
+                  style: {
+                    css: {
+                      verticalAlign: "top",
+                    },
+                  },
+                  id: "HUgCRZiP-FR",
+                  type: "tablecell",
+                  children: [
+                    {
+                      defaultStyleId: "global_style_text",
+                      id: "MpSG-H8ER7v",
+                      style: {
+                        id: "e8rQDCl9ier",
+                      },
+                      type: "paragraph",
+                      children: [
+                        {
+                          style: {
+                            id: "e6aRxaE7OLt",
+                          },
+                          id: "BlTysF1RUWC",
+                          data: "",
+                          type: "text",
+                        },
+                      ],
+                    },
+                  ],
+                },
+                {
+                  height: "20px",
+                  style: {
+                    css: {
+                      verticalAlign: "top",
+                    },
+                  },
+                  id: "e-8vFlMJTHUg",
+                  type: "tablecell",
+                  children: [
+                    {
+                      defaultStyleId: "global_style_text",
+                      id: "xcYOWnLdJZC",
+                      style: {
+                        id: "e8rQDCl9ier",
+                      },
+                      type: "paragraph",
+                      children: [
+                        {
+                          style: {
+                            id: "e6aRxaE7OLt",
+                          },
+                          id: "nG0mTQ-AiUM",
+                          data: "",
+                          type: "text",
+                        },
+                      ],
+                    },
+                  ],
+                },
+              ],
+            },
+            {
+              style: {
+                css: {
+                  height: "20.109px",
+                },
+              },
+              id: "e1nsxGKN88WH",
+              dataIndex: "审核信息",
+              fillRanger: "1:1-5",
+              dataExpandType: "keepData",
+              type: "tablerow",
+              children: [
+                {
+                  height: "20px",
+                  style: {
+                    css: {
+                      verticalAlign: "top",
+                    },
+                    id: "rTiYqDaP3P",
+                    class: "edl-cs ",
+                  },
+                  id: "IviRNyQ-o2h",
+                  colspan: 2,
+                  type: "tablecell",
+                  children: [
+                    {
+                      defaultStyleId: "global_style_text",
+                      id: "e7tytq9hhwAM",
+                      type: "paragraph",
+                      children: [
+                        {
+                          style: {
+                            id: "e6aRxaE7OLt",
+                          },
+                          id: "gNdESS5Sz",
+                          data: "",
+                          type: "text",
+                        },
+                      ],
+                    },
+                  ],
+                },
+                {
+                  height: "20px",
+                  style: {
+                    css: {
+                      verticalAlign: "top",
+                      display: "none",
+                    },
+                    id: "RDbIbsoGh",
+                    class: "edl-cs ",
+                  },
+                  id: "CW2bJB7Bc9z",
+                  type: "tablecell",
+                  children: [
+                    {
+                      defaultStyleId: "global_style_text",
+                      id: "Hadyopvz8d2",
+                      type: "paragraph",
+                      children: [
+                        {
+                          style: {
+                            id: "e6aRxaE7OLt",
+                          },
+                          id: "xD4xqmUnhpl",
+                          data: "",
+                          type: "text",
+                        },
+                      ],
+                    },
+                  ],
+                },
+                {
+                  height: "20px",
+                  style: {
+                    css: {
+                      verticalAlign: "top",
+                    },
+                    id: "rTiYqDaP3P",
+                    class: "edl-cs ",
+                  },
+                  id: "fFA11cGaTOH",
+                  colspan: 3,
+                  type: "tablecell",
+                  children: [
+                    {
+                      defaultStyleId: "global_style_text",
+                      id: "A6sjohrsilA",
+                      type: "paragraph",
+                      children: [
+                        {
+                          style: {
+                            id: "e6aRxaE7OLt",
+                          },
+                          id: "IOd6m6xA4",
+                          data: "",
+                          type: "text",
+                        },
+                      ],
+                    },
+                  ],
+                },
+                {
+                  height: "20px",
+                  style: {
+                    css: {
+                      verticalAlign: "top",
+                      display: "none",
+                    },
+                    id: "RDbIbsoGh",
+                    class: "edl-cs ",
+                  },
+                  id: "AWcVWhTUiW9",
+                  type: "tablecell",
+                  children: [
+                    {
+                      defaultStyleId: "global_style_text",
+                      id: "e3TH4xec7ktj",
+                      type: "paragraph",
+                      children: [
+                        {
+                          style: {
+                            id: "e6aRxaE7OLt",
+                          },
+                          id: "e9xistUpUrAg",
+                          data: "",
+                          type: "text",
+                        },
+                      ],
+                    },
+                  ],
+                },
+                {
+                  height: "20px",
+                  style: {
+                    css: {
+                      verticalAlign: "top",
+                      display: "none",
+                    },
+                    id: "RDbIbsoGh",
+                    class: "edl-cs ",
+                  },
+                  id: "kZ4A7uWz1sv",
+                  type: "tablecell",
+                  children: [
+                    {
+                      defaultStyleId: "global_style_text",
+                      id: "duoDJnGB3MT",
+                      type: "paragraph",
+                      children: [
+                        {
+                          style: {
+                            id: "e6aRxaE7OLt",
+                          },
+                          id: "k1UAWN0inzf",
+                          data: "",
+                          type: "text",
+                        },
+                      ],
+                    },
+                  ],
+                },
+              ],
+            },
+          ],
+        },
+      ],
+    },
+  ],
+  styles: {
+    text: {
+      e6aRxaE7OLt: {
+        fontFamily: "SimSun",
+        fontSize: "10.5pt",
+      },
+    },
+    table: {
+      RDbIbsoGh: {
+        verticalAlign: "top",
+        display: "none",
+      },
+      rTiYqDaP3P: {
+        verticalAlign: "top",
+      },
+    },
+    paragraph: {
+      e8rQDCl9ier: {
+        textAlign: "center",
+      },
+    },
+  },
+};

+ 4 - 0
src/views/settings/test.tsx

@@ -0,0 +1,4 @@
+export const Test22 = (props, content) => {
+  console.log(props, content);
+  return <div>ces2</div>;
+};

+ 45 - 0
src/views/settings/test/emr-test/index.vue

@@ -0,0 +1,45 @@
+<script setup lang="ts">
+import { useEmrInit } from "@/utils/emr/emr-init-v2";
+import { getDetail } from "@/api/jian-yan-jie-kou/jian-yan-jie-kou";
+import { EditType } from "@/utils/emr/edit";
+import { useEmrJianYan } from "@/utils/emr/use/useEmrJianYan";
+
+const divRef = ref();
+
+let editor: EditType;
+
+const jianYan = useEmrJianYan();
+
+function 插入(id) {
+  getDetail(id).then(res => {
+    jianYan.create({ data: res, id });
+  });
+}
+
+onMounted(() => {
+  useEmrInit(divRef.value).then(res => {
+    editor = res.editor;
+    res.loadAndSetDocument({
+      categoryId: "03cd3da0580011eda93f1fd7ab32baa6",
+      categoryCode: "ffc98fb057ff11eda93f1fd7ab32baa6",
+      documentId: null,
+    });
+    jianYan.install(editor);
+  });
+});
+</script>
+
+<template>
+  <div class="layout_container">
+    <header class="layout-header">
+      <el-button @click="插入('5286682')">插入1</el-button>
+      <el-button @click="插入('5356760')">插入2</el-button>
+      <el-button @click="jianYan.sort()">排序</el-button>
+    </header>
+    <div class="layout_main">
+      <div ref="divRef" class="layout_h-w_max"></div>
+    </div>
+  </div>
+</template>
+
+<style lang="scss"></style>