From e06cd3953ba8a6e0eee11c235bce9ced419a2800 Mon Sep 17 00:00:00 2001
From: WXL (wul) <wl_5969728@163.com>
Date: 星期三, 03 六月 2026 14:05:08 +0800
Subject: [PATCH] 测试完成
---
src/views/Satisfaction/sfstatistics/components/SatisfactionStatistics.vue | 897 ++++++++++++++++++++++++++++++++++++++++++++++++++---------
1 files changed, 761 insertions(+), 136 deletions(-)
diff --git a/src/views/Satisfaction/sfstatistics/components/SatisfactionStatistics.vue b/src/views/Satisfaction/sfstatistics/components/SatisfactionStatistics.vue
index 2d78fdf..3ff1958 100644
--- a/src/views/Satisfaction/sfstatistics/components/SatisfactionStatistics.vue
+++ b/src/views/Satisfaction/sfstatistics/components/SatisfactionStatistics.vue
@@ -24,13 +24,16 @@
</el-select>
</el-form-item>
- <el-form-item label="绉戝" prop="deptCode">
+ <!-- 绉戝閫夋嫨 -->
+ <el-form-item label="绉戝" prop="deptCodes">
<el-select
- v-model="queryParams.deptCode"
+ v-model="queryParams.deptCodes"
placeholder="璇烽�夋嫨绉戝"
clearable
filterable
- style="width: 200px"
+ multiple
+ collapse-tags
+ style="width: 300px"
@change="handleDeptChange"
>
<el-option
@@ -42,13 +45,16 @@
</el-select>
</el-form-item>
- <el-form-item label="鐥呭尯" prop="wardCode">
+ <!-- 鐥呭尯閫夋嫨 -->
+ <el-form-item label="鐥呭尯" prop="wardCodes">
<el-select
- v-model="queryParams.wardCode"
+ v-model="queryParams.wardCodes"
placeholder="璇烽�夋嫨鐥呭尯"
clearable
filterable
- style="width: 200px"
+ multiple
+ collapse-tags
+ style="width: 300px"
@change="handleWardChange"
>
<el-option
@@ -95,7 +101,7 @@
<el-card shadow="never">
<div class="chart-container">
<div class="chart-header">
- <h3 class="chart-title">婊℃剰搴︾被鍨嬪~鎶ユ瘮渚嬬粺璁�</h3>
+ <h3 class="chart-title">{{ getChartTitle() }}</h3>
<div class="statistic-info">
<div class="statistic-item">
<span class="statistic-label">鍙戦�侀棶鍗锋�婚噺锛�</span>
@@ -117,6 +123,20 @@
</div>
</div>
</div>
+
+ <!-- 鏍囩椤靛垏鎹� -->
+ <el-tabs
+ v-model="activeChartTab"
+ @tab-click="handleChartTabClick"
+ class="chart-tabs"
+ >
+ <el-tab-pane
+ label="婊℃剰搴︾被鍨�"
+ name="satisfactionType"
+ ></el-tab-pane>
+ <el-tab-pane label="缁村害缁熻" name="dimension"></el-tab-pane>
+ </el-tabs>
+
<div
id="satisfactionBarChart"
style="width: 100%; height: 400px"
@@ -304,6 +324,179 @@
</div>
</el-tab-pane>
+ <el-tab-pane label="缁村害棰樼洰鏄庣粏" name="dimensionDetail">
+ <!-- 缁村害棰樼洰鏄庣粏琛ㄦ牸 -->
+ <div class="dimension-detail-section">
+ <el-table
+ v-loading="dimensionDetailLoading"
+ :data="dimensionDetailData"
+ :border="true"
+ style="width: 100%"
+ row-class-name="dimension-row"
+ >
+ <el-table-column type="expand" width="60">
+ <template slot-scope="{ row }">
+ <div class="option-detail">
+ <el-table
+ :data="row.options"
+ :border="true"
+ style="width: 100%"
+ class="inner-table"
+ >
+ <el-table-column
+ label="閫夐」"
+ prop="optionText"
+ align="center"
+ min-width="200"
+ />
+ <el-table-column
+ label="閫夋嫨浜烘暟"
+ prop="chosenQuantity"
+ align="center"
+ min-width="120"
+ />
+ <el-table-column
+ label="閫夋嫨姣斾緥"
+ prop="chosenPercentage"
+ align="center"
+ min-width="120"
+ >
+ <template slot-scope="{ row: option }">
+ {{ formatPercent(option.chosenPercentage) }}
+ </template>
+ </el-table-column>
+ </el-table>
+ </div>
+ </template>
+ </el-table-column>
+
+ <el-table-column
+ label="搴忓彿"
+ type="index"
+ align="center"
+ width="60"
+ />
+
+ <el-table-column
+ label="棰樼洰"
+ prop="scriptContent"
+ align="center"
+ min-width="300"
+ >
+ <template slot-scope="{ row }">
+ <span>{{ row.scriptContent }}</span>
+ <el-tag
+ :type="row.scriptType === 1 ? 'primary' : 'success'"
+ size="mini"
+ style="margin-left: 5px"
+ >
+ {{ row.scriptType === 1 ? "鍗曢�夐" : "澶氶�夐" }}
+ </el-tag>
+ </template>
+ </el-table-column>
+
+ <el-table-column
+ label="缁村害"
+ prop="dimensionName"
+ align="center"
+ width="120"
+ >
+ <template slot-scope="{ row }">
+ <el-tag type="info" size="small">
+ {{ getDimensionLabel(row.dimension) }}
+ </el-tag>
+ </template>
+ </el-table-column>
+
+ <el-table-column
+ label="骞冲潎寰楀垎"
+ prop="averageScore"
+ align="center"
+ width="120"
+ >
+ <template slot-scope="{ row }">
+ <span class="score-text">{{
+ row.averageScore.toFixed(1)
+ }}</span>
+ </template>
+ </el-table-column>
+
+ <el-table-column
+ label="鏈�楂樺緱鍒�"
+ prop="maxScore"
+ align="center"
+ width="120"
+ >
+ <template slot-scope="{ row }">
+ <span class="score-text">{{
+ row.maxScore.toFixed(1)
+ }}</span>
+ </template>
+ </el-table-column>
+
+ <el-table-column
+ label="鏈�浣庡緱鍒�"
+ prop="minScore"
+ align="center"
+ width="120"
+ >
+ <template slot-scope="{ row }">
+ <span class="score-text">{{
+ row.minScore.toFixed(1)
+ }}</span>
+ </template>
+ </el-table-column>
+
+ <el-table-column
+ label="绛旈浜烘暟"
+ prop="answerPerson"
+ align="center"
+ width="100"
+ />
+
+ <el-table-column
+ label="鏈瓟棰樹汉鏁�"
+ prop="noAnswerPerson"
+ align="center"
+ width="100"
+ />
+
+ <el-table-column
+ label="绛旈鐜�"
+ prop="answerRate"
+ align="center"
+ width="100"
+ >
+ <template slot-scope="{ row }">
+ {{ formatPercent(row.answerRate) }}
+ </template>
+ </el-table-column>
+ </el-table>
+
+ <!-- 缁村害缁熻姹囨�� -->
+ <div class="dimension-summary-row">
+ <div class="dimension-summary-content">
+ <div class="dimension-summary-item">
+ <span class="label">棰樼洰鎬绘暟锛�</span>
+ <span class="value">{{ dimensionDetailData.length }}</span>
+ </div>
+ <div class="dimension-summary-item">
+ <span class="label">缁村害骞冲潎鍒嗭細</span>
+ <span class="value">{{
+ dimensionAverageScore.toFixed(1)
+ }}</span>
+ </div>
+ <div class="dimension-summary-item">
+ <span class="label">鎬讳綋绛旈鐜囷細</span>
+ <span class="value">{{
+ formatPercent(dimensionTotalAnswerRate)
+ }}</span>
+ </div>
+ </div>
+ </div>
+ </div>
+ </el-tab-pane>
+
<el-tab-pane label="鍚勭被鍨嬬粺璁℃槑缁�" name="typeDetail">
<!-- 鍚勭被鍨嬬粺璁℃槑缁嗚〃鏍� -->
<div class="type-detail-section">
@@ -414,40 +607,6 @@
</template>
</el-table-column>
- <!-- <el-table-column
- label="瓒嬪娍"
- prop="trend"
- align="center"
- width="120"
- >
- <template slot-scope="{ row }">
- <div class="trend-cell">
- <i
- v-if="row.trend === 'up'"
- class="el-icon-top trend-up"
- :style="{ color: '#67C23A' }"
- />
- <i
- v-else-if="row.trend === 'down'"
- class="el-icon-bottom trend-down"
- :style="{ color: '#F56C6C' }"
- />
- <i
- v-else
- class="el-icon-minus trend-stable"
- :style="{ color: '#909399' }"
- />
- <span class="trend-text">{{
- row.trend === "up"
- ? "涓婂崌"
- : row.trend === "down"
- ? "涓嬮檷"
- : "绋冲畾"
- }}</span>
- </div>
- </template>
- </el-table-column> -->
-
<el-table-column
label="鎿嶄綔"
align="center"
@@ -508,25 +667,31 @@
<script>
import * as echarts from "echarts";
-import { statistics, satisfactionGraph } from "@/api/system/user";
+import {
+ statistics,
+ satisfactionGraph,
+ statisticsByDimension,
+ satisfactionGraphDimension,
+} from "@/api/system/user";
import store from "@/store";
export default {
name: "SatisfactionStatistics",
+ dicts: ["dimensionality_type"],
data() {
return {
// 鏌ヨ鍙傛暟
queryParams: {
type: 2,
patientSource: "",
- deptCode: "",
- wardCode: "",
+ deptCodes: [], // 鏀逛负鏁扮粍锛屾敮鎸佸閫�
+ wardCodes: [], // 鏀逛负鏁扮粍锛屾敮鎸佸閫�
dateRange: [],
},
-
// 褰撳墠婵�娲荤殑tab
activeTab: "questionDetail",
-
+ // 褰撳墠婵�娲荤殑鍥捐〃tab
+ activeChartTab: "satisfactionType",
// 鎮h�呮潵婧愰�夐」
patientSourceList: [
{ value: "1", label: "闂ㄨ瘖" },
@@ -548,9 +713,13 @@
loading: false,
detailLoading: false,
typeDetailLoading: false,
+ dimensionDetailLoading: false,
// 棰樼洰鏄庣粏鏁版嵁
questionDetailData: [],
+
+ // 缁村害棰樼洰鏄庣粏鏁版嵁
+ dimensionDetailData: [],
// 棰樼洰鏄庣粏鏌ヨ鍙傛暟
detailQueryParams: {
@@ -561,10 +730,24 @@
// 棰樼洰鏄庣粏鎬绘暟
detailTotal: 0,
+ // 缁村害鏄庣粏鏌ヨ鍙傛暟
+ dimensionQueryParams: {
+ pageNum: 1,
+ pageSize: 10,
+ },
+
+ // 缁村害鏄庣粏鎬绘暟
+ dimensionTotal: 0,
+
// 缁煎悎寰楀垎
totalScore: 0,
totalAnswerCount: 0,
totalAnswerRate: 0,
+
+ // 缁村害缁熻姹囨��
+ dimensionTotalAnswerCount: 0,
+ dimensionTotalAnswerRate: 0,
+ dimensionAverageScore: 0,
// 鍚勭被鍨嬬粺璁℃槑缁嗘暟鎹�
typeDetailData: [],
@@ -660,16 +843,16 @@
// 璁$畻绉戝缂栫爜鏁扮粍
deptCodes() {
- if (this.queryParams.deptCode) {
- return [this.queryParams.deptCode];
+ if (this.queryParams.deptCodes && this.queryParams.deptCodes.length > 0) {
+ return this.queryParams.deptCodes;
}
return this.deptList.map((dept) => dept.value);
},
// 璁$畻鐥呭尯缂栫爜鏁扮粍
hospitalDistrictCodes() {
- if (this.queryParams.wardCode) {
- return [this.queryParams.wardCode];
+ if (this.queryParams.wardCodes && this.queryParams.wardCodes.length > 0) {
+ return this.queryParams.wardCodes;
}
return this.wardList.map((ward) => ward.value);
},
@@ -729,6 +912,13 @@
});
},
+ // 鑾峰彇鍥捐〃鏍囬
+ getChartTitle() {
+ return this.activeChartTab === "satisfactionType"
+ ? "婊℃剰搴︾被鍨嬪~鎶ユ瘮渚嬬粺璁�"
+ : "缁村害濉姤姣斾緥缁熻";
+ },
+
// 鍔犺浇鏁版嵁
async loadData() {
await Promise.all([
@@ -742,23 +932,10 @@
async loadChartData() {
this.loading = true;
try {
- const params = {
- type: this.queryParams.type,
- startTime: this.startTime,
- endTime: this.endTime,
- deptcodes: this.deptCodes,
- hospitaldistrictcodes: this.hospitalDistrictCodes,
- templateid: this.templateId,
- };
-
- const response = await satisfactionGraph(params);
-
- if (response.code === 200) {
- this.processChartData(response);
+ if (this.activeChartTab === "satisfactionType") {
+ await this.loadSatisfactionTypeChartData();
} else {
- this.$message.error(response.msg || "鑾峰彇鍥捐〃鏁版嵁澶辫触");
- // 浣跨敤mock鏁版嵁
- await this.generateMockChartData();
+ await this.loadDimensionChartData();
}
} catch (error) {
console.error("鑾峰彇鍥捐〃鏁版嵁鍑洪敊:", error);
@@ -770,14 +947,54 @@
}
},
- // 澶勭悊鍥捐〃鏁版嵁
- processChartData(apiData) {
+ // 鍔犺浇婊℃剰搴︾被鍨嬪浘琛ㄦ暟鎹�
+ async loadSatisfactionTypeChartData() {
+ const params = {
+ type: this.queryParams.type,
+ startTime: this.startTime,
+ endTime: this.endTime,
+ deptcodes: this.deptCodes, // 浣跨敤璁$畻灞炴��
+ hospitaldistrictcodes: this.hospitalDistrictCodes, // 浣跨敤璁$畻灞炴��
+ templateid: this.templateId,
+ };
+
+ const response = await satisfactionGraph(params);
+ if (response.code === 200) {
+ this.processSatisfactionTypeChartData(response);
+ } else {
+ this.$message.error(response.msg || "鑾峰彇鍥捐〃鏁版嵁澶辫触");
+ await this.generateMockChartData();
+ }
+ },
+
+ // 鍔犺浇缁村害鍥捐〃鏁版嵁
+ async loadDimensionChartData() {
+ const params = {
+ type: this.queryParams.type,
+ startTime: this.startTime,
+ endTime: this.endTime,
+ deptcodes: this.deptCodes, // 浣跨敤璁$畻灞炴��
+ hospitaldistrictcodes: this.hospitalDistrictCodes, // 浣跨敤璁$畻灞炴��
+ templateid: this.templateId,
+ };
+
+ const response = await satisfactionGraphDimension(params);
+ if (response.code === 200) {
+ this.processDimensionChartData(response);
+ } else {
+ this.$message.error(response.msg || "鑾峰彇缁村害鍥捐〃鏁版嵁澶辫触");
+ await this.generateMockDimensionChartData();
+ }
+ },
+
+ // 澶勭悊婊℃剰搴︾被鍨嬪浘琛ㄦ暟鎹�
+ processSatisfactionTypeChartData(apiData) {
if (!apiData || !apiData.rows || Object.keys(apiData.rows).length === 0) {
this.chartData = [];
this.totalSendCount = 0;
this.totalReceiveCount = 0;
this.overallRecoveryRate = 0;
- this.renderChart([]);
+ this.renderChart([], "satisfactionType");
return;
}
@@ -811,7 +1028,64 @@
this.overallRecoveryRate = totalSend > 0 ? totalReceive / totalSend : 0;
this.chartData = chartData;
- this.renderChart(chartData);
+ this.renderChart(chartData, "satisfactionType");
+ },
+
+ // 澶勭悊缁村害鍥捐〃鏁版嵁
+ processDimensionChartData(apiData) {
+ if (!apiData || !apiData.rows || Object.keys(apiData.rows).length === 0) {
+ this.chartData = [];
+ this.totalSendCount = 0;
+ this.totalReceiveCount = 0;
+ this.overallRecoveryRate = 0;
+ this.renderChart([], "dimension");
+ return;
+ }
+
+ const chartData = [];
+ let totalSend = 0;
+ let totalReceive = 0;
+ let index = 0;
+
+ // 澶勭悊鎺ュ彛杩斿洖鐨勭淮搴︾粺璁�
+ Object.entries(apiData.rows).forEach(([dimensionCode, dimensionStat]) => {
+ const sendCount = dimensionStat.subidAll || 0;
+ const receiveCount = dimensionStat.fillCountAll || 0;
+ const recoveryRate = dimensionStat.receiveRate || 0;
+
+ // 鑾峰彇缁村害鏍囩
+ const dimensionName = this.getDimensionLabel(dimensionCode);
+
+ chartData.push({
+ name: dimensionName,
+ value: (recoveryRate * 100).toFixed(2), // 杞崲涓虹櫨鍒嗘瘮
+ sendCount: sendCount,
+ receiveCount: receiveCount,
+ averageScore: dimensionStat.averageScore || 0,
+ dimension: dimensionCode,
+ itemStyle: { color: this.getChartColor(index) },
+ });
+
+ totalSend += sendCount;
+ totalReceive += receiveCount;
+ index++;
+ });
+
+ this.totalSendCount = totalSend;
+ this.totalReceiveCount = totalReceive;
+ this.overallRecoveryRate = totalSend > 0 ? totalReceive / totalSend : 0;
+ this.chartData = chartData;
+
+ this.renderChart(chartData, "dimension");
+ },
+
+ // 鑾峰彇缁村害鏍囩
+ getDimensionLabel(dimensionCode) {
+ if (!this.dict.type.dimensionality_type) return dimensionCode;
+ const dimension = this.dict.type.dimensionality_type.find(
+ (item) => item.value.toString() === dimensionCode.toString()
+ );
+ return dimension ? dimension.label : dimensionCode;
},
// 鍔犺浇棰樼洰鏄庣粏鏁版嵁
@@ -823,6 +1097,8 @@
startTime: this.startTime,
endTime: this.endTime,
scriptids: this.scriptIds,
+ deptcodes: this.deptCodes, // 浣跨敤璁$畻灞炴��
+ hospitaldistrictcodes: this.hospitalDistrictCodes, // 浣跨敤璁$畻灞炴��
templateid: this.templateId,
};
@@ -898,6 +1174,85 @@
this.totalAnswerRate = apiData.totalAnswerRate || 0;
},
+ // 鍔犺浇缁村害鏄庣粏鏁版嵁
+ async loadDimensionDetailData() {
+ this.dimensionDetailLoading = true;
+ try {
+ const params = {
+ type: this.queryParams.type,
+ startTime: this.startTime,
+ endTime: this.endTime,
+ deptcodes: this.deptCodes, // 浣跨敤璁$畻灞炴��
+ hospitaldistrictcodes: this.hospitalDistrictCodes, // 浣跨敤璁$畻灞炴��
+ templateid: this.templateId,
+ questionType: this.queryParams.type || null,
+ serviceTypes: this.defaultServiceTypes,
+ };
+
+ const response = await statisticsByDimension(params);
+
+ if (response.code === 200) {
+ this.processDimensionDetailData(response.rows);
+ } else {
+ this.$message.error(response.msg || "鑾峰彇缁村害鏄庣粏鏁版嵁澶辫触");
+ const mockData = await this.generateMockDimensionDetail();
+ this.dimensionDetailData = mockData;
+ this.calculateDimensionSummary(mockData);
+ }
+ } catch (error) {
+ console.error("鑾峰彇缁村害鏄庣粏鏁版嵁鍑洪敊:", error);
+ this.$message.error("鑾峰彇缁村害鏄庣粏鏁版嵁澶辫触");
+ const mockData = await this.generateMockDimensionDetail();
+ this.dimensionDetailData = mockData;
+ this.calculateDimensionSummary(mockData);
+ } finally {
+ this.dimensionDetailLoading = false;
+ }
+ },
+
+ // 澶勭悊缁村害鏄庣粏鏁版嵁
+ processDimensionDetailData(apiData) {
+ if (!apiData || !apiData.patSatisfactionDetailEntities) {
+ this.dimensionDetailData = [];
+ this.calculateDimensionSummary([]);
+ return;
+ }
+
+ const detailData = apiData.patSatisfactionDetailEntities.map((item) => {
+ const options = [];
+ if (item.matchedtextStats) {
+ Object.keys(item.matchedtextStats).forEach((key) => {
+ const stat = item.matchedtextStats[key];
+ options.push({
+ optionText: key,
+ chosenQuantity: stat.count || 0,
+ chosenPercentage: (stat.ratio || 0) / 100,
+ });
+ });
+ }
+
+ return {
+ scriptContent: item.scriptContent || "",
+ dimension: item.dimension || "0", // 缁村害浠g爜
+ dimensionName: this.getDimensionLabel(item.dimension || "0"), // 缁村害鍚嶇О
+ scriptType: 1,
+ answerPerson: item.answerPerson || 0,
+ noAnswerPerson: item.noAnswerPerson || 0,
+ answerCount: item.answerPerson || 0,
+ averageScore: item.averageScore || 0,
+ maxScore: item.maxScore || 0,
+ minScore: item.minScore || 0,
+ answerRate: item.answerRate || 0,
+ totalCount: (item.answerPerson || 0) + (item.noAnswerPerson || 0),
+ options: options,
+ };
+ });
+
+ this.dimensionDetailData = detailData;
+ this.dimensionTotal = detailData.length;
+ this.calculateDimensionSummary(detailData);
+ },
+
// 鍔犺浇绫诲瀷鏄庣粏鏁版嵁
async loadTypeDetailData() {
this.typeDetailLoading = true;
@@ -906,8 +1261,8 @@
type: this.queryParams.type,
startTime: this.startTime,
endTime: this.endTime,
- deptcodes: this.deptCodes,
- hospitaldistrictcodes: this.hospitalDistrictCodes,
+ deptcodes: this.deptCodes, // 浣跨敤璁$畻灞炴��
+ hospitaldistrictcodes: this.hospitalDistrictCodes, // 浣跨敤璁$畻灞炴��
templateid: this.templateId,
};
@@ -915,8 +1270,6 @@
if (response.code === 200) {
this.processTypeDetailData(response);
- console.log(11);
-
} else {
this.$message.error(response.msg || "鑾峰彇绫诲瀷鏄庣粏鏁版嵁澶辫触");
const mockData = await this.generateMockTypeDetail();
@@ -965,8 +1318,6 @@
});
this.typeDetailData = typeDetail;
- console.log(this.typeDetailData,'this.typeDetailData');
-
this.calculateTypeSummary(typeDetail);
},
@@ -977,13 +1328,6 @@
if (score >= 3.0) return "涓�鑸�";
if (score >= 2.0) return "杈冨樊";
return "鏈煡";
- },
-
- // 鑾峰彇瓒嬪娍
- getTrend(trend) {
- if (trend > 0.1) return "up";
- if (trend < -0.1) return "down";
- return "stable";
},
// 璁$畻缁煎悎寰楀垎
@@ -1002,6 +1346,32 @@
data.list.length > 0 ? totalScore / data.list.length : 0;
this.totalAnswerCount = totalAnswerCount;
this.totalAnswerRate = totalCount > 0 ? totalAnswerCount / totalCount : 0;
+ },
+
+ // 璁$畻缁村害缁熻姹囨��
+ calculateDimensionSummary(data) {
+ if (data.length === 0) {
+ this.dimensionTotalAnswerCount = 0;
+ this.dimensionTotalAnswerRate = 0;
+ this.dimensionAverageScore = 0;
+ return;
+ }
+
+ let totalScore = 0;
+ let totalAnswerCount = 0;
+ let totalCount = 0;
+
+ data.forEach((item) => {
+ totalScore += item.averageScore;
+ totalAnswerCount += item.answerPerson;
+ totalCount += item.answerPerson + item.noAnswerPerson;
+ });
+
+ this.dimensionAverageScore =
+ data.length > 0 ? totalScore / data.length : 0;
+ this.dimensionTotalAnswerCount = totalAnswerCount;
+ this.dimensionTotalAnswerRate =
+ totalCount > 0 ? totalAnswerCount / totalCount : 0;
},
// 璁$畻绫诲瀷缁熻姹囨��
@@ -1043,7 +1413,7 @@
},
// 娓叉煋鍥捐〃
- renderChart(chartData) {
+ renderChart(chartData, chartType = "satisfactionType") {
if (!this.barChart) return;
if (!chartData || chartData.length === 0) {
const emptyOption = {
@@ -1063,6 +1433,14 @@
this.barChart.setOption(emptyOption);
return;
}
+
+ const yAxisName =
+ chartType === "satisfactionType" ? "濉姤姣斾緥 (%)" : "濉姤姣斾緥 (%)";
+ const tooltipFormatter =
+ chartType === "satisfactionType"
+ ? this.getSatisfactionTypeTooltipFormatter
+ : this.getDimensionTooltipFormatter;
+
const option = {
title: {
text: "",
@@ -1073,28 +1451,7 @@
axisPointer: {
type: "shadow",
},
- formatter: (params) => {
- const data = params[0];
- return `
- <div style="margin-bottom: 5px; font-weight: bold; color: #333;">
- ${data.name}
- </div>
- <div style="margin: 2px 0;">
- <span style="display:inline-block;width:10px;height:10px;border-radius:2px;background:${
- data.color
- };margin-right:5px;"></span>
- 濉姤姣斾緥: <strong>${data.value}%</strong>
- </div>
- <div style="margin: 2px 0;">
- <span style="display:inline-block;width:10px;height:10px;border-radius:2px;background:#eee;margin-right:5px;"></span>
- 鍙戦�侀棶鍗�: <strong>${data.data.sendCount.toLocaleString()}</strong>
- </div>
- <div style="margin: 2px 0;">
- <span style="display:inline-block;width:10px;height:10px;border-radius:2px;background:#eee;margin-right:5px;"></span>
- 鍥炴敹闂嵎: <strong>${data.data.receiveCount.toLocaleString()}</strong>
- </div>
- `;
- },
+ formatter: tooltipFormatter,
},
grid: {
left: "3%",
@@ -1123,7 +1480,7 @@
},
yAxis: {
type: "value",
- name: "濉姤姣斾緥 (%)",
+ name: yAxisName,
min: 0,
max: 100,
axisLabel: {
@@ -1167,6 +1524,66 @@
this.barChart.setOption(option);
},
+ // 婊℃剰搴︾被鍨媡ooltip鏍煎紡鍖�
+ getSatisfactionTypeTooltipFormatter(params) {
+ const data = params[0];
+ return `
+ <div style="margin-bottom: 5px; font-weight: bold; color: #333;">
+ ${data.name}
+ </div>
+ <div style="margin: 2px 0;">
+ <span style="display:inline-block;width:10px;height:10px;border-radius:2px;background:${
+ data.color
+ };margin-right:5px;"></span>
+ 濉姤姣斾緥: <strong>${data.value}%</strong>
+ </div>
+ <div style="margin: 2px 0;">
+ <span style="display:inline-block;width:10px;height:10px;border-radius:2px;background:#eee;margin-right:5px;"></span>
+ 鍙戦�侀棶鍗�: <strong>${data.data.sendCount.toLocaleString()}</strong>
+ </div>
+ <div style="margin: 2px 0;">
+ <span style="display:inline-block;width:10px;height:10px;border-radius:2px;background:#eee;margin-right:5px;"></span>
+ 鍥炴敹闂嵎: <strong>${data.data.receiveCount.toLocaleString()}</strong>
+ </div>
+ <div style="margin: 2px 0;">
+ <span style="display:inline-block;width:10px;height:10px;border-radius:2px;background:#eee;margin-right:5px;"></span>
+ 骞冲潎鍒�: <strong>${data.data.averageScore.toFixed(1)}</strong>
+ </div>
+ `;
+ },
+
+ // 缁村害tooltip鏍煎紡鍖�
+ getDimensionTooltipFormatter(params) {
+ const data = params[0];
+ return `
+ <div style="margin-bottom: 5px; font-weight: bold; color: #333;">
+ ${data.name}
+ </div>
+ <div style="margin: 2px 0;">
+ <span style="display:inline-block;width:10px;height:10px;border-radius:2px;background:${
+ data.color
+ };margin-right:5px;"></span>
+ 濉姤姣斾緥: <strong>${data.value}%</strong>
+ </div>
+ <div style="margin: 2px 0;">
+ <span style="display:inline-block;width:10px;height:10px;border-radius:2px;background:#eee;margin-right:5px;"></span>
+ 鍙戦�侀棶鍗�: <strong>${data.data.sendCount.toLocaleString()}</strong>
+ </div>
+ <div style="margin: 2px 0;">
+ <span style="display:inline-block;width:10px;height:10px;border-radius:2px;background:#eee;margin-right:5px;"></span>
+ 鍥炴敹闂嵎: <strong>${data.data.receiveCount.toLocaleString()}</strong>
+ </div>
+ <div style="margin: 2px 0;">
+ <span style="display:inline-block;width:10px;height:10px;border-radius:2px;background:#eee;margin-right:5px;"></span>
+ 骞冲潎鍒�: <strong>${data.data.averageScore.toFixed(1)}</strong>
+ </div>
+ <div style="margin: 2px 0;">
+ <span style="display:inline-block;width:10px;height:10px;border-radius:2px;background:#eee;margin-right:5px;"></span>
+ 缁村害浠g爜: <strong>${data.data.dimension}</strong>
+ </div>
+ `;
+ },
+
// 鐢熸垚Mock鍥捐〃鏁版嵁
generateMockChartData() {
return new Promise((resolve) => {
@@ -1201,11 +1618,69 @@
value: item.recoveryRate * 100,
sendCount: item.sendCount,
receiveCount: item.receiveCount,
+ averageScore: 4.2 + Math.random() * 0.8,
itemStyle: { color: item.color },
}));
this.chartData = chartData;
- this.renderChart(chartData);
+ this.renderChart(chartData, "satisfactionType");
+ resolve();
+ }, 300);
+ });
+ },
+
+ // 鐢熸垚Mock缁村害鍥捐〃鏁版嵁
+ generateMockDimensionChartData() {
+ return new Promise((resolve) => {
+ setTimeout(() => {
+ // 妯℃嫙缁村害鏁版嵁
+ const dimensionLabels = this.dict.type.dimensionality_type || [
+ { value: "1", label: "缁村害1" },
+ { value: "2", label: "缁村害2" },
+ { value: "3", label: "缁村害3" },
+ { value: "4", label: "缁村害4" },
+ { value: "5", label: "缁村害5" },
+ ];
+
+ const data = dimensionLabels.map((dim, index) => ({
+ name: dim.label,
+ recoveryRate: Math.random() * 0.3 + 0.6,
+ sendCount: Math.floor(Math.random() * 2000) + 1000,
+ receiveCount: 0,
+ averageScore: 3.5 + Math.random() * 1.5,
+ dimension: dim.value,
+ color: this.getChartColor(index),
+ }));
+
+ data.forEach((item) => {
+ item.receiveCount = Math.floor(item.sendCount * item.recoveryRate);
+ });
+
+ this.totalSendCount = data.reduce(
+ (sum, item) => sum + item.sendCount,
+ 0
+ );
+ this.totalReceiveCount = data.reduce(
+ (sum, item) => sum + item.receiveCount,
+ 0
+ );
+ this.overallRecoveryRate =
+ this.totalSendCount > 0
+ ? this.totalReceiveCount / this.totalSendCount
+ : 0;
+
+ const chartData = data.map((item) => ({
+ name: item.name,
+ value: item.recoveryRate * 100,
+ sendCount: item.sendCount,
+ receiveCount: item.receiveCount,
+ averageScore: item.averageScore,
+ dimension: item.dimension,
+ itemStyle: { color: item.color },
+ }));
+
+ this.chartData = chartData;
+ this.renderChart(chartData, "dimension");
resolve();
}, 300);
});
@@ -1305,6 +1780,111 @@
});
},
+ // 鐢熸垚Mock缁村害璇︽儏鏁版嵁
+ generateMockDimensionDetail() {
+ return new Promise((resolve) => {
+ setTimeout(() => {
+ const questions = [
+ {
+ scriptContent: "鍖绘姢浜哄憳鏈嶅姟鎬佸害",
+ dimension: "1",
+ dimensionName: "鏈嶅姟鎬佸害",
+ scriptType: 1,
+ answerPerson: 120,
+ noAnswerPerson: 30,
+ answerCount: 120,
+ totalCount: 150,
+ averageScore: 4.2,
+ maxScore: 5.0,
+ minScore: 1.0,
+ answerRate: 0.8,
+ options: [
+ {
+ optionText: "闈炲父婊℃剰",
+ chosenQuantity: 60,
+ chosenPercentage: 0.5,
+ },
+ {
+ optionText: "婊℃剰",
+ chosenQuantity: 36,
+ chosenPercentage: 0.3,
+ },
+ {
+ optionText: "涓�鑸�",
+ chosenQuantity: 18,
+ chosenPercentage: 0.15,
+ },
+ ],
+ },
+ {
+ scriptContent: "鍖荤枟鎶�鏈按骞�",
+ dimension: "2",
+ dimensionName: "鎶�鏈按骞�",
+ scriptType: 1,
+ answerPerson: 145,
+ noAnswerPerson: 11,
+ answerCount: 145,
+ totalCount: 156,
+ averageScore: 4.5,
+ maxScore: 5,
+ minScore: 3,
+ answerRate: 0.93,
+ options: [
+ {
+ optionText: "闈炲父婊℃剰",
+ chosenQuantity: 89,
+ chosenPercentage: 0.61,
+ },
+ {
+ optionText: "婊℃剰",
+ chosenQuantity: 45,
+ chosenPercentage: 0.31,
+ },
+ {
+ optionText: "涓�鑸�",
+ chosenQuantity: 8,
+ chosenPercentage: 0.06,
+ },
+ ],
+ },
+ {
+ scriptContent: "灏卞尰鐜璁炬柦",
+ dimension: "3",
+ dimensionName: "鐜璁炬柦",
+ scriptType: 1,
+ answerPerson: 98,
+ noAnswerPerson: 22,
+ answerCount: 98,
+ totalCount: 120,
+ averageScore: 4.0,
+ maxScore: 5,
+ minScore: 2,
+ answerRate: 0.82,
+ options: [
+ {
+ optionText: "闈炲父婊℃剰",
+ chosenQuantity: 45,
+ chosenPercentage: 0.46,
+ },
+ {
+ optionText: "婊℃剰",
+ chosenQuantity: 40,
+ chosenPercentage: 0.41,
+ },
+ {
+ optionText: "涓�鑸�",
+ chosenQuantity: 10,
+ chosenPercentage: 0.1,
+ },
+ ],
+ },
+ ];
+
+ resolve(questions);
+ }, 300);
+ });
+ },
+
// 鐢熸垚Mock绫诲瀷鏄庣粏鏁版嵁
generateMockTypeDetail() {
return new Promise((resolve) => {
@@ -1378,6 +1958,12 @@
"#FF9D4D",
"#9B8DFF",
"#FF6B6B",
+ "#66C2A5",
+ "#FC8D62",
+ "#8DA0CB",
+ "#E78AC3",
+ "#A6D854",
+ "#FFD92F",
];
return colors[index % colors.length];
},
@@ -1389,14 +1975,21 @@
}
},
+ // 澶勭悊鍥捐〃Tab鍒囨崲
+ handleChartTabClick(tab) {
+ this.activeChartTab = tab.name;
+ this.loadChartData();
+ },
+
// 澶勭悊鏌ヨ
handleSearch() {
this.detailQueryParams.pageNum = 1;
+ this.dimensionQueryParams.pageNum = 1;
this.loadData();
// 寮哄埗閲嶆柊娓叉煋鍥捐〃
setTimeout(() => {
if (this.chartData.length === 0) {
- this.renderChart([]);
+ this.renderChart([], this.activeChartTab);
}
}, 100);
},
@@ -1405,14 +1998,30 @@
handleReset() {
this.$refs.queryForm.resetFields();
this.queryParams.dateRange = [];
+ this.queryParams.deptCodes = []; // 閲嶇疆涓烘暟缁�
+ this.queryParams.wardCodes = []; // 閲嶇疆涓烘暟缁�
this.detailQueryParams.pageNum = 1;
+ this.dimensionQueryParams.pageNum = 1;
this.loadData();
},
// 澶勭悊Tab鍒囨崲
handleTabClick(tab) {
- if (tab.name === "typeDetail" && this.typeDetailData.length === 0) {
+ if (
+ tab.name === "dimensionDetail" &&
+ this.dimensionDetailData.length === 0
+ ) {
+ this.loadDimensionDetailData();
+ } else if (
+ tab.name === "typeDetail" &&
+ this.typeDetailData.length === 0
+ ) {
this.loadTypeDetailData();
+ } else if (
+ tab.name === "questionDetail" &&
+ this.questionDetailData.length === 0
+ ) {
+ this.loadQuestionDetailData();
}
},
@@ -1427,6 +2036,19 @@
handleDetailPageChange(page) {
this.detailQueryParams.pageNum = page;
this.loadQuestionDetailData();
+ },
+
+ // 澶勭悊缁村害鏄庣粏鍒嗛〉澶у皬鍙樺寲
+ handleDimensionSizeChange(size) {
+ this.dimensionQueryParams.pageSize = size;
+ this.dimensionQueryParams.pageNum = 1;
+ this.loadDimensionDetailData();
+ },
+
+ // 澶勭悊缁村害鏄庣粏椤电爜鍙樺寲
+ handleDimensionPageChange(page) {
+ this.dimensionQueryParams.pageNum = page;
+ this.loadDimensionDetailData();
},
// 澶勭悊绫诲瀷璇︽儏
@@ -1549,6 +2171,14 @@
}
}
}
+
+ .chart-tabs {
+ margin-bottom: 20px;
+
+ ::v-deep .el-tabs__header {
+ margin-bottom: 0;
+ }
+ }
}
.tab-section {
@@ -1561,7 +2191,8 @@
}
}
- .detail-table-section {
+ .detail-table-section,
+ .dimension-detail-section {
.option-detail {
padding: 15px;
background: #f8f9fa;
@@ -1581,7 +2212,8 @@
padding: 12px 0;
}
- .question-row {
+ .question-row,
+ .dimension-row {
td {
background-color: #fff;
}
@@ -1600,19 +2232,22 @@
font-size: 16px;
}
- .summary-row {
+ .summary-row,
+ .dimension-summary-row {
margin-top: 20px;
padding: 20px;
background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%);
border-radius: 8px;
border: 1px solid #dee2e6;
- .summary-content {
+ .summary-content,
+ .dimension-summary-content {
display: flex;
justify-content: space-around;
align-items: center;
- .summary-item {
+ .summary-item,
+ .dimension-summary-item {
text-align: center;
.label {
@@ -1684,24 +2319,6 @@
color: #409eff;
font-size: 15px;
}
-
- .trend-cell {
- display: flex;
- align-items: center;
- justify-content: center;
- gap: 5px;
-
- .trend-up,
- .trend-down,
- .trend-stable {
- font-size: 16px;
- }
-
- .trend-text {
- font-size: 13px;
- color: #666;
- }
- }
}
.type-summary-row {
@@ -1763,7 +2380,13 @@
}
}
}
-
+/* 纭繚澶氶�変笅鎷夋鏍峰紡姝g‘ */
+::v-deep .el-select__tags {
+ max-width: 200px;
+ .el-tag {
+ margin: 2px 0 2px 6px;
+ }
+}
@media (max-width: 768px) {
.satisfaction-statistics {
padding: 10px;
@@ -1795,8 +2418,10 @@
}
}
- .detail-table-section {
- .summary-content {
+ .detail-table-section,
+ .dimension-detail-section {
+ .summary-content,
+ .dimension-summary-content {
flex-direction: column;
gap: 15px;
}
--
Gitblit v1.9.3