From a2c10da81668de1f5b7d38f5962d46d795e3cc7e Mon Sep 17 00:00:00 2001
From: WXL (wul) <wl_5969728@163.com>
Date: 星期二, 07 四月 2026 14:56:06 +0800
Subject: [PATCH] 测试完成

---
 src/views/Satisfaction/sfstatistics/components/SatisfactionStatistics.vue |  634 +++++++++++++++++++++++++++++++++++++++------------------
 1 files changed, 436 insertions(+), 198 deletions(-)

diff --git a/src/views/Satisfaction/sfstatistics/components/SatisfactionStatistics.vue b/src/views/Satisfaction/sfstatistics/components/SatisfactionStatistics.vue
index a6463e6..c1d3a0a 100644
--- a/src/views/Satisfaction/sfstatistics/components/SatisfactionStatistics.vue
+++ b/src/views/Satisfaction/sfstatistics/components/SatisfactionStatistics.vue
@@ -11,19 +11,16 @@
           label-width="100px"
           class="query-form"
         >
-          <el-form-item label="鎮h�呮潵婧�" prop="patientSource">
+          <el-form-item label="缁熻绫诲瀷" prop="patientSource">
             <el-select
-              v-model="queryParams.patientSource"
-              placeholder="璇烽�夋嫨鎮h�呮潵婧�"
+              v-model="queryParams.type"
+              placeholder="璇烽�夋嫨缁熻绫诲瀷"
               clearable
-              style="width: 200px"
+              style="width: 100%"
             >
-              <el-option
-                v-for="source in patientSourceList"
-                :key="source.value"
-                :label="source.label"
-                :value="source.value"
-              />
+              <el-option label="闂嵎绫诲瀷" :value="2" />
+              <el-option label="璇煶绫诲瀷" :value="1" />
+              <el-option label="鍏ㄩ儴" :value="null" />
             </el-select>
           </el-form-item>
 
@@ -34,6 +31,7 @@
               clearable
               filterable
               style="width: 200px"
+              @change="handleDeptChange"
             >
               <el-option
                 v-for="dept in deptList"
@@ -51,6 +49,7 @@
               clearable
               filterable
               style="width: 200px"
+              @change="handleWardChange"
             >
               <el-option
                 v-for="ward in wardList"
@@ -190,7 +189,7 @@
                   min-width="300"
                 >
                   <template slot-scope="{ row }">
-                    <span>{{ row.scriptContent }}?</span>
+                    <span>{{ row.scriptContent }}</span>
                     <el-tag
                       :type="row.scriptType === 1 ? 'primary' : 'success'"
                       size="mini"
@@ -254,7 +253,7 @@
                   width="100"
                 >
                   <template slot-scope="{ row }">
-                    {{ row.totalCount - row.answerCount }}
+                    {{ row.noAnswerPerson }}
                   </template>
                 </el-table-column>
 
@@ -265,7 +264,7 @@
                   width="100"
                 >
                   <template slot-scope="{ row }">
-                    {{ formatPercent(row.answerCount / row.totalCount) }}
+                    {{ formatPercent(row.answerRate) }}
                   </template>
                 </el-table-column>
               </el-table>
@@ -273,10 +272,6 @@
               <!-- 缁煎悎寰楀垎琛� -->
               <div class="summary-row">
                 <div class="summary-content">
-                  <div class="summary-item">
-                    <span class="label">缁煎悎寰楀垎锛�</span>
-                    <span class="value">{{ totalScore.toFixed(1) }}</span>
-                  </div>
                   <div class="summary-item">
                     <span class="label">鎬荤瓟棰樹汉鏁帮細</span>
                     <span class="value">{{ totalAnswerCount }}</span>
@@ -403,32 +398,6 @@
                 </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="satisfactionLevel"
                   align="center"
@@ -539,6 +508,8 @@
 
 <script>
 import * as echarts from "echarts";
+import { statistics, satisfactionGraph } from "@/api/system/user";
+import store from "@/store";
 
 export default {
   name: "SatisfactionStatistics",
@@ -546,6 +517,7 @@
     return {
       // 鏌ヨ鍙傛暟
       queryParams: {
+        type: 2,
         patientSource: "",
         deptCode: "",
         wardCode: "",
@@ -597,9 +569,12 @@
       // 鍚勭被鍨嬬粺璁℃槑缁嗘暟鎹�
       typeDetailData: [],
 
+      // 鏌辩姸鍥炬暟鎹�
+      chartData: [],
+
       // 缁熻淇℃伅
-      totalSendCount: 12560,
-      totalReceiveCount: 10240,
+      totalSendCount: 0,
+      totalReceiveCount: 0,
       overallRecoveryRate: 0,
 
       // 绫诲瀷缁熻姹囨��
@@ -650,7 +625,54 @@
         { id: 403, name: "闂ㄨ瘖婊℃剰搴�", color: "#409EFF" },
         { id: 404, name: "甯哥敤婊℃剰搴�", color: "#FF9D4D" },
       ],
+
+      // 鏂板锛氶粯璁ゆ湇鍔$被鍨嬫暟缁�
+      defaultServiceTypes: ["6", "14", "15", "16"],
+
+      // 鏂板锛氬熀纭�妯℃澘闂ID闆嗗悎
+      scriptIds: [],
+
+      // 鏂板锛氭ā鏉縄D
+      templateId: null,
     };
+  },
+
+  computed: {
+    // 璁$畻鏌ヨ寮�濮嬫椂闂�
+    startTime() {
+      if (this.queryParams.dateRange && this.queryParams.dateRange[0]) {
+        return this.queryParams.dateRange[0];
+      }
+      // 榛樿鏈�杩�7澶�
+      const date = new Date();
+      date.setDate(date.getDate() - 7);
+      return this.formatDate(date);
+    },
+
+    // 璁$畻鏌ヨ缁撴潫鏃堕棿
+    endTime() {
+      if (this.queryParams.dateRange && this.queryParams.dateRange[1]) {
+        return this.queryParams.dateRange[1];
+      }
+      // 榛樿浠婂ぉ
+      return this.formatDate(new Date());
+    },
+
+    // 璁$畻绉戝缂栫爜鏁扮粍
+    deptCodes() {
+      if (this.queryParams.deptCode) {
+        return [this.queryParams.deptCode];
+      }
+      return this.deptList.map((dept) => dept.value);
+    },
+
+    // 璁$畻鐥呭尯缂栫爜鏁扮粍
+    hospitalDistrictCodes() {
+      if (this.queryParams.wardCode) {
+        return [this.queryParams.wardCode];
+      }
+      return this.wardList.map((ward) => ward.value);
+    },
   },
 
   mounted() {
@@ -665,6 +687,14 @@
   },
 
   methods: {
+    // 鏍煎紡鍖栨棩鏈�
+    formatDate(date) {
+      const year = date.getFullYear();
+      const month = String(date.getMonth() + 1).padStart(2, "0");
+      const day = String(date.getDate()).padStart(2, "0");
+      return `${year}-${month}-${day}`;
+    },
+
     // 鍒濆鍖栨暟鎹�
     async initData() {
       await this.getDeptList();
@@ -676,34 +706,26 @@
     // 鑾峰彇绉戝鍒楄〃
     getDeptList() {
       return new Promise((resolve) => {
-        setTimeout(() => {
-          this.deptList = [
-            { value: "dept001", label: "蹇冭绠″唴绉�" },
-            { value: "dept002", label: "绁炵粡鍐呯" },
-            { value: "dept003", label: "鏅绉�" },
-            { value: "dept004", label: "楠ㄧ" },
-            { value: "dept005", label: "濡囦骇绉�" },
-            { value: "dept006", label: "鍎跨" },
-          ];
-          resolve();
-        }, 100);
+        this.deptList = (this.$store.getters.belongDepts || []).map((dept) => {
+          return {
+            label: dept.deptName,
+            value: dept.deptCode,
+          };
+        });
+        resolve();
       });
     },
 
     // 鑾峰彇鐥呭尯鍒楄〃
     getWardList() {
       return new Promise((resolve) => {
-        setTimeout(() => {
-          this.wardList = [
-            { value: "ward001", label: "鍐呯涓�鐥呭尯" },
-            { value: "ward002", label: "鍐呯浜岀梾鍖�" },
-            { value: "ward003", label: "澶栫涓�鐥呭尯" },
-            { value: "ward004", label: "澶栫浜岀梾鍖�" },
-            { value: "ward005", label: "濡囦骇绉戠梾鍖�" },
-            { value: "ward006", label: "鍎跨鐥呭尯" },
-          ];
-          resolve();
-        }, 100);
+        this.wardList = (this.$store.getters.belongWards || []).map((ward) => {
+          return {
+            label: ward.districtName,
+            value: ward.districtCode,
+          };
+        });
+        resolve();
       });
     },
 
@@ -720,21 +742,104 @@
     async loadChartData() {
       this.loading = true;
       try {
-        // 妯℃嫙API璋冪敤
-        const chartData = await this.generateChartData();
-        this.renderChart(chartData);
+        const params = {
+          type: this.queryParams.type,
+          startTime: this.startTime,
+          endTime: this.endTime,
+          deptcodes: this.deptCodes,
+          hospitaldistrictcodes: this.hospitalDistrictCodes,
+          templateid: this.templateId,
+        };
 
-        // 璁$畻鎬讳綋鍥炴敹鐜�
-        this.overallRecoveryRate = this.totalReceiveCount / this.totalSendCount;
+        const response = await satisfactionGraph(params);
+
+        if (response.code === 200) {
+          this.processChartData(response);
+        } else {
+          this.$message.error(response.msg || "鑾峰彇鍥捐〃鏁版嵁澶辫触");
+          // 浣跨敤mock鏁版嵁
+          await this.generateMockChartData();
+        }
+      } catch (error) {
+        console.error("鑾峰彇鍥捐〃鏁版嵁鍑洪敊:", error);
+        this.$message.error("鑾峰彇鍥捐〃鏁版嵁澶辫触");
+        // 閿欒鏃朵娇鐢╩ock鏁版嵁
+        await this.generateMockChartData();
       } finally {
         this.loading = false;
       }
+    },
+
+    // 澶勭悊鍥捐〃鏁版嵁
+    processChartData(apiData) {
+      if (!apiData || !apiData.rows || Object.keys(apiData.rows).length === 0) {
+        this.chartData = [];
+        this.totalSendCount = 0;
+        this.totalReceiveCount = 0;
+        this.overallRecoveryRate = 0;
+        this.renderChart([]);
+        return;
+      }
+
+      const chartData = [];
+      let totalSend = 0;
+      let totalReceive = 0;
+      let index = 0;
+
+      // 澶勭悊鎺ュ彛杩斿洖鐨勬弧鎰忓害绫诲瀷缁熻
+      Object.entries(apiData.rows).forEach(([typeName, typeStat]) => {
+        const sendCount = typeStat.subidAll || 0;
+        const receiveCount = typeStat.fillCountAll || 0;
+        const recoveryRate = typeStat.receiveRate || 0;
+
+        chartData.push({
+          name: typeName,
+          value: recoveryRate * 100, // 杞崲涓虹櫨鍒嗘瘮
+          sendCount: sendCount,
+          receiveCount: receiveCount,
+          averageScore: typeStat.averageScore || 0,
+          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);
     },
 
     // 鍔犺浇棰樼洰鏄庣粏鏁版嵁
     async loadQuestionDetailData() {
       this.detailLoading = true;
       try {
+        const params = {
+          type: this.queryParams.type,
+          startTime: this.startTime,
+          endTime: this.endTime,
+          scriptids: this.scriptIds,
+          templateid: this.templateId,
+        };
+
+        const response = await statistics(params);
+
+        if (response.code === 200) {
+          this.processQuestionDetailData(response.rows);
+        } else {
+          this.$message.error(response.msg || "鑾峰彇棰樼洰鏄庣粏鏁版嵁澶辫触");
+          const mockData = await this.generateMockQuestionDetail();
+          this.questionDetailData = mockData.list;
+          this.detailTotal = mockData.total;
+          this.calculateSummary(mockData);
+        }
+      } catch (error) {
+        console.error("鑾峰彇棰樼洰鏄庣粏鏁版嵁鍑洪敊:", error);
+        this.$message.error("鑾峰彇棰樼洰鏄庣粏鏁版嵁澶辫触");
         const mockData = await this.generateMockQuestionDetail();
         this.questionDetailData = mockData.list;
         this.detailTotal = mockData.total;
@@ -744,18 +849,137 @@
       }
     },
 
+    // 澶勭悊鎺ュ彛杩斿洖鐨勯鐩槑缁嗘暟鎹�
+    processQuestionDetailData(apiData) {
+      if (!apiData || !apiData.patSatisfactionDetailEntities) {
+        this.questionDetailData = [];
+        this.detailTotal = 0;
+        this.totalAnswerCount = 0;
+        this.totalAnswerRate = 0;
+        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 || "",
+          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,
+        };
+      });
+
+      const startIndex =
+        (this.detailQueryParams.pageNum - 1) * this.detailQueryParams.pageSize;
+      const endIndex = startIndex + this.detailQueryParams.pageSize;
+      const paginatedData = detailData.slice(startIndex, endIndex);
+
+      this.questionDetailData = paginatedData;
+      this.detailTotal = detailData.length;
+      this.totalAnswerCount = apiData.totalPerson || 0;
+      this.totalAnswerRate = apiData.totalAnswerRate || 0;
+    },
+
     // 鍔犺浇绫诲瀷鏄庣粏鏁版嵁
     async loadTypeDetailData() {
       this.typeDetailLoading = 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.processTypeDetailData(response.data);
+        } else {
+          this.$message.error(response.msg || "鑾峰彇绫诲瀷鏄庣粏鏁版嵁澶辫触");
+          const mockData = await this.generateMockTypeDetail();
+          this.typeDetailData = mockData;
+          this.calculateTypeSummary(mockData);
+        }
+      } catch (error) {
+        console.error("鑾峰彇绫诲瀷鏄庣粏鏁版嵁鍑洪敊:", error);
+        this.$message.error("鑾峰彇绫诲瀷鏄庣粏鏁版嵁澶辫触");
         const mockData = await this.generateMockTypeDetail();
         this.typeDetailData = mockData;
-
-        // 璁$畻绫诲瀷缁熻姹囨��
         this.calculateTypeSummary(mockData);
       } finally {
         this.typeDetailLoading = false;
       }
+    },
+
+    // 澶勭悊绫诲瀷鏄庣粏鏁版嵁
+    processTypeDetailData(apiData) {
+      if (!apiData || !apiData.rows || Object.keys(apiData.rows).length === 0) {
+        this.typeDetailData = [];
+        this.calculateTypeSummary([]);
+        return;
+      }
+
+      const typeDetail = [];
+      Object.entries(apiData.rows).forEach(([typeName, typeStat], index) => {
+        const sendCount = typeStat.subidAll || 0;
+        const receiveCount = typeStat.fillCountAll || 0;
+        const recoveryRate = typeStat.receiveRate || 0;
+        const averageScore = typeStat.averageScore || 0;
+
+        typeDetail.push({
+          id: index + 1,
+          typeName: typeName,
+          isSpecial: false, // 鏍规嵁瀹為檯鎯呭喌鍒ゆ柇
+          sendCount: sendCount,
+          receiveCount: receiveCount,
+          recoveryRate: recoveryRate,
+          averageScore: averageScore,
+          maxScore: 5, // 榛樿鍊�
+          minScore: 0, // 榛樿鍊�
+          satisfactionLevel: this.getSatisfactionLevel(averageScore),
+          trend: "stable", // 榛樿绋冲畾
+        });
+      });
+
+      this.typeDetailData = typeDetail;
+      this.calculateTypeSummary(typeDetail);
+    },
+
+    // 鏍规嵁骞冲潎鍒嗚幏鍙栨弧鎰忓害绛夌骇
+    getSatisfactionLevel(score) {
+      if (score >= 4.5) return "浼樼";
+      if (score >= 4.0) return "鑹ソ";
+      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";
     },
 
     // 璁$畻缁煎悎寰楀垎
@@ -814,50 +1038,27 @@
       window.addEventListener("resize", this.handleChartResize);
     },
 
-    // 鐢熸垚鍥捐〃鏁版嵁
-    generateChartData() {
-      return new Promise((resolve) => {
-        setTimeout(() => {
-          const data = this.satisfactionTypes.map((type) => ({
-            name: type.name,
-            recoveryRate: Math.random() * 0.3 + 0.6, // 60%-90%鐨勫洖鏀剁巼
-            sendCount: Math.floor(Math.random() * 3000) + 1500, // 1500-4500
-            receiveCount: 0,
-            color: type.color,
-          }));
-
-          // 璁$畻鍥炴敹鏁伴噺
-          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
-          );
-
-          resolve({
-            data: data.map((item) => ({
-              name: item.name,
-              value: item.recoveryRate * 100, // 杞崲涓虹櫨鍒嗘瘮
-              sendCount: item.sendCount,
-              receiveCount: item.receiveCount,
-              itemStyle: { color: item.color },
-            })),
-          });
-        }, 300);
-      });
-    },
-
     // 娓叉煋鍥捐〃
     renderChart(chartData) {
       if (!this.barChart) return;
-
+ if (!chartData || chartData.length === 0) {
+    const emptyOption = {
+      title: {
+        text: "鏆傛棤鏁版嵁",
+        left: "center",
+        top: "center",
+        textStyle: {
+          color: "#999",
+          fontSize: 16,
+          fontWeight: "normal"
+        }
+      },
+      xAxis: { show: false },
+      yAxis: { show: false }
+    };
+    this.barChart.setOption(emptyOption);
+    return;
+  }
       const option = {
         title: {
           text: "",
@@ -900,7 +1101,7 @@
         },
         xAxis: {
           type: "category",
-          data: chartData.data.map((item) => item.name),
+          data: chartData.map((item) => item.name),
           axisLabel: {
             interval: 0,
             rotate: 0,
@@ -942,7 +1143,7 @@
             name: "濉姤姣斾緥",
             type: "bar",
             barWidth: 40,
-            data: chartData.data,
+            data: chartData,
             itemStyle: {
               color: (params) => {
                 return params.data.itemStyle.color;
@@ -962,19 +1163,100 @@
       this.barChart.setOption(option);
     },
 
+    // 鐢熸垚Mock鍥捐〃鏁版嵁
+    generateMockChartData() {
+      return new Promise((resolve) => {
+        setTimeout(() => {
+          const data = this.satisfactionTypes.map((type, index) => ({
+            name: type.name,
+            recoveryRate: Math.random() * 0.3 + 0.6,
+            sendCount: Math.floor(Math.random() * 3000) + 1500,
+            receiveCount: 0,
+            color: type.color,
+          }));
+
+          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,
+            itemStyle: { color: item.color },
+          }));
+
+          this.chartData = chartData;
+          this.renderChart(chartData);
+          resolve();
+        }, 300);
+      });
+    },
+
     // 鐢熸垚Mock棰樼洰璇︽儏鏁版嵁
     generateMockQuestionDetail() {
       return new Promise((resolve) => {
         setTimeout(() => {
           const questions = [
             {
-              scriptContent: "鎮ㄥ鍖绘姢浜哄憳鐨勬湇鍔℃�佸害鏄惁婊℃剰",
+              scriptContent: "鎮ㄥ鏈灏卞尰鐨勬暣浣撴弧鎰忕▼搴︼紵",
               scriptType: 1,
-              totalCount: 156,
+              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,
+                },
+                {
+                  optionText: "涓嶆弧鎰�",
+                  chosenQuantity: 6,
+                  chosenPercentage: 0.05,
+                },
+              ],
+            },
+            {
+              scriptContent: "鎮ㄥ鍖绘姢浜哄憳鐨勬湇鍔℃�佸害鏄惁婊℃剰锛�",
+              scriptType: 1,
+              answerPerson: 145,
+              noAnswerPerson: 11,
               answerCount: 145,
+              totalCount: 156,
               averageScore: 4.5,
               maxScore: 5,
               minScore: 3,
+              answerRate: 0.93,
               options: [
                 {
                   optionText: "闈炲父婊℃剰",
@@ -1003,78 +1285,6 @@
                 },
               ],
             },
-            {
-              scriptContent: "鎮ㄥ鍖荤敓鐨勮瘖鐤楁按骞冲拰鎶�鏈兘鍔涜瘎浠峰浣�",
-              scriptType: 1,
-              totalCount: 156,
-              answerCount: 142,
-              averageScore: 4.7,
-              maxScore: 5,
-              minScore: 3,
-              options: [
-                {
-                  optionText: "闈炲父涓撲笟",
-                  chosenQuantity: 95,
-                  chosenPercentage: 0.67,
-                },
-                {
-                  optionText: "姣旇緝涓撲笟",
-                  chosenQuantity: 40,
-                  chosenPercentage: 0.28,
-                },
-                {
-                  optionText: "涓�鑸�",
-                  chosenQuantity: 5,
-                  chosenPercentage: 0.04,
-                },
-                {
-                  optionText: "涓嶅涓撲笟",
-                  chosenQuantity: 2,
-                  chosenPercentage: 0.01,
-                },
-                {
-                  optionText: "闈炲父涓嶄笓涓�",
-                  chosenQuantity: 0,
-                  chosenPercentage: 0,
-                },
-              ],
-            },
-            {
-              scriptContent: "鎮ㄥ鍖婚櫌鐨勭幆澧冨拰鍗敓鐘跺喌鏄惁婊℃剰",
-              scriptType: 1,
-              totalCount: 156,
-              answerCount: 138,
-              averageScore: 4.3,
-              maxScore: 5,
-              minScore: 2,
-              options: [
-                {
-                  optionText: "闈炲父婊℃剰",
-                  chosenQuantity: 75,
-                  chosenPercentage: 0.54,
-                },
-                {
-                  optionText: "婊℃剰",
-                  chosenQuantity: 50,
-                  chosenPercentage: 0.36,
-                },
-                {
-                  optionText: "涓�鑸�",
-                  chosenQuantity: 10,
-                  chosenPercentage: 0.07,
-                },
-                {
-                  optionText: "涓嶆弧鎰�",
-                  chosenQuantity: 3,
-                  chosenPercentage: 0.02,
-                },
-                {
-                  optionText: "闈炲父涓嶆弧鎰�",
-                  chosenQuantity: 0,
-                  chosenPercentage: 0,
-                },
-              ],
-            },
           ];
 
           const startIndex =
@@ -1095,7 +1305,6 @@
     generateMockTypeDetail() {
       return new Promise((resolve) => {
         setTimeout(() => {
-          // 鍦� generateMockTypeDetail 鏂规硶涓浛鎹负锛�
           const types = [
             {
               id: 401,
@@ -1156,6 +1365,19 @@
       });
     },
 
+    // 鑾峰彇鍥捐〃棰滆壊
+    getChartColor(index) {
+      const colors = [
+        "#36B37E",
+        "#4CAF50",
+        "#409EFF",
+        "#FF9D4D",
+        "#9B8DFF",
+        "#FF6B6B",
+      ];
+      return colors[index % colors.length];
+    },
+
     // 澶勭悊鍥捐〃鍝嶅簲寮�
     handleChartResize() {
       if (this.barChart) {
@@ -1167,6 +1389,12 @@
     handleSearch() {
       this.detailQueryParams.pageNum = 1;
       this.loadData();
+      // 寮哄埗閲嶆柊娓叉煋鍥捐〃
+      setTimeout(() => {
+        if (this.chartData.length === 0) {
+          this.renderChart([]);
+        }
+      }, 100);
     },
 
     // 澶勭悊閲嶇疆
@@ -1200,21 +1428,21 @@
     // 澶勭悊绫诲瀷璇︽儏
     handleTypeDetail(row) {
       this.$message.info(`鏌ョ湅绫诲瀷璇︽儏锛�${row.typeName}`);
-      // 杩欓噷鍙互璺宠浆鍒拌鎯呴〉闈㈡垨鎵撳紑璇︽儏瀵硅瘽妗�
     },
 
     // 澶勭悊瀵煎嚭鏁版嵁
     handleExportData(row) {
       this.$message.success(`姝e湪瀵煎嚭 ${row.typeName} 鏁版嵁...`);
-      // 杩欓噷鍙互瀹炵幇瀵煎嚭閫昏緫
     },
 
     // 鏍煎紡鍖栫櫨鍒嗘瘮
     formatPercent(value) {
-      if (value === null || value === undefined) return "-";
-      const num = parseFloat(value);
-      if (isNaN(num)) return "-";
-      return `${(num * 100).toFixed(2)}%`;
+   if (value === null || value === undefined) return "-";
+  const num = parseFloat(value);
+  if (isNaN(num)) return "-";
+  // 濡傛灉鍊煎皬浜�1锛岃涓烘槸灏忔暟姣斾緥锛岄渶瑕佷箻浠�100
+  const percentValue = num < 1 ? num * 100 : num;
+  return `${percentValue.toFixed(2)}%`;
     },
 
     // 鑾峰彇鍥炴敹鐜囨牱寮忕被
@@ -1235,6 +1463,16 @@
       };
       return levelMap[level] || "info";
     },
+
+    // 澶勭悊绉戝閫夋嫨鍙樺寲
+    handleDeptChange() {
+      this.loadData();
+    },
+
+    // 澶勭悊鐥呭尯閫夋嫨鍙樺寲
+    handleWardChange() {
+      this.loadData();
+    },
   },
 };
 </script>

--
Gitblit v1.9.3