浏览代码

解除电子病历限制

2998394161@qq.com 2 年之前
父节点
当前提交
5d5703e9af

+ 32 - 0
src/api/zhu-yuan-yi-sheng/emr-control-rule.js

@@ -110,4 +110,36 @@ export function reviewToLiftRestrictions(data) {
 }
 
 
+/// 下面是新的
+export function requestToUnlockMedicalRecords(data) {
+    return request({
+        url: url + '/requestToUnlockMedicalRecords',
+        method: 'post',
+        data
+    })
+}
+
+export function getApplicationData(data) {
+    return request({
+        url: url + '/getApplicationData',
+        method: 'post',
+        data
+    })
+}
+
+export function reviewMedicalRecordsToUnlock(data) {
+    return request({
+        url: url + '/reviewMedicalRecordsToUnlock',
+        method: 'post',
+        data
+    })
+}
+
+export function getMyUnlockByPatNo(patNo, times) {
+    return request({
+        url: url + '/getMyUnlockByPatNo',
+        method: 'get',
+        params: {patNo, times}
+    })
+}
 

+ 158 - 157
src/components/settings/permissions/PersonnelInformationEditing.vue

@@ -1,95 +1,96 @@
 <template>
-  <el-dialog v-model="dialog"
-             :title="title"
-             @closed="emit('close')">
-    <el-container>
-      <el-form :model="userInfo" :inline="true" label-width="80px" :rules="rules" ref="formRef">
-        <el-form-item prop="name" label="姓名">
-          <el-input v-model="userInfo.name"></el-input>
-        </el-form-item>
-
-        <el-form-item prop="codeRs" label="人事工号">
-          <el-input v-model="userInfo.codeRs"></el-input>
-        </el-form-item>
-
-        <el-form-item prop="deptCode" label="科室">
-          <xc-select :data="peopleAddData.deptData" v-model="userInfo"
-                     :name="['deptCode','deptName']"></xc-select>
-        </el-form-item>
-
-        <el-form-item prop="empPoCode" label="职务">
-          <xc-select :data="peopleAddData.empPosition" v-model="userInfo" :name="['empPoCode','position']"></xc-select>
-        </el-form-item>
-
-        <el-form-item prop="empTitCode" label="职称">
-          <xc-select :data="peopleAddData.zdEmpTitle" v-model="userInfo" :name="['empTitCode','title']"></xc-select>
-        </el-form-item>
-
-        <el-form-item prop="mark" label="在院标志">
-          <xc-select :data="peopleAddData.empInmark" v-model="userInfo" :name="['mark','markName']"></xc-select>
-        </el-form-item>
-
-        <el-form-item prop="ifcader" label="干工标志">
-          <xc-select :data="peopleAddData.zdIfcadre" v-model="userInfo" :name="['ifcadre','ifcadreName']"></xc-select>
-        </el-form-item>
-
-        <el-form-item prop="orderYn" label="处方权">
-          <xc-select :data="doctorSPrescription" v-model="userInfo" :name="['orderYn','orderYnName']"></xc-select>
-        </el-form-item>
-
-        <el-form-item prop="ysjb" label="病历级别">
-          <xc-select :data="peopleAddData.ysjbData" v-model="userInfo" :name="['ysjb','ysjbName']"></xc-select>
-        </el-form-item>
-
-        <el-form-item prop="ghChargeType" label="挂号号别">
-          <xc-select :data="peopleAddData.mzyZdChargeType" v-model="userInfo"
-                     :name="['ghChargeType','ghChargeTypeName']"/>
-        </el-form-item>
-        <el-form-item prop="doctorXzYp" label="限制级别">
-          <xc-select :data="peopleAddData.restrictedDrugLevels" v-model="userInfo"
-                     :name="['doctorXzYp','doctorXzYpName']"/>
-        </el-form-item>
-        <el-form-item prop="loginFlag" label="病区就诊">
-          <el-switch v-model="userInfo.loginFlag" active-color="#ff4949" active-text="不允许" active-value="2"
-                     inactive-color="#13ce66" inactive-text="允许" inactive-value="1">
-          </el-switch>
-        </el-form-item>
-        <el-form-item prop="delFlag" label="停用">
-          <el-switch v-model="userInfo.delFlag" active-color="#ff4949" active-text="停用" active-value="1"
-                     inactive-color="#13ce66" inactive-text="开启" inactive-value="0">
-          </el-switch>
-        </el-form-item>
-        <el-form-item prop="socialNo" label="身份证">
-          <el-input v-model="userInfo.socialNo" clearable></el-input>
-        </el-form-item>
-        <el-form-item prop="phoneNo" label="手机号">
-          <el-input v-model="userInfo.phoneNo" clearable></el-input>
-        </el-form-item>
-        <el-form-item prop="ybCode" label="医保">
-          <el-input v-model="userInfo.ybCode" clearable></el-input>
-        </el-form-item>
-        <el-form-item label="兼诊科室">
-          <el-select v-model="userInfo.partTimeDept"
-                     multiple
-                     filterable
-                     placeholder="兼诊科室"
-                     style="width: 240px">
-            <el-option
-                v-for="item in peopleAddData.deptData"
-                :key="item.code"
-                :label="item.name"
-                :value="item.code"/>
-          </el-select>
-        </el-form-item>
-      </el-form>
-    </el-container>
-    <template #footer>
-      <div>
-        <el-button type="primary" @click="confirm(formRef)">确认</el-button>
-        <el-button @click="emit('close')">取消</el-button>
-      </div>
-    </template>
-  </el-dialog>
+    <el-dialog v-model="dialog"
+               :title="title"
+               @closed="emit('close')">
+        <el-form :model="userInfo" :inline="true" label-width="80px" :rules="rules" ref="formRef">
+            <el-form-item prop="name" label="姓名">
+                <el-input v-model="userInfo.name"></el-input>
+            </el-form-item>
+
+            <el-form-item prop="codeRs" label="人事工号">
+                <el-input v-model="userInfo.codeRs"></el-input>
+            </el-form-item>
+
+            <el-form-item prop="deptCode" label="科室">
+                <xc-select :data="peopleAddData.deptData" v-model="userInfo"
+                           :name="['deptCode','deptName']"></xc-select>
+            </el-form-item>
+
+            <el-form-item prop="empPoCode" label="职务">
+                <xc-select :data="peopleAddData.empPosition" v-model="userInfo"
+                           :name="['empPoCode','position']"></xc-select>
+            </el-form-item>
+
+            <el-form-item prop="empTitCode" label="职称">
+                <xc-select :data="peopleAddData.zdEmpTitle" v-model="userInfo"
+                           :name="['empTitCode','title']"></xc-select>
+            </el-form-item>
+
+            <el-form-item prop="mark" label="在院标志">
+                <xc-select :data="peopleAddData.empInmark" v-model="userInfo" :name="['mark','markName']"></xc-select>
+            </el-form-item>
+
+            <el-form-item prop="ifcader" label="干工标志">
+                <xc-select :data="peopleAddData.zdIfcadre" v-model="userInfo"
+                           :name="['ifcadre','ifcadreName']"></xc-select>
+            </el-form-item>
+
+            <el-form-item prop="orderYn" label="处方权">
+                <xc-select :data="doctorSPrescription" v-model="userInfo" :name="['orderYn','orderYnName']"></xc-select>
+            </el-form-item>
+
+            <el-form-item prop="ysjb" label="病历级别">
+                <xc-select :data="peopleAddData.ysjbData" v-model="userInfo" :name="['ysjb','ysjbName']"></xc-select>
+            </el-form-item>
+
+            <el-form-item prop="ghChargeType" label="挂号号别">
+                <xc-select :data="peopleAddData.mzyZdChargeType" v-model="userInfo"
+                           :name="['ghChargeType','ghChargeTypeName']"/>
+            </el-form-item>
+            <el-form-item prop="doctorXzYp" label="限制级别">
+                <xc-select :data="peopleAddData.restrictedDrugLevels" v-model="userInfo"
+                           :name="['doctorXzYp','doctorXzYpName']"/>
+            </el-form-item>
+            <el-form-item prop="loginFlag" label="病区就诊">
+                <el-switch v-model="userInfo.loginFlag" active-color="#ff4949" active-text="不允许" active-value="2"
+                           inactive-color="#13ce66" inactive-text="允许" inactive-value="1">
+                </el-switch>
+            </el-form-item>
+            <el-form-item prop="delFlag" label="停用">
+                <el-switch v-model="userInfo.delFlag" active-color="#ff4949" active-text="停用" active-value="1"
+                           inactive-color="#13ce66" inactive-text="开启" inactive-value="0">
+                </el-switch>
+            </el-form-item>
+            <el-form-item prop="socialNo" label="身份证">
+                <el-input v-model="userInfo.socialNo" clearable></el-input>
+            </el-form-item>
+            <el-form-item prop="phoneNo" label="手机号">
+                <el-input v-model="userInfo.phoneNo" clearable></el-input>
+            </el-form-item>
+            <el-form-item prop="ybCode" label="医保">
+                <el-input v-model="userInfo.ybCode" clearable></el-input>
+            </el-form-item>
+            <el-form-item label="兼诊科室">
+                <el-select v-model="userInfo.partTimeDept"
+                           multiple
+                           filterable
+                           placeholder="兼诊科室"
+                           style="width: 240px">
+                    <el-option
+                            v-for="item in peopleAddData.deptData"
+                            :key="item.code"
+                            :label="item.name"
+                            :value="item.code"/>
+                </el-select>
+            </el-form-item>
+        </el-form>
+        <template #footer>
+            <div>
+                <el-button type="primary" @click="confirm(formRef)">确认</el-button>
+                <el-button @click="emit('close')">取消</el-button>
+            </div>
+        </template>
+    </el-dialog>
 </template>
 
 <script setup name="PersonnelInformationEditing">
@@ -104,16 +105,16 @@ import {modifyEmployeeInfo, saveEmployeeInfo} from "@/api/settings/permission-se
 import {stringIsBlank} from "@/utils/blank-utils";
 
 const props = defineProps({
-  userInfo: {
-    type: Object,
-    default: {
-      name: '添加员工'
-    }
-  },
-  index: {
-    type: Number,
-    default: -1
-  },
+    userInfo: {
+        type: Object,
+        default: {
+            name: '添加员工'
+        }
+    },
+    index: {
+        type: Number,
+        default: -1
+    },
 })
 const emit = defineEmits(['close', 'changeTheData'])
 const dialog = ref(true)
@@ -121,88 +122,88 @@ const title = stringIsBlank(props.userInfo.name) ? '添加员工' : '正在编
 let userInfo = $ref({})
 
 const doctorSPrescription = [
-  {code: '1', name: '普通处方权'},
-  {code: '2', name: '毒麻药处方权'},
+    {code: '1', name: '普通处方权'},
+    {code: '2', name: '毒麻药处方权'},
 ]
 
 const wardVisit = [
-  {code: '1', name: '允许'},
-  {code: '2', name: '不允许'}
+    {code: '1', name: '允许'},
+    {code: '2', name: '不允许'}
 ]
 
 const formRef = ref(null)
 
 const idVerification = async (rule, value, callback) => {
-  if (value) {
-    const check = await idVerificationApi(value)
-    if (check) {
-      callback()
+    if (value) {
+        const check = await idVerificationApi(value)
+        if (check) {
+            callback()
+        } else {
+            callback(new Error("请填写正确的身份证号码"))
+        }
     } else {
-      callback(new Error("请填写正确的身份证号码"))
+        callback(new Error("请填写身份证"))
     }
-  } else {
-    callback(new Error("请填写身份证"))
-  }
 }
 
 const phoneNumber = (rule, value, callback) => {
-  if (value) {
-    if (isValidPhone(value)) {
-      callback()
+    if (value) {
+        if (isValidPhone(value)) {
+            callback()
+        } else {
+            callback(new Error("请填写正确的手机号"))
+        }
     } else {
-      callback(new Error("请填写正确的手机号"))
+        callback(new Error("该项不能为空"))
     }
-  } else {
-    callback(new Error("该项不能为空"))
-  }
 }
 
 const rules = reactive({
-  name: [{required: true, message: '该项不能为空', trigger: 'blur'}],
-  codeRs: [{required: true, message: '该项不能为空', trigger: 'blur'}],
-  deptCode: [{required: true, message: '该项不能为空', trigger: 'blur'}],
-  empInmark: [{required: true, message: '该项不能为空', trigger: 'blur'}],
-  doctorXzYp: [{required: true, message: '该项不能为空', trigger: 'blur'}],
-  socialNo: [
-    {required: true, message: '该项不能为空', trigger: 'blur'},
-    {validator: idVerification, trigger: 'blur'}
-  ],
-  phoneNo: [
-    {required: true, message: '该项不能为空', trigger: 'change'},
-    {validator: phoneNumber, trigger: 'blur'}
-  ],
+    name: [{required: true, message: '该项不能为空', trigger: 'blur'}],
+    codeRs: [{required: true, message: '该项不能为空', trigger: 'blur'}],
+    deptCode: [{required: true, message: '该项不能为空', trigger: 'blur'}],
+    empInmark: [{required: true, message: '该项不能为空', trigger: 'blur'}],
+    doctorXzYp: [{required: true, message: '该项不能为空', trigger: 'blur'}],
+    socialNo: [
+        {required: true, message: '该项不能为空', trigger: 'blur'},
+        {validator: idVerification, trigger: 'blur'}
+    ],
+    phoneNo: [
+        {required: true, message: '该项不能为空', trigger: 'change'},
+        {validator: phoneNumber, trigger: 'blur'}
+    ],
 })
 
 const confirm = (formRef) => {
-  if (!formRef) return
-  formRef.validate(async (valid) => {
-    if (valid) {
-      if (props.index !== -1) {
-        await modifyEmployeeInfo(userInfo);
-        emit('changeTheData', props.index, userInfo)
-      } else {
-        await saveEmployeeInfo(userInfo)
-        emit('changeTheData', props.index, userInfo)
-      }
-
-    } else {
-      ElMessage.error("请仔细检查")
-    }
-  })
+    if (!formRef) return
+    formRef.validate(async (valid) => {
+        if (valid) {
+            if (props.index !== -1) {
+                await modifyEmployeeInfo(userInfo);
+                emit('changeTheData', props.index, userInfo)
+            } else {
+                await saveEmployeeInfo(userInfo)
+                emit('changeTheData', props.index, userInfo)
+            }
+
+        } else {
+            ElMessage.error("请仔细检查")
+        }
+    })
 
 }
 
 onMounted(async () => {
-  await Sleep(500)
-  if (props.userInfo) {
-    userInfo = clone(props.userInfo)
-    userInfo.oldData = true
-    if (userInfo.partTimeDeptCode) {
-      userInfo.partTimeDept = userInfo.partTimeDeptCode.split(',')
+    await Sleep(500)
+    if (props.userInfo) {
+        userInfo = clone(props.userInfo)
+        userInfo.oldData = true
+        if (userInfo.partTimeDeptCode) {
+            userInfo.partTimeDept = userInfo.partTimeDeptCode.split(',')
+        }
+    } else {
+        userInfo.oldData = false
     }
-  } else {
-    userInfo.oldData = false
-  }
 })
 
 

+ 165 - 166
src/components/xiao-chan/xc-table/XcTable.vue

@@ -1,150 +1,149 @@
 <template>
-  <el-table
-      ref="tableRef"
-      :data="tableData"
-      style="width: 100%"
-      @selection-change="selectionChange"
-      @row-click="rowClick"
-      :height="props.finalHeight === null ? visibleWindowSize.height - props.height : props.finalHeight"
-      highlight-current-row
-      @row-contextmenu="contextmenu"
-      :row-key="props.rowKey"
-      border
-      @select-all="selectAll"
-      :default-expand-all="props.defaultExpandAll"
-      stripe>
-    <slot/>
-  </el-table>
-  <el-pagination
-      v-if="props.openPaging"
-      :current-page="pageObject.currentPage"
-      :page-size="pageObject.pageSize"
-      :total="pageObject.total"
-      :layout="props.layout"
-      :small="props.small"
-      :page-sizes="props.pageSizes"
-      @current-change="currentChange"
-      @size-change="sizeChange"/>
+    <el-table
+            ref="tableRef"
+            :data="tableData"
+            style="width: 100%"
+            @selection-change="selectionChange"
+            @row-click="rowClick"
+            :height="props.finalHeight === null ? visibleWindowSize.height - props.height : props.finalHeight"
+            highlight-current-row
+            @row-contextmenu="contextmenu"
+            :row-key="props.rowKey"
+            border
+            @select-all="selectAll"
+            :default-expand-all="props.defaultExpandAll"
+            stripe>
+        <slot/>
+    </el-table>
+    <el-pagination
+            v-if="props.openPaging"
+            :current-page="pageObject.currentPage"
+            :page-size="pageObject.pageSize"
+            :total="pageObject.total"
+            :layout="props.layout"
+            :small="props.small"
+            :page-sizes="props.pageSizes"
+            @current-change="currentChange"
+            @size-change="sizeChange"/>
 </template>
 
 <script setup name='XcTable'>
 import {ElMessage} from "element-plus";
 import {BizException, ExceptionEnum} from "@/utils/BizException";
-import {getVisibleSize, visibleWindowSize} from "@/utils/window-size";
-import {onClickOutside} from "@vueuse/core";
+import {visibleWindowSize} from "@/utils/window-size";
 
 const props = defineProps({
-  finalHeight: {
-    type: Number,
-    default: null
-  },
-  data: {
-    type: Object,
-    default: null
-  },
-  localData: {
-    type: Array,
-    default: null
-  },
-  rowKey: {
-    type: String
-  },
-  height: {
-    type: Number,
-    default: 0
-  },
-  localPaging: {
-    type: Boolean,
-    default: false
-  },
-  openPaging: {
-    type: Boolean,
-    default: true
-  },
-  layout: {
-    type: String,
-    default: 'total, sizes, prev, pager, next, jumper'
-  },
-  small: {
-    type: Boolean,
-    default: false
-  },
-  pageSizes: {
-    type: Array,
-    default: [10, 20, 30, 100]
-  },
-  isArray: {
-    type: Boolean,
-    default: false
-  },
-  defaultExpandAll: {
-    type: Boolean,
-    default: true
-  }
+    finalHeight: {
+        type: Number,
+        default: null
+    },
+    data: {
+        type: Object,
+        default: null
+    },
+    localData: {
+        type: Array,
+        default: null
+    },
+    rowKey: {
+        type: String
+    },
+    height: {
+        type: Number,
+        default: 0
+    },
+    localPaging: {
+        type: Boolean,
+        default: false
+    },
+    openPaging: {
+        type: Boolean,
+        default: true
+    },
+    layout: {
+        type: String,
+        default: 'total, sizes, prev, pager, next, jumper'
+    },
+    small: {
+        type: Boolean,
+        default: false
+    },
+    pageSizes: {
+        type: Array,
+        default: [10, 20, 30, 100]
+    },
+    isArray: {
+        type: Boolean,
+        default: false
+    },
+    defaultExpandAll: {
+        type: Boolean,
+        default: true
+    }
 })
 const emit = defineEmits([
-  'currentChange',
-  'sizeChange',
-  'rowClick',
-  'selectionChange',
-  'rowContextmenu'
+    'currentChange',
+    'sizeChange',
+    'rowClick',
+    'selectionChange',
+    'rowContextmenu'
 ])
 
 const tableRef = ref(null)
 let selection = $ref([])
 
 const tableData = computed(() => {
-  if (!props.openPaging) {
-    return pageObject.data
-  }
-  if (props.localPaging) {
-    return props.data.data.slice((props.data.currentPage - 1) * props.data.pageSize, props.data.currentPage * props.data.pageSize)
-  } else if (isLocalData) {
-    return pageObject.data.slice((pageObject.currentPage - 1) * pageObject.pageSize, pageObject.currentPage * pageObject.pageSize)
-  } else {
-    return pageObject.data
-  }
+    if (!props.openPaging) {
+        return pageObject.data
+    }
+    if (props.localPaging) {
+        return props.data.data.slice((props.data.currentPage - 1) * props.data.pageSize, props.data.currentPage * props.data.pageSize)
+    } else if (isLocalData) {
+        return pageObject.data.slice((pageObject.currentPage - 1) * pageObject.pageSize, pageObject.currentPage * pageObject.pageSize)
+    } else {
+        return pageObject.data
+    }
 })
 
 let flag = false // 默认 为全不选
 const selectAll = (selection) => {
-  flag = !flag
-  if (!flag) {
-    // 在点击了全不选中 需要清空
-    tableRef.value.clearSelection()
-    return
-  }
-  let length = selection.length
-  for (let i = 0; i < length; i++) {
-    let item = selection[i]
-    if (item.children) {
-      toggleSelection(item.children, flag)
+    flag = !flag
+    if (!flag) {
+        // 在点击了全不选中 需要清空
+        tableRef.value.clearSelection()
+        return
+    }
+    let length = selection.length
+    for (let i = 0; i < length; i++) {
+        let item = selection[i]
+        if (item.children) {
+            toggleSelection(item.children, flag)
+        }
     }
-  }
 }
 
 const toggleSelection = (row, selected) => {
-  if (row) {
-    for (let i = 0, len = row.length; i < len; i++) {
-      tableRef.value.toggleRowSelection(row[i], selected)
+    if (row) {
+        for (let i = 0, len = row.length; i < len; i++) {
+            tableRef.value.toggleRowSelection(row[i], selected)
+        }
     }
-  }
 }
 
 const selectionChange = (selection) => {
-  emit('selectionChange', selection)
+    emit('selectionChange', selection)
 }
 
 const rowClick = (row, column, event) => {
-  nextTick(() => {
-    tableRef.value.toggleRowSelection(row)
-    if (row.children) {
-      for (let i = 0, len = row.children.length; i < len; i++) {
-        tableRef.value.toggleRowSelection(row.children[i])
-      }
-    }
-  })
-  emit('rowClick', row, column, event);
+    nextTick(() => {
+        tableRef.value.toggleRowSelection(row)
+        if (row.children) {
+            for (let i = 0, len = row.children.length; i < len; i++) {
+                tableRef.value.toggleRowSelection(row.children[i])
+            }
+        }
+    })
+    emit('rowClick', row, column, event);
 }
 
 /**
@@ -152,45 +151,45 @@ const rowClick = (row, column, event) => {
  * @param val
  */
 const toggleRowSelection = (...val) => {
-  tableRef.value.toggleRowSelection(...val)
+    tableRef.value.toggleRowSelection(...val)
 }
 
 const currentChange = (val) => {
-  if (isLocalData) {
-    pageObject.currentPage = val
-  } else {
-    props.data.currentPage = val
-    emit('currentChange', val)
-  }
-  tableRef.value.setScrollTop(0)
+    if (isLocalData) {
+        pageObject.currentPage = val
+    } else {
+        props.data.currentPage = val
+        emit('currentChange', val)
+    }
+    tableRef.value.setScrollTop(0)
 }
 
 const sizeChange = (val) => {
-  if (isLocalData) {
-    pageObject.pageSize = val
-  } else {
-    props.data.pageSize = val
-    props.data.currentPage = 1
-    if (!props.localPaging) {
-      props.data.total = 0
+    if (isLocalData) {
+        pageObject.pageSize = val
+    } else {
+        props.data.pageSize = val
+        props.data.currentPage = 1
+        if (!props.localPaging) {
+            props.data.total = 0
+        }
+        emit('sizeChange', val)
     }
-    emit('sizeChange', val)
-  }
-  tableRef.value.setScrollTop(0)
+    tableRef.value.setScrollTop(0)
 }
 
 const clearSelection = (msg = true) => {
-  tableRef.value.clearSelection()
-  if (msg) {
-    ElMessage.success('清空成功。');
-  }
+    tableRef.value.clearSelection()
+    if (msg) {
+        ElMessage.success('清空成功。');
+    }
 
 }
 
 const contextmenu = (row, column, event) => {
-  event.returnValue = false
-  event.preventDefault()
-  emit('rowContextmenu', row)
+    event.returnValue = false
+    event.preventDefault()
+    emit('rowContextmenu', row)
 }
 
 /**
@@ -198,39 +197,39 @@ const contextmenu = (row, column, event) => {
  * @returns {*}
  */
 const getSelectionRows = () => {
-  let data = tableRef.value.getSelectionRows()
-  if (data.length > 0) {
-    return data;
-  }
-  BizException(ExceptionEnum.MESSAGE_ERROR, "请先选择数据")
+    let data = tableRef.value.getSelectionRows()
+    if (data.length > 0) {
+        return data;
+    }
+    BizException(ExceptionEnum.MESSAGE_ERROR, "请先选择数据")
 }
 
 let pageObject = $ref({
-  currentPage: 1,
-  pageSize: 30,
-  total: 0,
-  data: []
+    currentPage: 1,
+    pageSize: 30,
+    total: 0,
+    data: []
 })
 
 let isLocalData = $ref(false)
 
 onMounted(() => {
-  if (props.data !== null && props.localData !== null) {
-    throw new Error('data 和 localData 不能同时使用')
-  }
-  if (props.localData !== null) {
-    pageObject.data = props.localData
-    pageObject.total = props.localData.length
-    pageObject.currentPage = 1
-    pageObject.pageSize = 30
-    isLocalData = true
-    watch(() => props.localData, () => {
-      pageObject.data = props.localData
-      pageObject.total = props.localData.length
-    })
-  } else {
-    pageObject = props.data
-  }
+    if (props.data !== null && props.localData !== null) {
+        throw new Error('data 和 localData 不能同时使用')
+    }
+    if (props.localData !== null) {
+        pageObject.data = props.localData
+        pageObject.total = props.localData.length
+        pageObject.currentPage = 1
+        pageObject.pageSize = 30
+        isLocalData = true
+        watch(() => props.localData, () => {
+            pageObject.data = props.localData
+            pageObject.total = props.localData.length
+        })
+    } else {
+        pageObject = props.data
+    }
 })
 
 defineExpose({clearSelection, getSelectionRows, toggleRowSelection})

+ 81 - 0
src/components/zhu-yuan-yi-sheng/emr/EmrQualityControlRelieve/EmrDialog.vue

@@ -0,0 +1,81 @@
+<template>
+    <xc-dialog-v2
+            v-model="dialog"
+            title="申请解锁病历质控限制"
+            @closed="emits('closed')"
+            show-button
+            @cancel="emits('closed')"
+            @confirm="confirm"
+    >
+        <el-form label-width="80" label-position="right">
+            <el-form-item label="解除限制:">
+                <el-checkbox-group v-model="data.unlockArray">
+                    <el-checkbox :label="item" v-for="(item,index) in limit "/>
+                </el-checkbox-group>
+            </el-form-item>
+            <el-form-item label="有效时间:">
+                <el-date-picker v-model="data.effectiveTime"
+                                type="datetime"
+                                style="width: 180px"
+                                format="YYYY-MM-DD HH:mm:ss"
+                                value-format="YYYY-MM-DD HH:mm:ss"/>
+                审核通过后 【{{ data.effectiveTime }}】后该申请失效。
+            </el-form-item>
+            <el-form-item label="申请备注:">
+                <el-input v-model="data.requestRemarks"
+                          type="textarea"
+                          :autosize="{ minRows:3, maxRows: 6 }"
+                          :maxlength="100"
+                          show-word-limit/>
+            </el-form-item>
+        </el-form>
+    </xc-dialog-v2>
+</template>
+
+<script setup name="EmrDialog">
+import XcDialogV2 from "@/components/xiao-chan/dialog/XcDialogV2.vue";
+import {requestToUnlockMedicalRecords} from "@/api/zhu-yuan-yi-sheng/emr-control-rule";
+import {getServerDateApi} from "@/api/public-api";
+import {getFormatDatetime} from "@/utils/date";
+import {xcMessage} from "@/utils/xiaochan-element-plus";
+import {stringIsBlank} from "@/utils/blank-utils";
+import {
+    query
+} from "@/views/hospitalization/zhu-yuan-yi-sheng/electronic-medical-record/emr-editor/emr-init";
+
+const emits = defineEmits(['closed'])
+const dialog = ref(true)
+let newDate = null
+
+const limit = ['转科创建病历', '出院编辑', '病历质控']
+const data = ref({
+    unlockJson: '',
+    unlockArray: [],
+    requestRemarks: '',
+    effectiveTime: ''
+})
+
+
+const confirm = async () => {
+    if (data.value.unlockArray.length === 0) {
+        return xcMessage.error('请选择需要解锁的规则。')
+    }
+    if (stringIsBlank(data.value.requestRemarks)) {
+        return xcMessage.error('请输入解锁备注。')
+    }
+    if (stringIsBlank(data.value.effectiveTime)) {
+        return xcMessage.error('请输入有效时间。')
+    }
+    data.value.unlockJson = JSON.stringify(data.value.unlockArray)
+    data.value.patNo = query.value.patNo
+    data.value.times = query.value.times
+    let res = await requestToUnlockMedicalRecords(data.value);
+    emits('closed')
+}
+
+
+</script>
+
+<style scoped lang="scss">
+
+</style>

+ 16 - 0
src/components/zhu-yuan-yi-sheng/emr/EmrQualityControlRelieve/EmrQualityControlRelieve.vue

@@ -0,0 +1,16 @@
+<template>
+    <el-button type="warning" @click="dialog = true">解锁病历质控</el-button>
+    <emr-dialog v-if="dialog" @closed="dialog = false"/>
+</template>
+
+<script setup name="EmrQualityControlRelieve">
+import EmrDialog from './EmrDialog.vue'
+
+const dialog = ref(false)
+
+
+</script>
+
+<style scoped lang="scss">
+
+</style>

+ 16 - 19
src/components/zhu-yuan-yi-sheng/emr/EmrSidebar.vue

@@ -35,7 +35,6 @@
             </el-tree>
         </div>
         <right-click-menu :mouse-position="mousePosition" :config="opt"/>
-        <unlock-medical-record :data="mousePosition.data.unlock" v-if="dialog" @closed="dialog = false"/>
     </div>
 </template>
 
@@ -47,14 +46,13 @@ import {
 } from "@/api/zhu-yuan-yi-sheng/emr-patient";
 import {BizException, ExceptionEnum} from "@/utils/BizException";
 import {
+    canIUnlockIt,
     emrConfig,
-    emrMitt
+    emrMitt, unlockEnum
 } from '@/views/hospitalization/zhu-yuan-yi-sheng/electronic-medical-record/emr-editor/emr-init'
 import {stringIsBlank} from "@/utils/blank-utils";
 import {getAllWards} from "@/api/zhu-yuan-yi-sheng/resident-doctor";
 import RightClickMenu from "@/components/menu-item/RightClickMenu.vue";
-import {needRule} from "@/utils/public";
-import UnlockMedicalRecord from "@/components/zhu-yuan-yi-sheng/emr/unlock-medical-record/UnlockMedicalRecord.vue";
 import {xcMessage} from "@/utils/xiaochan-element-plus";
 import store from "@/store";
 
@@ -111,6 +109,19 @@ const treeData = computed(() => {
     }
 })
 
+const wardCreationJudgment = async () => {
+    if (determineWhetherItCanBeCreated()) {
+        return
+    }
+    if (await judgeTheCreationOfTransfer()) {
+        return;
+    }
+    if (canIUnlockIt(unlockEnum.转科创建病历)) {
+        return;
+    }
+    BizException(ExceptionEnum.MESSAGE_ERROR, "当前患者所在病区不在您的管理病区范围内,无法创建病历。");
+}
+
 const handleNodeClick = async (val) => {
     let temp = {}
     if (templateType === 0 || templateType === 1) {
@@ -122,11 +133,7 @@ const handleNodeClick = async (val) => {
             name: val.name,
             createId: null
         }
-        if (!determineWhetherItCanBeCreated()) {
-            if (!await judgeTheCreationOfTransfer()) {
-                BizException(ExceptionEnum.MESSAGE_ERROR, "当前患者所在病区不在您的管理病区范围内,无法创建病历。");
-            }
-        }
+        await wardCreationJudgment()
     } else if (templateType === 2) {
         temp = {
             documentId: val.emrDocumentId,
@@ -161,7 +168,6 @@ const handleNodeClick = async (val) => {
     } else {
         emit('nodeClick', temp, false, templateType);
     }
-
 }
 
 const determineWhetherItCanBeCreated = () => {
@@ -285,15 +291,6 @@ const opt = [
             }
             dialog = true
         }
-    },
-    {
-        name: '打开已保存的病历', click: (data) => {
-            if (!data.unlock.id) {
-                xcMessage.error('请选中保存的病历。')
-                return
-            }
-            emit('openAndSaveTheMedicalRecord', data.unlock.id)
-        }
     }
 ]
 const contextmenuItem = (event, data) => {

+ 0 - 146
src/components/zhu-yuan-yi-sheng/emr/discharged-emr-modify-apply/EmrApply.vue

@@ -1,146 +0,0 @@
-<template>
-  <xc-table :local-data="reqData" :height="220">
-    <el-table-column fixed="left" width="150">
-      <template #header>
-        <el-button type="success" icon="Plus" title="添加申请" @click="addReqClick"/>
-        <el-button type="primary" icon="Search" title="查询数据" @click="queryData"/>
-      </template>
-      <template #default="{row}">
-        <el-button type="danger" icon="Delete" title="删除" @click="deleteClick(row)"/>
-        <el-button type="warning" icon="Edit" title="编辑" @click="editClick(row)"/>
-      </template>
-    </el-table-column>
-    <el-table-column label="住院号" prop="patNo" width="70"/>
-    <el-table-column label="修改时间" prop="editDate" width="80"/>
-    <el-table-column label="状态" prop="reqStatusName" width="50">
-      <template #default="{row}">
-        <span v-html="row.reqStatusHtml"></span>
-      </template>
-    </el-table-column>
-    <el-table-column label="申请备注" prop="reqRemarks" show-overflow-tooltip/>
-    <el-table-column label="审核备注" prop="reviewNotes" show-overflow-tooltip/>
-  </xc-table>
-
-  <xc-dialog-v2 v-model="dialog" width="30%" title="申请">
-    <el-form label-width="80px" :rules="rules" ref="formRef" :model="fromData">
-      <el-row>
-        <el-col :span="24">
-          <el-form-item label="住院号:" prop="inpatient">
-            <el-input style="width: 120px" v-model="fromData.inpatientNo" @blur="model=$event.target.value.trim()"/>
-          </el-form-item>
-        </el-col>
-        <el-col :span="24">
-          <el-form-item label="次数:" prop="times">
-            <el-input-number v-model="fromData.times" :min="1"/>
-          </el-form-item>
-        </el-col>
-        <el-col :span="24">
-          <el-form-item label="时间:" prop="editDate">
-            <el-date-picker type="date"
-                            :disabled-date="disabledDate"
-                            v-model="fromData.editDate"
-                            value-format="YYYY-MM-DD"
-                            format="YYYY-MM-DD"/>
-          </el-form-item>
-        </el-col>
-        <el-col :span="24">
-          <el-form-item label="备注:" prop="reqRemarks">
-            <el-input type="textarea" rows="3" maxlength="50" show-word-limit v-model="fromData.reqRemarks"/>
-          </el-form-item>
-        </el-col>
-        <el-col :span="24">
-          <el-form-item label="">
-            <el-button @click="submit">提交</el-button>
-          </el-form-item>
-        </el-col>
-      </el-row>
-    </el-form>
-  </xc-dialog-v2>
-</template>
-
-<script setup name='EmrApply'>
-import XcTable from "@/components/xiao-chan/xc-table/XcTable.vue";
-import XcDialogV2 from "@/components/xiao-chan/dialog/XcDialogV2.vue";
-import {deleteDisEmrDis, getDisReqEmr, saveDisEmrReq} from "@/api/zhu-yuan-yi-sheng/emr-patient";
-import {getServerDateApi} from "@/api/public-api";
-import moment from "moment";
-
-let reqData = $ref([])
-let dialog = $ref(false)
-let fromData = $ref({
-  patNo: '',
-  inpatient: '',
-  times: 1,
-  editDate: null,
-  reqRemarks: '',
-})
-let formRef = $ref(null)
-
-let rules = $ref({
-  inpatientNo: [{required: true, message: '字段值不可为空'}],
-  reqRemarks: [{required: true, message: '字段值不可为空'}],
-  editDate: [{required: true, message: '字段值不可为空'}],
-})
-
-const addReqClick = () => {
-  fromData = {
-    patNo: '',
-    inpatient: '',
-    times: 1,
-    editDate: null,
-    reqRemarks: '',
-  }
-  dialog = true
-}
-
-// 点击编辑
-const editClick = (val) => {
-  let temp = val.patNo.split("_")
-  fromData = val
-  fromData.inpatientNo = temp[0]
-  fromData.times = parseInt(temp[1])
-  dialog = true
-}
-
-// 确认申请
-const submit = () => {
-  formRef.validate(valid => {
-    if (!valid) return
-    fromData.patNo = fromData.inpatientNo + '_' + fromData.times
-    saveDisEmrReq(fromData).then((res) => {
-      dialog = false
-      queryData()
-    })
-  })
-}
-
-// 删除申请
-const deleteClick = (val) => {
-  deleteDisEmrDis(val.patNo).then(() => {
-    queryData()
-  })
-}
-
-const queryData = () => {
-  getDisReqEmr(1).then((res) => {
-    reqData = res
-  })
-}
-
-let newDate = null
-let manDate = null
-const disabledDate = (time) => {
-  return time.getTime() < newDate.getTime() || time.getTime() > manDate.getTime()
-}
-
-onMounted(async () => {
-  queryData()
-  newDate = new Date(await getServerDateApi())
-  manDate = new Date(moment(newDate).add(7, 'days'))
-})
-
-</script>
-
-<style scoped lang="scss">
-
-</style>

+ 0 - 41
src/components/zhu-yuan-yi-sheng/emr/discharged-emr-modify-apply/EmrDownDialog.vue

@@ -1,41 +0,0 @@
-<template>
-    <el-button type="success" icon="Download" title="下载" @click="downloadClick"/>
-    <el-dialog v-model="dialog" title="时间选择">
-        <xc-date-picker v-model="date"/>
-        <template #footer>
-            <el-button @click="submit">确认</el-button>
-        </template>
-    </el-dialog>
-</template>
-
-<script setup name='EmrDownDialog'>
-import {downloadTheDischargeEdit} from "@/api/zhu-yuan-yi-sheng/emr-patient";
-import XcDatePicker from "@/components/xiao-chan/date-picker/XcDatePicker.vue";
-import {getDateRangeFormatDate} from "@/utils/date";
-import {Export} from "@/utils/ExportExcel";
-
-const dialog = ref(false)
-const date = ref([])
-
-const downloadClick = () => {
-    dialog.value = true
-}
-
-const submit = async () => {
-    let {startTime, endTime} = getDateRangeFormatDate(date.value)
-    let res = await downloadTheDischargeEdit(startTime, endTime)
-
-    let exHeader = {
-        patNo: '住院号',
-        reqName: '申请人',
-        creationTime: '申请时间',
-        editDate: '编辑时间',
-        reqRemarks: '申请备注',
-    }
-    Export(res, exHeader, '出院编辑')
-}
-</script>
-
-<style scoped lang="scss">
-
-</style>

+ 0 - 70
src/components/zhu-yuan-yi-sheng/emr/discharged-emr-modify-apply/EmrToExamine.vue

@@ -1,70 +0,0 @@
-<template>
-    <xc-table :local-data="reqData" :height="220">
-        <el-table-column label="操作" fixed="left" width="150">
-            <template #header>
-                <el-button type="primary" icon="Search" title="查询数据" @click="queryData"/>
-                <emr-down-dialog/>
-            </template>
-            <template #default="{row}">
-                <el-button type="success" icon="Check" title="通过" @click="adoptClick(row.patNo)"/>
-                <el-button type="danger" icon="Close" title="拒绝" @click="refuseClick(row.patNo)"/>
-            </template>
-        </el-table-column>
-        <el-table-column label="住院号" prop="patNo" width="70"/>
-        <el-table-column label="修改时间" prop="editDate" width="80"/>
-        <el-table-column label="状态" prop="reqStatusName" width="50">
-            <template #default="{row}">
-                <span v-html="row.reqStatusHtml"></span>
-            </template>
-        </el-table-column>
-        <el-table-column label="申请备注" prop="reqRemarks" show-overflow-tooltip/>
-        <el-table-column label="审核备注" prop="reviewNotes" show-overflow-tooltip/>
-    </xc-table>
-</template>
-
-<script setup name='EmrToExamine'>
-
-import XcTable from "@/components/xiao-chan/xc-table/XcTable.vue";
-import {adoptEmrDisReq, getDisReqEmr, refuseEmrDisReq} from "@/api/zhu-yuan-yi-sheng/emr-patient";
-import {ElMessageBox} from "element-plus";
-import EmrDownDialog from "@/components/zhu-yuan-yi-sheng/emr/discharged-emr-modify-apply/EmrDownDialog.vue";
-
-let reqData = $ref([])
-
-const queryData = () => {
-    getDisReqEmr(2).then((res) => {
-        reqData = res
-    })
-}
-
-
-const adoptClick = (patNo) => {
-    adoptEmrDisReq(patNo).then((res) => {
-        queryData()
-    })
-}
-
-const refuseClick = (patNo) => {
-    ElMessageBox.prompt('驳回信息', '提示', {
-        type: 'warning',
-        confirmButtonText: '确定',
-        cancelButtonText: '取消',
-        inputPattern: /\S/,
-        inputErrorMessage: '驳回信息不能为空且不得超过 100 字 (∩•̀ω•́)⊃-*⋆',
-    }).then(({value}) => {
-        refuseEmrDisReq(patNo, value).then((res) => {
-            queryData()
-        })
-        console.log(value)
-    })
-}
-
-onMounted(() => {
-    queryData()
-})
-
-</script>
-
-<style scoped lang="scss">
-
-</style>

+ 0 - 70
src/components/zhu-yuan-yi-sheng/emr/unlock-medical-record/UnlockMedicalRecord.vue

@@ -1,70 +0,0 @@
-<template>
-  <xc-dialog-v2 v-model="dialog"
-                title="申请解锁限制"
-                @closed="emits('closed')"
-                show-button
-                confirm-text="申请"
-                @cancel="cancel"
-                @confirm="confirm">
-    <el-form label-position="right" label-width="100px">
-      <el-form-item label="病历id:">
-        {{ props.data.id }}
-      </el-form-item>
-      <el-form-item label="编码:">
-        {{ props.data.code }}
-      </el-form-item>
-      <el-form-item label="解锁到:">
-        <el-date-picker
-            v-model="dateValue"
-            type="date"
-            format="YYYY-MM-DD"
-            value-format="YYYY-MM-DD"/>
-      </el-form-item>
-      <el-form-item label="申请备注:">
-        <el-input v-model="inputValue"/>
-      </el-form-item>
-    </el-form>
-  </xc-dialog-v2>
-</template>
-
-<script setup name='UnlockMedicalRecord'>
-import XcDialogV2 from "@/components/xiao-chan/dialog/XcDialogV2.vue";
-import {removalOfMedicalRecordRestrictions} from "@/api/zhu-yuan-yi-sheng/emr-control-rule";
-import {xcMessage} from "@/utils/xiaochan-element-plus";
-
-const props = defineProps({
-  data: {
-    type: Object
-  }
-})
-
-const emits = defineEmits(['closed'])
-
-const dialog = ref(true)
-const dateValue = ref()
-const inputValue = ref()
-
-const cancel = () => {
-  dialog.value = false
-}
-
-const confirm = async () => {
-  if (!dateValue.value) {
-    return xcMessage.error('时间不能为空')
-  }
-  let data = props.data
-  data['date'] = dateValue.value
-  data['remarks'] = inputValue.value
-  await removalOfMedicalRecordRestrictions(data)
-  cancel()
-}
-
-onMounted(() => {
-  console.log(props.data)
-})
-
-</script>
-
-<style scoped lang="scss">
-
-</style>

+ 0 - 7
src/router/modules/dashboard.js

@@ -86,13 +86,6 @@ const route = [
                     title: '恢复病历',
                 },
             },
-            {
-                path: 'dischargedEmrModifyApply',
-                component: createNameComponent(() => import('@/views/hospitalization/zhu-yuan-yi-sheng/electronic-medical-record/DischargedEmrModifyApply.vue')),
-                meta: {
-                    title: '申请出院病历编辑',
-                },
-            },
             {
                 path: 'medicalHistoryPrompts',
                 component: createNameComponent(() => import('@/views/hospitalization/zhu-yuan-yi-sheng/electronic-medical-record/MedicalHistoryPrompts.vue')),

+ 16 - 0
src/utils/store-public.ts

@@ -0,0 +1,16 @@
+import {computed, ComputedRef} from "vue";
+import store from '../store'
+
+export const userInfoStore: ComputedRef<{
+    code: string
+    codeRs: string
+    deptCode: string
+    deptName: string
+    name: string
+    partTimeDeptMap: Object
+    roles: Array<number>
+    token: string
+    sid: string
+}> = computed(() => {
+    return store.state.user.info
+})

+ 0 - 22
src/views/hospitalization/zhu-yuan-yi-sheng/electronic-medical-record/DischargedEmrModifyApply.vue

@@ -1,22 +0,0 @@
-<template>
-  <el-tabs v-model="tabsMod">
-    <el-tab-pane name="1" label="申请编辑">
-      <emr-apply/>
-    </el-tab-pane>
-    <el-tab-pane name="2" label="审核" v-if="needRule(38)">
-      <emr-to-examine/>
-    </el-tab-pane>
-  </el-tabs>
-</template>
-
-<script setup name='DischargedEmrModifyApply'>
-import EmrApply from "@/components/zhu-yuan-yi-sheng/emr/discharged-emr-modify-apply/EmrApply.vue";
-import EmrToExamine from "@/components/zhu-yuan-yi-sheng/emr/discharged-emr-modify-apply/EmrToExamine.vue";
-import {needRule} from "@/utils/public";
-
-let tabsMod = $ref('1')
-</script>
-
-<style scoped lang="scss">
-
-</style>

+ 124 - 114
src/views/hospitalization/zhu-yuan-yi-sheng/electronic-medical-record/EmrRelieveRule.vue

@@ -1,140 +1,150 @@
 <template>
-  <!--  todo 加一个导出的功能 -->
-  <page-layer>
-
-    <template #header>
-      <xc-date-picker v-model="queryParam.applicationTime"/>
-      <el-select v-model="queryParam.flag">
-        <el-option label="全部" :value="-1"/>
-        <el-option label="待审核" :value="0"/>
-        <el-option label="通过" :value="1"/>
-        <el-option label="不通过" :value="2"/>
-      </el-select>
-      <el-button icon="Search" @click="queryData" type="primary">查询</el-button>
-      <el-button icon="Download" @click="download" type="primary">导出</el-button>
-    </template>
-
-    <template #main>
-      <xc-table :local-data="data" :height="100">
-        <el-table-column label="审核" prop="patNo" width="70">
-          <template #default="{row}">
-            <span v-html="flagToHtml(row)"/>
-          </template>
-        </el-table-column>
-        <el-table-column label="住院号" prop="patNo">
-          <template #default="{row}">
-            {{ row.patNo + "_" + row.times }}
-          </template>
-        </el-table-column>
-        <el-table-column label="病历编码" prop="code"/>
-        <el-table-column label="病历名称" prop="emrName"/>
-        <el-table-column label="修改日期" prop="date"/>
-        <el-table-column label="申请人" prop="inputName"/>
-        <el-table-column label="申请时间" prop="inputDate" show-overflow-tooltip/>
-        <el-table-column label="申请备注" prop="inputRemark" show-overflow-tooltip/>
-        <el-table-column label="审核人" prop="reviewedName"/>
-        <el-table-column label="审核备注" prop="reviewNotes"/>
-        <el-table-column label="审核日期" prop="reviewedTime"/>
-        <el-table-column v-if="needRule(38)">
-          <template #header>
-            <el-button icon="Search" @click="queryData" type="primary"/>
-          </template>
-          <template #default="{row}">
-            <el-button type="success" icon="Check" @click="approved(row.id,1)"></el-button>
-            <el-button type="danger" icon="Close" @click="approved(row.id,2)"></el-button>
-          </template>
-        </el-table-column>
-      </xc-table>
-    </template>
-
-  </page-layer>
+    <page-layer>
+        <template #header>
+            <xc-date-picker v-model="queryParam.applicationTime"/>
+            <el-select v-model="queryParam.flag">
+                <el-option label="全部" :value="-1"/>
+                <el-option label="待审核" :value="0"/>
+                <el-option label="通过" :value="1"/>
+                <el-option label="不通过" :value="2"/>
+            </el-select>
+            <el-button icon="Search" @click="queryData()" type="primary">查询</el-button>
+            <el-button icon="Download" @click="download" type="primary">导出</el-button>
+        </template>
+
+        <template #main>
+            <xc-table :data="queryParam" @current-change="currentPage" :final-height="getWindowSize.h / 1.1"
+                      open-paging>
+                <el-table-column label="住院号" prop="patNo" width="90"/>
+                <el-table-column label="次数" prop="times" width="90"/>
+                <el-table-column label="申请人" prop="applicantName" width="90"/>
+                <el-table-column label="申请时间" prop="applicationTime" width="130"/>
+                <el-table-column label="申请权限" prop="unlockJson" width="130"/>
+                <el-table-column label="申请编辑" prop="effectiveTime" width="130"/>
+                <el-table-column label="申请备注" prop="requestRemarks" width="450"
+                                 show-overflow-tooltip
+                                 show-tooltip-when-overflow/>
+                <el-table-column label="状态" prop="state" width="100">
+                    <template #default="{row}">
+                        <component :is="stateHtml(row.state)"/>
+                    </template>
+                </el-table-column>
+                <el-table-column label="审核人" prop="approveName" width="90"/>
+                <el-table-column label="审核时间" prop="reviewTime" width="130"/>
+                <el-table-column label="审核备注" prop="reviewNotes" width="130"/>
+
+                <el-table-column label="操作" width="120" fixed="right">
+                    <template #default="{row}">
+                        <el-button @click="approved(row)">通过</el-button>
+                        <el-button @click="refuseToPass(row)">拒绝</el-button>
+                    </template>
+                </el-table-column>
+            </xc-table>
+        </template>
+
+    </page-layer>
 
 </template>
 
 <script setup name='EmrRelieveRule'>
-import XcTable from "@/components/xiao-chan/xc-table/XcTable.vue";
-import {reviewToLiftRestrictions, selectRuleUnlock} from "@/api/zhu-yuan-yi-sheng/emr-control-rule";
-import {needRule} from "@/utils/public";
-import {ElMessageBox} from "element-plus";
 import PageLayer from "@/layout/PageLayer.vue";
 import XcDatePicker from "@/components/xiao-chan/date-picker/XcDatePicker.vue";
-import {ExcelName, Export} from "@/utils/ExportExcel";
-
-let data = $ref([])
-let queryParam = $ref({
-  applicationTime: [],
-  flag: -1
+import {
+    getApplicationData,
+    reviewMedicalRecordsToUnlock
+} from "@/api/zhu-yuan-yi-sheng/emr-control-rule";
+import XcTable from "@/components/xiao-chan/xc-table/XcTable.vue";
+import {getWindowSize} from "@/utils/window-size";
+import {ElMessageBox, ElTag} from "element-plus";
+import {clone} from "@/utils/clone";
+import {downloadExcel} from "@/utils/excel";
+
+const queryParam = ref({
+    applicationTime: '',
+    flag: 0,
+
+    currentPage: 1,
+    pageSize: 30,
+    total: 0,
+    data: []
 })
 
-
-const queryData = () => {
-  selectRuleUnlock(queryParam).then((res) => {
-    data = res
-  })
+const queryData = (total = 0) => {
+    queryParam.value.total = total
+    console.log(queryParam.value)
+    getApplicationData(queryParam.value).then(res => {
+        queryParam.value.data = res.records
+    })
 }
 
-const approved = (id, flag) => {
-  if (flag === 1) {
-    reviewToLiftRestrictions({
-      id, flag, reviewNotes: null
-    }).then(() => {
-      queryData()
-    })
-  } else {
-    ElMessageBox.prompt('拒绝申请备注', '提示', {
-      type: 'warning',
-      inputErrorMessage: '拒绝原因,不能为空,最多可输入50个字符。',
-      inputValidator: (val) => {
-        if (val === null || val.length < 1 || val.length > 50) {
-          return false;
-        }
-      },
-    }).then(({value}) => {
-      reviewToLiftRestrictions({
-        id, flag, reviewNotes: value
-      }).then(() => {
-        queryData()
-      })
-    }).catch(() => {
+const currentPage = (val) => {
+    queryParam.value.currentPage = val
+    queryData(queryParam.value.total)
+}
 
+const download = () => {
+    const tempData = {
+        param: queryParam.value,
+        url: '/emrControlRule/exportExcelUnlock',
+        fileName: '质控解锁导出',
+    }
+    setTimeout(() => {
+        downloadExcel(tempData)
     })
-  }
 }
 
-const download = () => {
-  const fields = {
-    flagName: '审核状态',
-    patNo: '住院号',
-    times: '次数',
-    code: '病历编码',
-    emrName: '病历名称',
-    date: '修改日期',
-    inputName: '申请人',
-    inputDate: '申请时间',
-    inputRemark: '申请备注',
-    reviewedName: '审核人',
-    reviewNotes: '审核备注',
-    reviewedTime: '审核日期',
-  }
-  Export(data, fields, '解除病历限制')
+const approved = (row) => {
+    toExamine(row, 1)
 }
 
+const refuseToPass = (row) => {
+    ElMessageBox.prompt('审核备注', '提示', {
+        inputPattern: /\S/,
+        inputErrorMessage: '审核备注不能为空',
+    }).then(({value}) => {
+        toExamine(row, 2, value)
+    })
+}
 
-function flagToHtml(row) {
-  switch (row.flag) {
-    case 0:
-      return '<span style="background-color: #909399;color: white;padding: 10px">待审核</span>';
-    case 1:
-      return '<span style="background-color: #00ff3c;color: black;padding: 10px">通过</span>';
-    case 2:
-      return '<span style="background-color: #F56C6C;color: white;padding: 10px">拒绝</span>';
-  }
+const toExamine = (data, state, reviewNotes = '审核通过') => {
+    let temp = clone(data)
+    temp.state = state
+    temp.reviewNotes = reviewNotes
+    reviewMedicalRecordsToUnlock(temp).then(() => {
+        queryData()
+    })
 }
 
+
 onMounted(() => {
-  queryData()
+    queryData()
 })
 
+const stateHtml = (val) => {
+    switch (val) {
+        case 0:
+            return h(ElTag, {
+                    type: 'info'
+                },
+                {default: () => '待审核'})
+        case 1:
+            return h(ElTag, {
+                    type: 'success'
+                },
+                {default: () => '审核通过'})
+        case 2:
+            return h(ElTag, {
+                    type: 'danger'
+                },
+                {default: () => '审核拒绝'})
+        case 3:
+            return h(ElTag, {
+                    type: 'warning'
+                },
+                {default: () => '申请替换'})
+    }
+}
+
 </script>
 
 <style scoped lang="scss">

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

@@ -388,7 +388,7 @@ import {
     copyEnum,
     getEmrCopy,
     delEmrCopy,
-    completeModeSwitch, query
+    completeModeSwitch, query, canIUnlockIt, unlockEnum
 } from "@/views/hospitalization/zhu-yuan-yi-sheng/electronic-medical-record/emr-editor/emr-init";
 import {ElMessage, ElMessageBox} from "element-plus";
 import {BizException, ExceptionEnum} from "@/utils/BizException";
@@ -1009,16 +1009,26 @@ const courseSegmentLocking = async () => {
     }
     let root = currentEmr.value.getRoot()
     let tempFlag = false
-    if (stringNotBlank(documentId)) {
+
+    if (!canIUnlockIt(unlockEnum.病历质控)) {
         let {
             flag,
             message
-        } = await createRestrictions(categoryCode, documentId, props.huanZheXinXi.inpatientNo + "_" + props.huanZheXinXi.admissTimes + '_' + doctorLevel)
-        tempFlag = flag
-        if (!flag && stringNotBlank(message)) {
-            xcMessage.success(message);
+        } = await createRestrictions(categoryCode, stringNotBlank(documentId) ? documentId : '', props.huanZheXinXi.inpatientNo + "_" + props.huanZheXinXi.admissTimes + '_' + doctorLevel);
+        console.log(flag, message)
+        if (flag) {
+            // 如果是空的病历那么就说明是新建的那么就需要跳转到空的编辑器并且跳转。
+            if (stringIsBlank(documentId)) {
+                emptyEditor();
+                BizException(ExceptionEnum.LOGICAL_ERROR, message)
+            } else {
+                // 如果不是空的就提示锁住主要片段就可以了。
+                xcMessage.error(message)
+            }
+            tempFlag = true
         }
     }
+
     if (documentId) {
         let courseTitles = [];
         let loginUserCode = userData.code;
@@ -1455,12 +1465,20 @@ const monitorPageRefresh = (event) => {
 }
 
 const medicalRecordQualityControl = async () => {
+    // 空的编辑器,不触发这个
+    if (stringIsBlank(categoryCode)) {
+        return
+    }
+    // 如果有申请就不触发
+    if (canIUnlockIt(unlockEnum.病历质控)) {
+        return
+    }
+
     if (stringIsBlank(documentId)) {
-        if (stringIsBlank(categoryCode)) return
         let {
             flag,
             message
-        } = await createRestrictions(categoryCode, stringIsBlank(documentId) ? '' : documentId, props.huanZheXinXi.inpatientNo + "_" + props.huanZheXinXi.admissTimes + '_' + doctorLevel)
+        } = await createRestrictions(categoryCode, '', props.huanZheXinXi.inpatientNo + "_" + props.huanZheXinXi.admissTimes + '_' + doctorLevel)
         if (flag) {
             emptyEditor()
             BizException(ExceptionEnum.LOGICAL_ERROR, message)
@@ -1470,7 +1488,7 @@ const medicalRecordQualityControl = async () => {
             }
         }
     } else {
-        if (stringNotBlank(categoryCode) && categoryCode !== emrCodeEnum.courseRecord) {
+        if (categoryCode !== emrCodeEnum.courseRecord) {
             let {
                 flag,
                 message

+ 18 - 5
src/views/hospitalization/zhu-yuan-yi-sheng/electronic-medical-record/emr-editor/Home.vue

@@ -10,7 +10,8 @@
             次数 ({{ query.times }})
             <emr-leave-hospital-patient @rowClick="disPatients"/>
             <el-button @click="allPatientsInTheHospital" :disabled="query.state === 4">全院患者</el-button>
-            <el-button @click="emrSocketUnlock">解锁病历</el-button>
+            <el-button @click="emrSocketUnlock">解锁重复打开病历</el-button>
+            <emr-quality-control-relieve/>
             <el-button @click="patientListDrawer = !patientListDrawer">患者列表</el-button>
             <el-checkbox v-model="conciseMode" @change="openOrCloseMode" label="简洁模式"/>
             出院天数:{{ dischargeDays }}
@@ -55,11 +56,12 @@ import {isDisReqEdit} from "@/api/zhu-yuan-yi-sheng/emr-patient";
 import {getOperationGuide, getServerDateApi} from "@/api/public-api";
 import {subtractTime} from "@/utils/date";
 import {
+    applicationData, canIUnlockIt,
     completeModeSwitch,
     conciseMode,
     emrConfig,
     query,
-    resolveRoute
+    resolveRoute, unlockEnum
 } from "@/views/hospitalization/zhu-yuan-yi-sheng/electronic-medical-record/emr-editor/emr-init";
 import EmrPatientList from "@/components/zhu-yuan-yi-sheng/emr/EmrPatientList.vue";
 import EmrLeaveHospitalPatient from "@/components/zhu-yuan-yi-sheng/emr/EmrLeaveHospitalPatient.vue";
@@ -67,6 +69,9 @@ import EmrSelectPat from "@/components/zhu-yuan-yi-sheng/EmrSelectPat.vue";
 import XcDialogV2 from "@/components/xiao-chan/dialog/XcDialogV2.vue";
 import {emrSocketUnlockApi, repeatedlyOpenTheSamePatient} from "@/api/zhu-yuan-yi-sheng/emr-socket";
 import {stringIsBlank} from "@/utils/blank-utils";
+import EmrQualityControlRelieve
+    from "@/components/zhu-yuan-yi-sheng/emr/EmrQualityControlRelieve/EmrQualityControlRelieve.vue";
+import {getMyUnlockByPatNo} from "@/api/zhu-yuan-yi-sheng/emr-control-rule";
 
 const patInfoRef = ref(null)
 const patInfoRefOld = ref(null)
@@ -116,7 +121,6 @@ const routerFunc = async () => {
         await router.push(url);
         location.reload()
     }
-
     show = false
     if (router.currentRoute.value.params.pat) {
         resolveRoute(router.currentRoute.value.params.pat)
@@ -127,9 +131,18 @@ const routerFunc = async () => {
             show = false
             BizException(ExceptionEnum.LOGICAL_ERROR, "请勿重复打开病历。")
         }
+        console.log(query.value.times)
+        let reqUnlock = await getMyUnlockByPatNo(query.value.patNo, query.value.times)
+        console.log('申请数据 %o', reqUnlock)
+        if (reqUnlock != null) {
+            reqUnlock.unlockJson = JSON.parse(reqUnlock.unlockJson)
+            applicationData.value = reqUnlock
+        } else {
+            applicationData.value = null
+        }
         if (query.value.state !== 2) {
             patientInfo = await getPatientInfo(query.value.patNo);
-            patientInfo.$inOutFlag = 1
+            patientInfo.$inOutFlag = 1;
         }
         if (query.value.state === 1) {
             await queryActPatient()
@@ -160,7 +173,7 @@ const queryDisPatient = async () => {
     emrConfig.value.editor = dischargeDays <= 7;
     // 如果超过了七天就去查看是否有申请编辑
     if (!emrConfig.value.editor) {
-        emrConfig.value.editor = await isDisReqEdit(query.value.patNo.trim() + '_' + query.value.times)
+        emrConfig.value.editor = canIUnlockIt(unlockEnum.出院编辑)
     }
     show = true;
 }

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

@@ -391,3 +391,39 @@ export const emrChannelEnum = {
     // 医嘱页面
     "medicalAdvice": 'medicalAdvice',
 }
+
+export const applicationData = ref({
+    "id": null,
+    "patNo": "",
+    "times": 0,
+    "unlockJson": null,
+    "applicant": "",
+    "applicantName": null,
+    "applicationTime": "",
+    "requestRemarks": "",
+    "approve": "",
+    "approveName": null,
+    "reviewTime": "",
+    "reviewNotes": "",
+    "effectiveTime": "",
+    "state": null
+})
+
+export const unlockEnum = {
+    "转科创建病历": "转科创建病历",
+    "出院编辑": "出院编辑",
+    "病历质控": "病历质控",
+}
+
+/**
+ * 判断是否可以解锁限制
+ * @param val 需要解锁的限制
+ * @returns {boolean}
+ */
+export function canIUnlockIt(val) {
+    console.log(applicationData.value)
+    if (applicationData.value === null) {
+        return false
+    }
+    return applicationData.value.unlockJson.includes(val)
+}