after_Blood.vue 23KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702
  1. <template>
  2. <div class="main-contain">
  3. <div class="position">
  4. <div>
  5. <span>
  6. <el-button @click="return_click" type="text" icon="el-icon-arrow-left">返回</el-button>
  7. </span>&nbsp;&nbsp;
  8. <span>患者透后血压分析</span>
  9. </div>
  10. </div>
  11. <div class="app-container">
  12. <div class="page_patientControlAnalysis">
  13. <div style="display: flex;">
  14. <div>
  15. 日期:
  16. <el-select v-model="date_value" @change="datachange" placeholder="请选择" style="width: 100px;">
  17. <el-option
  18. v-for="item in date_options"
  19. :key="item.value"
  20. :label="item.label"
  21. :value="item.value">
  22. </el-option>
  23. </el-select>
  24. </div>
  25. <div style="margin:0 10px">
  26. <el-date-picker
  27. v-model="start_date"
  28. type="date"
  29. value-format="yyyy-MM-dd"
  30. placeholder="选择日期"
  31. style="width: 150px;">
  32. </el-date-picker>
  33. <span>-</span>
  34. <el-date-picker
  35. v-model="end_date"
  36. type="date"
  37. value-format="yyyy-MM-dd"
  38. placeholder="选择日期"
  39. style="width: 150px;">
  40. </el-date-picker>
  41. </div>
  42. <div>
  43. <el-button type="primary" @click="sete_click">查询</el-button>
  44. <el-button type="primary" @click="Download_click">下载</el-button>
  45. </div>
  46. </div>
  47. <!-- 图表 -->
  48. <div ref="mychart">
  49. <div class="echart" id="mychart" style="width:100%;height:60vh"></div>
  50. </div>
  51. <div style="position: fixed;right: 5%;top: 50vh;">
  52. <el-popover
  53. placement="left"
  54. title="提示"
  55. width="500"
  56. trigger="click"
  57. content="1.统计时间段内留治患者干体重,在当前时间段的区间分布,不是统计每次透析的干体重。
  58. 2.如果一个患者在时间段内,调整过两次干体重,以最后一次为准。">
  59. <img src="@/assets/img/xiang.png" alt="" style="height: 20px;width: 20px;" slot="reference">
  60. <!-- <el-button slot="reference">click 激活</el-button> -->
  61. </el-popover>
  62. </div>
  63. </div>
  64. </div>
  65. <!-- 弹窗 -->
  66. <div>
  67. <el-dialog
  68. title="提示"
  69. :visible.sync="complete_dialog"
  70. width="80%">
  71. <div>
  72. <div style="display: flex;margin-bottom: 20px;">
  73. <div style="flex: 2;display: flex;">
  74. <div>
  75. 日期:
  76. <el-select v-model="date_value" @change="datachange" placeholder="请选择" style="width: 100px;">
  77. <el-option
  78. v-for="item in date_options"
  79. :key="item.value"
  80. :label="item.label"
  81. :value="item.value">
  82. </el-option>
  83. </el-select>
  84. </div>
  85. <div style="margin:0 10px">
  86. <el-date-picker
  87. v-model="start_date"
  88. type="date"
  89. value-format="yyyy-MM-dd"
  90. placeholder="选择日期"
  91. style="width: 150px;">
  92. </el-date-picker>
  93. <span>-</span>
  94. <el-date-picker
  95. v-model="end_date"
  96. type="date"
  97. value-format="yyyy-MM-dd"
  98. placeholder="选择日期"
  99. style="width: 150px;">
  100. </el-date-picker>
  101. </div>
  102. <div>
  103. 状态:
  104. <el-select v-model="status_value" placeholder="请选择" style="width: 130px;">
  105. <el-option :key="0" label="不限" :value="0"></el-option>
  106. <el-option
  107. v-for="item in status_options"
  108. :key="item.value"
  109. :label="item.label"
  110. :value="item.value">
  111. </el-option>
  112. </el-select>
  113. </div>
  114. </div>
  115. <div style="flex: 1;">
  116. <div>
  117. <el-button type="primary" @click="detil_click">查询</el-button>
  118. <el-button type="primary" @click="derive_click">导出</el-button>
  119. </div>
  120. </div>
  121. </div>
  122. <div>
  123. <el-table :data="tableData"
  124. border
  125. style="width: 100%;"
  126. :header-cell-style = "{'text-align':'center'}"
  127. :cell-style="{'text-align':'center'}"
  128. height="380">
  129. <el-table-column
  130. prop="index"
  131. label="序号"
  132. width="">
  133. </el-table-column>
  134. <el-table-column
  135. prop="dialysis_no"
  136. label="透析号"
  137. width="">
  138. </el-table-column>
  139. <el-table-column
  140. prop="patient_name"
  141. label="患者姓名">
  142. </el-table-column>
  143. <el-table-column
  144. prop="age"
  145. label="年龄">
  146. </el-table-column>
  147. <el-table-column
  148. prop="dialysis_date"
  149. label="透析日期"
  150. width="">
  151. </el-table-column>
  152. <el-table-column
  153. prop="PostDialysisBP"
  154. label="透后血压"
  155. width="">
  156. </el-table-column>
  157. </el-table>
  158. </div>
  159. <div style="text-align:right;margin-top: 10px;">
  160. <el-pagination
  161. @size-change="handleSizeChange"
  162. @current-change="handleCurrentChange"
  163. :current-page="currentPage"
  164. :page-sizes="[50,100, 200, 300, 400]"
  165. :page-size="limit"
  166. layout="total, sizes, prev, pager, next, jumper"
  167. :total="total">
  168. </el-pagination>
  169. </div>
  170. </div>
  171. <span slot="footer" class="dialog-footer">
  172. <el-button @click="complete_dialog = false">取 消</el-button>
  173. <el-button type="primary" @click="complete_dialog = false">确 定</el-button>
  174. </span>
  175. </el-dialog>
  176. </div>
  177. </div>
  178. </template>
  179. <script>
  180. import * as echarts from 'echarts';
  181. import XLSX from 'xlsx';
  182. import { uParseTime } from "@/utils/tools";
  183. import {Getpatinetbp,Getbpdetail} from '../../../../api/qcd'
  184. import {getAllNurseList} from '@/api/fallassement'
  185. import { getAllDoctorList} from "@/api/device"
  186. import html2canvas from "html2canvas"
  187. export default {
  188. components:{
  189. },
  190. data(){
  191. return{
  192. date_value:4,
  193. start_date:'',
  194. end_date:this.getTime(new Date()),
  195. mode:'',
  196. date_mode:'',
  197. source:'',
  198. status_value:0,
  199. complete_dialog:false,
  200. currentPage:1,
  201. limit:50,
  202. total:0,
  203. tableData:[],
  204. nurseList:[],
  205. operators:[],
  206. docList:[],
  207. status_options:[],
  208. date_options:[{value:1,label:'最近七天'},{value:2,label:'本周'},{value:3,label:'上周'},{value:4,label:'本月'},
  209. {value:5,label:'上月'},{value:6,label:'本年'},{value:7,label:'上一年'}
  210. ],
  211. date_mode_options:[{value:1,label:'按周'},{value:2,label:'按天'},{value:3,label:'按月'},{value:4,label:'按年'}],
  212. source_options:[{value:1,label:'以开始透析为准'},{value:2,label:'以排班为准'}],
  213. status_id:"",
  214. }
  215. },
  216. methods:{
  217. // 返回
  218. return_click(){
  219. this.$router.push('/Dialysisanalysis/qualitycontrol/weightblood')
  220. },
  221. // 数据源
  222. getecharts(){
  223. var chartDom = document.getElementById('mychart')
  224. var myChart = echarts.init(chartDom);
  225. const params={
  226. start_time:this.start_date,
  227. end_time:this.end_date,
  228. statistics_type:2
  229. }
  230. Getpatinetbp(params).then(response =>{
  231. if(response.data.state ==1){
  232. const list = response.data.data.list
  233. const xAxis = []
  234. const yAxis = []
  235. var option = []
  236. var total =0
  237. for(let key in list){
  238. const obj={
  239. name:list[key].name,
  240. value:list[key].total
  241. }
  242. xAxis.push(obj)
  243. yAxis.push(list[key].name)
  244. total = total + list[key].total
  245. const obj2 ={
  246. value:(key*1)+1,
  247. label:list[key].name
  248. }
  249. option.push(obj2)
  250. }
  251. this.status_options = option
  252. console.log('this.status_options',response.data.data);
  253. const option = {
  254. title:{
  255. text:'总数'+total,
  256. left:'5%',
  257. bottom:'5%',
  258. textStyle:{
  259. fontSize:30
  260. }
  261. },
  262. tooltip: {
  263. trigger: 'item',
  264. },
  265. legend: {
  266. data:yAxis,
  267. left: '10%',
  268. top: '30%',
  269. orient: 'vertical'
  270. },
  271. color:['#FFD7C0','#9FBDFC',"#A9E0F3", "#FF9994",'aquamarine','gold'],
  272. series: [
  273. {
  274. name: '',
  275. type: 'pie',
  276. radius: ['40%', '70%'],
  277. avoidLabelOverlap: true,
  278. itemStyle: {
  279. borderRadius: 10,
  280. borderColor: '#fff',
  281. borderWidth: 2
  282. },
  283. label: {
  284. show: true,
  285. position: 'center',
  286. normal : {
  287. formatter: '{b}:{c}: ({d}%)',
  288. textStyle : {
  289. fontWeight : 'normal',
  290. fontSize : 15,
  291. color : "black"
  292. }
  293. }
  294. },
  295. emphasis: {
  296. label: {
  297. show: true,
  298. fontSize: 40,
  299. fontWeight: 'bold'
  300. }
  301. },
  302. labelLine: {
  303. show: false
  304. },
  305. data: xAxis
  306. }
  307. ]
  308. };
  309. myChart.setOption(option);
  310. myChart.on('click',params =>{
  311. this.complete_dialog = true
  312. console.log('bbbb',params);
  313. for(let i in this.status_options){
  314. if(params.data.name == this.status_options[i].label){
  315. this.status_value = this.status_options[i].value
  316. }
  317. }
  318. this.getdetail(this.status_value)
  319. })
  320. }
  321. })
  322. },
  323. // 查询
  324. sete_click(){
  325. this.getecharts()
  326. },
  327. // 详情查询
  328. detil_click(){
  329. this.currentPage =1
  330. this.getdetail(this.status_value)
  331. },
  332. // 下载
  333. Download_click(){
  334. const options ={
  335. allowTaint: true,
  336. useCORS: true
  337. }
  338. html2canvas(this.$refs.mychart,options).then(canvas =>{
  339. // const imageSrc = canvas.toDataURL();
  340. const imageUrl = canvas.toDataURL("image/png");
  341. const blob = this.dataURLtoBlob(imageUrl)
  342. const url = URL.createObjectURL(blob);
  343. var link= document.createElement("a");
  344. // //将生成的图片url赋值给a标签的href属性
  345. link.href = url;
  346. // //设置下载的文件名
  347. link.download = "透析完成率统计.jpg";
  348. // // 将a标签插入dom中
  349. console.log('link',link);
  350. document.body.appendChild(link);
  351. //模拟点击事件触发下载
  352. link.click();
  353. // 完成之后销毁创建的a标签
  354. document.body.removeChild(link);
  355. })
  356. },
  357. // 导出excel
  358. derive_click(){
  359. let tableData = [
  360. ['序号', '透析号', '患者姓名', '年龄','透析日期', '透后血压']//导出表头
  361. ]
  362. this.tableData.forEach((item,index) =>{
  363. let rowdata=[]
  364. rowdata=[
  365. item.index,
  366. item.dialysis_no,
  367. item.patient_name,
  368. item.age,
  369. item.dialysis_date,
  370. item.PostDialysisBP
  371. ]
  372. tableData.push(rowdata)
  373. })
  374. let workSheet = XLSX.utils.aoa_to_sheet(tableData);
  375. let bookNew = XLSX.utils.book_new();
  376. XLSX.utils.book_append_sheet(bookNew, workSheet, '患者透后血压分析') // 工作簿名称
  377. let name = '患者透后血压分析'+ '.xlsx'
  378. XLSX.writeFile(bookNew, name) // 保存的文件名
  379. },
  380. // 详情数据源
  381. getdetail(value){
  382. const params ={
  383. start_time:this.start_date,
  384. end_time:this.end_date,
  385. status_type:value,
  386. statistics_type:2,
  387. page:this.currentPage,
  388. limit:this.limit,
  389. }
  390. Getbpdetail(params).then(response =>{
  391. if(response.data.state ==1){
  392. const list = response.data.data.list
  393. const xAxis = []
  394. const table = []
  395. if(list.length > 0){
  396. list.forEach((item,index) =>{
  397. const obj={
  398. index:index+1,
  399. dialysis_no:item.dialysis_no,
  400. patient_name:item.patient_name,
  401. age:item.age,
  402. dialysis_date:this.getTime(item.assessment_date),
  403. PostDialysisBP:item.post_dialysis_bp,
  404. }
  405. table.push(obj)
  406. })
  407. this.tableData = table
  408. this.total = response.data.data.total
  409. }
  410. }
  411. console.log('55555透后',response);
  412. })
  413. },
  414. // 选择日期
  415. datachange(eve){
  416. if(eve ==1){
  417. this.start_date = this.getPreviousDate(7)
  418. this.end_date = this.getTime(new Date())
  419. }else if(eve==2){
  420. this.start_date = this.getFirstDayOfWeek(new Date())
  421. this.end_date = this.getTime(new Date())
  422. console.log('this.start_date', this.start_date);
  423. }else if(eve ==3){
  424. var date=new Date()
  425. date.setDate(date.getDate()-7 - date.getDay() + 1);
  426. var m =''
  427. var d = ''
  428. if(date.getMonth() + 1<10){
  429. m = '0'+(date.getMonth() + 1)
  430. }else{
  431. m = date.getMonth() + 1
  432. }
  433. if(date.getDate()<10){
  434. d = '0'+date.getDate()
  435. }else{
  436. d = date.getDate()
  437. }
  438. // this.start_date = date.getFullYear() + "-" + (date.getMonth() + 1) + "-" + date.getDate() ;
  439. this.start_date = date.getFullYear() + "-" + m + "-" + d ;
  440. date.setDate(date.getDate() +6);
  441. var mm = ''
  442. var dd = ''
  443. if(date.getMonth() + 1<10){
  444. mm = '0'+(date.getMonth() + 1)
  445. }else{
  446. mm = date.getMonth() + 1
  447. }
  448. if(date.getDate()<10){
  449. dd = '0'+date.getDate()
  450. }else{
  451. dd = date.getDate()
  452. }
  453. // if(date.getMonth() + 1<10)
  454. // this.end_date = date.getFullYear() + "-" + (date.getMonth() + 1) + "-" + date.getDate();
  455. this.end_date = date.getFullYear() + "-" + mm + "-" + dd ;
  456. console.log('this.end_date',this.end_date);
  457. }else if(eve ==4){
  458. this.start_date = this.getFirstDayOfMonth(new Date())
  459. this.end_date = this.getTime(new Date())
  460. }else if(eve ==5){
  461. this.getLastMonthFirstDay()
  462. this.getLastMonthLastDay()
  463. }else if(eve == 6){
  464. this.start_date = this.getFirstDayOfYear(new Date())
  465. this.end_date = this.getTime(new Date())
  466. }else if(eve == 7){
  467. this.getLastYearFirstDay()
  468. this.getLastYearLastDay()
  469. }
  470. console.log('eve',eve);
  471. },
  472. // 首先定义一个getPreviousDate函数,方便调用
  473. getPreviousDate(numOfDays) {
  474. var date = new Date();
  475. date.setDate(date.getDate() - numOfDays);
  476. var year = date.getFullYear();
  477. if(date.getMonth() + 1<10){
  478. var month = '0'+(date.getMonth() + 1);
  479. }else{
  480. var month = date.getMonth() + 1;
  481. }
  482. if(date.getDate()<10){
  483. var day = '0'+date.getDate();
  484. }else{
  485. var day = date.getDate();
  486. }
  487. return year + "-" + month + "-" + day;
  488. },
  489. // 本周
  490. getFirstDayOfWeek(date){
  491. var weekday = date.getDay()
  492. date.setDate(date.getDate()-weekday+1);//往前算(weekday-1)天,年份、月份会自动变化
  493. return this.timeFormat(date);
  494. },
  495. // 本月
  496. getFirstDayOfMonth (date) {
  497. date.setDate(1);
  498. return this.timeFormat(date);
  499. },
  500. //上个月第一天
  501. getLastMonthFirstDay() {
  502. var date = new Date();
  503. date.setDate(0);
  504. var y = date.getFullYear(); //获取年份
  505. var m = date.getMonth() + 1; //获取月份
  506. m = m < 10 ? "0" + m : m;
  507. this.start_date = [y, m, '01'].join("-")
  508. // return [y, m, '01'].join("-");
  509. },
  510. // 上个月最后一天
  511. getLastMonthLastDay() {
  512. var date = new Date();
  513. date.setDate(0);
  514. var y = date.getFullYear(); //获取年份
  515. var m = date.getMonth() + 1; //获取月份
  516. var d = new Date(y, m, 0).getDate(); //获取当月最后一日
  517. m = m < 10 ? "0" + m : m; //月份补 0
  518. d = d < 10 ? "0" + d : d; //日数补 0
  519. this.end_date = [y, m, d].join("-")
  520. // return [y, m, d].join("-");
  521. },
  522. // 本年
  523. getFirstDayOfYear (date) {
  524. date.setDate(1);
  525. date.setMonth(0);
  526. return this.timeFormat(date);
  527. },
  528. // 上一年第一天
  529. getLastYearFirstDay() {
  530. let date = new Date();
  531. const year= date.setFullYear(date.getFullYear() - 1); // 设置年份为前一年
  532. const start_month= date.setMonth(0); // 设置月份为1月(注意月份是从0开始的)
  533. const start_day = date.setDate(1); // 设置日期为1日
  534. // const last_month = date.setMonth(11); // 设置月份为12月
  535. // const last_day = date.setDate(0); // 设置日期为0,这将自动设置为该月的最后一天
  536. // this.start_date = year+ "-" +start_month+ "-" +start_day
  537. this.start_date = this.getTime(start_day)
  538. // return this.start_date
  539. },
  540. // 上一年最后一天
  541. getLastYearLastDay() {
  542. let date = new Date();
  543. const year= date.setFullYear(date.getFullYear() - 1); // 设置年份为前一年
  544. const last_month = date.setMonth(12); // 设置月份为12月
  545. const last_day = date.setDate(0);// 设置日期为0,这将自动设置为该月的最后一天
  546. // this.end_date = year+ "-" +last_month+ "-" +last_day
  547. this.end_date = this.getTime(last_day)
  548. console.log('this.end_date',this.end_date);
  549. // return this.end_date;
  550. },
  551. // 日期格式化
  552. timeFormat(date) {
  553. if (!date || typeof(date) === "string") {
  554. this.error("参数异常,请检查...");
  555. }
  556. var y = date.getFullYear(); //年
  557. if(date.getMonth() + 1<10){
  558. var m ='0'+(date.getMonth() + 1); //月
  559. }else{
  560. var m =date.getMonth() + 1; //月
  561. }
  562. if(date.getDate()<10){
  563. var d ='0'+date.getDate(); //日
  564. }else{
  565. var d = date.getDate(); //日
  566. }
  567. // var d = date.getDate(); //日
  568. return y + "-" + m + "-" + d;
  569. },
  570. handleCurrentChange(val){
  571. this.currentPage = val
  572. this.getdetail(this.status_value)
  573. },
  574. handleSizeChange(val){
  575. this.limit = val
  576. this.getdetail(this.status_value)
  577. },
  578. // 转换时间
  579. getTime(val) {
  580. if(val < 0){
  581. return ""
  582. }
  583. if(val == ""){
  584. return ""
  585. }else {
  586. return uParseTime(val, '{y}-{m}-{d}')
  587. }
  588. },
  589. dataURLtoBlob(dataURL) {
  590. const arr = dataURL.split(',');
  591. const mime = arr[0].match(/:(.*?);/)[1];
  592. const bstr = atob(arr[1]);
  593. let n = bstr.length;
  594. const u8arr = new Uint8Array(n);
  595. while (n--) {
  596. u8arr[n] = bstr.charCodeAt(n);
  597. }
  598. return new Blob([u8arr], { type: mime });
  599. },
  600. // 计算年龄
  601. analyzeIDCard(IDCard){
  602. var age = 0,yearBirth,monthBirth,dayBirth;
  603. //获取用户身份证号码
  604. var userCard = IDCard;
  605. //如果身份证号码为undefind则返回空
  606. if(!userCard){
  607. return age;
  608. }
  609. var reg = /(^\d{15}$)|(^\d{17}([0-9]|X)$)/; //验证身份证号码的正则
  610. if (reg.test(userCard)) {
  611. if (userCard.length == 15) {
  612. var org_birthday = userCard.substring(6, 12);
  613. //获取出生年月日
  614. yearBirth = "19" + org_birthday.substring(0, 2);
  615. monthBirth = org_birthday.substring(2, 4);
  616. dayBirth = org_birthday.substring(4, 6);
  617. } else if (userCard.length == 18) {
  618. //获取出生年月日
  619. yearBirth = userCard.substring(6,10);
  620. monthBirth = userCard.substring(10,12);
  621. dayBirth = userCard.substring(12,14);
  622. }
  623. //获取当前年月日并计算年龄
  624. var myDate = new Date();
  625. var monthNow = myDate.getMonth() + 1;
  626. var dayNow = myDate.getDate();
  627. var age = myDate.getFullYear() - yearBirth;
  628. if(monthNow < monthBirth || (monthNow == monthBirth && dayNow < dayBirth)){
  629. age--;
  630. }
  631. //返回年龄
  632. return age;
  633. } else {
  634. return ''
  635. }
  636. },
  637. // 护士
  638. getAllNurseList(){
  639. getAllNurseList().then(response=>{
  640. if(response.data.state ==1){
  641. var nurseList = response.data.data.nurseList
  642. console.log('0000',nurseList);
  643. this.nurseList =nurseList
  644. }
  645. })
  646. },
  647. // 医生
  648. getAllDoctorList(){
  649. getAllDoctorList().then(response=>{
  650. if(response.data.state == 1){
  651. var list = response.data.data.list
  652. console.log("list222222",list)
  653. this.docList = list
  654. this.operators = response.data.data.operators
  655. }
  656. })
  657. },
  658. getnurse(ids){
  659. const nurse = this.nurseList
  660. for(let i in nurse){
  661. if(ids==nurse[i].admin_user_id){
  662. return nurse[i].user_name
  663. }
  664. }
  665. },
  666. getdoctor(ids){
  667. const doctor = this.docList
  668. for(let i in doctor){
  669. if(ids == doctor[i].admin_user_id){
  670. return doctor[i].user_name
  671. }
  672. }
  673. }
  674. },
  675. mounted(){
  676. this.getecharts()
  677. },
  678. created(){
  679. this.start_date = this.getFirstDayOfMonth(new Date())
  680. this.getAllNurseList()
  681. this.getAllDoctorList()
  682. },
  683. }
  684. </script>