From 4c5d48b7e9450e8e793970576caf2f3510e99dba Mon Sep 17 00:00:00 2001
From: WXL (wul) <wl_5969728@163.com>
Date: 星期五, 27 三月 2026 09:33:01 +0800
Subject: [PATCH] 测试完成

---
 src/views/Satisfaction/sfstatistics/IndicatorStatistics.vue               |   66 +
 src/views/followvisit/again/index.vue                                     |    2 
 vue.config.js                                                             |    4 
 src/views/followvisit/zbAgain/index.vue                                   |    2 
 src/views/followvisit/record/TracingInfo/index.vue                        |    6 
 指标统计整合页适配丽水省立同德.zip                                                       |    0 
 src/views/followvisit/Tracking/index.vue                                  |    2 
 src/views/Satisfaction/sfstatistics/components/visitStatistics.vue        | 1030 ++++++++++++++++
 src/views/followvisit/Continue/index.vue                                  |    2 
 src/views/patient/propaganda/QuestionnaireTask.vue                        |   73 
 src/views/followvisit/OutpatientAgain/index.vue                           |    2 
 /dev/null                                                                 | 1814 -----------------------------
 src/views/followvisit/record/physical/index.vue                           |    6 
 src/views/patient/propaganda/index.vue                                    |    6 
 src/views/followvisit/record/detailpage/index.vue                         |    6 
 src/views/sfstatistics/percentage/index.vue                               |  149 +
 src/views/Satisfaction/sfstatistics/components/FollowupStatistics.vue     |  387 ++++-
 src/views/Satisfaction/sfstatistics/components/components/TopicDialog.vue |  117 +
 src/views/followvisit/discharge/outpatientService.vue                     |    2 
 src/views/followvisit/discharge/index.vue                                 |    2 
 20 files changed, 1,665 insertions(+), 2,013 deletions(-)

diff --git a/src/views/Satisfaction/1.vue b/src/views/Satisfaction/1.vue
deleted file mode 100644
index b3544ca..0000000
--- a/src/views/Satisfaction/1.vue
+++ /dev/null
@@ -1,1814 +0,0 @@
-<template>
-  <div class="Questionnairemanagement">
-    <div class="leftvlue">
-      <div class="leftvlue-bg">
-        <el-row :gutter="20">
-          <!--鏍囩鏁版嵁-->
-          <el-col :span="24" :xs="24">
-            <el-form
-              :model="queryParams"
-              ref="queryForm"
-              size="small"
-              :inline="true"
-              v-show="showSearch"
-              label-width="98px"
-            >
-              <el-form-item label="缁熻绫诲瀷" prop="userName">
-                <el-select
-                  v-model="queryParams.statisticaltype"
-                  placeholder="璇烽�夋嫨缁熻绫诲瀷"
-                >
-                  <el-option
-                    v-for="item in Statisticallist"
-                    :key="item.value"
-                    :label="item.label"
-                    :value="item.value"
-                  >
-                  </el-option>
-                </el-select>
-                <el-select
-                  style="margin-left: 10px"
-                  v-if="queryParams.statisticaltype == 1"
-                  v-model="queryParams.leavehospitaldistrictcodes"
-                  size="medium"
-                  multiple
-                  filterable
-                  placeholder="璇烽�夋嫨鐥呭尯"
-                >
-                  <el-option
-                    v-for="item in flatArrayhospit"
-                    :key="item.value"
-                    :label="item.label"
-                    :value="item.value"
-                  >
-                  </el-option>
-                </el-select>
-                <el-select
-                  v-else-if="queryParams.statisticaltype == 2"
-                  v-model="queryParams.deptcodes"
-                  size="medium"
-                  multiple
-                  filterable
-                  placeholder="璇烽�夋嫨绉戝"
-                >
-                  <el-option
-                    v-for="item in flatArraydept"
-                    :key="item.value"
-                    :label="item.label"
-                    :value="item.value"
-                  >
-                  </el-option>
-                </el-select>
-              </el-form-item>
-
-              <el-form-item label="鏈嶅姟绫诲瀷" prop="userName">
-                <el-select
-                  v-model="queryParams.serviceType"
-                  multiple
-                  placeholder="璇烽�夋嫨"
-                >
-                  <el-option
-                    v-for="item in options"
-                    :key="item.value"
-                    :label="item.label"
-                    :value="item.value"
-                  >
-                  </el-option>
-                </el-select>
-              </el-form-item>
-              <el-form-item
-                label-width="200"
-                label="闅忚鏃堕棿鑼冨洿"
-                prop="userName"
-              >
-                <el-date-picker
-                  v-model="queryParams.dateRange"
-                  value-format="yyyy-MM-dd"
-                  type="daterange"
-                  range-separator="鑷�"
-                  start-placeholder="寮�濮嬫棩鏈�"
-                  end-placeholder="缁撴潫鏃ユ湡"
-                >
-                </el-date-picker>
-              </el-form-item>
-
-              <el-form-item>
-                <el-button
-                  type="primary"
-                  icon="el-icon-search"
-                  size="medium"
-                  @click="handleQuery"
-                  >鎼滅储</el-button
-                >
-                <el-button
-                  icon="el-icon-refresh"
-                  size="medium"
-                  @click="resetQuery"
-                  >閲嶇疆</el-button
-                >
-              </el-form-item>
-              <el-col :span="19">
-                <el-button
-                  type="warning"
-                  plain
-                  icon="el-icon-download"
-                  size="medium"
-                  @click="handleExport"
-                  >瀵煎嚭</el-button
-                >
-                <el-button
-                  type="primary"
-                  plain
-                  icon="el-icon-data-line"
-                  size="medium"
-                  @click="showChartDialog"
-                  >缁熻瓒嬪娍鍥�</el-button
-                >
-              </el-col>
-            </el-form>
-            <el-table
-              v-loading="loading"
-              :data="userList"
-              :border="true"
-              @selection-change="handleSelectionChange"
-              :row-key="getRowKey"
-              :expand-row-keys="expands"
-            >
-              <el-table-column
-                label="鍑洪櫌鐥呭尯"
-                align="center"
-                sortable
-                key="leavehospitaldistrictname"
-                prop="leavehospitaldistrictname"
-                :show-overflow-tooltip="true"
-              />
-              <el-table-column
-                label="绉戝"
-                align="center"
-                key="deptname"
-                prop="deptname"
-                :show-overflow-tooltip="true"
-              />
-              <el-table-column
-                label="鍑洪櫌浜烘"
-                align="center"
-                key="dischargeCount"
-                prop="dischargeCount"
-              >
-              </el-table-column>
-
-              <el-table-column
-                label="鏃犻渶闅忚浜烘"
-                align="center"
-                key="nonFollowUp"
-                prop="nonFollowUp"
-              >
-              </el-table-column>
-              <el-table-column
-                label="搴旈殢璁夸汉娆�"
-                align="center"
-                key="followUpNeeded"
-                prop="followUpNeeded"
-              >
-              </el-table-column>
-              <el-table-column
-                label="闅忚鐜�"
-                align="center"
-                key="followUpRate"
-                prop="followUpRate"
-              >
-                <!-- <template slot-scope="scope">
-                    <span
-                      >{{
-                        (Number(scope.row.followUpRate) * 100).toFixed(2)
-                      }}%</span
-                    >
-                  </template> -->
-              </el-table-column>
-              <el-table-column
-                label="鍙婃椂鐜�"
-                align="center"
-                key="rate"
-                prop="rate"
-              >
-                <template slot-scope="scope">
-                  <el-button
-                    size="medium"
-                    type="text"
-                    @click="Seedetails(scope.row)"
-                    ><span class="button-zx"
-                      >{{ (Number(scope.row.rate) * 100).toFixed(2) }}%</span
-                    ></el-button
-                  >
-                </template>
-              </el-table-column>
-              <el-table-column
-                label="婊℃剰搴﹂鐩�婚噺"
-                align="center"
-                key="joyAllCount"
-                prop="joyAllCount"
-              >
-              </el-table-column>
-              <el-table-column
-                label="婊℃剰搴﹀~鎶ラ噺"
-                align="center"
-                key="joyCount"
-                prop="joyCount"
-              >
-              </el-table-column>
-              <el-table-column
-                label="瀹屾垚姣旂巼"
-                align="center"
-                key="joyTotal"
-                prop="joyTotal"
-              >
-                <template slot-scope="scope">
-                  <span class="button-zx"
-                    >{{ (Number(scope.row.joyTotal) * 100).toFixed(2) }}%</span
-                  >
-                </template>
-              </el-table-column>
-              <el-table-column
-                label="鎿嶄綔"
-                align="center"
-                fixed="right"
-                width="300"
-                class-name="small-padding fixed-width"
-              >
-                <template slot-scope="scope">
-                  <el-button
-                    size="medium"
-                    type="text"
-                    @click="getinfo(scope.row)"
-                    ><span class="button-zx"
-                      ><i class="el-icon-s-order"></i>鏌ョ湅璇︽儏</span
-                    ></el-button
-                  >
-                </template>
-              </el-table-column>
-            </el-table>
-
-            <!-- <pagination
-              v-show="total > 0"
-              :total="total"
-              :page.sync="queryParams.pageNum"
-              :limit.sync="queryParams.pageSize"
-              @pagination="getList"
-            /> -->
-          </el-col>
-        </el-row>
-      </div>
-    </div>
-    <!-- 缁熻瓒嬪娍鍥惧脊绐� -->
-    <el-dialog
-      title="闅忚缁熻瓒嬪娍鍥�"
-      :visible.sync="chartDialogVisible"
-      width="80%"
-      :close-on-click-modal="false"
-    >
-      <div class="chart-container">
-        <el-row :gutter="20">
-          <el-col :span="12">
-            <div class="chart-title">闅忚鐘舵�佸垎甯�</div>
-            <div id="pieChart" style="width: 100%; height: 400px"></div>
-          </el-col>
-          <el-col :span="12">
-            <div class="chart-title">闅忚瓒嬪娍鍒嗘瀽</div>
-            <div id="barLineChart" style="width: 100%; height: 400px"></div>
-          </el-col>
-        </el-row>
-      </div>
-    </el-dialog>
-    <el-dialog
-      title="鏈強鏃堕殢璁挎偅鑰呮湇鍔�"
-      :visible.sync="SeedetailsVisible"
-      v-loading="Seedloading"
-      width="70%"
-      :close-on-click-modal="false"
-    >
-      <div class="examine-jic">
-        <div class="jic-value">
-          <el-row :gutter="20">
-            <!--鐢ㄦ埛鏁版嵁-->
-            <el-form
-              :model="patientqueryParams"
-              ref="queryForm"
-              size="small"
-              :inline="true"
-              label-width="98px"
-            >
-              <el-form-item label="鎮h�咃細">
-                <el-input
-                  v-model="patientqueryParams.name"
-                  @keyup.enter.native="handleQuery"
-                ></el-input>
-              </el-form-item>
-              <el-form-item label="鎮h�呰瘖鏂細">
-                <el-input
-                  v-model="patientqueryParams.leavediagname"
-                  @keyup.enter.native="handleQuery"
-                ></el-input>
-              </el-form-item>
-
-              <el-form-item>
-                <el-button
-                  type="primary"
-                  icon="el-icon-search"
-                  size="medium"
-                  @click="handleQuery"
-                  >鎼滅储</el-button
-                >
-                <el-button
-                  icon="el-icon-refresh"
-                  size="medium"
-                  @click="resetQuery"
-                  >鍙栨秷鍒涘缓</el-button
-                >
-              </el-form-item>
-            </el-form>
-            <!-- 閫夋嫨鎮h�呭垪琛� -->
-            <el-table :data="logsheetlist" style="width: 100%">
-              <el-table-column
-                prop="sendname"
-                align="center"
-                label="濮撳悕"
-                width="100"
-              >
-              </el-table-column>
-              <el-table-column
-                prop="taskName"
-                align="center"
-                width="200"
-                show-overflow-tooltip
-                label="浠诲姟鍚嶇О"
-              >
-              </el-table-column>
-              <el-table-column
-                prop="sendstate"
-                align="center"
-                width="200"
-                label="浠诲姟鐘舵��"
-              >
-                <template slot-scope="scope">
-                  <div v-if="scope.row.sendstate == 1">
-                    <el-tag type="primary" :disable-transitions="false"
-                      >琛ㄥ崟宸查鍙�</el-tag
-                    >
-                  </div>
-                  <div v-if="scope.row.sendstate == 2">
-                    <el-tag type="primary" :disable-transitions="false"
-                      >寰呴殢璁�</el-tag
-                    >
-                  </div>
-                  <div v-if="scope.row.sendstate == 3">
-                    <el-tag type="success" :disable-transitions="false"
-                      >琛ㄥ崟宸插彂閫�</el-tag
-                    >
-                  </div>
-                  <div v-if="scope.row.sendstate == 4">
-                    <el-tag type="info" :disable-transitions="false"
-                      >涓嶆墽琛�</el-tag
-                    >
-                  </div>
-                  <div v-if="scope.row.sendstate == 5">
-                    <el-tag type="danger" :disable-transitions="false"
-                      >鍙戦�佸け璐�</el-tag
-                    >
-                  </div>
-                  <div v-if="scope.row.sendstate == 6">
-                    <el-tag type="success" :disable-transitions="false"
-                      >宸插畬鎴�</el-tag
-                    >
-                  </div>
-                </template>
-              </el-table-column>
-              <el-table-column
-                prop="visitTime"
-                align="center"
-                label="搴旈殢璁挎椂闂�"
-                width="200"
-                show-overflow-tooltip
-              >
-              </el-table-column>
-              <el-table-column
-                prop="finishtime"
-                align="center"
-                label="闅忚瀹屾垚鏃堕棿"
-                width="200"
-                show-overflow-tooltip
-              >
-              </el-table-column>
-              <el-table-column
-                label="鍑洪櫌鏃ユ湡"
-                width="200"
-                align="center"
-                key="endtime"
-                prop="endtime"
-              >
-                <template slot-scope="scope">
-                  <span>{{ formatTime(scope.row.endtime) }}</span>
-                </template></el-table-column
-              >
-              <el-table-column
-                label="璐d换鎶ゅ+"
-                width="120"
-                align="center"
-                key="nurseName"
-                prop="nurseName"
-              />
-              <el-table-column
-                label="涓绘不鍖荤敓"
-                width="120"
-                align="center"
-                key="drname"
-                prop="drname"
-              />
-
-              <el-table-column
-                label="缁撴灉鐘舵��"
-                align="center"
-                key="excep"
-                prop="excep"
-                width="120"
-              >
-                <template slot-scope="scope">
-                  <dict-tag
-                    :options="dict.type.sys_yujing"
-                    :value="scope.row.excep"
-                  />
-                </template>
-              </el-table-column>
-              <el-table-column
-                label="澶勭悊鎰忚"
-                align="center"
-                key="suggest"
-                prop="suggest"
-                width="120"
-              >
-                <template slot-scope="scope">
-                  <dict-tag
-                    :options="dict.type.sys_suggest"
-                    :value="scope.row.suggest"
-                  />
-                </template>
-              </el-table-column>
-
-              <el-table-column
-                prop="templatename"
-                align="center"
-                label="鏈嶅姟妯℃澘"
-                width="200"
-                show-overflow-tooltip
-              >
-              </el-table-column>
-              <el-table-column
-                prop="remark"
-                align="center"
-                label="鏈嶅姟璁板綍"
-                width="200"
-                show-overflow-tooltip
-              >
-              </el-table-column>
-
-              <el-table-column
-                prop="bankcardno"
-                align="center"
-                label="鍛煎彨鐘舵��"
-                width="210"
-              >
-              </el-table-column>
-              <el-table-column
-                label="鎿嶄綔"
-                fixed="right"
-                align="center"
-                width="200"
-                class-name="small-padding fixed-width"
-              >
-                <template slot-scope="scope">
-                  <el-button
-                    size="medium"
-                    type="text"
-                    @click="SeedetailsgGo(scope.row)"
-                    ><span class="button-zx"
-                      ><i class="el-icon-s-order"></i>鏌ョ湅</span
-                    ></el-button
-                  >
-                </template>
-              </el-table-column>
-            </el-table>
-          </el-row>
-          <pagination
-            v-show="patienttotal > 0 && this.patientqueryParams.allhosp != 6"
-            :total="patienttotal"
-            :page.sync="patientqueryParams.pn"
-            :limit.sync="patientqueryParams.ps"
-            @pagination="Seedetails"
-          />
-        </div>
-      </div>
-    </el-dialog>
-    <!-- 鍗曠瀹ょ粺璁¤鎯� -->
-    <el-dialog :visible.sync="topicVisible" width="45%">
-      <div class="topicdia">
-        <div class="top-text">
-          {{ topicvalue.name }}<span>婊℃剰搴︽寚鏍囪鎯�</span>
-        </div>
-        <div style="overflow-x: hidden; overflow-y: auto; max-height: 65vh">
-          <div
-            class="ttaabbcc"
-            v-for="(item, index) in topiclist"
-            :key="item.name"
-          >
-            <div class="describe">
-              绗瑊{ index }}棰橈細 {{ item.scriptContent }}?<span
-                >[{{ item.scriptType == 1 ? "鍗曢�夐" : "澶氶�夐" }}]</span
-              >
-            </div>
-            <div>
-              <el-table :data="item.details" style="width: 100%">
-                <el-table-column prop="optionText" label="闂閫夐」">
-                </el-table-column>
-                <el-table-column prop="chosenQuantity" label="閫夋嫨浜烘暟">
-                </el-table-column>
-                <el-table-column prop="chosenPercentage" label="姣斾緥">
-                  <template slot-scope="scope">
-                    <span class="button-zx"
-                      >{{
-                        (Number(scope.row.chosenPercentage) * 100).toFixed(2)
-                      }}%</span
-                    >
-                  </template>
-                </el-table-column>
-              </el-table>
-            </div>
-          </div>
-        </div>
-      </div>
-      <span slot="footer" class="dialog-footer">
-        <el-button @click="topicVisible = false">鍏� 闂�</el-button>
-      </span>
-    </el-dialog>
-  </div>
-</template>
-
-<script>
-import {
-  toamendtag,
-  addapitag,
-  deletetag,
-  changetagcategory,
-} from "@/api/system/label";
-import store from "@/store";
-import {
-  getSfStatisticsJoy,
-  getSfStatisticsJoyInfo,
-  selectTimelyRate,
-} from "@/api/system/user";
-import ExcelJS from "exceljs";
-import { saveAs } from "file-saver";
-import Treeselect from "@riophae/vue-treeselect";
-import "@riophae/vue-treeselect/dist/vue-treeselect.css";
-const shortcuts = [
-  {
-    text: "浠婂ぉ",
-    onClick(picker) {
-      picker.$emit("pick", new Date());
-    },
-  },
-  {
-    text: "鏄ㄥぉ",
-    onClick(picker) {
-      const date = new Date();
-      date.setTime(date.getTime() - 3600 * 1000 * 24);
-      picker.$emit("pick", date);
-    },
-  },
-  {
-    text: "涓�鍛ㄥ墠",
-    onClick(picker) {
-      const date = new Date();
-      date.setTime(date.getTime() - 3600 * 1000 * 24 * 7);
-      picker.$emit("pick", date);
-    },
-  },
-];
-export default {
-  name: "Percentage",
-  dicts: ["sys_normal_disable", "sys_user_sex"],
-  components: { Treeselect },
-  data() {
-    return {
-      topactiveName: "Local", //椤堕儴閫夋嫨
-      activeName: "first", //渚ц竟閫夋嫨
-      expands: [],
-      // 閬僵灞�
-      loading: false,
-      Seedloading: false,
-      chartDialogVisible: false,
-      pieChart: null,
-      barLineChart: null,
-      // 閫変腑鏁扮粍
-      ids: [],
-      // 闈炲崟涓鐢�
-      single: true,
-      // 闈炲涓鐢�
-      multiple: true,
-      // 鏄剧ず鎼滅储鏉′欢
-      showSearch: true,
-      idds: "", //鍒嗙被id
-      // 鎬绘潯鏁�
-      total: 0,
-      flatArrayhospit: [],
-      flatArraydept: [],
-      patienttotal: 0,
-      logsheetlist: [],
-      Statisticallist: [
-        {
-          label: "鐥呭尯缁熻",
-          value: 1,
-        },
-        {
-          label: "绉戝缁熻",
-          value: 2,
-        },
-      ],
-      patientqueryParams: {
-        pn: 1,
-        ps: 10,
-      },
-      topiclist: [
-        {
-          name: "鎮ㄧ殑韬綋搴峰鎯呭喌濡備綍",
-          number: 1,
-          type: 1,
-        },
-        {
-          name: "鎮ㄧ殑楗鎯呭喌濡備綍",
-          number: 2,
-          type: 2,
-        },
-        {
-          name: "鎮ㄧ殑鎭㈠鎯呭喌濡備綍",
-          number: 3,
-          type: 1,
-        },
-      ],
-      tableData: [
-        {
-          date: "濂�",
-          name: 12,
-          address: "50%",
-        },
-        {
-          date: "涓�鑸�",
-          name: 2,
-          address: "6.2%",
-        },
-        {
-          date: "宸�",
-          name: 0,
-          address: "0%",
-        },
-      ],
-      amendtag: false, //鏄惁淇敼绫诲埆
-      lstamendtag: false, //鏄惁淇敼鏍囩
-      scavisible: false, //鍒犻櫎寮规
-      deleteVisible: false, //鍒嗙被鍒犻櫎寮规
-      deletefenl: "楂樿鍘�", //鍒犻櫎椤�
-      //淇敼娣诲姞鏍囩寮规鏁版嵁
-      tagform: {
-        isupload: "",
-        tagname: "",
-        tagcategoryid: "",
-        tagdescription: "",
-      },
-      classifyform: {
-        categoryname: "",
-      },
-      // 鏍囩琛ㄦ牸鏁版嵁
-      userList: [],
-      // 寮瑰嚭灞傛爣棰�
-      title: "",
-      // 鏄惁鏄剧ず寮瑰嚭灞�
-      open: false,
-      // 鏃ユ湡鑼冨洿
-      dateRange: [],
-      // 宀椾綅閫夐」
-      postOptions: [],
-      // 瑙掕壊閫夐」
-      roleOptions: [],
-      // 瀛樺偍鎵�鏈夌瀹や唬鐮�
-      allDeptCodes: [],
-      // 瀛樺偍鎵�鏈夌梾鍖轰唬鐮�
-      allWardCodes: [],
-      // 琛ㄥ崟鍙傛暟
-      form: {},
-      forms: {
-        name: "",
-      },
-      numberlb: 22,
-      dialogFormVisible: false, //娣诲姞銆佷慨鏀圭被鍒脊妗�
-      lstamendtagVisible: false, //娣诲姞銆佷慨鏀规爣绛惧脊妗�
-      goQRCodeVisible: false, //浜岀淮鐮佸脊妗�
-      topicVisible: false, //鎺у埗鍗曢寮规
-      topicvalue: {
-        name: "楠ㄧ闅忚妯℃澘",
-        number: 222,
-      },
-      sidecolumnval: "", //绫诲埆鎼滅储
-      propss: { multiple: true },
-      SeedetailsVisible: false,
-      options: store.getters.tasktypes,
-      pickerOptions: {
-        disabledDate(time) {
-          return time.getTime() < Date.now() - 3600 * 1000 * 24;
-        },
-        shortcuts: shortcuts,
-      },
-      pickerOptionsa: {
-        disabledDate(time) {
-          return time.getTime() > Date.now();
-        },
-        shortcuts: shortcuts,
-      },
-      // 鏌ヨ鏍囩鍒楄〃鍙傛暟
-      queryParams: {
-        serviceType: [2],
-        dateRange: [],
-        statisticaltype: 1,
-        leavehospitaldistrictcodes: ["all"], // 榛樿閫変腑鍏ㄩ儴鐥呭尯
-        deptcodes: [], // 榛樿閫変腑鍏ㄩ儴绉戝
-      },
-      // 鍒椾俊鎭�
-      columns: [
-        { key: 0, label: `鏍囩缂栧彿`, visible: true },
-        { key: 1, label: `鏍囩鍚嶇О`, visible: true },
-        { key: 2, label: `鏍囩鏄电О`, visible: true },
-        { key: 3, label: `閮ㄩ棬`, visible: true },
-        { key: 4, label: `鎵嬫満鍙风爜`, visible: true },
-        { key: 5, label: `鐘舵�乣, visible: true },
-        { key: 6, label: `鍒涘缓鏃堕棿`, visible: true },
-      ],
-    };
-  },
-  watch: {},
-  created() {
-    this.getDeptTree();
-    this.getList();
-  },
-
-  methods: {
-    /** 鏌ヨ鏍囩鍒楄〃 */
-    getList() {
-      // 澶勭悊鏌ヨ鍙傛暟
-      const params = {
-        configKey: "joyCount",
-        ...this.queryParams,
-        // 濡傛灉閫夋嫨浜�"鍏ㄩ儴"锛屽垯浼犳墍鏈夌梾鍖�/绉戝浠g爜
-        leavehospitaldistrictcodes:
-          this.queryParams.leavehospitaldistrictcodes.includes("all")
-            ? this.allWardCodes
-            : this.queryParams.leavehospitaldistrictcodes,
-        deptcodes: this.queryParams.deptcodes.includes("all")
-          ? this.allDeptCodes
-          : this.queryParams.deptcodes,
-      };
-      this.loading = true;
-
-      // 绉婚櫎鍙兘瀛樺湪鐨�"all"鍊�
-      delete params.leavehospitaldistrictcodes.all;
-      delete params.deptcodes.all;
-      getSfStatisticsJoy(params).then((response) => {
-        this.loading = false;
-
-        this.total = response.total;
-        this.userList = response.data;
-      });
-    },
-    getRowKey(row) {
-      return row.statisticaltype === 1
-        ? row.leavehospitaldistrictcode
-        : row.deptcode;
-    },
-    /** 淇敼鏍囩 */
-    handleUpdate(row) {
-      console.log(row, "淇敼鏍囩");
-      this.lstamendtagVisible = true;
-      this.lstamendtag = true;
-      this.tagform = {
-        isupload: row.isupload,
-        tagname: row.tagname,
-        tagcategoryid: row.tagcategoryid,
-        tagdescription: row.tagdescription,
-        tagid: row.tagid,
-      };
-    },
-    // 鑾峰彇绉戝鏍�
-    getDeptTree() {
-      // 绉戝鍒楄〃
-      this.flatArraydept = store.getters.belongDepts.map((dept) => {
-        return {
-          label: dept.deptName,
-          value: dept.deptCode,
-        };
-      });
-      // 瀛樺偍鎵�鏈夌瀹や唬鐮�
-      this.allDeptCodes = store.getters.belongDepts.map(
-        (dept) => dept.deptCode
-      );
-
-      // 鐥呭尯鍒楄〃
-      this.flatArrayhospit = store.getters.belongWards.map((ward) => {
-        return {
-          label: ward.districtName,
-          value: ward.districtCode,
-        };
-      });
-
-      // 瀛樺偍鎵�鏈夌梾鍖轰唬鐮�
-      this.allWardCodes = store.getters.belongWards.map(
-        (ward) => ward.districtCode
-      );
-      this.flatArraydept.push({ label: "鍏ㄩ儴", value: "all" });
-      this.flatArrayhospit.push({ label: "鍏ㄩ儴", value: "all" });
-    },
-    flattenArray(multiArray) {
-      let result = [];
-
-      // 閫掑綊鍑芥暟锛岀敤浜庡皢澶氱骇鏁扮粍杞崲涓轰竴缁存暟缁勶紝鍙寘鍚渶搴曞眰鐨勫厓绱�
-      function flatten(element) {
-        // 濡傛灉褰撳墠鍏冪礌鏈夊瓙鍏冪礌锛岀户缁�掑綊
-        if (element.children && element.children.length > 0) {
-          element.children.forEach((child) => flatten(child));
-        } else {
-          // 鍏嬮殕鍏冪礌浠ラ伩鍏嶄慨鏀瑰師濮嬫暟鎹�
-          let item = JSON.parse(JSON.stringify(element));
-          result.push(item); // 灏嗘渶搴曞眰鐨勫厓绱犳坊鍔犲埌缁撴灉鏁扮粍
-        }
-      }
-
-      // 浠庨《灞傚厓绱犲紑濮嬮�掑綊
-      multiArray.forEach((element) => flatten(element));
-      return result; // 杩斿洖鍙寘鍚渶搴曞眰鍏冪礌鐨勪竴缁存暟缁�
-    },
-    addladeltag() {
-      this.lstamendtagVisible = true;
-      this.lstamendtag = false;
-      this.tagform = {
-        isupload: "",
-        tagname: "",
-        tagcategoryid: "",
-        tagdescription: "",
-        tagid: "",
-      };
-    },
-    Seedetails(row) {
-      this.SeedetailsVisible = true;
-      this.Seedloading = true;
-      this.patientqueryParams.starttime = this.parseTime(
-        this.queryParams.dateRange[0]
-      );
-      this.patientqueryParams.endtime = this.parseTime(
-        this.queryParams.dateRange[1]
-      );
-      this.patientqueryParams.deptcode = row.deptcode;
-      selectTimelyRate(this.patientqueryParams).then((response) => {
-        this.logsheetlist = response.data.detail;
-        this.patienttotal = response.data.total;
-        this.Seedloading = false;
-      });
-    },
-    SeedetailsgGo(row) {
-      this.SeedetailsVisible = false;
-      let type = "";
-      if (row.preachformson && row.preachformson.includes("3")) {
-        type = 1;
-      }
-      setTimeout(() => {
-        this.$router.push({
-          path: "/followvisit/record/detailpage/",
-          query: {
-            taskid: row.taskid,
-            patid: row.patid,
-            id: row.id,
-            Voicetype: type,
-            // visitCount: this.topqueryParams.visitCount,
-          },
-        });
-      }, 300);
-    },
-    // 璋冭捣璇︽儏
-    getinfo(row) {
-      this.topicVisible = true;
-      // 澶勭悊鏌ヨ鍙傛暟
-      const params = {
-        configKey: "joyCount",
-        ...this.queryParams,
-      };
-      if (this.queryParams.statisticaltype == 1) {
-        this.topicvalue.name = row.leavehospitaldistrictname;
-
-        params.leavehospitaldistrictcodes = [row.leavehospitaldistrictcode];
-      } else {
-        this.topicvalue.name = row.deptname;
-
-        params.deptcodes = [row.deptcode];
-      }
-
-      // 绉婚櫎鍙兘瀛樺湪鐨�"all"鍊�
-      delete params.leavehospitaldistrictcodes.all;
-      delete params.deptcodes.all;
-      getSfStatisticsJoyInfo(params).then((response) => {
-        console.log(response);
-        this.topiclist = response.data;
-      });
-    },
-    // 娣诲姞/淇敼鏍囩
-    Maintenancetag() {
-      if (this.lstamendtag) {
-        toamendtag(this.addDateRange(this.tagform)).then((response) => {
-          console.log(response);
-          this.getList();
-        });
-      } else {
-        addapitag(this.addDateRange(this.tagform)).then((response) => {
-          console.log(response);
-          this.getList();
-        });
-      }
-      this.tagform = {
-        isupload: "",
-        tagname: "",
-        tagcategoryid: "",
-        tagdescription: "",
-        tagid: "",
-      };
-    },
-    routerErr(row) {
-      console.log(row, "璺宠浆寮傚父");
-      this.$router.push({
-        path: "/followvisit/discharge",
-        query: {
-          errtype: 1,
-          leavehospitaldistrictcode: row.leavehospitaldistrictcode,
-        },
-      });
-    },
-
-    // 琛ㄥ崟閲嶇疆
-    reset() {
-      this.form = {
-        userId: undefined,
-        deptId: undefined,
-        userName: undefined,
-        nickName: undefined,
-        password: undefined,
-        phonenumber: undefined,
-        email: undefined,
-        sex: undefined,
-        status: "0",
-        remark: undefined,
-        postIds: [],
-        roleIds: [],
-      };
-      this.resetForm("form");
-    },
-    // 鏍囩鐘舵�佷慨鏀�
-    handleStatusChange(row) {
-      console.log(row.isupload);
-      let text = row.isupload === "0" ? "鍚敤" : "鍋滅敤";
-      this.$modal
-        .confirm('纭瑕�"' + text + '""' + row.tagname + '"鏍囩鍚楋紵')
-        .then(function () {
-          return changetagcategory(row.tagid, row.isupload);
-        })
-        .then(() => {
-          this.$modal.msgSuccess(text + "鎴愬姛");
-        })
-        .catch(function () {
-          row.isupload = row.isupload === "0" ? "1" : "0";
-        });
-    },
-    /** 鎼滅储鎸夐挳鎿嶄綔 */
-    handleQuery() {
-      this.queryParams.pageNum = 1;
-      if (!this.queryParams.dateRange) this.queryParams.dateRange = [];
-      if (this.queryParams.statisticaltype == 1) {
-        this.queryParams.deptcodes = [];
-      } else if (this.queryParams.statisticaltype == 2) {
-        this.queryParams.leavehospitaldistrictcodes = [];
-      }
-      console.log(this.queryParams.dateRange);
-
-      this.queryParams.startTime = this.parseTime(
-        this.queryParams.dateRange[0]
-      );
-      this.queryParams.endTime = this.parseTime(this.queryParams.dateRange[1]);
-      this.getList();
-    },
-    /** 閲嶇疆鎸夐挳鎿嶄綔 */
-    resetQuery() {
-      this.queryParams.dateRange = [];
-      this.queryParams.leavehospitaldistrictcodes = [];
-      this.handleQuery();
-    },
-    // 澶氶�夋閫変腑鏁版嵁
-    handleSelectionChange(selection) {
-      this.ids = selection.map((item) => item.tagid);
-      this.single = selection.length != 1;
-      this.multiple = !selection.length;
-    },
-
-    /** 鍒犻櫎鎸夐挳鎿嶄綔 */
-    handleDelete(row) {
-      console.log(row, "鍒犻櫎寮圭獥");
-      const tagids = row.tagid || this.ids;
-      console.log(tagids);
-      const tagname = row.tagname;
-      this.$modal
-        .confirm(
-          tagname
-            ? '鏄惁纭鍒犻櫎鏍囩鍚嶇О涓�"' + tagname + '"鐨勬暟鎹」锛�'
-            : "鏄惁纭鍒犻櫎閫変腑鐨勬暟鎹」锛�"
-        )
-        .then(function () {
-          return deletetag(tagids);
-        })
-        .then(() => {
-          this.getList();
-          this.$modal.msgSuccess("鍒犻櫎鎴愬姛");
-        })
-        .catch(() => {});
-    },
-    /** 瀵煎嚭鎸夐挳鎿嶄綔 */
-    /** 瀵煎嚭鎸夐挳鎿嶄綔 */
-    async handleExport() {
-      try {
-        // 鑾峰彇骞舵牸寮忓寲鏃ユ湡鑼冨洿
-        let dateRangeString = "";
-        let sheetNameSuffix = "";
-
-        // 妫�鏌ユ槸鍚﹀瓨鍦ㄩ�変腑鐨勬棩鏈熻寖鍥�
-        if (
-          this.queryParams.dateRange &&
-          this.queryParams.dateRange.length === 2
-        ) {
-          const startDateStr = this.queryParams.dateRange[0]; // 寮�濮嬫棩鏈燂紝鏍煎紡 "yyyy-MM-dd"
-          const endDateStr = this.queryParams.dateRange[1]; // 缁撴潫鏃ユ湡
-
-          // 鐩存帴浣跨敤鏃ユ湡閮ㄥ垎锛堝凡缁忔槸 yyyy-MM-dd 鏍煎紡锛�
-          const startDateFormatted = startDateStr;
-          const endDateFormatted = endDateStr;
-
-          // 鏋勫缓鏃ユ湡鑼冨洿瀛楃涓�
-          dateRangeString = `${startDateFormatted}鑷�${endDateFormatted}`;
-          sheetNameSuffix = `${startDateFormatted}鑷�${endDateFormatted}`;
-        } else {
-          // 濡傛灉娌℃湁閫夋嫨鏃ユ湡鑼冨洿锛屽垯浣跨敤褰撳墠鏈堜唤浣滀负澶囬�夋柟妗�
-          const now = new Date();
-          const currentMonth = now.getMonth() + 1;
-          dateRangeString = `${currentMonth}鏈坄;
-          sheetNameSuffix = `${currentMonth}鏈坄;
-        }
-
-        // 鏋勫缓鏂囦欢鍚嶅拰宸ヤ綔琛ㄥ悕
-        const excelName = `婊℃剰搴︾粺璁¤〃_${dateRangeString}.xlsx`;
-        const worksheetName = `婊℃剰搴︾粺璁${sheetNameSuffix}`;
-
-        // 鍒涘缓宸ヤ綔绨垮拰宸ヤ綔琛�
-        const workbook = new ExcelJS.Workbook();
-        const worksheet = workbook.addWorksheet(worksheetName);
-
-        // 瀹氫箟鏍峰紡
-        const titleStyle = {
-          font: {
-            name: "寰蒋闆呴粦",
-            size: 16,
-            bold: true,
-            color: { argb: "FF000000" },
-          },
-          fill: {
-            type: "pattern",
-            pattern: "solid",
-            fgColor: { argb: "FFE6F3FF" },
-          },
-          alignment: {
-            vertical: "middle",
-            horizontal: "center",
-            wrapText: true,
-          },
-          border: {
-            top: { style: "thin", color: { argb: "FFD0D0D0" } },
-            left: { style: "thin", color: { argb: "FFD0D0D0" } },
-            bottom: { style: "thin", color: { argb: "FFD0D0D0" } },
-            right: { style: "thin", color: { argb: "FFD0D0D0" } },
-          },
-        };
-
-        const headerStyle = {
-          font: {
-            name: "寰蒋闆呴粦",
-            size: 11,
-            bold: true,
-            color: { argb: "FF000000" },
-          },
-          fill: {
-            type: "pattern",
-            pattern: "solid",
-            fgColor: { argb: "FFF5F7FA" },
-          },
-          alignment: {
-            vertical: "middle",
-            horizontal: "center",
-            wrapText: true,
-          },
-          border: {
-            top: { style: "thin", color: { argb: "FFD0D0D0" } },
-            left: { style: "thin", color: { argb: "FFD0D0D0" } },
-            bottom: { style: "thin", color: { argb: "FFD0D0D0" } },
-            right: { style: "thin", color: { argb: "FFD0D0D0" } },
-          },
-        };
-
-        const cellStyle = {
-          font: {
-            name: "瀹嬩綋",
-            size: 10,
-            color: { argb: "FF000000" },
-          },
-          alignment: {
-            vertical: "middle",
-            horizontal: "center",
-          },
-          border: {
-            top: { style: "thin", color: { argb: "FFD0D0D0" } },
-            left: { style: "thin", color: { argb: "FFD0D0D0" } },
-            bottom: { style: "thin", color: { argb: "FFD0D0D0" } },
-            right: { style: "thin", color: { argb: "FFD0D0D0" } },
-          },
-        };
-
-        // 娣诲姞鎬绘爣棰�
-        worksheet.mergeCells(1, 1, 1, 10);
-        const titleCell = worksheet.getCell(1, 1);
-        titleCell.value = `婊℃剰搴︾粺璁¤〃锛�${sheetNameSuffix}锛塦;
-        titleCell.style = titleStyle;
-        worksheet.getRow(1).height = 35;
-
-        // 娣诲姞琛ㄥご
-        const headers = [
-          "鍑洪櫌鐥呭尯",
-          "绉戝",
-          "鍑洪櫌浜烘",
-          "鏃犻渶闅忚浜烘",
-          "搴旈殢璁夸汉娆�",
-          "闅忚鐜�",
-          "鍙婃椂鐜�",
-          "婊℃剰搴﹂鐩�婚噺",
-          "婊℃剰搴﹀~鎶ラ噺",
-          "瀹屾垚姣旂巼",
-        ];
-
-        const headerRow = worksheet.addRow(headers);
-        headerRow.eachCell((cell) => {
-          cell.style = headerStyle;
-        });
-        headerRow.height = 25;
-
-        // 娣诲姞鏁版嵁琛�
-        this.userList.forEach((item) => {
-          const dataRow = worksheet.addRow([
-            item.leavehospitaldistrictname || "",
-            item.deptname || "",
-            item.dischargeCount || 0,
-            item.nonFollowUp || 0,
-            item.followUpNeeded || 0,
-            item.followUpRate || "0%",
-            item.rate ? (Number(item.rate) * 100).toFixed(2) + "%" : "0%",
-            item.joyAllCount || 0,
-            item.joyCount || 0,
-            item.joyTotal
-              ? (Number(item.joyTotal) * 100).toFixed(2) + "%"
-              : "0%",
-          ]);
-
-          dataRow.eachCell((cell) => {
-            cell.style = cellStyle;
-          });
-          dataRow.height = 22;
-        });
-
-        // 璁剧疆鍒楀
-        worksheet.columns = [
-          { width: 20 }, // 鍑洪櫌鐥呭尯
-          { width: 15 }, // 绉戝
-          { width: 12 }, // 鍑洪櫌浜烘
-          { width: 12 }, // 鏃犻渶闅忚浜烘
-          { width: 12 }, // 搴旈殢璁夸汉娆�
-          { width: 12 }, // 闅忚鐜�
-          { width: 12 }, // 鍙婃椂鐜�
-          { width: 15 }, // 婊℃剰搴﹂鐩�婚噺
-          { width: 15 }, // 婊℃剰搴﹀~鎶ラ噺
-          { width: 12 }, // 瀹屾垚姣旂巼
-        ];
-
-        // 鐢熸垚骞朵笅杞芥枃浠�
-        const buffer = await workbook.xlsx.writeBuffer();
-        const blob = new Blob([buffer], {
-          type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
-        });
-
-        // 浣跨敤FileSaver.js淇濆瓨鏂囦欢[2,3](@ref)
-        saveAs(blob, excelName);
-
-        this.$message.success("瀵煎嚭鎴愬姛");
-      } catch (error) {
-        console.error("瀵煎嚭澶辫触:", error);
-        this.$message.error(`瀵煎嚭澶辫触: ${error.message}`);
-      }
-    },
-    // 鏄剧ず鍥捐〃寮圭獥
-
-    showChartDialog() {
-      this.chartDialogVisible = true;
-      this.$nextTick(() => {
-        this.initPieChart();
-        this.initBarLineChart();
-      });
-    },
-    // 鍦╩ethods涓慨鏀圭粺璁℃柟娉�
-    showChartDialog() {
-      this.chartDialogVisible = true;
-      this.$nextTick(() => {
-        console.log(this.userList, "this.userList");
-
-        this.initCharts();
-      });
-    },
-
-    // 鏂板鍒濆鍖栧浘琛ㄦ柟娉�
-    initCharts() {
-      this.initPieChart();
-      this.initBarLineChart();
-    },
-
-    // 鍒濆鍖栭ゼ鍥�
-    initPieChart() {
-      const echarts = require("echarts");
-      const pieDom = document.getElementById("pieChart");
-      if (!pieDom) return;
-
-      if (this.pieChart) {
-        this.pieChart.dispose();
-      }
-
-      this.pieChart = echarts.init(pieDom);
-
-      // 璁$畻楗煎浘鏁版嵁
-      const followUpData = {
-        pending: 0,
-        success: 0,
-        fail: 0,
-      };
-
-      this.userList.forEach((item) => {
-        followUpData.pending += item.pendingFollowUp || 0;
-        followUpData.success += item.followUpSuccess || 0;
-        followUpData.fail += item.followUpFail || 0;
-      });
-
-      // 浣跨敤鏇寸編瑙傜殑棰滆壊鏂规
-      const pieOption = {
-        title: {
-          text: "闅忚鐘舵�佸垎甯�",
-          left: "center",
-          textStyle: {
-            color: "#333",
-            fontSize: 16,
-          },
-        },
-        tooltip: {
-          trigger: "item",
-          formatter: "{a} <br/>{b}: {c} ({d}%)",
-        },
-        legend: {
-          orient: "vertical",
-          left: "left",
-          data: ["寰呴殢璁�", "闅忚鎴愬姛", "闅忚澶辫触"],
-          textStyle: {
-            color: "#666",
-          },
-        },
-        color: ["#FF9D4D", "#36B37E", "#FF5C5C"], // 鏂扮殑閰嶈壊鏂规
-        series: [
-          {
-            name: "闅忚鐘舵��",
-            type: "pie",
-            radius: ["40%", "70%"],
-            avoidLabelOverlap: true,
-            itemStyle: {
-              borderRadius: 10,
-              borderColor: "#fff",
-              borderWidth: 2,
-            },
-            label: {
-              show: true,
-              formatter: "{b}: {c} ({d}%)",
-              color: "#333",
-            },
-            emphasis: {
-              label: {
-                show: true,
-                fontSize: "18",
-                fontWeight: "bold",
-              },
-              itemStyle: {
-                shadowBlur: 10,
-                shadowOffsetX: 0,
-                shadowColor: "rgba(0, 0, 0, 0.5)",
-              },
-            },
-            data: [
-              {
-                value: followUpData.pending,
-                name: "寰呴殢璁�",
-              },
-              {
-                value: followUpData.success,
-                name: "闅忚鎴愬姛",
-              },
-              {
-                value: followUpData.fail,
-                name: "闅忚澶辫触",
-              },
-            ],
-          },
-        ],
-      };
-
-      this.pieChart.setOption(pieOption);
-      window.addEventListener("resize", this.resizePieChart);
-    },
-
-    // 鍒濆鍖栨煴鐘舵姌绾垮浘
-    initBarLineChart() {
-      const echarts = require("echarts");
-      const barDom = document.getElementById("barLineChart");
-      if (!barDom) return;
-
-      if (this.barLineChart) {
-        this.barLineChart.dispose();
-      }
-
-      this.barLineChart = echarts.init(barDom);
-
-      // 鍑嗗鏁版嵁
-      const categories = this.userList.map(
-        (item) => item.leavehospitaldistrictname || item.deptname
-      );
-
-      const dischargeData = this.userList.map(
-        (item) => item.dischargeCount || 0
-      );
-      const followUpData = this.userList.map(
-        (item) => item.followUpNeeded || 0
-      );
-
-      // 鏂板涓ゆ潯鎶樼嚎鏁版嵁
-      const followUpRateData = this.userList.map((item) => {
-        if (!item.followUpRate) return 0;
-        // 鍘绘帀鐧惧垎鍙峰苟杞负鏁板瓧
-        const rateStr = String(item.followUpRate).replace("%", "");
-        return parseFloat(rateStr) || 0;
-      });
-
-      const timelyRateData = this.userList.map((item) =>
-        item.rate ? (Number(item.rate) * 100).toFixed(2) : 0
-      );
-
-      const option = {
-        title: {
-          text: "绉戝/鐥呭尯闅忚瓒嬪娍",
-          left: "center",
-          textStyle: {
-            color: "#333",
-            fontSize: 16,
-          },
-        },
-        tooltip: {
-          trigger: "axis",
-          axisPointer: {
-            type: "cross",
-            crossStyle: {
-              color: "#999",
-            },
-          },
-        },
-        legend: {
-          data: ["鍑洪櫌浜烘", "搴旈殢璁夸汉娆�", "闅忚鐜�(%)", "鍙婃椂鐜�(%)"],
-          top: "bottom",
-          textStyle: {
-            color: "#666",
-          },
-        },
-        color: ["#5470C6", "#91CC75", "#EE6666", "#9A60B4"], // 鏂板绱壊鐢ㄤ簬鍙婃椂鐜�
-        xAxis: {
-          type: "category",
-          data: categories,
-          axisLabel: {
-            interval: 0,
-            rotate: 30,
-            color: "#666",
-          },
-          axisLine: {
-            lineStyle: {
-              color: "#ddd",
-            },
-          },
-        },
-        yAxis: [
-          {
-            type: "value",
-            name: "浜烘",
-            min: 0,
-            axisLabel: {
-              color: "#666",
-            },
-            axisLine: {
-              lineStyle: {
-                color: "#ddd",
-              },
-            },
-            splitLine: {
-              lineStyle: {
-                color: "#f0f0f0",
-              },
-            },
-          },
-          {
-            type: "value",
-            name: "鐧惧垎姣�(%)",
-            min: 0,
-            max: 100,
-            axisLabel: {
-              color: "#666",
-              formatter: "{value}%",
-            },
-            axisLine: {
-              lineStyle: {
-                color: "#ddd",
-              },
-            },
-            splitLine: {
-              show: false,
-            },
-          },
-        ],
-        series: [
-          {
-            name: "鍑洪櫌浜烘",
-            type: "bar",
-            barWidth: "25%",
-            data: dischargeData,
-            itemStyle: {
-              borderRadius: [4, 4, 0, 0],
-            },
-          },
-          {
-            name: "搴旈殢璁夸汉娆�",
-            type: "bar",
-            barWidth: "25%",
-            data: followUpData,
-            itemStyle: {
-              borderRadius: [4, 4, 0, 0],
-            },
-          },
-          {
-            name: "闅忚鐜�(%)",
-            type: "line",
-            yAxisIndex: 1,
-            data: followUpRateData,
-            symbolSize: 8,
-            lineStyle: {
-              width: 3,
-            },
-            markLine: {
-              silent: true,
-              data: [
-                {
-                  yAxis: 80,
-                  lineStyle: {
-                    color: "#EE6666",
-                    type: "dashed",
-                  },
-                  // label: {
-                  //   position: 'end',
-                  //   formatter: '鐩爣80%'
-                  // }
-                },
-              ],
-            },
-          },
-          {
-            name: "鍙婃椂鐜�(%)",
-            type: "line",
-            yAxisIndex: 1,
-            data: timelyRateData,
-            symbolSize: 8,
-            lineStyle: {
-              width: 3,
-              type: "dotted", // 浣跨敤铏氱嚎鍖哄垎
-            },
-            markLine: {
-              silent: true,
-              data: [
-                {
-                  yAxis: 90,
-                  lineStyle: {
-                    color: "#9A60B4",
-                    type: "dashed",
-                  },
-                  // label: {
-                  //   position: 'end',
-                  //   formatter: '鐩爣90%'
-                  // }
-                },
-              ],
-            },
-          },
-        ],
-        grid: {
-          top: "15%",
-          left: "3%",
-          right: "4%",
-          bottom: "15%",
-          containLabel: true,
-        },
-      };
-
-      this.barLineChart.setOption(option);
-      window.addEventListener("resize", this.resizeBarLineChart);
-    },
-
-    // 鍥捐〃鍝嶅簲寮忚皟鏁存柟娉�
-    resizePieChart() {
-      if (this.pieChart) {
-        this.pieChart.resize();
-      }
-    },
-
-    resizeBarLineChart() {
-      if (this.barLineChart) {
-        this.barLineChart.resize();
-      }
-    },
-
-    // 鍦ㄧ粍浠堕攢姣佹椂娓呯悊
-    beforeDestroy() {
-      // 绉婚櫎浜嬩欢鐩戝惉
-      window.removeEventListener("resize", this.resizePieChart);
-      window.removeEventListener("resize", this.resizeBarLineChart);
-
-      // 閿�姣佸浘琛ㄥ疄渚�
-      if (this.pieChart) {
-        this.pieChart.dispose();
-        this.pieChart = null;
-      }
-      if (this.barLineChart) {
-        this.barLineChart.dispose();
-        this.barLineChart = null;
-      }
-    },
-  },
-};
-</script>
-
-<style lang="scss" scoped>
-.sidecolumn {
-  width: 180px;
-  min-height: 100vh;
-  text-align: center;
-  //   display: flex;
-  margin-top: 20px;
-  margin: 20px;
-  padding: 30px;
-  background: #edf1f7;
-  border: 1px solid #dcdfe6;
-  -webkit-box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.12),
-    0 0 6px 0 rgba(0, 0, 0, 0.04);
-  .sidecolumn-top {
-    display: flex;
-    justify-content: space-between;
-    .top-wj {
-      font-size: 20px;
-    }
-    .top-tj {
-      font-size: 18px;
-
-      color: rgb(0, 89, 255);
-      cursor: pointer;
-    }
-  }
-  .center-ss {
-    margin-top: 30px;
-    .input-with-select {
-      height: 40px !important;
-    }
-  }
-  .bottom-fl {
-    margin-top: 30px;
-    display: center !important;
-  }
-}
-.qrcode-dialo {
-  text-align: center;
-  //   display: flex;
-  margin: 20px;
-  padding: 30px;
-  background: #edf1f7;
-  border: 1px solid #dcdfe6;
-  -webkit-box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.12),
-    0 0 6px 0 rgba(0, 0, 0, 0.04);
-  .qrcode-text {
-    font-size: 20px;
-    span {
-      margin-left: 20px;
-    }
-  }
-  .qrcode-img {
-    width: 300px;
-    height: 400px;
-  }
-}
-.topicdia {
-  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
-    "Helvetica Neue", Arial, sans-serif;
-  color: #333; /* 涓绘枃瀛楄壊 */
-}
-
-/* 澶撮儴鏍囬鏍峰紡 */
-.top-text {
-  font-size: 18px;
-  font-weight: 600;
-  padding-bottom: 16px;
-  margin-bottom: 20px;
-  border-bottom: 1px solid #e8e8e8; /* 绾ょ粏鐨勫垎闅旂嚎 */
-  color: #1f2d3d; /* 娣辫壊鏍囬 */
-}
-.top-text span {
-  font-size: 14px;
-  font-weight: normal;
-  color: #666; /* 鍓爣棰橀鑹茬◢娴� */
-  margin-left: 10px;
-}
-
-/* 棰樼洰瀹瑰櫒鏍峰紡 */
-.ttaabbcc {
-  background: #fafafa; /* 闈炲父娴呯殑鐏拌壊鑳屾櫙 */
-  border-radius: 6px;
-  padding: 16px;
-  margin-bottom: 20px;
-  border-left: 4px solid #4794c5; /* 宸︿晶瑁呴グ鑹叉潯锛屽鍔犲眰娆℃劅 */
-}
-
-/* 棰樼洰鎻忚堪鏍峰紡 */
-.describe {
-  font-size: 15px;
-  line-height: 1.6;
-  margin-bottom: 12px;
-  color: #1f2d3d;
-}
-.describe span {
-  font-size: 13px;
-  color: #999; /* 棰樺瀷鎻愮ず淇℃伅棰滆壊鏇存祬 */
-  font-style: italic;
-  margin-left: 8px;
-}
-
-/* 琛ㄦ牸鏁翠綋鏍峰紡璋冩暣 */
-.ttaabbcc .el-table {
-  border-radius: 4px;
-  overflow: hidden;
-  font-size: 14px;
-}
-
-/* 琛ㄥご鏍峰紡 */
-.ttaabbcc .el-table th {
-  background-color: #f1f5f9; /* 娴呰摑鑹茶〃澶磋儗鏅� */
-  color: #333;
-  font-weight: 600;
-}
-
-/* 鍗曞厓鏍兼牱寮� */
-.ttaabbcc .el-table td {
-  border-bottom: 1px solid #f0f0f0; /* 绾ょ粏鐨勮鍒嗛殧绾� */
-  padding: 12px 0;
-}
-
-/* 姣斾緥鏁版嵁鏍峰紡 */
-.button-zx {
-  color: #4794c5; /* 浣跨敤涓庝富棰樺懠搴旂殑钃濊壊 */
-  font-weight: 500;
-}
-::v-deep.el-tabs--left,
-.el-tabs--right {
-  overflow: hidden;
-  align-items: center;
-  display: flex;
-}
-::v-deep.el-input--medium .el-input__inner {
-  height: 40px !important;
-}
-::v-deep.el-tabs--right .el-tabs__active-bar.is-right {
-  height: 40px;
-  width: 5px;
-  left: 0;
-}
-::v-deep.el-tabs--right .el-tabs__item.is-right {
-  display: block;
-  text-align: left;
-  font-size: 20px;
-}
-
-.leftvlue {
-  //   display: flex;
-  //   flex: 1;
-  // width: 80%;
-  // margin-top: 20px;
-  margin: 20px;
-  padding: 30px;
-  background: #ffff;
-  border: 1px solid #dcdfe6;
-  -webkit-box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.12),
-    0 0 6px 0 rgba(0, 0, 0, 0.04);
-  .mulsz {
-    font-size: 20px;
-  }
-}
-/* 浣胯鏈夋墜鍨嬫寚閽� */
-.el-table__row {
-  cursor: pointer;
-}
-/* 鍐呭眰鍖荤敓琛ㄦ牸鏍峰紡 */
-.inner-table {
-  // 琛ㄥご鑳屾櫙鑹�
-  ::v-deep .el-table__header-wrapper {
-    background-color: #f0f7ff !important;
-
-    th {
-      background-color: #f0f7ff !important;
-    }
-  }
-
-  // 琛ㄦ牸琛岃儗鏅壊
-  ::v-deep .el-table__body-wrapper {
-    tr {
-      background-color: #f9fbfe !important;
-
-      &:hover {
-        background-color: #e6f1ff !important;
-      }
-    }
-  }
-
-  // 杈规棰滆壊
-  ::v-deep .el-table--border {
-    border-color: #d9e8ff !important;
-
-    td,
-    th {
-      border-color: #d9e8ff !important;
-    }
-  }
-
-  // 鏂戦┈绾规晥鏋�
-  ::v-deep .el-table--striped .el-table__body tr.el-table__row--striped td {
-    background-color: #f5f9ff !important;
-  }
-}
-/* 灞曞紑琛屾牱寮� */
-.el-table__expanded-cell {
-  padding: 10px 0 !important;
-  background: #f8f8f8;
-}
-.document {
-  width: 100px;
-  height: 50px;
-}
-.documentf {
-  display: flex;
-  justify-content: flex-end;
-}
-.button-text {
-  color: rgb(70, 204, 238);
-}
-.button-textck {
-  color: rgb(39, 167, 67);
-}
-.button-textxg {
-  color: rgb(35, 81, 233);
-}
-.button-textsc {
-  color: rgb(235, 23, 23);
-}
-</style>
diff --git a/src/views/Satisfaction/sfstatistics/IndicatorStatistics.vue b/src/views/Satisfaction/sfstatistics/IndicatorStatistics.vue
new file mode 100644
index 0000000..53f5355
--- /dev/null
+++ b/src/views/Satisfaction/sfstatistics/IndicatorStatistics.vue
@@ -0,0 +1,66 @@
+<!-- StatisticsMain.vue -->
+<template>
+  <div class="statistics-main">
+    <el-tabs v-model="activeTab" @tab-click="handleTabChange">
+      <el-tab-pane label="婊℃剰搴︾粺璁�" name="followup">
+        <followup-statistics
+          v-if="activeTab === 'followup'"
+          ref="followupRef"
+        />
+      </el-tab-pane>
+      <el-tab-pane label="澶嶈瘖閫氱煡缁熻" name="visitStatistics">
+        <visit-Statistics
+          v-if="activeTab === 'visitStatistics'"
+          ref="visitStatisticsRef"
+        />
+      </el-tab-pane>
+
+    </el-tabs>
+  </div>
+</template>
+
+<script>
+import FollowupStatistics from "./components/FollowupStatistics.vue";
+import visitStatistics from "./components/visitStatistics.vue";
+import SatisfactionStatistics from "./components/SatisfactionStatistics.vue";
+
+export default {
+  name: "StatisticsMain",
+  components: {
+    FollowupStatistics,
+    SatisfactionStatistics,
+    visitStatistics,
+  },
+  data() {
+    return {
+      activeTab: "followup",
+    };
+  },
+  methods: {
+    handleTabChange(tab) {
+      console.log("鍒囨崲鍒�:", tab.name);
+    },
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+.statistics-main {
+  padding: 20px;
+  background: #fff;
+  min-height: calc(100vh - 84px);
+
+  ::v-deep .el-tabs__header {
+    margin-bottom: 20px;
+  }
+
+  ::v-deep .el-tabs__item {
+    font-size: 16px;
+    font-weight: 500;
+  }
+
+  ::v-deep .el-tabs__nav-wrap::after {
+    height: 1px;
+  }
+}
+</style>
diff --git a/src/views/Satisfaction/sfstatistics/components/FollowupStatistics.vue b/src/views/Satisfaction/sfstatistics/components/FollowupStatistics.vue
index 07f6c19..1b59b49 100644
--- a/src/views/Satisfaction/sfstatistics/components/FollowupStatistics.vue
+++ b/src/views/Satisfaction/sfstatistics/components/FollowupStatistics.vue
@@ -142,9 +142,11 @@
           v-if="queryParams.statisticaltype == 1"
           label="鍑洪櫌鐥呭尯"
           align="center"
+          sortable
           key="leavehospitaldistrictname"
           prop="leavehospitaldistrictname"
           :show-overflow-tooltip="true"
+          :sort-method="sortChineseNumber"
           min-width="120"
         />
 
@@ -191,7 +193,12 @@
           min-width="100"
         >
           <template slot-scope="scope">
-            <span v-if="scope.row.followUpRate !== null && scope.row.followUpRate !== undefined">
+            <span
+              v-if="
+                scope.row.followUpRate !== null &&
+                scope.row.followUpRate !== undefined
+              "
+            >
               {{ formatPercent(scope.row.followUpRate) }}
             </span>
             <span v-else>-</span>
@@ -241,24 +248,20 @@
           min-width="100"
         >
           <template slot-scope="scope">
-            <span v-if="scope.row.joyTotal !== null && scope.row.joyTotal !== undefined">
+            <span
+              v-if="
+                scope.row.joyTotal !== null && scope.row.joyTotal !== undefined
+              "
+            >
               {{ formatPercent(scope.row.joyTotal) }}
             </span>
             <span v-else>-</span>
           </template>
         </el-table-column>
 
-        <el-table-column
-          label="鎿嶄綔"
-          align="center"
-          fixed="right"
-          width="120"
-        >
+        <el-table-column label="鎿嶄綔" align="center" fixed="right" width="120">
           <template slot-scope="scope">
-            <el-button
-              type="text"
-              @click="getinfo(scope.row)"
-            >
+            <el-button type="text" @click="getinfo(scope.row)">
               <i class="el-icon-s-order" style="margin-right: 4px"></i>
               鏌ョ湅璇︽儏
             </el-button>
@@ -303,15 +306,21 @@
       :close-on-click-modal="false"
     >
       <template #title>
-        <div style="display: flex; align-items: center;">
-          <i class="el-icon-s-data" style="margin-right: 8px; color: #409EFF;"></i>
+        <div style="display: flex; align-items: center">
+          <i
+            class="el-icon-s-data"
+            style="margin-right: 8px; color: #409eff"
+          ></i>
           <span>{{ topicvalue.name }}</span>
-          <span style="margin-left: 10px; color: #666; font-size: 14px;">婊℃剰搴︽寚鏍囪鎯�</span>
+          <span style="margin-left: 10px; color: #666; font-size: 14px"
+            >婊℃剰搴︽寚鏍囪鎯�</span
+          >
         </div>
       </template>
       <topic-dialog
         v-if="topicVisible"
         :row-data="currentRow"
+        :topicList="topiclist"
         :query-params="queryParams"
         @close="topicVisible = false"
       />
@@ -320,35 +329,39 @@
 </template>
 
 <script>
-import { getSfStatisticsJoy, getSfStatisticsJoyInfo, selectTimelyRate } from "@/api/system/user";
+import {
+  getSfStatisticsJoy,
+  getSfStatisticsJoyInfo,
+  selectTimelyRate,
+} from "@/api/system/user";
 import ExcelJS from "exceljs";
 import { saveAs } from "file-saver";
-import SeedetailsDialog from './components/SeedetailsDialog.vue';
-import TopicDialog from './components/TopicDialog.vue';
+import SeedetailsDialog from "./components/SeedetailsDialog.vue";
+import TopicDialog from "./components/TopicDialog.vue";
 
 export default {
-  name: 'FollowupStatistics',
+  name: "FollowupStatistics",
   components: {
     SeedetailsDialog,
-    TopicDialog
+    TopicDialog,
   },
   data() {
     return {
       // 鏌ヨ鍙傛暟
       queryParams: {
         statisticaltype: 1,
-        leavehospitaldistrictcodes: [],
+        leavehospitaldistrictcodes: ["all"],
         deptcodes: [],
         serviceType: [2],
         dateRange: [],
         pageNum: 1,
-        pageSize: 20
+        pageSize: 20,
       },
 
       // 缁熻绫诲瀷鍒楄〃
       Statisticallist: [
         { label: "鐥呭尯缁熻", value: 1 },
-        { label: "绉戝缁熻", value: 2 }
+        { label: "绉戝缁熻", value: 2 },
       ],
 
       // 鐥呭尯鍒楄〃
@@ -384,44 +397,44 @@
       // 婊℃剰搴﹁鎯呮暟鎹�
       topiclist: [],
       topicvalue: {
-        name: ''
+        name: "",
       },
 
       // 鏃ユ湡閫夋嫨鍣ㄩ�夐」
       pickerOptions: {
         shortcuts: [
           {
-            text: '鏈�杩戜竴鍛�',
+            text: "鏈�杩戜竴鍛�",
             onClick(picker) {
               const end = new Date();
               const start = new Date();
               start.setTime(start.getTime() - 3600 * 1000 * 24 * 7);
-              picker.$emit('pick', [start, end]);
-            }
+              picker.$emit("pick", [start, end]);
+            },
           },
           {
-            text: '鏈�杩戜竴涓湀',
+            text: "鏈�杩戜竴涓湀",
             onClick(picker) {
               const end = new Date();
               const start = new Date();
               start.setTime(start.getTime() - 3600 * 1000 * 24 * 30);
-              picker.$emit('pick', [start, end]);
-            }
+              picker.$emit("pick", [start, end]);
+            },
           },
           {
-            text: '鏈�杩戜笁涓湀',
+            text: "鏈�杩戜笁涓湀",
             onClick(picker) {
               const end = new Date();
               const start = new Date();
               start.setTime(start.getTime() - 3600 * 1000 * 24 * 90);
-              picker.$emit('pick', [start, end]);
-            }
-          }
+              picker.$emit("pick", [start, end]);
+            },
+          },
         ],
         disabledDate(time) {
           return time.getTime() > Date.now();
-        }
-      }
+        },
+      },
     };
   },
 
@@ -442,20 +455,24 @@
       this.options = this.$store.getters.tasktypes || [];
 
       // 鑾峰彇绉戝鍒楄〃
-      this.flatArraydept = (this.$store.getters.belongDepts || []).map((dept) => {
-        return {
-          label: dept.deptName,
-          value: dept.deptCode
-        };
-      });
+      this.flatArraydept = (this.$store.getters.belongDepts || []).map(
+        (dept) => {
+          return {
+            label: dept.deptName,
+            value: dept.deptCode,
+          };
+        }
+      );
 
       // 鑾峰彇鐥呭尯鍒楄〃
-      this.flatArrayhospit = (this.$store.getters.belongWards || []).map((ward) => {
-        return {
-          label: ward.districtName,
-          value: ward.districtCode
-        };
-      });
+      this.flatArrayhospit = (this.$store.getters.belongWards || []).map(
+        (ward) => {
+          return {
+            label: ward.districtName,
+            value: ward.districtCode,
+          };
+        }
+      );
 
       // 娣诲姞鍏ㄩ儴閫夐」
       this.flatArraydept.push({ label: "鍏ㄩ儴", value: "all" });
@@ -469,11 +486,14 @@
         // 澶勭悊鏌ヨ鍙傛暟
         const params = {
           configKey: "joyCount",
-          ...this.queryParams
+          ...this.queryParams,
         };
 
         // 澶勭悊鏃ユ湡鑼冨洿
-        if (this.queryParams.dateRange && this.queryParams.dateRange.length === 2) {
+        if (
+          this.queryParams.dateRange &&
+          this.queryParams.dateRange.length === 2
+        ) {
           params.startTime = this.queryParams.dateRange[0];
           params.endTime = this.queryParams.dateRange[1];
         }
@@ -483,31 +503,215 @@
           // 鐥呭尯缁熻
           if (params.leavehospitaldistrictcodes.includes("all")) {
             // 濡傛灉閫夋嫨浜�"鍏ㄩ儴"锛屽垯绉婚櫎"all"鍊�
-            params.leavehospitaldistrictcodes = params.leavehospitaldistrictcodes.filter(item => item !== "all");
+            params.leavehospitaldistrictcodes =
+              params.leavehospitaldistrictcodes.filter(
+                (item) => item !== "all"
+              );
             // 濡傛灉闇�瑕佷紶鎵�鏈夌梾鍖轰唬鐮侊紝鍙互浠巗tore涓幏鍙�
-            params.leavehospitaldistrictcodes = (this.$store.getters.belongWards || []).map(ward => ward.districtCode);
+            params.leavehospitaldistrictcodes = (
+              this.$store.getters.belongWards || []
+            ).map((ward) => ward.districtCode);
           }
         } else if (params.statisticaltype == 2) {
           // 绉戝缁熻
           if (params.deptcodes.includes("all")) {
             // 濡傛灉閫夋嫨浜�"鍏ㄩ儴"锛屽垯绉婚櫎"all"鍊�
-            params.deptcodes = params.deptcodes.filter(item => item !== "all");
+            params.deptcodes = params.deptcodes.filter(
+              (item) => item !== "all"
+            );
             // 濡傛灉闇�瑕佷紶鎵�鏈夌瀹や唬鐮侊紝鍙互浠巗tore涓幏鍙�
-            params.deptcodes = (this.$store.getters.belongDepts || []).map(dept => dept.deptCode);
+            params.deptcodes = (this.$store.getters.belongDepts || []).map(
+              (dept) => dept.deptCode
+            );
           }
         }
 
         const response = await getSfStatisticsJoy(params);
-        this.userList = response.data || [];
+        this.userList = this.customSort(response.data) || [];
         this.total = response.total || 0;
       } catch (error) {
-        console.error('鑾峰彇缁熻鍒楄〃澶辫触:', error);
-        this.$message.error('鑾峰彇鏁版嵁澶辫触');
+        console.error("鑾峰彇缁熻鍒楄〃澶辫触:", error);
+        this.$message.error("鑾峰彇鏁版嵁澶辫触");
       } finally {
         this.loading = false;
       }
     },
+    sortChineseNumber(aRow, bRow) {
+      const a = aRow.leavehospitaldistrictname;
+      const b = bRow.leavehospitaldistrictname;
 
+      // 涓枃鏁板瓧鍒伴樋鎷変集鏁板瓧鐨勬槧灏勶紙鎵╁睍鍒�45锛�
+      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);
+
+      // 澶勭悊鏃犳硶瑙f瀽鐨勬儏鍐�
+      if (numA === -1 && numB === -1) {
+        return (a || "").localeCompare(b || "");
+      }
+      if (numA === -1) return 1;
+      if (numB === -1) return -1;
+
+      return numA - numB;
+    },
+    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; // 鍥犱负鏁扮粍绱㈠紩浠�0寮�濮�
+            }
+          }
+
+          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;
+      });
+    },
     // 澶勭悊缁熻绫诲瀷鍙樺寲
     handleStatisticalTypeChange(value) {
       if (value === 1) {
@@ -534,7 +738,7 @@
         serviceType: [2],
         dateRange: [],
         pageNum: 1,
-        pageSize: 20
+        pageSize: 20,
       };
       this.getList();
     },
@@ -554,7 +758,7 @@
 
     // 澶勭悊琛岄�夋嫨
     handleSelectionChange(selection) {
-      this.ids = selection.map(item => item.id);
+      this.ids = selection.map((item) => item.id);
       this.single = selection.length !== 1;
       this.multiple = !selection.length;
     },
@@ -568,9 +772,9 @@
 
     // 鏍煎紡鍖栫櫨鍒嗘瘮
     formatPercent(value) {
-      if (value === null || value === undefined) return '-';
+      if (value === null || value === undefined) return "-";
       const num = parseFloat(value);
-      if (isNaN(num)) return '-';
+      if (isNaN(num)) return "-";
       return `${(num * 100).toFixed(2)}%`;
     },
 
@@ -583,17 +787,19 @@
     // 鏌ョ湅婊℃剰搴﹁鎯�
     async getinfo(row) {
       this.currentRow = row;
-      this.topicVisible = true;
 
       try {
         // 澶勭悊鏌ヨ鍙傛暟
         const params = {
           configKey: "joyCount",
-          ...this.queryParams
+          ...this.queryParams,
         };
 
         // 澶勭悊鏃ユ湡鑼冨洿
-        if (this.queryParams.dateRange && this.queryParams.dateRange.length === 2) {
+        if (
+          this.queryParams.dateRange &&
+          this.queryParams.dateRange.length === 2
+        ) {
           params.startTime = this.queryParams.dateRange[0];
           params.endTime = this.queryParams.dateRange[1];
         }
@@ -608,16 +814,18 @@
 
         const response = await getSfStatisticsJoyInfo(params);
         this.topiclist = response.data || [];
+      this.topicVisible = true;
+
       } catch (error) {
-        console.error('鑾峰彇婊℃剰搴﹁鎯呭け璐�:', error);
-        this.$message.error('鑾峰彇璇︽儏澶辫触');
+        console.error("鑾峰彇婊℃剰搴﹁鎯呭け璐�:", error);
+        this.$message.error("鑾峰彇璇︽儏澶辫触");
       }
     },
 
     // 瀵煎嚭鏁版嵁
     async handleExport() {
       if (!this.userList.length) {
-        this.$message.warning('娌℃湁鏁版嵁鍙鍑�');
+        this.$message.warning("娌℃湁鏁版嵁鍙鍑�");
         return;
       }
 
@@ -628,7 +836,10 @@
         let dateRangeString = "";
         let sheetNameSuffix = "";
 
-        if (this.queryParams.dateRange && this.queryParams.dateRange.length === 2) {
+        if (
+          this.queryParams.dateRange &&
+          this.queryParams.dateRange.length === 2
+        ) {
           const startDateFormatted = this.queryParams.dateRange[0];
           const endDateFormatted = this.queryParams.dateRange[1];
           dateRangeString = `${startDateFormatted}鑷�${endDateFormatted}`;
@@ -650,26 +861,34 @@
         // 瀹氫箟鏍峰紡
         const titleStyle = {
           font: { name: "寰蒋闆呴粦", size: 16, bold: true },
-          fill: { type: "pattern", pattern: "solid", fgColor: { argb: "FFE6F3FF" } },
+          fill: {
+            type: "pattern",
+            pattern: "solid",
+            fgColor: { argb: "FFE6F3FF" },
+          },
           alignment: { vertical: "middle", horizontal: "center" },
           border: {
             top: { style: "thin", color: { argb: "FFD0D0D0" } },
             left: { style: "thin", color: { argb: "FFD0D0D0" } },
             bottom: { style: "thin", color: { argb: "FFD0D0D0" } },
-            right: { style: "thin", color: { argb: "FFD0D0D0" } }
-          }
+            right: { style: "thin", color: { argb: "FFD0D0D0" } },
+          },
         };
 
         const headerStyle = {
           font: { name: "寰蒋闆呴粦", size: 11, bold: true },
-          fill: { type: "pattern", pattern: "solid", fgColor: { argb: "FFF5F7FA" } },
+          fill: {
+            type: "pattern",
+            pattern: "solid",
+            fgColor: { argb: "FFF5F7FA" },
+          },
           alignment: { vertical: "middle", horizontal: "center" },
           border: {
             top: { style: "thin", color: { argb: "FFD0D0D0" } },
             left: { style: "thin", color: { argb: "FFD0D0D0" } },
             bottom: { style: "thin", color: { argb: "FFD0D0D0" } },
-            right: { style: "thin", color: { argb: "FFD0D0D0" } }
-          }
+            right: { style: "thin", color: { argb: "FFD0D0D0" } },
+          },
         };
 
         const cellStyle = {
@@ -679,8 +898,8 @@
             top: { style: "thin", color: { argb: "FFD0D0D0" } },
             left: { style: "thin", color: { argb: "FFD0D0D0" } },
             bottom: { style: "thin", color: { argb: "FFD0D0D0" } },
-            right: { style: "thin", color: { argb: "FFD0D0D0" } }
-          }
+            right: { style: "thin", color: { argb: "FFD0D0D0" } },
+          },
         };
 
         // 娣诲姞鎬绘爣棰�
@@ -700,7 +919,7 @@
           "鍙婃椂鐜�",
           "婊℃剰搴﹂鐩�婚噺",
           "婊℃剰搴﹀~鎶ラ噺",
-          "瀹屾垚姣旂巼"
+          "瀹屾垚姣旂巼",
         ];
 
         const headerRow = worksheet.addRow(headers);
@@ -712,7 +931,9 @@
         // 娣诲姞鏁版嵁琛�
         this.userList.forEach((item) => {
           const dataRow = worksheet.addRow([
-            this.queryParams.statisticaltype == 1 ? item.leavehospitaldistrictname : item.deptname,
+            this.queryParams.statisticaltype == 1
+              ? item.leavehospitaldistrictname
+              : item.deptname,
             item.dischargeCount || 0,
             item.nonFollowUp || 0,
             item.followUpNeeded || 0,
@@ -720,7 +941,7 @@
             item.rate ? this.formatPercent(item.rate) : "0%",
             item.joyAllCount || 0,
             item.joyCount || 0,
-            item.joyTotal ? this.formatPercent(item.joyTotal) : "0%"
+            item.joyTotal ? this.formatPercent(item.joyTotal) : "0%",
           ]);
 
           dataRow.eachCell((cell) => {
@@ -739,13 +960,13 @@
           { width: 12 },
           { width: 15 },
           { width: 15 },
-          { width: 12 }
+          { width: 12 },
         ];
 
         // 鐢熸垚骞朵笅杞芥枃浠�
         const buffer = await workbook.xlsx.writeBuffer();
         const blob = new Blob([buffer], {
-          type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
+          type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
         });
 
         saveAs(blob, excelName);
@@ -756,8 +977,8 @@
       } finally {
         this.loading = false;
       }
-    }
-  }
+    },
+  },
 };
 </script>
 
diff --git a/src/views/Satisfaction/sfstatistics/components/components/TopicDialog.vue b/src/views/Satisfaction/sfstatistics/components/components/TopicDialog.vue
index c0f9faf..46e59de 100644
--- a/src/views/Satisfaction/sfstatistics/components/components/TopicDialog.vue
+++ b/src/views/Satisfaction/sfstatistics/components/components/TopicDialog.vue
@@ -2,13 +2,14 @@
   <div class="topic-dialog">
     <div class="topicdia">
       <div style="overflow-x: hidden; overflow-y: auto; max-height: 65vh">
+        <!-- 淇敼杩欓噷锛氫娇鐢� processedTopicList 鑰屼笉鏄� topicList -->
         <div
-          v-for="(item, index) in topiclist"
-          :key="index"
+          v-for="(item, index) in processedTopicList"
+          :key="item.scriptid"
           class="ttaabbcc"
         >
           <div class="describe">
-            绗瑊{ index + 1 }}棰橈細 {{ item.scriptContent }}?
+            绗瑊{ index + 1 }}棰橈細 {{ item.scriptContent }}
             <span>[{{ item.scriptType == 1 ? "鍗曢�夐" : "澶氶�夐" }}]</span>
           </div>
           <div>
@@ -24,7 +25,11 @@
                 label="閫夋嫨浜烘暟"
                 align="center"
                 min-width="120"
-              />
+              >
+                <template slot-scope="{ row }">
+                  {{ row.chosenQuantity || 0 }}
+                </template>
+              </el-table-column>
               <el-table-column
                 prop="chosenPercentage"
                 label="姣斾緥"
@@ -32,8 +37,13 @@
                 min-width="120"
               >
                 <template slot-scope="{ row }">
-                  <span v-if="row.chosenPercentage !== null && row.chosenPercentage !== undefined">
-                    {{ formatPercent(row.chosenPercentage) }}
+                  <span
+                    v-if="
+                      row.chosenPercentage !== null &&
+                      row.chosenPercentage !== undefined
+                    "
+                  >
+                    {{ (Number(row.chosenPercentage) * 100).toFixed(2) }}%
                   </span>
                   <span v-else>-</span>
                 </template>
@@ -44,7 +54,20 @@
       </div>
     </div>
 
-    <div slot="footer" class="dialog-footer" style="text-align: center; padding-top: 20px;">
+    <!-- 濡傛灉娌℃湁鏁版嵁 -->
+    <div
+      v-if="!processedTopicList.length"
+      class="no-data"
+      style="text-align: center; padding: 50px 0"
+    >
+      <el-empty description="鏆傛棤鏁版嵁"></el-empty>
+    </div>
+
+    <div
+      slot="footer"
+      class="dialog-footer"
+      style="text-align: center; padding-top: 20px"
+    >
       <el-button @click="handleClose">鍏� 闂�</el-button>
     </div>
   </div>
@@ -52,52 +75,86 @@
 
 <script>
 export default {
-  name: 'TopicDialog',
+  name: "TopicDialog",
   props: {
     rowData: {
       type: Object,
-      default: () => ({})
+      default: () => ({}),
     },
     queryParams: {
       type: Object,
-      default: () => ({})
-    }
+      default: () => ({}),
+    },
+    topicList: {
+      type: [Array, Object],
+      default: () => ({}),
+    },
   },
   data() {
     return {
-      topiclist: []
+      processedTopicList: [], // 澶勭悊鍚庣殑鏁版嵁
     };
   },
-
-  mounted() {
-    this.loadData();
+  watch: {
+    // 鐩戝惉鐖剁粍浠朵紶閫掔殑鏁版嵁鍙樺寲
+    topicList: {
+      immediate: true,
+      handler(newVal) {
+        console.log("TopicDialog鎺ユ敹鍒扮埗缁勪欢鏁版嵁:", newVal);
+        this.processTopicList(newVal);
+      },
+    },
   },
-
+  mounted() {
+    console.log("TopicDialog mounted, props:", this.$props);
+  },
   methods: {
-    // 鍔犺浇鏁版嵁
-    async loadData() {
-      try {
-        // 杩欓噷浠庣埗缁勪欢浼犻�掓暟鎹紝涓嶉渶瑕侀噸鏂拌皟鐢ˋPI
-        this.topiclist = this.$parent.topiclist || [];
-      } catch (error) {
-        console.error('鍔犺浇棰樼洰璇︽儏澶辫触:', error);
-        this.$message.error('鍔犺浇棰樼洰璇︽儏澶辫触');
+    // 澶勭悊topicList鏁版嵁
+    processTopicList(data) {
+      console.log("寮�濮嬪鐞嗘暟鎹�:", data);
+
+      if (!data || typeof data !== "object") {
+        this.processedTopicList = [];
+        return;
       }
+
+      // 灏嗗璞¤浆鎹负鏁扮粍
+      const result = [];
+
+      Object.keys(data).forEach((key) => {
+        const item = data[key];
+        if (item && item.scriptContent) {
+          // 娣辨嫹璐漣tem锛岄伩鍏嶄慨鏀瑰師鏁版嵁
+          const processedItem = JSON.parse(JSON.stringify(item));
+
+          // 杩囨护details锛屽彧淇濈暀鏈夐�夐」鏂囨湰鐨�
+          if (processedItem.details && Array.isArray(processedItem.details)) {
+            processedItem.details = processedItem.details.filter(
+              (detail) => detail && detail.optionText
+            );
+          }
+
+          result.push(processedItem);
+        }
+      });
+
+      console.log("澶勭悊鍚庣殑鏁版嵁:", result);
+      this.processedTopicList = result;
     },
 
     // 鏍煎紡鍖栫櫨鍒嗘瘮
     formatPercent(value) {
-      if (value === null || value === undefined) return '-';
+      if (value === null || value === undefined) return "-";
       const num = parseFloat(value);
-      if (isNaN(num)) return '-';
-      return `${(num * 100).toFixed(2)}%`;
+      if (isNaN(num)) return "-";
+      return `${num.toFixed(2)}%`; // 娉ㄦ剰锛氫綘鐨勬暟鎹腑鐧惧垎姣斿凡缁忔槸0-100鐨勫舰寮�
     },
 
     // 鍏抽棴瀵硅瘽妗�
     handleClose() {
-      this.$emit('close');
-    }
-  }
+      this.$emit("close");
+    },
+  },
 };
 </script>
 
diff --git a/src/views/Satisfaction/sfstatistics/components/visitStatistics.vue b/src/views/Satisfaction/sfstatistics/components/visitStatistics.vue
new file mode 100644
index 0000000..60a1c59
--- /dev/null
+++ b/src/views/Satisfaction/sfstatistics/components/visitStatistics.vue
@@ -0,0 +1,1030 @@
+<template>
+  <div class="followup-statistics">
+    <div class="query-section">
+      <el-form
+        :model="queryParams"
+        ref="queryForm"
+        size="medium"
+        :inline="true"
+        label-width="100px"
+        class="query-form"
+      >
+        <el-form-item label="缁熻绫诲瀷" prop="statisticaltype">
+          <el-select
+            v-model="queryParams.statisticaltype"
+            placeholder="璇烽�夋嫨缁熻绫诲瀷"
+            clearable
+            @change="handleStatisticalTypeChange"
+          >
+            <el-option
+              v-for="item in Statisticallist"
+              :key="item.value"
+              :label="item.label"
+              :value="item.value"
+            />
+          </el-select>
+        </el-form-item>
+
+        <!-- 鐥呭尯閫夋嫨 -->
+        <el-form-item
+          v-if="queryParams.statisticaltype == 1"
+          label="鐥呭尯"
+          prop="leavehospitaldistrictcodes"
+        >
+          <el-select
+            v-model="queryParams.leavehospitaldistrictcodes"
+            placeholder="璇烽�夋嫨鐥呭尯"
+            multiple
+            collapse-tags
+            filterable
+            clearable
+            style="width: 300px"
+          >
+            <el-option
+              v-for="item in flatArrayhospit"
+              :key="item.value"
+              :label="item.label"
+              :value="item.value"
+            />
+          </el-select>
+        </el-form-item>
+
+        <!-- 绉戝閫夋嫨 -->
+        <el-form-item
+          v-if="queryParams.statisticaltype == 2"
+          label="绉戝"
+          prop="deptcodes"
+        >
+          <el-select
+            v-model="queryParams.deptcodes"
+            placeholder="璇烽�夋嫨绉戝"
+            multiple
+            collapse-tags
+            filterable
+            clearable
+            style="width: 300px"
+          >
+            <el-option
+              v-for="item in flatArraydept"
+              :key="item.value"
+              :label="item.label"
+              :value="item.value"
+            />
+          </el-select>
+        </el-form-item>
+
+        <el-form-item label="鏈嶅姟绫诲瀷" prop="serviceType">
+          <el-select
+            v-model="queryParams.serviceType"
+            placeholder="璇烽�夋嫨鏈嶅姟绫诲瀷"
+            multiple
+            collapse-tags
+            clearable
+            style="width: 300px"
+          >
+            <el-option
+              v-for="item in options"
+              :key="item.value"
+              :label="item.label"
+              :value="item.value"
+            />
+          </el-select>
+        </el-form-item>
+
+        <el-form-item label="闅忚鏃堕棿" prop="dateRange">
+          <el-date-picker
+            v-model="queryParams.dateRange"
+            type="daterange"
+            range-separator="鑷�"
+            start-placeholder="寮�濮嬫棩鏈�"
+            end-placeholder="缁撴潫鏃ユ湡"
+            value-format="yyyy-MM-dd"
+            :picker-options="pickerOptions"
+            style="width: 380px"
+          />
+        </el-form-item>
+
+        <el-form-item>
+          <el-button
+            type="primary"
+            icon="el-icon-search"
+            @click="handleQuery"
+            :loading="loading"
+          >
+            鎼滅储
+          </el-button>
+          <el-button icon="el-icon-refresh" @click="resetQuery">
+            閲嶇疆
+          </el-button>
+          <el-button
+            type="warning"
+            icon="el-icon-download"
+            @click="handleExport"
+            :disabled="!userList.length"
+          >
+            瀵煎嚭
+          </el-button>
+        </el-form-item>
+      </el-form>
+    </div>
+
+    <div class="table-section">
+      <el-table
+        v-loading="loading"
+        :data="userList"
+        :border="true"
+        style="width: 100%"
+        @selection-change="handleSelectionChange"
+        :row-key="getRowKey"
+      >
+        <!-- 鐥呭尯鍒� -->
+        <el-table-column
+          v-if="queryParams.statisticaltype == 1"
+          label="鍑洪櫌鐥呭尯"
+          align="center"
+          sortable
+          key="leavehospitaldistrictname"
+          prop="leavehospitaldistrictname"
+          :show-overflow-tooltip="true"
+          :sort-method="sortChineseNumber"
+          min-width="120"
+        />
+
+        <!-- 绉戝鍒� -->
+        <el-table-column
+          v-if="queryParams.statisticaltype == 2"
+          label="绉戝"
+          align="center"
+          key="deptname"
+          prop="deptname"
+          :show-overflow-tooltip="true"
+          min-width="120"
+        />
+
+        <el-table-column
+          label="鍑洪櫌浜烘"
+          align="center"
+          key="dischargeCount"
+          prop="dischargeCount"
+          min-width="100"
+        />
+
+        <el-table-column
+          label="鏃犻渶闅忚浜烘"
+          align="center"
+          key="nonFollowUp"
+          prop="nonFollowUp"
+          min-width="120"
+        />
+
+        <el-table-column
+          label="搴旈殢璁夸汉娆�"
+          align="center"
+          key="followUpNeeded"
+          prop="followUpNeeded"
+          min-width="120"
+        />
+
+        <el-table-column
+          label="闅忚鐜�"
+          align="center"
+          key="followUpRate"
+          prop="followUpRate"
+          min-width="100"
+        >
+          <template slot-scope="scope">
+            <span
+              v-if="
+                scope.row.followUpRate !== null &&
+                scope.row.followUpRate !== undefined
+              "
+            >
+              {{ formatPercent(scope.row.followUpRate) }}
+            </span>
+            <span v-else>-</span>
+          </template>
+        </el-table-column>
+
+        <el-table-column
+          label="鍙婃椂鐜�"
+          align="center"
+          key="rate"
+          prop="rate"
+          min-width="100"
+        >
+          <template slot-scope="scope">
+            <el-button
+              v-if="scope.row.rate !== null && scope.row.rate !== undefined"
+              type="text"
+              @click="handleSeedetails(scope.row)"
+            >
+              {{ formatPercent(scope.row.rate) }}
+            </el-button>
+            <span v-else style="color: #909399">-</span>
+          </template>
+        </el-table-column>
+
+        <el-table-column
+          label="澶嶈瘖閫氱煡棰樼洰鎬婚噺"
+          align="center"
+          key="joyAllCount"
+          prop="joyAllCount"
+          min-width="140"
+        />
+
+        <el-table-column
+          label="澶嶈瘖閫氱煡濉姤閲�"
+          align="center"
+          key="joyCount"
+          prop="joyCount"
+          min-width="120"
+        />
+
+        <el-table-column
+          label="瀹屾垚姣旂巼"
+          align="center"
+          key="joyTotal"
+          prop="joyTotal"
+          min-width="100"
+        >
+          <template slot-scope="scope">
+            <span
+              v-if="
+                scope.row.joyTotal !== null && scope.row.joyTotal !== undefined
+              "
+            >
+              {{ formatPercent(scope.row.joyTotal) }}
+            </span>
+            <span v-else>-</span>
+          </template>
+        </el-table-column>
+
+        <el-table-column label="鎿嶄綔" align="center" fixed="right" width="120">
+          <template slot-scope="scope">
+            <el-button type="text" @click="getinfo(scope.row)">
+              <i class="el-icon-s-order" style="margin-right: 4px"></i>
+              鏌ョ湅璇︽儏
+            </el-button>
+          </template>
+        </el-table-column>
+      </el-table>
+    </div>
+
+    <!-- 鍒嗛〉 -->
+    <div class="pagination-section" v-if="total > 0">
+      <el-pagination
+        background
+        layout="total, sizes, prev, pager, next, jumper"
+        :current-page="queryParams.pageNum"
+        :page-size="queryParams.pageSize"
+        :page-sizes="[10, 20, 30, 50]"
+        :total="total"
+        @size-change="handleSizeChange"
+        @current-change="handlePageChange"
+      />
+    </div>
+
+    <!-- 鏈強鏃堕殢璁胯鎯呭璇濇 -->
+    <el-dialog
+      title="鏈強鏃堕殢璁挎偅鑰呮湇鍔�"
+      :visible.sync="SeedetailsVisible"
+      width="80%"
+      :close-on-click-modal="false"
+    >
+      <SeedetailsDialog
+        v-if="SeedetailsVisible"
+        :row-data="currentRow"
+        :query-params="queryParams"
+        @close="SeedetailsVisible = false"
+      />
+    </el-dialog>
+
+    <!-- 澶嶈瘖閫氱煡璇︽儏瀵硅瘽妗� -->
+    <el-dialog
+      :visible.sync="topicVisible"
+      width="60%"
+      :close-on-click-modal="false"
+    >
+      <template #title>
+        <div style="display: flex; align-items: center">
+          <i
+            class="el-icon-s-data"
+            style="margin-right: 8px; color: #409eff"
+          ></i>
+          <span>{{ topicvalue.name }}</span>
+          <span style="margin-left: 10px; color: #666; font-size: 14px"
+            >澶嶈瘖閫氱煡鎸囨爣璇︽儏</span
+          >
+        </div>
+      </template>
+      <topic-dialog
+        v-if="topicVisible"
+        :row-data="currentRow"
+        :topicList="topiclist"
+        :query-params="queryParams"
+        @close="topicVisible = false"
+      />
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import {
+  getSfStatisticsJoy,
+  getSfStatisticsJoyInfo,
+  selectTimelyRate,
+} from "@/api/system/user";
+import ExcelJS from "exceljs";
+import { saveAs } from "file-saver";
+import SeedetailsDialog from "./components/SeedetailsDialog.vue";
+import TopicDialog from "./components/TopicDialog.vue";
+
+export default {
+  name: "FollowupStatistics",
+  components: {
+    SeedetailsDialog,
+    TopicDialog,
+  },
+  data() {
+    return {
+      // 鏌ヨ鍙傛暟
+      queryParams: {
+        statisticaltype: 1,
+        leavehospitaldistrictcodes: ["all"],
+        deptcodes: [],
+        serviceType: [2],
+        dateRange: [],
+        pageNum: 1,
+        pageSize: 20,
+      },
+
+      // 缁熻绫诲瀷鍒楄〃
+      Statisticallist: [
+        { label: "鐥呭尯缁熻", value: 1 },
+        { label: "绉戝缁熻", value: 2 },
+      ],
+
+      // 鐥呭尯鍒楄〃
+      flatArrayhospit: [],
+
+      // 绉戝鍒楄〃
+      flatArraydept: [],
+
+      // 鏈嶅姟绫诲瀷閫夐」
+      options: [],
+
+      // 琛ㄦ牸鏁版嵁
+      userList: [],
+
+      // 鎬绘潯鏁�
+      total: 0,
+
+      // 鍔犺浇鐘舵��
+      loading: false,
+
+      // 閫変腑鐨勮
+      ids: [],
+      single: true,
+      multiple: true,
+
+      // 褰撳墠鎿嶄綔鐨勮
+      currentRow: null,
+
+      // 瀵硅瘽妗嗘樉绀烘帶鍒�
+      SeedetailsVisible: false,
+      topicVisible: false,
+
+      // 澶嶈瘖閫氱煡璇︽儏鏁版嵁
+      topiclist: [],
+      topicvalue: {
+        name: "",
+      },
+
+      // 鏃ユ湡閫夋嫨鍣ㄩ�夐」
+      pickerOptions: {
+        shortcuts: [
+          {
+            text: "鏈�杩戜竴鍛�",
+            onClick(picker) {
+              const end = new Date();
+              const start = new Date();
+              start.setTime(start.getTime() - 3600 * 1000 * 24 * 7);
+              picker.$emit("pick", [start, end]);
+            },
+          },
+          {
+            text: "鏈�杩戜竴涓湀",
+            onClick(picker) {
+              const end = new Date();
+              const start = new Date();
+              start.setTime(start.getTime() - 3600 * 1000 * 24 * 30);
+              picker.$emit("pick", [start, end]);
+            },
+          },
+          {
+            text: "鏈�杩戜笁涓湀",
+            onClick(picker) {
+              const end = new Date();
+              const start = new Date();
+              start.setTime(start.getTime() - 3600 * 1000 * 24 * 90);
+              picker.$emit("pick", [start, end]);
+            },
+          },
+        ],
+        disabledDate(time) {
+          return time.getTime() > Date.now();
+        },
+      },
+    };
+  },
+
+  created() {
+    this.initData();
+  },
+
+  methods: {
+    // 鍒濆鍖栨暟鎹�
+    async initData() {
+      await this.getDeptTree();
+      await this.getList();
+    },
+
+    // 鑾峰彇绉戝鏍�
+    getDeptTree() {
+      // 鑾峰彇鏈嶅姟绫诲瀷
+      this.options = this.$store.getters.tasktypes || [];
+
+      // 鑾峰彇绉戝鍒楄〃
+      this.flatArraydept = (this.$store.getters.belongDepts || []).map(
+        (dept) => {
+          return {
+            label: dept.deptName,
+            value: dept.deptCode,
+          };
+        }
+      );
+
+      // 鑾峰彇鐥呭尯鍒楄〃
+      this.flatArrayhospit = (this.$store.getters.belongWards || []).map(
+        (ward) => {
+          return {
+            label: ward.districtName,
+            value: ward.districtCode,
+          };
+        }
+      );
+
+      // 娣诲姞鍏ㄩ儴閫夐」
+      this.flatArraydept.push({ label: "鍏ㄩ儴", value: "all" });
+      this.flatArrayhospit.push({ label: "鍏ㄩ儴", value: "all" });
+    },
+
+    // 鑾峰彇缁熻鍒楄〃
+    async getList() {
+      this.loading = true;
+      try {
+        // 澶勭悊鏌ヨ鍙傛暟
+        const params = {
+          configKey: "returnVisitCount",
+          ...this.queryParams,
+        };
+
+        // 澶勭悊鏃ユ湡鑼冨洿
+        if (
+          this.queryParams.dateRange &&
+          this.queryParams.dateRange.length === 2
+        ) {
+          params.startTime = this.queryParams.dateRange[0];
+          params.endTime = this.queryParams.dateRange[1];
+        }
+
+        // 澶勭悊鐥呭尯/绉戝閫夋嫨
+        if (params.statisticaltype == 1) {
+          // 鐥呭尯缁熻
+          if (params.leavehospitaldistrictcodes.includes("all")) {
+            // 濡傛灉閫夋嫨浜�"鍏ㄩ儴"锛屽垯绉婚櫎"all"鍊�
+            params.leavehospitaldistrictcodes =
+              params.leavehospitaldistrictcodes.filter(
+                (item) => item !== "all"
+              );
+            // 濡傛灉闇�瑕佷紶鎵�鏈夌梾鍖轰唬鐮侊紝鍙互浠巗tore涓幏鍙�
+            params.leavehospitaldistrictcodes = (
+              this.$store.getters.belongWards || []
+            ).map((ward) => ward.districtCode);
+          }
+        } else if (params.statisticaltype == 2) {
+          // 绉戝缁熻
+          if (params.deptcodes.includes("all")) {
+            // 濡傛灉閫夋嫨浜�"鍏ㄩ儴"锛屽垯绉婚櫎"all"鍊�
+            params.deptcodes = params.deptcodes.filter(
+              (item) => item !== "all"
+            );
+            // 濡傛灉闇�瑕佷紶鎵�鏈夌瀹や唬鐮侊紝鍙互浠巗tore涓幏鍙�
+            params.deptcodes = (this.$store.getters.belongDepts || []).map(
+              (dept) => dept.deptCode
+            );
+          }
+        }
+
+        const response = await getSfStatisticsJoy(params);
+        this.userList = this.customSort(response.data) || [];
+        this.total = response.total || 0;
+      } catch (error) {
+        console.error("鑾峰彇缁熻鍒楄〃澶辫触:", error);
+        this.$message.error("鑾峰彇鏁版嵁澶辫触");
+      } finally {
+        this.loading = false;
+      }
+    },
+    sortChineseNumber(aRow, bRow) {
+      const a = aRow.leavehospitaldistrictname;
+      const b = bRow.leavehospitaldistrictname;
+
+      // 涓枃鏁板瓧鍒伴樋鎷変集鏁板瓧鐨勬槧灏勶紙鎵╁睍鍒�45锛�
+      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);
+
+      // 澶勭悊鏃犳硶瑙f瀽鐨勬儏鍐�
+      if (numA === -1 && numB === -1) {
+        return (a || "").localeCompare(b || "");
+      }
+      if (numA === -1) return 1;
+      if (numB === -1) return -1;
+
+      return numA - numB;
+    },
+    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; // 鍥犱负鏁扮粍绱㈠紩浠�0寮�濮�
+            }
+          }
+
+          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;
+      });
+    },
+    // 澶勭悊缁熻绫诲瀷鍙樺寲
+    handleStatisticalTypeChange(value) {
+      if (value === 1) {
+        this.queryParams.deptcodes = [];
+      } else {
+        this.queryParams.leavehospitaldistrictcodes = [];
+      }
+      this.queryParams.pageNum = 1;
+      this.getList();
+    },
+
+    // 澶勭悊鏌ヨ
+    handleQuery() {
+      this.queryParams.pageNum = 1;
+      this.getList();
+    },
+
+    // 閲嶇疆鏌ヨ
+    resetQuery() {
+      this.queryParams = {
+        statisticaltype: 1,
+        leavehospitaldistrictcodes: [],
+        deptcodes: [],
+        serviceType: [2],
+        dateRange: [],
+        pageNum: 1,
+        pageSize: 20,
+      };
+      this.getList();
+    },
+
+    // 澶勭悊鍒嗛〉澶у皬鍙樺寲
+    handleSizeChange(size) {
+      this.queryParams.pageSize = size;
+      this.queryParams.pageNum = 1;
+      this.getList();
+    },
+
+    // 澶勭悊椤电爜鍙樺寲
+    handlePageChange(page) {
+      this.queryParams.pageNum = page;
+      this.getList();
+    },
+
+    // 澶勭悊琛岄�夋嫨
+    handleSelectionChange(selection) {
+      this.ids = selection.map((item) => item.id);
+      this.single = selection.length !== 1;
+      this.multiple = !selection.length;
+    },
+
+    // 鑾峰彇琛宬ey
+    getRowKey(row) {
+      return row.statisticaltype === 1
+        ? row.leavehospitaldistrictcode
+        : row.deptcode;
+    },
+
+    // 鏍煎紡鍖栫櫨鍒嗘瘮
+    formatPercent(value) {
+      if (value === null || value === undefined) return "-";
+      const num = parseFloat(value);
+      if (isNaN(num)) return "-";
+      return `${(num * 100).toFixed(2)}%`;
+    },
+
+    // 鏌ョ湅鏈強鏃堕殢璁胯鎯�
+    handleSeedetails(row) {
+      this.currentRow = row;
+      this.SeedetailsVisible = true;
+    },
+
+    // 鏌ョ湅澶嶈瘖閫氱煡璇︽儏
+    async getinfo(row) {
+      this.currentRow = row;
+
+      try {
+        // 澶勭悊鏌ヨ鍙傛暟
+        const params = {
+          configKey: "returnVisitCount",
+          ...this.queryParams,
+        };
+
+        // 澶勭悊鏃ユ湡鑼冨洿
+        if (
+          this.queryParams.dateRange &&
+          this.queryParams.dateRange.length === 2
+        ) {
+          params.startTime = this.queryParams.dateRange[0];
+          params.endTime = this.queryParams.dateRange[1];
+        }
+
+        if (this.queryParams.statisticaltype == 1) {
+          this.topicvalue.name = row.leavehospitaldistrictname;
+          params.leavehospitaldistrictcodes = [row.leavehospitaldistrictcode];
+        } else {
+          this.topicvalue.name = row.deptname;
+          params.deptcodes = [row.deptcode];
+        }
+
+        const response = await getSfStatisticsJoyInfo(params);
+        this.topiclist = response.data || [];
+        console.log(this.topiclist);
+        this.topicVisible = true;
+      } catch (error) {
+        console.error("鑾峰彇澶嶈瘖閫氱煡璇︽儏澶辫触:", error);
+        this.$message.error("鑾峰彇璇︽儏澶辫触");
+      }
+    },
+
+    // 瀵煎嚭鏁版嵁
+    async handleExport() {
+      if (!this.userList.length) {
+        this.$message.warning("娌℃湁鏁版嵁鍙鍑�");
+        return;
+      }
+
+      try {
+        this.loading = true;
+
+        // 鏋勫缓鏃ユ湡鑼冨洿瀛楃涓�
+        let dateRangeString = "";
+        let sheetNameSuffix = "";
+
+        if (
+          this.queryParams.dateRange &&
+          this.queryParams.dateRange.length === 2
+        ) {
+          const startDateFormatted = this.queryParams.dateRange[0];
+          const endDateFormatted = this.queryParams.dateRange[1];
+          dateRangeString = `${startDateFormatted}鑷�${endDateFormatted}`;
+          sheetNameSuffix = `${startDateFormatted}鑷�${endDateFormatted}`;
+        } else {
+          const now = new Date();
+          const currentMonth = now.getMonth() + 1;
+          dateRangeString = `${currentMonth}鏈坄;
+          sheetNameSuffix = `${currentMonth}鏈坄;
+        }
+
+        const excelName = `闅忚缁熻琛╛${dateRangeString}.xlsx`;
+        const worksheetName = `闅忚缁熻_${sheetNameSuffix}`;
+
+        // 鍒涘缓Excel宸ヤ綔绨�
+        const workbook = new ExcelJS.Workbook();
+        const worksheet = workbook.addWorksheet(worksheetName);
+
+        // 瀹氫箟鏍峰紡
+        const titleStyle = {
+          font: { name: "寰蒋闆呴粦", size: 16, bold: true },
+          fill: {
+            type: "pattern",
+            pattern: "solid",
+            fgColor: { argb: "FFE6F3FF" },
+          },
+          alignment: { vertical: "middle", horizontal: "center" },
+          border: {
+            top: { style: "thin", color: { argb: "FFD0D0D0" } },
+            left: { style: "thin", color: { argb: "FFD0D0D0" } },
+            bottom: { style: "thin", color: { argb: "FFD0D0D0" } },
+            right: { style: "thin", color: { argb: "FFD0D0D0" } },
+          },
+        };
+
+        const headerStyle = {
+          font: { name: "寰蒋闆呴粦", size: 11, bold: true },
+          fill: {
+            type: "pattern",
+            pattern: "solid",
+            fgColor: { argb: "FFF5F7FA" },
+          },
+          alignment: { vertical: "middle", horizontal: "center" },
+          border: {
+            top: { style: "thin", color: { argb: "FFD0D0D0" } },
+            left: { style: "thin", color: { argb: "FFD0D0D0" } },
+            bottom: { style: "thin", color: { argb: "FFD0D0D0" } },
+            right: { style: "thin", color: { argb: "FFD0D0D0" } },
+          },
+        };
+
+        const cellStyle = {
+          font: { name: "瀹嬩綋", size: 10 },
+          alignment: { vertical: "middle", horizontal: "center" },
+          border: {
+            top: { style: "thin", color: { argb: "FFD0D0D0" } },
+            left: { style: "thin", color: { argb: "FFD0D0D0" } },
+            bottom: { style: "thin", color: { argb: "FFD0D0D0" } },
+            right: { style: "thin", color: { argb: "FFD0D0D0" } },
+          },
+        };
+
+        // 娣诲姞鎬绘爣棰�
+        worksheet.mergeCells(1, 1, 1, 10);
+        const titleCell = worksheet.getCell(1, 1);
+        titleCell.value = `闅忚缁熻琛紙${sheetNameSuffix}锛塦;
+        titleCell.style = titleStyle;
+        worksheet.getRow(1).height = 35;
+
+        // 娣诲姞琛ㄥご
+        const headers = [
+          this.queryParams.statisticaltype == 1 ? "鍑洪櫌鐥呭尯" : "绉戝",
+          "鍑洪櫌浜烘",
+          "鏃犻渶闅忚浜烘",
+          "搴旈殢璁夸汉娆�",
+          "闅忚鐜�",
+          "鍙婃椂鐜�",
+          "澶嶈瘖閫氱煡棰樼洰鎬婚噺",
+          "澶嶈瘖閫氱煡濉姤閲�",
+          "瀹屾垚姣旂巼",
+        ];
+
+        const headerRow = worksheet.addRow(headers);
+        headerRow.eachCell((cell) => {
+          cell.style = headerStyle;
+        });
+        headerRow.height = 25;
+
+        // 娣诲姞鏁版嵁琛�
+        this.userList.forEach((item) => {
+          const dataRow = worksheet.addRow([
+            this.queryParams.statisticaltype == 1
+              ? item.leavehospitaldistrictname
+              : item.deptname,
+            item.dischargeCount || 0,
+            item.nonFollowUp || 0,
+            item.followUpNeeded || 0,
+            item.followUpRate || "0%",
+            item.rate ? this.formatPercent(item.rate) : "0%",
+            item.joyAllCount || 0,
+            item.joyCount || 0,
+            item.joyTotal ? this.formatPercent(item.joyTotal) : "0%",
+          ]);
+
+          dataRow.eachCell((cell) => {
+            cell.style = cellStyle;
+          });
+          dataRow.height = 22;
+        });
+
+        // 璁剧疆鍒楀
+        worksheet.columns = [
+          { width: 20 },
+          { width: 12 },
+          { width: 12 },
+          { width: 12 },
+          { width: 12 },
+          { width: 12 },
+          { width: 15 },
+          { width: 15 },
+          { width: 12 },
+        ];
+
+        // 鐢熸垚骞朵笅杞芥枃浠�
+        const buffer = await workbook.xlsx.writeBuffer();
+        const blob = new Blob([buffer], {
+          type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
+        });
+
+        saveAs(blob, excelName);
+        this.$message.success("瀵煎嚭鎴愬姛");
+      } catch (error) {
+        console.error("瀵煎嚭澶辫触:", error);
+        this.$message.error(`瀵煎嚭澶辫触: ${error.message}`);
+      } finally {
+        this.loading = false;
+      }
+    },
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+.followup-statistics {
+  .query-section {
+    background: #fff;
+    padding: 20px;
+    border-radius: 4px;
+    margin-bottom: 20px;
+
+    .query-form {
+      display: flex;
+      flex-wrap: wrap;
+
+      ::v-deep .el-form-item {
+        margin-bottom: 20px;
+
+        &:not(:last-child) {
+          margin-right: 20px;
+        }
+      }
+    }
+  }
+
+  .table-section {
+    background: #fff;
+    padding: 20px;
+    border-radius: 4px;
+    margin-bottom: 20px;
+
+    ::v-deep .el-table {
+      th {
+        background-color: #f8f9fa;
+        font-weight: 600;
+        color: #333;
+      }
+    }
+  }
+
+  .pagination-section {
+    display: flex;
+    justify-content: flex-end;
+    background: #fff;
+    padding: 20px;
+    border-radius: 4px;
+  }
+}
+</style>
diff --git a/src/views/followvisit/Continue/index.vue b/src/views/followvisit/Continue/index.vue
index 18949b8..7394444 100644
--- a/src/views/followvisit/Continue/index.vue
+++ b/src/views/followvisit/Continue/index.vue
@@ -1875,7 +1875,7 @@
           this.zcform.remark =
             this.zcform.remark + "銆�" + this.getCurrentTime() + "銆�";
           let form = structuredClone(this.zcform);
-          form.longSendTime = this.formatTime(form.date1);
+          form.visitTime = this.formatTime(form.date1);
           form.finishtime = "";
           if (form.resource) {
             if (form.resource == 2) {
diff --git a/src/views/followvisit/OutpatientAgain/index.vue b/src/views/followvisit/OutpatientAgain/index.vue
index 43c9daf..8ba6250 100644
--- a/src/views/followvisit/OutpatientAgain/index.vue
+++ b/src/views/followvisit/OutpatientAgain/index.vue
@@ -1654,7 +1654,7 @@
           this.zcform.remark =
             this.zcform.remark + "銆�" + this.getCurrentTime() + "銆�";
           let form = structuredClone(this.zcform);
-          form.longSendTime = this.formatTime(form.date1);
+          form.visitTime = this.formatTime(form.date1);
           form.finishtime = "";
           if (form.resource) {
             if (form.resource == 2) {
diff --git a/src/views/followvisit/Tracking/index.vue b/src/views/followvisit/Tracking/index.vue
index bcc1d04..d93f58c 100644
--- a/src/views/followvisit/Tracking/index.vue
+++ b/src/views/followvisit/Tracking/index.vue
@@ -1593,7 +1593,7 @@
           this.zcform.remark =
             this.zcform.remark + "銆�" + this.getCurrentTime() + "銆�";
           let form = structuredClone(this.zcform);
-          form.longSendTime = this.formatTime(form.date1);
+          form.visitTime = this.formatTime(form.date1);
           form.finishtime = "";
           if (form.resource) {
             if (form.resource == 2) {
diff --git a/src/views/followvisit/again/index.vue b/src/views/followvisit/again/index.vue
index b045ccf..5a959d1 100644
--- a/src/views/followvisit/again/index.vue
+++ b/src/views/followvisit/again/index.vue
@@ -1655,7 +1655,7 @@
           this.zcform.remark =
             this.zcform.remark + "銆�" + this.getCurrentTime() + "銆�";
           let form = structuredClone(this.zcform);
-          form.longSendTime = this.formatTime(form.date1);
+          form.visitTime = this.formatTime(form.date1);
           form.finishtime = "";
           if (form.resource) {
             if (form.resource == 2) {
diff --git a/src/views/followvisit/discharge/index.vue b/src/views/followvisit/discharge/index.vue
index fb620ef..e03f048 100644
--- a/src/views/followvisit/discharge/index.vue
+++ b/src/views/followvisit/discharge/index.vue
@@ -2062,7 +2062,7 @@
           this.zcform.remark =
             this.zcform.remark + "銆�" + this.getCurrentTime() + "銆�";
           let form = structuredClone(this.zcform);
-          form.longSendTime = this.formatTime(form.date1);
+          form.visitTime = this.formatTime(form.date1);
           form.finishtime = "";
           if (form.resource) {
             if (form.resource == 2) {
diff --git a/src/views/followvisit/discharge/outpatientService.vue b/src/views/followvisit/discharge/outpatientService.vue
index c914289..98e33c4 100644
--- a/src/views/followvisit/discharge/outpatientService.vue
+++ b/src/views/followvisit/discharge/outpatientService.vue
@@ -1626,7 +1626,7 @@
           this.zcform.remark =
             this.zcform.remark + "銆�" + this.getCurrentTime() + "銆�";
           let form = structuredClone(this.zcform);
-          form.longSendTime = this.formatTime(form.date1);
+          form.visitTime = this.formatTime(form.date1);
           form.finishtime = "";
           if (form.resource) {
             if (form.resource == 2) {
diff --git a/src/views/followvisit/record/TracingInfo/index.vue b/src/views/followvisit/record/TracingInfo/index.vue
index a2e6e5e..90bfb77 100644
--- a/src/views/followvisit/record/TracingInfo/index.vue
+++ b/src/views/followvisit/record/TracingInfo/index.vue
@@ -1875,7 +1875,7 @@
     // 鍐嶆闅忚鏁版嵁鏇存浛
     formtidy() {
       this.form.visitType2 = this.form.visitType;
-      this.form.date2 = this.form.longSendTime;
+      this.form.date2 = this.form.visitTime;
       // this.form.date1 = this.setCurrentDate();
       this.form.remark2 = this.form.remark;
     },
@@ -1909,7 +1909,7 @@
           this.logsheetlist = res.rows[0].serviceSubtaskList;
           this.templateid = this.form.templateid;
           this.selectedTag = this.form.excep;
-          const targetDate = new Date(this.form.longSendTime); // 鐩爣鏃ユ湡
+          const targetDate = new Date(this.form.visitTime); // 鐩爣鏃ユ湡
           const now = new Date(); // 褰撳墠鏃堕棿
           if (now < targetDate && this.form.sendstate == 2) {
             this.$confirm("褰撳墠鏈嶅姟鏈埌鍙戦�佹椂闂磋璋ㄦ厧淇敼", "鎻愮ず", {
@@ -2245,7 +2245,7 @@
           this.form.remark =
             this.form.remark + "銆�" + this.getCurrentTime() + "銆�";
           let form = structuredClone(this.form);
-          form.longSendTime = this.formatTime(form.date1);
+          form.visitTime = this.formatTime(form.date1);
           form.finishtime = "";
           if (form.resource) {
             if (form.resource == 2) {
diff --git a/src/views/followvisit/record/detailpage/index.vue b/src/views/followvisit/record/detailpage/index.vue
index 360bc90..70752cc 100644
--- a/src/views/followvisit/record/detailpage/index.vue
+++ b/src/views/followvisit/record/detailpage/index.vue
@@ -2047,7 +2047,7 @@
     // 鍐嶆闅忚鏁版嵁鏇存浛
     formtidy() {
       this.form.visitType2 = this.form.visitType;
-      this.form.date2 = this.form.longSendTime;
+      this.form.date2 = this.form.visitTime;
       // this.form.date1 = this.setCurrentDate();
       this.form.remark2 = this.form.remark;
     },
@@ -2081,7 +2081,7 @@
           this.logsheetlist = res.rows[0].serviceSubtaskList;
           this.templateid = this.form.templateid;
           this.selectedTag = this.form.excep;
-          const targetDate = new Date(this.form.longSendTime); // 鐩爣鏃ユ湡
+          const targetDate = new Date(this.form.visitTime); // 鐩爣鏃ユ湡
           const now = new Date(); // 褰撳墠鏃堕棿
           if (now < targetDate && this.form.sendstate == 2) {
             this.$confirm("褰撳墠鏈嶅姟鏈埌鍙戦�佹椂闂磋璋ㄦ厧淇敼", "鎻愮ず", {
@@ -2450,7 +2450,7 @@
           this.form.remark =
             this.form.remark + "銆�" + this.getCurrentTime() + "銆�";
           let form = structuredClone(this.form);
-          form.longSendTime = this.formatTime(form.date1);
+          form.visitTime = this.formatTime(form.date1);
           form.finishtime = "";
           if (form.resource) {
             if (form.resource == 2) {
diff --git a/src/views/followvisit/record/physical/index.vue b/src/views/followvisit/record/physical/index.vue
index 7e370f1..bace874 100644
--- a/src/views/followvisit/record/physical/index.vue
+++ b/src/views/followvisit/record/physical/index.vue
@@ -1000,7 +1000,7 @@
     // 鍐嶆闅忚鏁版嵁鏇存浛
     formtidy() {
       this.form.visitType2 = this.form.visitType;
-      this.form.date2 = this.form.longSendTime;
+      this.form.date2 = this.form.visitTime;
       this.form.remark2 = this.form.remark;
     },
     // 鑾峰彇鎮h�呰褰�
@@ -1024,7 +1024,7 @@
           }
           this.logsheetlist = res.rows[0].serviceSubtaskList;
           this.templateid = this.logsheetlist[0].templateid;
-          const targetDate = new Date(this.form.longSendTime); // 鐩爣鏃ユ湡
+          const targetDate = new Date(this.form.visitTime); // 鐩爣鏃ユ湡
           const now = new Date(); // 褰撳墠鏃堕棿
           this.form.endtime = this.formatTime(this.form.endtime);
           if (now < targetDate && this.form.sendstate == 2) {
@@ -1169,7 +1169,7 @@
           this.form.remark =
             this.form.remark + "銆�" + this.getCurrentTime() + "銆�";
           let form = structuredClone(this.form);
-          form.longSendTime = this.formatTime(form.date1);
+          form.visitTime = this.formatTime(form.date1);
           form.finishtime = "";
           if (form.resource) {
             if (form.resource == 2) {
diff --git a/src/views/followvisit/zbAgain/index.vue b/src/views/followvisit/zbAgain/index.vue
index a002030..f9a5b49 100644
--- a/src/views/followvisit/zbAgain/index.vue
+++ b/src/views/followvisit/zbAgain/index.vue
@@ -1643,7 +1643,7 @@
           this.zcform.remark =
             this.zcform.remark + "銆�" + this.getCurrentTime() + "銆�";
           let form = structuredClone(this.zcform);
-          form.longSendTime = this.formatTime(form.date1);
+          form.visitTime = this.formatTime(form.date1);
           form.finishtime = "";
           if (form.resource) {
             if (form.resource == 2) {
diff --git a/src/views/patient/propaganda/QuestionnaireTask.vue b/src/views/patient/propaganda/QuestionnaireTask.vue
index 5074600..3ab1854 100644
--- a/src/views/patient/propaganda/QuestionnaireTask.vue
+++ b/src/views/patient/propaganda/QuestionnaireTask.vue
@@ -296,12 +296,11 @@
                   <el-col :span="20"
                     ><el-form-item label="閫傜敤鎵嬫湳" prop="region">
                       <el-select
-                        v-model="operationcodes"
+                        v-model="form.oplevelcode"
                         style="width: 400px"
                         @remove-tag="removeopera"
                         size="medium"
                         :remote-method="remoteopcode"
-                        multiple
                         filterable
                         remote
                         placeholder="璇烽�夋嫨鎵嬫湳"
@@ -309,8 +308,8 @@
                         <el-option
                           class="ruleFormaa"
                           v-for="item in baseoperaList"
-                          :label="item.opdesc"
-                          :value="item.opcode"
+                          :label="item.label"
+                          :value="item.value"
                         >
                         </el-option>
                       </el-select> </el-form-item
@@ -943,14 +942,18 @@
       dialogVisiblepatientjb: false, //娣诲姞鐤剧梾寮规
       deptcodesWards: [], //绉戝鏁版嵁
       leavehospitaldistrictcodes: [], //鐥呭尯鏁版嵁
-      operationcodes: [], //鎵嬫湳鏁版嵁
       illnesscodes: [], //鐤剧梾鏁版嵁
       radio: 1,
       checkboxlist: [],
       tableLabel: [],
       questionList: [],
       donorchargeList: [],
-      baseoperaList: [],
+      baseoperaList: [
+        { value: "1", label: "涓�绾ф墜鏈�" },
+        { value: "2", label: "浜岀骇鎵嬫湳" },
+        { value: "3", label: "涓夌骇鎵嬫湳" },
+        { value: "4", label: "鍥涚骇鎵嬫湳" },
+      ],
       usable: [
         { value: "0", label: "鍙敤" },
         { value: "1", label: "鍋滅敤" },
@@ -1431,16 +1434,16 @@
         ];
         if (this.form.appltype == 1) {
           this.leavehospitaldistrictcodes = [];
-          this.operationcodes = [];
+          this.form.oplevelcode = null;
           this.illnesscodes = [];
         } else if (this.form.appltype == 2) {
           this.deptcodesWards = [];
-          this.operationcodes = [];
+          this.form.oplevelcode = null;
           this.illnesscodes = [];
         } else if (this.form.appltype == 3) {
           this.deptcodesWards = [];
           this.leavehospitaldistrictcodes = [];
-          this.operationcodes = [];
+          this.form.oplevelcode = null;
         } else if (this.form.appltype == 4) {
           this.deptcodesWards = [];
           this.illnesscodes = [];
@@ -1460,7 +1463,7 @@
           this.deptcodesWards[0] ||
           this.leavehospitaldistrictcodes[0] ||
           this.diagglist[0] ||
-          this.operationcodes[0] ||
+          this.form.oplevelcode ||
           this.form.longTask == 2 ||
           this.serviceType == 3
         ) {
@@ -1511,7 +1514,7 @@
         this.form.deptcode = this.deptcodesWards.join(",");
         this.form.leavehospitaldistrictcode =
           this.leavehospitaldistrictcodes.join(",");
-        this.form.opcode = this.operationcodes.join(",");
+        // this.form.opcode = this.operationcodes.join(",");
         this.form.icd10code = this.diagglist
           .map((item) => item.icdcode)
           .join(",");
@@ -1636,36 +1639,36 @@
       }).then((res) => {
         this.donorchargeList = res.rows;
       });
-      getbaseopera({
-        pageNum: 1,
-        pageSize: 1000,
-      }).then((res) => {
-        this.baseoperaList = res.rows;
-      });
+      // getbaseopera({
+      //   pageNum: 1,
+      //   pageSize: 1000,
+      // }).then((res) => {
+      //   this.baseoperaList = res.rows;
+      // });
     },
     // 鎵嬫湳鏌ヨ
     remoteopcode(name) {
-      if (name) {
-        getbaseopera({
-          pageNum: 1,
-          pageSize: 1000,
-          opdesc: name,
-        }).then((res) => {
-          this.baseoperaList = res.rows;
-        });
-      }
+      // if (name) {
+      //   getbaseopera({
+      //     pageNum: 1,
+      //     pageSize: 1000,
+      //     opdesc: name,
+      //   }).then((res) => {
+      //     this.baseoperaList = res.rows;
+      //   });
+      // }
     },
     // 鐤剧梾鏌ヨ
     remotedonor(name) {
-      if (name) {
-        getbaseopera({
-          pageNum: 1,
-          pageSize: 1000,
-          opdesc: name,
-        }).then((res) => {
-          this.baseoperaList = res.rows;
-        });
-      }
+      // if (name) {
+      //   getbaseopera({
+      //     pageNum: 1,
+      //     pageSize: 1000,
+      //     opdesc: name,
+      //   }).then((res) => {
+      //     this.baseoperaList = res.rows;
+      //   });
+      // }
     },
     // 澶勭悊闂灞傚彉閲�
     Variablehandling(arr, type) {
diff --git a/src/views/patient/propaganda/index.vue b/src/views/patient/propaganda/index.vue
index cf89a0c..d930a80 100644
--- a/src/views/patient/propaganda/index.vue
+++ b/src/views/patient/propaganda/index.vue
@@ -259,11 +259,11 @@
           label="搴斿鏁欐棩鏈�"
           width="200"
           align="center"
-          key="longSendTime"
-          prop="longSendTime"
+          key="visitTime"
+          prop="visitTime"
         >
           <template slot-scope="scope">
-            <span>{{ formatTime(scope.row.longSendTime) }}</span>
+            <span>{{ formatTime(scope.row.visitTime) }}</span>
           </template></el-table-column
         >
         <el-table-column
diff --git a/src/views/sfstatistics/percentage/index.vue b/src/views/sfstatistics/percentage/index.vue
index 03f5de7..f94291b 100644
--- a/src/views/sfstatistics/percentage/index.vue
+++ b/src/views/sfstatistics/percentage/index.vue
@@ -1511,43 +1511,97 @@
       getSfStatistics(params).then((response) => {
         this.loading = false;
 
-        // this.total = response.total;
+        this.total = response.total;
+        // this.userList = response.data;
         this.userList = this.customSort(response.data);
       });
     },
-    sortChineseNumber(a, b) {
-      // 鎻愬彇涓枃鏁板瓧
-      const chineseNumbers = [
-        "涓�",
-        "浜�",
-        "涓�",
-        "鍥�",
-        "浜�",
-        "鍏�",
-        "涓�",
-        "鍏�",
-        "涔�",
-        "鍗�",
-        "鍗佷竴",
-        "鍗佷簩",
-      ];
+    sortChineseNumber(aRow, bRow) {
+      const a = aRow.leavehospitaldistrictname;
+      const b = bRow.leavehospitaldistrictname;
 
-      // 浠庡瓧绗︿覆涓彁鍙栫梾鍖烘暟瀛楋紝濡�"鍥涚梾鍖�" -> "鍥�"
+      // 涓枃鏁板瓧鍒伴樋鎷変集鏁板瓧鐨勬槧灏勶紙鎵╁睍鍒�45锛�
+      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) return -1;
+        if (!text || typeof text !== "string") return -1;
+
+        // 鍖归厤涓枃鏁板瓧锛屾敮鎸佷竴鍒板洓鍗佷簲
         const match = text.match(/^([涓�浜屼笁鍥涗簲鍏竷鍏節鍗乚+)/);
+
         if (match && match[1]) {
-          return chineseNumbers.indexOf(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 0;
-      if (numA === -1) return 1; // 鏃犳硶瑙f瀽鐨勬斁鍒板悗闈�
-      if (numB === -1) return -1; // 鏃犳硶瑙f瀽鐨勬斁鍒板悗闈�
+      // 澶勭悊鏃犳硶瑙f瀽鐨勬儏鍐�
+      if (numA === -1 && numB === -1) {
+        return (a || "").localeCompare(b || "");
+      }
+      if (numA === -1) return 1;
+      if (numB === -1) return -1;
 
       return numA - numB;
     },
@@ -1565,8 +1619,9 @@
       }
     },
     customSort(data) {
-      // 瀹氫箟鎮ㄦ湡鏈涚殑鐥呭尯椤哄簭锛堟墿灞曞埌涓夊崄锛�
+      // 瀹氫箟鎮ㄦ湡鏈涚殑鐥呭尯椤哄簭锛堟墿灞曞埌鍥涘崄浜旓級
       const order = [
+        "涓�",
         "浜�",
         "涓�",
         "鍥�",
@@ -1596,21 +1651,55 @@
         "浜屽崄鍏�",
         "浜屽崄涔�",
         "涓夊崄",
+        "涓夊崄涓�",
+        "涓夊崄浜�",
+        "涓夊崄涓�",
+        "涓夊崄鍥�",
+        "涓夊崄浜�",
+        "涓夊崄鍏�",
+        "涓夊崄涓�",
+        "涓夊崄鍏�",
+        "涓夊崄涔�",
+        "鍥涘崄",
+        "鍥涘崄涓�",
+        "鍥涘崄浜�",
+        "鍥涘崄涓�",
+        "鍥涘崄鍥�",
+        "鍥涘崄浜�",
       ];
 
       return data.sort((a, b) => {
-        // 鎻愬彇鐥呭尯鍚嶇О涓殑涓枃鏁板瓧閮ㄥ垎[6](@ref)
+        // 鎻愬彇鐥呭尯鍚嶇О涓殑涓枃鏁板瓧閮ㄥ垎
         const getIndex = (name) => {
-          const numStr = name.match(
-            /^(浜寍涓墊鍥泑浜攟鍏瓅涓億鍏珅涔潀鍗亅鍗佷竴|鍗佷簩|鍗佷笁|鍗佸洓|鍗佷簲|鍗佸叚|鍗佷竷|鍗佸叓|鍗佷節|浜屽崄|浜屽崄涓�|浜屽崄浜寍浜屽崄涓墊浜屽崄鍥泑浜屽崄浜攟浜屽崄鍏瓅浜屽崄涓億浜屽崄鍏珅浜屽崄涔潀涓夊崄)/
-          )?.[1];
-          return order.indexOf(numStr);
+          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; // 鍥犱负鏁扮粍绱㈠紩浠�0寮�濮�
+            }
+          }
+
+          return -1;
         };
 
         const indexA = getIndex(a.leavehospitaldistrictname);
         const indexB = getIndex(b.leavehospitaldistrictname);
 
-        // 濡傛灉閮藉湪瀹氫箟鐨勯『搴忎腑锛屾寜瀹氫箟椤哄簭鎺掞紱鍚﹀垯锛屾湭瀹氫箟鐨勬帓鍦ㄥ悗闈2](@ref)
+        // 鎺掑簭閫昏緫
+        if (indexA === -1 && indexB === -1) {
+          return (a.leavehospitaldistrictname || "").localeCompare(
+            b.leavehospitaldistrictname || ""
+          );
+        }
         if (indexA === -1) return 1;
         if (indexB === -1) return -1;
         return indexA - indexB;
diff --git a/vue.config.js b/vue.config.js
index 79d9dfb..5a49e1f 100644
--- a/vue.config.js
+++ b/vue.config.js
@@ -36,8 +36,8 @@
       // detail: https://cli.vuejs.org/config/#devserver-proxy
       [process.env.VUE_APP_BASE_API]: {
         // target: `https://www.health-y.cn/lssf`,
-        // target: `http://192.168.100.10:8096`,
-        target: `http://192.168.100.10:8094`,//鐪佺珛鍚屽痉
+        target: `http://192.168.100.10:8096`,
+        // target: `http://192.168.100.10:8094`,//鐪佺珛鍚屽痉
         // target: `http://192.168.100.10:8095`,//鏂板崕
         // target:`http://localhost:8095`,
         // target:`http://35z1t16164.qicp.vip`,
diff --git a/ls.zip "b/\346\214\207\346\240\207\347\273\237\350\256\241\346\225\264\345\220\210\351\241\265\351\200\202\351\205\215\344\270\275\346\260\264\347\234\201\347\253\213\345\220\214\345\276\267.zip"
similarity index 90%
rename from ls.zip
rename to "\346\214\207\346\240\207\347\273\237\350\256\241\346\225\264\345\220\210\351\241\265\351\200\202\351\205\215\344\270\275\346\260\264\347\234\201\347\253\213\345\220\214\345\276\267.zip"
index ab01b0c..85fc265 100644
--- a/ls.zip
+++ "b/\346\214\207\346\240\207\347\273\237\350\256\241\346\225\264\345\220\210\351\241\265\351\200\202\351\205\215\344\270\275\346\260\264\347\234\201\347\253\213\345\220\214\345\276\267.zip"
Binary files differ

--
Gitblit v1.9.3