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.
 
 
 

509 lines
14 KiB

<template>
<div>
<el-card>
<div slot="header">医生工作量统计</div>
<div :style="'display: block;width:' + (window.pageWidth - 45) + 'px;'">
<div style="display: flex; flex-wrap: wrap; height: 35px">
<div class="query">
<span>医生</span>
<el-select
v-model="username"
placeholder="请选择"
size="small"
multiple
>
<el-option
v-for="item in registrardata"
:key="item.id"
:label="item.surname"
:value="item.id"
>
</el-option>
</el-select>
</div>
<div class="query">
<span>开始日期:</span>
<el-date-picker
type="date"
placeholder="选择开始日期"
size="small"
v-model="startDate"
value-format="yyyy-MM-dd"
editable
>
</el-date-picker>
</div>
<div class="query">
<span>结束日期:</span>
<el-date-picker
type="date"
placeholder="选择结束日期"
size="small"
v-model="endDate"
value-format="yyyy-MM-dd"
editable
>
</el-date-picker>
</div>
<div class="query">
<el-button size="small" @click="onSubmit">查询</el-button>
</div>
<div class="query">
<el-button size="small" @click="handleExport">导出excel</el-button>
</div>
<div class="query">
<el-button size="small" @click="onPrint">打印</el-button>
</div>
<div class="query">
<el-button size="small" @click="columnarChart">柱状图</el-button>
</div>
<div class="query">
<el-button size="small" @click="peiChart">饼图</el-button>
</div>
</div>
<div
style="
display: flex;
justify-content: space-between;
position: relative;
margin-top: 5px;
"
id="domTable"
>
<div style="width: 49%" ref="imageDom">
<!-- <h3 align="center">登记员工作量统计</h3>
- 53-18
<h5 align="right" style="margin-bottom: 5px;">
时间:<span>{{ startDate }}</span
>至<span>{{ endDate }}</span>
</h5> -->
<el-table
border
:span-method="objectSpanMethod"
:height="
flag
? window.pageHeight < 600
? 415
: window.pageHeight - 185 - 10
: ''
"
:data="tableData"
id="table"
ref="table"
style="width: 100%"
:header-cell-class-name="headerStyle"
>
<el-table-column label="医生工作量统计">
<el-table-column :label="'时间:' + startDate + '至' + endDate">
<el-table-column
prop="doctorName"
label="医生"
></el-table-column>
<el-table-column
prop="asbitemName"
label="组合项目"
></el-table-column>
<el-table-column
prop="checkCount"
label="人数"
></el-table-column>
<el-table-column prop="avgStandardPrice" label="标准价格">
</el-table-column>
<el-table-column prop="avgChargePrice" label="实际价格">
</el-table-column>
<el-table-column prop="sumStandardPrice" label="标准金额">
</el-table-column>
<el-table-column prop="sumChargePrice" label="实际金额">
</el-table-column>
</el-table-column>
</el-table-column>
</el-table>
</div>
<div
:style="
'width: 49%;overflow: hidden;height:' +
(window.pageHeight < 600 ? 415 : window.pageHeight - 185 - 5) +
'px;'
"
>
<ChartBlock ref="chart2"></ChartBlock>
</div>
</div>
</div>
</el-card>
</div>
</template>
<script>
import { mapState, mapActions } from "vuex";
import { getapi, postapi, putapi, deletapi } from "@/api/api";
import ChartBlock from "../../components/workload/chartsBlock";
import { exportToExcel } from "../../utlis/Export2Excel";
import html2canvas from "html2canvas";
import printJs from "print-js";
export default {
components: {
ChartBlock,
},
data() {
return {
registrardata: [],
username: [],
startDate: "",
endDate: "",
tableData: [],
seriesData: [],
yAxisData: [],
flag: true,
arr1: [],
pieData: [],
};
},
created() {
this.getList();
},
mounted() {
this.getNowTime();
},
methods: {
peiChart() {
let option2 = {
title: {
text: "医生工作量统计",
left: "center",
},
tooltip: {
trigger: "item",
confine: true,
},
legend: {
data:this.yAxisData,
orient: "horizontal",
right: "3%",
top: "3%",
},
grid: {
show: false,
left: "0%",
right: "5%",
top: "8%",
bottom: "2%",
containLabel: true,
},
series: [
{
type: "pie",
label: {
show: true,
formatter: "{b} : {c}人 ({d}%)" // b代表名称,c代表对应值,d代表百分比
},
data: this.pieData
}
],
};
this.$refs.chart2.setOption(option2);
},
columnarChart() {
let option2 = {
title: {
text: "医生工作量统计",
left: "center",
},
tooltip: {
trigger: "axis",
confine: true,
},
legend: {
type: "scroll",
orient: "horizontal",
right: "3%",
top: "3%",
},
grid: {
show: false,
left: "0%",
right: "5%",
top: "8%",
bottom: "2%",
containLabel: true,
},
xAxis: {
type: "value",
axisLabel: {
textStyle: {
fontSize: "14",
},
},
axisLine: {
show: true,
},
},
yAxis: {
type: "category",
data: this.yAxisData,
axisLabel: {
textStyle: {
fontSize: "14",
},
},
},
series: [
{
name: "人数",
type: "bar",
data: this.seriesData,
},
],
};
this.$refs.chart2.setOption(option2);
},
headerStyle({ row, column, rowIndex, columnIndex }) {
if (rowIndex === 1) {
return "right-align";
}
},
summarizeRegisterCount(param) {
const { columns, data } = param;
const sums = [];
columns.forEach((column, index) => {
if (index === 0) {
sums[index] = "合计";
return;
}
const values = data.map((item) => Number(item[column.property]));
if (index === 1) {
sums[index] = values.reduce((prev, curr) => {
const value = Number(curr);
if (!isNaN(value)) {
return prev + curr;
} else {
return prev;
}
}, 0);
sums[index] = "共" + sums[index] + "人";
} else {
sums[index] = "";
}
});
return sums;
},
onPrint() {
this.flag = false;
this.$nextTick(() => {
let width = this.$refs.imageDom.style.width;
let cloneDom = this.$refs.imageDom.cloneNode(true);
let imageDom = this.$refs.imageDom;
cloneDom.style.position = "absolute";
cloneDom.style.top = "0px";
cloneDom.style.zIndex = "-1";
cloneDom.style.width = width;
console.log(cloneDom);
imageDom.appendChild(cloneDom);
html2canvas(cloneDom).then((canvas) => {
// 转成图片,生成图片地址
const url = canvas.toDataURL("image/png");
printJs({
printable: url,
type: "image",
documentTitle: "", // 标题
style: "@page{size:auto;margin: 0cm 1cm 0cm 1cm;}", // 去除页眉页脚
});
});
cloneDom.style.display = "none";
this.flag = true;
});
},
onSubmit() {
let that = this;
if (this.startDate == "") {
return this.$message({
message: "请先选择开始日期",
type: "error",
});
}
if (this.endDate == "") {
return this.$message({
message: "请先选择结束日期",
type: "error",
});
}
postapi("/api/app/internalreport/getdoctorpersonnelworkloadreport", {
userIds: that.username,
startDate: that.startDate,
endDate: that.endDate,
}).then((res) => {
if (res.code != -1) {
// that.tableData = res.data;
that.computedTableData(res.data);
}
});
},
setdates(arr) {
var obj = {},
k,
arr1 = [];
this.arr1 = [];
for (var i = 0, len = arr.length; i < len; i++) {
k = arr[i].doctorName; //需要合并的字段
if (obj[k]) obj[k]++;
else obj[k] = 1;
}
//保存结果{el-'元素',count-出现次数}
for (var o in obj) {
for (let i = 0; i < obj[o]; i++) {
if (i === 0) {
this.arr1.push(obj[o]);
} else {
this.arr1.push(0);
}
}
}
},
objectSpanMethod({ row, column, rowIndex, columnIndex }) {
if (columnIndex === 0) {
let _row = this.arr1[rowIndex];
let _col = this.arr1[rowIndex] > 0 ? 1 : 0;
return [_row, _col];
}
},
getList() {
getapi("/api/identity/users/getlist").then((res) => {
if (res.code != -1) {
this.registrardata = [...res.data.items];
}
});
},
getNowTime() {
var now = new Date();
var year = now.getFullYear(); // 得到年份
var month = now.getMonth(); // 得到月份
var date = now.getDate(); // 得到日期
month = month + 1;
month = month.toString().padStart(2, "0");
date = date.toString().padStart(2, "0");
var defaultDate = `${year}-${month}-${date}`;
this.startDate = defaultDate;
this.endDate = defaultDate;
},
ForwardRanking(data, p) {
for (var i = 0; i < data.length - 1; i++) {
for (var j = 0; j < data.length - 1 - i; j++) {
var dd = data[j][p].localeCompare(data[j + 1][p], "zh"); //1---前者往后移,-1===位置不变
if (dd > 0) {
var temp = data[j];
data[j] = data[j + 1];
data[j + 1] = temp;
}
}
}
this.tableData = data;
this.setdates(this.tableData);
},
computedTableData(tableData) {
const newData = [...tableData]; // 创建一个新的数组,避免修改原始数据
const totalRows = {
doctorName: "",
asbitemName: "合计",
checkCount: 0,
avgStandardPrice: 0,
avgChargePrice: 0,
sumStandardPrice: 0,
sumChargePrice: 0,
}; // 合计行的数据
let pies = {
name: "",
value: 0,
};
let obj = {};
for (let i = 0; i < tableData.length; i++) {
var item = tableData[i].doctorName;
obj[item] = obj[item] + 1 || 1;
}
Object.keys(obj).forEach((key) => {
let totalRow = JSON.parse(JSON.stringify(totalRows));
let pie = JSON.parse(JSON.stringify(pies));
tableData.forEach((item) => {
if (item.doctorName == key) {
totalRow.doctorName = item.doctorName;
pie.name = item.doctorName;
totalRow.checkCount += item.checkCount;
pie.value += item.checkCount;
totalRow.avgStandardPrice =
(totalRow.avgStandardPrice * 100000 +
item.avgStandardPrice * 100000) /
100000;
totalRow.avgChargePrice =
(totalRow.avgChargePrice * 100000 +
item.avgChargePrice * 100000) /
100000;
totalRow.sumStandardPrice =
(totalRow.sumStandardPrice * 100000 +
item.sumStandardPrice * 100000) /
100000;
totalRow.sumChargePrice =
(totalRow.sumChargePrice * 100000 +
item.sumChargePrice * 100000) /
100000;
}
});
newData.push(totalRow);
this.pieData.push(pie);
this.yAxisData.push(totalRow.doctorName);
this.seriesData.push(totalRow.checkCount);
});
this.ForwardRanking(newData, "doctorName");
this.columnarChart();
},
handleExport() {
exportToExcel("#table", "医生工作量统计");
},
},
computed: {
...mapState(["window", "dict", "patientRegister", "report"]),
},
updated() {
this.$nextTick(() => {
this.$refs.table.doLayout();
});
},
};
</script>
<style scoped>
@import "../../assets/css/global_button.css";
@import "../../assets/css/global_card.css";
@import "../../assets/css/global_input.css";
@import "../../assets/css/global_table.css";
@import "../../assets/css/global.css";
.query {
margin-left: 10px;
display: flex;
justify-content: center;
align-items: center;
}
:deep .right-align .cell {
text-align: right !important;
}
::v-deep .el-table__body-wrapper::-webkit-scrollbar {
width: 0px;
background: rgba(213, 215, 220, 0.3);
border: none;
}
::v-deep .el-table__body-wrapper::-webkit-scrollbar-track {
border: none;
}
::v-deep .el-table th.gutter {
display: none;
width: 0;
}
::v-deep .el-table colgroup col[name="gutter"] {
display: none;
width: 0;
}
::v-deep .el-table__body {
width: 100% !important;
}
</style>