You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

621 lines
17 KiB

2 years ago
2 years ago
2 years ago
5 months ago
2 years ago
5 months ago
3 years ago
11 months ago
5 months ago
3 years ago
2 years ago
3 years ago
11 months ago
5 months ago
3 years ago
2 years ago
11 months ago
5 months ago
11 months ago
3 years ago
3 years ago
3 years ago
5 months ago
2 years ago
5 months ago
2 years ago
5 months ago
2 years ago
5 months ago
3 years ago
2 years ago
5 months ago
2 years ago
5 months ago
2 years ago
5 months ago
2 years ago
5 months ago
11 months ago
2 years ago
5 months ago
2 years ago
5 months ago
2 years ago
5 months ago
2 years ago
2 years ago
3 years ago
2 years ago
3 years ago
5 months ago
2 years ago
2 years ago
3 years ago
5 months ago
3 years ago
3 years ago
2 years ago
3 years ago
2 years ago
3 years ago
3 years ago
2 years ago
3 years ago
2 years ago
3 years ago
2 years ago
2 years ago
5 months ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
2 years ago
3 years ago
2 years ago
3 years ago
2 years ago
3 years ago
3 years ago
2 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
2 years ago
3 years ago
3 years ago
2 years ago
3 years ago
3 years ago
2 years ago
3 years ago
2 years ago
3 years ago
2 years ago
3 years ago
2 years ago
2 years ago
2 years ago
2 years ago
3 years ago
2 years ago
2 years ago
3 years ago
2 years ago
5 months ago
2 years ago
3 years ago
2 years ago
3 years ago
2 years ago
3 years ago
2 years ago
3 years ago
2 years ago
3 years ago
2 years ago
2 years ago
3 years ago
2 years ago
5 months ago
11 months ago
3 years ago
2 years ago
5 months ago
2 years ago
5 months ago
2 years ago
2 years ago
5 months ago
2 years ago
2 years ago
5 months ago
2 years ago
2 years ago
2 years ago
3 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
3 years ago
3 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
11 months ago
2 years ago
2 years ago
2 years ago
2 years ago
11 months ago
2 years ago
3 years ago
2 years ago
3 years ago
11 months ago
2 years ago
5 months ago
2 years ago
11 months ago
2 years ago
11 months ago
3 years ago
  1. <template>
  2. <div class="box">
  3. <div>
  4. <div class="middlebox">
  5. <div class="contenttitle">
  6. 客户报表 /
  7. <span class="contenttitleBold">疾病人数统计</span>
  8. </div>
  9. </div>
  10. <div :style="'display: block;'">
  11. <div
  12. style="
  13. background-color: #fff;
  14. padding: 15px;
  15. border-radius: 8px;
  16. display: flex;
  17. flex-wrap: wrap;
  18. margin-bottom: 10px;
  19. height: 35px;
  20. margin-top: 7px;
  21. "
  22. >
  23. <div class="query">
  24. <span class="spanClass">体检单位</span>
  25. <el-input
  26. placeholder="请选择体检单位"
  27. v-model="patientRegister.query.cusOrgOCX"
  28. style="width: 240px"
  29. size="small"
  30. disabled
  31. >
  32. <el-button
  33. slot="append"
  34. icon="el-icon-search"
  35. @click="diagnosis.dialogCusOrgOCX = true"
  36. style="font-size: 20px"
  37. ></el-button>
  38. </el-input>
  39. </div>
  40. <div class="query">
  41. <span class="spanClass">诊断</span>
  42. <el-input
  43. placeholder="请选择诊断"
  44. v-model="patientRegister.query.StatisticsOCX"
  45. style="width: 200px"
  46. size="small"
  47. disabled
  48. >
  49. <el-button
  50. slot="append"
  51. icon="el-icon-search"
  52. @click="diagnosis.dialogAsbitemOCX = true"
  53. style="font-size: 20px"
  54. ></el-button>
  55. </el-input>
  56. </div>
  57. <div class="query">
  58. <span class="spanClass">状态</span>
  59. <el-select
  60. v-model="patientRegister.query.completeFlags"
  61. placeholder="请选择"
  62. clearable
  63. style="width: 150px"
  64. size="small"
  65. multiple
  66. collapse-tags
  67. >
  68. <el-option
  69. v-for="item in dict.completeFlag"
  70. :key="item.id"
  71. :label="item.displayName"
  72. :value="item.id"
  73. >
  74. </el-option>
  75. </el-select>
  76. </div>
  77. <!-- <div class="query">
  78. <span>疾病来源</span>
  79. <el-select v-model="patientRegister.query.isCharge" placeholder="请选择" clearable style="width: 80px"
  80. size="small">
  81. <el-option label="综述" value="0" />
  82. <el-option label="建议" value="1" />
  83. <el-option label="疾病列表" value="2" />
  84. </el-select>
  85. </div>
  86. <div class="query">
  87. <el-checkbox v-model="classification" true-label="Y" false-label="N"/>
  88. <span>分类统计</span>
  89. </div> -->
  90. <div class="query">
  91. <el-button @click="btnQuery" size="small" class="commonbutton"
  92. >查询</el-button
  93. >
  94. </div>
  95. <div class="query">
  96. <el-button @click="handleExport" size="small" class="commonbutton"
  97. >导出excel</el-button
  98. >
  99. </div>
  100. <div class="query">
  101. <el-button @click="onPrint" size="small" class="commonbutton"
  102. >打印</el-button
  103. >
  104. </div>
  105. <div class="query">
  106. <el-button @click="columnarChart" size="small" class="commonbutton"
  107. >柱状图</el-button
  108. >
  109. </div>
  110. <div class="query">
  111. <el-button @click="peiChart" size="small" class="commonbutton"
  112. >饼图</el-button
  113. >
  114. </div>
  115. </div>
  116. <div
  117. style="
  118. display: flex;
  119. justify-content: space-between;
  120. position: relative;
  121. "
  122. id="domTable"
  123. >
  124. <div
  125. style="
  126. width: 47.7%;
  127. background-color: #fff;
  128. padding: 15px;
  129. border-radius: 8px;
  130. "
  131. ref="imageDom"
  132. >
  133. <el-table
  134. :data="dataList"
  135. border
  136. width="45%"
  137. :height="
  138. flag
  139. ? window.pageHeight < 600
  140. ? 415
  141. : window.pageHeight - 185 - 20
  142. : ''
  143. "
  144. row-key="id"
  145. highlight-current-row
  146. ref="dataList"
  147. id="table"
  148. :row-class-name="tableRowClassName"
  149. show-summary
  150. :summary-method="getSummaries"
  151. >
  152. <el-table-column
  153. :label="`开始时间: ${summary.startDate || ''} 结束时间:${
  154. summary.endDate || ''
  155. } 男性 ${summary.maleCount} 女性 ${summary.femaleCount}`"
  156. align="left"
  157. >
  158. <el-table-column prop="diagnosisName" label="疾病" />
  159. <el-table-column prop="patientCount" label="人数" />
  160. <el-table-column prop="percentage" label="人员占比">
  161. <template slot-scope="scope">
  162. {{ scope.row.percentage + "%" }}
  163. </template>
  164. </el-table-column>
  165. </el-table-column>
  166. </el-table>
  167. </div>
  168. <div
  169. :style="
  170. 'width: 47.7%;overflow: hidden;height:' +
  171. (window.pageHeight < 600 ? 415 : window.pageHeight - 185 - 20) +
  172. 'px;background-color: #fff; padding: 15px; border-radius: 8px;'
  173. "
  174. >
  175. <div
  176. style="
  177. font-size: 20px;
  178. font-weight: 700;
  179. color: #232748;
  180. font-family: 'NotoSansSC-Bold';
  181. text-align: center;
  182. "
  183. >
  184. 疾病人数统计
  185. </div>
  186. <div
  187. :style="
  188. 'height:' +
  189. (window.pageHeight < 600 ? 387 : window.pageHeight - 185 - 48) +
  190. 'px;'
  191. "
  192. >
  193. <ChartBlock ref="chart2"></ChartBlock>
  194. </div>
  195. </div>
  196. </div>
  197. </div>
  198. </div>
  199. <!--通用选单位体检次数分组的控件-->
  200. <el-dialog
  201. title="体检单位选择"
  202. :visible.sync="diagnosis.dialogCusOrgOCX"
  203. :close-on-click-modal="false"
  204. width="880px"
  205. height="600px"
  206. >
  207. <CusOrgOCX :initDateType="'creationTime'" :useCustomerOrg="true" />
  208. </el-dialog>
  209. <!--通用选组合项目的控件-->
  210. <el-dialog
  211. title="诊断选择"
  212. :visible.sync="diagnosis.dialogAsbitemOCX"
  213. :close-on-click-modal="false"
  214. width="700px"
  215. height="600px"
  216. >
  217. <StatisticsOCX />
  218. </el-dialog>
  219. </div>
  220. </template>
  221. <script>
  222. import moment from "moment";
  223. import { mapState, mapActions } from "vuex";
  224. import { getapi, postapi, putapi, deletapi } from "@/api/api";
  225. import { exportToExcel } from "../../utlis/Export2Excel";
  226. import html2canvas from "html2canvas";
  227. import printJs from "print-js";
  228. import {
  229. dddw,
  230. objCopy,
  231. arrayReduce,
  232. arrayExistObj,
  233. tcdate,
  234. } from "@/utlis/proFunc";
  235. import CusOrgOCX from "../../components/report/CusOrgOCX.vue";
  236. import StatisticsOCX from "../../components/report/StatisticsOCX.vue";
  237. import ChartBlock from "../../components/workload/chartsBlock";
  238. export default {
  239. components: {
  240. CusOrgOCX,
  241. StatisticsOCX,
  242. ChartBlock,
  243. },
  244. data() {
  245. return {
  246. dataList: [], //列表数据
  247. // classification:'Y'
  248. seriesData: [],
  249. yAxisData: [],
  250. pieData: [],
  251. flag: true,
  252. summary: {
  253. startDate: "",
  254. endDate: "",
  255. femaleCount: "",
  256. maleCount: "",
  257. },
  258. };
  259. },
  260. created() {
  261. this.dictInit();
  262. },
  263. //挂载完成
  264. mounted() {
  265. // this.btnQuery();
  266. },
  267. computed: {
  268. ...mapState(["window", "dict", "patientRegister", "diagnosis"]),
  269. },
  270. methods: {
  271. moment,
  272. dddw,
  273. //数据初始化
  274. dictInit() {
  275. //体检中心
  276. getapi("/api/app/organization-units/organization-unit-by-is-peis").then(
  277. (res) => {
  278. if (res.code == 1) {
  279. this.dict.organization = res.data;
  280. }
  281. }
  282. );
  283. //体检单位树
  284. getapi("/api/app/customerorg/getbycodeall").then((res) => {
  285. if (res.code == 1) {
  286. this.patientRegister.customerOrgTreeAll = res.data;
  287. tcdate(this.patientRegister.customerOrgTreeAll);
  288. }
  289. });
  290. //体检类别
  291. getapi("/api/app/medical-type/in-filter").then((res) => {
  292. if (res.code == 1) {
  293. this.dict.medicalType = res.data;
  294. }
  295. });
  296. //体检类别 树结构
  297. getapi("/api/app/item-type/by-code-all").then((res) => {
  298. if (res.code == 1) {
  299. this.dict.itemTypeTree = res.data;
  300. tcdate(this.dict.itemTypeTree);
  301. }
  302. });
  303. postapi("/api/app/Diagnosis/GetSimpleList").then((res) => {
  304. if (res.code == 1) {
  305. this.dict.asbItemAll = res.data;
  306. }
  307. });
  308. },
  309. getSummaries(param) {
  310. const { columns, data } = param;
  311. const sums = [];
  312. columns.forEach((column, index) => {
  313. if (index === 0) {
  314. sums[index] = "合计";
  315. return;
  316. }
  317. if (index === 1) {
  318. let num = 0;
  319. data.forEach((item, index) => {
  320. num += item.patientCount;
  321. });
  322. sums[index] = num + " 人";
  323. }
  324. });
  325. return sums;
  326. },
  327. tableRowClassName({ row, rowIndex }) {
  328. switch (row.isCharge) {
  329. case "N":
  330. return "danger";
  331. default:
  332. return "";
  333. }
  334. },
  335. onPrint() {
  336. this.flag = false;
  337. this.$nextTick(() => {
  338. let width = this.$refs.imageDom.style.width;
  339. let cloneDom = this.$refs.imageDom.cloneNode(true);
  340. let imageDom = this.$refs.imageDom;
  341. cloneDom.style.position = "absolute";
  342. cloneDom.style.top = "0px";
  343. cloneDom.style.zIndex = "-1";
  344. cloneDom.style.width = width;
  345. console.log(cloneDom);
  346. imageDom.appendChild(cloneDom);
  347. html2canvas(cloneDom).then((canvas) => {
  348. // 转成图片,生成图片地址
  349. const url = canvas.toDataURL("image/png");
  350. printJs({
  351. printable: url,
  352. type: "image",
  353. documentTitle: "", // 标题
  354. style: `@media print { @page {size: auto; margin: 0 0 0 0; } body{margin:0 5px}canvas{page-break-after: always;page-break-inside: avoid;
  355. page-break-after: avoid;
  356. page-break-before: avoid;}}`, // 去除页眉页脚
  357. });
  358. });
  359. cloneDom.style.display = "none";
  360. this.flag = true;
  361. });
  362. },
  363. handleExport() {
  364. exportToExcel("#table", "疾病人数统计", false);
  365. },
  366. //查询
  367. btnQuery() {
  368. let body = {},
  369. customerOrgs = [],
  370. diagnosisIds = [];
  371. if (this.diagnosis.dataCusOrgOCX.length > 0) {
  372. this.diagnosis.dataCusOrgOCX.forEach((e) => {
  373. let rd = {
  374. startDate: moment(e.startDate).format("yyyy-MM-DD"),
  375. endDate: moment(e.endDate).format("yyyy-MM-DD"),
  376. dateType:
  377. e.dateType == "summaryDate"
  378. ? "3"
  379. : e.dateType == "medicalStartDate"
  380. ? "2"
  381. : "1",
  382. };
  383. if (e.customerOrgId) {
  384. rd.customerOrgId = e.customerOrgId;
  385. if (e.customerOrgId == this.dict.personOrgId) {
  386. rd.customerOrgRegisterId = null;
  387. rd.customerOrgGroupId = [];
  388. } else {
  389. rd.customerOrgRegisterId = e.customerOrgRegister.id;
  390. rd.customerOrgGroupId = e.customerOrgGroupIds;
  391. }
  392. }
  393. customerOrgs.push(rd);
  394. });
  395. }
  396. if (this.diagnosis.dataAsbitemOCX.length > 0) {
  397. this.diagnosis.dataAsbitemOCX.forEach((e) => {
  398. diagnosisIds.push(e.id);
  399. });
  400. }
  401. body.customerOrgs = customerOrgs;
  402. body.diagnosisIds = diagnosisIds;
  403. if (
  404. this.patientRegister.query.completeFlags &&
  405. Array.isArray(this.patientRegister.query.completeFlags) &&
  406. this.patientRegister.query.completeFlags.length > 0
  407. ) {
  408. body.completeFlags = this.patientRegister.query.completeFlags;
  409. } else {
  410. delete body["completeFlags"];
  411. }
  412. // if (this.patientRegister.query.isCharge) body.isCharge = this.patientRegister.query.isCharge
  413. //console.log('/api/app/peisreport/getregisterasbitemchargestatus',body)
  414. postapi("/api/customerreport/getdiseasecountstatisticsreport", body).then(
  415. (res) => {
  416. if (res.code != -1) {
  417. this.dataList = res.data.details;
  418. this.summary.startDate = res.data.startDate;
  419. this.summary.endDate = res.data.endDate;
  420. this.summary.femaleCount = res.data.femaleCount;
  421. this.summary.maleCount = res.data.maleCount;
  422. this.yAxisData = [];
  423. this.seriesData = [];
  424. this.pieData = [];
  425. let pies = {
  426. name: "",
  427. value: 0,
  428. };
  429. for (
  430. let i = 0;
  431. i < (this.dataList.length > 10 ? 10 : this.dataList.length);
  432. i++
  433. ) {
  434. let pie = JSON.parse(JSON.stringify(pies));
  435. this.yAxisData.push(this.dataList[i].diagnosisName);
  436. this.seriesData.push(this.dataList[i].patientCount);
  437. pie.name = this.dataList[i].diagnosisName;
  438. pie.value = this.dataList[i].patientCount;
  439. this.pieData.push(pie);
  440. }
  441. this.columnarChart();
  442. this.$nextTick(() => {
  443. this.$refs.dataList.doLayout();
  444. });
  445. }
  446. }
  447. );
  448. },
  449. columnarChart() {
  450. let option2 = {
  451. // title: {
  452. // text: "疾病人数统计",
  453. // left: "center",
  454. // },
  455. tooltip: {
  456. trigger: "axis",
  457. confine: true,
  458. },
  459. legend: {
  460. type: "scroll",
  461. orient: "horizontal", // 垂直
  462. right: "3%", // 左对齐
  463. top: "0%", // 位于顶部
  464. },
  465. grid: {
  466. show: false,
  467. left: "0%",
  468. right: "0%",
  469. top: "0%",
  470. bottom: "0%",
  471. containLabel: true,
  472. },
  473. xAxis: {
  474. type: "value",
  475. axisLabel: {
  476. textStyle: {
  477. fontSize: "14",
  478. },
  479. },
  480. axisLine: {
  481. show: true,
  482. },
  483. },
  484. yAxis: {
  485. type: "category",
  486. data: this.yAxisData,
  487. axisLabel: {
  488. textStyle: {
  489. fontSize: "14",
  490. },
  491. },
  492. },
  493. series: [
  494. {
  495. name: "人数",
  496. type: "bar",
  497. data: this.seriesData,
  498. },
  499. ],
  500. };
  501. this.$refs.chart2.setOption(option2);
  502. },
  503. peiChart() {
  504. let option2 = {
  505. // title: {
  506. // text: "疾病人数统计",
  507. // left: "center",
  508. // },
  509. tooltip: {
  510. trigger: "item",
  511. confine: true,
  512. },
  513. legend: {
  514. data: this.yAxisData,
  515. orient: "horizontal",
  516. right: "3%",
  517. top: "0%",
  518. },
  519. grid: {
  520. show: false,
  521. left: "0%",
  522. right: "0%",
  523. top: "0%",
  524. bottom: "0%",
  525. containLabel: true,
  526. },
  527. series: [
  528. {
  529. type: "pie",
  530. label: {
  531. show: true,
  532. formatter: "{b} : {c}人 ({d}%)", // b代表名称,c代表对应值,d代表百分比
  533. },
  534. data: this.pieData,
  535. },
  536. ],
  537. };
  538. this.$refs.chart2.setOption(option2);
  539. },
  540. },
  541. //监听事件
  542. watch: {
  543. //触发查询事件
  544. // "patientRegister.query.times"(newVal, oldVal) {
  545. // if (newVal != oldVal) {
  546. // //alert('触发查询事件')
  547. // this.query();
  548. // }
  549. // },
  550. },
  551. };
  552. </script>
  553. <style scoped>
  554. @import "../../assets/css/global_button.css";
  555. @import "../../assets/css/global_dialog.css";
  556. @import "../../assets/css/global_table.css";
  557. @import "../../assets/css/global_form.css";
  558. @import "../../assets/css/global_input.css";
  559. @import "../../assets/css/global.css";
  560. .query {
  561. margin-right: 10px;
  562. display: flex;
  563. justify-content: center;
  564. align-items: center;
  565. font-size: 14px;
  566. color: #232748;
  567. font-size: 400;
  568. font-family: "NotoSansSC-Regular";
  569. }
  570. .box {
  571. display: flex;
  572. flex-direction: column;
  573. }
  574. ::v-deep .el-input__inner {
  575. /*text-align: center;*/
  576. padding-left: 5px;
  577. padding-right: 15px;
  578. }
  579. ::v-deep .el-input__icon {
  580. width: 15px;
  581. /* 输入框下拉箭头或清除图标 默认 25 */
  582. }
  583. ::v-deep .el-input-group__append {
  584. padding: 0 5px;
  585. /* 控件默认 0 20px;*/
  586. }
  587. ::v-deep .el-icon-search:before {
  588. color: #00f;
  589. }
  590. .query:last-child {
  591. margin-right: 0;
  592. }
  593. .spanClass {
  594. font-size: 14px;
  595. padding: 0 2px 0 0;
  596. }
  597. </style>