|
|
@@ -140,8 +140,8 @@
|
|
|
:disabled="loading2"
|
|
|
@change="onTop3DeptTabChange"
|
|
|
>
|
|
|
- <el-radio-button label="top">一级部门</el-radio-button>
|
|
|
- <el-radio-button label="all">子孙部门明细</el-radio-button>
|
|
|
+ <el-radio-button label="top">部门明细</el-radio-button>
|
|
|
+ <el-radio-button label="all">小组明细</el-radio-button>
|
|
|
</el-radio-group>
|
|
|
<el-radio-group
|
|
|
v-model="top3PieMode"
|
|
|
@@ -170,11 +170,22 @@
|
|
|
<div class="chart-card">
|
|
|
<div class="chart-title">
|
|
|
<span>各部门总工时和人均工时表</span>
|
|
|
+ <div class="chart-title-actions">
|
|
|
+ <el-radio-group
|
|
|
+ v-model="deptHoursTabMode"
|
|
|
+ size="mini"
|
|
|
+ :disabled="loading3"
|
|
|
+ @change="onDeptHoursTabChange"
|
|
|
+ >
|
|
|
+ <el-radio-button label="top">部门明细</el-radio-button>
|
|
|
+ <el-radio-button label="all">小组明细</el-radio-button>
|
|
|
+ </el-radio-group>
|
|
|
+ </div>
|
|
|
</div>
|
|
|
<div v-if="loading3" class="chart-loading">
|
|
|
<i class="el-icon-loading"></i> 加载中...
|
|
|
</div>
|
|
|
- <div v-else-if="deptHoursData.length === 0" class="chart-empty">
|
|
|
+ <div v-else-if="!hasDeptHoursData()" class="chart-empty">
|
|
|
暂无数据
|
|
|
</div>
|
|
|
<div v-else ref="chart3" class="chart-body"></div>
|
|
|
@@ -403,6 +414,8 @@ export default {
|
|
|
top3PieMode: "working",
|
|
|
top3DeptTabMode: "top",
|
|
|
top3DeptDataAll: [],
|
|
|
+ deptHoursTabMode: "top",
|
|
|
+ deptHoursDataAll: [],
|
|
|
userProjectTop10Data: [],
|
|
|
loading9: false,
|
|
|
};
|
|
|
@@ -785,37 +798,66 @@ export default {
|
|
|
});
|
|
|
},
|
|
|
|
|
|
+ onDeptHoursTabChange() {
|
|
|
+ this.$nextTick(() => this.renderChart3());
|
|
|
+ },
|
|
|
+
|
|
|
+ hasDeptHoursData() {
|
|
|
+ const sourceData = this.deptHoursTabMode === "top" ? this.deptHoursData : this.deptHoursDataAll;
|
|
|
+ return (sourceData || []).some((dept) => Number(dept.workingTime || 0) > 0);
|
|
|
+ },
|
|
|
+
|
|
|
loadDeptHours() {
|
|
|
const requestMonth = this.selectedMonth;
|
|
|
this.loading3 = true;
|
|
|
this.deptHoursData = [];
|
|
|
- this.http.post(
|
|
|
- "/report/getProjectReportGroupByDept",
|
|
|
- { ymonth: requestMonth },
|
|
|
- (res) => {
|
|
|
- if (!this.isCurrentMonthRequest(requestMonth)) return;
|
|
|
- this.loading3 = false;
|
|
|
- if (res.code === "ok") {
|
|
|
- const data = res.data || [];
|
|
|
- const processData = (translated) => {
|
|
|
- this.deptHoursData = translated;
|
|
|
- this.$nextTick(() => this.renderChart3());
|
|
|
- };
|
|
|
- if (this.needWxOpenData && data.length > 0) {
|
|
|
- this.translateDeptNames(data, "departmentName", processData);
|
|
|
+ this.deptHoursDataAll = [];
|
|
|
+
|
|
|
+ const loadMode = (deptMode, storeKey, callback) => {
|
|
|
+ this.http.post(
|
|
|
+ "/report/getProjectReportGroupByDept",
|
|
|
+ { ymonth: requestMonth, deptMode },
|
|
|
+ (res) => {
|
|
|
+ if (!this.isCurrentMonthRequest(requestMonth)) return;
|
|
|
+ if (res.code === "ok") {
|
|
|
+ const data = res.data || [];
|
|
|
+ const processData = (translated) => {
|
|
|
+ this[storeKey] = translated;
|
|
|
+ if (callback) callback();
|
|
|
+ };
|
|
|
+ if (this.needWxOpenData && data.length > 0) {
|
|
|
+ this.translateDeptNames(data, "departmentName", processData);
|
|
|
+ } else {
|
|
|
+ processData(data);
|
|
|
+ }
|
|
|
} else {
|
|
|
- processData(data);
|
|
|
+ this.$message({ message: res.msg, type: "error" });
|
|
|
}
|
|
|
- } else {
|
|
|
- this.$message({ message: res.msg, type: "error" });
|
|
|
- }
|
|
|
- },
|
|
|
- (err) => {
|
|
|
- if (!this.isCurrentMonthRequest(requestMonth)) return;
|
|
|
+ },
|
|
|
+ (err) => {
|
|
|
+ if (!this.isCurrentMonthRequest(requestMonth)) return;
|
|
|
+ this.$message({ message: err, type: "error" });
|
|
|
+ },
|
|
|
+ );
|
|
|
+ };
|
|
|
+
|
|
|
+ let topDone = false;
|
|
|
+ let allDone = false;
|
|
|
+ const tryFinish = () => {
|
|
|
+ if (topDone && allDone) {
|
|
|
this.loading3 = false;
|
|
|
- this.$message({ message: err, type: "error" });
|
|
|
- },
|
|
|
- );
|
|
|
+ this.$nextTick(() => this.renderChart3());
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ loadMode("top", "deptHoursData", () => {
|
|
|
+ topDone = true;
|
|
|
+ tryFinish();
|
|
|
+ });
|
|
|
+ loadMode(null, "deptHoursDataAll", () => {
|
|
|
+ allDone = true;
|
|
|
+ tryFinish();
|
|
|
+ });
|
|
|
},
|
|
|
|
|
|
loadDeptProjectCount() {
|
|
|
@@ -1453,18 +1495,26 @@ export default {
|
|
|
const el = this.$refs.chart3;
|
|
|
const parentEl = el.parentElement;
|
|
|
const width = parentEl ? parentEl.clientWidth - 32 : el.clientWidth;
|
|
|
- this.chart3 = echarts.init(el, null, { width, height: 300 });
|
|
|
|
|
|
- const depts = this.deptHoursData.map((item) => item.departmentName);
|
|
|
- const totalHours = this.deptHoursData.map((item) =>
|
|
|
+ const sourceData = this.deptHoursTabMode === "top" ? this.deptHoursData : this.deptHoursDataAll;
|
|
|
+ const chartData = (sourceData || []).filter((item) => Number(item.workingTime || 0) > 0);
|
|
|
+
|
|
|
+ const rowHeight = 28;
|
|
|
+ const minHeight = 300;
|
|
|
+ const height = Math.max(minHeight, chartData.length * rowHeight + 100);
|
|
|
+ el.style.height = height + "px";
|
|
|
+ this.chart3 = echarts.init(el, null, { width, height });
|
|
|
+
|
|
|
+ const depts = chartData.map((item) => item.departmentName);
|
|
|
+ const totalHours = chartData.map((item) =>
|
|
|
Number((item.workingTime || 0).toFixed(2)),
|
|
|
);
|
|
|
- const avgHours = this.deptHoursData.map((item) =>
|
|
|
+ const avgHours = chartData.map((item) =>
|
|
|
Number((item.avgWorkingTime || 0).toFixed(2)),
|
|
|
);
|
|
|
|
|
|
const deptOpenIdMap3 = {};
|
|
|
- this.deptHoursData.forEach((item) => {
|
|
|
+ chartData.forEach((item) => {
|
|
|
deptOpenIdMap3[item.departmentName] = item._deptOpenId || null;
|
|
|
});
|
|
|
|
|
|
@@ -1477,7 +1527,7 @@ export default {
|
|
|
deptOpenIdMap: deptOpenIdMap3,
|
|
|
});
|
|
|
this.chart3.setOption(option);
|
|
|
- this.chart3.resize({ width, height: 300 });
|
|
|
+ this.chart3.resize({ width, height });
|
|
|
},
|
|
|
|
|
|
renderChart4() {
|