index.vue 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687
  1. <template>
  2. <div class="layout_display_flex_y">
  3. <div class="obviousBox" style="margin-bottom: 6px;">
  4. <searchArea :searchData="searchData" @submit="searchByForm"></searchArea>
  5. </div>
  6. <div class="title-area">
  7. <div class="title-top">
  8. 物资库存清单
  9. </div>
  10. </div>
  11. <div class="layout_display_flex_y" style="height: 80%">
  12. <el-table
  13. :data="ypClassData.slice(pageSizeClass * (currentPageClass - 1), pageSizeClass * currentPageClass)"
  14. border style="width: 100%" height="100%" stripe highlight-current-row
  15. class="ypClassTable normal-size">
  16. <el-table-column type="index" label="序号">
  17. </el-table-column>
  18. <el-table-column prop="name" label="供应商">
  19. </el-table-column>
  20. <el-table-column prop="name" label="购入金额">
  21. </el-table-column>
  22. <el-table-column prop="name" label="零售金额">
  23. </el-table-column>
  24. <el-table-column prop="name" label="差额">
  25. </el-table-column>
  26. <el-table-column prop="name" label="差价率">
  27. </el-table-column>
  28. </el-table>
  29. </div>
  30. <div>
  31. <el-pagination :current-page="currentPageClass" :page-size="pageSizeClass"
  32. :page-sizes="[10, 15, 20, 25]" :total="ypClassData.length"
  33. layout="total, sizes, prev, pager, next, jumper" style="margin-top: 5px"
  34. @size-change="handleSizeChangeClass" @current-change="handleCurrentChangeClass">
  35. </el-pagination>
  36. </div>
  37. </div>
  38. <el-dialog v-model="showDialog" :close-on-click-modal="false" :close-on-press-escape="false" :title="'调拨接收'"
  39. width="100%" destroy-on-close fullscreen>
  40. <!-- <YpPrintName :ypPrintNameDetail="ypPrintNameDetail" @closeYpPrintNameEditFor="closeYpPrintName" /> -->
  41. <info :currentEditCode="currentEditCode"></info>
  42. </el-dialog>
  43. </template>
  44. <script setup name="YpDict">
  45. import { ref, onMounted, nextTick } from 'vue'
  46. import { ElMessage, ElMessageBox } from 'element-plus'
  47. import {
  48. selectYpClass, saveYpClass, delYpClassByCode,
  49. selectDrugKind,
  50. selectYpDosage,
  51. selectYpUnit,
  52. selectYpChargeGroup,
  53. selectYpVisibleFlag,
  54. selectYpSupply,
  55. selectYpManuFactory,
  56. } from '@/api/yp-dict/yp-dict-base.js'
  57. import searchArea from '@/components/searchArea/index.vue';
  58. import info from '@/views/logisticsMaterials/transfer/transferReceipt/info.vue';
  59. const editableTabsValue = ref('ypClass')
  60. const msgTip = '分类编码(code)有变更,原始字典记录存在关联,请谨慎做更改,是否确认!!!'
  61. const delFlagOptions = [{ code: '0', name: '启用' }, { code: '1', name: '停用' }]
  62. const searchData = ref([
  63. {
  64. label: '科室名称',
  65. key: 'vehicleType',
  66. type: 'select',
  67. value: '',
  68. optionsData: [ //(0:轿车,1:面包车,2:越野车,3:吉普车,4:巴士,5:卡车)
  69. {
  70. label: '轿车',
  71. value: '0',
  72. },
  73. {
  74. label: '面包车',
  75. value: '1',
  76. },
  77. ],
  78. },
  79. {
  80. label: '项目名称',
  81. key: 'vehicleType',
  82. type: 'input',
  83. value: '',
  84. },
  85. ])
  86. const pageSizeClass = ref(20)
  87. const currentPageClass = ref(1)
  88. const handleSizeChangeClass = (val) => {
  89. pageSizeClass.value = val
  90. }
  91. const handleCurrentChangeClass = (val) => {
  92. currentPageClass.value = val
  93. }
  94. const pageSizeKind = ref(20)
  95. const currentPageKind = ref(1)
  96. const pageSizeDosage = ref(20)
  97. const currentPageDosage = ref(1)
  98. const pageSizeUnit = ref(20)
  99. const currentPageUnit = ref(1)
  100. const pageSizeSupply = ref(20)
  101. const currentPageSupply = ref(1)
  102. const pageSizeManuFactory = ref(20)
  103. const currentPageManuFactory = ref(1)
  104. const ypClassData = ref([])
  105. const drugKindData = ref([])
  106. const ypDosageData = ref([])
  107. const ypUnitData = ref([])
  108. const ypChargeGroupData = ref([])
  109. const visibleFlagData = ref([])
  110. const ypSupplyData = ref([])
  111. const ypManuFactoryData = ref([])
  112. let showDialog = ref(false)
  113. const text = ref('')
  114. onMounted(() => {
  115. nextTick(() => {
  116. queryYpClass()
  117. })
  118. })
  119. //搜索表单方法
  120. const searchByForm = (form) => {
  121. console.log("search", form)
  122. }
  123. // 查询药品字典-药性字典
  124. const queryYpClass = () => {
  125. selectYpClass(text.value)
  126. .then((res) => {
  127. res.forEach(row => {
  128. // 是否标记
  129. row['isEdit'] = false
  130. // 是否新增
  131. row['isAdd'] = false
  132. })
  133. ypClassData.value = res
  134. })
  135. .catch(() => {
  136. ypClassData.value = []
  137. })
  138. }
  139. // 查询药品字典-药品分类字典
  140. const queryDrugKind = () => {
  141. selectDrugKind(text.value)
  142. .then((res) => {
  143. res.forEach(row => {
  144. // 是否标记
  145. row['isEdit'] = false
  146. // 是否新增
  147. row['isAdd'] = false
  148. })
  149. drugKindData.value = res
  150. })
  151. .catch(() => {
  152. drugKindData.value = []
  153. })
  154. }
  155. // 查询药品字典-药品剂型字典
  156. const queryYpDosage = () => {
  157. selectYpDosage(text.value)
  158. .then((res) => {
  159. res.forEach(row => {
  160. // 是否标记
  161. row['isEdit'] = false
  162. // 是否新增
  163. row['isAdd'] = false
  164. })
  165. ypDosageData.value = res
  166. })
  167. .catch(() => {
  168. ypDosageData.value = []
  169. })
  170. }
  171. // 查询药品字典-药品单位字典
  172. const queryYpUnit = () => {
  173. selectYpUnit(text.value)
  174. .then((res) => {
  175. res.forEach(row => {
  176. // 是否标记
  177. row['isEdit'] = false
  178. // 是否新增
  179. row['isAdd'] = false
  180. })
  181. ypUnitData.value = res
  182. })
  183. .catch(() => {
  184. ypUnitData.value = []
  185. })
  186. }
  187. // 查询药品字典-药品费别字典
  188. const queryYpChargeGroup = () => {
  189. selectYpChargeGroup(text.value)
  190. .then((res) => {
  191. res.forEach(row => {
  192. // 是否标记
  193. row['isEdit'] = false
  194. // 是否新增
  195. row['isAdd'] = false
  196. })
  197. ypChargeGroupData.value = res
  198. })
  199. .catch(() => {
  200. ypChargeGroupData.value = []
  201. })
  202. }
  203. // 查询药房药品停用情况
  204. const flagFilter = ref('')
  205. const queryVisibleFlag = () => {
  206. selectYpVisibleFlag(text.value, flagFilter.value)
  207. .then((res) => {
  208. res.forEach(row => {
  209. // 是否标记
  210. row['isEdit'] = false
  211. // 是否新增
  212. row['isAdd'] = false
  213. })
  214. visibleFlagData.value = res
  215. })
  216. .catch(() => {
  217. visibleFlagData.value = []
  218. })
  219. }
  220. // 查询药品字典-药品厂家字典
  221. const queryYpSupply = () => {
  222. selectYpSupply(text.value)
  223. .then((res) => {
  224. res.forEach(row => {
  225. // 是否标记
  226. row['isEdit'] = false
  227. // 是否新增
  228. row['isAdd'] = false
  229. })
  230. ypSupplyData.value = res
  231. })
  232. .catch(() => {
  233. ypSupplyData.value = []
  234. })
  235. }
  236. // 查询药品字典-药品供应商字典
  237. const queryYpManuFactory = () => {
  238. selectYpManuFactory(text.value)
  239. .then((res) => {
  240. res.forEach(row => {
  241. // 是否标记
  242. row['isEdit'] = false
  243. // 是否新增
  244. row['isAdd'] = false
  245. })
  246. ypManuFactoryData.value = res
  247. })
  248. .catch(() => {
  249. ypManuFactoryData.value = []
  250. })
  251. }
  252. // 查询
  253. const queryItem = () => {
  254. if (editableTabsValue.value === 'ypClass') {
  255. queryYpClass()
  256. } else if (editableTabsValue.value === 'drugKind') {
  257. queryDrugKind()
  258. } else if (editableTabsValue.value === 'ypDosage') {
  259. queryYpDosage()
  260. } else if (editableTabsValue.value === 'ypUnit') {
  261. queryYpUnit()
  262. } else if (editableTabsValue.value === 'ypChargeGroup') {
  263. queryYpChargeGroup()
  264. } else if (editableTabsValue.value === 'visibleFlag') {
  265. queryVisibleFlag()
  266. } else if (editableTabsValue.value === 'ypSupply') {
  267. queryYpSupply()
  268. } else if (editableTabsValue.value === 'ypManuFactory') {
  269. queryYpManuFactory()
  270. }
  271. }
  272. // 新增行
  273. const onAddItem = () => {
  274. showDialog.value = true
  275. return
  276. if (editableTabsValue.value === 'ypClass') {
  277. let count
  278. if (ypClassData.value.length % pageSizeClass.value === 0) {
  279. count = Math.ceil(ypClassData.value.length / pageSizeClass.value) + 1
  280. } else {
  281. count = Math.ceil(ypClassData.value.length / pageSizeClass.value)
  282. }
  283. currentPageClass.value = count
  284. ypClassData.value.push({
  285. code: '',
  286. name: '',
  287. pyCode: '',
  288. dcode: '',
  289. delFlag: '',
  290. isEdit: true,
  291. isAdd: true,
  292. })
  293. const el = document.querySelector('.ypClassTable .el-scrollbar__wrap')
  294. const el2 = document.querySelector('.ypClassTable .el-table__body tbody')
  295. setTimeout(() => {
  296. const height = el2.clientHeight - el.clientHeight
  297. if (height > 0) {
  298. el.scrollTop = height
  299. }
  300. }, 100)
  301. } else if (editableTabsValue.value === 'drugKind') {
  302. let count
  303. if (drugKindData.value.length % pageSizeKind.value === 0) {
  304. count = Math.ceil(drugKindData.value.length / pageSizeKind.value) + 1
  305. } else {
  306. count = Math.ceil(drugKindData.value.length / pageSizeKind.value)
  307. }
  308. currentPageKind.value = count
  309. drugKindData.value.push({
  310. code: '',
  311. name: '',
  312. pyCode: '',
  313. dcode: '',
  314. ypType: '',
  315. mzBillCode: '',
  316. zyBillCode: '',
  317. isEdit: true,
  318. isAdd: true,
  319. })
  320. const el = document.querySelector('.drugKindTable .el-scrollbar__wrap')
  321. const el2 = document.querySelector('.drugKindTable .el-table__body tbody')
  322. setTimeout(() => {
  323. const height = el2.clientHeight - el.clientHeight
  324. if (height > 0) {
  325. el.scrollTop = height
  326. }
  327. }, 100)
  328. } else if (editableTabsValue.value === 'ypDosage') {
  329. let count
  330. if (ypDosageData.value.length % pageSizeDosage.value === 0) {
  331. count = Math.ceil(ypDosageData.value.length / pageSizeDosage.value) + 1
  332. } else {
  333. count = Math.ceil(ypDosageData.value.length / pageSizeDosage.value)
  334. }
  335. currentPageDosage.value = count
  336. ypDosageData.value.push({
  337. code: '',
  338. name: '',
  339. pyCode: '',
  340. dcode: '',
  341. dosaType: '',
  342. dosaRemark: '',
  343. orderNo: '',
  344. delFlag: '',
  345. ybCode: '',
  346. hnsybCode: '',
  347. isEdit: true,
  348. isAdd: true,
  349. })
  350. const el = document.querySelector('.ypDosageTable .el-scrollbar__wrap')
  351. const el2 = document.querySelector('.ypDosageTable .el-table__body tbody')
  352. setTimeout(() => {
  353. const height = el2.clientHeight - el.clientHeight
  354. if (height > 0) {
  355. el.scrollTop = height
  356. }
  357. }, 100)
  358. } else if (editableTabsValue.value === 'ypUnit') {
  359. let count
  360. if (ypUnitData.value.length % pageSizeUnit.value === 0) {
  361. count = Math.ceil(ypUnitData.value.length / pageSizeUnit.value) + 1
  362. } else {
  363. count = Math.ceil(ypUnitData.value.length / pageSizeUnit.value)
  364. }
  365. currentPageUnit.value = count
  366. ypUnitData.value.push({
  367. code: '',
  368. name: '',
  369. pyCode: '',
  370. dcode: '',
  371. orderNo: '',
  372. delFlag: '',
  373. refundableFees: '',
  374. isEdit: true,
  375. isAdd: true,
  376. })
  377. const el = document.querySelector('.ypUnitTable .el-scrollbar__wrap')
  378. const el2 = document.querySelector('.ypUnitTable .el-table__body tbody')
  379. setTimeout(() => {
  380. const height = el2.clientHeight - el.clientHeight
  381. if (height > 0) {
  382. el.scrollTop = height
  383. }
  384. }, 100)
  385. } else if (editableTabsValue.value === 'ypChargeGroup') {
  386. ypChargeGroupData.value.push({
  387. code: '',
  388. name: '',
  389. pyCode: '',
  390. dcode: '',
  391. delFlag: '',
  392. isEdit: true,
  393. isAdd: true,
  394. })
  395. } else if (editableTabsValue.value === 'visibleFlag') {
  396. ElMessage({
  397. type: "warning",
  398. message: "不能新增药房药品停用,需先维护药品信息!",
  399. duration: 2500,
  400. showClose: true,
  401. });
  402. } else if (editableTabsValue.value === 'ypSupply') {
  403. let count
  404. if (ypSupplyData.value.length % pageSizeSupply.value === 0) {
  405. count = Math.ceil(ypSupplyData.value.length / pageSizeSupply.value) + 1
  406. } else {
  407. count = Math.ceil(ypSupplyData.value.length / pageSizeSupply.value)
  408. }
  409. currentPageSupply.value = count
  410. ypSupplyData.value.push({
  411. code: '',
  412. name: '',
  413. abbrName: '',
  414. address: '',
  415. zipCode: '',
  416. telNo: '',
  417. relName: '',
  418. busiRange: '',
  419. comment: '',
  420. useFlag: '',
  421. pyCode: '',
  422. dcode: '',
  423. delFlag: '',
  424. isEdit: true,
  425. isAdd: true,
  426. })
  427. const el = document.querySelector('.ypSupplyTable .el-scrollbar__wrap')
  428. const el2 = document.querySelector('.ypSupplyTable .el-table__body tbody')
  429. setTimeout(() => {
  430. const height = el2.clientHeight - el.clientHeight
  431. if (height > 0) {
  432. el.scrollTop = height
  433. }
  434. }, 100)
  435. } else if (editableTabsValue.value === 'ypManuFactory') {
  436. let count
  437. if (ypManuFactoryData.value.length % pageSizeManuFactory.value === 0) {
  438. count = Math.ceil(ypManuFactoryData.value.length / pageSizeManuFactory.value) + 1
  439. } else {
  440. count = Math.ceil(ypManuFactoryData.value.length / pageSizeManuFactory.value)
  441. }
  442. currentPageManuFactory.value = count
  443. ypManuFactoryData.value.push({
  444. code: '',
  445. name: '',
  446. abbrName: '',
  447. address: '',
  448. zipCode: '',
  449. telNo: '',
  450. relName: '',
  451. productRange: '',
  452. comment: '',
  453. useFlag: '',
  454. pyCode: '',
  455. dcode: '',
  456. delFlag: '',
  457. isEdit: true,
  458. isAdd: true,
  459. })
  460. const el = document.querySelector('.ypManuFactoryTable .el-scrollbar__wrap')
  461. const el2 = document.querySelector('.ypManuFactoryTable .el-table__body tbody')
  462. setTimeout(() => {
  463. const height = el2.clientHeight - el.clientHeight
  464. if (height > 0) {
  465. el.scrollTop = height
  466. }
  467. }, 100)
  468. }
  469. }
  470. // 药品字典-药性字典增删改存开始
  471. // 编辑
  472. const editYpClass = (row) => {
  473. showDialog.value = true
  474. return
  475. // 备份原始数据
  476. row['oldRow'] = JSON.parse(JSON.stringify(row))
  477. row.isEdit = true
  478. }
  479. // 取消
  480. const cancelYpClass = (row) => {
  481. // 如果是新增的数据
  482. if (row.isAdd) {
  483. ypClassData.value.splice(ypClassData.value.length - 1, 1)
  484. } else {
  485. // 不是新增的数据 还原数据
  486. for (const i in row.oldRow) {
  487. row[i] = row.oldRow[i]
  488. }
  489. }
  490. }
  491. // 保存
  492. const updateYpClass = (row) => {
  493. if (!row.code || !row.name) {
  494. ElMessage({
  495. type: "warning",
  496. message: "药性字典编码或名称不存在,请检查!",
  497. duration: 2500,
  498. showClose: true,
  499. });
  500. return
  501. }
  502. if (row.isAdd) {
  503. let fe = 0
  504. for (let num in ypClassData.value) {
  505. if (ypClassData.value[num].code === row.code) {
  506. fe++
  507. }
  508. }
  509. if (fe === 2) {
  510. ElMessage({
  511. type: "warning",
  512. message: "存在重复的药性字典,请核对!",
  513. duration: 2500,
  514. showClose: true,
  515. });
  516. } else {
  517. callSaveYpClass(row, null)
  518. }
  519. } else {
  520. let oldCode = row.oldRow.code
  521. if (oldCode !== row.code) {
  522. ElMessageBox.confirm(msgTip, {
  523. cancelButtonText: '取消',
  524. confirmButtonText: '确定',
  525. type: 'warning',
  526. distinguishCancelAndClose: true,
  527. dangerouslyUseHTMLString: true
  528. }).then(() => {
  529. callSaveYpClass(row, oldCode)
  530. }).catch((action) => {
  531. if (action === 'cancel') {
  532. queryYpClass()
  533. }
  534. })
  535. } else {
  536. callSaveYpClass(row, oldCode)
  537. }
  538. }
  539. }
  540. const callSaveYpClass = (row, oldCode) => {
  541. let title = '请确认是否保存<span style="color:#d12020;">' + row.name + '</span>?'
  542. ElMessageBox.confirm(title, {
  543. cancelButtonText: '取消',
  544. confirmButtonText: '确定',
  545. type: 'warning',
  546. distinguishCancelAndClose: true,
  547. dangerouslyUseHTMLString: true
  548. }).then(() => {
  549. saveYpClass(row).then((res) => {
  550. ElMessage({
  551. type: "success",
  552. message: res.cg,
  553. duration: 2500,
  554. showClose: true,
  555. });
  556. if (oldCode !== null && oldCode !== row.code) {
  557. // 删除原始数据
  558. delYpClassByCode(oldCode).then((res) => {
  559. queryYpClass()
  560. })
  561. } else {
  562. queryYpClass()
  563. }
  564. })
  565. }).catch((action) => {
  566. if (action === 'cancel') {
  567. queryYpClass()
  568. }
  569. })
  570. }
  571. const deleteYpClass = (index, row) => {
  572. let title = '请确认是否删除<span style="color:#d12020;">' + row.name + '</span>?'
  573. ElMessageBox.confirm(title, {
  574. cancelButtonText: '取消',
  575. confirmButtonText: '确定',
  576. type: 'warning',
  577. distinguishCancelAndClose: true,
  578. dangerouslyUseHTMLString: true
  579. }).then(() => {
  580. delYpClassByCode(row.code).then((res) => {
  581. ElMessage({
  582. type: "success",
  583. message: res.cg,
  584. duration: 2500,
  585. showClose: true,
  586. });
  587. queryYpClass()
  588. })
  589. }).catch((action) => {
  590. if (action === 'cancel') {
  591. queryYpClass()
  592. }
  593. })
  594. }
  595. const currentEditCode = ref('')
  596. const tableEdit = (row) => {
  597. currentEditCode.value = row.code
  598. }
  599. </script>
  600. <style lang="scss" deep>
  601. .el-dialog__body {
  602. // padding: 0 16px;
  603. // height: calc(100% - 25px);
  604. }
  605. .el-tabs {
  606. height: calc(100% - 10px);
  607. .el-tabs__content {
  608. padding: 5px;
  609. height: calc(100% - 27px);
  610. }
  611. .el-tab-pane {
  612. height: calc(100% - 27px);
  613. overflow: auto;
  614. }
  615. .el-table__inner-wrapper {
  616. height: calc(100% - 10px) !important;
  617. }
  618. }
  619. .el-table .warning-row {
  620. --el-table-tr-bg-color: #dd7694;
  621. }
  622. .search-select-pre {
  623. padding: 0 12px;
  624. color: var(--el-text-color-regular);
  625. background: var(--el-fill-color-light);
  626. border-right: 1px solid var(--el-border-color);
  627. --el-select-input-padding-left: '0'
  628. }
  629. .title-area {
  630. box-sizing: border-box;
  631. background-color: #fff;
  632. padding: 5px 20px;
  633. .title-top {
  634. width: 100%;
  635. text-align: center;
  636. font-size: 1.2rem;
  637. font-weight: bold;
  638. }
  639. .title-bottom {
  640. display: flex;
  641. justify-content: space-between;
  642. }
  643. }
  644. </style>