Browse Source

电子病历新增内涵质控数据

xiaochan 2 years ago
parent
commit
67d3fe1b20

+ 6 - 0
package-lock.json

@@ -24,6 +24,7 @@
         "js-cookie": "^3.0.0",
         "jsbarcode": "^3.11.4",
         "moment": "^2.29.1",
+        "monaco-editor": "^0.40.0",
         "normalize.css": "^8.0.1",
         "nprogress": "^0.2.0",
         "qrcanvas": "^3.1.2",
@@ -6482,6 +6483,11 @@
         "node": "*"
       }
     },
+    "node_modules/monaco-editor": {
+      "version": "0.40.0",
+      "resolved": "https://registry.npmmirror.com/monaco-editor/-/monaco-editor-0.40.0.tgz",
+      "integrity": "sha512-1wymccLEuFSMBvCk/jT1YDW/GuxMLYwnFwF9CDyYCxoTw2Pt379J3FUhwy9c43j51JdcxVPjwk0jm0EVDsBS2g=="
+    },
     "node_modules/mrmime": {
       "version": "1.0.1",
       "resolved": "https://registry.npmmirror.com/mrmime/-/mrmime-1.0.1.tgz",

+ 1 - 0
package.json

@@ -28,6 +28,7 @@
     "js-cookie": "^3.0.0",
     "jsbarcode": "^3.11.4",
     "moment": "^2.29.1",
+    "monaco-editor": "^0.40.0",
     "normalize.css": "^8.0.1",
     "nprogress": "^0.2.0",
     "qrcanvas": "^3.1.2",

+ 8 - 0
src/api/emr-control/emr-control.ts

@@ -32,3 +32,11 @@ export function selectControlByPatNo(patNo: string, times: number) {
         params: {patNo, times}
     })
 }
+
+export function saveEmr(data) {
+    return request({
+        url: '/save',
+        method: 'post',
+        data
+    });
+}

+ 22 - 0
src/components/query-components/XcPageTable.vue

@@ -0,0 +1,22 @@
+<script setup lang="ts">
+import {defineProps} from 'vue'
+import {componentType} from "./page-help-type";
+import {useVModels} from "@vueuse/core";
+
+const props = defineProps<{
+  testJson: componentType,
+}>()
+
+const emits = defineEmits(['update:testJson'])
+
+const {testJson} = useVModels(props, emits)
+
+</script>
+
+<template>
+  <vxe-grid v-bind="testJson.tableConfig"></vxe-grid>
+</template>
+
+<style scoped lang="scss">
+
+</style>

+ 12 - 8
src/components/query-components/XcQuery.vue

@@ -141,19 +141,21 @@ const submit = async () => {
     countIfTags(tempQuerySql)
   }
 
-  let tempData = {}
+  let queryData = {}
 
   testJson.value.header.forEach((item) => {
     if (isDateRange(item)) {
       let {startTime, endTime} = getDateRangeFormatDate(testJson.value.queryParam[item.key])
-      tempData[item.dataRange.startAlias] = startTime
-      tempData[item.dataRange.endAlias] = endTime
-    } else {
-      tempData[item.key] = testJson.value.queryParam[item.key]
+      queryData[item.dataRange.startAlias] = startTime
+      queryData[item.dataRange.endAlias] = endTime
     }
+    queryData[item.key] = testJson.value.queryParam[item.key]
   })
 
-  console.log('查询条件', tempData)
+  let func = new Function('', 'return ' + testJson.value.submitEvent)
+  func()(queryData, testJson.value, axios)
+
+  console.log('查询条件', queryData)
   emits('submit', testJson.value.queryParam)
 }
 
@@ -238,6 +240,7 @@ const delClick = async (key) => {
 }
 
 const initAttribute = () => {
+
   let data = {
     pageJson: testJson.value,
     axios: axios
@@ -247,8 +250,8 @@ const initAttribute = () => {
     if (item.bind) {
       for (const key in item.bind) {
         if (key.startsWith("_")) {
-          let tempKey = key.substr(1);
-          item.bind[tempKey] = (val) => {
+          let tempKey = key.substring(1);
+          item.bind[tempKey] = async (val) => {
             let func = new Function('value', 'data', '...val', "return " + item.bind[key])
             func()(item, data, val)
           }
@@ -258,6 +261,7 @@ const initAttribute = () => {
   })
 }
 
+
 watch(() => testJson.value.header.length, () => {
   dataReset()
   intiRules()

+ 1 - 0
src/components/query-components/page-help-type.ts

@@ -66,6 +66,7 @@ export interface componentType {
     formConfig: formConfig,
     // 点击提交时候触发的值
     submitEvent?: string,
+    tableConfig: any
 }
 
 

+ 9 - 11
src/components/query-components/page-help.ts

@@ -66,14 +66,15 @@ export const collapseData: {
                     style: {
                         width: null
                     },
+                    loading: false,
                     options: [],
                     remote: true,
                     filterable: true,
-                    _remoteMethod: `async function (value, data, ...val) {
+                    _remoteMethod: async function (currentValue, data, ...val) {
                         let {pageJson, axios} = data
-                        value.bind.loading = true
+                        currentValue.bind.loading = true
                         let tempData = {}
-                        let net = value.networkRequests
+                        let net = currentValue.networkRequests
 
                         net.params.forEach(item => {
                             if (item.queryValue) {
@@ -90,20 +91,17 @@ export const collapseData: {
                                 params: tempData,
                                 data: tempData
                             })
-
                             let a = new Function('res', 'return res.' + net.returnsVolumeResolutionDetail)
-                            value.bind.options = a(res)
+                            currentValue.bind.options = a(res) || []
                         } catch (e) {
-                            value.bind.options = []
+                            currentValue.bind.options = []
                         }
-                            
-                        value.bind.loading = false
-                    }`
+                        currentValue.bind.loading = false
+                    }
                 },
-                // f64e8d769e5149fe88ce5dbb84326235
                 networkRequests: {
                     method: 'get',
-                    url: '/bdp/dataservice/api/f64e8d769e5149fe88ce5dbb84326235',
+                    url: '/bdp/dataservice/api/4a34eb26909d416188d0cb7d26026b08 ',
                     params: [{queryName: 'query', queryValue: ''}],
                     requestInterfaced: '创智中台',
                     returnsVolumeResolutionDetail: 'data.rows'

+ 1 - 2
src/components/xiao-chan/combo-grid/XcComboGridV2.vue

@@ -1,7 +1,6 @@
 <script setup lang="ts">
 import {computed, defineProps, nextTick, onMounted, ref, watch} from "vue";
 import XEUtils from 'xe-utils'
-import {PulldownMethods} from "vxe-table/types/pulldown";
 import {useVModel} from "@vueuse/core";
 import {VxeTableInstance} from "vxe-table";
 import {$ref} from "vue/macros";
@@ -77,7 +76,7 @@ let scrollTopRecording = 0
 
 const isObj = typeof props.modelValue === 'object'
 const tempData = ref([])
-const pullDownRef = ref<PulldownMethods>()
+const pullDownRef = ref()
 const inputData = ref('')
 const placeholder = ref(props.placeholder)
 const vxeTableRef = ref<VxeTableInstance>()

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

@@ -238,10 +238,14 @@
                 minlength="1"
                 show-word-limit/>
 
-      <br> <br>
-
-      <el-alert type="warning" title="正在解析病程记录,请稍等。" v-if="解析病程提示"/>
-      <el-alert type="success" title="解析完成,点击确认即可。" v-else/>
+      <br/> <br/>
+      <div style="max-height: 200px;overflow-y: auto">
+        <el-alert type="warning" title="正在解析病程记录,请稍等。" v-if="解析病程提示"/>
+        <el-alert type="success" title="解析完成,点击确认即可。" v-else/>
+        <br/>
+        <el-alert type="warning" :title="saveDialog.warningPrompt"
+                  v-if="saveDialog.warningPrompt"/>
+      </div>
 
       <emr-connotation :category-code="categoryCode"/>
 
@@ -317,6 +321,7 @@ import {
 } from "@/views/hospitalization/zhu-yuan-yi-sheng/electronic-medical-record/emr-editor/emr-edit-create-limit";
 import EmrStyleBar
   from "@/views/hospitalization/zhu-yuan-yi-sheng/electronic-medical-record/emr-editor/components/EmrStyleBar.vue";
+import {saveEmr} from "@/api/emr-control/emr-control";
 
 
 const props = defineProps({
@@ -511,6 +516,7 @@ let saveDialog = $ref({
   cb: null,
   err: null,
   analyzeTheCourseOfTheDisease: false,
+  warningPrompt: '',
   prompt: (name, cb, err) => {
     saveDialog.name = name
     saveDialog.cb = cb
@@ -588,7 +594,6 @@ const editJudgment = async () => {
       } else {
         editor.setEditorMode('readonly')
       }
-      console.log(value)
     })
   }
   readonlyPattern()
@@ -608,12 +613,12 @@ const clickSaveData = async () => {
   try {
     let validator = editor.getValidator();
     let valid = validator.valid();
-
     if (valid) {
       BizException(ExceptionEnum.MESSAGE_ERROR, "有必填项不能为空,请仔细检查,红色输入框.")
     }
   } catch {
   }
+
   // 解析 id
   let id = await analysisIframeSrcSearch()
   let data = {
@@ -633,9 +638,9 @@ const clickSaveData = async () => {
     templateName = '病程记录'
   }
   if (isDev) {
-    // save(data).then(res => {
-    //   ElMessage.warning(res.data.data)
-    // })
+    saveEmr(data).then(res => {
+      saveDialog.warningPrompt = res
+    })
   }
   saveDialog.dialog = true
   data.fragment = 解析病程记录()

+ 88 - 0
src/views/utilities/page-editor-help/JsEditDialog.vue

@@ -0,0 +1,88 @@
+<script setup lang="ts">
+import {defineProps, nextTick, onMounted, ref} from "vue";
+import {useVModel} from "@vueuse/core";
+import jsonWorker from 'monaco-editor/esm/vs/language/json/json.worker?worker'
+import cssWorker from 'monaco-editor/esm/vs/language/css/css.worker?worker'
+import htmlWorker from 'monaco-editor/esm/vs/language/html/html.worker?worker'
+import tsWorker from 'monaco-editor/esm/vs/language/typescript/ts.worker?worker'
+import EditorWorker from 'monaco-editor/esm/vs/editor/editor.worker?worker'
+import * as monaco from 'monaco-editor';
+import sleep from "@/utils/sleep";
+
+
+const props = defineProps<{
+  jsData: string,
+  modelValue: boolean
+}>()
+
+const dialog = ref(true)
+const emits = defineEmits(['update:modelValue', 'update:jsData'])
+
+const dataVal = useVModel(props, 'jsData', emits)
+const modValue = useVModel(props, 'modelValue', emits)
+
+const jsEdit = ref(null)
+
+
+// 提示
+self.MonacoEnvironment = {
+  getWorker(_: string, label: string) {
+    if (label === 'json') {
+      return new jsonWorker()
+    }
+    if (label === 'css' || label === 'scss' || label === 'less') {
+      return new cssWorker()
+    }
+    if (label === 'html' || label === 'handlebars' || label === 'razor') {
+      return new htmlWorker()
+    }
+    if (['typescript', 'javascript'].includes(label)) {
+      return new tsWorker()
+    }
+    return new EditorWorker()
+  },
+}
+
+onMounted(async () => {
+  await nextTick()
+  const monacoEditor = monaco.editor.create(jsEdit.value, {
+    // 初始化的dom节点
+    value: dataVal.value, // 初始化值
+    language: 'javascript', // 语言支持自行查阅demo
+    automaticLayout: true, // 自适应布局
+    theme: 'vs-dark', // 官方自带三种主题vs, hc-black, or vs-dark
+    foldingStrategy: 'indentation',
+    renderLineHighlight: 'all', // 行亮
+    selectOnLineNumbers: true, // 显示行号
+    minimap: {
+      enabled: false,
+    },
+    readOnly: false, // 只读
+    fontSize: 16, // 字体大小
+    scrollBeyondLastLine: false, // 取消代码后面一大段空白
+    overviewRulerBorder: true,
+  });
+
+  monacoEditor.onDidChangeModelContent((val) => {
+    dataVal.value = monacoEditor.getValue();
+  })
+
+  await nextTick()
+  await sleep(200)
+
+  monacoEditor.focus()
+
+})
+
+
+</script>
+
+<template>
+  <el-dialog v-model="dialog" title="代码编辑" draggable @closed="modValue=false">
+    <div ref="jsEdit" style="width: 100%; height: 400px"></div>
+  </el-dialog>
+</template>
+
+<style scoped lang="scss">
+
+</style>

+ 13 - 6
src/views/utilities/page-editor-help/PageEditorHelp.vue

@@ -3,24 +3,22 @@ import {onMounted, ref} from 'vue'
 import {collapseData, generateRandomString} from "../../../components/query-components/page-help.ts";
 import XcQuery from "../../../components/query-components/XcQuery.vue";
 import {componentType, headerType} from "../../../components/query-components/page-help-type";
-import PageEditotInfo from "./PageEditotInfo.vue";
+import PageEditotInfo from "./PageEditorInfo.vue";
 import {clone} from "xe-utils";
-import PageForm from "@/views/utilities/page-editor-help/PageForm.vue";
-
+import PageForm from "../../../views/utilities/page-editor-help/PageForm.vue";
+import XcTable from "../../../components/query-components/XcPageTable.vue";
 
 const activeNames = ref(['1', '2', '3'])
 const infoRef = ref()
 const tabs = ref('form')
 
 const addEl = (val: headerType) => {
-
   let key = generateRandomString(5)
   let data = val
   if (!val.bind) {
     data['bind'] = {}
   }
   data.key = key
-
   pageJson.value.header.push(clone(data, true))
   pageJson.value.queryParam[key] = val.defaultValue
 }
@@ -32,7 +30,12 @@ const pageJson = ref<componentType>({
   formConfig: {
     inline: true
   },
-  submitEvent: null
+  submitEvent: `function func(queryData,config,axios){
+
+}`,
+  tableConfig: {
+    border: true,
+  }
 })
 
 const theCurrentComponent = ref(-1)
@@ -79,6 +82,7 @@ onMounted(() => {
                         @delClick="infoRef.setShow(false)"
                         v-model:current-index="theCurrentComponent"
                         @item-click="itemClick"/>
+              <xc-table :test-json="pageJson"/>
             </div>
             <div class="right_box">
               <el-tabs v-model="tabs">
@@ -90,6 +94,9 @@ onMounted(() => {
                 <el-tab-pane label="表单配置" name="form">
                   <page-form :page-json="pageJson"/>
                 </el-tab-pane>
+                <el-tab-pane label="表单配置" name="table">
+
+                </el-tab-pane>
               </el-tabs>
 
             </div>

+ 0 - 1
src/views/utilities/page-editor-help/PageEditotInfo.vue → src/views/utilities/page-editor-help/PageEditorInfo.vue

@@ -31,7 +31,6 @@ const setShow = (val) => {
   show.value = val
 }
 
-
 const selectRender = (data: bindType, key) => {
   let optionList = [];
   data.selectData?.forEach(item => {

+ 18 - 2
src/views/utilities/page-editor-help/PageForm.vue

@@ -1,25 +1,41 @@
 <script setup lang="ts">
 import {defineProps, ref} from 'vue'
 import {componentType} from "../../../components/query-components/page-help-type";
+import JsEditDialog from "@/views/utilities/page-editor-help/JsEditDialog.vue";
 
 const props = defineProps<{
   pageJson: componentType
 }>()
 
 const collapse = ref(['1'])
+const jsEdit = ref()
+
+const dialogConfig = ref({
+  dialog: false
+})
+
+
+const submit = () => {
+  dialogConfig.value.dialog = true
+}
 
 </script>
 
 <template>
   <el-form label-width="150px" label-position="left">
-    <el-collapse v-model="collapse"  >
+    <el-collapse v-model="collapse">
       <el-collapse-item title="事件属性" name="1">
         <el-form-item label="提交事件">
-          <el-button type="info" icon="Edit" round plain>编写代码</el-button>
+          <el-button type="info" icon="Edit" round plain @click="submit">编写代码</el-button>
         </el-form-item>
       </el-collapse-item>
     </el-collapse>
   </el-form>
+
+  <js-edit-dialog v-if="dialogConfig.dialog"
+                  v-model:js-data="props.pageJson.submitEvent"
+                  v-model="dialogConfig.dialog"/>
+
 </template>
 
 <style lang="scss">

+ 9 - 0
vite.config.js

@@ -29,6 +29,15 @@ export default defineConfig({
         alias,
         extensions: ['.mjs', '.js', '.ts', '.jsx', '.tsx', '.json', '.vue']
     },
+    optimizeDeps: {
+        include: [
+            `monaco-editor/esm/vs/language/json/json.worker`,
+            `monaco-editor/esm/vs/language/css/css.worker`,
+            `monaco-editor/esm/vs/language/html/html.worker`,
+            `monaco-editor/esm/vs/language/typescript/ts.worker`,
+            `monaco-editor/esm/vs/editor/editor.worker`
+        ],
+    },
     plugins: [
         Icons({
             autoInstall: true,