IllegalChargesAnalysis.vue 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779
  1. <template>
  2. <el-container>
  3. <div class="overlay" v-show="menuVisible" @click="menuVisible = false">
  4. <div id="menu" class="menu-box">
  5. <div class="menu-title">{{ rightClickData.label }}</div>
  6. <div class="menu-item" @click="editTemplateRule">
  7. <i class="el-icon-edit"></i>
  8. 编辑模板规则
  9. </div>
  10. <div class="menu-item" @click="addTemplate(0)">
  11. <i class="el-icon-folder"></i>
  12. 添加模板目录
  13. </div>
  14. <div class="menu-item" @click="addTemplate(1)">
  15. <i class="el-icon-plus"></i>
  16. 添加模板文件
  17. </div>
  18. <div class="menu-item" @click="deleteTemplate">
  19. <i class="el-icon-delete"></i>
  20. 删除此项目
  21. </div>
  22. </div>
  23. </div>
  24. <el-header height="36px" style="margin-top: 8px">
  25. <el-date-picker
  26. v-model="dateRange"
  27. type="daterange"
  28. range-separator="至"
  29. start-placeholder="开始日期"
  30. end-placeholder="结束日期"
  31. :shortcuts="shortcuts"
  32. style="width: 220px"
  33. ></el-date-picker>
  34. <el-select v-model="selectedMedtypes" style="width: 150px" multiple clearable collapse-tags
  35. placeholder="不选则为全部类别">
  36. <el-option v-for="item in medtypes" :key="item.code" :label="item.name" :value="item.code"></el-option>
  37. </el-select>
  38. <el-divider direction="vertical"></el-divider>
  39. <el-button type="primary" icon="el-icon-search" @click="fetchTargetData">检索</el-button>
  40. <el-button type="primary" icon="el-icon-upload" @click="exportExcel">导出Excel</el-button>
  41. <el-button type="success" icon="el-icon-search" @click="queryHuanZheRuYuanJianGe">患者入院间隔</el-button>
  42. <huan-zhe-zhu-yuan-tian-shu :date-range="dateRange"></huan-zhe-zhu-yuan-tian-shu>
  43. </el-header>
  44. <el-container>
  45. <el-aside>
  46. <el-input v-model="templateSearch" placeholder="输入模板名称检索" clearable>
  47. <template #prepend>模板检索</template>
  48. </el-input>
  49. <div style="height: 4px"></div>
  50. <el-tree
  51. ref="tree"
  52. :data="templates"
  53. :props="defaultProps"
  54. @node-click="handleNodeClick"
  55. @node-contextmenu="handleNodeRightClick"
  56. :style="{ height: treeHeight + 'px', overflowY: 'scroll' }"
  57. :filter-node-method="filterNode"
  58. highlight-current
  59. >
  60. <template #default="{ node }">
  61. <span class="custom-tree-node">{{ node.label }}</span>
  62. </template>
  63. </el-tree>
  64. </el-aside>
  65. <el-main>
  66. <el-table :data="targetData.slice((currentPage - 1) * pageSize, currentPage * pageSize)" stripe
  67. :height="treeHeight">
  68. <el-table-column prop="name" label="姓名" width="50"></el-table-column>
  69. <el-table-column prop="inpatientNo" label="住院号"></el-table-column>
  70. <el-table-column prop="admissTimes" label="次数" width="50"></el-table-column>
  71. <el-table-column prop="responceTypeName" label="医保身份" width="60"></el-table-column>
  72. <el-table-column prop="deptName" label="入院科室" v-if="nowAttribute === 1"></el-table-column>
  73. <el-table-column prop="wardName" label="入院病房"></el-table-column>
  74. <el-table-column prop="diag" label="出院诊断"></el-table-column>
  75. <el-table-column prop="detailSn" label="流水号" width="50" v-if="nowAttribute === 1"></el-table-column>
  76. <el-table-column label="医嘱号" v-if="nowAttribute === 1">
  77. <template #default="scope">
  78. <el-link type="primary" href="#" @click="fetchOrder(scope.row)">{{ scope.row.orderNo }}</el-link>
  79. </template>
  80. </el-table-column>
  81. <el-table-column prop="chargeCode" label="收费编码"></el-table-column>
  82. <el-table-column prop="chargeName" label="收费名称"></el-table-column>
  83. <el-table-column prop="chargeDate" label="收费时间" v-if="nowAttribute === 1"></el-table-column>
  84. <el-table-column prop="chargeDay" label="收费日期" v-if="nowAttribute === 2"></el-table-column>
  85. <el-table-column prop="chargeFee" label="金额" width="50"></el-table-column>
  86. <el-table-column prop="chargeAmount" label="数量" width="50"></el-table-column>
  87. <el-table-column prop="conflictDetailSn" label="冲突流水号" v-if="nowAttribute === 1"></el-table-column>
  88. <el-table-column label="冲突医嘱号" v-if="nowAttribute === 1">
  89. <template #default="scope">
  90. <el-link type="danger" href="#" @click="fetchOrder(scope.row)">{{ scope.row.conflictOrderNo }}</el-link>
  91. </template>
  92. </el-table-column>
  93. <el-table-column prop="conflictChargeCode" label="冲突收费编码" v-if="nowAttribute === 1"></el-table-column>
  94. <el-table-column prop="conflictChargeName" label="冲突收费名称" v-if="nowAttribute === 1"></el-table-column>
  95. <el-table-column prop="conflictChargeDate" label="冲突收费日期" v-if="nowAttribute === 1"></el-table-column>
  96. <el-table-column prop="conflictChargeFee" label="冲突收费金额" v-if="nowAttribute === 1"></el-table-column>
  97. <el-table-column prop="conflictChargeAmount" label="冲突收费数量" v-if="nowAttribute === 1"></el-table-column>
  98. </el-table>
  99. <el-pagination
  100. @size-change="handleSizeChange"
  101. @current-change="handleCurrentChange"
  102. :current-page="currentPage"
  103. :page-sizes="[15, 30, 45, 70, 100]"
  104. :page-size="pageSize"
  105. layout="total, sizes, prev, pager, next, jumper"
  106. :total="targetData.length"
  107. style="margin-top: 5px"
  108. ></el-pagination>
  109. </el-main>
  110. </el-container>
  111. <el-dialog v-model="showEditRule" title="模板编辑" width="700px">
  112. <div>
  113. <el-divider></el-divider>
  114. <div class="edit-line-title">基本信息:</div>
  115. <el-input v-model="currentTemplate.id" disabled style="width: 560px; margin-bottom: 8px">
  116. <template #prepend>模板编码</template>
  117. </el-input>
  118. <el-input v-model="currentTemplate.label" style="width: 560px">
  119. <template #prepend>模板名称</template>
  120. </el-input>
  121. <div v-show="currentTemplate.type === 1">
  122. <div class="edit-line-title">规则属性:</div>
  123. <div>
  124. <el-radio v-model="currentTemplate.attribute" :label="1">同时收费</el-radio>
  125. <el-radio v-model="currentTemplate.attribute" :label="2">超量收费</el-radio>
  126. </div>
  127. <div class="edit-line-title">
  128. 规则数据:(&nbsp;<span style="font-weight: 500">检索方式:</span>
  129. <el-radio v-model="searchMethod" label="alpha">首拼</el-radio>
  130. <el-radio v-model="searchMethod" label="code">编码</el-radio>
  131. <el-radio v-model="searchMethod" label="name">名称</el-radio>
  132. <el-divider direction="vertical"></el-divider>
  133. <el-checkbox v-model="includeDeactivate" style="margin-left: 16px">包含停用内容</el-checkbox>
  134. &nbsp;)
  135. </div>
  136. <el-row :gutter="5">
  137. <el-col :span="12">
  138. <el-autocomplete v-model="mainCharge" :fetch-suggestions="fetchChargeItem" placeholder="请输入内容" clearable
  139. @select="handleSelectMainCharge">
  140. <template #prepend>收费主体</template>
  141. <template #default="{ item }">
  142. <span style="color: #8492a6; font-size: 12px">{{ item.code }}</span>
  143. <el-divider direction="vertical"></el-divider>
  144. <span>{{ item.name }}</span>
  145. </template>
  146. </el-autocomplete>
  147. <el-table :data="currentTemplate.mainCharges" height="120">
  148. <el-table-column prop="code" label="收费编码"></el-table-column>
  149. <el-table-column prop="name" label="收费名称"></el-table-column>
  150. <el-table-column label="操作">
  151. <template #default="scope">
  152. <el-button type="text" icon="el-icon-delete" @click="removeMainCharge(scope.$index)">删除</el-button>
  153. </template>
  154. </el-table-column>
  155. </el-table>
  156. </el-col>
  157. <el-col :span="12" v-show="currentTemplate.attribute === 1">
  158. <el-autocomplete v-model="conflictCharge" :fetch-suggestions="fetchChargeItem" placeholder="请输入内容"
  159. clearable @select="handleSelectConflictCharge">
  160. <template #prepend>冲突收费</template>
  161. <template #default="{ item }">
  162. <span style="color: #8492a6; font-size: 12px">{{ item.code }}</span>
  163. <el-divider direction="vertical"></el-divider>
  164. <span>{{ item.name }}</span>
  165. </template>
  166. </el-autocomplete>
  167. <el-table :data="currentTemplate.conflictCharges" height="120">
  168. <el-table-column prop="code" label="收费编码"></el-table-column>
  169. <el-table-column prop="name" label="收费名称"></el-table-column>
  170. <el-table-column label="操作">
  171. <template #default="scope">
  172. <el-button type="text" icon="el-icon-delete" @click="removeConflictCharge(scope.$index)">删除
  173. </el-button>
  174. </template>
  175. </el-table-column>
  176. </el-table>
  177. </el-col>
  178. <el-col :span="12" v-show="currentTemplate.attribute === 2">
  179. <el-input type="number" v-model="currentTemplate.maxChargeNum" style="width: 230px" clearable>
  180. <template #prepend>数量上限(每天)</template>
  181. </el-input>
  182. <!-- <el-select v-model="currentTemplate.maxChargeUnit" style="width: 60px">
  183. <el-option label="天" value="day"></el-option>
  184. <el-option label="周" value="week"></el-option>
  185. <el-option label="月" value="month"></el-option>
  186. </el-select> -->
  187. </el-col>
  188. </el-row>
  189. </div>
  190. </div>
  191. <div style="width: 100%; text-align: right; margin: 16px 0 8px 0">
  192. <el-button type="success" icon="el-icon-upload" @click="saveTemplate">保存模板</el-button>
  193. </div>
  194. </el-dialog>
  195. <el-dialog v-model="ruYuanJianGeDialog" title="查询入院间隔" width="1200px">
  196. <el-button type="primary" icon="el-icon-upload" @click="exportExcelHuanZhe">导出Excel</el-button>
  197. <el-table
  198. :data="huoQuHuanZheShuJu.slice((queryHuanZhe.currentPage - 1) * queryHuanZhe.pageSize, queryHuanZhe.currentPage * queryHuanZhe.pageSize)"
  199. stripe
  200. :height="treeHeight - 200"
  201. >
  202. <el-table-column label="姓名" prop="name"></el-table-column>
  203. <el-table-column label="住院号" prop="inpatientNo"></el-table-column>
  204. <el-table-column label="住院次数" prop="admissTimes"></el-table-column>
  205. <el-table-column label="住院科室" prop="deptName"></el-table-column>
  206. <el-table-column label="入院日期" width="80" prop="admissDate"></el-table-column>
  207. <el-table-column label="出院日期" width="80" prop="disDate"></el-table-column>
  208. <el-table-column label="相差天数" prop="differDate"></el-table-column>
  209. <el-table-column label="诊断编码" prop="disDiag"></el-table-column>
  210. <el-table-column label="主要诊断" prop="disDiagComment"></el-table-column>
  211. <el-table-column label="医保类型" prop="responceTypeName"></el-table-column>
  212. </el-table>
  213. <el-pagination
  214. @size-change="handleSizeChangeHuanZhe"
  215. @current-change="handleCurrentChangeHuanZhe"
  216. :current-page="queryHuanZhe.currentPage"
  217. :page-sizes="[20, 30, 40, 50, 100]"
  218. :page-size="queryHuanZhe.pageSize"
  219. layout="total, sizes, prev, pager, next, jumper"
  220. :total="huoQuHuanZheShuJu.length"
  221. style="margin-top: 5px"
  222. ></el-pagination>
  223. </el-dialog>
  224. <el-dialog v-model="showOrders" title="医嘱详情" width="60%">
  225. <el-table :data="orders" stripe>
  226. <el-table-column prop="actOrderNo" label="医嘱号" width="70"></el-table-column>
  227. <el-table-column prop="inpatientNo" label="住院号" width="70"></el-table-column>
  228. <el-table-column prop="admissTimes" label="住院次数" width="70"></el-table-column>
  229. <el-table-column prop="physicianName" label="医生" width="70"></el-table-column>
  230. <el-table-column prop="frequCode" label="频率" width="60"></el-table-column>
  231. <el-table-column prop="orderCode" label="医嘱码" width="70"></el-table-column>
  232. <el-table-column prop="orderName" label="医嘱名称"></el-table-column>
  233. <el-table-column prop="startTime" label="开始时间"></el-table-column>
  234. <el-table-column prop="endTime" label="结束时间"></el-table-column>
  235. </el-table>
  236. </el-dialog>
  237. </el-container>
  238. </template>
  239. <script>
  240. import {ref} from 'vue'
  241. import store from '@/store'
  242. import {onMounted, watchEffect} from 'vue'
  243. import {ElMessage, ElMessageBox} from 'element-plus'
  244. import {
  245. analyzeTargetData,
  246. deleteChosenTemplate,
  247. fetchMyTemplates,
  248. insertNewTemplate,
  249. queryHuanZheLiangCiRuYuanRiQi,
  250. saveTemplateChanges,
  251. searchChargeItem,
  252. selectOrderPair,
  253. } from '@/api/reports/illegal-charges-analysis'
  254. import {shortcuts} from '@/data/shortcuts'
  255. import {getGreatestRole} from '@/utils/permission'
  256. import {formatDate, getDateRangeFormatDate} from '@/utils/date'
  257. import {createWorkSheet, writeExcelFile} from '@/utils/excel'
  258. import HuanZheZhuYuanTianShu from '../../components/reports/huanZheZhuYuanTianShu.vue'
  259. export default {
  260. components: {HuanZheZhuYuanTianShu},
  261. setup() {
  262. const medtypes = initMedtypes()
  263. const selectedMedtypes = ref([])
  264. const isAdmin = getGreatestRole() === 1
  265. const windowSize = store.state.app.windowSize
  266. const treeHeight = windowSize.h - 80
  267. const tree = ref(null)
  268. const templateSearch = ref('')
  269. const showOrders = ref(false)
  270. const orders = ref([])
  271. const includeDeactivate = ref(false)
  272. watchEffect(() => {
  273. if (templateSearch.value !== null) {
  274. if (tree.value) {
  275. tree.value.filter(templateSearch.value)
  276. }
  277. }
  278. })
  279. const templates = ref([])
  280. const defaultProps = {
  281. children: 'children',
  282. label: 'label',
  283. }
  284. const filterNode = (value, data) => {
  285. if (!value) {
  286. return true
  287. }
  288. return data.label.indexOf(value) !== -1
  289. }
  290. const menuVisible = ref(false)
  291. const selectedTemplate = ref({})
  292. const handleNodeClick = (data) => {
  293. selectedTemplate.value = data
  294. }
  295. const rightClickData = ref({})
  296. const rightClickNode = ref(null)
  297. const handleNodeRightClick = (event, data, node) => {
  298. if (data.personal === 1 || isAdmin) {
  299. rightClickData.value = data
  300. rightClickNode.value = node
  301. menuVisible.value = true
  302. const menu = document.getElementById('menu')
  303. menu.style.left = event.clientX + 20 + 'px'
  304. menu.style.top = event.clientY + 10 + 'px'
  305. }
  306. }
  307. const addTemplate = (type) => {
  308. if (rightClickData.value.type === 1) {
  309. ElMessage({
  310. message: '无法在模板文件下进行创建操作!',
  311. type: 'warning',
  312. duration: 2000,
  313. showClose: true,
  314. })
  315. return
  316. }
  317. const message = type === 0 ? '请输入目录名称' : '请输入模板名称'
  318. const title = type === 0 ? '添加模板目录' : '添加模板文件'
  319. ElMessageBox.prompt(message, title, {
  320. confirmButtonText: '添加',
  321. cancelButtonText: '取消',
  322. type: 'warning',
  323. }).then(({value}) => {
  324. const parentId = rightClickData.value.id
  325. const childrenLength = rightClickData.value.children.length
  326. const template = {
  327. id: parentId + '-' + (childrenLength + 1),
  328. parent: parentId,
  329. label: value,
  330. personal: rightClickData.value.personal,
  331. type: type,
  332. children: [],
  333. mainCharges: [],
  334. conflictCharges: [],
  335. }
  336. insertNewTemplate(template).then((res) => {
  337. ElMessage({
  338. message: res,
  339. type: 'success',
  340. duration: 2000,
  341. showClose: true,
  342. })
  343. rightClickData.value.children.push(template)
  344. })
  345. })
  346. }
  347. const deleteTemplate = () => {
  348. if (!isAdmin && rightClickData.value.personal === 0) {
  349. ElMessage({
  350. message: '公共节点无法删除!',
  351. type: 'warning',
  352. duration: 2000,
  353. showClose: true,
  354. })
  355. return
  356. }
  357. if (rightClickData.value.id === 'admin_2') {
  358. ElMessage({
  359. message: '主节点无法删除!',
  360. type: 'warning',
  361. duration: 2000,
  362. showClose: true,
  363. })
  364. return
  365. }
  366. deleteChosenTemplate(rightClickData.value).then((res) => {
  367. ElMessage({
  368. message: res,
  369. type: 'success',
  370. duration: 2000,
  371. showClose: true,
  372. })
  373. const parent = rightClickNode.value.parent
  374. const children = parent.data.children || parent.data
  375. const index = children.findIndex((d) => d.id === rightClickData.value.id)
  376. children.splice(index, 1)
  377. })
  378. }
  379. const showEditRule = ref(false)
  380. const currentTemplate = ref({
  381. children: [],
  382. mainCharges: [],
  383. conflictCharges: [],
  384. maxChargeNum: null,
  385. maxChargeUnit: 'day',
  386. })
  387. const editTemplateRule = () => {
  388. if (!rightClickData.value.parent) {
  389. ElMessage({
  390. message: '主节点无法编辑!',
  391. type: 'warning',
  392. duration: 2000,
  393. showClose: true,
  394. })
  395. return
  396. }
  397. currentTemplate.value = {...rightClickData.value}
  398. showEditRule.value = true
  399. }
  400. const dateRange = ref(null)
  401. const mainCharge = ref(null)
  402. const conflictCharge = ref(null)
  403. const searchMethod = ref('alpha')
  404. const fetchChargeItem = (queryString, cb) => {
  405. if (queryString && queryString.length > 1) {
  406. const param = {
  407. method: searchMethod.value,
  408. content: queryString,
  409. includeDeactivate: includeDeactivate.value,
  410. }
  411. searchChargeItem(param).then((res) => {
  412. cb(res)
  413. })
  414. }
  415. }
  416. const handleSelectMainCharge = (item) => {
  417. currentTemplate.value.mainCharges.push(item)
  418. }
  419. const handleSelectConflictCharge = (item) => {
  420. currentTemplate.value.conflictCharges.push(item)
  421. }
  422. const removeMainCharge = (index) => {
  423. currentTemplate.value.mainCharges.splice(index, 1)
  424. }
  425. const removeConflictCharge = (index) => {
  426. currentTemplate.value.conflictCharges.splice(index, 1)
  427. }
  428. const saveTemplate = () => {
  429. if (currentTemplate.value.type === 1 && !currentTemplate.value.attribute) {
  430. ElMessage({
  431. message: '请选择规则属性!',
  432. type: 'warning',
  433. duration: 2000,
  434. showClose: true,
  435. })
  436. return
  437. }
  438. if (currentTemplate.value.attribute === 2 && !currentTemplate.value.maxChargeNum) {
  439. ElMessage({
  440. message: '请输入超量收费的可收费数量上限!',
  441. type: 'warning',
  442. duration: 2000,
  443. showClose: true,
  444. })
  445. return
  446. }
  447. saveTemplateChanges(currentTemplate.value).then(() => {
  448. rightClickNode.value.data = {...currentTemplate.value}
  449. ElMessage({
  450. message: '保存成功。',
  451. type: 'success',
  452. duration: 2000,
  453. showClose: true,
  454. })
  455. showEditRule.value = false
  456. })
  457. }
  458. const targetData = ref([])
  459. const nowAttribute = ref(1)
  460. const fetchTargetData = () => {
  461. if (!dateRange.value) {
  462. ElMessage({
  463. message: '请选择日期范围',
  464. type: 'warning',
  465. duration: 2000,
  466. showClose: true,
  467. })
  468. return
  469. }
  470. if (selectedTemplate.value.type !== 1) {
  471. ElMessage({
  472. message: '请选择模板',
  473. type: 'warning',
  474. duration: 2000,
  475. showClose: true,
  476. })
  477. } else {
  478. selectedTemplate.value.start = formatDate(dateRange.value[0])
  479. selectedTemplate.value.end = formatDate(dateRange.value[1])
  480. selectedTemplate.value.medtypes = selectedMedtypes.value
  481. analyzeTargetData(selectedTemplate.value).then((res) => {
  482. targetData.value = res
  483. nowAttribute.value = selectedTemplate.value.attribute
  484. })
  485. }
  486. }
  487. const fetchOrder = (row) => {
  488. selectOrderPair(row.orderNo, row.conflictOrderNo).then((res) => {
  489. orders.value = res
  490. showOrders.value = true
  491. })
  492. }
  493. const pageSize = ref(30)
  494. const currentPage = ref(1)
  495. const handleSizeChange = (val) => {
  496. pageSize.value = val
  497. }
  498. const handleCurrentChange = (val) => {
  499. currentPage.value = val
  500. }
  501. const exportExcel = () => {
  502. if (!targetData.value || targetData.value.length === 0) {
  503. ElMessage({
  504. message: '没有可以导出的数据',
  505. type: 'warning',
  506. duration: 2000,
  507. showClose: true,
  508. })
  509. return
  510. }
  511. store.commit('app/setLoading', true)
  512. setTimeout(() => {
  513. const title = {
  514. name: '姓名',
  515. inpatientNo: '住院号',
  516. admissTimes: '住院次数',
  517. responceTypeName: '医保身份',
  518. deptName: '入院科室',
  519. wardName: '入院病房',
  520. diag: '出院诊断',
  521. detailSn: '收费流水号',
  522. chargeCode: '收费编码',
  523. chargeName: '收费名称',
  524. chargeDate: '收费日期',
  525. chargeFee: '收费金额',
  526. chargeAmount: '收费数量',
  527. conflictDetailSn: '冲突收费流水号',
  528. conflictChargeCode: '冲突收费编码',
  529. conflictChargeName: '冲突收费名称',
  530. conflictChargeDate: '冲突收费日期',
  531. conflictChargeFee: '冲突收费金额',
  532. conflictChargeAmount: '冲突收费数量',
  533. }
  534. const fields = [
  535. 'name',
  536. 'inpatientNo',
  537. 'admissTimes',
  538. 'responceTypeName',
  539. 'deptName',
  540. 'wardName',
  541. 'diag',
  542. 'detailSn',
  543. 'chargeCode',
  544. 'chargeName',
  545. 'chargeDate',
  546. 'chargeFee',
  547. 'chargeAmount',
  548. 'conflictDetailSn',
  549. 'conflictChargeCode',
  550. 'conflictChargeName',
  551. 'conflictChargeDate',
  552. 'conflictChargeFee',
  553. 'conflictChargeAmount',
  554. ]
  555. const workSheet = createWorkSheet(targetData.value, fields, title)
  556. const fileName = '违规收费分析.xlsx'
  557. writeExcelFile(workSheet, fileName)
  558. }, 50)
  559. }
  560. onMounted(() => {
  561. fetchMyTemplates().then((res) => {
  562. templates.value = res
  563. })
  564. })
  565. /**
  566. * 查询患者入院间隔
  567. */
  568. const ruYuanJianGeDialog = ref(false)
  569. const queryHuanZhe = ref({
  570. start: '',
  571. end: '',
  572. total: 0,
  573. currentPage: 1,
  574. pageSize: 50,
  575. })
  576. const huoQuHuanZheShuJu = ref([])
  577. const queryHuanZheRuYuanJianGe = () => {
  578. let date = getDateRangeFormatDate(dateRange.value)
  579. queryHuanZhe.value.start = date.startTime
  580. queryHuanZhe.value.end = date.endTime
  581. queryHuanZhe.value.medtypes = selectedMedtypes.value
  582. queryHuanZheLiangCiRuYuanRiQi(queryHuanZhe.value).then((res) => {
  583. huoQuHuanZheShuJu.value = res
  584. ruYuanJianGeDialog.value = true
  585. })
  586. }
  587. const handleSizeChangeHuanZhe = (val) => {
  588. queryHuanZhe.value.pageSize = val
  589. }
  590. const handleCurrentChangeHuanZhe = (val) => {
  591. queryHuanZhe.value.currentPage = val
  592. }
  593. const exportExcelHuanZhe = () => {
  594. if (huoQuHuanZheShuJu.value.length === 0) {
  595. return ElMessage.error({
  596. message: '没有可以导出的数据',
  597. showClose: true,
  598. })
  599. }
  600. store.commit('app/setLoading', true)
  601. setTimeout(() => {
  602. const fields = ['name', 'inpatientNo', 'admissTimes', 'deptName', 'admissDate', 'disDate', 'differDate', 'disDiag', 'disDiagComment', 'responceType', 'responceTypeName']
  603. const title = {
  604. name: '姓名',
  605. inpatientNo: '住院号',
  606. admissTimes: '住院次数',
  607. deptName: '住院科室',
  608. admissDate: '住院日期',
  609. disDate: '出院日期',
  610. differDate: '相差天数',
  611. disDiag: '诊断编码',
  612. disDiagComment: '主要诊断',
  613. responceType: '医保编码',
  614. responceTypeName: '医保名称',
  615. }
  616. const workSheet = createWorkSheet(huoQuHuanZheShuJu.value, fields, title)
  617. const fileName = '患者入院间隔.xlsx'
  618. writeExcelFile(workSheet, fileName)
  619. }, 50)
  620. }
  621. return {
  622. medtypes,
  623. selectedMedtypes,
  624. includeDeactivate,
  625. treeHeight,
  626. tree,
  627. templateSearch,
  628. templates,
  629. defaultProps,
  630. handleNodeClick,
  631. filterNode,
  632. rightClickData,
  633. handleNodeRightClick,
  634. menuVisible,
  635. addTemplate,
  636. deleteTemplate,
  637. editTemplateRule,
  638. dateRange,
  639. shortcuts,
  640. currentTemplate,
  641. showEditRule,
  642. mainCharge,
  643. conflictCharge,
  644. fetchChargeItem,
  645. searchMethod,
  646. showOrders,
  647. orders,
  648. fetchOrder,
  649. handleSelectMainCharge,
  650. handleSelectConflictCharge,
  651. saveTemplate,
  652. removeMainCharge,
  653. removeConflictCharge,
  654. selectedTemplate,
  655. nowAttribute,
  656. fetchTargetData,
  657. targetData,
  658. pageSize,
  659. currentPage,
  660. handleSizeChange,
  661. handleCurrentChange,
  662. exportExcel,
  663. queryHuanZheRuYuanJianGe,
  664. ruYuanJianGeDialog,
  665. queryHuanZhe,
  666. huoQuHuanZheShuJu,
  667. handleSizeChangeHuanZhe,
  668. handleCurrentChangeHuanZhe,
  669. exportExcelHuanZhe,
  670. }
  671. },
  672. }
  673. function initMedtypes() {
  674. return [
  675. // { code: '02', name: '省医保' },
  676. // { code: '03', name: '市城居医保' },
  677. // { code: '04', name: '新农合' },
  678. // { code: '09', name: '市城职医保' },
  679. // { code: '10', name: '省医保-异地' },
  680. {code: '2101', name: '普通住院'},
  681. {code: '2102', name: '单病种住院'},
  682. {code: '2106', name: '生育平产(居民)'},
  683. {code: '2107', name: '生育剖宫产(居民)'},
  684. {code: '22', name: '外伤住院'},
  685. {code: '52', name: '生育住院(职工)'},
  686. {code: '42', name: '工伤住院'},
  687. ]
  688. }
  689. </script>
  690. <style scoped>
  691. :deep(.el-tree-node) {
  692. white-space: normal;
  693. }
  694. :deep(.el-tree-node__content) {
  695. padding: 8px 4px 0 0;
  696. height: 100%;
  697. align-items: start;
  698. }
  699. .node-label {
  700. margin: 5px 0;
  701. width: 220px;
  702. }
  703. .overlay {
  704. position: absolute;
  705. top: 0;
  706. left: 0;
  707. right: 0;
  708. bottom: 0;
  709. z-index: 3000;
  710. background-color: transparent;
  711. }
  712. .menu-box {
  713. position: fixed;
  714. border: 1px solid #409eff;
  715. border-radius: 8px;
  716. background-color: white;
  717. width: 120px;
  718. }
  719. .menu-item {
  720. padding: 8px;
  721. cursor: pointer;
  722. }
  723. .menu-item:hover {
  724. color: #409eff;
  725. }
  726. .menu-title {
  727. padding: 4px;
  728. background-color: #409eff;
  729. color: white;
  730. text-align: center;
  731. border-top-left-radius: 8px;
  732. border-top-right-radius: 8px;
  733. text-overflow: ellipsis;
  734. white-space: nowrap;
  735. overflow: hidden;
  736. }
  737. .edit-line-title {
  738. font-size: 14px;
  739. font-weight: bold;
  740. padding: 8px 0;
  741. }
  742. :deep(.edit-line-title .el-radio__label) {
  743. padding-left: 6px;
  744. }
  745. :deep(.edit-line-title .el-radio) {
  746. margin-right: 16px;
  747. }
  748. </style>