patientComplianceDetails.vue 18KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585
  1. <template>
  2. <div class="main-contain">
  3. <div class="position">
  4. <bread-crumb :crumbs="crumbs"></bread-crumb>
  5. <el-button type="primary" @click="$router.back(-1)">返回</el-button>
  6. </div>
  7. <div class="app-container">
  8. <div class="page_patientComplianceDetails">
  9. <div class="cell clearfix" style="margin:0">
  10. <el-form :inline="true" :model="listQuery">
  11. </el-form>
  12. </div>
  13. <el-container>
  14. <div style="width:160px">
  15. <el-form :inline="true" :model="listQuery">
  16. <el-form-item label>
  17. <el-autocomplete
  18. class="checkSearch"
  19. popper-class="my-autocomplete"
  20. v-model.trim="listQuery.search"
  21. :fetch-suggestions="querySearchAsync"
  22. :trigger-on-focus="false"
  23. placeholder="病人透析号/姓名"
  24. @select="handleSelect"
  25. >
  26. <i class="el-icon-search el-input__icon" slot="suffix"></i>
  27. <template slot-scope="{ item }">
  28. <div class="name">{{ item.name }}</div>
  29. </template>
  30. </el-autocomplete>
  31. </el-form-item>
  32. </el-form>
  33. <div class="tableTitle">患者列表</div>
  34. <el-table :data="patientsData" border style="width: 100%;" height="500" highlight-current-row @current-change="handleChange" :row-style="{ color: '#303133' }" :header-cell-style="{backgroundColor: 'rgb(245, 247, 250)',color: '#606266'}">
  35. <el-table-column prop="name" label="透析号" width="70">
  36. <template slot-scope="scope">
  37. {{scope.row.dialysis_no}}
  38. </template>
  39. </el-table-column>
  40. <el-table-column prop="date" label="姓名" width="90">
  41. <template slot-scope="scope">
  42. {{scope.row.name }}
  43. </template>
  44. </el-table-column>
  45. </el-table>
  46. </div>
  47. <div class="containerRight" style="flex:1;overflow: hidden">
  48. <div class="cell clearfix">
  49. <label class="title" style="text-align:left">
  50. <span class="name">统计方式</span> :
  51. </label>
  52. <div class="time">
  53. <ul class>
  54. <li
  55. :class="item.state == monthType ? 'active' : ''"
  56. @click="chooseMonth(item.state)"
  57. v-for="item in month"
  58. :key="item.value"
  59. >{{ item.label }}</li>
  60. </ul>
  61. </div>
  62. <label class="title">
  63. <span class="name">日期查询</span> :
  64. </label>
  65. <el-date-picker
  66. v-model="listQuery.start_time"
  67. prefix-icon="el-icon-date"
  68. @change="changeTime"
  69. :editable="false"
  70. type="date"
  71. style="max-width:160px"
  72. placeholder="选择日期时间"
  73. align="right"
  74. format="yyyy-MM-dd"
  75. value-format="yyyy-MM-dd"
  76. :picker-options="pickerOptions"
  77. ></el-date-picker>
  78. <span class>-</span>
  79. <el-date-picker
  80. v-model="listQuery.end_time"
  81. prefix-icon="el-icon-date"
  82. @change="changeEndTime"
  83. :editable="false"
  84. type="date"
  85. style="max-width:160px"
  86. placeholder="选择日期时间"
  87. align="right"
  88. format="yyyy-MM-dd"
  89. value-format="yyyy-MM-dd"
  90. :picker-options="pickerOptions"
  91. ></el-date-picker>
  92. </div>
  93. <div class="tableTitle">指标监控</div>
  94. <div style="width:100%;overflow-x:auto">
  95. <div class="qualityBox">
  96. <div
  97. class="qualityOne"
  98. v-for="(item,index) in normData"
  99. :key="index"
  100. :class="quality == index ? 'active' : ''"
  101. @click="clickQuality(index,item.inspection_minor)"
  102. >
  103. <p>{{ item.item_name }}</p>
  104. <span v-if="isTrue == 1"><i class="iconfont icon-gou gou"></i></span>
  105. <span v-if="isTrue == 0"><i class="iconfont icon-gantanhao gth"></i></span>
  106. </div>
  107. </div>
  108. </div>
  109. <div class="tableTitle">指标趋势</div>
  110. <div class="cell clearfix">
  111. <p class="point"></p>
  112. <p class="pointTitle">达标率</p>
  113. </div>
  114. <div>
  115. <line-chart :options="chart"></line-chart>
  116. </div>
  117. </div>
  118. </el-container>
  119. </div>
  120. </div>
  121. </div>
  122. </template>
  123. <script>
  124. const moment = require('moment')
  125. import echarts from "echarts";
  126. import BreadCrumb from "@/xt_pages/components/bread-crumb";
  127. import LineChart from "../qcd/components/LineChart";
  128. import { uParseTime } from "@/utils/tools";
  129. import { getCurrentOrgPatients,GetQualityControl,getNormData,getPatientComplianceDetail } from "@/api/common/common"
  130. export default {
  131. components: {
  132. LineChart,
  133. BreadCrumb
  134. },
  135. data() {
  136. return {
  137. isTrue:0,
  138. crumbs: [
  139. { path: false, name: "质控管理" },
  140. { path: false, name: "患者达标详情" }
  141. ],
  142. patientsData:[],
  143. normData:[],
  144. startime:0,
  145. endtime:0,
  146. listQuery: {
  147. start_time: "",
  148. end_time: "",
  149. page: 1,
  150. limit: 10
  151. },
  152. item_id:0,
  153. month: [
  154. { value: 0, label: "本月", state: 0 },
  155. { value: 1, label: "近三月", state: 1 },
  156. { value: 2, label: "近半年", state: 2 },
  157. { value: 3, label: "近一年", state: 3 }
  158. ],
  159. modesData: {
  160. xAxis: [],
  161. series: []
  162. },
  163. pickerOptions: {
  164. disabledDate(time) {
  165. let threeMonths = new Date(new Date().setFullYear(new Date().getFullYear()-1)).getTime() - 24 * 3600 * 1000;
  166. return time.getTime() > Date.now() || time.getTime() < threeMonths;;
  167. }
  168. },
  169. patientid:0,
  170. monthType: 0,
  171. arr: [],
  172. quality: 0,
  173. chart: {
  174. title: {
  175. text: "ECharts 入门示例"
  176. },
  177. tooltip: {},
  178. // legend: {
  179. // data: ["次数"],
  180. // left: 0
  181. // },
  182. xAxis: {
  183. data: []
  184. },
  185. yAxis: {
  186. axisLabel: {
  187. formatter: "{value} %"
  188. },
  189. show: false
  190. },
  191. series: [
  192. {
  193. name: "次数",
  194. type: "line",
  195. data: [],
  196. barWidth: 30,
  197. label: {
  198. normal: {
  199. show: true,
  200. position: "top",
  201. formatter: "{c}g/L"
  202. }
  203. },
  204. //配置样式
  205. itemStyle: {
  206. //通常情况下:
  207. //每个柱子的颜色即为colorList数组里的每一项,如果柱子数目多于colorList的长度,则柱子颜色循环使用该数组
  208. normal: {
  209. color: function(params) {
  210. //我这边就两个柱子,大体就两个柱子颜色渐变,所以数组只有两个值,多个颜色就多个值
  211. var colorList = [
  212. ["#A9E0F3", "#9FBDFC"],
  213. ["#A9E0F3", "#9FBDFC"],
  214. ["#A9E0F3", "#9FBDFC"],
  215. ["#FFD7C0", "#FF9994"],
  216. ["#FFD7C0", "#FF9994"],
  217. ["#FFD7C0", "#FF9994"],
  218. ["#D7C3FD", "#B3A8F7"],
  219. ["#D7C3FD", "#B3A8F7"],
  220. ["#D7C3FD", "#B3A8F7"]
  221. ];
  222. var index = params.dataIndex;
  223. if (params.dataIndex >= colorList.length) {
  224. index = params.dataIndex % colorList.length;
  225. }
  226. return new echarts.graphic.LinearGradient(0, 0, 0, 1, [
  227. { offset: 0, color: colorList[index][0] },
  228. // { offset: 0.5, color: colorList[index][1] },
  229. { offset: 1, color: colorList[index][1] }
  230. ]);
  231. },
  232. lineStyle:{
  233. color:'#409eff' //改变折线颜色
  234. },
  235. barBorderRadius: [5, 5, 0, 0] //柱状角成椭圆形
  236. },
  237. //鼠标悬停时:
  238. emphasis: {
  239. shadowBlur: 10,
  240. shadowOffsetX: 0,
  241. shadowColor: "rgba(0, 0, 0, 0.5)"
  242. }
  243. }
  244. }
  245. ]
  246. },
  247. inspect_date:0,
  248. monthActive:0,
  249. };
  250. },
  251. methods: {
  252. chooseMonth(month) {
  253. //一月
  254. if(month == 0){
  255. this.monthActive = 0
  256. const startDate = moment().subtract('month', 0).format('YYYY-MM') + '-01'
  257. const endDate = moment(new Date()).format('YYYY-MM-DD')
  258. var now = new Date()
  259. var nowMonth = now.getMonth(); //当前月
  260. var nowYear = now.getFullYear(); //当前年
  261. //本月的开始时间
  262. var monthStartDate = new Date(nowYear, nowMonth, 1);
  263. this.startime=Date.parse(monthStartDate)/1000;//s
  264. //本月的结束时间
  265. var monthEndDate = moment().endOf('month').format('YYYY-MM-DD HH:mm:ss');
  266. this.endtime =Date.parse(monthEndDate)/1000-1;//s
  267. this.getlistDetail()
  268. }
  269. //近三月
  270. if(month == 1){
  271. this.monthActive = 1
  272. const startDate = moment().subtract('month', 3).format('YYYY-MM-DD')
  273. this.startime = Date.parse(startDate)/1000
  274. const endDate = moment(new Date()).format('YYYY-MM-DD')
  275. this.endtime = Date.parse(endDate)/1000
  276. this.getlistDetail()
  277. }
  278. //近半年
  279. if(month == 2){
  280. this.monthActive = 2
  281. const startDate = moment().subtract('month', 6).format('YYYY-MM-DD')
  282. this.startime = Date.parse(startDate)/1000
  283. const endDate = moment(new Date()).format('YYYY-MM-DD')
  284. this.endtime = Date.parse(endDate)/1000
  285. this.getlistDetail()
  286. }
  287. //近一年
  288. if(month == 3){
  289. this.monthActive = 3
  290. const startDate = moment().subtract('month', 12).format('YYYY-MM-DD')
  291. this.startime = Date.parse(startDate)/1000
  292. const endDate = moment(new Date()).format('YYYY-MM-DD')
  293. this.endtime = Date.parse(endDate)/1000
  294. this.getlistDetail()
  295. }
  296. this.monthType = month;
  297. },
  298. clickQuality(index,itemid) {
  299. this.quality = index;
  300. this.item_id = itemid
  301. this.getlistDetail()
  302. },
  303. handleSizeChange(limit) {
  304. //this.limit = limit;
  305. //this.getConfigurationList();
  306. },
  307. handleCurrentChange(page) {
  308. //this.page = page;
  309. //this.getConfigurationList();
  310. },
  311. getTime(time) {
  312. return uParseTime(time, "{y}-{m}-{d}");
  313. },
  314. onSearch(){
  315. },
  316. changeTime(val){
  317. var time = this.getTimestamp(val) - this.getTimestamp(this.listQuery.end_time);
  318. if (time > 0) {
  319. this.$message.error("结束时间不能小于开始时间");
  320. this.listQuery.start_time = "";
  321. } else {
  322. this.startime = Date.parse(val)/1000;//s
  323. this.getlistDetail()
  324. }
  325. },
  326. changeEndTime(val){
  327. var time =
  328. this.getTimestamp(val) - this.getTimestamp(this.listQuery.start_time);
  329. if (time < 0) {
  330. this.$message.error("结束时间不能小于开始时间");
  331. this.listQuery.end_time = "";
  332. } else {
  333. this.endtime = Date.parse(val)/1000;//s
  334. this.getlistDetail()
  335. }
  336. },
  337. getTimestamp(time) {
  338. // 把时间日期转成时间戳
  339. return new Date(time).getTime() / 1000;
  340. },
  341. handleChange(val){
  342. this.patientid = val.id
  343. this.getlistDetail()
  344. },
  345. getCurrentOrgPatients(){
  346. getCurrentOrgPatients().then(response=>{
  347. if(response.data.state == 1){
  348. var patients = response.data.data.patients
  349. this.patientsData = patients
  350. }
  351. })
  352. },
  353. getNormData(){
  354. getNormData().then(response=>{
  355. var normdata = response.data.data.normdata
  356. for(let i=0;i<normdata.length;i++){
  357. this.item_id = normdata[0].inspection_minor
  358. }
  359. this.normData = normdata
  360. this.getlist()
  361. })
  362. },
  363. getlist(){
  364. console.log("进来没有")
  365. this.modesData.series = []
  366. this.modesData.xAxis = []
  367. const startDate = moment().subtract('month', 0).format('YYYY-MM') + '-01'
  368. const endDate = moment(new Date()).format('YYYY-MM-DD')
  369. var now = new Date()
  370. var nowMonth = now.getMonth(); //当前月
  371. var nowYear = now.getFullYear(); //当前年
  372. //本月的开始时间
  373. var monthStartDate = new Date(nowYear, nowMonth, 1);
  374. this.startime=Date.parse(monthStartDate)/1000;//s
  375. //本月的结束时间
  376. var monthEndDate = moment().endOf('month').format('YYYY-MM-DD HH:mm:ss');
  377. this.endtime =Date.parse(monthEndDate)/1000-1;//s
  378. const params = {
  379. patientid:this.patientid,
  380. startime:this.startime,
  381. endtime:this.endtime,
  382. itemid:this.item_id,
  383. inspectdate:this.inspect_date,
  384. }
  385. GetQualityControl(params).then(response=>{
  386. if(response.data.state == 1){
  387. var list = response.data.data.list
  388. console.log("list",list)
  389. for(let i=0;i<list.length;i++){
  390. if(parseInt(list[i].inspect_value)>= parseInt(list[i].range_min) && parseInt(list[i].inspect_value)<= parseInt(list[i].range_max)){
  391. this.isTrue = 1
  392. }
  393. if(parseInt(list[i].inspect_value)< parseInt(list[i].range_min) || parseInt(list[i].inspect_value) > parseInt(list[i].range_max)){
  394. this.isTrue =0
  395. }
  396. this.modesData.xAxis.push(this.getTime(list[i].inspect_date));
  397. this.modesData.series.push(list[i].inspect_value)
  398. }
  399. this.chart.series[0].data = this.modesData.series
  400. this.chart.xAxis.data = this.modesData.xAxis
  401. }
  402. })
  403. },
  404. getlistDetail(){
  405. this.modesData.series = []
  406. this.modesData.xAxis = []
  407. const startDate = moment().subtract('month', 0).format('YYYY-MM') + '-01'
  408. const endDate = moment(new Date()).format('YYYY-MM-DD')
  409. if(this.monthActive == 0){
  410. var now = new Date()
  411. var nowMonth = now.getMonth(); //当前月
  412. var nowYear = now.getFullYear(); //当前年
  413. //本月的开始时间
  414. var monthStartDate = new Date(nowYear, nowMonth, 1);
  415. this.startime=Date.parse(monthStartDate)/1000;//s
  416. //本月的结束时间
  417. var monthEndDate = moment().endOf('month').format('YYYY-MM-DD HH:mm:ss');
  418. this.endtime =Date.parse(monthEndDate)/1000-1;//s
  419. }
  420. const params = {
  421. patientid:this.patientid,
  422. startime:this.startime,
  423. endtime:this.endtime,
  424. itemid:this.item_id,
  425. }
  426. console.log("params",params)
  427. getPatientComplianceDetail(params).then(response=>{
  428. if(response.data.state == 1){
  429. var list = response.data.data.list
  430. for(let i=0;i<list.length;i++){
  431. if(parseInt(list[i].inspect_value)>= parseInt(list[i].range_min) && parseInt(list[i].inspect_value)<= parseInt(list[i].range_max)){
  432. this.isTrue = 1
  433. }
  434. if(parseInt(list[i].inspect_value)< parseInt(list[i].range_min) || parseInt(list[i].inspect_value) > parseInt(list[i].range_max)){
  435. this.isTrue =0
  436. }
  437. this.modesData.xAxis.push(this.getTime(list[i].inspect_date));
  438. this.modesData.series.push(list[i].inspect_value)
  439. }
  440. this.chart.series[0].data = this.modesData.series
  441. this.chart.xAxis.data = this.modesData.xAxis
  442. }
  443. })
  444. }
  445. },
  446. created(){
  447. this.patientid = this.$route.query.patientid
  448. this.inspect_date = this.$route.query.date
  449. //获取指标项
  450. this.getNormData()
  451. //获取该机构下的所有患者
  452. this.getCurrentOrgPatients()
  453. }
  454. };
  455. </script>
  456. <style lang="scss" scoped>
  457. .point {
  458. width: 13px;
  459. height: 13px;
  460. background: linear-gradient(
  461. 0deg,
  462. rgba(169, 224, 243, 1),
  463. rgba(159, 189, 252, 1)
  464. );
  465. border-radius: 7px;
  466. margin-right: 8px;
  467. }
  468. .pointTitle {
  469. font-size: 13px;
  470. }
  471. .containerRight {
  472. padding-left: 10px;
  473. }
  474. .tableTitle {
  475. font-size: 16px;
  476. color: #000;
  477. font-weight: bold;
  478. margin-bottom: 10px;
  479. margin-top: 8px;
  480. }
  481. .qualityBox {
  482. display: flex;
  483. flex-wrap: nowrap;
  484. min-width: 1800px;
  485. padding-bottom: 10px;
  486. .qualityOne {
  487. width: 4.5rem;
  488. height: 4.5rem;
  489. border-radius: 0.3125rem;
  490. border: 1px solid rgba(229, 229, 229, 1);
  491. display: flex;
  492. align-items: center;
  493. flex-direction: column;
  494. margin-right: 0.875rem;
  495. cursor: pointer;
  496. // justify-content: space-around;
  497. .gth {
  498. color: #ff974a;
  499. font-size: 1.25rem;
  500. }
  501. .gou {
  502. color: #5cd924;
  503. font-size: 1.25rem;
  504. }
  505. p {
  506. width: 100%;
  507. margin-top: 1.25rem;
  508. margin-bottom: 0.625rem;
  509. font-weight: bold;
  510. color: #666666;
  511. font-size: 0.875rem;
  512. text-align: center;
  513. white-space: nowrap;
  514. overflow: hidden;
  515. text-overflow: ellipsis;
  516. }
  517. }
  518. .active {
  519. background: #5b98ff;
  520. p {
  521. color: #fff;
  522. }
  523. .gth {
  524. color: #fff;
  525. font-size: 1.25rem;
  526. }
  527. .gou {
  528. color: #fff;
  529. font-size: 1.25rem;
  530. }
  531. }
  532. }
  533. </style>
  534. <style lang="scss">
  535. .page_patientComplianceDetails {
  536. .cell {
  537. text-align: center;
  538. }
  539. .el-form-item {
  540. margin-bottom: 0;
  541. }
  542. ::-webkit-scrollbar{
  543. height: 15px !important;
  544. }
  545. .el-form--inline .el-form-item{
  546. margin-right:0;
  547. }
  548. }
  549. </style>