InsurIncomeAnalysis.vue 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458
  1. <template>
  2. <el-container>
  3. <el-header style="height: 35px; margin-top: 10px">
  4. <el-date-picker v-model="setlCondition.month" :clearable="false" placeholder="请选择" style="width: 110px"
  5. type="month"></el-date-picker>
  6. <el-cascader v-model="setlCondition.dataInfo" :options="setlCondition.options" :props="{ expandTrigger: 'hover' }"
  7. @change="handleChange" :clearable="true" :filterable="true" placeholder="请选择险种">
  8. </el-cascader>
  9. <el-divider direction="vertical"></el-divider>
  10. <el-button icon="el-icon-search" type="success" @click="fetchSetlinfos">查询</el-button>
  11. <el-button icon="el-icon-download" type="primary" @click="exportSetlinfoExcel">导出Excel</el-button>
  12. </el-header>
  13. <el-main>
  14. <el-table :data="setlinfos" :max-height="tableHeight" border highlight-current-row row-key="childKey" show-summary
  15. :summary-method="getSummaries1">
  16. <el-table-column label="险种类型" prop="insurName" header-align="center"></el-table-column>
  17. <el-table-column label="住院人次" prop="psnCount" align="center" header-align="center"></el-table-column>
  18. <el-table-column label="住院天数" prop="inDays" align="center" header-align="center"></el-table-column>
  19. <el-table-column label="平均住院日" prop="avgInDays" align="right" header-align="center"></el-table-column>
  20. <el-table-column label="总费用" prop="totalFee" align="right" header-align="center"></el-table-column>
  21. <el-table-column label="药品费用" prop="drugFee" align="right" header-align="center"></el-table-column>
  22. <el-table-column label="药品占比(%)" prop="drugFeeRatio" align="right" header-align="center"></el-table-column>
  23. <el-table-column label="耗材费用" prop="matFee" align="right" header-align="center"></el-table-column>
  24. <el-table-column label="耗材占比(%)" prop="matFeeRatio" align="right" header-align="center"></el-table-column>
  25. <el-table-column label="基本医疗统筹金额" prop="fundPooling" align="right" header-align="center"></el-table-column>
  26. <el-table-column label="大病基金" prop="bigIllFundPooling" align="right" header-align="center"></el-table-column>
  27. <el-table-column label="公务员基金支付" prop="civilServiceFund" align="right" header-align="center"></el-table-column>
  28. <el-table-column label="其他基金" prop="otherFunds" align="right" header-align="center"></el-table-column>
  29. <el-table-column label="全部基金" prop="allFunds" align="right" header-align="center"></el-table-column>
  30. </el-table>
  31. <el-pagination :current-page="currentPage" :page-size="pageSize" :page-sizes="[15, 30, 45, 60]"
  32. :total="setldetails.length" layout="total, sizes, prev, pager, next, jumper" style="margin-top: 5px"
  33. @size-change="handleSizeChange" @current-change="handleCurrentChange"></el-pagination>
  34. </el-main>
  35. </el-container>
  36. </template>
  37. <script>
  38. import { computed, onMounted, reactive, ref } from 'vue'
  39. import { formatMonth } from '@/utils/date'
  40. import { useStore } from 'vuex'
  41. import {
  42. selectYbStatInfo
  43. } from '@/api/medical-insurance/si-ybkf'
  44. import { clone } from '@/utils/clone'
  45. import { Export } from '@/utils/ExportExcel'
  46. import { ElMessage } from 'element-plus'
  47. export default {
  48. components: {
  49. },
  50. setup() {
  51. const store = useStore()
  52. const windowSize = store.state.app.windowSize
  53. const tableHeight = windowSize.h - 55
  54. const setlCondition = reactive({
  55. month: formatMonth(new Date()),
  56. setlType: '21',
  57. insurType: null,
  58. dataInfo: null,
  59. options: initInsurOptions(),
  60. })
  61. const setlinfos = ref([])
  62. const setldetails = ref([])
  63. const showSetldetails = ref(false)
  64. const admdvsNameStyle = (children, isChildren) => {
  65. return {
  66. position: 'absolute',
  67. top: '6px',
  68. left: children || isChildren ? '24px' : '10px',
  69. width: '110px',
  70. }
  71. }
  72. const fetchSetlinfos = () => {
  73. if (!setlCondition.month) {
  74. ElMessage({
  75. message: '请选择年月!',
  76. type: 'warning',
  77. duration: 2500,
  78. showClose: true,
  79. })
  80. return
  81. }
  82. if (!setlCondition.dataInfo) {
  83. ElMessage({
  84. message: '请选择险种!',
  85. type: 'warning',
  86. duration: 2500,
  87. showClose: true,
  88. })
  89. return
  90. }
  91. setlCondition.setlType = setlCondition.dataInfo[0]
  92. setlCondition.insurType = setlCondition.dataInfo[1]
  93. setlCondition.month = formatMonth(setlCondition.month)
  94. selectYbStatInfo(setlCondition)
  95. .then((res) => {
  96. setlinfos.value = res
  97. })
  98. .catch(() => {
  99. setlinfos.value = []
  100. })
  101. }
  102. const handleChange = (value) => {
  103. console.log(value);
  104. }
  105. const getSummaries = () => {
  106. let sums = {
  107. psnCount: 0,
  108. inDays: 0,
  109. avgInDays: 0,
  110. totalFee: 0,
  111. drugFee: 0,
  112. drugFeeRatio: 0,
  113. matFee: 0,
  114. matFeeRatio: 0,
  115. fundPooling: 0,
  116. bigIllFundPooling: 0,
  117. civilServiceFund: 0,
  118. otherFunds: 0,
  119. allFunds: 0,
  120. }
  121. setlinfos.value.forEach((itm) => {
  122. for (let k in sums) {
  123. sums[k] = Number(sums[k]) + Number(itm[k])
  124. }
  125. })
  126. sums.insurName = '合计'
  127. sums.avgInDays = (sums.inDays / sums.psnCount).toFixed(2)
  128. sums.drugFeeRatio = (sums.drugFee / sums.totalFee * 100).toFixed(2)
  129. sums.matFeeRatio = (sums.matFee / sums.totalFee * 100).toFixed(2)
  130. return sums
  131. }
  132. const getSummaries1 = (param) => {
  133. const { columns, data } = param
  134. const sums = []
  135. // 住院人次下标
  136. let psnCountIndex = 0
  137. // 住院天数下标
  138. let inDaysIndex = 0
  139. // 总费用下标
  140. let zfyIndex = 0
  141. // 药品费下标
  142. let ypfIndex = 0
  143. // 材料费下标
  144. let clfIndex = 0
  145. columns.forEach((column, index) => {
  146. if (index === 0) {
  147. sums[index] = '合计'
  148. return
  149. }
  150. if (column.property === 'psnCount') {
  151. psnCountIndex = index
  152. }
  153. if (column.property === 'inDays') {
  154. inDaysIndex = index
  155. }
  156. if (column.property === 'totalFee') {
  157. zfyIndex = index
  158. }
  159. if (column.property === 'drugFee') {
  160. ypfIndex = index
  161. }
  162. if (column.property === 'matFee') {
  163. clfIndex = index
  164. }
  165. const values = data.map(item => Number(item[column.property]))
  166. if (column.property === 'avgInDays') {
  167. sums[index] = (sums[inDaysIndex] / sums[psnCountIndex]).toFixed(2)
  168. } else if (column.property === 'drugFeeRatio') {
  169. if (sums[zfyIndex] > 0) {
  170. sums[index] = (sums[ypfIndex] / sums[zfyIndex] * 100).toFixed(2)
  171. } else {
  172. sums[index] = 0.00
  173. }
  174. } else if (column.property === 'matFeeRatio') {
  175. if (sums[zfyIndex] > 0) {
  176. sums[index] = (sums[clfIndex] / sums[zfyIndex] * 100).toFixed(2)
  177. } else {
  178. sums[index] = 0.00
  179. }
  180. } else if (!values.every(value => isNaN(value))) {
  181. sums[index] = values.reduce((prev, curr) => {
  182. const value = Number(curr)
  183. if (!isNaN(value)) {
  184. return prev + curr
  185. } else {
  186. return prev
  187. }
  188. }, 0)
  189. //合计特殊处理
  190. if (column.property === 'psnCount' || column.property === 'inDays') {
  191. sums[index] = sums[index].toFixed(0)
  192. } else {
  193. sums[index] = sums[index].toFixed(2)
  194. }
  195. } else {
  196. sums[index] = 0
  197. }
  198. })
  199. sums.avgInDays = (sums.inDays / sums.psnCount).toFixed(2)
  200. sums.drugFeeRatio = (sums.drugFee / sums.totalFee * 100).toFixed(2)
  201. sums.matFeeRatio = (sums.matFee / sums.totalFee * 100).toFixed(2)
  202. return sums
  203. }
  204. const filterSetlTypeName = () => {
  205. if ("21" === setlCondition.setlType) {
  206. return setlCondition.options[0].label
  207. } else {
  208. return setlCondition.options[1].label
  209. }
  210. return ''
  211. }
  212. const filterInsurTypeName = () => {
  213. if ("21" === setlCondition.setlType) {
  214. for (let i = 0; i < setlCondition.options[0].children.length; i++) {
  215. if (setlCondition.options[0].children[i].value === setlCondition.insurType) {
  216. return setlCondition.options[0].children[i].label
  217. }
  218. }
  219. } else {
  220. for (let i = 0; i < setlCondition.options[1].children.length; i++) {
  221. if (setlCondition.options[1].children[i].value === setlCondition.insurType) {
  222. return setlCondition.options[1].children[i].label
  223. }
  224. }
  225. }
  226. return ''
  227. }
  228. const exportSetlinfoExcel = () => {
  229. if (setlinfos.value.length === 0) {
  230. ElMessage({
  231. message: '没有可以导出的数据!',
  232. type: 'warning',
  233. duration: 2500,
  234. showClose: true,
  235. })
  236. } else {
  237. const data = clone(setlinfos.value)
  238. data.push(getSummaries())
  239. const title = {
  240. insurName: '险种类型',
  241. psnCount: '住院人次',
  242. inDays: '住院天数',
  243. avgInDays: '平均住院日',
  244. totalFee: '总费用',
  245. drugFee: '药品费用',
  246. drugFeeRatio: '药品占比(%)',
  247. matFee: '耗材费用',
  248. matFeeRatio: '耗材占比(%)',
  249. fundPooling: '基本医疗统筹金额',
  250. bigIllFundPooling: '大病基金',
  251. civilServiceFund: '公务员基金支付',
  252. otherFunds: '其他基金',
  253. allFunds: '全部基金',
  254. }
  255. const setlTypeName = filterSetlTypeName()
  256. const insurTypeName = filterInsurTypeName()
  257. Export(data, title, `【${setlCondition.month}】【${setlTypeName}】【${insurTypeName}】`)
  258. }
  259. }
  260. const pageSize = ref(30)
  261. const currentPage = ref(1)
  262. const handleSizeChange = (val) => {
  263. pageSize.value = val
  264. }
  265. const handleCurrentChange = (val) => {
  266. currentPage.value = val
  267. }
  268. onMounted(() => {
  269. })
  270. return {
  271. tableHeight,
  272. setlCondition,
  273. setlinfos,
  274. setldetails,
  275. showSetldetails,
  276. pageSize,
  277. currentPage,
  278. getSummaries1,
  279. exportSetlinfoExcel,
  280. handleChange,
  281. admdvsNameStyle,
  282. handleCurrentChange,
  283. handleSizeChange,
  284. fetchSetlinfos,
  285. }
  286. },
  287. }
  288. function initInsurOptions() {
  289. return [
  290. {
  291. value: '21',
  292. label: '住院',
  293. children: [
  294. {
  295. value: 99,
  296. label: '全部',
  297. },
  298. {
  299. value: 43010031001,
  300. label: '长沙市城职',
  301. },
  302. {
  303. value: 43010039001,
  304. label: '长沙市城居',
  305. },
  306. {
  307. value: 43010034001,
  308. label: '长沙市离休',
  309. },
  310. {
  311. value: 43010051052,
  312. label: '长沙市生育',
  313. },
  314. {
  315. value: 43012131001,
  316. label: '长沙县城职',
  317. },
  318. {
  319. value: 43012139001,
  320. label: '长沙县城居',
  321. },
  322. {
  323. value: 43012134001,
  324. label: '长沙县离休',
  325. },
  326. {
  327. value: 43012151052,
  328. label: '长沙县生育',
  329. },
  330. {
  331. value: 43018131001,
  332. label: '浏阳市城职',
  333. },
  334. {
  335. value: 43018139001,
  336. label: '浏阳市城居',
  337. },
  338. {
  339. value: 43018134001,
  340. label: '浏阳市离休',
  341. },
  342. {
  343. value: 43018151052,
  344. label: '浏阳市生育',
  345. },
  346. {
  347. value: 43990031001,
  348. label: '湖南省城职',
  349. },
  350. {
  351. value: 43990034001,
  352. label: '湖南省离休',
  353. },
  354. {
  355. value: 43990051052,
  356. label: '湖南省生育',
  357. },
  358. {
  359. value: 43990001,
  360. label: '省内异地',
  361. },
  362. {
  363. value: 43990002,
  364. label: '省外异地',
  365. },
  366. {
  367. value: 4301002102,
  368. label: '市单病种',
  369. },
  370. {
  371. value: 4399002102,
  372. label: '省单病种',
  373. },
  374. {
  375. value: 4399012102,
  376. label: '省内单病种',
  377. },
  378. ]
  379. },
  380. {
  381. value: '11',
  382. label: '门诊',
  383. children: [
  384. {
  385. value: 99,
  386. label: '全部',
  387. },
  388. {
  389. value: 11,
  390. label: '普通门诊',
  391. },
  392. {
  393. value: 14,
  394. label: '特殊门诊',
  395. },
  396. {
  397. value: 3,
  398. label: '工伤门诊',
  399. },
  400. {
  401. value: 51,
  402. label: '生育门诊',
  403. },
  404. ]
  405. },
  406. ]
  407. }
  408. </script>
  409. <style scoped>
  410. :deep(.el-table .children-row) {
  411. background: rgba(145, 247, 145, 0.5);
  412. }
  413. :deep(.el-table--border td:first-child .cell, .el-table--border th:first-child .cell) {
  414. padding-left: 4px;
  415. }
  416. :deep(.el-table) {
  417. --el-table-row-hover-background-color: #85dbfd7a;
  418. }
  419. :deep(.el-table__footer-wrapper tbody td) {
  420. background: #df4a25;
  421. color: white;
  422. font-weight: bold;
  423. }
  424. </style>