after_Blood.vue 23KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701
  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.getdetail(this.status_value)
  330. },
  331. // 下载
  332. Download_click(){
  333. const options ={
  334. allowTaint: true,
  335. useCORS: true
  336. }
  337. html2canvas(this.$refs.mychart,options).then(canvas =>{
  338. // const imageSrc = canvas.toDataURL();
  339. const imageUrl = canvas.toDataURL("image/png");
  340. const blob = this.dataURLtoBlob(imageUrl)
  341. const url = URL.createObjectURL(blob);
  342. var link= document.createElement("a");
  343. // //将生成的图片url赋值给a标签的href属性
  344. link.href = url;
  345. // //设置下载的文件名
  346. link.download = "透析完成率统计.jpg";
  347. // // 将a标签插入dom中
  348. console.log('link',link);
  349. document.body.appendChild(link);
  350. //模拟点击事件触发下载
  351. link.click();
  352. // 完成之后销毁创建的a标签
  353. document.body.removeChild(link);
  354. })
  355. },
  356. // 导出excel
  357. derive_click(){
  358. let tableData = [
  359. ['序号', '透析号', '患者姓名', '年龄','透析日期', '透后血压']//导出表头
  360. ]
  361. this.tableData.forEach((item,index) =>{
  362. let rowdata=[]
  363. rowdata=[
  364. item.index,
  365. item.dialysis_no,
  366. item.patient_name,
  367. item.age,
  368. item.dialysis_date,
  369. item.PostDialysisBP
  370. ]
  371. tableData.push(rowdata)
  372. })
  373. let workSheet = XLSX.utils.aoa_to_sheet(tableData);
  374. let bookNew = XLSX.utils.book_new();
  375. XLSX.utils.book_append_sheet(bookNew, workSheet, '患者透后血压分析') // 工作簿名称
  376. let name = '患者透后血压分析'+ '.xlsx'
  377. XLSX.writeFile(bookNew, name) // 保存的文件名
  378. },
  379. // 详情数据源
  380. getdetail(value){
  381. const params ={
  382. start_time:this.start_date,
  383. end_time:this.end_date,
  384. status_type:value,
  385. statistics_type:2,
  386. page:this.currentPage,
  387. limit:this.limit,
  388. }
  389. Getbpdetail(params).then(response =>{
  390. if(response.data.state ==1){
  391. const list = response.data.data.list
  392. const xAxis = []
  393. const table = []
  394. if(list.length > 0){
  395. list.forEach((item,index) =>{
  396. const obj={
  397. index:index+1,
  398. dialysis_no:item.dialysis_no,
  399. patient_name:item.patient_name,
  400. age:item.age,
  401. dialysis_date:this.getTime(item.assessment_date),
  402. PostDialysisBP:item.post_dialysis_bp,
  403. }
  404. table.push(obj)
  405. })
  406. this.tableData = table
  407. this.total = response.data.data.total
  408. }
  409. }
  410. console.log('55555透后',response);
  411. })
  412. },
  413. // 选择日期
  414. datachange(eve){
  415. if(eve ==1){
  416. this.start_date = this.getPreviousDate(7)
  417. this.end_date = this.getTime(new Date())
  418. }else if(eve==2){
  419. this.start_date = this.getFirstDayOfWeek(new Date())
  420. this.end_date = this.getTime(new Date())
  421. console.log('this.start_date', this.start_date);
  422. }else if(eve ==3){
  423. var date=new Date()
  424. date.setDate(date.getDate()-7 - date.getDay() + 1);
  425. var m =''
  426. var d = ''
  427. if(date.getMonth() + 1<10){
  428. m = '0'+(date.getMonth() + 1)
  429. }else{
  430. m = date.getMonth() + 1
  431. }
  432. if(date.getDate()<10){
  433. d = '0'+date.getDate()
  434. }else{
  435. d = date.getDate()
  436. }
  437. // this.start_date = date.getFullYear() + "-" + (date.getMonth() + 1) + "-" + date.getDate() ;
  438. this.start_date = date.getFullYear() + "-" + m + "-" + d ;
  439. date.setDate(date.getDate() +6);
  440. var mm = ''
  441. var dd = ''
  442. if(date.getMonth() + 1<10){
  443. mm = '0'+(date.getMonth() + 1)
  444. }else{
  445. mm = date.getMonth() + 1
  446. }
  447. if(date.getDate()<10){
  448. dd = '0'+date.getDate()
  449. }else{
  450. dd = date.getDate()
  451. }
  452. // if(date.getMonth() + 1<10)
  453. // this.end_date = date.getFullYear() + "-" + (date.getMonth() + 1) + "-" + date.getDate();
  454. this.end_date = date.getFullYear() + "-" + mm + "-" + dd ;
  455. console.log('this.end_date',this.end_date);
  456. }else if(eve ==4){
  457. this.start_date = this.getFirstDayOfMonth(new Date())
  458. this.end_date = this.getTime(new Date())
  459. }else if(eve ==5){
  460. this.getLastMonthFirstDay()
  461. this.getLastMonthLastDay()
  462. }else if(eve == 6){
  463. this.start_date = this.getFirstDayOfYear(new Date())
  464. this.end_date = this.getTime(new Date())
  465. }else if(eve == 7){
  466. this.getLastYearFirstDay()
  467. this.getLastYearLastDay()
  468. }
  469. console.log('eve',eve);
  470. },
  471. // 首先定义一个getPreviousDate函数,方便调用
  472. getPreviousDate(numOfDays) {
  473. var date = new Date();
  474. date.setDate(date.getDate() - numOfDays);
  475. var year = date.getFullYear();
  476. if(date.getMonth() + 1<10){
  477. var month = '0'+(date.getMonth() + 1);
  478. }else{
  479. var month = date.getMonth() + 1;
  480. }
  481. if(date.getDate()<10){
  482. var day = '0'+date.getDate();
  483. }else{
  484. var day = date.getDate();
  485. }
  486. return year + "-" + month + "-" + day;
  487. },
  488. // 本周
  489. getFirstDayOfWeek(date){
  490. var weekday = date.getDay()
  491. date.setDate(date.getDate()-weekday+1);//往前算(weekday-1)天,年份、月份会自动变化
  492. return this.timeFormat(date);
  493. },
  494. // 本月
  495. getFirstDayOfMonth (date) {
  496. date.setDate(1);
  497. return this.timeFormat(date);
  498. },
  499. //上个月第一天
  500. getLastMonthFirstDay() {
  501. var date = new Date();
  502. date.setDate(0);
  503. var y = date.getFullYear(); //获取年份
  504. var m = date.getMonth() + 1; //获取月份
  505. m = m < 10 ? "0" + m : m;
  506. this.start_date = [y, m, '01'].join("-")
  507. // return [y, m, '01'].join("-");
  508. },
  509. // 上个月最后一天
  510. getLastMonthLastDay() {
  511. var date = new Date();
  512. date.setDate(0);
  513. var y = date.getFullYear(); //获取年份
  514. var m = date.getMonth() + 1; //获取月份
  515. var d = new Date(y, m, 0).getDate(); //获取当月最后一日
  516. m = m < 10 ? "0" + m : m; //月份补 0
  517. d = d < 10 ? "0" + d : d; //日数补 0
  518. this.end_date = [y, m, d].join("-")
  519. // return [y, m, d].join("-");
  520. },
  521. // 本年
  522. getFirstDayOfYear (date) {
  523. date.setDate(1);
  524. date.setMonth(0);
  525. return this.timeFormat(date);
  526. },
  527. // 上一年第一天
  528. getLastYearFirstDay() {
  529. let date = new Date();
  530. const year= date.setFullYear(date.getFullYear() - 1); // 设置年份为前一年
  531. const start_month= date.setMonth(0); // 设置月份为1月(注意月份是从0开始的)
  532. const start_day = date.setDate(1); // 设置日期为1日
  533. // const last_month = date.setMonth(11); // 设置月份为12月
  534. // const last_day = date.setDate(0); // 设置日期为0,这将自动设置为该月的最后一天
  535. // this.start_date = year+ "-" +start_month+ "-" +start_day
  536. this.start_date = this.getTime(start_day)
  537. // return this.start_date
  538. },
  539. // 上一年最后一天
  540. getLastYearLastDay() {
  541. let date = new Date();
  542. const year= date.setFullYear(date.getFullYear() - 1); // 设置年份为前一年
  543. const last_month = date.setMonth(12); // 设置月份为12月
  544. const last_day = date.setDate(0);// 设置日期为0,这将自动设置为该月的最后一天
  545. // this.end_date = year+ "-" +last_month+ "-" +last_day
  546. this.end_date = this.getTime(last_day)
  547. console.log('this.end_date',this.end_date);
  548. // return this.end_date;
  549. },
  550. // 日期格式化
  551. timeFormat(date) {
  552. if (!date || typeof(date) === "string") {
  553. this.error("参数异常,请检查...");
  554. }
  555. var y = date.getFullYear(); //年
  556. if(date.getMonth() + 1<10){
  557. var m ='0'+(date.getMonth() + 1); //月
  558. }else{
  559. var m =date.getMonth() + 1; //月
  560. }
  561. if(date.getDate()<10){
  562. var d ='0'+date.getDate(); //日
  563. }else{
  564. var d = date.getDate(); //日
  565. }
  566. // var d = date.getDate(); //日
  567. return y + "-" + m + "-" + d;
  568. },
  569. handleCurrentChange(val){
  570. this.currentPage = val
  571. this.getdetail(this.status_value)
  572. },
  573. handleSizeChange(val){
  574. this.limit = val
  575. this.getdetail(this.status_value)
  576. },
  577. // 转换时间
  578. getTime(val) {
  579. if(val < 0){
  580. return ""
  581. }
  582. if(val == ""){
  583. return ""
  584. }else {
  585. return uParseTime(val, '{y}-{m}-{d}')
  586. }
  587. },
  588. dataURLtoBlob(dataURL) {
  589. const arr = dataURL.split(',');
  590. const mime = arr[0].match(/:(.*?);/)[1];
  591. const bstr = atob(arr[1]);
  592. let n = bstr.length;
  593. const u8arr = new Uint8Array(n);
  594. while (n--) {
  595. u8arr[n] = bstr.charCodeAt(n);
  596. }
  597. return new Blob([u8arr], { type: mime });
  598. },
  599. // 计算年龄
  600. analyzeIDCard(IDCard){
  601. var age = 0,yearBirth,monthBirth,dayBirth;
  602. //获取用户身份证号码
  603. var userCard = IDCard;
  604. //如果身份证号码为undefind则返回空
  605. if(!userCard){
  606. return age;
  607. }
  608. var reg = /(^\d{15}$)|(^\d{17}([0-9]|X)$)/; //验证身份证号码的正则
  609. if (reg.test(userCard)) {
  610. if (userCard.length == 15) {
  611. var org_birthday = userCard.substring(6, 12);
  612. //获取出生年月日
  613. yearBirth = "19" + org_birthday.substring(0, 2);
  614. monthBirth = org_birthday.substring(2, 4);
  615. dayBirth = org_birthday.substring(4, 6);
  616. } else if (userCard.length == 18) {
  617. //获取出生年月日
  618. yearBirth = userCard.substring(6,10);
  619. monthBirth = userCard.substring(10,12);
  620. dayBirth = userCard.substring(12,14);
  621. }
  622. //获取当前年月日并计算年龄
  623. var myDate = new Date();
  624. var monthNow = myDate.getMonth() + 1;
  625. var dayNow = myDate.getDate();
  626. var age = myDate.getFullYear() - yearBirth;
  627. if(monthNow < monthBirth || (monthNow == monthBirth && dayNow < dayBirth)){
  628. age--;
  629. }
  630. //返回年龄
  631. return age;
  632. } else {
  633. return ''
  634. }
  635. },
  636. // 护士
  637. getAllNurseList(){
  638. getAllNurseList().then(response=>{
  639. if(response.data.state ==1){
  640. var nurseList = response.data.data.nurseList
  641. console.log('0000',nurseList);
  642. this.nurseList =nurseList
  643. }
  644. })
  645. },
  646. // 医生
  647. getAllDoctorList(){
  648. getAllDoctorList().then(response=>{
  649. if(response.data.state == 1){
  650. var list = response.data.data.list
  651. console.log("list222222",list)
  652. this.docList = list
  653. this.operators = response.data.data.operators
  654. }
  655. })
  656. },
  657. getnurse(ids){
  658. const nurse = this.nurseList
  659. for(let i in nurse){
  660. if(ids==nurse[i].admin_user_id){
  661. return nurse[i].user_name
  662. }
  663. }
  664. },
  665. getdoctor(ids){
  666. const doctor = this.docList
  667. for(let i in doctor){
  668. if(ids == doctor[i].admin_user_id){
  669. return doctor[i].user_name
  670. }
  671. }
  672. }
  673. },
  674. mounted(){
  675. this.getecharts()
  676. },
  677. created(){
  678. this.start_date = this.getFirstDayOfMonth(new Date())
  679. this.getAllNurseList()
  680. this.getAllDoctorList()
  681. },
  682. }
  683. </script>