Elizabeth's proactive approach involves introducing urinal toilet attachment , an ingenious concept that optimizes space and functionality.

p_urr.vue 20KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648
  1. <template>
  2. <div class="main-contain">
  3. <div class="app-container">
  4. <div class="page_process">
  5. <new-nav activeName="process"></new-nav>
  6. <div class="cell clearfix">
  7. <el-form :inline="true">
  8. <el-form-item label>
  9. <el-autocomplete
  10. class="checkSearch"
  11. popper-class="my-autocomplete"
  12. v-model="search_value"
  13. :fetch-suggestions="querySearchAsync"
  14. :trigger-on-focus="false"
  15. placeholder="请输入病人名字"
  16. @select="handleSelect"
  17. style="width:160px;"
  18. >
  19. <i class="el-icon-search el-input__icon" slot="suffix"></i>
  20. <template slot-scope="{ item }">
  21. <div class="name">{{ item.name }}</div>
  22. </template>
  23. </el-autocomplete>
  24. </el-form-item>
  25. </el-form>
  26. <label class="title">
  27. <span class="name">日期查询</span> :
  28. </label>
  29. <el-date-picker
  30. v-model="query.start_time"
  31. prefix-icon="el-icon-date"
  32. @change="changeTime"
  33. :editable="false"
  34. style="width: 150px;"
  35. type="date"
  36. placeholder="选择日期时间"
  37. align="right"
  38. format="yyyy-MM-dd"
  39. value-format="yyyy-MM-dd"
  40. ></el-date-picker>
  41. <span class>-</span>
  42. <el-date-picker
  43. v-model="query.end_time"
  44. prefix-icon="el-icon-date"
  45. @change="changeEndTime"
  46. :editable="false"
  47. style="width: 150px;"
  48. type="date"
  49. placeholder="选择日期时间"
  50. align="right"
  51. format="yyyy-MM-dd"
  52. value-format="yyyy-MM-dd"
  53. ></el-date-picker>
  54. <el-button size="small" icon="el-icon-printer" @click="printAction" type="primary">打印
  55. </el-button>
  56. <el-button size="small" icon="el-icon-printer" @click="exportAction" type="primary">导出
  57. </el-button>
  58. </div>
  59. <el-container>
  60. <div style="width:160px">
  61. <div class="tableTitle">患者列表</div>
  62. <el-table ref="table" :data="patientsData" border style="width: 100%;" height="500"
  63. :row-style="{ color: '#303133' }"
  64. :header-cell-style="{backgroundColor: 'rgb(245, 247, 250)',color: '#606266'}"
  65. highlight-current-row
  66. @current-change="handleChange">
  67. <el-table-column prop="dialysis_no" label="透析号" width="70" align="center">
  68. <template slot-scope="scope">{{scope.row.dialysis_no}}</template>
  69. </el-table-column>
  70. <el-table-column prop="name" label="姓名" width="90" align="center">
  71. <template slot-scope="scope">{{ scope.row.name }}</template>
  72. </el-table-column>
  73. </el-table>
  74. </div>
  75. <div style="padding-left:10px;flex:1;width:0;">
  76. <div class="tableTitle">指标趋势<span style="font-weight:normal">&nbsp;&nbsp;(当前患者: {{patient_name}})</span></div>
  77. <div>
  78. <line-chart :options="chart"></line-chart>
  79. <!-- <line-chart :options="bar" v-if="query.statistics_type == 9 || query.statistics_type == 10"></line-chart>-->
  80. <!-- <line-chart></line-chart>-->
  81. </div>
  82. <div class="tableTitle">统计表</div>
  83. <div>
  84. <el-table ref="table" :data="tableData" v-loading="loading" border :row-style="{ color: '#303133' }" :header-cell-style="{backgroundColor: 'rgb(245, 247, 250)',color: '#606266'}">
  85. <el-table-column label="姓名" align="center">
  86. <template slot-scope="scope">
  87. {{scope.row.name}}
  88. </template>
  89. </el-table-column>
  90. <el-table-column width="100" label="检查日期" align="center">
  91. <template slot-scope="scope">
  92. {{getTime(scope.row.inspect_date)}}
  93. </template>
  94. </el-table-column>
  95. <el-table-column width="100" label="URR(%)" align="center">
  96. <template slot-scope="scope">
  97. {{parseFloat(scope.row.value).toFixed(1)}}
  98. </template>
  99. </el-table-column>
  100. </el-table>
  101. </div>
  102. </div>
  103. </el-container>
  104. </div>
  105. </div>
  106. </div>
  107. </template>
  108. <script>
  109. import echarts from 'echarts'
  110. import { uParseTime } from '@/utils/tools'
  111. import { getCurrentOrgPatients } from '@/api/common/common'
  112. import {
  113. GetDefaultPatient,
  114. } from '@/api/common/statistics'
  115. import { PostSearch } from '@/api/patient'
  116. import { getDataConfig } from '@/utils/data'
  117. import { GetPersonQCStatistisData } from '../../../api/qcd'
  118. import LineChart from '../../qcd/components/LineChart.vue'
  119. export default {
  120. components: {
  121. LineChart
  122. },
  123. data() {
  124. return {
  125. pickerOptions: {
  126. disabledDate(time) {
  127. let threeMonths = new Date(new Date().setFullYear(new Date().getFullYear() - 1)).getTime() - 24 * 3600 * 1000
  128. return time.getTime() > Date.now() || time.getTime() < threeMonths
  129. }
  130. },
  131. patient_name:'',
  132. percent:[],
  133. patientsData: [],
  134. tableData: [],
  135. loading: false,
  136. search_value: '',
  137. total: 0,
  138. query: {
  139. patient_id: '',
  140. statistics_type: 1,
  141. start_time: '',
  142. end_time: '',
  143. type:3,
  144. limit: 10,
  145. page: 1
  146. },
  147. crumbs: [
  148. { path: false, name: '科室质控' },
  149. { path: false, name: '指标评估统计' },
  150. { path: false, name: '透析过程指标统计' }
  151. ],
  152. tableData1: [],
  153. chart: {
  154. title: {
  155. text: 'ECharts 入门示例'
  156. },
  157. tooltip: {},
  158. legend: {
  159. data: [],
  160. left: 0
  161. },
  162. xAxis: {
  163. data: []
  164. },
  165. yAxis: {
  166. axisLabel: {
  167. formatter: '{value} %'
  168. },
  169. show: false
  170. },
  171. series: [
  172. {
  173. name: '',
  174. type: 'line',
  175. data: [],
  176. barWidth: 30,
  177. label: {
  178. normal: {
  179. show: true,
  180. position: 'top',
  181. formatter: (params) => {
  182. if(this.percent.length > 0){
  183. let str = ''
  184. str = params.data + '('+ this.percent[params.dataIndex] +'%)'
  185. return str
  186. }else{
  187. let str = ''
  188. str = params.data
  189. return str
  190. }
  191. }
  192. }
  193. },
  194. //配置样式
  195. itemStyle: {
  196. //通常情况下:
  197. //每个柱子的颜色即为colorList数组里的每一项,如果柱子数目多于colorList的长度,则柱子颜色循环使用该数组
  198. normal: {
  199. color: function(params) {
  200. //我这边就两个柱子,大体就两个柱子颜色渐变,所以数组只有两个值,多个颜色就多个值
  201. var colorList = [
  202. ['#A9E0F3', '#9FBDFC'],
  203. ['#FFD7C0', '#FF9994']
  204. ]
  205. var index = params.dataIndex
  206. if (params.dataIndex >= colorList.length) {
  207. index = params.dataIndex % colorList.length
  208. }
  209. return new echarts.graphic.LinearGradient(0, 0, 0, 1, [
  210. { offset: 0, color: colorList[index][0] },
  211. // { offset: 0.5, color: colorList[index][1] },
  212. { offset: 1, color: colorList[index][1] }
  213. ])
  214. },
  215. lineStyle:{
  216. color:'#409eff' //改变折线颜色
  217. },
  218. barBorderRadius: [5, 5, 0, 0] //柱状角成椭圆形
  219. },
  220. //鼠标悬停时:
  221. emphasis: {
  222. shadowBlur: 10,
  223. shadowOffsetX: 0,
  224. shadowColor: 'rgba(0, 0, 0, 0.5)'
  225. }
  226. }
  227. }
  228. ],
  229. dataZoom: [
  230. {
  231. // Y轴固定,让内容滚动
  232. type: 'slider',
  233. show: false,
  234. xAxisIndex: [0],
  235. start: 1,
  236. end: 20, // 设置X轴刻度之间的间隔(根据数据量来调整)
  237. zoomLock: true // 锁定区域禁止缩放(鼠标滚动会缩放,所以禁止)
  238. },
  239. {
  240. type: 'inside',
  241. xAxisIndex: [0],
  242. start: 1,
  243. end: 20,
  244. zoomLock: true // 锁定区域禁止缩放
  245. }
  246. ]
  247. },
  248. bar: {
  249. title: {
  250. text: 'ECharts 入门示例'
  251. },
  252. tooltip: {},
  253. legend: {
  254. data: [],
  255. left: 0
  256. },
  257. xAxis: {
  258. data: []
  259. },
  260. yAxis: {
  261. axisLabel: {
  262. formatter: '{value} %'
  263. },
  264. show: false
  265. },
  266. series: [
  267. {
  268. name: '',
  269. type: 'bar',
  270. data: [],
  271. barWidth: 30,
  272. label: {
  273. normal: {
  274. show: true,
  275. position: 'top',
  276. formatter: (params) => {
  277. if(this.percent.length > 0){
  278. let str = ''
  279. str = params.data + '('+ this.percent[params.dataIndex] +'%)'
  280. return str
  281. }else{
  282. let str = ''
  283. str = params.data
  284. return str
  285. }
  286. }
  287. }
  288. },
  289. //配置样式
  290. itemStyle: {
  291. //通常情况下:
  292. //每个柱子的颜色即为colorList数组里的每一项,如果柱子数目多于colorList的长度,则柱子颜色循环使用该数组
  293. normal: {
  294. color: function(params) {
  295. //我这边就两个柱子,大体就两个柱子颜色渐变,所以数组只有两个值,多个颜色就多个值
  296. var colorList = [
  297. ['#A9E0F3', '#9FBDFC'],
  298. ['#FFD7C0', '#FF9994']
  299. ]
  300. var index = params.dataIndex
  301. if (params.dataIndex >= colorList.length) {
  302. index = params.dataIndex % colorList.length
  303. }
  304. return new echarts.graphic.LinearGradient(0, 0, 0, 1, [
  305. { offset: 0, color: colorList[index][0] },
  306. // { offset: 0.5, color: colorList[index][1] },
  307. { offset: 1, color: colorList[index][1] }
  308. ])
  309. },
  310. barBorderRadius: [5, 5, 0, 0] //柱状角成椭圆形
  311. },
  312. //鼠标悬停时:
  313. emphasis: {
  314. shadowBlur: 10,
  315. shadowOffsetX: 0,
  316. shadowColor: 'rgba(0, 0, 0, 0.5)'
  317. }
  318. }
  319. }
  320. ]
  321. }
  322. }
  323. },
  324. methods: {
  325. printAction(){
  326. this.$router.push({
  327. path: "/Dialysisanalysis/qualitycontrol/print?patient_id=" + this.query.patient_id+"&project_id="+this.query.project_id+"&item_id="+this.query.item_id+"&start_time="+this.query.start_time+"&end_time="+this.query.end_time
  328. });
  329. },exportAction(){
  330. let list = []
  331. for (let i = 0; i < this.tableData.length; i++) {
  332. let order = this.tableData[i]
  333. let name = order.name
  334. let value = order.value
  335. let inspect_date = order.inspect_date
  336. let obj = {
  337. '姓名': name,
  338. '数值': value,
  339. '日期': inspect_date,
  340. }
  341. list.push(obj)
  342. }
  343. import('@/vendor/Export2Excel').then(excel => {
  344. const tHeader = ['姓名', '数值', '日期']
  345. const filterVal = ['姓名', '数值', '日期']
  346. const data = this.formatJson(filterVal, list)
  347. excel.export_json_to_excel1({
  348. header: tHeader,
  349. data,
  350. filename: '明细',
  351. ref: this.$refs['table'].$el
  352. })
  353. })
  354. },
  355. changeProject(val) {
  356. this.query.statistics_type = val
  357. this.query.page = 1
  358. this.GetPersonQCStatistisData(this.query)
  359. this.GetInspectionCheckIndexTableData(this.query)
  360. },
  361. handleChange(val) {
  362. this.query.patient_id = val.id
  363. this.query.page = 1
  364. this.patient_name = val.name
  365. this.GetPersonQCStatistisData(this.query)
  366. this.GetInspectionCheckIndexTableData(this.query)
  367. },
  368. handleSizeChange(limit) {
  369. this.query.limit = limit
  370. this.GetInspectionCheckIndexTableData(this.query)
  371. },
  372. handleCurrentChange(page) {
  373. this.query.page = page
  374. this.GetPersonQCStatistisData(this.query)
  375. },formatJson(filterVal, jsonData) {
  376. return jsonData.map(v => filterVal.map(j => v[j]))
  377. },
  378. changeTime(val) {
  379. var time = this.getTimestamp(val) - this.getTimestamp(this.query.end_time)
  380. if (time > 0) {
  381. this.$message.error('结束时间不能小于开始时间')
  382. this.query.start_time = ''
  383. } else {
  384. // this.getDialysisList()
  385. this.query.page = 1
  386. this.GetPersonQCStatistisData(this.query)
  387. this.GetInspectionCheckIndexTableData(this.query)
  388. }
  389. },
  390. changeEndTime(val) {
  391. var time =
  392. this.getTimestamp(val) - this.getTimestamp(this.query.start_time)
  393. if (time < 0) {
  394. this.$message.error('结束时间不能小于开始时间')
  395. this.query.end_time = ''
  396. } else {
  397. this.query.page = 1
  398. this.GetPersonQCStatistisData(this.query)
  399. this.GetInspectionCheckIndexTableData(this.query)
  400. }
  401. },
  402. getTimestamp(time) {
  403. // 把时间日期转成时间戳
  404. return new Date(time).getTime() / 1000
  405. },
  406. QueryOperaById: function(val) {
  407. let vascular_access_desc_name = ''
  408. let vascular_access_desc = getDataConfig(
  409. 'hemodialysis',
  410. 'vascular_access_desc'
  411. )
  412. for (let i = 0; i < vascular_access_desc.length; i++) {
  413. if (vascular_access_desc[i].id == val) {
  414. vascular_access_desc_name = vascular_access_desc[i].name
  415. }
  416. }
  417. return vascular_access_desc_name
  418. },
  419. GetAnticoagulantById: function(val) {
  420. let anticoagulan_name = ''
  421. var anticoagulantsConfitTwo = this.$store.getters.anticoagulants_confit
  422. let anticoagulant = anticoagulantsConfitTwo
  423. for (let keys in anticoagulant) {
  424. if (anticoagulant[keys].id == val) {
  425. anticoagulan_name = anticoagulant[keys].name
  426. }
  427. }
  428. return anticoagulan_name
  429. },
  430. getModeName(mode_id) {
  431. return this.$store.getters.treatment_mode[mode_id] != undefined ? this.$store.getters.treatment_mode[mode_id].name : ''
  432. }, getTime(val) {
  433. if(val == "" || val == undefined){
  434. return ""
  435. }else {
  436. return uParseTime(val, '{y}-{m}-{d}')
  437. }
  438. },
  439. GetInspectionCheckIndexTableData(params) {
  440. this.loading = true
  441. GetPersonQCStatistisData(params)
  442. .then(rs => {
  443. var resp = rs.data
  444. console.log("resp=====",resp)
  445. if (resp.state == 1) {
  446. this.loading = false
  447. this.tableData = []
  448. for (let i = 0; i < resp.data.inspections.length; i++) {
  449. let obj = {
  450. name:resp.data.patient.name,
  451. value:parseFloat(resp.data.inspections[i].inspect_value).toFixed(1),
  452. inspect_date:resp.data.inspections[i].inspect_date
  453. }
  454. this.tableData.push(obj)
  455. }
  456. this.total = resp.data.total
  457. } else {
  458. this.loading = false
  459. }
  460. })
  461. .catch(error => {
  462. })
  463. },
  464. GetPersonQCStatistisData(params) {
  465. this.chart.xAxis.data = []
  466. this.chart.series[0].data = []
  467. this.bar.xAxis.data = []
  468. this.bar.series[0].data = []
  469. this.percent = []
  470. GetPersonQCStatistisData(params)
  471. .then(rs => {
  472. var resp = rs.data
  473. if (resp.state == 1) {
  474. console.log(resp.data.inspections)
  475. for (let i = 0; i < resp.data.inspections.length; i++) {
  476. this.chart.xAxis.data.push(this.getTime(resp.data.inspections[i].inspect_date))
  477. this.chart.series[0].data.push(resp.data.inspections[i].inspect_value)
  478. }
  479. console.log(this.chart.xAxis.data)
  480. console.log( this.chart.series[0].data)
  481. this.getArrLength(this.chart.xAxis.data,1)
  482. } else {
  483. }
  484. })
  485. .catch(error => {
  486. })
  487. },
  488. handleSelect(val) {
  489. this.query.patient_id = val.id
  490. this.query.page = 1
  491. this.patient_name = val.name
  492. for (let i = 0;i < this.patientsData.length; i++){
  493. if (this.patientsData[i].id == val.id){
  494. this.$refs.table.setCurrentRow(this.patientsData[i])
  495. }
  496. }
  497. },
  498. querySearchAsync(keyword, cb) {
  499. let key = ''
  500. if (keyword != undefined) {
  501. key = keyword
  502. }
  503. let searchArray = []
  504. PostSearch(key).then(response => {
  505. if (response.data.state == 1) {
  506. searchArray = response.data.data.patient
  507. cb(searchArray)
  508. } else {
  509. cb([])
  510. }
  511. })
  512. },
  513. chooseWay(way) {
  514. this.wayType = way
  515. }, getCurrentOrgPatients() {
  516. getCurrentOrgPatients().then(response => {
  517. if (response.data.state == 1) {
  518. var patients = response.data.data.patients
  519. this.patientsData = patients
  520. this.GetDefaultPatient()
  521. }
  522. })
  523. }, GetDefaultPatient() {
  524. GetDefaultPatient().then(response => {
  525. if (response.data.state == 1) {
  526. var patient = response.data.data.patient
  527. for (let i = 0;i < this.patientsData.length; i++){
  528. if (this.patientsData[i].id == patient.id){
  529. this.patient_name = this.patientsData[i].name
  530. this.$refs.table.setCurrentRow(this.patientsData[i])
  531. }
  532. }
  533. this.query.patient_id = patient.id
  534. this.GetPersonQCStatistisData(this.query)
  535. }
  536. })
  537. },
  538. getArrLength(result,type){
  539. if(type == 1){
  540. if(result.length > 10){
  541. var dataZoom_end = (10/result.length)*100;
  542. this.chart.dataZoom[0].end = dataZoom_end
  543. }else{
  544. var dataZoom_end = 100;
  545. this.chart.dataZoom[0].end = dataZoom_end
  546. }
  547. }else if(type == 2){
  548. if(result.length > 10){
  549. var dataZoom_end = (10/result.length)*100;
  550. this.bar.dataZoom[0].end = dataZoom_end
  551. }else{
  552. var dataZoom_end = 100;
  553. this.bar.dataZoom[0].end = dataZoom_end
  554. }
  555. }
  556. }
  557. }, mounted() {
  558. var date = new Date()
  559. var year = date.getFullYear() //获取完整的年份(4位)
  560. var month = date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1).toString() : date.getMonth() + 1 //获取当前月份(0-11,0代表1月)
  561. var day = date.getDate() < 10 ? '0' + date.getDate().toString() : date.getDate() //获取当前日(1-31)
  562. var last_month = date.getMonth() < 10 ? '0' + date.getMonth().toString() : date.getMonth() //获取当前月份(0-11,0代表1月)
  563. this.query.patient_id = 0
  564. this.query.end_time = year + '-' + month + '-' + day
  565. this.query.start_time = year + '-' + last_month + '-' + day
  566. this.query.project_id = 1
  567. this.query.item_id = 166
  568. this.getCurrentOrgPatients()
  569. // this.GetPersonQCStatistisData()
  570. }
  571. }
  572. </script>
  573. <style lang="scss" scoped>
  574. .tableTitle {
  575. font-size: 16px;
  576. color: #000;
  577. font-weight: bold;
  578. margin-bottom: 10px;
  579. }
  580. </style>
  581. <style lang="scss">
  582. .page_process {
  583. .el-tabs{
  584. margin-bottom:0 !important;
  585. }
  586. .el-button--medium {
  587. padding: 10px 8px;
  588. }
  589. .el-form-item {
  590. margin-bottom: 0;
  591. }
  592. ::-webkit-scrollbar{
  593. height: 15px !important;
  594. }
  595. }
  596. </style>