From 51461f369f0b0ad1da96346afee5637302f1525b Mon Sep 17 00:00:00 2001
From: WXL (wul) <wl_5969728@163.com>
Date: 星期二, 18 八月 2026 16:38:47 +0800
Subject: [PATCH] 提交

---
 src/views/sfstatistics/percentage/components/FirstFollowUp.vue | 1170 ++++++++++++++++++++++++++++++++++++++++++++++------------
 1 files changed, 922 insertions(+), 248 deletions(-)

diff --git a/src/views/sfstatistics/percentage/components/FirstFollowUp.vue b/src/views/sfstatistics/percentage/components/FirstFollowUp.vue
index 546bc0c..67d329f 100644
--- a/src/views/sfstatistics/percentage/components/FirstFollowUp.vue
+++ b/src/views/sfstatistics/percentage/components/FirstFollowUp.vue
@@ -25,6 +25,26 @@
               show-summary
               :summary-method="getInnerSummaries"
             >
+              <el-table-column label="" align="center" width="96" fixed="left">
+                <template slot="header">
+                  <div
+                    style="
+                      display: flex;
+                      justify-content: space-between;
+                      align-items: center;
+                    "
+                  >
+                    <el-button
+                      type="primary"
+                      size="mini"
+                      icon="el-icon-download"
+                      @click="exportDoctorTable(props.row)"
+                    >
+                      瀵煎嚭
+                    </el-button>
+                  </div>
+                </template>
+              </el-table-column>
               <el-table-column label="鍖荤敓濮撳悕" prop="drname" align="center" />
               <el-table-column
                 label="绉戝"
@@ -32,31 +52,82 @@
                 prop="deptname"
                 align="center"
               />
-              <el-table-column
-                label="鍑洪櫌浜烘"
-                prop="dischargeCount"
-                align="center"
-              />
+
               <el-table-column
                 label="鍑洪櫌浜烘"
                 align="center"
                 key="dischargeCount"
                 prop="dischargeCount"
-              />
+              >
+                <template slot-scope="scope">
+                  <el-button
+                    size="medium"
+                    type="text"
+                    @click="
+                      handleViewDetails(
+                        scope.row,
+                        'dischargeCountInfo',
+                        '鍑洪櫌鎮h�呭垪琛�',
+                        '1'
+                      )
+                    "
+                  >
+                    <span class="button-zx">{{
+                      scope.row.dischargeCount
+                    }}</span>
+                  </el-button>
+                </template>
+              </el-table-column>
               <el-table-column
                 label="鏃犻渶闅忚浜烘"
                 align="center"
                 width="100"
                 key="nonFollowUp"
                 prop="nonFollowUp"
-              />
+              >
+                <template slot-scope="scope">
+                  <el-button
+                    size="medium"
+                    type="text"
+                    @click="
+                      handleViewDetails(
+                        scope.row,
+                        'nonFollowUpInfo',
+                        '鏃犻渶闅忚鍒楄〃',
+                        '1'
+                      )
+                    "
+                  >
+                    <span class="button-zx">{{ scope.row.nonFollowUp }}</span>
+                  </el-button>
+                </template>
+              </el-table-column>
               <el-table-column
                 label="搴旈殢璁夸汉娆�"
                 align="center"
                 width="100"
                 key="followUpNeeded"
                 prop="followUpNeeded"
-              />
+              >
+                <template slot-scope="scope">
+                  <el-button
+                    size="medium"
+                    type="text"
+                    @click="
+                      handleViewDetails(
+                        scope.row,
+                        'followUpNeededInfo',
+                        '搴旈殢璁垮垪琛�',
+                        '1'
+                      )
+                    "
+                  >
+                    <span class="button-zx">{{
+                      scope.row.followUpNeeded
+                    }}</span>
+                  </el-button>
+                </template>
+              </el-table-column>
 
               <el-table-column align="center" label="棣栨鍑洪櫌闅忚">
                 <el-table-column
@@ -64,31 +135,127 @@
                   align="center"
                   key="needFollowUp"
                   prop="needFollowUp"
-                />
+                >
+                  <template slot-scope="scope">
+                    <el-button
+                      size="medium"
+                      type="text"
+                      @click="
+                        handleViewDetails(
+                          scope.row,
+                          'needFollowUpInfo',
+                          '闇�闅忚鍒楄〃',
+                          '1'
+                        )
+                      "
+                    >
+                      <span class="button-zx">{{
+                        scope.row.needFollowUp
+                      }}</span>
+                    </el-button>
+                  </template>
+                </el-table-column>
                 <el-table-column
                   label="寰呴殢璁�"
                   align="center"
                   key="pendingFollowUp"
                   prop="pendingFollowUp"
-                />
+                >
+                  <template slot-scope="scope">
+                    <el-button
+                      size="medium"
+                      type="text"
+                      @click="
+                        handleViewDetails(
+                          scope.row,
+                          'pendingFollowUpInfo',
+                          '寰呴殢璁垮垪琛�',
+                          '1'
+                        )
+                      "
+                    >
+                      <span class="button-zx">{{
+                        scope.row.pendingFollowUp
+                      }}</span>
+                    </el-button>
+                  </template>
+                </el-table-column>
                 <el-table-column
                   label="闅忚鎴愬姛"
                   align="center"
                   key="followUpSuccess"
                   prop="followUpSuccess"
-                />
+                >
+                  <template slot-scope="scope">
+                    <el-button
+                      size="medium"
+                      type="text"
+                      @click="
+                        handleViewDetails(
+                          scope.row,
+                          'followUpSuccessInfo',
+                          '闅忚鎴愬姛鍒楄〃',
+                          '1'
+                        )
+                      "
+                    >
+                      <span class="button-zx">{{
+                        scope.row.followUpSuccess
+                      }}</span>
+                    </el-button>
+                  </template>
+                </el-table-column>
                 <el-table-column
                   label="闅忚澶辫触"
                   align="center"
                   key="followUpFail"
                   prop="followUpFail"
-                />
+                >
+                  <template slot-scope="scope">
+                    <el-button
+                      size="medium"
+                      type="text"
+                      @click="
+                        handleViewDetails(
+                          scope.row,
+                          'followUpFailInfo',
+                          '闅忚澶辫触鍒楄〃',
+                          '1'
+                        )
+                      "
+                    >
+                      <span class="button-zx">{{
+                        scope.row.followUpFail
+                      }}</span>
+                    </el-button>
+                  </template>
+                </el-table-column>
+                <el-table-column
+                  v-if="orgname != '鏅畞鐣叉棌鑷不鍘夸汉姘戝尰闄�'"
+                  label="鎴愬姛鐜�"
+                  align="center"
+                  width="120"
+                  key="successRate"
+                  prop="successRate"
+                  :render-header="Tooltipcgl"
+                >
+                  <template slot-scope="scope">
+                    <span class="success-rate">{{
+                      calculateSuccessRate(
+                        scope.row.followUpSuccess,
+                        scope.row.needFollowUp,
+                        scope.row.pendingFollowUp
+                      )
+                    }}</span>
+                  </template>
+                </el-table-column>
                 <el-table-column
                   label="闅忚鐜�"
                   align="center"
                   width="120"
                   key="followUpRate"
                   prop="followUpRate"
+                  :render-header="Tooltipsfl"
                 />
                 <el-table-column
                   v-if="orgname != '涓芥按甯備腑鍖婚櫌'"
@@ -97,6 +264,7 @@
                   width="120"
                   key="rate"
                   prop="rate"
+                  :render-header="Tooltipjsl"
                 >
                   <template slot-scope="scope">
                     <el-button
@@ -115,19 +283,93 @@
                   align="center"
                   key="manual"
                   prop="manual"
-                />
+                >
+                  <template slot-scope="scope">
+                    <el-button
+                      size="medium"
+                      type="text"
+                      @click="
+                        handleViewDetails(
+                          scope.row,
+                          'manualInfo',
+                          '浜哄伐闅忚鍒楄〃',
+                          '1'
+                        )
+                      "
+                    >
+                      <span class="button-zx">{{ scope.row.manual }}</span>
+                    </el-button>
+                  </template>
+                </el-table-column>
+                <el-table-column
+                  label="璇煶"
+                  align="center"
+                  key="voice"
+                  prop="voice"
+                >
+                  <template slot-scope="scope">
+                    <el-button
+                      size="medium"
+                      type="text"
+                      @click="
+                        handleViewDetails(
+                          scope.row,
+                          'voiceInfo',
+                          '璇煶闅忚鍒楄〃',
+                          '1'
+                        )
+                      "
+                    >
+                      <span class="button-zx">{{ scope.row.voice }}</span>
+                    </el-button>
+                  </template>
+                </el-table-column>
                 <el-table-column
                   label="鐭俊"
                   align="center"
                   key="sms"
                   prop="sms"
-                />
+                >
+                  <template slot-scope="scope">
+                    <el-button
+                      size="medium"
+                      type="text"
+                      @click="
+                        handleViewDetails(
+                          scope.row,
+                          'smsInfo',
+                          '鐭俊闅忚鍒楄〃',
+                          '1'
+                        )
+                      "
+                    >
+                      <span class="button-zx">{{ scope.row.sms }}</span>
+                    </el-button>
+                  </template>
+                </el-table-column>
                 <el-table-column
                   label="寰俊"
                   align="center"
                   key="weChat"
                   prop="weChat"
-                />
+                >
+                  <template slot-scope="scope">
+                    <el-button
+                      size="medium"
+                      type="text"
+                      @click="
+                        handleViewDetails(
+                          scope.row,
+                          'weChatInfo',
+                          '寰俊闅忚鍒楄〃',
+                          '1'
+                        )
+                      "
+                    >
+                      <span class="button-zx">{{ scope.row.weChat }}</span>
+                    </el-button>
+                  </template>
+                </el-table-column>
               </el-table-column>
             </el-table>
           </template>
@@ -135,6 +377,7 @@
 
         <!-- 琛ㄦ牸鍒楀畾涔� -->
         <el-table-column
+          v-if="queryParams.statisticaltype == 1"
           label="鍑洪櫌鐥呭尯"
           align="center"
           sortable
@@ -145,6 +388,7 @@
           :sort-method="sortChineseNumber"
         />
         <el-table-column
+          v-if="queryParams.statisticaltype == 2"
           label="绉戝"
           align="center"
           key="deptname"
@@ -156,21 +400,61 @@
           align="center"
           key="dischargeCount"
           prop="dischargeCount"
-        />
+        >
+          <template slot-scope="scope">
+            <el-button
+              size="medium"
+              type="text"
+              @click="
+                handleViewDetails(
+                  scope.row,
+                  'dischargeCountInfo',
+                  '鍑洪櫌鎮h�呭垪琛�'
+                )
+              "
+            >
+              <span class="button-zx">{{ scope.row.dischargeCount }}</span>
+            </el-button>
+          </template>
+        </el-table-column>
         <el-table-column
           label="鏃犻渶闅忚浜烘"
           align="center"
           width="100"
           key="nonFollowUp"
           prop="nonFollowUp"
-        />
+        >
+          <template slot-scope="scope">
+            <el-button
+              size="medium"
+              type="text"
+              @click="
+                handleViewDetails(scope.row, 'nonFollowUpInfo', '鏃犻渶闅忚鍒楄〃')
+              "
+            >
+              <span class="button-zx">{{ scope.row.nonFollowUp }}</span>
+            </el-button>
+          </template>
+        </el-table-column>
         <el-table-column
           label="搴旈殢璁夸汉娆�"
           align="center"
           width="100"
           key="followUpNeeded"
           prop="followUpNeeded"
-        />
+        >
+          <template slot-scope="scope">
+            <el-button
+              size="medium"
+              type="text"
+              @click="
+                handleViewDetails(scope.row, 'followUpNeededInfo', '搴旈殢璁垮垪琛�')
+              "
+            >
+              <span class="button-zx">{{ scope.row.followUpNeeded }}</span>
+            </el-button>
+          </template>
+        </el-table-column>
 
         <el-table-column align="center" label="棣栨鍑洪櫌闅忚">
           <el-table-column
@@ -258,11 +542,31 @@
             </template>
           </el-table-column>
           <el-table-column
+            v-if="orgname != '鏅畞鐣叉棌鑷不鍘夸汉姘戝尰闄�'"
+            label="鎴愬姛鐜�"
+            align="center"
+            width="120"
+            key="successRate"
+            prop="successRate"
+            :render-header="Tooltipcgl"
+          >
+            <template slot-scope="scope">
+              <span class="success-rate">{{
+                calculateSuccessRate(
+                  scope.row.followUpSuccess,
+                  scope.row.needFollowUp,
+                  scope.row.pendingFollowUp
+                )
+              }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column
             label="闅忚鐜�"
             align="center"
             width="120"
             key="followUpRate"
             prop="followUpRate"
+            :render-header="Tooltipsfl"
           />
           <el-table-column
             v-if="orgname != '涓芥按甯備腑鍖婚櫌'"
@@ -271,6 +575,7 @@
             width="120"
             key="rate"
             prop="rate"
+            :render-header="Tooltipjsl"
           >
             <template slot-scope="scope">
               <el-button
@@ -299,6 +604,19 @@
                 "
               >
                 <span class="button-zx">{{ scope.row.manual }}</span>
+              </el-button>
+            </template>
+          </el-table-column>
+          <el-table-column label="璇煶" align="center" key="voice" prop="voice">
+            <template slot-scope="scope">
+              <el-button
+                size="medium"
+                type="text"
+                @click="
+                  handleViewDetails(scope.row, 'voiceInfo', '璇煶闅忚鍒楄〃')
+                "
+              >
+                <span class="button-zx">{{ scope.row.voice }}</span>
               </el-button>
             </template>
           </el-table-column>
@@ -335,7 +653,9 @@
 
         <!-- 闅忚鎯呭喌鍒楋紙浠呬附姘村競涓尰闄㈡樉绀猴級 -->
         <el-table-column
-          v-if="orgname == '涓芥按甯備腑鍖婚櫌'"
+          v-if="
+            orgname == '涓芥按甯備腑鍖婚櫌' || orgname == '鏅畞鐣叉棌鑷不鍘夸汉姘戝尰闄�'
+          "
           align="center"
           label="闅忚鎯呭喌"
         >
@@ -388,6 +708,9 @@
 </template>
 
 <script>
+import { getSfStatisticsHyperlink } from "@/api/AiCentre/index";
+import store from "@/store";
+
 import { getSfStatistics, selectTimelyRate } from "@/api/system/user";
 import ExcelJS from "exceljs";
 import { saveAs } from "file-saver";
@@ -423,6 +746,7 @@
       expands: [],
       ids: [],
       patientqueryParams: { pn: 1, ps: 10 },
+      tasktypes: store.getters.tasktypes,
     };
   },
   methods: {
@@ -442,7 +766,7 @@
 
       delete params.leavehospitaldistrictcodes.all;
       delete params.deptcodes.all;
-
+      params.rateDay = this.orgname == "榫欐硥甯備汉姘戝尰闄�" ? 21 : 7;
       getSfStatistics(params)
         .then((response) => {
           this.tableData = this.customSort(response.data);
@@ -469,163 +793,19 @@
     },
 
     customSort(data) {
-      const order = [
-        "涓�",
-        "浜�",
-        "涓�",
-        "鍥�",
-        "浜�",
-        "鍏�",
-        "涓�",
-        "鍏�",
-        "涔�",
-        "鍗�",
-        "鍗佷竴",
-        "鍗佷簩",
-        "鍗佷笁",
-        "鍗佸洓",
-        "鍗佷簲",
-        "鍗佸叚",
-        "鍗佷竷",
-        "鍗佸叓",
-        "鍗佷節",
-        "浜屽崄",
-        "浜屽崄涓�",
-        "浜屽崄浜�",
-        "浜屽崄涓�",
-        "浜屽崄鍥�",
-        "浜屽崄浜�",
-        "浜屽崄鍏�",
-        "浜屽崄涓�",
-        "浜屽崄鍏�",
-        "浜屽崄涔�",
-        "涓夊崄",
-        "涓夊崄涓�",
-        "涓夊崄浜�",
-        "涓夊崄涓�",
-        "涓夊崄鍥�",
-        "涓夊崄浜�",
-        "涓夊崄鍏�",
-        "涓夊崄涓�",
-        "涓夊崄鍏�",
-        "涓夊崄涔�",
-        "鍥涘崄",
-        "鍥涘崄涓�",
-        "鍥涘崄浜�",
-        "鍥涘崄涓�",
-        "鍥涘崄鍥�",
-        "鍥涘崄浜�",
-      ];
-
-      return data.sort((a, b) => {
-        const getIndex = (name) => {
-          if (!name || typeof name !== "string") return -1;
-          const chineseMatch = name.match(/^([涓�浜屼笁鍥涗簲鍏竷鍏節鍗乚+)/);
-          if (chineseMatch && chineseMatch[1]) {
-            return order.indexOf(chineseMatch[1]);
-          }
-          const arabicMatch = name.match(/^(\d+)/);
-          if (arabicMatch && arabicMatch[1]) {
-            const num = parseInt(arabicMatch[1], 10);
-            if (num >= 1 && num <= 45) {
-              return num - 1;
-            }
-          }
-          return -1;
-        };
-
-        const indexA = getIndex(a.leavehospitaldistrictname);
-        const indexB = getIndex(b.leavehospitaldistrictname);
-
-        if (indexA === -1 && indexB === -1) {
-          return (a.leavehospitaldistrictname || "").localeCompare(
-            b.leavehospitaldistrictname || ""
-          );
-        }
-        if (indexA === -1) return 1;
-        if (indexB === -1) return -1;
-        return indexA - indexB;
-      });
+      return data.sort((a, b) =>
+        this.compareWardName(
+          a.leavehospitaldistrictname,
+          b.leavehospitaldistrictname
+        )
+      );
     },
 
     sortChineseNumber(aRow, bRow) {
-      const a = aRow.leavehospitaldistrictname;
-      const b = bRow.leavehospitaldistrictname;
-
-      const chineseNumMap = {
-        涓�: 1,
-        浜�: 2,
-        涓�: 3,
-        鍥�: 4,
-        浜�: 5,
-        鍏�: 6,
-        涓�: 7,
-        鍏�: 8,
-        涔�: 9,
-        鍗�: 10,
-        鍗佷竴: 11,
-        鍗佷簩: 12,
-        鍗佷笁: 13,
-        鍗佸洓: 14,
-        鍗佷簲: 15,
-        鍗佸叚: 16,
-        鍗佷竷: 17,
-        鍗佸叓: 18,
-        鍗佷節: 19,
-        浜屽崄: 20,
-        浜屽崄涓�: 21,
-        浜屽崄浜�: 22,
-        浜屽崄涓�: 23,
-        浜屽崄鍥�: 24,
-        浜屽崄浜�: 25,
-        浜屽崄鍏�: 26,
-        浜屽崄涓�: 27,
-        浜屽崄鍏�: 28,
-        浜屽崄涔�: 29,
-        涓夊崄: 30,
-        涓夊崄涓�: 31,
-        涓夊崄浜�: 32,
-        涓夊崄涓�: 33,
-        涓夊崄鍥�: 34,
-        涓夊崄浜�: 35,
-        涓夊崄鍏�: 36,
-        涓夊崄涓�: 37,
-        涓夊崄鍏�: 38,
-        涓夊崄涔�: 39,
-        鍥涘崄: 40,
-        鍥涘崄涓�: 41,
-        鍥涘崄浜�: 42,
-        鍥涘崄涓�: 43,
-        鍥涘崄鍥�: 44,
-        鍥涘崄浜�: 45,
-      };
-
-      const getNumberFromText = (text) => {
-        if (!text || typeof text !== "string") return -1;
-        const match = text.match(/^([涓�浜屼笁鍥涗簲鍏竷鍏節鍗乚+)/);
-        if (match && match[1]) {
-          const chineseNum = match[1];
-          return chineseNumMap[chineseNum] !== undefined
-            ? chineseNumMap[chineseNum]
-            : -1;
-        }
-        const arabicMatch = text.match(/^(\d+)/);
-        if (arabicMatch && arabicMatch[1]) {
-          const num = parseInt(arabicMatch[1], 10);
-          return num >= 1 && num <= 45 ? num : -1;
-        }
-        return -1;
-      };
-
-      const numA = getNumberFromText(a);
-      const numB = getNumberFromText(b);
-
-      if (numA === -1 && numB === -1) {
-        return (a || "").localeCompare(b || "");
-      }
-      if (numA === -1) return 1;
-      if (numB === -1) return -1;
-      return numA - numB;
+      return this.compareWardName(
+        aRow.leavehospitaldistrictname,
+        bRow.leavehospitaldistrictname
+      );
     },
 
     getRowKey(row) {
@@ -655,6 +835,8 @@
 
       if (!row.doctorStats) {
         this.loading = true;
+        params.rateDay = this.orgname == "榫欐硥甯備汉姘戝尰闄�" ? 21 : 7;
+
         getSfStatistics(params).then((res) => {
           this.$set(row, "doctorStats", res.data);
           this.expands = [this.getRowKey(row)];
@@ -664,7 +846,23 @@
         this.expands = [this.getRowKey(row)];
       }
     },
+    // 璁$畻鎴愬姛鐜囩殑鏂规硶
+    calculateSuccessRate(followUpSuccess, needFollowUp, pendingFollowUp) {
+      const success = Number(followUpSuccess) || 0;
+      const need = Number(needFollowUp) || 0;
+      const pending = Number(pendingFollowUp) || 0;
 
+      // 鍒嗘瘝 = 闇�闅忚 - 寰呴殢璁�
+      const denominator = need - pending;
+
+      if (denominator <= 0) {
+        return "0.00%";
+      }
+
+      const rate = (success / denominator) * 100;
+      return rate.toFixed(2) + "%";
+    },
+    // 鍦ㄧ粺璁℃眹鎬绘柟娉曚腑澶勭悊鎴愬姛鐜�
     getSummaries(param) {
       const { columns, data } = param;
       const sums = [];
@@ -674,12 +872,36 @@
           sums[index] = "鍚堣";
           return;
         }
-        if (index === 1 || index === 2) {
+        if (index === 1) {
           sums[index] = "/";
           return;
         }
 
-        if (column.property === "followUpRate" || column.property === "rate") {
+        if (column.property === "successRate") {
+          // 鎴愬姛鐜囬渶瑕侀噸鏂拌绠楁�荤殑鎴愬姛鐜囷紝鑰屼笉鏄钩鍧囧��
+          const totalSuccess = data.reduce((sum, item) => {
+            return sum + (Number(item.followUpSuccess) || 0);
+          }, 0);
+
+          const totalNeed = data.reduce((sum, item) => {
+            return sum + (Number(item.needFollowUp) || 0);
+          }, 0);
+
+          const totalPending = data.reduce((sum, item) => {
+            return sum + (Number(item.pendingFollowUp) || 0);
+          }, 0);
+
+          const denominator = totalNeed - totalPending;
+
+          if (denominator > 0) {
+            sums[index] = ((totalSuccess / denominator) * 100).toFixed(2) + "%";
+          } else {
+            sums[index] = "0.00%";
+          }
+        } else if (
+          column.property === "followUpRate" ||
+          column.property === "rate"
+        ) {
           const percentageValues = data
             .map((item) => {
               const value = item[column.property];
@@ -720,7 +942,46 @@
 
       return sums;
     },
-
+    Tooltipcgl(h, { column }) {
+      return h(
+        "el-tooltip",
+        {
+          props: {
+            content: "闅忚鎴愬姛/(闇�闅忚-寰呴殢璁�)",
+            placement: "top",
+            effect: "dark",
+          },
+        },
+        [h("span", column.label)]
+      );
+    },
+    Tooltipjsl(h, { column }) {
+      return h(
+        "el-tooltip",
+        {
+          props: {
+            content:
+              "(鍑洪櫌鏃堕棿+浠诲姟鍛ㄦ湡)灏忎簬瀹屾垚鏃堕棿鍗充负瓒呮椂;(闇�闅忚-瓒呮椂)/闇�闅忚",
+            placement: "top",
+            effect: "dark",
+          },
+        },
+        [h("span", column.label)]
+      );
+    },
+    Tooltipsfl(h, { column }) {
+      return h(
+        "el-tooltip",
+        {
+          props: {
+            content: "(闅忚鎴愬姛+棣栨闅忚澶辫触)/棣栨搴旈殢璁�",
+            placement: "top",
+            effect: "dark",
+          },
+        },
+        [h("span", column.label)]
+      );
+    },
     getInnerSummaries(param) {
       const { columns, data } = param;
       const sums = [];
@@ -736,7 +997,31 @@
           return;
         }
 
-        if (column.property === "followUpRate" || column.property === "rate") {
+        if (column.property === "successRate") {
+          // 鎴愬姛鐜囬渶瑕侀噸鏂拌绠楁�荤殑鎴愬姛鐜囷紝鑰屼笉鏄钩鍧囧��
+          const totalSuccess = data.reduce((sum, item) => {
+            return sum + (Number(item.followUpSuccess) || 0);
+          }, 0);
+
+          const totalNeed = data.reduce((sum, item) => {
+            return sum + (Number(item.needFollowUp) || 0);
+          }, 0);
+
+          const totalPending = data.reduce((sum, item) => {
+            return sum + (Number(item.pendingFollowUp) || 0);
+          }, 0);
+
+          const denominator = totalNeed - totalPending;
+
+          if (denominator > 0) {
+            sums[index] = ((totalSuccess / denominator) * 100).toFixed(2) + "%";
+          } else {
+            sums[index] = "0.00%";
+          }
+        } else if (
+          column.property === "followUpRate" ||
+          column.property === "rate"
+        ) {
           const percentageValues = data
             .map((item) => {
               const value = item[column.property];
@@ -783,25 +1068,99 @@
       return Number.isInteger(num) ? num.toString() : num.toFixed(0);
     },
 
+    // ===== 鐥呭尯鍚嶆帓搴忥紙鏀寔 1-B10 / 2-A2 绛� 鏁板瓧-瀛楁瘝鏁板瓧 鏍煎紡锛� =====
+    // 瑙f瀽鐥呭尯鍚嶏紝杩斿洖鎺掑簭閿� { group, letter, number }
+    parseWardKey(name) {
+      if (!name || typeof name !== "string") return null;
+      const trimmed = name.trim();
+
+      // 鏍煎紡1锛氭暟瀛�-瀛楁瘝鏁板瓧锛屽 1-B10銆�2-A2銆�1-A11
+      const dashMatch = trimmed.match(/^(\d+)-([A-Za-z]+)(\d+)/);
+      if (dashMatch) {
+        return {
+          group: parseInt(dashMatch[1], 10),
+          letter: dashMatch[2].toUpperCase(),
+          number: parseInt(dashMatch[3], 10),
+        };
+      }
+
+      // 鏍煎紡2锛氫腑鏂囨暟瀛楀紑澶达紝濡� 涓�鐥呭尯銆佸崄涓�鐥呭尯銆佷簩鍗佷竴鐥呭尯
+      const cnMatch = trimmed.match(/^([涓�浜屼笁鍥涗簲鍏竷鍏節鍗乚+)/);
+      if (cnMatch && cnMatch[1]) {
+        const num = this.chineseToNumber(cnMatch[1]);
+        if (num > 0) return { group: num, letter: "", number: 0 };
+      }
+
+      // 鏍煎紡3锛氶樋鎷変集鏁板瓧寮�澶达紝濡� 1鐥呭尯銆�12鐥呭尯
+      const numMatch = trimmed.match(/^(\d+)/);
+      if (numMatch && numMatch[1]) {
+        return { group: parseInt(numMatch[1], 10), letter: "", number: 0 };
+      }
+
+      return null;
+    },
+
+    // 涓枃鏁板瓧杞樋鎷変集鏁板瓧锛堟敮鎸� 涓� ~ 涔濆崄涔濓級
+    chineseToNumber(str) {
+      const digits = {
+        涓�: 1,
+        浜�: 2,
+        涓�: 3,
+        鍥�: 4,
+        浜�: 5,
+        鍏�: 6,
+        涓�: 7,
+        鍏�: 8,
+        涔�: 9,
+      };
+      if (!str) return -1;
+      if (str === "鍗�") return 10;
+      if (str.startsWith("鍗�")) return 10 + (digits[str[1]] || 0);
+      if (str.includes("鍗�")) {
+        const parts = str.split("鍗�");
+        const tens = digits[parts[0]] || 0;
+        const ones = digits[parts[1]] || 0;
+        return tens * 10 + ones;
+      }
+      return digits[str] !== undefined ? digits[str] : -1;
+    },
+
+    // 鐥呭尯鍚嶆瘮杈冨櫒锛氭暟瀛楁 鈫� 瀛楁瘝娈� 鈫� 鏁板瓧娈�
+    compareWardName(nameA, nameB) {
+      const ka = this.parseWardKey(nameA);
+      const kb = this.parseWardKey(nameB);
+
+      if (!ka && !kb) return (nameA || "").localeCompare(nameB || "", "zh-CN");
+      if (!ka) return 1;
+      if (!kb) return -1;
+
+      if (ka.group !== kb.group) return ka.group - kb.group;
+      if (ka.letter !== kb.letter) return ka.letter.localeCompare(kb.letter);
+      return ka.number - kb.number;
+    },
+
     handleSelectionChange(selection) {
       this.ids = selection.map((item) => item.tagid);
     },
 
-    handleViewDetails(row, infoKey, titleSuffix) {
+    handleViewDetails(row, infoKey, titleSuffix, type) {
       const title = `${
         row.leavehospitaldistrictname || row.deptname
       }${titleSuffix}`;
-      this.$emit("view-details", row[infoKey], title);
+      this.$emit("view-details", row, infoKey, title, type);
     },
 
     handleSeeDetails(row) {
       this.$emit("see-details", row);
     },
-
+    // 涓昏〃瀵煎嚭
     async exportTable() {
       try {
         let dateRangeString = "";
         let sheetNameSuffix = "";
+
+        // 鍒ゆ柇鏄惁鏄附姘村競涓尰闄�
+        const isLishuiHospital = this.orgname == "涓芥按甯備腑鍖婚櫌";
 
         if (
           this.queryParams.dateRange &&
@@ -809,25 +1168,97 @@
         ) {
           const startDateStr = this.queryParams.dateRange[0];
           const endDateStr = this.queryParams.dateRange[1];
-          const formatDateForDisplay = (dateTimeStr) => {
-            return dateTimeStr.split(" ")[0];
-          };
-          const startDateFormatted = formatDateForDisplay(startDateStr);
-          const endDateFormatted = formatDateForDisplay(endDateStr);
-          dateRangeString = `${startDateFormatted}鑷�${endDateFormatted}`;
-          sheetNameSuffix = `${startDateFormatted}鑷�${endDateFormatted}`;
+
+          if (isLishuiHospital) {
+            // 涓芥按甯備腑鍖婚櫌锛氬彧鏄剧ず骞存湀
+            const formatMonthOnly = (dateTimeStr) => {
+              const date = new Date(dateTimeStr);
+              const year = date.getFullYear();
+              const month = date.getMonth() + 1;
+              return `${year}骞�${month}鏈坄;
+            };
+            const startDateFormatted = formatMonthOnly(startDateStr);
+            const endDateFormatted = formatMonthOnly(endDateStr);
+            dateRangeString = `${startDateFormatted}鑷�${endDateFormatted}`;
+            sheetNameSuffix = `${startDateFormatted}鑷�${endDateFormatted}`;
+          } else {
+            // 鍏朵粬鍖婚櫌锛氭樉绀哄勾鏈堟棩
+            const formatDateForDisplay = (dateTimeStr) => {
+              return dateTimeStr.split(" ")[0];
+            };
+            const startDateFormatted = formatDateForDisplay(startDateStr);
+            const endDateFormatted = formatDateForDisplay(endDateStr);
+            dateRangeString = `${startDateFormatted}鑷�${endDateFormatted}`;
+            sheetNameSuffix = `${startDateFormatted}鑷�${endDateFormatted}`;
+          }
         } else {
           const now = new Date();
           const currentMonth = now.getMonth() + 1;
-          dateRangeString = `${currentMonth}鏈坄;
-          sheetNameSuffix = `${currentMonth}鏈坄;
+          const currentYear = now.getFullYear();
+
+          if (isLishuiHospital) {
+            // 涓芥按甯備腑鍖婚櫌锛氭樉绀哄勾鏈�
+            dateRangeString = `${currentYear}骞�${currentMonth}鏈坄;
+            sheetNameSuffix = `${currentYear}骞�${currentMonth}鏈坄;
+          } else {
+            // 鍏朵粬鍖婚櫌锛氭樉绀烘湀浠�
+            dateRangeString = `${currentMonth}鏈坄;
+            sheetNameSuffix = `${currentMonth}鏈坄;
+          }
         }
 
-        const excelName = `棣栨鍑洪櫌闅忚缁熻琛╛${dateRangeString}.xlsx`;
-        const worksheetName = `棣栨闅忚缁熻_${sheetNameSuffix}`;
+        // 鏍规嵁 serviceType 鐢熸垚闅忚绫诲瀷鍚嶇О
+        let serviceTypeName = "棣栨鍑洪櫌闅忚"; // 鏂囦欢鍚嶄娇鐢ㄧ殑鍚嶇О
+        let sheetTypeName = "棣栨闅忚"; // 宸ヤ綔琛ㄤ娇鐢ㄧ殑鍚嶇О锛堢畝鍖栫増锛�
+
+        if (
+          this.queryParams.serviceType &&
+          Array.isArray(this.queryParams.serviceType) &&
+          this.queryParams.serviceType.length > 0
+        ) {
+          // 浣跨敤 props 涓殑 options锛堝嵆 tasktypes锛�
+          if (this.options && Array.isArray(this.options)) {
+            const matchedTypes = this.options.filter((task) =>
+              this.queryParams.serviceType.includes(task.value)
+            );
+            console.log(matchedTypes, "matchedTypes");
+
+            if (matchedTypes.length === 1) {
+              const label = matchedTypes[0].label;
+              serviceTypeName = `棣栨${label}`;
+              sheetTypeName = `棣栨${label}`;
+            } else if (matchedTypes.length > 1) {
+              const typeNames = matchedTypes.map((task) => task.label);
+              serviceTypeName = `棣栨${typeNames.join("/")}`;
+              // 宸ヤ綔琛ㄥ悕绠�鍖栵紙鍙栫涓�涓�+鈥滅瓑鈥濓級
+              sheetTypeName = `棣栨${typeNames[0]}绛塦;
+            } else if (this.queryParams.serviceType.length > 0) {
+              // 鏃犲尮閰嶆椂浣跨敤鍘熷鍊�
+              const typeStr = this.queryParams.serviceType.join("/");
+              serviceTypeName = `棣栨${typeStr}`;
+              sheetTypeName = "棣栨闅忚";
+            }
+          } else if (this.queryParams.serviceType.length > 0) {
+            const typeStr = this.queryParams.serviceType.join("/");
+            serviceTypeName = `棣栨${typeStr}`;
+            sheetTypeName = "棣栨闅忚";
+          }
+        }
+
+        const excelName = `${serviceTypeName}缁熻琛╛${dateRangeString}.xlsx`;
+
+        // 娓呯悊宸ヤ綔琛ㄥ悕绉帮紝绉婚櫎闈炴硶瀛楃
+        const cleanSheetName = (name) => {
+          // Excel宸ヤ綔琛ㄥ悕涓嶈兘鍖呭惈鐨勫瓧绗�: * ? : \ / [ ]
+          return name.replace(/[*?:\\/[\]]/g, " ");
+        };
+
+        const worksheetName = cleanSheetName(
+          `${sheetTypeName}缁熻_${sheetNameSuffix}`
+        );
 
         if (!this.tableData || this.tableData.length === 0) {
-          this.$message.warning("鏆傛棤棣栨闅忚鏁版嵁鍙鍑�");
+          this.$message.warning(`鏆傛棤${serviceTypeName}鏁版嵁鍙鍑篳);
           return false;
         }
 
@@ -835,7 +1266,7 @@
         const worksheet = workbook.addWorksheet(worksheetName);
 
         // 鏋勫缓琛ㄦ牸
-        this.buildExportSheet(worksheet, sheetNameSuffix);
+        this.buildExportSheet(worksheet, sheetNameSuffix, serviceTypeName);
 
         const buffer = await workbook.xlsx.writeBuffer();
         const blob = new Blob([buffer], {
@@ -851,8 +1282,220 @@
         return false;
       }
     },
+    // 瀛愯〃瀵煎嚭
+    /** 瀵煎嚭鍖荤敓瀛愯〃 */
+    async exportDoctorTable(row) {
+      try {
+        const areaName =
+          row.leavehospitaldistrictname || row.deptname || "鏈煡鐥呭尯";
 
-    buildExportSheet(worksheet, sheetNameSuffix) {
+        let dateRangeString = "";
+        if (
+          this.queryParams.dateRange &&
+          this.queryParams.dateRange.length === 2
+        ) {
+          const start = this.queryParams.dateRange[0].split(" ")[0];
+          const end = this.queryParams.dateRange[1].split(" ")[0];
+          dateRangeString = `${start}鑷�${end}`;
+        } else {
+          dateRangeString = `${new Date().getMonth() + 1}鏈坄;
+        }
+
+        const fileName = `${areaName}鍖荤敓闅忚鍒楄〃_${dateRangeString}.xlsx`;
+        const sheetName = `${areaName}鍖荤敓闅忚`;
+
+        if (!row.doctorStats || row.doctorStats.length === 0) {
+          this.$message.warning("褰撳墠鐥呭尯鏆傛棤鍖荤敓闅忚鏁版嵁");
+          return;
+        }
+
+        const workbook = new ExcelJS.Workbook();
+        const worksheet = workbook.addWorksheet(sheetName);
+        console.log(111);
+
+        this.buildDoctorExportSheet(worksheet, row.doctorStats, areaName);
+        console.log(222);
+
+        const buffer = await workbook.xlsx.writeBuffer();
+        saveAs(
+          new Blob([buffer], {
+            type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
+          }),
+          fileName
+        );
+
+        this.$message.success("鍖荤敓闅忚鍒楄〃瀵煎嚭鎴愬姛");
+      } catch (err) {
+        console.error(err);
+        this.$message.error("瀵煎嚭澶辫触");
+      }
+    },
+    buildDoctorExportSheet(worksheet, data, areaName) {
+      const titleStyle = {
+        font: { name: "寰蒋闆呴粦", size: 16, bold: true },
+        alignment: { horizontal: "center", vertical: "middle" },
+      };
+
+      const headerStyle = {
+        font: { name: "寰蒋闆呴粦", size: 11, bold: true },
+        fill: {
+          type: "pattern",
+          pattern: "solid",
+          fgColor: { argb: "FFF5F7FA" },
+        },
+        alignment: { horizontal: "center", vertical: "middle", wrapText: true },
+        border: {
+          top: { style: "thin" },
+          left: { style: "thin" },
+          bottom: { style: "thin" },
+          right: { style: "thin" },
+        },
+      };
+
+      const cellStyle = {
+        font: { name: "瀹嬩綋", size: 10 },
+        alignment: { horizontal: "center", vertical: "middle" },
+        border: {
+          top: { style: "thin" },
+          left: { style: "thin" },
+          bottom: { style: "thin" },
+          right: { style: "thin" },
+        },
+      };
+
+      // 鏍囬
+      worksheet.mergeCells(1, 1, 1, 10);
+      worksheet.getCell(1, 1).value = `${areaName}鍖荤敓闅忚鍒楄〃`;
+      worksheet.getCell(1, 1).style = titleStyle;
+      worksheet.getRow(1).height = 30;
+
+      // 琛ㄥご
+      const headers = [
+        "鍖荤敓濮撳悕",
+        "绉戝",
+        "鍑洪櫌浜烘",
+        "鏃犻渶闅忚",
+        "搴旈殢璁�",
+        "闇�闅忚",
+        "寰呴殢璁�",
+        "闅忚鎴愬姛",
+        "闅忚澶辫触",
+        "鎴愬姛鐜�", // 鏂板
+        "闅忚鐜�", // 鍘熸潵鍦ㄦ垚鍔熺巼浣嶇疆
+      ];
+
+      const headerRow = worksheet.addRow(headers);
+      headerRow.eachCell((cell) => {
+        cell.style = headerStyle;
+      });
+      worksheet.getRow(2).height = 25;
+
+      // 鏁版嵁
+      data.forEach((item) => {
+        const row = worksheet.addRow([
+          item.drname,
+          item.deptname,
+          item.dischargeCount,
+          item.nonFollowUp,
+          item.followUpNeeded,
+          item.needFollowUp,
+          item.pendingFollowUp,
+          item.followUpSuccess,
+          item.followUpFail,
+          this.calculateSuccessRate(
+            item.followUpSuccess,
+            item.needFollowUp,
+            item.pendingFollowUp
+          ),
+          item.followUpRate,
+        ]);
+        row.eachCell((cell) => {
+          cell.style = cellStyle;
+        });
+      });
+
+      // 灏忚琛�
+      const summaryRow = worksheet.addRow(this.getDoctorExportSummary(data));
+      summaryRow.eachCell((cell) => {
+        cell.font = { bold: true };
+        cell.fill = {
+          type: "pattern",
+          pattern: "solid",
+          fgColor: { argb: "FFF5F7FA" },
+        };
+      });
+
+      // 鍒楀
+      worksheet.columns = [
+        { width: 15 },
+        { width: 15 },
+        { width: 12 },
+        { width: 12 },
+        { width: 12 },
+        { width: 12 },
+        { width: 12 },
+        { width: 12 },
+        { width: 12 },
+        { width: 12 }, // 鎴愬姛鐜�
+        { width: 12 }, // 闅忚鐜�
+      ];
+    },
+    getDoctorExportSummary(data) {
+      const sums = ["灏忚"];
+
+      const keys = [
+        "dischargeCount",
+        "nonFollowUp",
+        "followUpNeeded",
+        "needFollowUp",
+        "pendingFollowUp",
+        "followUpSuccess",
+        "followUpFail",
+      ];
+
+      keys.forEach((key) => {
+        sums.push(data.reduce((t, r) => t + (Number(r[key]) || 0), 0));
+      });
+
+      // 鎴愬姛鐜囷紙骞冲潎鍊硷級
+      const successRates = data
+        .map((item) => {
+          const success = Number(item.followUpSuccess) || 0;
+          const need = Number(item.needFollowUp) || 0;
+          const pending = Number(item.pendingFollowUp) || 0;
+          const denominator = need - pending;
+          if (denominator <= 0) return 0;
+          return success / denominator;
+        })
+        .filter((rate) => !isNaN(rate));
+
+      sums.push(
+        successRates.length
+          ? (
+              (successRates.reduce((a, b) => a + b, 0) / successRates.length) *
+              100
+            ).toFixed(2) + "%"
+          : "0.00%"
+      );
+
+      // 闅忚鐜囷紙骞冲潎鍊硷級
+      const followUpRates = data
+        .map((i) => this.extractPercentageValue(i.followUpRate))
+        .filter(Boolean);
+
+      sums.push(
+        followUpRates.length
+          ? (
+              (followUpRates.reduce((a, b) => a + b, 0) /
+                followUpRates.length) *
+              100
+            ).toFixed(2) + "%"
+          : "0.00%"
+      );
+
+      return sums;
+    },
+    buildExportSheet(worksheet, sheetNameSuffix, serviceTypeName) {
       const titleStyle = {
         font: {
           name: "寰蒋闆呴粦",
@@ -926,11 +1569,11 @@
           right: { style: "thin", color: { argb: "FFD0D0D0" } },
         },
       };
-
+      const titleText = `${serviceTypeName}缁熻琛╛${sheetNameSuffix}`;
       // 娣诲姞鏍囬琛�
       worksheet.mergeCells(1, 1, 1, 16);
       const titleCell = worksheet.getCell(1, 1);
-      titleCell.value = `棣栨鍑洪櫌闅忚缁熻琛╛${sheetNameSuffix}`;
+      titleCell.value = titleText; // 浣跨敤鍔ㄦ�佹爣棰�
       titleCell.style = titleStyle;
       worksheet.getRow(1).height = 35;
 
@@ -946,11 +1589,13 @@
         "寰呴殢璁�",
         "闅忚鎴愬姛",
         "闅忚澶辫触",
-        "闅忚鐜�",
-        "鍙婃椂鐜�",
+        "鎴愬姛鐜�", // 鏂板
+        "闅忚鐜�", // 鍘熶綅缃悗绉�
+        "鍙婃椂鐜�", // 鍙婃椂鐜囧悗绉�
         "浜哄伐",
-        "鐭俊",
-        "寰俊",
+        "璇煶", // 淇锛氬簲璇ユ槸璇煶
+        "鐭俊", // 鐭俊
+        "寰俊", // 寰俊
       ];
 
       secondRowHeaders.forEach((header, index) => {
@@ -973,8 +1618,8 @@
       worksheet.getCell(2, 5).value = "鏃犻渶闅忚浜烘";
       worksheet.getCell(2, 6).value = "搴旈殢璁夸汉娆�";
 
-      worksheet.mergeCells(2, 7, 2, 15);
-      worksheet.getCell(2, 7).value = "棣栨鍑洪櫌闅忚";
+      worksheet.mergeCells(2, 7, 2, 16); // 浠�7鍚堝苟鍒�16锛堝師鏉ユ槸7-15锛�
+      worksheet.getCell(2, 7).value = serviceTypeName; // 鎴栭�傚綋鎴彇
       worksheet.getCell(2, 7).style = headerStyle;
 
       worksheet.getRow(2).height = 28;
@@ -994,15 +1639,21 @@
             item.pendingFollowUp || 0,
             item.followUpSuccess || 0,
             item.followUpFail || 0,
-            item.followUpRate || "0%",
-            item.rate ? (Number(item.rate) * 100).toFixed(2) + "%" : "0%",
+            // 鎴愬姛鐜� - 闇�瑕佸姩鎬佽绠�
+            this.calculateSuccessRate(
+              item.followUpSuccess,
+              item.needFollowUp,
+              item.pendingFollowUp
+            ),
+            item.followUpRate || "0%", // 闅忚鐜�
+            item.rate ? (Number(item.rate) * 100).toFixed(2) + "%" : "0%", // 鍙婃椂鐜�
             item.manual || 0,
-            item.sms || 0,
-            item.weChat || 0,
+            item.voice || 0, // 璇煶
+            item.sms || 0, // 鐭俊
+            item.weChat || 0, // 寰俊
           ],
           rowIndex + 4
         );
-
         dataRow.eachCell((cell) => {
           cell.style = cellStyle;
         });
@@ -1032,11 +1683,13 @@
         { width: 10 },
         { width: 10 },
         { width: 10 },
-        { width: 12 },
-        { width: 12 },
-        { width: 8 },
-        { width: 8 },
-        { width: 8 },
+        { width: 12 }, // 鎴愬姛鐜�
+        { width: 12 }, // 闅忚鐜�
+        { width: 12 }, // 鍙婃椂鐜�
+        { width: 8 }, // 浜哄伐
+        { width: 8 }, // 璇煶
+        { width: 8 }, // 鐭俊
+        { width: 8 }, // 寰俊
       ];
     },
 
@@ -1045,18 +1698,20 @@
         "鍚堣",
         "/",
         "/",
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        "0%",
-        "0%",
-        0,
-        0,
-        0,
+        0, // 3: dischargeCount
+        0, // 4: nonFollowUp
+        0, // 5: followUpNeeded
+        0, // 6: needFollowUp
+        0, // 7: pendingFollowUp
+        0, // 8: followUpSuccess
+        0, // 9: followUpFail
+        "0%", // 10: 鎴愬姛鐜�
+        "0%", // 11: 闅忚鐜�
+        "0%", // 12: 鍙婃椂鐜�
+        0, // 13: manual
+        0, // 14: voice
+        0, // 15: sms
+        0, // 16: weChat
       ];
 
       this.tableData.forEach((item) => {
@@ -1067,42 +1722,51 @@
         summaries[7] += Number(item.pendingFollowUp) || 0;
         summaries[8] += Number(item.followUpSuccess) || 0;
         summaries[9] += Number(item.followUpFail) || 0;
-        summaries[12] += Number(item.manual) || 0;
-        summaries[13] += Number(item.sms) || 0;
-        summaries[14] += Number(item.weChat) || 0;
+        summaries[13] += Number(item.manual) || 0;
+        summaries[14] += Number(item.voice) || 0;
+        summaries[15] += Number(item.sms) || 0;
+        summaries[16] += Number(item.weChat) || 0;
       });
 
+      // 鎴愬姛鐜囪绠�
+      const totalSuccess = summaries[8]; // followUpSuccess鐨勬�诲拰
+      const totalNeed = summaries[6]; // needFollowUp鐨勬�诲拰
+      const totalPending = summaries[7]; // pendingFollowUp鐨勬�诲拰
+      const denominator = totalNeed - totalPending;
+
+      if (denominator > 0) {
+        summaries[10] = ((totalSuccess / denominator) * 100).toFixed(2) + "%";
+      } else {
+        summaries[10] = "0.00%";
+      }
+
+      // 闅忚鐜囪绠�
       const followUpRateValues = this.tableData
         .map((item) => this.extractPercentageValue(item.followUpRate))
-        .filter((value) => value !== null);
-
-      const rateValues = this.tableData
-        .map((item) => this.extractPercentageValue(item.rate))
         .filter((value) => value !== null);
 
       if (followUpRateValues.length > 0) {
         const avgFollowUpRate =
           followUpRateValues.reduce((sum, val) => sum + val, 0) /
           followUpRateValues.length;
-        summaries[10] = (avgFollowUpRate * 100).toFixed(2) + "%";
+        summaries[11] = (avgFollowUpRate * 100).toFixed(2) + "%";
       }
+
+      // 鍙婃椂鐜囪绠�
+      const rateValues = this.tableData
+        .map((item) => this.extractPercentageValue(item.rate))
+        .filter((value) => value !== null);
 
       if (rateValues.length > 0) {
         const avgRate =
           rateValues.reduce((sum, val) => sum + val, 0) / rateValues.length;
-        summaries[11] = (avgRate * 100).toFixed(2) + "%";
+        summaries[12] = (avgRate * 100).toFixed(2) + "%";
       }
 
-      summaries[3] = this.formatNumber(summaries[3]);
-      summaries[4] = this.formatNumber(summaries[4]);
-      summaries[5] = this.formatNumber(summaries[5]);
-      summaries[6] = this.formatNumber(summaries[6]);
-      summaries[7] = this.formatNumber(summaries[7]);
-      summaries[8] = this.formatNumber(summaries[8]);
-      summaries[9] = this.formatNumber(summaries[9]);
-      summaries[12] = this.formatNumber(summaries[12]);
-      summaries[13] = this.formatNumber(summaries[13]);
-      summaries[14] = this.formatNumber(summaries[14]);
+      // 鏍煎紡鍖栨暟瀛�
+      [3, 4, 5, 6, 7, 8, 9, 13, 14, 15, 16].forEach((index) => {
+        summaries[index] = this.formatNumber(summaries[index]);
+      });
 
       return summaries;
     },
@@ -1117,8 +1781,8 @@
       return isNaN(num) ? null : num;
     },
 
-    selectTimelyRate(row, dateRange) {
-      console.log(row, dateRange, 88);
+    selectTimelyRate(row, queryParams) {
+      console.log(row, queryParams, 88);
 
       // const params = {
       //   ...this.patientqueryParams,
@@ -1126,9 +1790,19 @@
       //   endtime: this.parseTime(dateRange[1]),
       //   deptcode: row.deptcode,
       // };
-      this.patientqueryParams.starttime = this.parseTime(dateRange[0]);
-      this.patientqueryParams.endtime = this.parseTime(dateRange[1]);
+      this.patientqueryParams.starttime = this.parseTime(
+        queryParams.dateRange[0]
+      );
+      this.patientqueryParams.endtime = this.parseTime(
+        queryParams.dateRange[1]
+      );
       this.patientqueryParams.deptcode = row.deptcode;
+      console.log(1);
+
+      this.patientqueryParams.serviceTypes = queryParams.serviceType
+        ? queryParams.serviceType.join(",")
+        : null;
+
       return selectTimelyRate(this.patientqueryParams);
     },
     selectTimelyRates(dateRange) {

--
Gitblit v1.9.3