Cure.vue 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761
  1. <template>
  2. <div class="doctorWork">
  3. <!-- 顶部筛选 -->
  4. <div class="screening">
  5. <div class="screening-title flex-vertical-center-l">
  6. <span></span>
  7. <div>筛选</div>
  8. </div>
  9. <div class="screening-form flex-vertical-center-l flex-wrap">
  10. <div class="screening-item flex-vertical-center-l">
  11. <span>年度:</span>
  12. <div class="input">
  13. <el-date-picker size="mini" v-model="form.year" type="year" placeholder="选择年"></el-date-picker>
  14. </div>
  15. </div>
  16. <div class="screening-item flex-vertical-center-l">
  17. <span>月度:</span>
  18. <div class="input">
  19. <el-date-picker
  20. size="mini"
  21. v-model="form.month"
  22. format="MM"
  23. type="month"
  24. placeholder="选择月"
  25. ></el-date-picker>
  26. </div>
  27. </div>
  28. <div class="screening-item flex-vertical-center-l">
  29. <span>机构名称:</span>
  30. <div class="input">
  31. <el-select size="mini" v-model="form.medName" placeholder="请选择">
  32. <el-option
  33. :label="item.name"
  34. :value="item.pid"
  35. v-for="(item,index) in medSelectList"
  36. :key="index"
  37. ></el-option>
  38. </el-select>
  39. </div>
  40. </div>
  41. <div class="screening-item flex-vertical-center-l">
  42. <div class="input flex-vertical-center-l">
  43. <el-checkbox v-model="form.checked">是否包含下级</el-checkbox>
  44. </div>
  45. </div>
  46. <el-button size="mini" type="primary" @click="search">搜索</el-button>
  47. <el-button size="mini" type="warning" @click="clearFilter">清空</el-button>
  48. </div>
  49. </div>
  50. <!-- 展示数据层 -->
  51. <div class="data-container">
  52. <div class="showData">
  53. <div class="flex-vertical-center-l">
  54. <div class="top-change flex-vertical-center-l">
  55. <div :class="isEcharts==0?'choosed':''" @click="topChange(0)">图表</div>
  56. <div :class="isEcharts==1?'choosed':''" @click="topChange(1)">列表</div>
  57. </div>
  58. <div class="flex-center bg-yellow" v-if="isEcharts==1" @click="exportCure">导出</div>
  59. </div>
  60. <!-- 展示两种数据 -->
  61. <div class="showEcharts" v-if="isEcharts==0">
  62. <div id="myChart" :style="{width: '100%', height: '400px'}"></div>
  63. <div class="e-format" style="margin-bottom:20px;">
  64. 格式:体质结果-时间:数量
  65. <span style="margin-left:30px;"></span> X轴:体质结果-时间 Y轴:单位(人)
  66. </div>
  67. </div>
  68. <!-- 列表展示 -->
  69. <div class="showList" v-if="isEcharts==1">
  70. <ul>
  71. <div class="title1">体质结果与性别分布量</div>
  72. <li class="flex-vertical-between" v-for="(item,index) in list1" :key="index">
  73. <div class="title">{{item.year}}</div>
  74. <div>
  75. 体质结果:
  76. <span>{{item.name}}</span>
  77. </div>
  78. <div>
  79. 男:
  80. <span>{{item.man}}</span>
  81. </div>
  82. <div>
  83. 女:
  84. <span>{{item.woman}}</span>
  85. </div>
  86. </li>
  87. </ul>
  88. <ul>
  89. <div class="title1">体质结果与年龄段分布量</div>
  90. <li class="flex-vertical-between" v-for="(item,index) in list2" :key="index">
  91. <div class="title">{{item.year}}</div>
  92. <div>
  93. 体质结果:
  94. <span>{{item.name}}</span>
  95. </div>
  96. <div>
  97. 10岁以下:
  98. <span>{{item.ac1}}</span>
  99. </div>
  100. <div>
  101. 10岁—30岁:
  102. <span>{{item.ac2}}</span>
  103. </div>
  104. <div>
  105. 30岁—50岁:
  106. <span>{{item.ac3}}</span>
  107. </div>
  108. <div>
  109. 50岁-60岁:
  110. <span>{{item.ac4}}</span>
  111. </div>
  112. <div>
  113. 60岁以上:
  114. <span>{{item.ac5}}</span>
  115. </div>
  116. </li>
  117. </ul>
  118. <ul>
  119. <div class="title1">体质测评人数与年龄段分布量</div>
  120. <li class="flex-vertical-between" v-for="(item,index) in list3" :key="index">
  121. <div class="title">{{item.year}}</div>
  122. <div>
  123. 10岁以下:
  124. <span>{{item.ac1}}</span>
  125. </div>
  126. <div>
  127. 10岁—30岁:
  128. <span>{{item.ac2}}</span>
  129. </div>
  130. <div>
  131. 30岁—50岁:
  132. <span>{{item.ac3}}</span>
  133. </div>
  134. <div>
  135. 50岁-60岁:
  136. <span>{{item.ac4}}</span>
  137. </div>
  138. <div>
  139. 60岁以上:
  140. <span>{{item.ac5}}</span>
  141. </div>
  142. </li>
  143. </ul>
  144. </div>
  145. </div>
  146. <div class="showData" v-if="isEcharts==0">
  147. <div class="showEcharts">
  148. <div id="myChart1" :style="{width: '100%', height: '400px'}"></div>
  149. <div class="e-format" style="margin-bottom:20px;">
  150. 格式:体质结果-时间:数量
  151. <span style="margin-left:30px;"></span> X轴:体质结果-时间 Y轴:单位(人)
  152. </div>
  153. </div>
  154. </div>
  155. <div class="showData" v-if="isEcharts==0">
  156. <div class="showEcharts">
  157. <div id="myChart2" :style="{width: '100%', height: '400px'}"></div>
  158. <div class="e-format" style="margin-bottom:20px;">
  159. 格式:时间:数量
  160. <span style="margin-left:30px;"></span> X轴:体质结果-时间 Y轴:单位(人)
  161. </div>
  162. </div>
  163. </div>
  164. </div>
  165. </div>
  166. </template>
  167. <script>
  168. import { mapState, mapGetters, mapActions, mapMutations } from "vuex";
  169. import { medicalInstitution } from "@/api/city.js";
  170. import { cureCount, exportCure } from "@/api/dataAnalysis.js";
  171. export default {
  172. data() {
  173. return {
  174. // 筛选数据
  175. form: {
  176. medName: "",
  177. year: "",
  178. month: "",
  179. checked: false
  180. },
  181. // 医疗机构
  182. medSelectList: [],
  183. // 是否是图表
  184. isEcharts: 0, // 0 图表 1 列表
  185. xAxisData: [], // 图表 横向坐标
  186. xAxisData1: [],
  187. xAxisData2: [],
  188. physicalAndSexCountVoList: [], // 体质结果与性别
  189. physicalAndAgeCountVoList: [], // 体质结果 与年龄段
  190. measurementCountVos: [], // 测评人数与年龄段
  191. list1: [],
  192. list2: [],
  193. list3: []
  194. };
  195. },
  196. created() {
  197. this.medicalInstitution();
  198. },
  199. mounted() {
  200. let date = new Date();
  201. this.form.year = date.getFullYear().toString();
  202. this.cureCount();
  203. },
  204. methods: {
  205. // 顶部列表更改
  206. topChange(type) {
  207. this.isEcharts = type;
  208. if (type == 0) {
  209. setTimeout(() => {
  210. this.cureCount();
  211. }, 200);
  212. }
  213. },
  214. // 绘制 图表
  215. drawLine2() {
  216. // 基于准备好的dom,初始化echarts实例
  217. let myChart = this.$echarts.init(document.getElementById("myChart2"));
  218. // 绘制图表
  219. myChart.setOption({
  220. title: {
  221. text: "体质测评人数与年龄段分布量",
  222. left: "center"
  223. },
  224. grid: {
  225. left: "10%",
  226. right: "10%",
  227. bottom: "3%",
  228. containLabel: true
  229. },
  230. legend: {
  231. orient: "vertical",
  232. left: "left"
  233. },
  234. color: ["#5FA0FA", "#FFB703", "#1bb2d8", "#FD2446", "#51CEC6"],
  235. tooltip: {},
  236. xAxis: {
  237. type: "category",
  238. data: this.xAxisData2
  239. },
  240. yAxis: {
  241. type: "value"
  242. },
  243. series: [
  244. {
  245. name: "10岁以下",
  246. type: "bar",
  247. data: this.measurementCountVos[0]
  248. },
  249. {
  250. name: "10岁—30岁",
  251. type: "bar",
  252. data: this.measurementCountVos[1]
  253. },
  254. {
  255. name: "30岁—50岁",
  256. type: "bar",
  257. data: this.measurementCountVos[2]
  258. },
  259. {
  260. name: "50岁-60岁",
  261. type: "bar",
  262. data: this.measurementCountVos[3]
  263. },
  264. {
  265. name: "60岁以上",
  266. type: "bar",
  267. data: this.measurementCountVos[4]
  268. }
  269. ]
  270. });
  271. },
  272. // 绘制 图表
  273. drawLine1() {
  274. // 基于准备好的dom,初始化echarts实例
  275. let myChart = this.$echarts.init(document.getElementById("myChart1"));
  276. // 绘制图表
  277. myChart.setOption({
  278. title: {
  279. text: "体质结果与年龄段分布量",
  280. left: "center"
  281. },
  282. legend: {
  283. orient: "vertical",
  284. left: "left"
  285. },
  286. grid: {
  287. left: "10%",
  288. right: "10%",
  289. bottom: "3%",
  290. containLabel: true
  291. },
  292. color: ["#5FA0FA", "#FFB703", "#1bb2d8", "#FD2446", "#51CEC6"],
  293. tooltip: {},
  294. xAxis: {
  295. type: "category",
  296. data: this.xAxisData1
  297. },
  298. yAxis: {
  299. type: "value"
  300. },
  301. series: [
  302. {
  303. name: "10岁以下",
  304. type: "bar",
  305. data: this.physicalAndAgeCountVoList[0]
  306. },
  307. {
  308. name: "10岁—30岁",
  309. type: "bar",
  310. data: this.physicalAndAgeCountVoList[1]
  311. },
  312. {
  313. name: "30岁—50岁",
  314. type: "bar",
  315. data: this.physicalAndAgeCountVoList[2]
  316. },
  317. {
  318. name: "50岁-60岁",
  319. type: "bar",
  320. data: this.physicalAndAgeCountVoList[3]
  321. },
  322. {
  323. name: "60岁以上",
  324. type: "bar",
  325. data: this.physicalAndAgeCountVoList[4]
  326. }
  327. ]
  328. });
  329. },
  330. // 绘制 图表
  331. drawLine() {
  332. // 基于准备好的dom,初始化echarts实例
  333. let myChart = this.$echarts.init(document.getElementById("myChart"));
  334. // 绘制图表
  335. myChart.setOption({
  336. legend: {
  337. orient: "vertical",
  338. left: "left"
  339. },
  340. title: {
  341. text: "体质结果与性别分布量",
  342. left: "center"
  343. },
  344. grid: {
  345. left: "10%",
  346. right: "10%",
  347. bottom: "3%",
  348. containLabel: true
  349. },
  350. color: ["#5FA0FA", "#FFB703", "#1bb2d8", "#FD2446", "#51CEC6"],
  351. tooltip: {},
  352. xAxis: {
  353. type: "category",
  354. data: this.xAxisData
  355. },
  356. yAxis: {
  357. type: "value"
  358. },
  359. series: [
  360. {
  361. name: "男",
  362. type: "bar",
  363. data: this.physicalAndSexCountVoList[0]
  364. },
  365. {
  366. name: "女",
  367. type: "bar",
  368. data: this.physicalAndSexCountVoList[1]
  369. }
  370. ]
  371. });
  372. },
  373. search() {
  374. this.cureCount();
  375. },
  376. clearFilter() {
  377. let date = new Date();
  378. this.form = {
  379. medName: "",
  380. year: date.getFullYear().toString(),
  381. month: "",
  382. checked: false
  383. };
  384. this.cureCount();
  385. },
  386. // 处理选择器 时间数据
  387. forMatDate(type, data) {
  388. if (!data) return "";
  389. // type : 0 year 1 month
  390. let date = new Date(data);
  391. let year = date.getFullYear();
  392. let month = date.getMonth() + 1;
  393. if (type == 0) {
  394. return year;
  395. } else if (type == 1) {
  396. return month;
  397. }
  398. },
  399. // 获取医疗机构选择器
  400. async medicalInstitution() {
  401. let params = {
  402. organizationId: this.getuserinfo.organizationid
  403. };
  404. let res = await medicalInstitution(params);
  405. if (res.ResultCode == 0) {
  406. this.medSelectList = res.Data;
  407. }
  408. },
  409. // 获取治未病分析数据
  410. async cureCount() {
  411. let params = {
  412. month: this.forMatDate(1, this.form.month),
  413. stiId: this.form.medName,
  414. type: this.form.checked ? "0" : "1",
  415. year: this.forMatDate(0, this.form.year)
  416. };
  417. let res = await cureCount(params);
  418. if (res.ResultCode == 0) {
  419. let data = res.Data[0];
  420. // 体质结果与性别
  421. let physicalAndSexCountVoList = [];
  422. let man = [];
  423. let woman = [];
  424. this.xAxisData = [];
  425. let list1 = [];
  426. data.physicalAndSexCountVoList.forEach(item => {
  427. let obj = {
  428. name: item.physicalName,
  429. man: item.manCount,
  430. woman: item.womanCount,
  431. year: ""
  432. };
  433. if (!this.form.month) {
  434. let xAxis =
  435. item.physicalName + "-" + this.forMatDate(0, this.form.year);
  436. this.xAxisData.push(xAxis);
  437. obj.year = this.forMatDate(0, this.form.year);
  438. } else {
  439. let xAxis =
  440. item.physicalName +
  441. "-" +
  442. this.forMatDate(0, this.form.year) +
  443. "-" +
  444. this.forMatDate(1, this.form.month) +
  445. "月";
  446. this.xAxisData.push(xAxis);
  447. obj.year =
  448. this.forMatDate(0, this.form.year) +
  449. "-" +
  450. this.forMatDate(1, this.form.month) +
  451. "月";
  452. }
  453. man.push(item.manCount);
  454. woman.push(item.womanCount);
  455. list1.push(obj);
  456. });
  457. this.list1 = list1;
  458. physicalAndSexCountVoList.push(man);
  459. physicalAndSexCountVoList.push(woman);
  460. this.physicalAndSexCountVoList = physicalAndSexCountVoList;
  461. // 体质结果 与年龄段
  462. let physicalAndAgeCountVoList = [];
  463. this.xAxisData1 = [];
  464. let ac1 = [];
  465. let ac2 = [];
  466. let ac3 = [];
  467. let ac4 = [];
  468. let ac5 = [];
  469. let list2 = [];
  470. data.physicalAndAgeCountVoList.forEach(item => {
  471. let obj = {
  472. ac1: item.ageCount1,
  473. ac2: item.ageCount2,
  474. ac3: item.ageCount3,
  475. ac4: item.ageCount4,
  476. ac5: item.ageCount5,
  477. year: "",
  478. name: item.physicalName
  479. };
  480. if (!this.form.month) {
  481. let xAxis =
  482. item.physicalName + "-" + this.forMatDate(0, this.form.year);
  483. this.xAxisData1.push(xAxis);
  484. obj.year = this.forMatDate(0, this.form.year);
  485. } else {
  486. let xAxis =
  487. item.physicalName +
  488. "-" +
  489. this.forMatDate(0, this.form.year) +
  490. "-" +
  491. this.forMatDate(1, this.form.month) +
  492. "月";
  493. this.xAxisData1.push(xAxis);
  494. obj.year =
  495. this.forMatDate(0, this.form.year) +
  496. "-" +
  497. this.forMatDate(1, this.form.month) +
  498. "月";
  499. }
  500. ac1.push(item.ageCount1);
  501. ac2.push(item.ageCount2);
  502. ac3.push(item.ageCount3);
  503. ac4.push(item.ageCount4);
  504. ac5.push(item.ageCount5);
  505. list2.push(obj);
  506. });
  507. physicalAndAgeCountVoList.push(ac1);
  508. physicalAndAgeCountVoList.push(ac2);
  509. physicalAndAgeCountVoList.push(ac3);
  510. physicalAndAgeCountVoList.push(ac4);
  511. physicalAndAgeCountVoList.push(ac5);
  512. this.physicalAndAgeCountVoList = physicalAndAgeCountVoList;
  513. this.list2 = list2;
  514. // 测评人数和年龄段
  515. let measurementCountVos = [];
  516. this.xAxisData2 = [];
  517. let mac1 = [];
  518. let mac2 = [];
  519. let mac3 = [];
  520. let mac4 = [];
  521. let mac5 = [];
  522. let list3 = [];
  523. data.measurementCountVos.forEach(item => {
  524. let obj = {
  525. ac1: item.ageCount1,
  526. ac2: item.ageCount2,
  527. ac3: item.ageCount3,
  528. ac4: item.ageCount4,
  529. ac5: item.ageCount5,
  530. year: ""
  531. };
  532. if (!this.form.month) {
  533. let xAxis = this.forMatDate(0, this.form.year) + "年";
  534. this.xAxisData2.push(xAxis);
  535. obj.year = this.forMatDate(0, this.form.year);
  536. } else {
  537. let xAxis =
  538. this.forMatDate(0, this.form.year) +
  539. "年" +
  540. this.forMatDate(1, this.form.month) +
  541. "月";
  542. this.xAxisData2.push(xAxis);
  543. obj.year =
  544. this.forMatDate(0, this.form.year) +
  545. "-" +
  546. this.forMatDate(1, this.form.month) +
  547. "月";
  548. }
  549. mac1.push(item.ageCount1);
  550. mac2.push(item.ageCount2);
  551. mac3.push(item.ageCount3);
  552. mac4.push(item.ageCount4);
  553. mac5.push(item.ageCount5);
  554. list3.push(obj);
  555. });
  556. measurementCountVos.push(mac1);
  557. measurementCountVos.push(mac2);
  558. measurementCountVos.push(mac3);
  559. measurementCountVos.push(mac4);
  560. measurementCountVos.push(mac5);
  561. this.measurementCountVos = measurementCountVos;
  562. this.list3 = list3;
  563. this.drawLine();
  564. this.drawLine1();
  565. this.drawLine2();
  566. }
  567. },
  568. // 治未病 导出
  569. async exportCure() {
  570. let params = {
  571. month: this.forMatDate(1, this.form.month),
  572. stiId: this.form.medName,
  573. type: this.form.checked ? "0" : "1",
  574. year: this.forMatDate(0, this.form.year)
  575. };
  576. const loading = this.$loading({
  577. lock: true,
  578. text: "正在导出,请稍后",
  579. spinner: "el-icon-loading",
  580. background: "rgba(0, 0, 0, 0.7)"
  581. });
  582. let res = await exportCure(params).catch(err => {
  583. loading.close();
  584. });
  585. if (res.ResultCode == 0) {
  586. let path = process.env.VUE_APP_UPLOAD + "file/" + res.ResultInfo;
  587. const a = document.createElement("a"); // 创建a标签
  588. a.setAttribute("download", ""); // download属性
  589. a.setAttribute("href", path); // href链接
  590. a.click(); // 自执行点击事件
  591. a.remove();
  592. this.$message({
  593. type: "success",
  594. message: "导出成功",
  595. showClose: true
  596. });
  597. loading.close();
  598. }
  599. }
  600. },
  601. computed: {
  602. ...mapGetters(["getuserinfo"])
  603. }
  604. };
  605. </script>
  606. <style lang="scss" scoped>
  607. @import "../../style/common.scss";
  608. @import "../../style/base.scss";
  609. .data-container {
  610. height: 75vh;
  611. overflow: auto;
  612. }
  613. .showData {
  614. background: #fff;
  615. border-radius: 10px;
  616. margin-top: 5px;
  617. padding: 10px;
  618. .top-change {
  619. margin-bottom: 20px;
  620. width: 100px;
  621. height: 34px;
  622. border-radius: 8px;
  623. cursor: pointer;
  624. border: 1px solid #dcdfe6;
  625. font-size: 14px;
  626. div:first-child {
  627. border-radius: 8px 0 0 8px;
  628. }
  629. div:last-child {
  630. border-radius: 0 8px 8px 0;
  631. }
  632. div {
  633. height: 34px;
  634. width: 50px;
  635. box-sizing: border-box;
  636. line-height: 34px;
  637. text-align: center;
  638. }
  639. .choosed {
  640. background: #9F643A;
  641. color: #fff;
  642. }
  643. }
  644. .bg-yellow {
  645. border-radius: 8px;
  646. background: #ffae45;
  647. color: #fff;
  648. width: 74px;
  649. height: 34px;
  650. margin-bottom: 20px;
  651. cursor: pointer;
  652. margin-left: 20px;
  653. }
  654. .showEcharts {
  655. width: 100%;
  656. margin-bottom: 20px;
  657. }
  658. .showList {
  659. width: 100%;
  660. ul {
  661. li {
  662. padding: 15px;
  663. border-bottom: 1px solid #dcdfe6;
  664. }
  665. li:hover {
  666. background: #dcdfe6;
  667. cursor: default;
  668. }
  669. .title {
  670. font-weight: bold;
  671. color: #9F643A;
  672. width: 90px;
  673. }
  674. .title1 {
  675. font-weight: bold;
  676. color: #000;
  677. margin-bottom: 20px;
  678. margin-top: 20px;
  679. font-size: 18px;
  680. }
  681. }
  682. }
  683. }
  684. </style>
  685. <style lang="scss" scoped>
  686. @media screen and (min-width: 1681px) and (max-width: 1920px) {
  687. .data-container {
  688. height: 84vh;
  689. }
  690. }
  691. @media screen and (min-width: 1601px) and (max-width: 1680px) {
  692. .data-container {
  693. height: 84vh;
  694. }
  695. }
  696. @media screen and (min-width: 1361px) and (max-width: 1600px) {
  697. .data-container {
  698. height: 77vh;
  699. }
  700. }
  701. @media screen and(min-width:1281px) and (max-width: 1360px) {
  702. .data-container {
  703. height: 77vh;
  704. }
  705. }
  706. </style>