YiZhuLuRu.vue 17 KB

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