MzSpltryRcrd.vue 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573
  1. <template>
  2. <el-container>
  3. <el-header>
  4. <el-input v-model="patNo" style="width: 120px; margin-left: 2px" clearable placeholder="门诊id"> </el-input>
  5. <el-select v-model="medType" style="width: 120px" placeholder="医疗类别">
  6. <el-option v-for="item in medTypes" :key="item.code" :value="item.code" :label="item.name"></el-option>
  7. </el-select>
  8. <el-date-picker
  9. style="width: 200px"
  10. v-model="dateRange"
  11. type="daterange"
  12. :shortcuts="shortcuts"
  13. range-separator="至"
  14. start-placeholder="开始日期"
  15. end-placeholder="结束日期"
  16. ></el-date-picker>
  17. <el-divider direction="vertical"></el-divider>
  18. <el-button type="primary" @click="fetchHistoryReceipts">历史处方</el-button>
  19. <ReadCard :pat-no="patNo" @success="afterReadCard" />
  20. <el-dropdown trigger="click" @command="registor">
  21. <el-button type="primary">
  22. 登记&nbsp;<el-icon><ArrowDown /></el-icon>
  23. </el-button>
  24. <template #dropdown>
  25. <el-dropdown-menu>
  26. <el-dropdown-item icon="CreditCard" command="execute">医保登记</el-dropdown-item>
  27. <el-dropdown-item icon="RefreshLeft" command="revoke">取消登记</el-dropdown-item>
  28. </el-dropdown-menu>
  29. </template>
  30. </el-dropdown>
  31. <el-dropdown trigger="click" @command="receiptsOpts" style="margin-left: 8px">
  32. <el-button type="primary">
  33. 处方&nbsp;<el-icon><ArrowDown /></el-icon>
  34. </el-button>
  35. <template #dropdown>
  36. <el-dropdown-menu>
  37. <el-dropdown-item icon="Document" command="insert">生成医保处方</el-dropdown-item>
  38. <el-dropdown-item icon="Delete" command="delete">删除已生成处方</el-dropdown-item>
  39. <el-dropdown-item icon="Upload" command="upload">医保处方上传</el-dropdown-item>
  40. <el-dropdown-item icon="RefreshLeft" command="retract">撤销医保上传</el-dropdown-item>
  41. </el-dropdown-menu>
  42. </template>
  43. </el-dropdown>
  44. <el-dropdown trigger="click" @command="settlement" style="margin-left: 8px">
  45. <el-button type="primary">
  46. 结算&nbsp;<el-icon><ArrowDown /></el-icon>
  47. </el-button>
  48. <template #dropdown>
  49. <el-dropdown-menu>
  50. <el-dropdown-item icon="SetUp" command="pre">试算</el-dropdown-item>
  51. <el-dropdown-item icon="Stamp" command="fin">结算</el-dropdown-item>
  52. <el-dropdown-item icon="RefreshLeft" command="revoke">取消结算</el-dropdown-item>
  53. </el-dropdown-menu>
  54. </template>
  55. </el-dropdown>
  56. <el-button type="danger" icon="Refresh" @click="clearinfo" style="margin-left: 8px"> 重置 </el-button>
  57. </el-header>
  58. <el-container>
  59. <el-aside width="300px">
  60. <el-tag>历史处方目录</el-tag>
  61. <el-table :height="tableHeight" :data="historyReceipts" stripe highlight-current-row @row-click="fetchHistoryReceiptDetail">
  62. <el-table-column property="patNo" label="Id号" width="70">
  63. <template #default="scope">
  64. <span v-html="colorStatus(scope.row)"></span>
  65. </template>
  66. </el-table-column>
  67. <el-table-column property="times" label="次数" width="40"></el-table-column>
  68. <el-table-column property="chargeFee" label="金额" width="60"></el-table-column>
  69. <el-table-column property="chargeDate" label="时间"></el-table-column>
  70. </el-table>
  71. </el-aside>
  72. <el-main>
  73. <el-tag>历史处方明细</el-tag>
  74. <div :style="receiptBoxStyle">
  75. <div v-for="(item, index) in currentReceipts" :key="index">
  76. <div>
  77. <el-checkbox v-model="item.checked"></el-checkbox>&nbsp;
  78. <span style="color: rgb(94, 50, 50)"> {{ index + 1 }})【{{ item.chargeItemCode }}】{{ item.drugName }}&nbsp;&times;&nbsp;&nbsp;{{ item.quantity }} </span>
  79. <span :style="{ color: item.nationalCode ? 'green' : 'red', fontWeight: 'bold' }"> &nbsp;&nbsp;【医保码:{{ item.nationalCode || '未匹配' }} 】</span>
  80. </div>
  81. <div style="margin-bottom: 16px"></div>
  82. </div>
  83. </div>
  84. <el-dialog title="个人参保信息" v-model="showInsuinfo" width="65%">
  85. <el-table :data="insuinfo" @row-click="handleClickInsuinfo">
  86. <el-table-column property="balc" label="余额"></el-table-column>
  87. <el-table-column label="险种类型" prop="insutypeName"></el-table-column>
  88. <el-table-column label="人员类别" prop="psnTypeName"></el-table-column>
  89. <el-table-column label="参保状态" prop="psnInsuStasName"></el-table-column>
  90. <el-table-column property="psnInsuDate" label="个人参保日期"></el-table-column>
  91. <el-table-column property="pausInsuDate" label="暂停参保日期"></el-table-column>
  92. <el-table-column property="cvlservFlagName" label="公务员标志"></el-table-column>
  93. <el-table-column property="insuplcAdmdvs" label="参保地医保区划"></el-table-column>
  94. <el-table-column property="insuplcAdmdvsName" label="参保地名称"></el-table-column>
  95. <el-table-column property="empName" label="单位名称"></el-table-column>
  96. </el-table>
  97. </el-dialog>
  98. <el-dialog title="请选择(慢特病备案信息)" v-model="showSpcChrAccts" width="40%">
  99. <el-table :data="spcChrDiseAccts" @row-click="uploadFees">
  100. <el-table-column property="opspDiseCode" label="病种编码"></el-table-column>
  101. <el-table-column property="opspDiseName" label="病种名称"></el-table-column>
  102. <el-table-column property="begndate" label="生效日期"></el-table-column>
  103. <el-table-column property="enddate" label="失效日期"></el-table-column>
  104. </el-table>
  105. </el-dialog>
  106. <el-dialog title="请选择生育诊断" v-model="showMatnDises" width="50%">
  107. <el-table :data="matnDises" @row-click="uploadFees" stripe height="360" highlight-current-row>
  108. <el-table-column property="code" label="病种编码"></el-table-column>
  109. <el-table-column property="name" label="病种名称"></el-table-column>
  110. <el-table-column property="insutype" label="险种类型"></el-table-column>
  111. <el-table-column property="limitAmt" label="疾病限额"></el-table-column>
  112. </el-table>
  113. </el-dialog>
  114. </el-main>
  115. </el-container>
  116. </el-container>
  117. </template>
  118. <script>
  119. import {
  120. deleteAllMzReceipts,
  121. getHistoryMzReceipts,
  122. getHistoryReceiptDetail,
  123. insertSiMzFees,
  124. outpatientPreSettlement,
  125. outpatientRegistration,
  126. revokeOutpatientFeeDetails,
  127. revokeOutpatientRegistration,
  128. uploadOutpatientFeeDetails,
  129. outpatientSettlement,
  130. revokeOutpatientSettlement,
  131. } from '@/api/medical-insurance/si-outpatient'
  132. import { obtainBasicPersonInfo, querySpecialChronicDiseasesAccreditation, queryMzMatnDises } from '@/api/medical-insurance/si-query'
  133. import { onMounted, ref } from 'vue'
  134. import store from '@/store'
  135. import { ElMessage, ElMessageBox } from 'element-plus'
  136. import { getMedTypesByFlag } from '@/api/medical-insurance/si-dict'
  137. import { shortcuts } from '@/data/shortcuts'
  138. import { getDateRangeFormatDate } from '@/utils/date'
  139. import ReadCard from '@/components/medical-insurance/readcard/Index.vue'
  140. export default {
  141. components: {
  142. ReadCard,
  143. },
  144. setup() {
  145. const windowSize = store.state.app.windowSize
  146. const tableHeight = windowSize.h - 70
  147. const receiptBoxStyle = {
  148. height: tableHeight - 8 + 'px',
  149. marginTop: '8px',
  150. overflowY: 'auto',
  151. }
  152. const patNo = ref('')
  153. const medType = ref('')
  154. const medTypes = ref([])
  155. const historyReceipts = ref([])
  156. const currentRow = ref({})
  157. const currentReceipts = ref([])
  158. const dateRange = ref(shortcuts[2].value)
  159. const colorStatus = (row) => {
  160. return row.status > 0 ? `<span style="color: green">${row.patNo}</span>` : `<span style="color: red">${row.patNo}</span>`
  161. }
  162. const nullPatNo = () => {
  163. if (patNo.value) {
  164. return false
  165. }
  166. ElMessage({
  167. message: '请输入门诊ID!',
  168. type: 'warning',
  169. duration: 2500,
  170. showClose: true,
  171. })
  172. return true
  173. }
  174. const nullMedtype = () => {
  175. if (medType.value) {
  176. return false
  177. }
  178. ElMessage({
  179. message: '请选择医疗类别!',
  180. type: 'warning',
  181. duration: 2500,
  182. showClose: true,
  183. })
  184. return true
  185. }
  186. const fetchHistoryReceipts = () => {
  187. if (nullPatNo()) {
  188. return
  189. }
  190. if (nullMedtype()) {
  191. return
  192. }
  193. if (!dateRange.value) {
  194. ElMessage({
  195. message: '请选择日期范围!',
  196. type: 'warning',
  197. duration: 2500,
  198. showClose: true,
  199. })
  200. return
  201. }
  202. clearReadCardData()
  203. historyReceipts.value = []
  204. currentRow.value = {}
  205. const dates = getDateRangeFormatDate(dateRange.value)
  206. getHistoryMzReceipts(patNo.value, dates.startTime, dates.endTime).then((res) => {
  207. historyReceipts.value = res
  208. })
  209. }
  210. const fetchHistoryReceiptDetail = (row) => {
  211. currentRow.value = row
  212. getHistoryReceiptDetail(row).then((res) => {
  213. currentReceipts.value = res
  214. })
  215. }
  216. const insuinfo = ref([])
  217. const showInsuinfo = ref(false)
  218. const registor = (command) => {
  219. if (!currentRow.value.times) {
  220. ElMessage({
  221. message: '请先选择历史处方。',
  222. type: 'warning',
  223. duration: 2000,
  224. showClose: true,
  225. })
  226. return
  227. }
  228. const param = {
  229. patNo: patNo.value,
  230. medType: medType.value,
  231. times: currentRow.value.times,
  232. needSaving: 1,
  233. }
  234. if (command === 'execute') {
  235. obtainBasicPersonInfo(param).then((res) => {
  236. insuinfo.value = res.insuinfo
  237. showInsuinfo.value = true
  238. })
  239. } else {
  240. revokeOutpatientRegistration(param).then((res) => {
  241. ElMessage({
  242. message: res,
  243. type: 'success',
  244. duration: 2000,
  245. showClose: true,
  246. })
  247. })
  248. }
  249. }
  250. const readCardData = reactive({
  251. mdtrtCertType: null,
  252. readCardResult: null,
  253. readCardBizType: null,
  254. })
  255. const clearReadCardData = () => {
  256. readCardData.mdtrtCertType = null
  257. readCardData.readCardResult = null
  258. readCardData.readCardBizType = null
  259. }
  260. const afterReadCard = (result) => {
  261. readCardData.mdtrtCertType = result.mdtrtCertType
  262. readCardData.readCardResult = result.readCardResult
  263. readCardData.readCardBizType = result.readCardBizType
  264. }
  265. const handleClickInsuinfo = (row) => {
  266. const param = {
  267. patNo: patNo.value,
  268. times: currentRow.value.times,
  269. insutype: row.insutype,
  270. psnType: row.psnType,
  271. insuplcAdmdvs: row.insuplcAdmdvs,
  272. empName: row.empName,
  273. mdtrtCertType: readCardData.mdtrtCertType,
  274. readCardResult: readCardData.readCardResult,
  275. readCardBizType: readCardData.readCardBizType,
  276. }
  277. outpatientRegistration(param).then((res) => {
  278. clearReadCardData()
  279. showInsuinfo.value = false
  280. ElMessage({
  281. message: res,
  282. type: 'success',
  283. duration: 2000,
  284. showClose: true,
  285. })
  286. })
  287. }
  288. const receiptsOpts = (command) => {
  289. switch (command) {
  290. case 'insert':
  291. markMzFees()
  292. break
  293. case 'delete':
  294. deleteMtFees()
  295. break
  296. case 'upload':
  297. qrySpcChrDiseAcct()
  298. break
  299. case 'retract':
  300. revokeFees()
  301. break
  302. }
  303. }
  304. const markMzFees = () => {
  305. if (currentReceipts.value.length === 0) {
  306. ElMessage({
  307. message: '请先选择要保存的处方!',
  308. type: 'warning',
  309. duration: 2500,
  310. showClose: true,
  311. })
  312. return
  313. }
  314. ElMessageBox.confirm('是否将选中处方生成医保处方?', '提示', {
  315. type: 'warning',
  316. confirmButtonText: '生成',
  317. cancelButtonText: '取消',
  318. })
  319. .then(() => {
  320. insertSiMzFees(currentReceipts.value).then(() => {
  321. currentRow.value.status = '1'
  322. ElMessage({
  323. message: '已成功生成医保处方。',
  324. type: 'success',
  325. duration: 2500,
  326. showClose: true,
  327. })
  328. })
  329. })
  330. .catch(() => {})
  331. }
  332. const matnDises = ref([])
  333. const showMatnDises = ref(false)
  334. const spcChrDiseAccts = ref([])
  335. const showSpcChrAccts = ref(false)
  336. const qrySpcChrDiseAcct = () => {
  337. if (!currentRow.value.times) {
  338. ElMessage({
  339. message: '请先选择历史处方。',
  340. type: 'warning',
  341. duration: 2000,
  342. showClose: true,
  343. })
  344. return
  345. }
  346. const param = {
  347. patNo: patNo.value,
  348. times: currentRow.value.times,
  349. }
  350. if (medType.value === '51') {
  351. queryMzMatnDises().then((res) => {
  352. matnDises.value = res
  353. showMatnDises.value = true
  354. })
  355. } else {
  356. querySpecialChronicDiseasesAccreditation(param).then((res) => {
  357. spcChrDiseAccts.value = res
  358. showSpcChrAccts.value = true
  359. })
  360. }
  361. }
  362. const uploadFees = (row) => {
  363. if (medType.value === '51') {
  364. row.patNo = patNo.value
  365. row.times = currentRow.value.times
  366. row.opspDiseCode = row.code
  367. row.opspDiseName = row.name
  368. }
  369. uploadOutpatientFeeDetails(row).then((res) => {
  370. showMatnDises.value = false
  371. showSpcChrAccts.value = false
  372. mzPreSetl()
  373. })
  374. }
  375. const mzPreSetl = () => {
  376. if (!currentRow.value.times) {
  377. ElMessage({
  378. message: '请先选择历史处方。',
  379. type: 'warning',
  380. duration: 2000,
  381. showClose: true,
  382. })
  383. return
  384. }
  385. const param = {
  386. staffId: store.state.user.info.code,
  387. patNo: patNo.value,
  388. times: currentRow.value.times,
  389. mdtrtCertType: readCardData.mdtrtCertType,
  390. readCardResult: readCardData.readCardResult,
  391. readCardBizType: readCardData.readCardBizType,
  392. }
  393. outpatientPreSettlement(param).then((res) => {
  394. const message = '医保处方总费用:' + res.totalCost + ',医保报销金额:' + res.fundPay + '。'
  395. ElMessageBox.alert(message, '试算成功', {
  396. type: 'success',
  397. showCancelButton: false,
  398. }).then(() => {})
  399. })
  400. }
  401. const revokeFees = () => {
  402. if (!currentRow.value.times) {
  403. ElMessage({
  404. message: '请先选择历史处方。',
  405. type: 'warning',
  406. duration: 2000,
  407. showClose: true,
  408. })
  409. return
  410. }
  411. const param = {
  412. patNo: patNo.value,
  413. times: currentRow.value.times,
  414. }
  415. revokeOutpatientFeeDetails(param).then((res) => {
  416. ElMessage({
  417. message: res,
  418. type: 'success',
  419. duration: 2000,
  420. showClose: true,
  421. })
  422. })
  423. }
  424. const deleteMtFees = () => {
  425. if (!currentRow.value.times) {
  426. ElMessage({
  427. message: '请先选择历史处方。',
  428. type: 'warning',
  429. duration: 2000,
  430. showClose: true,
  431. })
  432. return
  433. }
  434. const param = {
  435. patNo: patNo.value,
  436. times: currentRow.value.times,
  437. }
  438. deleteAllMzReceipts(param).then((res) => {
  439. ElMessage({
  440. message: res,
  441. type: 'success',
  442. duration: 2000,
  443. showClose: true,
  444. })
  445. currentReceipts.value = []
  446. fetchHistoryReceipts()
  447. })
  448. }
  449. const mzSettle = () => {
  450. if (!currentRow.value.times) {
  451. ElMessage({
  452. message: '请先选择历史处方。',
  453. type: 'warning',
  454. duration: 2000,
  455. showClose: true,
  456. })
  457. return
  458. }
  459. const param = {
  460. patNo: patNo.value,
  461. times: currentRow.value.times,
  462. saved: 1,
  463. mdtrtCertType: readCardData.mdtrtCertType,
  464. readCardResult: readCardData.readCardResult,
  465. readCardBizType: readCardData.readCardBizType,
  466. }
  467. outpatientSettlement(param).then((res) => {
  468. clearReadCardData()
  469. const message = '医保处方总费用:' + res.totalCost + ',医保报销金额:' + res.fundPay + '。'
  470. ElMessageBox.alert(message, '结算成功', {
  471. type: 'success',
  472. showCancelButton: false,
  473. }).then(() => {})
  474. })
  475. }
  476. const revokeMzSettle = () => {
  477. if (!currentRow.value.times) {
  478. ElMessage({
  479. message: '请先选择历史处方。',
  480. type: 'warning',
  481. duration: 2000,
  482. showClose: true,
  483. })
  484. return
  485. }
  486. const param = {
  487. patNo: patNo.value,
  488. times: currentRow.value.times,
  489. }
  490. revokeOutpatientSettlement(param).then((res) => {
  491. ElMessageBox.alert('撤销门诊结算成功', '提示', {
  492. type: 'success',
  493. showCancelButton: false,
  494. })
  495. })
  496. }
  497. const settlement = (command) => {
  498. if (command === 'pre') {
  499. mzPreSetl()
  500. } else if (command == 'fin') {
  501. mzSettle()
  502. } else {
  503. revokeMzSettle()
  504. }
  505. }
  506. const clearinfo = () => {
  507. patNo.value = ''
  508. medType.value = ''
  509. historyReceipts.value = []
  510. currentRow.value = {}
  511. currentReceipts.value = []
  512. }
  513. onMounted(() => {
  514. getMedTypesByFlag('clinic').then((res) => {
  515. medTypes.value = res
  516. })
  517. })
  518. return {
  519. patNo,
  520. medType,
  521. medTypes,
  522. tableHeight,
  523. receiptBoxStyle,
  524. historyReceipts,
  525. currentRow,
  526. currentReceipts,
  527. matnDises,
  528. showMatnDises,
  529. insuinfo,
  530. showInsuinfo,
  531. spcChrDiseAccts,
  532. showSpcChrAccts,
  533. shortcuts,
  534. dateRange,
  535. afterReadCard,
  536. colorStatus,
  537. fetchHistoryReceipts,
  538. fetchHistoryReceiptDetail,
  539. registor,
  540. handleClickInsuinfo,
  541. receiptsOpts,
  542. uploadFees,
  543. settlement,
  544. revokeMzSettle,
  545. clearinfo,
  546. }
  547. },
  548. }
  549. </script>