YiJiXiangMuLuRu.vue 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473
  1. <template>
  2. <div class="layout_display_flex">
  3. <div style="width: 195px">
  4. <HuoQuMuBan
  5. ref="muBanRef"
  6. @selectionFeiYong="xuanZeXiangMuTable"/>
  7. </div>
  8. <div class="layout_flex_1-x layout_display_flex_y">
  9. <div>
  10. <el-button icon="Document" type="warning" @click="baoCunMuBanDialog = true">存模板</el-button>
  11. <el-button icon="Upload" type="primary" @click="shangChuanXiangMu">保存</el-button>
  12. <el-button icon="Plus" type="success" @click="xinZhengXiangMuDialog = true">新增</el-button>
  13. <el-select v-model="zhiXingKeShi" filterable style="width: 120px; margin: 0px 10px 0px 10px">
  14. <el-option v-for="item in deptData" :key="item.code" :label="item.name" :value="item.code">
  15. <span style="color: #8492a6; font-size: 12px">{{ item.code }}</span>
  16. <el-divider direction="vertical"></el-divider>
  17. <span>{{ item.name }}</span></el-option
  18. >
  19. </el-select>
  20. <el-button icon="Edit" type="warning" @click="xieGaiZhiXingKeShi">修改执行科室</el-button>
  21. 病区:
  22. <el-select v-model="queryWard" filterable style="width: 120px" @change="getBingQuDuiYingKeShiChange">
  23. <el-option v-for="item in wardData" :key="item.code" :label="item.name" :value="item.code">
  24. <span style="color: #8492a6; font-size: 12px">{{ item.code }}</span>
  25. <el-divider direction="vertical"></el-divider>
  26. <span>{{ item.name }}</span></el-option>
  27. </el-select>
  28. 小科室:
  29. <el-select v-model="queryDept" filterable style="width: 120px">
  30. <el-option v-for="item in xiaoKeShiList"
  31. :key="item.code" :label="item.name" :value="item.code">
  32. <span style="color: #8492a6; font-size: 12px">{{ item.code }}</span>
  33. <el-divider direction="vertical"></el-divider>
  34. <span>{{ item.name }}</span></el-option>
  35. </el-select>
  36. 手术编码:
  37. <el-input
  38. v-model="ssCode"
  39. @blur="ssCode = ssCode.trim()"
  40. clearable
  41. placeholder="请输入手术编码"
  42. style="width: 120px"/>
  43. <el-tag type="danger"> 项目总价:{{ xiangMuZongJia }}</el-tag>
  44. </div>
  45. <div class="layout_flex_1-y">
  46. <el-table :data="saveData"
  47. height="100%"
  48. highlight-current-row
  49. stripe
  50. style="margin-top: 10px">
  51. <el-table-column label="录入信息">
  52. <el-table-column label="是否自费" width="130">
  53. <template #default="scope">
  54. <el-switch
  55. v-model="scope.row.ybSelfFlag"
  56. :active-value="1"
  57. :inactive-value="0"
  58. active-color="#ff4949"
  59. active-text="自费"
  60. inactive-color="#13ce66"
  61. inactive-text="医保"
  62. ></el-switch>
  63. </template>
  64. </el-table-column>
  65. <el-table-column label="医生" width="70px">
  66. <template #default="scope">
  67. <el-select v-model="scope.row.doctorCode" :remote-method="remoteMethodRenYuan" clearable filterable
  68. remote
  69. style="width: 100px">
  70. <el-option v-for="item in renYuanList" :key="item.code" :label="item.name" :value="item.code">
  71. <span style="color: #8492a6; font-size: 12px">{{ item.code }}</span>
  72. <el-divider direction="vertical"></el-divider>
  73. <span>{{ item.name }}</span>
  74. </el-option>
  75. </el-select>
  76. </template>
  77. </el-table-column>
  78. <el-table-column label="项目编码" prop="chargeCodeMx"></el-table-column>
  79. <el-table-column label="名称" prop="chargeName"></el-table-column>
  80. <el-table-column label="执行科室" prop="deptCode">
  81. <template #default="scope">
  82. <el-select v-model="scope.row.deptCode" filterable style="width: 90%">
  83. <el-option v-for="item in deptData" :key="item.code" :label="item.name" :value="item.code">
  84. <span style="color: #8492a6; font-size: 12px">{{ item.code }}</span>
  85. <el-divider direction="vertical"></el-divider>
  86. <span>{{ item.name }}</span>
  87. </el-option>
  88. </el-select>
  89. </template>
  90. </el-table-column>
  91. <el-table-column label="单价" prop="chargeAmount"></el-table-column>
  92. <el-table-column label="数量" prop="amount" width="130">
  93. <template #default="scope">
  94. <el-input-number v-model="scope.row.amount" :min="0"
  95. :precision="scope.row.serial === '00' ? 2 : 3"
  96. style="width: 120px"/>
  97. </template>
  98. </el-table-column>
  99. </el-table-column>
  100. <el-table-column label="金额">
  101. <template #default="scope">
  102. {{ (scope.row.chargeAmount * scope.row.amount).toFixed(2) }}
  103. </template>
  104. </el-table-column>
  105. <el-table-column label="账单码" prop="billItemName"></el-table-column>
  106. <el-table-column label="操作">
  107. <template #default="scope">
  108. <el-button type="danger" @click="shanChuXiangMuClick(scope.$index)">删除</el-button>
  109. </template>
  110. </el-table-column>
  111. </el-table>
  112. </div>
  113. </div>
  114. </div>
  115. <el-dialog v-model="xinZhengXiangMuDialog" :width="1500" title="新增">
  116. 搜索:
  117. <el-input v-model="chargeCodePy" style="width: 140px" @keyup.enter="rmChargePyCode"></el-input>
  118. <el-divider direction="vertical"></el-divider>
  119. <el-button type="primary" @click="rmChargePyCode">查询</el-button>
  120. <el-divider direction="vertical"></el-divider>
  121. <el-switch
  122. v-model="xiangMuHuoYaoPinFlag"
  123. @change="clearXiangMuHuoYaoPinShuJu"
  124. :active-value="1"
  125. :inactive-value="0"
  126. active-color="#409EFF"
  127. active-text="药品"
  128. inactive-color="#13ce66"
  129. inactive-text="项目"
  130. ></el-switch>
  131. <el-divider direction="vertical"></el-divider>
  132. <el-table
  133. :data="
  134. xiangMuHuoYaoPinShuJu.data.slice(
  135. (xiangMuHuoYaoPinShuJu.currentPage - 1) * xiangMuHuoYaoPinShuJu.pageSize,
  136. xiangMuHuoYaoPinShuJu.currentPage * xiangMuHuoYaoPinShuJu.pageSize
  137. )
  138. "
  139. :height="tableHeight / 1.2"
  140. >
  141. <el-table-column label="操作" width="40">
  142. <template #default="scope">
  143. <el-button text @click="danGeXiangMuBaoCun(scope.row)" type="primary">添加</el-button>
  144. </template>
  145. </el-table-column>
  146. <el-table-column label="项目编码" prop="chargeCodeMx"></el-table-column>
  147. <el-table-column label="厂家" prop="manuName"></el-table-column>
  148. <el-table-column label="项目名称" prop="chargeName"></el-table-column>
  149. <el-table-column label="国家编码" prop="nationalCode"></el-table-column>
  150. <el-table-column label="国家名称" prop="nationalName"></el-table-column>
  151. <el-table-column label="单位" prop="spec"></el-table-column>
  152. <el-table-column label="执行科室" prop="execUnitName"/>
  153. <el-table-column label="单价" prop="chargeAmount"></el-table-column>
  154. <el-table-column label="数量" prop="amount"/>
  155. <el-table-column label="金额">
  156. <template #default="scope">
  157. {{ (scope.row.chargeAmount * scope.row.amount).toFixed(2) }}
  158. </template>
  159. </el-table-column>
  160. <el-table-column label="账单码" prop="billItemName"></el-table-column>
  161. <el-table-column label="规格" prop="descriptions" show-overflow-tooltip></el-table-column>
  162. <el-table-column v-if="xiangMuHuoYaoPinFlag === 1" label="库存" prop="stockAmount"></el-table-column>
  163. <el-table-column v-if="xiangMuHuoYaoPinFlag === 1" label="医保类型" prop="yblx"></el-table-column>
  164. </el-table>
  165. <el-pagination
  166. :current-page="xiangMuHuoYaoPinShuJu.currentPage"
  167. :page-size="xiangMuHuoYaoPinShuJu.pageSize"
  168. :total="xiangMuHuoYaoPinShuJu.data.length"
  169. background
  170. layout="total, sizes, prev, pager, next, jumper"
  171. @size-change="xinZhengSizeChange"
  172. @current-change="xinZhengCurrentChange"
  173. >
  174. </el-pagination>
  175. </el-dialog>
  176. <el-dialog v-model="baoCunMuBanDialog" title="保存模板">
  177. <el-row>
  178. <el-col :span="24">
  179. 模板名称:
  180. <el-input v-model="cunMuBanPojo.name" maxlength="15" show-word-limit @blur="zhuanPinYin"></el-input>
  181. </el-col>
  182. <el-col :span="12">
  183. 拼音码:
  184. <el-input v-model="cunMuBanPojo.pyCode" maxlength="8" show-word-limit></el-input>
  185. </el-col>
  186. <el-col :span="12">
  187. 五笔码:
  188. <el-input v-model="cunMuBanPojo.dcode" maxlength="8" show-word-limit></el-input>
  189. </el-col>
  190. <el-col :span="12">
  191. <el-button icon="Upload" style="margin-top: 10px" type="primary" @click="baoCunMuBan">保存</el-button>
  192. </el-col>
  193. </el-row>
  194. </el-dialog>
  195. </template>
  196. <script setup lang="ts">
  197. import {computed, onMounted, ref, watch} from 'vue'
  198. import {
  199. getBingQuDuiYingKeShi,
  200. getDept,
  201. getPyCode,
  202. getWard,
  203. queryDanGeXiangMu,
  204. shangChuanMuBan,
  205. xiangMuFeiYongShangChuan
  206. } from '@/api/inpatient/xiang-mu-lu-ru'
  207. import {getRenYuan} from '@/api/public-api'
  208. import {ElMessage, ElMessageBox} from 'element-plus'
  209. import {clone} from '@/utils/clone'
  210. import HuoQuMuBan from './HuoQuMuBan.vue'
  211. import {stringIsBlank, stringNotBlank} from "@/utils/blank-utils";
  212. import {BizException, ExceptionEnum} from "@/utils/BizException";
  213. import {useUserStore} from "@/pinia/user-store";
  214. import cyRefList from "@/utils/cyRefList";
  215. import Dig from "@/utils/math";
  216. import XEUtils from "xe-utils";
  217. import useCompRef from "@/utils/useCompRef";
  218. const props = defineProps<{
  219. patient: {
  220. inpatientNo: string;
  221. admissTimes: number;
  222. zySerialNo: string;
  223. referPhysician: string;
  224. ledgerSn: number
  225. }
  226. }>()
  227. const emits = defineEmits(['theUploadIsSuccessful'])
  228. const userStore = useUserStore().userInfo
  229. const tableHeight = window.innerHeight - 170
  230. const deptData = ref([])
  231. const wardData = ref([])
  232. const muBanRef = useCompRef(HuoQuMuBan)
  233. // 手术编码
  234. const ssCode = ref('')
  235. const queryDept = ref('')
  236. const queryWard = ref('')
  237. const xiaoKeShiList = ref([])
  238. declare type ChargeCodeType = {
  239. chargeCodeMx: string;
  240. serial: string;
  241. chargeName: string
  242. deptCode: string;
  243. chargeAmount: number
  244. amount: number
  245. }
  246. const [saveData, saveProxy] = cyRefList<ChargeCodeType>((item) => {
  247. return item.chargeCodeMx.trim() + "_" + item.serial.trim();
  248. }, (item) => {
  249. return `项目【${item.chargeName}】请勿重复添加`
  250. });
  251. // 获取选择的数据
  252. const xuanZeXiangMuTable = (value) => {
  253. for (let i = 0; i < value.length; i++) {
  254. const item = value[i];
  255. item.deptCode = userStore.deptCode;
  256. }
  257. saveProxy.push(...value)
  258. }
  259. const chargeCode = ref([])
  260. const shangChuanXiangMu = () => {
  261. if (operationRoom() && stringIsBlank(ssCode.value)) {
  262. BizException(ExceptionEnum.LOGICAL_ERROR, "请填写手术编码。");
  263. }
  264. if (operationRoom() && stringNotBlank(ssCode.value) && !XEUtils.isStringNumber(ssCode.value)) {
  265. BizException(ExceptionEnum.LOGICAL_ERROR, "手术编码必须纯数字且中间不得有空格。");
  266. }
  267. if (stringIsBlank(props.patient.inpatientNo)) {
  268. BizException(ExceptionEnum.LOGICAL_ERROR, "请先选择患者。");
  269. }
  270. if (saveData.value.length === 0) {
  271. BizException(ExceptionEnum.LOGICAL_ERROR, "请先选择上传数据。");
  272. }
  273. const shangChuanFeiYong = {
  274. // 这里又要反回来 就尼玛坑爹 我也不知道为什么
  275. dept: queryWard.value,
  276. ward: queryDept.value,
  277. inpatientNo: props.patient.inpatientNo,
  278. admissTimes: props.patient.admissTimes,
  279. zySerialNo: props.patient.zySerialNo,
  280. ssCode: ssCode.value,
  281. referPhysician: props.patient.referPhysician,
  282. list: saveData.value,
  283. orderNo: 3,
  284. ledgerSn: props.patient.ledgerSn,
  285. };
  286. //在此处上传
  287. ElMessageBox.confirm('共上传【' + saveData.value.length + '】条', '请认真核对', {
  288. cancelButtonText: '取消',
  289. confirmButtonText: '确定',
  290. })
  291. .then(() => {
  292. xiangMuFeiYongShangChuan(shangChuanFeiYong).then(() => {
  293. saveData.value = []
  294. chargeCode.value = []
  295. emits('theUploadIsSuccessful')
  296. })
  297. })
  298. .catch(() => {
  299. })
  300. }
  301. const shanChuXiangMuClick = (val) => {
  302. saveProxy.delIndex(val)
  303. }
  304. // 新增项目或者药品
  305. const xinZhengXiangMuDialog = ref(false)
  306. // 判断查询药品还是项目
  307. const xiangMuHuoYaoPinFlag = ref(0)
  308. // 这个是远程查询数据后 保存
  309. const xiangMuHuoYaoPinShuJu = ref({
  310. currentPage: 1,
  311. pageSize: 20,
  312. data: [],
  313. })
  314. // 远程查询的
  315. const chargeCodePy = ref('')
  316. /**
  317. * 远程搜索
  318. */
  319. const rmChargePyCode = () => {
  320. if (chargeCodePy.value.length >= 2) {
  321. queryDanGeXiangMu(chargeCodePy.value, xiangMuHuoYaoPinFlag.value).then((res) => {
  322. xiangMuHuoYaoPinShuJu.value.data = res
  323. })
  324. }
  325. }
  326. const danGeXiangMuBaoCun = (val: ChargeCodeType) => {
  327. if (stringIsBlank(val.deptCode)) {
  328. val.deptCode = userStore.deptCode
  329. }
  330. saveProxy.push(val);
  331. }
  332. const xiangMuZongJia = computed(() => {
  333. let sum = 0
  334. saveData.value.forEach((item) => {
  335. sum += Dig.multiply(item.chargeAmount, item.amount)
  336. })
  337. return XEUtils.toFixed(sum, 2)
  338. })
  339. // 以下是保存模板
  340. const baoCunMuBanDialog = ref(false)
  341. const cunMuBanPojo = ref({
  342. pyCode: '',
  343. dcode: '',
  344. name: '',
  345. paiXu: '',
  346. dept: '',
  347. deptCode: userStore.deptCode,
  348. list: [],
  349. })
  350. // 获取到保存模板的拼音码和五笔码
  351. const zhuanPinYin = () => {
  352. if (cunMuBanPojo.value.name !== '') {
  353. getPyCode(cunMuBanPojo.value.name).then((res) => {
  354. cunMuBanPojo.value.pyCode = res.pyCode
  355. cunMuBanPojo.value.dcode = res.wbCode
  356. })
  357. }
  358. }
  359. const baoCunMuBan = () => {
  360. if (saveData.value.length === 0) {
  361. ElMessage.error({
  362. message: '请先选择项目',
  363. showClose: true,
  364. })
  365. return
  366. }
  367. if (cunMuBanPojo.value.name === '' || cunMuBanPojo.value.pyCode === '' || cunMuBanPojo.value.dcode === '') {
  368. ElMessage.error({
  369. message: '模板名称,拼音码,五笔码不能为空',
  370. showClose: true,
  371. })
  372. return
  373. }
  374. cunMuBanPojo.value.list = clone(saveData.value)
  375. // 开始上传
  376. shangChuanMuBan(cunMuBanPojo.value).then(() => {
  377. cunMuBanPojo.value = {}
  378. muBanRef.value?.reloadData()
  379. })
  380. }
  381. // 根据病人的科室来获取
  382. const getBingQuDuiYingKeShiChange = () => {
  383. getBingQuDuiYingKeShi(queryWard.value).then((res) => {
  384. xiaoKeShiList.value = res
  385. })
  386. }
  387. const zhiXingKeShi = ref(userStore.deptCode)
  388. const xieGaiZhiXingKeShi = () => {
  389. for (let i = 0; i < saveData.value.length; i++) {
  390. saveData.value[i].deptCode = zhiXingKeShi.value
  391. }
  392. }
  393. // 新增中的分页 事件
  394. const xinZhengSizeChange = (val) => {
  395. xiangMuHuoYaoPinShuJu.value.pageSize = val
  396. }
  397. const xinZhengCurrentChange = (val) => {
  398. xiangMuHuoYaoPinShuJu.value.currentPage = val
  399. }
  400. const clearXiangMuHuoYaoPinShuJu = () => {
  401. xiangMuHuoYaoPinShuJu.value.data = []
  402. }
  403. const renYuanList = ref([])
  404. // 搜索 医生工号
  405. const remoteMethodRenYuan = (val) => {
  406. if (val.length >= 2)
  407. getRenYuan(val).then((res) => {
  408. renYuanList.value = res
  409. })
  410. }
  411. function operationRoom() {
  412. let dept = userStore.deptCode
  413. return dept === '1300000'
  414. }
  415. const updateDeptAndWard = async (ward, dept) => {
  416. queryWard.value = ward
  417. await getBingQuDuiYingKeShiChange()
  418. queryDept.value = dept
  419. }
  420. onMounted(() => {
  421. // 获取科室
  422. getDept().then((res) => {
  423. deptData.value = res
  424. })
  425. getWard().then((res) => {
  426. wardData.value = res
  427. })
  428. })
  429. defineExpose({
  430. updateDeptAndWard
  431. })
  432. </script>
  433. <style></style>