YiZhuLuRu.vue 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479
  1. <template>
  2. <div :style="{width: winsize.editor + 40 + 'px'}" style="margin: 0">
  3. <yz-query-condition :patient-info="huanZheXinXi"
  4. ref="yzQueryRef"
  5. :to-delete-an-order="toDeleteAnOrder"
  6. :add-yi-zhu-click="addYiZhuClick"
  7. :click-on-the-order-template="clickOnTheOrderTemplate"
  8. :confirm-orders-click="confirmOrdersClick"/>
  9. <div>
  10. <div style="height: 5px"/>
  11. <button @click="orderTemplateClick" title="维护自己创建的模板">维护模板</button>
  12. <button @click="clickToStopTheOrder" title="选择了停止时间后记得选中医嘱在点击">批量停止</button>
  13. <el-divider direction="vertical"></el-divider>
  14. <button :disabled="stringIsBlank(huanZheXinXi.inpatientNo)"
  15. @click="clickToModifyTheDoctorSOrderTime"
  16. title="跳转到修改医嘱时间的页面,可修改开始和停止时间">
  17. 修改医嘱时间
  18. </button>
  19. <button :disabled="stringIsBlank(huanZheXinXi.inpatientNo)"
  20. @click="jumpToMedicalRecord" title="跳转到患者的病案首页">
  21. 病案首页
  22. </button>
  23. <button @click="confirmAssociationClick" title="关联医嘱">关联</button>
  24. <button @click="openRationalDrugUse" title="进入到合理用药的页面">合理用药</button>
  25. <button @click="allergen.open()" title="患者过敏源信息维护">患者过敏源信息维护</button>
  26. <button @click="openDualScreen" title="双屏模式">双屏模式</button>
  27. </div>
  28. <div style="height: 5px"/>
  29. <yz-editor :patient-info="huanZheXinXi"
  30. ref="yzEditorRef"
  31. @duplicate-and-paste="duplicateAndPaste"
  32. :current-page="currentPage"
  33. :open-group-order-template="openGroupOrderTemplate"
  34. :successfullyEntered="successfullyEntered"/>
  35. <div style="overflow-x: auto; " :style="{width: winsize.main - 20 + 'px'}">
  36. <yz-table :data="tempYzData"
  37. ref="tableRef"
  38. @rowClick="rowClick"
  39. @clickAssociate="clickAssociate"
  40. :void-orders="voidOrdersClick"/>
  41. <yz-table-v2 ref="tableRef" v-if="false"/>
  42. </div>
  43. <doctor-s-order-fee :data="chargeDetails.data"
  44. v-if="chargeDetails.dialog"
  45. :sum="chargeDetails.sum"
  46. @close="chargeDetails.dialog = false"/>
  47. <!-- 获取模板的数据 -->
  48. <huo-qu-mu-ban
  49. ref="mubanRef"
  50. :editor="false"
  51. @muBanShuJu="muBanShuJu"/>
  52. <xc-dialog v-model="stopOrderDialog.dialog" title="停止医嘱错误信息">
  53. <div v-for="(value,key) in stopOrderDialog.error">
  54. 医嘱号: {{ key }} 序号: {{ getYzIndex(key) + 1 }}
  55. <br>
  56. {{ value }}
  57. </div>
  58. </xc-dialog>
  59. <yao-ping-xiang-qing v-if="drugManual.dialog"
  60. :code="drugManual.code"
  61. @close="drugManual.dialog = false"/>
  62. <!-- 这个是过敏源的 -->
  63. <AllergenEntry v-if="allergen.dialog"
  64. :pat-no="huanZheXinXi.inpatientNo"
  65. @close="allergen.dialog = false"/>
  66. <order-progress ref="orderProgressRef"/>
  67. <!-- 合理用药窗口 -->
  68. <rational-drug-use-window ref="reasonableRef" @submit="confirmOrder"/>
  69. </div>
  70. </template>
  71. <script name="YiZhuLuRuZhuJian" setup>
  72. import {
  73. associateOrdersApi,
  74. insertTemplateOrder,
  75. stopOrder, voidOrders,
  76. } from '@/api/zhu-yuan-yi-sheng/yi-zhu-lu-ru'
  77. import {
  78. huanZheXinXi,
  79. getYzIndex,
  80. winsize,
  81. zkList,
  82. selectedData,
  83. queryParam,
  84. currentPage,
  85. clickOnThePatient,
  86. drugManual,
  87. associateOrders,
  88. clearAssociate, youWuXuanZheHuanZhe, isOpenDualScreen, dualScreenSrc
  89. } from '../public-js/zhu-yuan-yi-sheng'
  90. import store from '@/store'
  91. import {stringIsBlank, stringNotBlank} from '@/utils/blank-utils'
  92. import {getTheTransferList} from '@/api/public-api'
  93. import router from '@/router'
  94. import sleep from "@/utils/sleep";
  95. import DoctorSOrderFee from "@/components/zhu-yuan-yi-sheng/yi-zhu-lu-ru/DoctorSOrderFee.vue";
  96. import {BizException, ExceptionEnum} from "@/utils/BizException";
  97. import {ElMessageBox} from "element-plus";
  98. import YzQueryCondition from "@/components/zhu-yuan-yi-sheng/yi-zhu-lu-ru/yz-header/YzQueryCondition";
  99. import YzTable from "@/components/zhu-yuan-yi-sheng/yi-zhu-lu-ru/table/YzTable";
  100. import YzEditor from "@/components/zhu-yuan-yi-sheng/yi-zhu-lu-ru/yz-edit/YzEditor.vue";
  101. import {tempYzData} from "@/views/hospitalization/zhu-yuan-yi-sheng/public-js/zhu-yuan-yi-sheng";
  102. import HuoQuMuBan from '@/components/zhu-yuan-yi-sheng/yi-zhu-lu-ru/HuoQuMuBan.vue'
  103. import {getFormatDatetime} from "@/utils/date";
  104. import XcDialog from "@/components/xiao-chan/dialog/XcDialog";
  105. import {xcMessage} from "@/utils/xiaochan-element-plus";
  106. import YaoPingXiangQing from "@/components/zhu-yuan-yi-sheng/he-li-yong-yao/YaoPingXiangQing.vue";
  107. import AllergenEntry from "@/components/zhu-yuan-yi-sheng/AllergenEntry.vue";
  108. import OrderProgress from "@/components/zhu-yuan-yi-sheng/yi-zhu-lu-ru/OrderProgress.vue";
  109. import {getEmrUrl} from "@/views/hospitalization/zhu-yuan-yi-sheng/electronic-medical-record/emr-editor/emr-init";
  110. import RationalDrugUseWindow from "@/components/zhu-yuan-yi-sheng/yi-zhu-lu-ru/RationalDrugUseWindow.vue";
  111. import YzTableV2 from "@/components/zhu-yuan-yi-sheng/yi-zhu-lu-ru/table/YzTableV2.vue";
  112. const windowSize = computed(() => {
  113. return store.state.app.windowSize
  114. })
  115. const user = computed(() => {
  116. return store.state.user.info
  117. })
  118. let allergen = $ref({
  119. dialog: false,
  120. open: () => {
  121. if (youWuXuanZheHuanZhe()) return
  122. allergen.dialog = true
  123. }
  124. })
  125. // 医嘱查询
  126. const yzQueryRef = ref(null)
  127. // 医嘱进度
  128. const orderProgressRef = ref(null)
  129. // 医嘱编辑
  130. const yzEditorRef = ref(null)
  131. const successfullyEntered = async () => {
  132. await yzQueryRef.value.queryYz()
  133. queryParam.value.displayRange = 0
  134. queryParam.value.frequCode = 0
  135. queryParam.value.zhuangTai = 0
  136. tableRef.value.scrollToTheEnd()
  137. addYiZhuClick()
  138. }
  139. /**
  140. * 下面这里是添加医嘱了
  141. */
  142. const addYiZhuClick = () => {
  143. yzEditorRef.value.addOrderNo()
  144. }
  145. const reasonableRef = ref(null)
  146. /**
  147. * 确认医嘱 , 已经做过无患者的判断了
  148. */
  149. const confirmOrdersClick = async () => {
  150. // 如果没有问题就可以直接确认医嘱了。
  151. let temp = await reasonableRef.value.check(huanZheXinXi.value.inpatientNo, huanZheXinXi.value.admissTimes)
  152. if (temp) {
  153. await confirmOrder()
  154. console.log('无错误药品直接确认');
  155. }
  156. }
  157. // 真正的向后台确认医嘱
  158. const confirmOrder = async () => {
  159. // 确认医嘱
  160. await yzEditorRef.value.confirmOrdersClick()
  161. // 查询医嘱
  162. await yzQueryRef.value.queryYz();
  163. }
  164. /**
  165. * 删除医嘱
  166. */
  167. const toDeleteAnOrder = () => {
  168. yzEditorRef.value.toDeleteAnOrderClick()
  169. }
  170. const openRationalDrugUse = () => {
  171. window.open('http://172.16.32.121:9097/index.html')
  172. }
  173. // 表格
  174. let tableRef = ref(null)
  175. const rowClick = (val) => {
  176. orderProgressRef.value.fillOrder(val)
  177. if (associateOrders.value.actOrderNo) {
  178. let index = associateOrders.value.associatedGroup.indexOf(val.actOrderNo)
  179. if (associateOrders.value.actOrderNo === val.actOrderNo) {
  180. BizException(ExceptionEnum.MESSAGE_ERROR, '无法关联自己');
  181. }
  182. if (val.serial === '00') {
  183. BizException(ExceptionEnum.MESSAGE_ERROR, '无法关联项目');
  184. }
  185. if (val.statusFlag !== '1') {
  186. BizException(ExceptionEnum.MESSAGE_ERROR, '无法关联不是录入状态的医嘱。');
  187. }
  188. if (index > -1) {
  189. val.associationFlag = false;
  190. associateOrders.value.associatedGroup.splice(index, 1);
  191. } else {
  192. val.associationFlag = true;
  193. associateOrders.value.associatedGroup.push(val.actOrderNo);
  194. }
  195. } else {
  196. yzEditorRef.value.fillData(val)
  197. }
  198. }
  199. const stopOrderDialog = ref({
  200. dialog: false,
  201. error: ''
  202. })
  203. /**
  204. * 停止医嘱
  205. */
  206. const clickToStopTheOrder = () => {
  207. selectedData.value.forEach(item => {
  208. item.endTime = getFormatDatetime(item.endTimeTemp)
  209. })
  210. let param = {
  211. inpatientNo: huanZheXinXi.value.inpatientNo,
  212. admissTimes: huanZheXinXi.value.admissTimes,
  213. list: selectedData.value
  214. }
  215. stopOrder(param).then(res => {
  216. if (res?.error) {
  217. stopOrderDialog.value.error = res.data
  218. stopOrderDialog.value.dialog = true
  219. for (let i = 0; i < selectedData.value.length; i++) {
  220. let item = selectedData.value[i]
  221. item.endTime = ''
  222. }
  223. } else {
  224. stopOrderDialog.value.error = {}
  225. yzQueryRef.value.queryYz()
  226. }
  227. })
  228. }
  229. /**
  230. * 作废医嘱
  231. */
  232. const voidOrdersClick = (val) => {
  233. ElMessageBox.prompt(`请问是否要撤销<br><span style="color: red">【${val.orderName}】</span>医嘱<br>
  234. 撤销父医嘱会自动撤销子医嘱。`, '提示', {
  235. type: 'warning',
  236. confirmButtonText: '确定',
  237. cancelButtonText: '取消',
  238. inputValidator: (val) => {
  239. if (val === null || val.length < 1 || val.length > 50) {
  240. return false;
  241. }
  242. },
  243. dangerouslyUseHTMLString: true,
  244. inputErrorMessage: '作废原因,不能为空,最多可输入50个字符。',
  245. closeOnPressEscape: false,
  246. closeOnClickModal: false
  247. }).then(({value}) => {
  248. voidOrders(val.id, value).then(res => {
  249. yzQueryRef.value.queryYz()
  250. })
  251. }).catch(() => {
  252. })
  253. }
  254. /**
  255. * 右键点击查看医嘱产生的费用
  256. * @param val
  257. */
  258. let doctorSOrderFee = $ref({
  259. data: {},
  260. problem: {},
  261. totalCost: {}
  262. })
  263. let chargeDetails = $ref({
  264. dialog: false,
  265. data: [],
  266. sum: {}
  267. })
  268. const clickToViewTheDoctorSOrderFee = (val) => {
  269. chargeDetails.data = doctorSOrderFee.data[val.actOrderNoStr]
  270. if (chargeDetails.data) {
  271. chargeDetails.sum = doctorSOrderFee.totalCost[val.actOrderNoStr]
  272. chargeDetails.dialog = true
  273. } else {
  274. BizException(ExceptionEnum.MESSAGE_ERROR, '该医嘱还没有产生费用')
  275. }
  276. }
  277. // 获取模板
  278. const mubanRef = ref(null)
  279. const clickOnTheOrderTemplate = () => {
  280. if (stringIsBlank(huanZheXinXi.value.inpatientNo)) {
  281. BizException(ExceptionEnum.MESSAGE_ERROR, '请先选择患者')
  282. }
  283. mubanRef.value.openOrCloseDialog(true)
  284. }
  285. /**
  286. * 把模板的数据插入到患者的医嘱表
  287. * @param val
  288. */
  289. const muBanShuJu = (val) => {
  290. let tempGroupNo = ['71', '73']
  291. if (currentPage.value === 'takeMedicine') {
  292. val = val.filter((item) => {
  293. item.selfBuy = '4'
  294. item.instruction = item.frequCodeName
  295. return item.serial !== '00'
  296. })
  297. if (val.length === 0) {
  298. BizException(ExceptionEnum.LOGICAL_ERROR, '项目无法出院带药。')
  299. }
  300. }
  301. val.forEach(item => {
  302. if (item.serial === '00') {
  303. item.groupNo = '00'
  304. } else {
  305. if (!tempGroupNo.includes(item.groupNo)) {
  306. item.groupNo = queryParam.value.groupNo;
  307. }
  308. }
  309. })
  310. let param = {
  311. inpatientNo: huanZheXinXi.value.inpatientNo,
  312. admissTimes: huanZheXinXi.value.admissTimes,
  313. groupNo: queryParam.value.groupNo,
  314. list: val
  315. }
  316. insertTemplateOrder(param).then(() => {
  317. successfullyEntered()
  318. mubanRef.value.openOrCloseDialog(false)
  319. })
  320. }
  321. /**
  322. * 打开模板的对话框
  323. * @param code
  324. * @returns {Promise<void>}
  325. */
  326. const openGroupOrderTemplate = async (code) => {
  327. mubanRef.value.openOrCloseDialog(true)
  328. await nextTick()
  329. mubanRef.value.openTemplateByCode(code)
  330. }
  331. /**
  332. * 添加模板
  333. */
  334. const orderTemplateClick = () => {
  335. router.push({
  336. name: 'orderTemplateMaintenance',
  337. })
  338. }
  339. onMounted(async () => {
  340. await sleep(200)
  341. zkList.value = await getTheTransferList()
  342. })
  343. // 点击修改医嘱时间
  344. const clickToModifyTheDoctorSOrderTime = () => {
  345. router.push({
  346. name: 'yzActOrderModify',
  347. query: {
  348. patNo: huanZheXinXi.value.inpatientNo,
  349. },
  350. })
  351. }
  352. // 跳转到病案首页
  353. const jumpToMedicalRecord = () => {
  354. router.push({
  355. name: 'fillCaseFrontSheet',
  356. query: {
  357. patNo: huanZheXinXi.value.inpatientNo,
  358. deptCode: huanZheXinXi.value.smallDept,
  359. },
  360. })
  361. }
  362. // 点击关联
  363. const clickAssociate = async (data) => {
  364. if (stringNotBlank(data.parentNo)) {
  365. xcMessage.error('该医嘱已经有父医嘱了。');
  366. } else if (data.statusFlag !== '1') {
  367. xcMessage.error('不是录入状态的医嘱无法关联。');
  368. } else if (data.serial === '00') {
  369. xcMessage.error('项目无法关联。');
  370. } else {
  371. if (associateOrders.value.actOrderNo === null) {
  372. await yzQueryRef.value.queryYz()
  373. associateOrders.value.actOrderNo = data.actOrderNo
  374. } else {
  375. xcMessage.error('请先确认当前关联医嘱。')
  376. }
  377. }
  378. }
  379. // 点击确认关联
  380. const confirmAssociationClick = () => {
  381. if (associateOrders.value.actOrderNo === null) {
  382. BizException(ExceptionEnum.MESSAGE_ERROR, '请先选择需要关联的父医嘱')
  383. }
  384. if (associateOrders.value.associatedGroup.length === 0) {
  385. BizException(ExceptionEnum.MESSAGE_ERROR, '至少选择一个子医嘱')
  386. }
  387. ElMessageBox.confirm('请确认是否要关联这些医嘱。', '提示', {
  388. type: 'warning'
  389. }).then(() => {
  390. associateOrdersApi(associateOrders.value).then((res) => {
  391. clearAssociate()
  392. yzQueryRef.value.queryYz()
  393. })
  394. }).catch(() => {
  395. })
  396. }
  397. const openDualScreen = () => {
  398. if (youWuXuanZheHuanZhe()) return
  399. isOpenDualScreen.value = !isOpenDualScreen.value
  400. dualScreenSrc.value = getEmrUrl(huanZheXinXi.value.inpatientNo, huanZheXinXi.value.admissTimes, 1)
  401. }
  402. const duplicateAndPaste = async () => {
  403. await yzQueryRef.value.queryYz()
  404. tableRef.value.scrollToTheEnd()
  405. }
  406. watch(() => router.currentRoute.value, () => {
  407. currentPage.value = router.currentRoute.value.query.pattern
  408. }, {immediate: true})
  409. onActivated(async () => {
  410. if (router.currentRoute.value.params.inpatientNo) {
  411. await nextTick()
  412. clickOnThePatient(router.currentRoute.value.params.inpatientNo);
  413. await yzQueryRef.value.queryYz()
  414. }
  415. })
  416. </script>
  417. <style scoped lang="scss">
  418. :deep(.el-table .children-row) {
  419. background: rgba(145, 247, 145, 0.93);
  420. }
  421. :deep(.el-table) {
  422. --el-table-row-hover-background-color: #85dbfd7a;
  423. }
  424. :deep(.el-dropdown-menu__item) {
  425. font-size: 14px !important;
  426. height: 26px;
  427. line-height: 26px;
  428. font-weight: bold;
  429. }
  430. </style>