From 0c7cc21d8a51e164dd2fe4ce73ab566b3a9081a9 Mon Sep 17 00:00:00 2001
From: WXL (wul) <wl_5969728@163.com>
Date: 星期四, 26 三月 2026 10:25:05 +0800
Subject: [PATCH] 测试完成

---
 src/views/Satisfaction/sfstatistics/components/components/SeedetailsDialog.vue |  401 ++
 src/views/followvisit/outpatient/index.vue                                     |   12 
 vue.config.js                                                                  |    4 
 src/components/Assistant/index.vue                                             | 1132 +++++--
 src/views/followvisit/zbAgain/index.vue                                        |   19 
 src/views/patient/subsequent/index.vue                                         |   12 
 ls.zip                                                                         |    0 
 src/views/login-sy.vue                                                         |    2 
 src/views/followvisit/zysatisfaction/index.vue                                 |   13 
 src/views/Satisfaction/sfstatistics/components/SatisfactionStatistics.vue      |  990 +++++++
 src/views/followvisit/mzsatisfaction/index.vue                                 |   13 
 src/views/patient/propaganda/index.vue                                         |    6 
 src/views/followvisit/record/detailpage/index.vue                              |    9 
 src/views/Satisfaction/sfstatistics/components/FollowupStatistics.vue          |  809 +++++
 src/views/Satisfaction/configurationmyd/index.vue                              | 1246 +++++++++
 src/views/followvisit/discharge/outpatientService.vue                          |   19 
 src/views/followvisit/complaint/index.vue                                      |   13 
 src/views/followvisit/technology/index.vue                                     |   12 
 src/views/patient/physical/index.vue                                           |   12 
 src/store/modules/user.js                                                      |    2 
 src/views/followvisit/SpecificDisease/index.vue                                |   12 
 src/views/followvisit/again/index.vue                                          |   53 
 src/views/patient/patient/indexls.vue                                          |    6 
 src/views/followvisit/Tracking/index.vue                                       |   19 
 src/views/sfstatistics/percentage/satisfaction.vue                             |   71 
 src/views/patient/questionnaire/index.vue                                      |   12 
 src/views/followvisit/record/index.vue                                         |   12 
 src/views/followvisit/Continue/index.vue                                       |   19 
 src/views/followvisit/OutpatientAgain/index.vue                                |   75 
 src/views/system/user/index.vue                                                |    4 
 src/views/followvisit/HistoricalFollow/index.vue                               |   12 
 src/views/sfstatistics/percentage/index.vue                                    |   38 
 src/views/Satisfaction/particulars/index.vue                                   |  889 ++++++
 src/views/Satisfaction/sfstatistics/components/components/TopicDialog.vue      |  151 +
 src/views/patient/shadow/index.vue                                             |   12 
 src/api/AiCentre/EChartsdata.js                                                |   11 
 src/views/Satisfaction/sfstatistics/index.vue                                  |   63 
 src/App.vue                                                                    |   29 
 src/views/Satisfaction/1.vue                                                   | 1814 +++++++++++++
 src/views/followvisit/discharge/index.vue                                      |  125 
 40 files changed, 7,539 insertions(+), 614 deletions(-)

diff --git a/dist.zip b/ls.zip
similarity index 76%
rename from dist.zip
rename to ls.zip
index 3c26eda..ab01b0c 100644
--- a/dist.zip
+++ b/ls.zip
Binary files differ
diff --git a/src/App.vue b/src/App.vue
index 30d9a8f..83f295c 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -3,6 +3,13 @@
     <router-view />
     <theme-picker />
     <!-- <Assistant v-if="routertf" /> -->
+    <Assistant
+      v-if="Assvite"
+      :initial-position="{ x: 50, y: 200 }"
+      :auto-hide="false"
+      :hide-delay="3000"
+      primary-color="#1890ff"
+    />
   </div>
 </template>
 
@@ -13,17 +20,29 @@
   name: "App",
   components: {
     ThemePicker,
-    Assistant: () => import("./components/Assistant"), //寮傛缁勪欢鍔犺浇鏂瑰紡
+    Assistant: () => import("./components/Assistant"),
   },
   data() {
     return {
-      routers: window.location.href,
-      routertf: true,
+      Assvite: true,
     };
   },
   created() {
-    var startIndex = this.routers.indexOf("param5=") + "param5=".length; // 鎵惧埌绗竴涓瓧绗︾殑浣嶇疆
-    this.routertf = JSON.parse(this.routers.substring(startIndex)); // 鎴彇浠� 'param5=' 涔嬪悗鐨勫唴瀹�
+    // 鍒濆鍖栧垽鏂�
+    this.checkAndUpdateAssvite();
+  },
+  watch: {
+    // 鐩戝惉璺敱鍙樺寲
+    '$route'(to, from) {
+      this.checkAndUpdateAssvite();
+    }
+  },
+  methods: {
+    checkAndUpdateAssvite() {
+      const isLoginPage = window.location.pathname.includes("/login");
+      this.Assvite = !isLoginPage;
+      console.log('褰撳墠璺敱:', this.$route.path, '鏄惁鐧诲綍椤�:', isLoginPage, '鏄剧ず鎮诞鐞�:', this.Assvite);
+    }
   },
   metaInfo() {
     return {
diff --git a/src/api/AiCentre/EChartsdata.js b/src/api/AiCentre/EChartsdata.js
index 18c600d..6a193bd 100644
--- a/src/api/AiCentre/EChartsdata.js
+++ b/src/api/AiCentre/EChartsdata.js
@@ -1,6 +1,5 @@
 import request from "@/utils/request";
 
-
 // 鏌ヨ闂ㄨ瘖鐪嬬梾浜烘鍜屼汉鏁�
 export function getEChartsPatMedOuthospCount(data) {
   return request({
@@ -73,6 +72,14 @@
   return request({
     url: "/sms/send",
     method: "post",
-    data: data
+    data: data,
+  });
+}
+// 鍙戦�佺煭淇�
+export function getCurrentUserServiceSubtaskCount(data) {
+  return request({
+    url: "/smartor/serviceSubtask/getCurrentUserServiceSubtaskCount",
+    method: "post",
+    data: data,
   });
 }
diff --git a/src/components/Assistant/index.vue b/src/components/Assistant/index.vue
index 356ef75..2ee2946 100644
--- a/src/components/Assistant/index.vue
+++ b/src/components/Assistant/index.vue
@@ -1,479 +1,809 @@
 <template>
   <div
-    ref="floatDrag"
-    class="float-position"
-    id="float-box"
-    :style="{
-      left: left + 'px',
-      top: top + 'px',
-      right: right + 'px !important',
-      zIndex: zIndex,
+    ref="floatBall"
+    class="float-ball"
+    :class="{
+      'float-ball-hidden': isHidden && !isHovering,
+      'float-ball-expanded': isExpanded,
     }"
-    @touchmove.prevent
-    @mousemove.prevent
-    @mousedown="mouseDown"
-    @mouseup="mouseUp"
+    :style="{
+      left: position.x + 'px',
+      top: position.y + 'px',
+      '--primary-color': primaryColor,
+      '--hover-color': hoverColor,
+    }"
+    @mouseenter="handleMouseEnter"
+    @mouseleave="handleMouseLeave"
   >
-    <div class="drag">
-      <svg
-        t="1682058484158"
-        class="icon"
-        viewBox="0 0 1024 1024"
-        version="1.1"
-        xmlns="http://www.w3.org/2000/svg"
-        p-id="2023"
-        width="32"
-        height="32"
-      >
-        <path
-          d="M556.297 172.715a42.407 42.407 0 0 1 42.426 42.398l0.837 267.69c-0.118 1.703 0.63 2.737 1.408 2.737 0.63 0 1.29-0.699 1.506-2.284l37.74-208.953c3.732-20.672 21.844-36.166 42.162-36.166a40.074 40.074 0 0 1 7.136 0.64c23.064 4.164 38.391 27.562 34.217 50.587l-33.656 244.529c0 2.559 0.483 4.478 1.32 4.478 0.58 0 1.328-0.935 2.175-3.218l50.144-134.063c6.27-17.65 23.034-29.403 40.793-29.403A39.798 39.798 0 0 1 797.892 374c22.08 7.875 33.626 33.41 25.78 55.47l-87.904 287.191c-0.453 1.585-0.984 3.16-1.437 4.725l-0.187 0.591v0.128a187.031 187.031 0 0 1-177.847 129.1c-53.156 0-108.42-18.752-150.472-51-45.419-27.336-190.968-183.783-190.968-183.783-22.09-22.07-18.792-55.882 3.297-77.962 11.537-11.537 25.919-17.6 40.173-17.6 13.033 0 25.967 5.05 36.51 15.592l63.138 63.157c8.603 8.594 18.132 12.699 26.922 12.699a26.952 26.952 0 0 0 20.88-9.893c7.658-9.037 4.635-36.914 2.49-54.594l-31.668-260.259c-2.825-23.26 13.781-45.724 37.003-48.549a40.497 40.497 0 0 1 4.853-0.295c21.282 0 39.749 16.98 42.387 38.597l34.926 204.425c0.905 2.54 2.342 4.036 3.602 4.036s2.353-1.496 2.58-4.922l11.88-265.741a42.417 42.417 0 0 1 42.467-42.398m0-70.875a113.36 113.36 0 0 0-104.344 69.153c-0.246 0.57-0.482 1.152-0.718 1.732a111.234 111.234 0 0 0-90.022 10.976 113.597 113.597 0 0 0-32.415 29.207 115.23 115.23 0 0 0-19.067 38.489 113.843 113.843 0 0 0-3.465 44.68l21.36 175.77a120.842 120.842 0 0 0-69.3-21.863c-33.468 0-65.549 13.614-90.286 38.332-23.212 23.202-36.993 53.363-38.863 84.952a120.92 120.92 0 0 0 34.502 92.216c5.532 5.906 39.64 42.407 79.203 82.412 74.586 75.422 105.328 99.648 122.702 110.771 53.973 40.36 123.254 63.414 190.674 63.414A257.906 257.906 0 0 0 801.14 745.1c0.247-0.709 0.483-1.417 0.7-2.136l0.117-0.374a178.56 178.56 0 0 0 1.723-5.64l87.413-285.578a113.203 113.203 0 0 0 5.729-42.86 115.585 115.585 0 0 0-35.772-77.135 111.431 111.431 0 0 0-67.45-30.19l0.148-0.985a113.676 113.676 0 0 0-1.201-43.155 115.408 115.408 0 0 0-16.872-39.523 113.774 113.774 0 0 0-30.703-30.968 111.077 111.077 0 0 0-84.981-17.06 113.203 113.203 0 0 0-103.694-67.656z"
-          fill="#ffffff"
-          p-id="2024"
-        ></path>
-      </svg>
-    </div>
-    <div class="content" id="content" @click="handelFlex">
-      <!-- <img src="../../../../assets/image/alarm.png" alt="" /> -->
-      <div class="label">
-        <div v-if="flag">灞曞紑</div>
-        <div v-else>鏀惰捣</div>
-      </div>
-      <div class="item-container">
-        <div
-          v-for="(item, index) in powerList"
-          :key="index"
-          @click.stop="activeHandle(index,item.url)"
+    <!-- 涓荤悆浣� -->
+    <div
+      class="ball-main"
+      :class="{ 'ball-main-expanded': isExpanded }"
+      @click="toggleExpand"
+      @mousedown="startDrag"
+      @touchstart="startDrag"
+    >
+      <!-- 鎶樺彔鐘舵�佸浘鏍� -->
+      <div v-if="!isExpanded" class="ball-icon">
+        <svg
+          class="fold-icon"
+          viewBox="0 0 24 24"
+          fill="none"
+          stroke="currentColor"
+          stroke-width="2"
         >
+          <path d="M4 6h16M4 12h16M4 18h16" />
+        </svg>
+      </div>
+
+      <!-- 灞曞紑鐘舵�佸叧闂寜閽� -->
+      <div v-else class="close-btn" @click.stop="toggleExpand">
+        <svg
+          class="close-icon"
+          viewBox="0 0 24 24"
+          fill="none"
+          stroke="currentColor"
+          stroke-width="2"
+        >
+          <path d="M6 18L18 6M6 6l12 12" />
+        </svg>
+      </div>
+
+      <!-- 瑙掓爣鎻愮ず锛堟湁鏈鏁版椂鏄剧ず锛� -->
+      <div v-if="totalUnread > 0" class="ball-badge">
+        {{ totalUnread > 99 ? "99+" : totalUnread }}
+      </div>
+    </div>
+
+    <!-- 灞曞紑鐨勫唴瀹归潰鏉� -->
+    <transition name="ball-expand">
+      <div v-if="isExpanded" class="ball-content">
+        <div class="content-header">
+          <h3>闅忚宸ヤ綔鍙�</h3>
+          <div class="update-time">鏇存柊浜� {{ updateTime }}</div>
+        </div>
+
+        <div class="stats-grid">
           <div
-            :class="activeIndex == index ? 'active power-item' : 'power-item'"
+            v-for="(item, index) in statsItems"
+            :key="index"
+            class="stat-item"
+            :class="{ 'stat-item-highlight': item.highlight }"
+            @click="handleItemClick(item)"
           >
-            <img :src="item.path" alt="" style="width: 26px" />
+            <div class="stat-icon">
+              <svg
+                v-if="item.icon === 'IconUsers'"
+                viewBox="0 0 24 24"
+                fill="none"
+                stroke="currentColor"
+                stroke-width="2"
+              >
+                <path
+                  d="M12 4.354a4 4 0 110 5.292M15 21H3v-1a6 6 0 0112 0v1zm0 0h6v-1a6 6 0 00-9-5.197m13-7.157a4 4 0 11-8 0 4 4 0 018 0z"
+                />
+              </svg>
+              <svg
+                v-else-if="item.icon === 'IconAlertCircle'"
+                viewBox="0 0 24 24"
+                fill="none"
+                stroke="currentColor"
+                stroke-width="2"
+              >
+                <path d="M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
+              </svg>
+              <svg
+                v-else-if="item.icon === 'IconTask'"
+                viewBox="0 0 24 24"
+                fill="none"
+                stroke="currentColor"
+                stroke-width="2"
+              >
+                <path
+                  d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"
+                />
+              </svg>
+            </div>
+            <div class="stat-info">
+              <div class="stat-label">{{ item.label }}</div>
+              <div class="stat-value">{{ item.value }}</div>
+              <div
+                v-if="item.trend"
+                class="stat-trend"
+                :class="'trend-' + item.trend.type"
+              >
+                <span class="trend-arrow">{{ item.trend.arrow }}</span>
+                <span class="trend-value">{{ item.trend.value }}</span>
+              </div>
+            </div>
+            <div v-if="item.unread > 0" class="stat-badge">
+              {{ item.unread > 99 ? "99+" : item.unread }}
+            </div>
           </div>
-          <div :class="activeIndex == index ? 'active-des des' : 'des'">
-            {{ item.label }}
+        </div>
+
+        <div class="quick-actions">
+          <div
+            v-for="(action, index) in quickActions"
+            :key="index"
+            class="action-item"
+            @click="handleActionClick(action)"
+          >
+            <div class="action-icon">
+              <svg
+                v-if="action.icon === 'IconMessageCircle'"
+                viewBox="0 0 24 24"
+                fill="none"
+                stroke="currentColor"
+                stroke-width="2"
+              >
+                <path
+                  d="M8 12h.01M12 12h.01M16 12h.01M21 12c0 4.418-4.03 8-9 8a9.863 9.863 0 01-4.255-.949L3 20l1.395-3.72C3.512 15.042 3 13.574 3 12c0-4.418 4.03-8 9-8s9 3.582 9 8z"
+                />
+              </svg>
+              <svg
+                v-else-if="action.icon === 'IconPhone'"
+                viewBox="0 0 24 24"
+                fill="none"
+                stroke="currentColor"
+                stroke-width="2"
+              >
+                <path
+                  d="M3 5a2 2 0 012-2h3.28a1 1 0 01.948.684l1.498 4.493a1 1 0 01-.502 1.21l-2.257 1.13a11.042 11.042 0 005.516 5.516l1.13-2.257a1 1 0 011.21-.502l4.493 1.498a1 1 0 01.684.949V19a2 2 0 01-2 2h-1C9.716 21 3 14.284 3 6V5z"
+                />
+              </svg>
+            </div>
+            <div class="action-label">{{ action.label }}</div>
           </div>
         </div>
       </div>
-    </div>
+    </transition>
   </div>
 </template>
 
 <script>
+import { getCurrentUserServiceSubtaskCount } from "@/api/AiCentre/index";
 export default {
-  name: "DragBall",
+  name: "FloatBall",
+
   props: {
-    distanceRight: {
-      type: Number,
-      default: 36,
+    // 鍒濆浣嶇疆
+    initialPosition: {
+      type: Object,
+      default: () => ({ x: 20, y: 100 }),
     },
-    distanceBottom: {
-      type: Number,
-      default: 600,
-    },
-    isScrollHidden: {
-      type: Boolean,
-      default: false,
-    },
-    isCanDraggable: {
+    // 鏄惁鑷姩闅愯棌
+    autoHide: {
       type: Boolean,
       default: true,
     },
-    zIndex: {
+    // 闅愯棌寤惰繜锛堟绉掞級
+    hideDelay: {
       type: Number,
-      default: 50,
+      default: 2000,
     },
-    value: {
+    // 涓婚棰滆壊
+    primaryColor: {
       type: String,
-      default: "鎮诞鐞冿紒",
+      default: "#4f46e5",
+    },
+    // 鎮仠棰滆壊
+    hoverColor: {
+      type: String,
+      default: "#4338ca",
+    },
+    // 鏁版嵁婧愶紙鍙粠澶栭儴浼犲叆锛�
+    statsData: {
+      type: Object,
+      default: null,
     },
   },
+
   data() {
     return {
-      clientWidth: null,
-      clientHeight: null,
-      left: null,
-      top: null,
-      right: null,
-      timer: null,
-      currentTop: 0,
-      mousedownX: 0,
-      mousedownY: 0,
+      isExpanded: false,
+      isHovering: false,
+      isHidden: false,
+      isDragging: false,
+      position: { ...this.initialPosition },
+      dragStart: { x: 0, y: 0 },
+      hideTimer: null,
+      updateTime: "",
+      roles: null,
+      // 缁熻鏁版嵁
+      statsItems: [
+        {
+          id: "pending",
+          label: "寰呴殢璁�",
+          value: "0",
+          unread: 0,
+          urltype: 2,
+          icon: "IconUsers",
+          url: "/followvisit/discharge",
+          trend: { type: "up", arrow: "", value: "" },
+          highlight: true,
+        },
+        {
+          id: "failed",
+          label: "闅忚澶辫触",
+          value: "0",
+          unread: 0,
+          urltype: 3,
+          icon: "IconAlertCircle",
+          url: "/followvisit/discharge",
+          trend: { type: "down", arrow: "", value: "" },
+        },
+        {
+          id: "abnormal",
+          label: "浠诲姟寮傚父",
+          value: "0",
+          unread: 0,
+          urltype: 4,
+          icon: "IconAlertCircle",
+          url: "/followvisit/discharge",
+          trend: { type: "up", arrow: "", value: "" },
+        },
+        {
+          id: "myTasks",
+          label: "鎴戠殑浠诲姟",
+          value: "0",
+          unread: 0,
+          urltype: 5,
+          icon: "IconTask",
+          url: "/followvisit/discharge",
+          trend: { type: "stable", arrow: "", value: "" },
+        },
+      ],
 
-      flag: true, // 鎺у埗鎮诞妗嗘槸鍚﹀睍寮�
-      box: "", // 鎮诞鐞冪殑dom
-      activeIndex: 0, //楂樹寒鏄剧ず
-      powerList: [
+      // 蹇嵎鎿嶄綔
+      quickActions: [
         {
-          path: require("@/assets/images/huanzheliebiao.png"),
-          url:'/patient/patient/',
-          label: "鎮h��",
+          id: "sms",
+          label: "鍒涘缓闂嵎浠诲姟",
+          icon: "IconMessageCircle",
+          url: "/followvisit/QuestionnaireTask?type=2&serviceType=2",
         },
         {
-          path: require("@/assets/images/fwwu.png"),
-          url:'/followvisit/tasklist/',
-          label: "浠诲姟",
+          id: "call",
+          label: "鍒涘缓璇煶浠诲姟",
+          icon: "IconPhone",
+          url: "/followvisit/particty?type=1&serviceType=2",
         },
-        {
-          path: require("@/assets/images/duanxinjilu.png"),
-          url:'',
-          label: "鐭俊",
-        },
-        {
-          path: require("@/assets/images/dianhua.png"),
-          url:'',
-          label: "鐢佃瘽",
-        },
-        {
-          path: require("@/assets/images/zxlt.png"),
-          url:'',
-          label: "鍦ㄧ嚎鑱婂ぉ",
-        },
+        // {
+        //   id: 'chat',
+        //   label: '鍦ㄧ嚎鑱婂ぉ',
+        //   icon: 'IconMessageCircle',
+        //   url: '/chat'
+        // }
       ],
     };
   },
-  created() {
-    this.clientWidth = document.documentElement.clientWidth;
-    this.clientHeight = document.documentElement.clientHeight;
+
+  computed: {
+    totalUnread() {
+      return this.statsItems.reduce((sum, item) => sum + item.unread, 0);
+    },
   },
+
   mounted() {
-    this.isCanDraggable &&
-      this.$nextTick(() => {
-        this.floatDrag = this.$refs.floatDrag;
-        // 鑾峰彇鍏冪礌浣嶇疆灞炴��
-        this.floatDragDom = this.floatDrag.getBoundingClientRect();
-        // 璁剧疆鍒濆浣嶇疆
-        this.left = this.clientWidth - this.floatDragDom.width - this.distanceRight;
-        // this.right = 0;
-        this.top =
-          this.clientHeight - this.floatDragDom.height - this.distanceBottom;
-        this.initDraggable();
-      });
-    // this.isScrollHidden && window.addEventListener('scroll', this.handleScroll);
+    this.roles = this.$store.state.user.roles;
+    this.loadPosition();
+
+    if (this.autoHide) {
+      this.startAutoHide();
+    }
+
+    // 鐐瑰嚮澶栭儴鍏抽棴
+    document.addEventListener("click", this.handleClickOutside);
+
+    // 绐楀彛澶у皬鍙樺寲鏃堕噸鏂板畾浣�
     window.addEventListener("resize", this.handleResize);
-
-    this.box = document.getElementById("float-box");
   },
-  beforeUnmount() {
-    window.removeEventListener("scroll", this.handleScroll);
+
+  beforeDestroy() {
+    document.removeEventListener("click", this.handleClickOutside);
     window.removeEventListener("resize", this.handleResize);
+    clearTimeout(this.hideTimer);
   },
-  methods: {
-    // 浼哥缉鎮诞鐞�
-    handelFlex() {
-      if (this.flag) {
-        this.buffer(this.box, "height", 600);
-      } else {
-        this.buffer(this.box, "height", 70);
-      }
-      this.flag = !this.flag;
-      console.log("鏄惁灞曞紑", this.flag);
-    },
-    // 鐐瑰嚮鍝釜power
-    activeHandle(index,url) {
-      //鎶婃垜浠嚜瀹氫箟鐨勪笅鏍囪祴鍊�
-      this.activeIndex = index;
-      this.$router.push({
-        path: url,
-      })
-      console.log("HHHH", index);
-    },
-    // 鑾峰彇瑕佹敼鍙樺緱鏍峰紡灞炴��
-    getStyleAttr(obj, attr) {
-      if (obj.currentStyle) {
-        // IE 鍜� opera
-        return obj.currentStyle[attr];
-      } else {
-        return window.getComputedStyle(obj, null)[attr];
-      }
-    },
-    // 鍔ㄧ敾鍑芥暟
-    buffer(eleObj, attr, target) {
-      // setInterval鏂瑰紡寮�鍚姩鐢�
-      //鍏堟竻鍚庤
-      // clearInterval(eleObj.timer);
-      // let speed = 0
-      // let begin = 0
-      // //璁剧疆瀹氭椂鍣�
-      // eleObj.timer = setInterval(() => {
-      //     //鑾峰彇鍔ㄧ敾灞炴�х殑鍒濆鍊�
-      //     begin = parseInt(this.getStyleAttr(eleObj, attr));
-      //     speed = (target - begin) * 0.2;
-      //     speed = target > begin ? Math.ceil(speed) : Math.floor(speed);
-      //     eleObj.style[attr] = begin + speed + "px";
-      //     if (begin === target) {
-      //         clearInterval(eleObj.timer);
-      //     }
-      // }, 20);
-      // cancelAnimationFrame寮�鍚姩鐢�
-      // 鍏堟竻鍚庤
-      cancelAnimationFrame(eleObj.timer);
-      let speed = 0;
-      let begin = 0;
-      let _this = this;
-      eleObj.timer = requestAnimationFrame(function fn() {
-        begin = parseInt(_this.getStyleAttr(eleObj, attr));
-        // 鍔ㄧ敾閫熷害
-        speed = (target - begin) * 0.9;
-        speed = target > begin ? Math.ceil(speed) : Math.floor(speed);
-        eleObj.style[attr] = begin + speed + "px";
-        eleObj.timer = requestAnimationFrame(fn);
-        if (begin === target) {
-          cancelAnimationFrame(eleObj.timer);
-        }
-      });
-    },
-    /**
-     * 绐楀彛resize鐩戝惉
-     */
-    handleResize() {
-      // this.clientWidth = document.documentElement.clientWidth;
-      // this.clientHeight = document.documentElement.clientHeight;
-      // console.log(window.innerWidth);
-      // console.log(document.documentElement.clientWidth);
 
-      this.checkDraggablePosition();
-    },
-    /**
-     * 鍒濆鍖杁raggable
-     */
-    initDraggable() {
-      this.floatDrag.addEventListener("touchstart", this.toucheStart);
-      this.floatDrag.addEventListener("touchmove", (e) => this.touchMove(e));
-      this.floatDrag.addEventListener("touchend", this.touchEnd);
-    },
-    mouseDown(e) {
-      const event = e || window.event;
-      this.mousedownX = event.screenX;
-      this.mousedownY = event.screenY;
-      const that = this;
-      let floatDragWidth = this.floatDragDom.width / 2;
-      let floatDragHeight = this.floatDragDom.height / 2;
-      if (event.preventDefault) {
-        event.preventDefault();
+  methods: {
+    toggleExpand() {
+      this.isExpanded = !this.isExpanded;
+      if (this.isExpanded) {
+        this.isHidden = false;
+        clearTimeout(this.hideTimer);
+        this.updateStats();
       }
-      this.canClick = false;
-      this.floatDrag.style.transition = "none";
-      document.onmousemove = function (e) {
-        var event = e || window.event;
-        that.left = event.clientX - floatDragWidth;
-        that.top = event.clientY - floatDragHeight;
-        if (that.left < 0) that.left = 0;
-        if (that.top < 0) that.top = 0;
-        // 榧犳爣绉诲嚭鍙鍖哄煙鍚庣粰鎸夐挳杩樺師
-        if (
-          event.clientY < 0 ||
-          event.clientY > Number(this.clientHeight) ||
-          event.clientX > Number(this.clientWidth) ||
-          event.clientX < 0
-        ) {
-          this.right = 0;
-          this.top =
-            this.clientHeight - this.floatDragDom.height - this.distanceBottom;
-          document.onmousemove = null;
-          this.floatDrag.style.transition = "all 0.3s";
-          return;
+    },
+
+    handleMouseEnter() {
+      this.isHovering = true;
+      if (this.autoHide) {
+        clearTimeout(this.hideTimer);
+        this.isHidden = false;
+      }
+    },
+
+    handleMouseLeave() {
+      this.isHovering = false;
+      if (this.autoHide && !this.isExpanded) {
+        this.startAutoHide();
+      }
+    },
+
+    startAutoHide() {
+      this.hideTimer = setTimeout(() => {
+        if (!this.isExpanded && !this.isHovering) {
+          this.isHidden = true;
         }
-        if (
-          that.left >=
-          document.documentElement.clientWidth - floatDragWidth * 2
-        ) {
-          that.left = document.documentElement.clientWidth - floatDragWidth * 2;
+      }, this.hideDelay);
+    },
+
+    startDrag(e) {
+      e.preventDefault();
+      e.stopPropagation();
+      this.isDragging = true;
+
+      const clientX = e.type.includes("touch")
+        ? e.touches[0].clientX
+        : e.clientX;
+      const clientY = e.type.includes("touch")
+        ? e.touches[0].clientY
+        : e.clientY;
+
+      this.dragStart = {
+        x: clientX - this.position.x,
+        y: clientY - this.position.y,
+      };
+
+      const onMove = (moveEvent) => {
+        if (!this.isDragging) return;
+
+        const moveX = moveEvent.type.includes("touch")
+          ? moveEvent.touches[0].clientX
+          : moveEvent.clientX;
+        const moveY = moveEvent.type.includes("touch")
+          ? moveEvent.touches[0].clientY
+          : moveEvent.clientY;
+
+        const newX = moveX - this.dragStart.x;
+        const newY = moveY - this.dragStart.y;
+
+        // 杈圭晫妫�鏌�
+        const maxX = window.innerWidth - 60;
+        const maxY = window.innerHeight - 60;
+
+        this.position.x = Math.max(0, Math.min(newX, maxX));
+        this.position.y = Math.max(0, Math.min(newY, maxY));
+      };
+
+      const onEnd = () => {
+        this.isDragging = false;
+        document.removeEventListener("mousemove", onMove);
+        document.removeEventListener("mouseup", onEnd);
+        document.removeEventListener("touchmove", onMove);
+        document.removeEventListener("touchend", onEnd);
+
+        // 濡傛灉闈犺繎杈圭紭锛岃嚜鍔ㄥ惛闄�
+        if (this.position.x < 20) {
+          this.position.x = 0;
+        } else if (this.position.x > window.innerWidth - 80) {
+          this.position.x = window.innerWidth - 60;
         }
-        if (that.top >= that.clientHeight - floatDragHeight * 2) {
-          that.top = that.clientHeight - floatDragHeight * 2;
+
+        // 淇濆瓨浣嶇疆鍒版湰鍦板瓨鍌�
+        try {
+          localStorage.setItem(
+            "floatBallPosition",
+            JSON.stringify(this.position)
+          );
+        } catch (e) {
+          console.error("淇濆瓨浣嶇疆澶辫触:", e);
         }
       };
+
+      document.addEventListener("mousemove", onMove);
+      document.addEventListener("mouseup", onEnd);
+      document.addEventListener("touchmove", onMove, { passive: false });
+      document.addEventListener("touchend", onEnd);
     },
-    mouseUp(e) {
-      const event = e || window.event;
-      //鍒ゆ柇鍙槸鍗曠函鐨勭偣鍑伙紝娌℃湁鎷栨嫿
+
+    handleItemClick(item) {
+      if (item.url) {
+        console.log(item.url, "item.url");
+
+        // this.$router.push(item.url);
+        this.$router.replace({
+          path: item.url,
+          query: {
+            errtype: item.urltype,
+          },
+        });
+        this.toggleExpand();
+      }
+    },
+
+    handleActionClick(action) {
+      console.log(this.roles, "this.roles");
       if (
-        this.mousedownY == event.screenY &&
-        this.mousedownX == event.screenX
+        action.url &&
+        (this.roles.includes("admin") || this.roles.includes("sysadmin"))
       ) {
-        this.$emit("handlepaly");
-      }
-      document.onmousemove = null;
-      this.checkDraggablePosition();
-      this.floatDrag.style.transition = "all 0.3s";
-    },
-    toucheStart() {
-      this.canClick = false;
-      this.floatDrag.style.transition = "none";
-    },
-    touchMove(e) {
-      this.canClick = true;
-      if (e.targetTouches.length === 1) {
-        // 鍗曟寚鎷栧姩
-        let touch = event.targetTouches[0];
-        this.left = touch.clientX - this.floatDragDom.width / 2;
-        this.top = touch.clientY - this.floatDragDom.height / 2;
-      }
-    },
-    touchEnd() {
-      if (!this.canClick) return; // 瑙e喅鐐瑰嚮浜嬩欢鍜宼ouch浜嬩欢鍐茬獊鐨勯棶棰�
-      this.floatDrag.style.transition = "all 0.3s";
-      this.checkDraggablePosition();
-    },
-    /**
-     * 鍒ゆ柇鍏冪礌鏄剧ず浣嶇疆
-     * 鍦ㄧ獥鍙f敼鍙樺拰move end鏃惰皟鐢�
-     */
-    checkDraggablePosition() {
-      this.clientWidth = document.documentElement.clientWidth;
-      this.clientHeight = document.documentElement.clientHeight;
-      if (this.left + this.floatDragDom.width / 2 >= this.clientWidth / 2) {
-        // 鍒ゆ柇浣嶇疆鏄線宸﹀線鍙虫粦鍔�
-        this.left = this.clientWidth - this.floatDragDom.width;
+        this.$router.replace(action.url);
+        this.toggleExpand();
       } else {
-        this.left = 0;
+        this.$modal.msgError("闈炵鐞嗗憳鐢ㄦ埛鏆傛棤鍒涘缓浠诲姟鏉冮檺");
       }
-      if (this.top < 0) {
-        // 鍒ゆ柇鏄惁瓒呭嚭灞忓箷涓婃部
-        this.top = 0;
+    },
+
+    async updateStats() {
+      try {
+        // 杩欓噷鍙互鏇挎崲涓哄疄闄呯殑 API 璋冪敤
+        // const response = await this.$api.getFollowupStats()
+        // this.statsItems = response.data
+
+        // 妯℃嫙鏁版嵁鏇存柊
+        const mockData = {
+          pending: {
+            value: "128",
+            unread: null,
+            trend: { type: "up", arrow: "鈫�", value: "5" },
+          },
+          failed: {
+            value: "24",
+            unread: null,
+            trend: { type: "down", arrow: "鈫�", value: "2" },
+          },
+          abnormal: {
+            value: "8",
+            unread: null,
+            trend: { type: "up", arrow: "鈫�", value: "3" },
+          },
+          myTasks: {
+            value: "156",
+            unread: null,
+            trend: { type: "stable", arrow: "鈫�", value: "0" },
+          },
+        };
+        const response = await getCurrentUserServiceSubtaskCount();
+        mockData.pending.value = response.pendingVisitCount;
+        mockData.failed.value = response.failedVisitCount;
+        mockData.abnormal.value = response.abnormalVisitCount;
+        mockData.myTasks.value = response.allVisitCount;
+        this.statsItems = this.statsItems.map((item) => {
+          const data = mockData[item.id] || {};
+          return {
+            ...item,
+            value: data.value || item.value,
+            unread: data.unread || item.unread,
+            trend: data.trend || item.trend,
+          };
+        });
+
+        // 鏇存柊鏃堕棿
+        const now = new Date();
+        this.updateTime = `${now.getHours().toString().padStart(2, "0")}:${now
+          .getMinutes()
+          .toString()
+          .padStart(2, "0")}`;
+      } catch (error) {
+        console.error("鏇存柊缁熻鏁版嵁澶辫触:", error);
       }
-      if (this.top + this.floatDragDom.height >= this.clientHeight) {
-        // 鍒ゆ柇鏄惁瓒呭嚭灞忓箷涓嬫部
-        this.top = this.clientHeight - this.floatDragDom.height;
+    },
+
+    loadPosition() {
+      try {
+        const savedPosition = localStorage.getItem("floatBallPosition");
+        if (savedPosition) {
+          const parsed = JSON.parse(savedPosition);
+          this.position = parsed;
+        }
+      } catch (e) {
+        console.error("鍔犺浇浣嶇疆澶辫触:", e);
       }
+    },
+
+    handleClickOutside(e) {
+      if (
+        this.isExpanded &&
+        this.$refs.floatBall &&
+        !this.$refs.floatBall.contains(e.target)
+      ) {
+        this.toggleExpand();
+      }
+    },
+
+    handleResize() {
+      const maxX = window.innerWidth - 60;
+      const maxY = window.innerHeight - 60;
+
+      this.position.x = Math.min(this.position.x, maxX);
+      this.position.y = Math.min(this.position.y, maxY);
     },
   },
 };
 </script>
-<style>
-html,
-body {
-  overflow: hidden;
-}
-</style>
-<style scoped lang="scss">
-.float-position {
+
+<style scoped>
+.float-ball {
   position: fixed;
-  z-index: 10003 !important;
-  left: 0;
-  top: 20%;
-  width: 70px;
-  height: 70px;
-  border-radius: 32px;
+  z-index: 9999;
+  transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
+  pointer-events: auto;
+}
+
+.float-ball-hidden {
+  opacity: 0.3;
+  transform: translateX(10px);
+}
+
+.float-ball-hidden:hover {
+  opacity: 1;
+  transform: translateX(0);
+}
+
+.ball-main {
+  width: 60px;
+  height: 60px;
+  border-radius: 50%;
+  background: linear-gradient(135deg, var(--primary-color), #7c3aed);
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  cursor: move;
+  box-shadow: 0 4px 20px rgba(79, 70, 229, 0.3);
+  transition: all 0.3s ease;
+  position: relative;
+  z-index: 10000;
+}
+
+.ball-main:hover {
+  background: linear-gradient(135deg, var(--hover-color), #6d28d9);
+  box-shadow: 0 6px 25px rgba(79, 70, 229, 0.4);
+  transform: scale(1.05);
+}
+
+.ball-main-expanded {
+  background: linear-gradient(135deg, #6366f1, #8b5cf6);
+}
+
+.ball-icon {
+  width: 24px;
+  height: 24px;
+  color: white;
+}
+
+.fold-icon {
+  width: 100%;
+  height: 100%;
+}
+
+.close-btn {
+  width: 24px;
+  height: 24px;
+  display: flex;
+  align-items: center;
+  justify-content: center;
   cursor: pointer;
-  overflow: hidden;
-  user-select: none;
+  color: white;
+  transition: transform 0.2s ease;
+}
 
-  display: block;
-  background: black;
-  background: -webkit-radial-gradient(100px 100px, circle, #5788FE, #292929);
-  //   background: -moz-radial-gradient(100px 100px, circle, #35a1a1, #000);Firefox 娴忚鍣ㄧ殑瀹炵幇
-  //   background: radial-gradient(100px 100px, circle, #35a1a1, #000);鏍囧噯 HTML5 灞炴��
-  margin: 0;
-  .drag {
-    width: 70px;
-    height: 35px;
-    // background: #f2e96a;
-    text-align: center;
-    line-height: 35px;
-    border-bottom: 1px solid #fff;
+.close-btn:hover {
+  transform: rotate(90deg);
+}
+
+.close-icon {
+  width: 20px;
+  height: 20px;
+}
+
+.ball-badge {
+  position: absolute;
+  top: -5px;
+  right: -5px;
+  min-width: 20px;
+  height: 20px;
+  padding: 0 6px;
+  background: #ef4444;
+  color: white;
+  font-size: 12px;
+  font-weight: 600;
+  border-radius: 10px;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  border: 2px solid white;
+  animation: pulse 2s infinite;
+}
+
+@keyframes pulse {
+  0%,
+  100% {
+    transform: scale(1);
   }
-  .content {
-    width: 70px;
-    height: 35px;
-    // background: #716af2;
-    .label {
-      width: 70px;
-      height: 35px;
-      text-align: center;
-      line-height: 35px;
-      color: white;
-    }
-    .label:hover {
-      color: rgb(19, 217, 243);
-      transition: all 0.5;
-    }
-
-    .item-container {
-      margin-top: 10px;
-      width: 70px;
-      height: 500px;
-      display: flex;
-      justify-content: space-between;
-      align-items: center;
-      flex-direction: column;
-
-      .power-item {
-        width: 40px;
-        height: 40px;
-        border-radius: 50%;
-        background-color: #f1f7ff;
-        display: flex;
-        justify-content: center;
-        align-items: center;
-        flex-direction: column;
-      }
-      .des {
-        width: 40px;
-        text-align: center;
-        margin-bottom: 5px;
-        font-size: 10px;
-        color: #fff;
-      }
-    }
-  }
-
-  .close {
-    width: 20px;
-    height: 20px;
-    border-radius: 50%;
-    display: flex;
-    align-items: center;
-    justify-content: center;
-    color: #fff;
-    background: rgba(0, 0, 0, 0.6);
-    position: absolute;
-    right: -10px;
-    top: -12px;
-    cursor: pointer;
+  50% {
+    transform: scale(1.1);
   }
 }
 
-.cart {
-  border-radius: 50%;
-  width: 5em;
-  height: 5em;
+.ball-content {
+  position: absolute;
+  top: 70px;
+  left: 0;
+  width: 320px;
+  background: white;
+  border-radius: 16px;
+  box-shadow: 0 10px 40px rgba(0, 0, 0, 0.1);
+  overflow: hidden;
+  z-index: 9999;
+}
+
+.ball-expand-enter-active,
+.ball-expand-leave-active {
+  transition: all 0.3s ease;
+}
+
+.ball-expand-enter,
+.ball-expand-leave-to {
+  opacity: 0;
+  transform: translateY(-10px);
+}
+
+.content-header {
+  padding: 20px 20px 16px;
+  background: linear-gradient(135deg, var(--primary-color), #7c3aed);
+  color: white;
+}
+
+.content-header h3 {
+  margin: 0 0 8px 0;
+  font-size: 18px;
+  font-weight: 600;
+}
+
+.update-time {
+  font-size: 12px;
+  opacity: 0.9;
+}
+
+.stats-grid {
+  padding: 16px;
+  display: grid;
+  grid-template-columns: 1fr 1fr;
+  gap: 12px;
+}
+
+.stat-item {
+  padding: 16px;
+  background: #f8fafc;
+  border-radius: 12px;
+  cursor: pointer;
+  transition: all 0.2s ease;
+  position: relative;
+  border: 2px solid transparent;
+}
+
+.stat-item:hover {
+  background: #f1f5f9;
+  border-color: #e2e8f0;
+  transform: translateY(-2px);
+}
+
+.stat-item-highlight {
+  border-color: var(--primary-color);
+  background: linear-gradient(to bottom right, #f0f9ff, #f8fafc);
+}
+
+.stat-icon {
+  width: 32px;
+  height: 32px;
+  background: white;
+  border-radius: 8px;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  margin-bottom: 12px;
+  color: var(--primary-color);
+  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
+}
+
+.stat-icon svg {
+  width: 18px;
+  height: 18px;
+}
+
+.stat-label {
+  font-size: 12px;
+  color: #64748b;
+  margin-bottom: 4px;
+}
+
+.stat-value {
+  font-size: 20px;
+  font-weight: 700;
+  color: #1e293b;
+  margin-bottom: 4px;
+}
+
+.stat-trend {
+  font-size: 11px;
+  display: flex;
+  align-items: center;
+  gap: 2px;
+}
+
+.trend-up {
+  color: #10b981;
+}
+
+.trend-down {
+  color: #ef4444;
+}
+
+.trend-stable {
+  color: #64748b;
+}
+
+.trend-arrow {
+  font-size: 10px;
+}
+
+.stat-badge {
+  position: absolute;
+  top: 12px;
+  right: 12px;
+  min-width: 18px;
+  height: 18px;
+  padding: 0 4px;
+  background: #ef4444;
+  color: white;
+  font-size: 10px;
+  font-weight: 600;
+  border-radius: 9px;
   display: flex;
   align-items: center;
   justify-content: center;
 }
 
-.header-notice {
-  display: inline-block;
-  transition: all 0.3s;
-
-  span {
-    vertical-align: initial;
-  }
-
-  .notice-badge {
-    color: inherit;
-
-    .header-notice-icon {
-      font-size: 16px;
-      padding: 4px;
-    }
-  }
+.quick-actions {
+  padding: 12px 20px 20px;
+  border-top: 1px solid #f1f5f9;
+  display: flex;
+  gap: 12px;
+  justify-content: center;
 }
 
-.drag-ball .drag-content {
-  overflow-wrap: break-word;
-  font-size: 14px;
-  color: #fff;
-  letter-spacing: 2px;
+.action-item {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  gap: 8px;
+  cursor: pointer;
+  padding: 12px;
+  border-radius: 8px;
+  transition: all 0.2s ease;
+  flex: 1;
 }
 
-.active {
-  background-color: #f9f1db !important;
+.action-item:hover {
+  background: #f8fafc;
 }
-.active-des {
-  color: #71dcfa !important;
-  font-size: 20px !important;
-  font-weight: 500 !important;
+
+.action-icon {
+  width: 24px;
+  height: 24px;
+  color: var(--primary-color);
+}
+
+.action-icon svg {
+  width: 20px;
+  height: 20px;
+}
+
+.action-label {
+  font-size: 12px;
+  color: #475569;
+  font-weight: 500;
 }
 </style>
diff --git a/src/store/modules/user.js b/src/store/modules/user.js
index 4d12013..20931b9 100644
--- a/src/store/modules/user.js
+++ b/src/store/modules/user.js
@@ -205,7 +205,7 @@
             } else if (orgid == "47231077933110211A1101") {
               localStorage.setItem("orgname", "鑾查兘鍖轰汉姘戝尰闄�");
               localStorage.setItem("ZuHuID", "1429338802177000011");
-              localStorage.setItem("deptCode", "");
+              localStorage.setItem("deptCode", "01020901");
               localStorage.setItem("YongHuID", "1512710152715767808");
               localStorage.setItem("YongHuXM", "LDRMYY");
             } else if (orgid == "1" && campusid == 1) {
diff --git a/src/views/Satisfaction/1.vue b/src/views/Satisfaction/1.vue
new file mode 100644
index 0000000..b3544ca
--- /dev/null
+++ b/src/views/Satisfaction/1.vue
@@ -0,0 +1,1814 @@
+<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/configurationmyd/index.vue b/src/views/Satisfaction/configurationmyd/index.vue
new file mode 100644
index 0000000..8aa3dc9
--- /dev/null
+++ b/src/views/Satisfaction/configurationmyd/index.vue
@@ -0,0 +1,1246 @@
+<template>
+  <div class="satisfaction-exception-config">
+    <!-- 椤甸潰鏍囬 -->
+    <div class="page-header">
+      <div class="header-content">
+        <h2 class="page-title">婊℃剰搴﹂鐩紓甯稿鐞嗛厤缃�</h2>
+        <p class="page-description">
+          涓烘弧鎰忓害棰樼洰閰嶇疆璐d换绉戝鍜屾姤澶囩瀹わ紝浼樺寲寮傚父鍙嶉娴佺▼
+        </p>
+      </div>
+    </div>
+
+    <!-- 鎼滅储鍖哄煙 -->
+    <div class="search-card">
+      <el-card shadow="never" class="search-container">
+        <el-form :model="queryParams" :inline="true" size="medium">
+          <el-form-item label="闂涓婚">
+            <el-input
+              v-model="queryParams.scriptTopic"
+              placeholder="璇疯緭鍏ラ棶棰樹富棰�"
+              clearable
+              @keyup.enter.native="handleQuery"
+            />
+          </el-form-item>
+          <el-form-item label="闂鍐呭">
+            <el-input
+              v-model="queryParams.scriptContent"
+              placeholder="璇疯緭鍏ラ棶棰樺唴瀹�"
+              clearable
+              @keyup.enter.native="handleQuery"
+            />
+          </el-form-item>
+          <el-form-item label="鏄惁鍙敤">
+            <el-select
+              v-model="queryParams.isavailable"
+              placeholder="璇烽�夋嫨"
+              clearable
+            >
+              <el-option
+                v-for="item in qyoptions"
+                :key="item.value"
+                :label="item.label"
+                :value="item.value"
+              />
+            </el-select>
+          </el-form-item>
+          <el-form-item>
+            <el-button
+              type="primary"
+              icon="el-icon-search"
+              @click="handleQuery"
+            >
+              鎼滅储
+            </el-button>
+            <el-button icon="el-icon-refresh" @click="resetQuery">
+              閲嶇疆
+            </el-button>
+          </el-form-item>
+        </el-form>
+      </el-card>
+    </div>
+
+    <!-- 閰嶇疆鍒楄〃 -->
+    <div class="config-content">
+      <!-- 鎵归噺鎿嶄綔鏍� -->
+      <div v-if="questionList.length > 0" class="batch-actions-card">
+        <el-card shadow="never">
+          <div class="batch-actions">
+            <el-button
+              type="success"
+              icon="el-icon-check"
+              :loading="batchSaving"
+              :disabled="!hasChanges || batchSaving"
+              @click="handleBatchSave"
+              size="medium"
+            >
+              {{ batchSaving ? "鎵归噺淇濆瓨涓�..." : "鎵归噺淇濆瓨閰嶇疆" }}
+            </el-button>
+            <span v-if="changedCount > 0" class="change-count">
+              鏈� {{ changedCount }} 椤归厤缃渶瑕佷繚瀛�
+            </span>
+            <div class="total-count">鍏� {{ total }} 鏉¤褰�</div>
+          </div>
+        </el-card>
+      </div>
+
+      <div v-if="loading" class="loading-wrapper">
+        <div class="loading-spinner">
+          <i class="el-icon-loading"></i>
+          <span>鍔犺浇涓�...</span>
+        </div>
+      </div>
+
+      <div v-else-if="questionList.length === 0" class="empty-wrapper">
+        <el-empty description="鏆傛棤婊℃剰搴﹂鐩暟鎹�">
+          <el-button type="primary" @click="getQuestionList"
+            >鍒锋柊鏁版嵁</el-button
+          >
+        </el-empty>
+      </div>
+
+      <!-- 涓�琛屼竴琛岀殑鍗$墖鍒楄〃 -->
+      <div v-else class="question-list">
+        <div
+          v-for="(question, index) in questionList"
+          :key="question.id"
+          class="question-item"
+        >
+          <el-card
+            shadow="hover"
+            class="question-card"
+            :class="{ 'has-changes': question.hasChanges }"
+          >
+            <!-- 鍗$墖澶撮儴 -->
+            <div class="card-header">
+              <div class="header-left">
+                <div class="question-index">
+                  <span class="index-number">{{ index + 1 }}</span>
+                  <div class="index-line"></div>
+                </div>
+                <div class="question-basic-info">
+                  <div class="question-title-section">
+                    <h3 class="question-topic" :title="question.scriptTopic">
+                      {{ question.scriptTopic || "鏃犱富棰�" }}
+                    </h3>
+                    <div class="question-tags">
+                      <el-tag
+                        :type="question.isavailable == 1 ? 'danger' : 'success'"
+                        size="small"
+                      >
+                        {{ question.isavailable == 1 ? "涓嶅彲鐢�" : "鍙敤" }}
+                      </el-tag>
+                      <dict-tag
+                        :options="askvaluetype"
+                        :value="question.scriptType"
+                        size="small"
+                      />
+                      <el-tag
+                        v-if="question.targetname"
+                        size="small"
+                        type="info"
+                      >
+                        {{ question.targetname }}
+                      </el-tag>
+                    </div>
+                  </div>
+                  <div class="question-content-section">
+                    <span class="content-label">棰樼洰鍐呭锛�</span>
+                    <span class="content-text">{{
+                      question.scriptContent
+                    }}</span>
+                  </div>
+                </div>
+              </div>
+              <div class="header-right">
+                <el-button
+                  type="text"
+                  icon="el-icon-view"
+                  @click="previewQuestion(question)"
+                  size="small"
+                >
+                  棰勮
+                </el-button>
+              </div>
+            </div>
+
+            <!-- 寮傚父澶勭悊閰嶇疆 -->
+            <div class="config-section">
+              <div class="config-title">
+                <i class="el-icon-setting"></i>
+                <span>寮傚父澶勭悊閰嶇疆</span>
+              </div>
+
+              <el-form
+                :model="question.exceptionConfig"
+                :rules="configRules"
+                ref="configForm"
+                label-width="100px"
+                size="small"
+                class="config-form"
+              >
+                <div class="config-fields">
+                  <!-- 璐d换绉戝 -->
+                  <div class="config-field">
+                    <el-form-item
+                      label="璐d换绉戝"
+                      prop="responsibilityDept"
+                      class="config-item"
+                    >
+                      <el-select
+                        v-model="question.exceptionConfig.responsibilityDept"
+                        placeholder="璇烽�夋嫨璐d换绉戝"
+                        filterable
+                        clearable
+                        style="width: 100%"
+                        @change="handleConfigChange(question)"
+                      >
+                        <el-option
+                          v-for="dept in deptOptions"
+                          :key="dept.id"
+                          :label="dept.name"
+                          :value="dept.id"
+                        />
+                      </el-select>
+                      <div class="config-tip">璐熻矗澶勭悊璇ラ鐩弽棣堢殑绉戝</div>
+                    </el-form-item>
+                  </div>
+
+                  <!-- 鎶ュ绉戝 -->
+                  <div class="config-field">
+                    <el-form-item
+                      label="鎶ュ绉戝"
+                      prop="reportDept"
+                      class="config-item"
+                    >
+                      <el-select
+                        v-model="question.exceptionConfig.reportDept"
+                        placeholder="璇烽�夋嫨鎶ュ绉戝"
+                        filterable
+                        clearable
+                        multiple
+                        collapse-tags
+                        style="width: 100%"
+                        @change="handleConfigChange(question)"
+                      >
+                        <el-option
+                          v-for="dept in deptOptions"
+                          :key="dept.id"
+                          :label="dept.name"
+                          :value="dept.id"
+                        />
+                      </el-select>
+                      <div class="config-tip">
+                        闇�瑕佹帴鏀跺紓甯稿弽棣堢殑绉戝锛屽彲澶氶��
+                      </div>
+                    </el-form-item>
+                  </div>
+
+                  <!-- 閫氱煡鏂瑰紡 -->
+                  <div class="config-field">
+                    <el-form-item
+                      label="閫氱煡鏂瑰紡"
+                      prop="notifyTypes"
+                      class="config-item"
+                    >
+                      <el-checkbox-group
+                        v-model="question.exceptionConfig.notifyTypes"
+                        @change="handleConfigChange(question)"
+                      >
+                        <el-checkbox label="system">绯荤粺娑堟伅</el-checkbox>
+                        <el-checkbox label="sms">鐭俊</el-checkbox>
+                        <el-checkbox label="email">閭欢</el-checkbox>
+                        <el-checkbox label="wechat">浼佷笟寰俊</el-checkbox>
+                      </el-checkbox-group>
+                    </el-form-item>
+                  </div>
+                </div>
+
+                <!-- 閰嶇疆鐘舵�佸拰鎿嶄綔鎸夐挳 -->
+                <div class="config-footer">
+                  <div v-if="question.saveStatus" class="save-status">
+                    <el-alert
+                      :type="question.saveStatus.type"
+                      :title="question.saveStatus.message"
+                      :closable="false"
+                      show-icon
+                      :effect="
+                        question.saveStatus.type === 'success'
+                          ? 'dark'
+                          : 'light'
+                      "
+                      size="small"
+                    />
+                  </div>
+
+                  <div class="config-actions">
+                    <el-button
+                      type="primary"
+                      :loading="question.saving"
+                      :disabled="!question.hasChanges"
+                      @click="saveSingleConfig(question)"
+                      size="small"
+                      icon="el-icon-check"
+                    >
+                      {{ question.saving ? "淇濆瓨涓�..." : "淇濆瓨閰嶇疆" }}
+                    </el-button>
+                    <el-button
+                      v-if="question.hasChanges"
+                      type="text"
+                      @click="resetSingleConfig(question)"
+                      size="small"
+                    >
+                      閲嶇疆
+                    </el-button>
+                  </div>
+                </div>
+              </el-form>
+            </div>
+          </el-card>
+        </div>
+      </div>
+
+      <!-- 鍒嗛〉 -->
+      <div v-if="questionList.length > 0" class="pagination-wrapper">
+        <pagination
+          v-show="total > 0"
+          :total="total"
+          :page.sync="queryParams.pageNum"
+          :limit.sync="queryParams.pageSize"
+          @pagination="getQuestionList"
+        />
+      </div>
+    </div>
+
+    <!-- 棰樼洰棰勮瀵硅瘽妗� -->
+    <el-dialog
+      title="棰樼洰棰勮"
+      :visible.sync="previewVisible"
+      width="600px"
+      center
+    >
+      <div v-if="currentPreview" class="preview-wrapper">
+        <div class="preview-header">
+          <h4>{{ currentPreview.scriptTopic || "鏃犱富棰�" }}</h4>
+          <div class="preview-tags">
+            <dict-tag
+              :options="askvaluetype"
+              :value="currentPreview.scriptType"
+              size="small"
+            />
+            <el-tag
+              :type="currentPreview.isavailable === 1 ? 'success' : 'danger'"
+              size="small"
+            >
+              {{ currentPreview.isavailable === 1 ? "鍙敤" : "涓嶅彲鐢�" }}
+            </el-tag>
+            <el-tag v-if="currentPreview.targetname" size="small" type="info">
+              {{ currentPreview.targetname }}
+            </el-tag>
+          </div>
+        </div>
+
+        <div class="preview-content">
+          <p class="preview-question">{{ currentPreview.scriptContent }}</p>
+
+          <div
+            v-if="
+              currentPreview.scriptType != 3 && currentPreview.scriptType != 4
+            "
+            class="preview-options"
+          >
+            <el-radio-group v-model="previewAnswer">
+              <el-radio
+                v-for="(option, idx) in currentPreview.svyLibScriptOptions ||
+                []"
+                :key="idx"
+                :label="option.optioncontent"
+                class="option-item"
+              >
+                {{ option.optioncontent }}
+              </el-radio>
+            </el-radio-group>
+          </div>
+
+          <div v-else class="preview-textarea">
+            <el-input
+              type="textarea"
+              placeholder="璇疯緭鍏ュ洖绛�"
+              v-model="previewAnswer"
+              :rows="4"
+            />
+          </div>
+        </div>
+      </div>
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="previewVisible = false">鍏抽棴</el-button>
+      </span>
+    </el-dialog>
+
+    <!-- 淇濆瓨鎴愬姛鎻愮ず -->
+    <el-dialog
+      title="淇濆瓨鎴愬姛"
+      :visible.sync="saveSuccessVisible"
+      width="400px"
+      center
+    >
+      <div class="success-content">
+        <i class="el-icon-success success-icon"></i>
+        <p class="success-text">閰嶇疆宸叉垚鍔熶繚瀛橈紒</p>
+      </div>
+      <span slot="footer" class="dialog-footer">
+        <el-button type="primary" @click="saveSuccessVisible = false"
+          >纭畾</el-button
+        >
+      </span>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import {
+  getissuelist,
+  compileissue,
+  getissueclassify,
+} from "@/api/AiCentre/index";
+import store from "@/store";
+import Pagination from "@/components/Pagination";
+
+export default {
+  name: "SatisfactionExceptionConfig",
+  components: { Pagination },
+  data() {
+    return {
+      // 鏌ヨ鍙傛暟
+      queryParams: {
+        pageNum: 1,
+        pageSize: 10,
+        scriptTopic: "",
+        scriptContent: "",
+        targetname: "",
+        isavailable: "",
+        categoryids: "404,405,406", // 鍥哄畾鏌ヨ婊℃剰搴︾被鍨�
+      },
+
+      // 鏁版嵁鍒楄〃
+      questionList: [],
+      total: 0,
+      loading: false,
+      batchSaving: false,
+
+      // 瀛楀吀鏁版嵁
+      askvaluetype: store.getters.askvaluetype || [],
+      qyoptions: store.getters.usable || [],
+      mode: store.getters.mode || [],
+      languagelist: store.getters.languagelist || [],
+
+      // 绉戝閫夐」
+      deptOptions: [],
+
+      // 棰勮鐩稿叧
+      previewVisible: false,
+      currentPreview: null,
+      previewAnswer: "",
+
+      // 淇濆瓨鐩稿叧
+      saveSuccessVisible: false,
+      hasChanges: false,
+      changedCount: 0,
+
+      // 琛ㄥ崟楠岃瘉瑙勫垯
+      configRules: {
+        responsibilityDept: [
+          { required: true, message: "璇烽�夋嫨璐d换绉戝", trigger: "change" },
+        ],
+        reportDept: [
+          {
+            required: true,
+            message: "璇烽�夋嫨鑷冲皯涓�涓姤澶囩瀹�",
+            trigger: "change",
+          },
+          {
+            validator: (rule, value, callback) => {
+              if (!value || value.length === 0) {
+                callback(new Error("璇烽�夋嫨鑷冲皯涓�涓姤澶囩瀹�"));
+              } else {
+                callback();
+              }
+            },
+            trigger: "change",
+          },
+        ],
+        notifyTypes: [
+          {
+            validator: (rule, value, callback) => {
+              if (!value || value.length === 0) {
+                callback(new Error("璇疯嚦灏戦�夋嫨涓�绉嶉�氱煡鏂瑰紡"));
+              } else {
+                callback();
+              }
+            },
+            trigger: "change",
+          },
+        ],
+      },
+    };
+  },
+  created() {
+    this.getDeptOptions();
+    this.getQuestionList();
+  },
+  methods: {
+    /** 鏌ヨ绉戝鍒楄〃 */
+    getDeptOptions() {
+      getissueclassify({})
+        .then((res) => {
+          if (res.code === 200) {
+            this.deptOptions = res.rows || [];
+          }
+        })
+        .catch((error) => {
+          console.error("鑾峰彇绉戝鍒楄〃澶辫触:", error);
+          this.$message.error("鑾峰彇绉戝鍒楄〃澶辫触");
+        });
+    },
+
+    /** 鏌ヨ婊℃剰搴﹂鐩垪琛� */
+    getQuestionList() {
+      this.loading = true;
+      this.questionList = [];
+
+      getissuelist(this.queryParams)
+        .then((res) => {
+          this.loading = false;
+          if (res.code === 200) {
+            this.questionList = (res.rows || []).map((item) => {
+              // 瑙f瀽寮傚父澶勭悊閰嶇疆
+              let exceptionConfig = {
+                responsibilityDept: "",
+                reportDept: [],
+                notifyTypes: ["system"],
+              };
+
+              try {
+                if (item.otherdata) {
+                  const otherData = JSON.parse(item.otherdata);
+                  if (otherData.exceptionConfig) {
+                    exceptionConfig = {
+                      ...exceptionConfig,
+                      ...otherData.exceptionConfig,
+                    };
+                  }
+                }
+              } catch (error) {
+                console.warn("瑙f瀽寮傚父閰嶇疆澶辫触:", error);
+              }
+
+              return {
+                ...item,
+                originalConfig: JSON.parse(JSON.stringify(exceptionConfig)),
+                exceptionConfig: exceptionConfig,
+                hasChanges: false,
+                saving: false,
+                saveStatus: null,
+              };
+            });
+
+            this.total = res.total || 0;
+            this.updateChangedStatus();
+          } else {
+            this.$message.error(res.msg || "鑾峰彇鏁版嵁澶辫触");
+          }
+        })
+        .catch((error) => {
+          this.loading = false;
+          console.error("鏌ヨ澶辫触:", error);
+          this.$message.error("鑾峰彇鏁版嵁澶辫触");
+        });
+    },
+
+    /** 閰嶇疆鍙樻洿澶勭悊 */
+    handleConfigChange(question) {
+      this.$nextTick(() => {
+        const index = this.questionList.findIndex((q) => q.id === question.id);
+        if (index !== -1) {
+          const formRef = this.$refs.configForm && this.$refs.configForm[index];
+          if (formRef) {
+            formRef.validate((valid) => {
+              if (valid) {
+                question.hasChanges = !this.isConfigEqual(
+                  question.exceptionConfig,
+                  question.originalConfig
+                );
+                this.updateChangedStatus();
+              }
+            });
+          }
+        }
+      });
+    },
+
+    /** 姣旇緝閰嶇疆鏄惁鏀瑰彉 */
+    isConfigEqual(config1, config2) {
+      if (!config1 || !config2) return false;
+
+      const report1 = [...(config1.reportDept || [])].sort().join(",");
+      const report2 = [...(config2.reportDept || [])].sort().join(",");
+      const notify1 = [...(config1.notifyTypes || [])].sort().join(",");
+      const notify2 = [...(config2.notifyTypes || [])].sort().join(",");
+
+      return (
+        config1.responsibilityDept === config2.responsibilityDept &&
+        report1 === report2 &&
+        notify1 === notify2
+      );
+    },
+
+    /** 鏇存柊鍙樻洿鐘舵�� */
+    updateChangedStatus() {
+      const changedItems = this.questionList.filter((q) => q.hasChanges);
+      this.changedCount = changedItems.length;
+      this.hasChanges = changedItems.length > 0;
+    },
+
+    /** 淇濆瓨鍗曚釜棰樼洰閰嶇疆 */
+    async saveSingleConfig(question) {
+      if (!question.hasChanges) return;
+
+      const index = this.questionList.findIndex((q) => q.id === question.id);
+      if (index === -1) return;
+
+      const formRef = this.$refs.configForm && this.$refs.configForm[index];
+      if (!formRef) return;
+
+      const valid = await formRef.validate();
+      if (!valid) {
+        this.$message.warning("璇峰厛瀹屾垚蹇呭~椤�");
+        return;
+      }
+
+      question.saving = true;
+      question.saveStatus = null;
+
+      try {
+        // 鏋勫缓淇濆瓨鏁版嵁
+        const saveData = {
+          id: question.id,
+          isoperation: 2, // 淇敼鎿嶄綔
+          ...question,
+        };
+
+        // 灏嗗紓甯搁厤缃繚瀛樺埌 otherdata
+        const otherData = JSON.parse(question.otherdata || "{}");
+        otherData.exceptionConfig = question.exceptionConfig;
+        saveData.otherdata = JSON.stringify(otherData);
+
+        // 绉婚櫎涓嶉渶瑕佺殑瀛楁
+        delete saveData.originalConfig;
+        delete saveData.hasChanges;
+        delete saveData.saving;
+        delete saveData.saveStatus;
+        delete saveData.exceptionConfig;
+
+        const response = await compileissue(saveData);
+
+        if (response.code === 200) {
+          // 鏇存柊鍘熷閰嶇疆
+          question.originalConfig = JSON.parse(
+            JSON.stringify(question.exceptionConfig)
+          );
+          question.hasChanges = false;
+          question.saveStatus = {
+            type: "success",
+            message: "閰嶇疆淇濆瓨鎴愬姛",
+          };
+
+          this.updateChangedStatus();
+          this.$message.success("閰嶇疆淇濆瓨鎴愬姛");
+
+          // 5绉掑悗娓呴櫎鎴愬姛鎻愮ず
+          setTimeout(() => {
+            question.saveStatus = null;
+          }, 5000);
+        } else {
+          question.saveStatus = {
+            type: "error",
+            message: response.msg || "淇濆瓨澶辫触",
+          };
+          this.$message.error(response.msg || "淇濆瓨澶辫触");
+        }
+      } catch (error) {
+        console.error("淇濆瓨澶辫触:", error);
+        question.saveStatus = {
+          type: "error",
+          message: "淇濆瓨澶辫触锛岃绋嶅悗閲嶈瘯",
+        };
+        this.$message.error("淇濆瓨澶辫触锛岃绋嶅悗閲嶈瘯");
+      } finally {
+        question.saving = false;
+      }
+    },
+
+    /** 閲嶇疆鍗曚釜棰樼洰閰嶇疆 */
+    resetSingleConfig(question) {
+      this.$confirm("纭畾瑕侀噸缃綋鍓嶉鐩殑閰嶇疆鍚楋紵", "鎻愮ず", {
+        confirmButtonText: "纭畾",
+        cancelButtonText: "鍙栨秷",
+        type: "warning",
+      })
+        .then(() => {
+          question.exceptionConfig = JSON.parse(
+            JSON.stringify(question.originalConfig)
+          );
+          question.hasChanges = false;
+          question.saveStatus = null;
+          this.updateChangedStatus();
+          this.$message.success("閰嶇疆宸查噸缃�");
+        })
+        .catch(() => {});
+    },
+
+    /** 鎵归噺淇濆瓨閰嶇疆 */
+    async handleBatchSave() {
+      if (!this.hasChanges || this.batchSaving) return;
+
+      this.$confirm("纭畾瑕佷繚瀛樻墍鏈変慨鏀硅繃鐨勯厤缃悧锛�", "鎵归噺淇濆瓨", {
+        confirmButtonText: "纭畾",
+        cancelButtonText: "鍙栨秷",
+        type: "warning",
+      })
+        .then(async () => {
+          this.batchSaving = true;
+
+          const changedQuestions = this.questionList.filter(
+            (q) => q.hasChanges
+          );
+          const results = [];
+
+          for (const question of changedQuestions) {
+            try {
+              await this.saveSingleConfig(question);
+              results.push({
+                id: question.id,
+                success:
+                  !question.hasChanges &&
+                  question.saveStatus?.type === "success",
+              });
+            } catch (error) {
+              results.push({
+                id: question.id,
+                success: false,
+              });
+            }
+          }
+
+          this.batchSaving = false;
+
+          const successCount = results.filter((r) => r.success).length;
+          const failCount = results.length - successCount;
+
+          if (failCount === 0) {
+            this.saveSuccessVisible = true;
+            this.$message.success(`鎴愬姛淇濆瓨 ${successCount} 涓厤缃甡);
+          } else {
+            this.$message.warning(
+              `鎴愬姛淇濆瓨 ${successCount} 涓紝澶辫触 ${failCount} 涓猔
+            );
+          }
+        })
+        .catch(() => {
+          this.batchSaving = false;
+        });
+    },
+
+    /** 棰勮棰樼洰 */
+    previewQuestion(question) {
+      this.currentPreview = { ...question };
+      this.previewAnswer = "";
+      this.previewVisible = true;
+    },
+
+    /** 鎼滅储 */
+    handleQuery() {
+      this.queryParams.pageNum = 1;
+      this.getQuestionList();
+    },
+
+    /** 閲嶇疆鎼滅储 */
+    resetQuery() {
+      this.queryParams = {
+        pageNum: 1,
+        pageSize: 10,
+        scriptTopic: "",
+        scriptContent: "",
+        targetname: "",
+        isavailable: "",
+        categoryids: "404,405,406",
+      };
+      this.getQuestionList();
+    },
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+.satisfaction-exception-config {
+  min-height: 100%;
+  background-color: #f5f7fa;
+  padding: 20px;
+
+  .page-header {
+    margin-bottom: 20px;
+    padding: 20px;
+    background: linear-gradient(135deg, #409eff 0%, #66b1ff 100%);
+    border-radius: 8px;
+    color: white;
+
+    .header-content {
+      .page-title {
+        margin: 0 0 8px 0;
+        font-size: 20px;
+        font-weight: 600;
+      }
+
+      .page-description {
+        margin: 0;
+        opacity: 0.9;
+        font-size: 14px;
+      }
+    }
+  }
+
+  .search-card {
+    margin-bottom: 20px;
+
+    .search-container {
+      border-radius: 8px;
+
+      .el-form {
+        display: flex;
+        flex-wrap: wrap;
+        gap: 16px;
+        align-items: center;
+      }
+    }
+  }
+
+  .config-content {
+    .batch-actions-card {
+      margin-bottom: 20px;
+
+      .batch-actions {
+        display: flex;
+        align-items: center;
+        gap: 20px;
+        padding: 8px 0;
+
+        .change-count {
+          color: #e6a23c;
+          font-size: 14px;
+          font-weight: 500;
+        }
+
+        .total-count {
+          margin-left: auto;
+          color: #909399;
+          font-size: 14px;
+        }
+      }
+    }
+
+    .loading-wrapper {
+      display: flex;
+      justify-content: center;
+      align-items: center;
+      min-height: 400px;
+
+      .loading-spinner {
+        text-align: center;
+        color: #409eff;
+
+        i {
+          font-size: 24px;
+          margin-right: 8px;
+        }
+
+        span {
+          font-size: 16px;
+        }
+      }
+    }
+
+    .empty-wrapper {
+      min-height: 400px;
+      display: flex;
+      align-items: center;
+      justify-content: center;
+    }
+
+    .question-list {
+      display: flex;
+      flex-direction: column;
+      gap: 16px;
+    }
+
+    .question-item {
+      .question-card {
+        border-radius: 8px;
+        border: 1px solid #ebeef5;
+        transition: all 0.3s ease;
+
+        &.has-changes {
+          border-color: #409eff;
+          box-shadow: 0 2px 12px 0 rgba(64, 158, 255, 0.1);
+        }
+
+        &:hover {
+          box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
+        }
+
+        .card-header {
+          display: flex;
+          justify-content: space-between;
+          align-items: flex-start;
+          margin-bottom: 20px;
+          padding-bottom: 20px;
+          border-bottom: 1px solid #f0f0f0;
+
+          .header-left {
+            display: flex;
+            gap: 20px;
+            flex: 1;
+
+            .question-index {
+              display: flex;
+              flex-direction: column;
+              align-items: center;
+              min-width: 40px;
+
+              .index-number {
+                display: flex;
+                align-items: center;
+                justify-content: center;
+                width: 32px;
+                height: 32px;
+                background: #409eff;
+                color: white;
+                border-radius: 50%;
+                font-size: 14px;
+                font-weight: 600;
+                margin-bottom: 8px;
+              }
+
+              .index-line {
+                width: 2px;
+                height: 100%;
+                background: #e0e0e0;
+                border-radius: 1px;
+              }
+            }
+
+            .question-basic-info {
+              flex: 1;
+
+              .question-title-section {
+                margin-bottom: 12px;
+
+                .question-topic {
+                  margin: 0 0 8px 0;
+                  font-size: 16px;
+                  font-weight: 600;
+                  color: #303133;
+                  line-height: 1.4;
+                }
+
+                .question-tags {
+                  display: flex;
+                  gap: 8px;
+                  flex-wrap: wrap;
+                }
+              }
+
+              .question-content-section {
+                display: flex;
+                align-items: flex-start;
+                gap: 8px;
+
+                .content-label {
+                  color: #606266;
+                  font-size: 13px;
+                  font-weight: 500;
+                  min-width: 80px;
+                }
+
+                .content-text {
+                  color: #303133;
+                  font-size: 13px;
+                  line-height: 1.6;
+                  flex: 1;
+                }
+              }
+            }
+          }
+
+          .header-right {
+            flex-shrink: 0;
+          }
+        }
+
+        .config-section {
+          .config-title {
+            display: flex;
+            align-items: center;
+            gap: 8px;
+            margin-bottom: 20px;
+            padding: 8px 12px;
+            background: #f8f9fa;
+            border-radius: 4px;
+
+            i {
+              color: #409eff;
+              font-size: 16px;
+            }
+
+            span {
+              color: #303133;
+              font-weight: 600;
+              font-size: 14px;
+            }
+          }
+
+          .config-form {
+            .config-fields {
+              display: grid;
+              grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
+              gap: 20px;
+              margin-bottom: 20px;
+
+              .config-field {
+                .config-item {
+                  margin-bottom: 0;
+
+                  :deep(.el-form-item__label) {
+                    font-weight: 500;
+                    color: #606266;
+                    padding-right: 12px;
+                  }
+
+                  .config-tip {
+                    font-size: 12px;
+                    color: #909399;
+                    margin-top: 4px;
+                    line-height: 1.4;
+                  }
+                }
+              }
+            }
+
+            .config-footer {
+              display: flex;
+              justify-content: space-between;
+              align-items: center;
+              padding-top: 20px;
+              border-top: 1px dashed #dcdfe6;
+
+              .save-status {
+                flex: 1;
+                margin-right: 20px;
+
+                .el-alert {
+                  padding: 8px 16px;
+                  border-radius: 4px;
+                }
+              }
+
+              .config-actions {
+                display: flex;
+                align-items: center;
+                gap: 12px;
+                flex-shrink: 0;
+
+                .el-button {
+                  min-width: 100px;
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+
+    .pagination-wrapper {
+      margin-top: 20px;
+      padding: 20px;
+      background: white;
+      border-radius: 8px;
+      display: flex;
+      justify-content: center;
+    }
+  }
+
+  .preview-wrapper {
+    .preview-header {
+      margin-bottom: 20px;
+
+      h4 {
+        margin: 0 0 12px 0;
+        color: #303133;
+        font-size: 18px;
+        font-weight: 600;
+      }
+
+      .preview-tags {
+        display: flex;
+        gap: 8px;
+        flex-wrap: wrap;
+      }
+    }
+
+    .preview-content {
+      .preview-question {
+        margin-bottom: 20px;
+        padding: 16px;
+        background: #f8f9fa;
+        border-radius: 4px;
+        color: #606266;
+        line-height: 1.6;
+      }
+
+      .preview-options {
+        .option-item {
+          display: block;
+          margin-bottom: 12px;
+          padding: 12px;
+          border-radius: 4px;
+          border: 1px solid #ebeef5;
+          transition: all 0.3s;
+
+          &:hover {
+            background: #f5f7fa;
+            border-color: #409eff;
+          }
+
+          &:last-child {
+            margin-bottom: 0;
+          }
+        }
+      }
+
+      .preview-textarea {
+        .el-textarea__inner {
+          resize: none;
+        }
+      }
+    }
+  }
+
+  .success-content {
+    text-align: center;
+    padding: 20px 0;
+
+    .success-icon {
+      color: #67c23a;
+      font-size: 48px;
+      margin-bottom: 20px;
+    }
+
+    .success-text {
+      font-size: 16px;
+      color: #606266;
+      margin: 0;
+    }
+  }
+}
+
+@media (max-width: 768px) {
+  .satisfaction-exception-config {
+    padding: 12px;
+
+    .page-header {
+      padding: 16px;
+      margin-bottom: 16px;
+    }
+
+    .search-card {
+      margin-bottom: 16px;
+    }
+
+    .config-content {
+      .batch-actions-card {
+        margin-bottom: 16px;
+      }
+
+      .question-item {
+        .question-card {
+          .card-header {
+            flex-direction: column;
+            gap: 12px;
+
+            .header-left {
+              flex-direction: column;
+              gap: 12px;
+
+              .question-index {
+                flex-direction: row;
+                align-items: center;
+                min-width: auto;
+
+                .index-number {
+                  margin-bottom: 0;
+                  margin-right: 12px;
+                }
+
+                .index-line {
+                  width: 100%;
+                  height: 2px;
+                }
+              }
+            }
+          }
+
+          .config-section {
+            .config-form {
+              .config-fields {
+                grid-template-columns: 1fr;
+                gap: 16px;
+              }
+
+              .config-footer {
+                flex-direction: column;
+                align-items: stretch;
+                gap: 12px;
+
+                .save-status {
+                  margin-right: 0;
+                  margin-bottom: 8px;
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+}
+</style>
+
+<style lang="scss">
+.config-form {
+  .el-checkbox-group {
+    display: flex;
+    flex-wrap: wrap;
+    gap: 12px;
+  }
+
+  .el-checkbox {
+    margin: 0;
+  }
+}
+
+.option-item {
+  .el-radio__label {
+    display: block;
+    padding-left: 8px;
+  }
+}
+</style>
diff --git a/src/views/Satisfaction/particulars/index.vue b/src/views/Satisfaction/particulars/index.vue
new file mode 100644
index 0000000..6ef8d94
--- /dev/null
+++ b/src/views/Satisfaction/particulars/index.vue
@@ -0,0 +1,889 @@
+<template>
+  <div class="Questionnairemanagement">
+    <!-- 涓婁晶鏍� -->
+    <div class="sidecolumn">
+      <div>
+        <el-steps simple :active="Editprogress">
+          <el-step
+            icon="el-icon-edit"
+            title="鍩虹淇℃伅"
+            description="閫夋嫨瀹f暀妯℃澘銆佸舰寮忕瓑鍩虹淇℃伅"
+          ></el-step>
+          <el-step
+            icon="el-icon-user"
+            title="瀹f暀瀵硅薄"
+            description="鍦ㄦ湰閮ㄩ�夋嫨瀹f暀鐥呬汉"
+          ></el-step>
+        </el-steps>
+      </div>
+    </div>
+    <!-- 涓嬩晶鏁版嵁 -->
+    <div class="leftvlue" style="margin: 0 20px">
+      <!-- 鍩烘湰淇℃伅 -->
+      <div v-if="Editprogress == 1">
+        <el-alert
+          title="閫夋嫨瀹f暀妯℃澘銆佸舰寮忕瓑鍩虹淇℃伅"
+          type="success"
+          effect="dark"
+        >
+        </el-alert>
+        <div class="leftvlue-jbxx">
+          <!-- 鍩虹淇℃伅 -->
+          <div class="examine-jic">
+            <div class="headline">
+              <div>鍩虹淇℃伅</div>
+            </div>
+            <div class="jic-value">
+              <el-form ref="form" :model="form" label-width="105px">
+                <el-form-item label="鍙戦�佹椂闂达細" v-if="currenttype != 2">
+                  <el-date-picker
+                    v-model="form.name"
+                    type="date"
+                    placeholder="閫夋嫨鏃ユ湡"
+                  >
+                  </el-date-picker>
+                </el-form-item>
+                <el-form-item label="鍙戦�佹椂闂存锛�" v-if="currenttype != 2">
+                  <el-checkbox-group v-model="checkList">
+                    <el-checkbox label="涓婂崍锛�8:30-11:30锛�"></el-checkbox>
+                    <el-checkbox label="涓嬪崍锛�14:30-16:30锛�"></el-checkbox>
+                    <el-checkbox label="澶滈棿锛�18:30-20:30锛�"></el-checkbox>
+                  </el-checkbox-group>
+                </el-form-item>
+                <el-form-item label="鏈嶅姟褰㈠紡">
+                  <el-checkbox-group v-model="checkList">
+                    <el-checkbox
+                      v-for="(item, index) in checkboxlist"
+                      :key="index"
+                      :label="item"
+                    ></el-checkbox>
+                  </el-checkbox-group>
+                </el-form-item>
+                <el-form-item label="缁勭粐褰㈠紡">
+                  <el-radio-group v-model="form.radio">
+                    <el-radio :label="3">鍗曚汉</el-radio>
+                    <el-radio :label="6">澶氫汉</el-radio>
+                  </el-radio-group>
+                </el-form-item>
+                <el-form-item label="璇煶妯℃澘" prop="region">
+                  <el-select v-model="form.region" placeholder="璇烽�夋嫨妯℃澘">
+                    <el-option label="涓�鍙锋ā鏉�" value="shanghai"></el-option>
+                    <el-option label="浜屽彿妯℃澘" value="beijing"></el-option>
+                  </el-select>
+                </el-form-item>
+              </el-form>
+            </div>
+          </div>
+          <div class="examine-jic">
+            <div class="headline">
+              <div>{{ title }}</div>
+            </div>
+            <div class="examine-jic">
+              <div class="jic-value">
+                <el-row :gutter="20">
+                  <!--鐢ㄦ埛鏁版嵁-->
+
+                  <el-form
+                    :model="topqueryParams"
+                    ref="queryForm"
+                    size="small"
+                    :inline="true"
+                    v-show="showSearch"
+                    label-width="98px"
+                  >
+                    <el-form-item label="鎵ц鐘舵��" prop="status">
+                      <el-select
+                        v-model="topqueryParams.topic"
+                        placeholder="璇烽�夋嫨"
+                      >
+                        <el-option
+                          v-for="item in taskoptions"
+                          :key="item.value"
+                          :label="item.label"
+                          :value="item.value"
+                        >
+                        </el-option>
+                      </el-select>
+                    </el-form-item>
+                    <el-form-item
+                      label="绉戝鍚嶇О"
+                      v-if="currenttype == 1 || currenttype == 3"
+                    >
+                      <el-input
+                        v-model="topqueryParams.name"
+                      ></el-input> </el-form-item
+                    ><el-form-item label="鐥呭尯鍚嶇О" v-if="currenttype == 2">
+                      <el-input v-model="topqueryParams.name"></el-input>
+                    </el-form-item>
+                    <el-form-item
+                      label="鎮h�呭鍚�"
+                      v-if="currenttype == 1 || currenttype == 2"
+                    >
+                      <el-input v-model="topqueryParams.name"></el-input>
+                    </el-form-item>
+                    <el-form-item
+                      label="涓绘不鍖荤敓"
+                      v-if="currenttype == 1 || currenttype == 2"
+                    >
+                      <el-input v-model="topqueryParams.name"></el-input>
+                    </el-form-item>
+                    <el-form-item
+                      label="绠″簥鎶ゅ+"
+                      v-if="currenttype == 1 || currenttype == 2"
+                    >
+                      <el-input v-model="topqueryParams.name"></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>
+                  <el-divider></el-divider>
+                  <!-- 閫夋嫨浠诲姟鍒楄〃 -->
+                  <SFtable
+                    @handleUpdate="handleUpdate"
+                    @handleSelectionChange="handleSelectionChange"
+                    :currentList="userList"
+                    :tableLabel="tableLabelxj"
+                    :controlsc="false"
+                    :multiplechoice="false"
+                  />
+                  <pagination
+                    v-show="total > 0"
+                    :total="total"
+                    :page.sync="topqueryParams.pageNum"
+                    :limit.sync="topqueryParams.pageSize"
+                    @pagination="getList"
+                  />
+                </el-row>
+              </div>
+            </div>
+          </div>
+        </div>
+        <el-button type="success" @click="submitForm('ruleForm')">{{
+          quote ? "绔嬪嵆鍒涘缓" : "浠诲姟璇︽儏璁剧疆"
+        }}</el-button>
+        <el-button @click="resetForm('ruleForm')">閲嶇疆</el-button>
+      </div>
+
+      <!-- 浠诲姟璇︽儏 -->
+      <div v-if="Editprogress == 2">
+        <el-alert title="鍦ㄦ湰闃舵閫夋嫨鐥呬汉" type="success" effect="dark">
+        </el-alert>
+        <div class="leftvlue-jbxx">
+          <div class="examine-jic">
+            <div class="headline">
+              <div>鎮h�呭垪琛�</div>
+            </div>
+            <div class="examine-jic">
+              <div class="jic-value">
+                <el-row :gutter="20">
+                  <!--鐢ㄦ埛鏁版嵁-->
+                  <el-form
+                    :model="topqueryParams"
+                    ref="queryForm"
+                    size="small"
+                    :inline="true"
+                    v-show="showSearch"
+                    label-width="98px"
+                  >
+                    <el-form-item label="鎮h�呭悕绉�">
+                      <el-input v-model="topqueryParams.name"></el-input>
+                    </el-form-item>
+
+                    <el-form-item label="鎮h�呰寖鍥�" prop="status">
+                      <el-select
+                        v-model="topqueryParams.searchscope"
+                        placeholder="璇烽�夋嫨"
+                      >
+                        <el-option
+                          v-for="item in source"
+                          :key="item.value"
+                          :label="item.label"
+                          :value="item.value"
+                        >
+                        </el-option>
+                      </el-select>
+                    </el-form-item>
+
+                    <el-form-item label="鎮h�呯姸鎬�" prop="status">
+                      <el-select
+                        v-model="topqueryParams.topic"
+                        placeholder="璇烽�夋嫨"
+                      >
+                        <el-option
+                          v-for="item in topicoptions"
+                          :key="item.value"
+                          :label="item.label"
+                          :value="item.value"
+                        >
+                        </el-option>
+                      </el-select>
+                    </el-form-item>
+                    <el-form-item label="闅忚缁撴灉" prop="status">
+                      <el-select
+                        v-model="topqueryParams.topic"
+                        placeholder="璇烽�夋嫨"
+                      >
+                        <el-option
+                          v-for="item in topicoptions"
+                          :key="item.value"
+                          :label="item.label"
+                          :value="item.value"
+                        >
+                        </el-option>
+                      </el-select>
+                    </el-form-item>
+                    <el-form-item label="鎮h�呯數璇�">
+                      <el-input v-model="topqueryParams.name"></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-button
+                        icon="el-icon-upload2"
+                        size="medium"
+                        type="warning"
+                        >褰撳墠鎮h�呬竴閿彂閫�</el-button
+                      >
+                    </el-form-item>
+                  </el-form>
+                  <el-divider></el-divider>
+                  <el-row :gutter="10" class="mb8">
+                    <el-col :span="1.5">
+                      <el-select
+                        v-model="tasktopic"
+                        placeholder="璇烽�夋嫨鏂板绫诲瀷"
+                      >
+                        <el-option
+                          v-for="item in taskoptions"
+                          :key="item.value"
+                          :label="item.label"
+                          :value="item.value"
+                        >
+                        </el-option>
+                      </el-select>
+                    </el-col>
+                    <el-col :span="1.5">
+                      <el-button
+                        type="primary"
+                        plain
+                        icon="el-icon-plus"
+                        size="medium"
+                        :disabled="!tasktopic"
+                        @click="handleAddpatient"
+                        >鏂板</el-button
+                      >
+                    </el-col>
+
+                    <el-col :span="1.5">
+                      <el-button
+                        type="danger"
+                        plain
+                        icon="el-icon-delete"
+                        size="medium"
+                        :disabled="multiple"
+                        @click="handleDelete"
+                        >鍒犻櫎</el-button
+                      >
+                    </el-col>
+
+                    <!-- <el-col :span="1.5"> </el-col> -->
+                  </el-row>
+                  <!-- 閫変腑鎮h�呭垪琛� -->
+                  <SFtable
+                    @handleUpdate="handleUpdate"
+                    @handleSelectionChange="handleSelectionChange"
+                    :currentList="sonuserList"
+                    :tableLabel="tableLabelhz"
+                    :controlxz="false"
+                  />
+                  <pagination
+                    v-show="total > 0"
+                    :total="total"
+                    :page.sync="topqueryParams.pageNum"
+                    :limit.sync="topqueryParams.pageSize"
+                    @pagination="getList"
+                  />
+                </el-row>
+              </div>
+            </div>
+          </div>
+        </div>
+        <el-button type="primary" @click="laststep()">涓婁竴姝�</el-button>
+        <el-button type="success" @click="submitForm('ruleForm')"
+          >绔嬪嵆鍒涘缓</el-button
+        >
+        <el-button @click="resetForm('ruleForm')">閲嶇疆</el-button>
+      </div>
+    </div>
+    <!-- 娣诲姞鎮h�� -->
+    <el-dialog
+      title="閫夋嫨鎮h��"
+      :visible.sync="dialogVisiblepatient"
+      width="70%"
+      :before-close="handleClosehz"
+    >
+      <div class="examine-jic">
+        <div class="jic-value">
+          <el-row :gutter="20">
+            <!--鐢ㄦ埛鏁版嵁-->
+            <el-form
+              :model="patientqueryParams"
+              ref="queryForm"
+              size="small"
+              :inline="true"
+              v-show="showSearch"
+              label-width="98px"
+            >
+              <el-form-item label="鎮h�呭悕绉帮細">
+                <el-input v-model="patientqueryParams.name"></el-input>
+              </el-form-item>
+              <el-form-item label="鎮h�呰寖鍥�" prop="status">
+                <el-select
+                  v-model="patientqueryParams.topic"
+                  placeholder="璇烽�夋嫨"
+                >
+                  <el-option
+                    v-for="item in topicoptions"
+                    :key="item.value"
+                    :label="item.label"
+                    :value="item.value"
+                  >
+                  </el-option>
+                </el-select>
+              </el-form-item>
+              <el-form-item label="鍑洪櫌绉戝" prop="status">
+                <el-select
+                  v-model="patientqueryParams.topic"
+                  placeholder="璇烽�夋嫨"
+                >
+                  <el-option
+                    v-for="item in topicoptions"
+                    :key="item.value"
+                    :label="item.label"
+                    :value="item.value"
+                  >
+                  </el-option>
+                </el-select>
+              </el-form-item>
+
+              <el-form-item label="鍑洪櫌鐥呭尯" prop="status">
+                <el-select
+                  v-model="patientqueryParams.topic"
+                  placeholder="璇烽�夋嫨"
+                >
+                  <el-option
+                    v-for="item in topicoptions"
+                    :key="item.value"
+                    :label="item.label"
+                    :value="item.value"
+                  >
+                  </el-option>
+                </el-select>
+              </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�呭垪琛� -->
+            <SFtable
+              @handleUpdate="handleUpdate"
+              @handleSelectionChange="handleSelectionChange"
+              :currentList="patientuserList"
+              :tableLabel="tableLabelhz"
+              :controlsc="false"
+            />
+          </el-row>
+          <pagination
+            v-show="patienttotal > 0"
+            :total="patienttotal"
+            :page.sync="patientqueryParams.pageNum"
+            :limit.sync="patientqueryParams.pageSize"
+            @pagination="handleAddpatient"
+          />
+        </div>
+      </div>
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="dialogVisiblepatient = false">鍙� 娑�</el-button>
+        <el-button type="primary" @click="AddDispatchpatients"
+          >纭畾娣诲姞</el-button
+        >
+      </span>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import { messagelistpatient } from "@/api/patient/homepage";
+import SFtable from "@/components/SFtable"; //琛ㄦ牸缁勪欢
+
+export default {
+  name: "ServiceDetails",
+  data() {
+    return {
+      title: "瀹f暀鍐呭鍒楄〃",
+      currenttype: 1, //1瀹f暀2闂ㄨ瘖3鍑洪櫌4澶嶈瘖5浣撴6闂嵎
+      Editprogress: 1, //缂栬緫杩涘害
+      loading: false, // 閬僵灞�
+      patientloading: false, // 閬僵灞�
+      dialogVisiblepatient: false, //娣诲姞鎮h�呭脊妗�
+      checkboxlist: [],
+      tableLabel: [],
+      // 鎮h�呰〃鍗�
+      tableLabelhz: [
+        { label: "鎮h�呭悕绉�", width: "", prop: "name" },
+        { label: "鎬у埆", width: "", prop: "sex" },
+        { label: "骞撮緞", width: "", prop: "age" },
+        { label: "灏辫瘖绉戝", width: "", prop: "impTemplate" },
+        { label: "鍏ラ櫌鏃ユ湡", width: "", prop: "create_time" },
+        { label: "鍒涘缓浜�", width: "", prop: "update_by" },
+      ],
+      tableLabelxj: [
+        { label: "闂ㄨ瘖缂栧彿", width: "", prop: "name" },
+        { label: "濮撳悕", width: "", prop: "name" },
+        { label: "骞撮緞", width: "", prop: "age" },
+        { label: "鑱旂郴鐢佃瘽", width: "", prop: "telcode" },
+        { label: "灏辫瘖绉戝", width: "", prop: "impTemplate" },
+        { label: "璇婃柇", width: "", prop: "name" },
+        { label: "鍑洪櫌鏃堕棿", width: "", prop: "name" },
+        { label: "鍙戣捣鏃堕棿", width: "", prop: "create_time" },
+        { label: "鐘舵��", width: "", prop: "sex" },
+        { label: "閲嶅娆℃暟", width: "", prop: "update_by" },
+        { label: "浠诲姟鏉ユ簮", width: "", prop: "update_by" },
+        { label: "鍒涘缓浜�", width: "", prop: "update_by" },
+      ],
+      tableLabelmz: [
+        { label: "闂ㄨ瘖缂栧彿", width: "", prop: "name" },
+        { label: "濮撳悕", width: "", prop: "name" },
+        { label: "骞撮緞", width: "", prop: "age" },
+        { label: "鑱旂郴鐢佃瘽", width: "", prop: "telcode" },
+        { label: "灏辫瘖绉戝", width: "", prop: "impTemplate" },
+        { label: "璇婃柇", width: "", prop: "name" },
+        { label: "鍑洪櫌鏃堕棿", width: "", prop: "name" },
+        { label: "鍙戣捣鏃堕棿", width: "", prop: "create_time" },
+        { label: "鐘舵��", width: "", prop: "sex" },
+        { label: "閲嶅娆℃暟", width: "", prop: "update_by" },
+        { label: "浠诲姟鏉ユ簮", width: "", prop: "update_by" },
+        { label: "鍒涘缓浜�", width: "", prop: "update_by" },
+      ],
+      tableLabelcy: [
+        { label: "鍛樺伐缂栧彿", width: "", prop: "name" },
+        { label: "濮撳悕", width: "", prop: "name" },
+        { label: "骞撮緞", width: "", prop: "age" },
+        { label: "鑱旂郴鐢佃瘽", width: "", prop: "telcode" },
+        { label: "鎵�鍦ㄧ瀹�", width: "", prop: "impTemplate" },
+        { label: "瀹屾垚鏃堕棿", width: "", prop: "finishtime" },
+        { label: "鐘舵��", width: "", prop: "sex" },
+        { label: "閲嶅娆℃暟", width: "", prop: "update_by" },
+        { label: "浠诲姟鏉ユ簮", width: "", prop: "update_by" },
+        { label: "鍒涘缓浜�", width: "", prop: "update_by" },
+      ],
+
+      topqueryParams: {
+        pageNum: 1, //
+        pageSize: 10,
+        searchscope:2,
+      },
+      checkList: [],
+      deliverytopqueryParams: {
+        pageNum: 1, //
+        pageSize: 10,
+      },
+      patientqueryParams: {
+        pageNum: 1, //
+        pageSize: 10,
+      },
+      topicoptions: [],
+      showSearch: true, //
+      total: 0, //
+      sontotal: 0, //
+      patienttotal: 0, //
+      // 閫変腑鏁扮粍
+      ids: [],
+      // 闈炲崟涓鐢�
+      single: true,
+      // 闈炲涓鐢�
+      multiple: true,
+      // 鐢ㄦ埛琛ㄦ牸鏁版嵁
+      userList: [], //妯℃澘鍒楄〃
+      patientuserList: [], //閫夋嫨鎮h�呭垪琛�
+      sonuserList: [], //閫変腑鎮h�呭垪琛�
+      tasktopic: null, //鏂板绫诲瀷
+      form: {
+        name: "",
+        region: "",
+        date1: "",
+        date2: "",
+        delivery: false,
+        type: [],
+        resource: "",
+        desc: "",
+      },
+      source: [
+        {
+          value: 0,
+          label: "鎵�灞炴偅鑰�",
+        },
+        {
+          value: 1,
+          label: "绉戝鎮h��",
+        },
+        {
+          value: 2,
+          label: "鐥呭尯鎮h��",
+        },
+      ],
+      options: [
+        {
+          value: "閫夐」1",
+          label: "榛勯噾绯�",
+        },
+        {
+          value: "閫夐」2",
+          label: "鍙岀毊濂�",
+        },
+        {
+          value: "閫夐」5",
+          label: "鍖椾含鐑ら腑",
+        },
+      ],
+      taskoptions: [
+        {
+          value: "1",
+          label: "閫氱煡",
+        },
+        {
+          value: "2",
+          label: "闅忚",
+        },
+        {
+          value: "3",
+          label: "闂嵎",
+        },
+        {
+          value: "4",
+          label: "瀹f暀",
+        },
+      ],
+      quote: false,
+    };
+  },
+  components: { SFtable },
+
+  created() {
+    this.Addsubtask();
+    this.Getsubtask();
+    this.Acquisitiontype();
+  },
+
+  methods: {
+    // 鑾峰彇褰撳墠绫诲瀷
+    Acquisitiontype() {
+      this.currenttype = this.$route.query.type;
+      console.log(this.currenttype);
+      if (this.currenttype == 1) {
+        this.title = "闂ㄨ瘖鐥呬汉浠诲姟";
+        this.tableLabel = this.tableLabelxj;
+        this.checkboxlist = [
+          "褰撻潰",
+          "澶氬獟浣�",
+          "绾歌川",
+          "鐢佃瘽",
+          "鐭俊",
+          "寰俊鍏紬鍙�",
+          "寰俊灏忕▼搴�",
+          "閽夐拤",
+        ];
+      } else if (this.currenttype == 2) {
+        this.title = "鍑洪櫌鐥呬汉浠诲姟";
+        this.tableLabel = this.tableLabelmz;
+        this.checkboxlist = ["褰撻潰", "绾歌川", "鐢佃瘽", "鐭俊", "寰俊鍏紬鍙�"];
+      } else if (this.currenttype == 3) {
+        this.title = "鍖诲姟浜哄憳浠诲姟";
+        this.tableLabel = this.tableLabelcy;
+        this.checkboxlist = ["褰撻潰", "绾歌川", "鐢佃瘽", "鐭俊", "寰俊鍏紬鍙�"];
+      }
+    },
+    // 涓嬩竴姝�
+    submitForm(formName) {
+      if (this.Editprogress <= 3) {
+        return this.Editprogress++;
+      }
+      // 鎻愪氦
+      // this.$refs[formName].validate((valid, object) => {
+      //   if (valid) {
+      //     alert("submit!");
+      //   } else {
+      //     console.log("error submit!!", object);
+      //     return false;
+      //   }
+      // });
+    },
+    // 瀛愪换鍔′簩绾у脊妗�
+    handleAddpatient(row) {
+      console.log(row, "瀛愮粍浠舵暟鎹�");
+      messagelistpatient(this.patientqueryParams).then((response) => {
+        console.log(response);
+        this.patientuserList = response.rows;
+        this.patienttotal = response.total;
+        this.loading = false;
+      });
+      this.dialogVisiblepatient = true;
+    },
+    handleUpdate() {},
+    handleDelete() {},
+    handleExport() {},
+    // 澶氶�夋閫変腑鏁版嵁
+    handleSelectionChange(selection) {
+      this.ids = null;
+      this.ids = selection.map((item) => item.patid).join(",");
+      // let result = this.ids.join(",");
+      this.multiple = !selection.length;
+      console.log(this.ids);
+    },
+    getList() {},
+    handleQuery() {},
+    resetQuery() {},
+    handleClosehz() {
+      this.dialogVisiblepatient = false;
+    },
+    // 涓婁竴姝�
+    laststep() {
+      this.Editprogress--;
+    },
+    // 鎻愪氦琛ㄥ崟
+    resetForm(formName) {
+      this.$refs[formName].resetFields();
+    },
+    // 棰勮妯℃澘
+    PreviewTemplate() {},
+    Acknowledgereference() {
+      this.quote = true;
+    },
+    // 鏂板瀛愪换鍔�
+    Addsubtask() {
+      this.topqueryParams.pguid = 2;
+      // addsvr_prjtask(this.topqueryParams).then((res) => {
+      //   console.log(res);
+      // });
+    },
+    // 鏂板娲鹃�佹偅鑰�
+    AddDispatchpatients() {
+      let objictpint = {};
+      objictpint.patientes = this.ids;
+      objictpint.pguid = 2;
+      // Addpatienttask(objictpint).then((res) => {
+      //   console.log(res);
+      // });
+      this.dialogVisiblepatient = false;
+    },
+
+    // 鏌ヨ瀛愪换鍔″垪琛�
+    Getsubtask() {
+      this.topqueryParams.pguid = 2;
+      console.log(this.topqueryParams);
+      messagelistpatient(this.topqueryParams).then((res) => {
+        this.userList = res.rows;
+        this.total = res.total;
+        console.log(this.userList);
+      });
+    },
+    /** 鏌ヨ鎮h�呭垪琛� */
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+.Questionnairemanagement {
+}
+.leftvlue-jbxx {
+  margin-top: 10px;
+}
+.sidecolumn {
+  width: 100%;
+  // min-height: 12vh;
+  margin: 20px;
+  margin-bottom: 0;
+  padding: 20px;
+  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);
+}
+.leftvlue {
+  //   display: flex;
+  //   flex: 1;
+  width: 100%;
+  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);
+}
+.examine-jic {
+  .headline {
+    font-size: 24px;
+    border-left: 5px solid #41a1be;
+    padding-left: 5px;
+    margin-bottom: 10px;
+    display: flex;
+    justify-content: space-between;
+    .Add-details {
+      font-size: 18px;
+      color: #02a7f0;
+      cursor: pointer;
+    }
+  }
+  .jic-value {
+    font-size: 20px;
+    border-top: 1px solid #a7abac;
+    padding: 10px;
+    margin-bottom: 10px;
+    .details-jic {
+      padding: 10px 15px;
+      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);
+      .details-title {
+        display: flex;
+        justify-content: space-between;
+        margin-bottom: 10px;
+        div:nth-child(2) {
+          color: #02a7f0;
+          cursor: pointer;
+        }
+      }
+      .details-renw {
+        background: #e4ebfc;
+        padding: 15px 5px;
+        border-radius: 5px;
+        margin-bottom: 20px;
+      }
+    }
+  }
+}
+// .leftvlue-jbxx {
+//   margin-bottom: 50px;
+//   font-size: 20px;
+//   span {
+//     position: absolute;
+//     right: 80px;
+//   }
+//   .demo-cascader {
+//     margin-right: 20px;
+//   }
+//   .PreviewTemplate {
+//     color: #02a7f0;
+//     cursor: pointer;
+//     font-size: 20px;
+//     margin: 0 20px;
+//   }
+// }
+.jic-value {
+  font-size: 20px;
+  border-top: 1px solid #a7abac;
+  padding: 10px;
+  margin-bottom: 10px;
+  .details-jic {
+    padding: 10px 15px;
+    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);
+    .details-title {
+      display: flex;
+      justify-content: space-between;
+      margin-bottom: 10px;
+      div:nth-child(2) {
+        color: #02a7f0;
+        cursor: pointer;
+      }
+    }
+    .details-renw {
+      background: #e4ebfc;
+      padding: 15px 5px;
+      border-radius: 5px;
+      margin-bottom: 20px;
+    }
+  }
+}
+::v-deep .addtopic-input {
+  input {
+    background: #02a7f0;
+    color: #edf1f7;
+    width: 150px;
+  }
+}
+::v-deep.el-step.is-vertical .el-step__title {
+  font-size: 25px;
+}
+::v-deep.el-row {
+  margin-bottom: 10px;
+}
+// ::v-deep.el-input--medium {
+//   font-size: 24px !important;
+// }
+::v-deep.ruleFormaa.el-select {
+  display: inline-block;
+  position: relative;
+  width: 700px;
+}
+.el-select__tags {
+  font-size: 20px;
+  max-width: 888px !important;
+}
+::v-deep.el-radio__inner {
+  width: 22px;
+  height: 22px;
+}
+// ::v-deep.topic-dev.el-radio__label {
+//   font-size: 24px;
+// }
+::v-deep.el-radio-group {
+  span {
+    font-size: 24px;
+  }
+}
+::v-deep.el-checkbox-group {
+  span {
+    font-size: 24px;
+  }
+}
+</style>
diff --git a/src/views/Satisfaction/sfstatistics/components/FollowupStatistics.vue b/src/views/Satisfaction/sfstatistics/components/FollowupStatistics.vue
new file mode 100644
index 0000000..07f6c19
--- /dev/null
+++ b/src/views/Satisfaction/sfstatistics/components/FollowupStatistics.vue
@@ -0,0 +1,809 @@
+<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"
+          key="leavehospitaldistrictname"
+          prop="leavehospitaldistrictname"
+          :show-overflow-tooltip="true"
+          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"
+        :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: [],
+        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: "joyCount",
+          ...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 = response.data || [];
+        this.total = response.total || 0;
+      } catch (error) {
+        console.error('鑾峰彇缁熻鍒楄〃澶辫触:', error);
+        this.$message.error('鑾峰彇鏁版嵁澶辫触');
+      } finally {
+        this.loading = false;
+      }
+    },
+
+    // 澶勭悊缁熻绫诲瀷鍙樺寲
+    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;
+      this.topicVisible = true;
+
+      try {
+        // 澶勭悊鏌ヨ鍙傛暟
+        const params = {
+          configKey: "joyCount",
+          ...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 || [];
+      } 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/Satisfaction/sfstatistics/components/SatisfactionStatistics.vue b/src/views/Satisfaction/sfstatistics/components/SatisfactionStatistics.vue
new file mode 100644
index 0000000..678ecfd
--- /dev/null
+++ b/src/views/Satisfaction/sfstatistics/components/SatisfactionStatistics.vue
@@ -0,0 +1,990 @@
+<template>
+  <div class="satisfaction-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="鎮h�呮潵婧�" prop="patientSource">
+          <el-select
+            v-model="queryParams.patientSource"
+            placeholder="璇烽�夋嫨鎮h�呮潵婧�"
+            clearable
+            style="width: 200px"
+          >
+            <el-option
+              v-for="source in patientSourceList"
+              :key="source.value"
+              :label="source.label"
+              :value="source.value"
+            />
+          </el-select>
+        </el-form-item>
+
+        <el-form-item label="绉戝" prop="deptCode">
+          <el-select
+            v-model="queryParams.deptCode"
+            placeholder="璇烽�夋嫨绉戝"
+            clearable
+            filterable
+            style="width: 200px"
+          >
+            <el-option
+              v-for="dept in deptList"
+              :key="dept.value"
+              :label="dept.label"
+              :value="dept.value"
+            />
+          </el-select>
+        </el-form-item>
+
+        <el-form-item label="鐥呭尯" prop="wardCode">
+          <el-select
+            v-model="queryParams.wardCode"
+            placeholder="璇烽�夋嫨鐥呭尯"
+            clearable
+            filterable
+            style="width: 200px"
+          >
+            <el-option
+              v-for="ward in wardList"
+              :key="ward.value"
+              :label="ward.label"
+              :value="ward.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="handleSearch"
+            :loading="loading"
+          >
+            鏌ヨ
+          </el-button>
+          <el-button icon="el-icon-refresh" @click="handleReset">
+            閲嶇疆
+          </el-button>
+        </el-form-item>
+      </el-form>
+    </div>
+
+    <!-- 婊℃剰搴﹀垎绫荤粺璁″浘琛� -->
+    <div class="chart-section">
+      <div class="chart-container">
+        <div class="chart-title">婊℃剰搴︾被鍨嬬粺璁�</div>
+        <div id="satisfactionBarChart" style="width: 100%; height: 400px"></div>
+      </div>
+    </div>
+
+    <!-- 棰樼洰鏄庣粏琛ㄦ牸 -->
+    <div class="detail-table-section">
+      <div class="section-title">棰樼洰鏄庣粏缁熻</div>
+
+      <el-table
+        v-loading="detailLoading"
+        :data="questionDetailData"
+        :border="true"
+        style="width: 100%"
+        row-class-name="question-row"
+      >
+        <el-table-column
+          type="expand"
+          width="60"
+        >
+          <template slot-scope="{ row }">
+            <div class="option-detail">
+              <el-table
+                :data="row.options"
+                :border="true"
+                style="width: 100%"
+                class="inner-table"
+              >
+                <el-table-column
+                  label="閫夐」"
+                  prop="optionText"
+                  align="center"
+                  min-width="200"
+                />
+                <el-table-column
+                  label="閫夋嫨浜烘暟"
+                  prop="chosenQuantity"
+                  align="center"
+                  min-width="120"
+                />
+                <el-table-column
+                  label="閫夋嫨姣斾緥"
+                  prop="chosenPercentage"
+                  align="center"
+                  min-width="120"
+                >
+                  <template slot-scope="{ row: option }">
+                    {{ formatPercent(option.chosenPercentage) }}
+                  </template>
+                </el-table-column>
+              </el-table>
+            </div>
+          </template>
+        </el-table-column>
+
+        <el-table-column
+          label="搴忓彿"
+          type="index"
+          align="center"
+          width="60"
+        />
+
+        <el-table-column
+          label="棰樼洰"
+          prop="scriptContent"
+          align="center"
+          min-width="300"
+        >
+          <template slot-scope="{ row }">
+            <span>{{ row.scriptContent }}?</span>
+            <el-tag
+              :type="row.scriptType === 1 ? 'primary' : 'success'"
+              size="mini"
+              style="margin-left: 5px"
+            >
+              {{ row.scriptType === 1 ? '鍗曢�夐' : '澶氶�夐' }}
+            </el-tag>
+          </template>
+        </el-table-column>
+
+        <el-table-column
+          label="骞冲潎寰楀垎"
+          prop="averageScore"
+          align="center"
+          width="120"
+        >
+          <template slot-scope="{ row }">
+            <span class="score-text">{{ row.averageScore.toFixed(1) }}</span>
+          </template>
+        </el-table-column>
+
+        <el-table-column
+          label="鏈�楂樺緱鍒�"
+          prop="maxScore"
+          align="center"
+          width="120"
+        >
+          <template slot-scope="{ row }">
+            <span class="score-text">{{ row.maxScore.toFixed(1) }}</span>
+          </template>
+        </el-table-column>
+
+        <el-table-column
+          label="鏈�浣庡緱鍒�"
+          prop="minScore"
+          align="center"
+          width="120"
+        >
+          <template slot-scope="{ row }">
+            <span class="score-text">{{ row.minScore.toFixed(1) }}</span>
+          </template>
+        </el-table-column>
+
+        <el-table-column
+          label="绛旈浜烘暟"
+          prop="answerCount"
+          align="center"
+          width="100"
+        />
+
+        <el-table-column
+          label="鏈瓟棰樹汉鏁�"
+          prop="unanswerCount"
+          align="center"
+          width="100"
+        >
+          <template slot-scope="{ row }">
+            {{ row.totalCount - row.answerCount }}
+          </template>
+        </el-table-column>
+
+        <el-table-column
+          label="绛旈鐜�"
+          prop="answerRate"
+          align="center"
+          width="100"
+        >
+          <template slot-scope="{ row }">
+            {{ formatPercent(row.answerCount / row.totalCount) }}
+          </template>
+        </el-table-column>
+      </el-table>
+
+      <!-- 缁煎悎寰楀垎琛� -->
+      <div class="summary-row">
+        <div class="summary-content">
+          <div class="summary-item">
+            <span class="label">缁煎悎寰楀垎锛�</span>
+            <span class="value">{{ totalScore.toFixed(1) }}</span>
+          </div>
+          <div class="summary-item">
+            <span class="label">鎬荤瓟棰樹汉鏁帮細</span>
+            <span class="value">{{ totalAnswerCount }}</span>
+          </div>
+          <div class="summary-item">
+            <span class="label">鎬荤瓟棰樼巼锛�</span>
+            <span class="value">{{ formatPercent(totalAnswerRate) }}</span>
+          </div>
+        </div>
+      </div>
+    </div>
+
+    <!-- 鍒嗛〉 -->
+    <div class="pagination-section" v-if="questionDetailData.length > 0">
+      <el-pagination
+        background
+        layout="total, sizes, prev, pager, next, jumper"
+        :current-page="detailQueryParams.pageNum"
+        :page-size="detailQueryParams.pageSize"
+        :page-sizes="[10, 20, 30]"
+        :total="detailTotal"
+        @size-change="handleDetailSizeChange"
+        @current-change="handleDetailPageChange"
+      />
+    </div>
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'SatisfactionStatistics',
+  data() {
+    return {
+      // 鏌ヨ鍙傛暟
+      queryParams: {
+        patientSource: '',
+        deptCode: '',
+        wardCode: '',
+        dateRange: []
+      },
+
+      // 鎮h�呮潵婧愰�夐」
+      patientSourceList: [
+        { value: '1', label: '闂ㄨ瘖' },
+        { value: '2', label: '浣忛櫌' },
+        { value: '3', label: '鎬ヨ瘖' },
+        { value: '4', label: '浣撴' }
+      ],
+
+      // 绉戝鍒楄〃
+      deptList: [],
+
+      // 鐥呭尯鍒楄〃
+      wardList: [],
+
+      // 鍥捐〃瀹炰緥
+      barChart: null,
+
+      // 鍔犺浇鐘舵��
+      loading: false,
+      detailLoading: false,
+
+      // 棰樼洰鏄庣粏鏁版嵁
+      questionDetailData: [],
+
+      // 棰樼洰鏄庣粏鏌ヨ鍙傛暟
+      detailQueryParams: {
+        pageNum: 1,
+        pageSize: 10
+      },
+
+      // 棰樼洰鏄庣粏鎬绘暟
+      detailTotal: 0,
+
+      // 缁煎悎寰楀垎
+      totalScore: 0,
+      totalAnswerCount: 0,
+      totalAnswerRate: 0,
+
+      // 鏃ユ湡閫夋嫨鍣ㄩ�夐」
+      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();
+        }
+      },
+
+      // Mock鏁版嵁 - 婊℃剰搴﹀垎绫�
+      mockSatisfactionCategories: ['鏈嶅姟鎬佸害', '鎶�鏈按骞�', '鐜璁炬柦', '娌熼�氭晥鏋�', '绛夊緟鏃堕棿', '鏀惰垂鍚堢悊鎬�'],
+      // Mock鏁版嵁 - 婊℃剰搴︾被鍨�
+      mockSatisfactionTypes: [
+        { name: '闈炲父婊℃剰', value: 85, color: '#36B37E' },
+        { name: '婊℃剰', value: 72, color: '#4CAF50' },
+        { name: '涓�鑸�', value: 60, color: '#FF9D4D' },
+        { name: '涓嶆弧鎰�', value: 15, color: '#FF5C5C' },
+        { name: '闈炲父涓嶆弧鎰�', value: 5, color: '#F44336' }
+      ]
+    };
+  },
+
+  mounted() {
+    this.initData();
+    this.initChart();
+  },
+
+  beforeDestroy() {
+    if (this.barChart) {
+      this.barChart.dispose();
+      this.barChart = null;
+    }
+  },
+
+  methods: {
+    // 鍒濆鍖栨暟鎹�
+    async initData() {
+      await this.getDeptList();
+      await this.getWardList();
+      await this.loadData();
+    },
+
+    // 鑾峰彇绉戝鍒楄〃
+    getDeptList() {
+      // 妯℃嫙API璋冪敤鑾峰彇绉戝鍒楄〃
+      return new Promise((resolve) => {
+        setTimeout(() => {
+          this.deptList = [
+            { value: 'dept001', label: '蹇冭绠″唴绉�' },
+            { value: 'dept002', label: '绁炵粡鍐呯' },
+            { value: 'dept003', label: '鏅绉�' },
+            { value: 'dept004', label: '楠ㄧ' },
+            { value: 'dept005', label: '濡囦骇绉�' },
+            { value: 'dept006', label: '鍎跨' }
+          ];
+          resolve();
+        }, 100);
+      });
+    },
+
+    // 鑾峰彇鐥呭尯鍒楄〃
+    getWardList() {
+      // 妯℃嫙API璋冪敤鑾峰彇鐥呭尯鍒楄〃
+      return new Promise((resolve) => {
+        setTimeout(() => {
+          this.wardList = [
+            { value: 'ward001', label: '鍐呯涓�鐥呭尯' },
+            { value: 'ward002', label: '鍐呯浜岀梾鍖�' },
+            { value: 'ward003', label: '澶栫涓�鐥呭尯' },
+            { value: 'ward004', label: '澶栫浜岀梾鍖�' },
+            { value: 'ward005', label: '濡囦骇绉戠梾鍖�' },
+            { value: 'ward006', label: '鍎跨鐥呭尯' }
+          ];
+          resolve();
+        }, 100);
+      });
+    },
+
+    // 鍔犺浇鏁版嵁
+    async loadData() {
+      await Promise.all([
+        this.loadChartData(),
+        this.loadQuestionDetailData()
+      ]);
+    },
+
+    // 鍔犺浇鍥捐〃鏁版嵁
+    loadChartData() {
+      this.loading = true;
+      return new Promise((resolve) => {
+        setTimeout(() => {
+          this.renderChart(this.generateChartData());
+          this.loading = false;
+          resolve();
+        }, 500);
+      });
+    },
+
+    // 鍔犺浇棰樼洰鏄庣粏鏁版嵁
+    loadQuestionDetailData() {
+      this.detailLoading = true;
+      return new Promise((resolve) => {
+        setTimeout(() => {
+          const mockData = this.generateMockQuestionDetail();
+          this.questionDetailData = mockData.list;
+          this.detailTotal = mockData.total;
+
+          // 璁$畻缁煎悎寰楀垎
+          this.calculateSummary(mockData);
+          this.detailLoading = false;
+          resolve();
+        }, 500);
+      });
+    },
+
+    // 璁$畻缁煎悎寰楀垎
+    calculateSummary(data) {
+      let totalScore = 0;
+      let totalAnswerCount = 0;
+      let totalCount = 0;
+
+      data.list.forEach(item => {
+        totalScore += item.averageScore;
+        totalAnswerCount += item.answerCount;
+        totalCount += item.totalCount;
+      });
+
+      this.totalScore = data.list.length > 0 ? totalScore / data.list.length : 0;
+      this.totalAnswerCount = totalAnswerCount;
+      this.totalAnswerRate = totalCount > 0 ? totalAnswerCount / totalCount : 0;
+    },
+
+    // 鍒濆鍖栧浘琛�
+    initChart() {
+      const echarts = require('echarts');
+      const chartDom = document.getElementById('satisfactionBarChart');
+      if (!chartDom) return;
+
+      this.barChart = echarts.init(chartDom);
+
+      // 鐩戝惉绐楀彛鍙樺寲
+      window.addEventListener('resize', this.handleChartResize);
+    },
+
+    // 鐢熸垚鍥捐〃鏁版嵁
+    generateChartData() {
+      const categories = this.mockSatisfactionCategories;
+      const series = this.mockSatisfactionTypes.map(type => ({
+        name: type.name,
+        type: 'bar',
+        barWidth: 25,
+        stack: '婊℃剰搴�',
+        data: categories.map(() => Math.floor(Math.random() * 20) + 10), // 闅忔満鏁版嵁
+        itemStyle: {
+          color: type.color
+        }
+      }));
+
+      return {
+        categories,
+        legend: this.mockSatisfactionTypes.map(type => type.name),
+        series
+      };
+    },
+
+    // 娓叉煋鍥捐〃
+    renderChart(chartData) {
+      if (!this.barChart) return;
+
+      const option = {
+        title: {
+          text: '婊℃剰搴︾被鍨嬬粺璁�',
+          left: 'center',
+          textStyle: {
+            fontSize: 16,
+            fontWeight: 'normal',
+            color: '#333'
+          }
+        },
+        tooltip: {
+          trigger: 'axis',
+          axisPointer: {
+            type: 'shadow'
+          },
+          formatter: (params) => {
+            let result = `<div style="margin-bottom: 5px; font-weight: bold;">${params[0].name}</div>`;
+            let total = 0;
+
+            params.forEach(param => {
+              result += `<div style="margin: 2px 0;">
+                <span style="display:inline-block;width:10px;height:10px;border-radius:50%;background:${param.color};margin-right:5px;"></span>
+                ${param.seriesName}: <strong>${param.value}%</strong>
+              </div>`;
+              total += param.value;
+            });
+
+            result += `<div style="margin-top: 5px; padding-top: 5px; border-top: 1px solid #eee;">
+              <strong>鎬昏: ${total}%</strong>
+            </div>`;
+            return result;
+          }
+        },
+        legend: {
+          data: chartData.legend,
+          top: 20,
+          textStyle: {
+            fontSize: 12,
+            color: '#666'
+          }
+        },
+        grid: {
+          left: '3%',
+          right: '4%',
+          bottom: '3%',
+          top: 80,
+          containLabel: true
+        },
+        xAxis: {
+          type: 'category',
+          data: chartData.categories,
+          axisLabel: {
+            interval: 0,
+            rotate: 0,
+            fontSize: 12,
+            color: '#666'
+          },
+          axisLine: {
+            lineStyle: {
+              color: '#DCDFE6'
+            }
+          },
+          axisTick: {
+            alignWithLabel: true
+          }
+        },
+        yAxis: {
+          type: 'value',
+          name: '鐧惧垎姣� (%)',
+          min: 0,
+          max: 100,
+          axisLabel: {
+            formatter: '{value}%',
+            color: '#666'
+          },
+          axisLine: {
+            lineStyle: {
+              color: '#DCDFE6'
+            }
+          },
+          splitLine: {
+            lineStyle: {
+              type: 'dashed',
+              color: '#E4E7ED'
+            }
+          }
+        },
+        series: chartData.series
+      };
+
+      this.barChart.setOption(option);
+    },
+
+    // 鐢熸垚Mock棰樼洰璇︽儏鏁版嵁
+    generateMockQuestionDetail() {
+      const questions = [
+        {
+          scriptContent: '鎮ㄥ鍖绘姢浜哄憳鐨勬湇鍔℃�佸害鏄惁婊℃剰',
+          scriptType: 1, // 1: 鍗曢�夐, 2: 澶氶�夐
+          totalCount: 156,
+          answerCount: 145,
+          averageScore: 4.5,
+          maxScore: 5,
+          minScore: 3,
+          options: [
+            { optionText: '闈炲父婊℃剰', chosenQuantity: 89, chosenPercentage: 0.61 },
+            { optionText: '婊℃剰', chosenQuantity: 45, chosenPercentage: 0.31 },
+            { optionText: '涓�鑸�', chosenQuantity: 8, chosenPercentage: 0.06 },
+            { optionText: '涓嶆弧鎰�', chosenQuantity: 2, chosenPercentage: 0.01 },
+            { optionText: '闈炲父涓嶆弧鎰�', chosenQuantity: 1, chosenPercentage: 0.01 }
+          ]
+        },
+        {
+          scriptContent: '鎮ㄥ鍖荤敓鐨勮瘖鐤楁按骞冲拰鎶�鏈兘鍔涜瘎浠峰浣�',
+          scriptType: 1,
+          totalCount: 156,
+          answerCount: 142,
+          averageScore: 4.7,
+          maxScore: 5,
+          minScore: 3,
+          options: [
+            { optionText: '闈炲父涓撲笟', chosenQuantity: 95, chosenPercentage: 0.67 },
+            { optionText: '姣旇緝涓撲笟', chosenQuantity: 40, chosenPercentage: 0.28 },
+            { optionText: '涓�鑸�', chosenQuantity: 5, chosenPercentage: 0.04 },
+            { optionText: '涓嶅涓撲笟', chosenQuantity: 2, chosenPercentage: 0.01 },
+            { optionText: '闈炲父涓嶄笓涓�', chosenQuantity: 0, chosenPercentage: 0 }
+          ]
+        },
+        {
+          scriptContent: '鎮ㄥ鍖婚櫌鐨勭幆澧冨拰鍗敓鐘跺喌鏄惁婊℃剰',
+          scriptType: 1,
+          totalCount: 156,
+          answerCount: 138,
+          averageScore: 4.3,
+          maxScore: 5,
+          minScore: 2,
+          options: [
+            { optionText: '闈炲父婊℃剰', chosenQuantity: 75, chosenPercentage: 0.54 },
+            { optionText: '婊℃剰', chosenQuantity: 50, chosenPercentage: 0.36 },
+            { optionText: '涓�鑸�', chosenQuantity: 10, chosenPercentage: 0.07 },
+            { optionText: '涓嶆弧鎰�', chosenQuantity: 3, chosenPercentage: 0.02 },
+            { optionText: '闈炲父涓嶆弧鎰�', chosenQuantity: 0, chosenPercentage: 0 }
+          ]
+        },
+        {
+          scriptContent: '鎮ㄨ涓哄尰鎶や汉鍛樹笌鎮ㄧ殑娌熼�氭槸鍚﹀厖鍒�',
+          scriptType: 1,
+          totalCount: 156,
+          answerCount: 140,
+          averageScore: 4.6,
+          maxScore: 5,
+          minScore: 3,
+          options: [
+            { optionText: '娌熼�氶潪甯稿厖鍒�', chosenQuantity: 85, chosenPercentage: 0.61 },
+            { optionText: '娌熼�氭瘮杈冨厖鍒�', chosenQuantity: 45, chosenPercentage: 0.32 },
+            { optionText: '娌熼�氫竴鑸�', chosenQuantity: 8, chosenPercentage: 0.06 },
+            { optionText: '娌熼�氫笉澶熷厖鍒�', chosenQuantity: 2, chosenPercentage: 0.01 },
+            { optionText: '娌熼�氶潪甯镐笉鍏呭垎', chosenQuantity: 0, chosenPercentage: 0 }
+          ]
+        },
+        {
+          scriptContent: '鎮ㄥ绛夊緟灏辫瘖鍜屾不鐤楃殑鏃堕棿鏄惁婊℃剰',
+          scriptType: 1,
+          totalCount: 156,
+          answerCount: 135,
+          averageScore: 4.0,
+          maxScore: 5,
+          minScore: 1,
+          options: [
+            { optionText: '绛夊緟鏃堕棿寰堢煭', chosenQuantity: 60, chosenPercentage: 0.44 },
+            { optionText: '绛夊緟鏃堕棿鍚堢悊', chosenQuantity: 55, chosenPercentage: 0.41 },
+            { optionText: '绛夊緟鏃堕棿杈冮暱', chosenQuantity: 15, chosenPercentage: 0.11 },
+            { optionText: '绛夊緟鏃堕棿寰堥暱', chosenQuantity: 5, chosenPercentage: 0.04 },
+            { optionText: '鏃犳硶蹇嶅彈鐨勭瓑寰�', chosenQuantity: 0, chosenPercentage: 0 }
+          ]
+        },
+        {
+          scriptContent: '鎮ㄥ鍖婚櫌鏀惰垂鐨勯�忔槑搴﹀拰鍚堢悊鎬ц瘎浠峰浣�',
+          scriptType: 1,
+          totalCount: 156,
+          answerCount: 130,
+          averageScore: 4.2,
+          maxScore: 5,
+          minScore: 2,
+          options: [
+            { optionText: '闈炲父閫忔槑鍚堢悊', chosenQuantity: 70, chosenPercentage: 0.54 },
+            { optionText: '姣旇緝閫忔槑鍚堢悊', chosenQuantity: 45, chosenPercentage: 0.35 },
+            { optionText: '涓�鑸�', chosenQuantity: 10, chosenPercentage: 0.08 },
+            { optionText: '涓嶅お閫忔槑', chosenQuantity: 5, chosenPercentage: 0.04 },
+            { optionText: '闈炲父涓嶉�忔槑', chosenQuantity: 0, chosenPercentage: 0 }
+          ]
+        },
+        {
+          scriptContent: '鎮ㄤ細鍚戜翰鍙嬫帹鑽愭垜浠尰闄㈠悧',
+          scriptType: 1,
+          totalCount: 156,
+          answerCount: 148,
+          averageScore: 4.8,
+          maxScore: 5,
+          minScore: 3,
+          options: [
+            { optionText: '闈炲父鎰挎剰鎺ㄨ崘', chosenQuantity: 100, chosenPercentage: 0.68 },
+            { optionText: '姣旇緝鎰挎剰鎺ㄨ崘', chosenQuantity: 40, chosenPercentage: 0.27 },
+            { optionText: '涓�鑸�', chosenQuantity: 6, chosenPercentage: 0.04 },
+            { optionText: '涓嶅お鎰挎剰鎺ㄨ崘', chosenQuantity: 2, chosenPercentage: 0.01 },
+            { optionText: '缁濆涓嶄細鎺ㄨ崘', chosenQuantity: 0, chosenPercentage: 0 }
+          ]
+        },
+        {
+          scriptContent: '鎮ㄥ浠ヤ笅鍝簺鏂归潰姣旇緝婊℃剰锛堝閫夛級',
+          scriptType: 2, // 澶氶�夐
+          totalCount: 156,
+          answerCount: 150,
+          averageScore: 4.4,
+          maxScore: 5,
+          minScore: 3,
+          options: [
+            { optionText: '鍖荤枟鎶�鏈按骞�', chosenQuantity: 120, chosenPercentage: 0.8 },
+            { optionText: '鏈嶅姟鎬佸害', chosenQuantity: 110, chosenPercentage: 0.73 },
+            { optionText: '鐜鍗敓', chosenQuantity: 90, chosenPercentage: 0.6 },
+            { optionText: '鍖荤枟璁惧', chosenQuantity: 85, chosenPercentage: 0.57 },
+            { optionText: '鏀惰垂閫忔槑搴�', chosenQuantity: 70, chosenPercentage: 0.47 },
+            { optionText: '绛夊緟鏃堕棿', chosenQuantity: 60, chosenPercentage: 0.4 }
+          ]
+        },
+        {
+          scriptContent: '鎮ㄨ涓哄尰闄㈠摢浜涙柟闈㈤渶瑕佹敼杩涳紙澶氶�夛級',
+          scriptType: 2,
+          totalCount: 156,
+          answerCount: 125,
+          averageScore: 3.8,
+          maxScore: 5,
+          minScore: 2,
+          options: [
+            { optionText: '绛夊緟鏃堕棿杩囬暱', chosenQuantity: 80, chosenPercentage: 0.64 },
+            { optionText: '灏辫瘖娴佺▼澶嶆潅', chosenQuantity: 70, chosenPercentage: 0.56 },
+            { optionText: '璐圭敤杈冮珮', chosenQuantity: 60, chosenPercentage: 0.48 },
+            { optionText: '鍋滆溅鍥伴毦', chosenQuantity: 50, chosenPercentage: 0.4 },
+            { optionText: '鎸囧紩鏍囪瘑涓嶆竻', chosenQuantity: 40, chosenPercentage: 0.32 },
+            { optionText: '缃戠粶棰勭害涓嶄究', chosenQuantity: 30, chosenPercentage: 0.24 }
+          ]
+        },
+        {
+          scriptContent: '鎮ㄥ鏈浣忛櫌鐨勬暣浣撲綋楠岃瘎鍒�',
+          scriptType: 1,
+          totalCount: 156,
+          answerCount: 152,
+          averageScore: 4.6,
+          maxScore: 5,
+          minScore: 3,
+          options: [
+            { optionText: '5鍒嗭紙闈炲父婊℃剰锛�', chosenQuantity: 90, chosenPercentage: 0.59 },
+            { optionText: '4鍒嗭紙婊℃剰锛�', chosenQuantity: 50, chosenPercentage: 0.33 },
+            { optionText: '3鍒嗭紙涓�鑸級', chosenQuantity: 10, chosenPercentage: 0.07 },
+            { optionText: '2鍒嗭紙涓嶆弧鎰忥級', chosenQuantity: 2, chosenPercentage: 0.01 },
+            { optionText: '1鍒嗭紙闈炲父涓嶆弧鎰忥級', chosenQuantity: 0, chosenPercentage: 0 }
+          ]
+        }
+      ];
+
+      // 鍒嗛〉澶勭悊
+      const startIndex = (this.detailQueryParams.pageNum - 1) * this.detailQueryParams.pageSize;
+      const endIndex = startIndex + this.detailQueryParams.pageSize;
+      const paginatedData = questions.slice(startIndex, endIndex);
+
+      return {
+        list: paginatedData,
+        total: questions.length
+      };
+    },
+
+    // 澶勭悊鍥捐〃鍝嶅簲寮�
+    handleChartResize() {
+      if (this.barChart) {
+        this.barChart.resize();
+      }
+    },
+
+    // 澶勭悊鏌ヨ
+    handleSearch() {
+      this.detailQueryParams.pageNum = 1;
+      this.loadData();
+    },
+
+    // 澶勭悊閲嶇疆
+    handleReset() {
+      this.$refs.queryForm.resetFields();
+      this.queryParams.dateRange = [];
+      this.detailQueryParams.pageNum = 1;
+      this.loadData();
+    },
+
+    // 澶勭悊鏄庣粏鍒嗛〉澶у皬鍙樺寲
+    handleDetailSizeChange(size) {
+      this.detailQueryParams.pageSize = size;
+      this.detailQueryParams.pageNum = 1;
+      this.loadQuestionDetailData();
+    },
+
+    // 澶勭悊鏄庣粏椤电爜鍙樺寲
+    handleDetailPageChange(page) {
+      this.detailQueryParams.pageNum = page;
+      this.loadQuestionDetailData();
+    },
+
+    // 鏍煎紡鍖栫櫨鍒嗘瘮
+    formatPercent(value) {
+      if (value === null || value === undefined) return '-';
+      const num = parseFloat(value);
+      if (isNaN(num)) return '-';
+      return `${(num * 100).toFixed(2)}%`;
+    }
+  }
+};
+</script>
+
+<style lang="scss" scoped>
+.satisfaction-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;
+        }
+      }
+    }
+  }
+
+  .chart-section {
+    background: #fff;
+    padding: 20px;
+    border-radius: 4px;
+    margin-bottom: 20px;
+
+    .chart-container {
+      width: 100%;
+
+      .chart-title {
+        font-size: 16px;
+        font-weight: 600;
+        color: #333;
+        margin-bottom: 20px;
+        padding-bottom: 10px;
+        border-bottom: 1px solid #f0f0f0;
+      }
+
+      #satisfactionBarChart {
+        width: 100%;
+        height: 400px;
+      }
+    }
+  }
+
+  .detail-table-section {
+    background: #fff;
+    padding: 20px;
+    border-radius: 4px;
+
+    .section-title {
+      font-size: 16px;
+      font-weight: 600;
+      color: #333;
+      margin-bottom: 20px;
+      padding-bottom: 10px;
+      border-bottom: 1px solid #f0f0f0;
+    }
+
+    .option-detail {
+      padding: 20px;
+      background: #f8f9fa;
+      border-radius: 4px;
+      margin: 10px 0;
+    }
+
+    ::v-deep .el-table {
+      th {
+        background-color: #f8f9fa;
+        font-weight: 600;
+        color: #333;
+      }
+
+      .question-row {
+        td {
+          background-color: #fff;
+        }
+
+        &:hover {
+          td {
+            background-color: #f5f7fa;
+          }
+        }
+      }
+    }
+
+    .score-text {
+      font-weight: 600;
+      color: #1890ff;
+      font-size: 16px;
+    }
+
+    .summary-row {
+      margin-top: 20px;
+      padding: 20px;
+      background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%);
+      border-radius: 4px;
+      border: 1px solid #dee2e6;
+
+      .summary-content {
+        display: flex;
+        justify-content: space-around;
+        align-items: center;
+
+        .summary-item {
+          text-align: center;
+
+          .label {
+            font-size: 16px;
+            color: #666;
+            margin-right: 8px;
+          }
+
+          .value {
+            font-size: 24px;
+            font-weight: 600;
+            color: #1890ff;
+          }
+        }
+      }
+    }
+  }
+
+  .pagination-section {
+    display: flex;
+    justify-content: flex-end;
+    background: #fff;
+    padding: 20px;
+    border-radius: 4px;
+    margin-top: 20px;
+  }
+
+  // 鍐呭眰琛ㄦ牸鏍峰紡
+  .inner-table {
+    ::v-deep .el-table__header-wrapper {
+      th {
+        background-color: #f0f7ff !important;
+        color: #333;
+        font-weight: 600;
+      }
+    }
+
+    ::v-deep .el-table__body-wrapper {
+      tr {
+        background-color: #fff;
+
+        &:hover {
+          background-color: #f5f7fa;
+        }
+      }
+    }
+  }
+}
+</style>
diff --git a/src/views/Satisfaction/sfstatistics/components/components/SeedetailsDialog.vue b/src/views/Satisfaction/sfstatistics/components/components/SeedetailsDialog.vue
new file mode 100644
index 0000000..ce29cd3
--- /dev/null
+++ b/src/views/Satisfaction/sfstatistics/components/components/SeedetailsDialog.vue
@@ -0,0 +1,401 @@
+<template>
+  <div class="seedetails-dialog">
+    <div class="examine-jic">
+      <div class="jic-value">
+        <!-- 鏌ヨ琛ㄥ崟 -->
+        <el-form
+          :model="patientqueryParams"
+          ref="patientQueryForm"
+          size="small"
+          :inline="true"
+          class="detail-query-form"
+        >
+          <el-form-item label="鎮h�咃細" prop="name">
+            <el-input
+              v-model="patientqueryParams.name"
+              placeholder="璇疯緭鍏ユ偅鑰呭鍚�"
+              clearable
+              @keyup.enter.native="handleSearch"
+              style="width: 180px"
+            />
+          </el-form-item>
+
+          <el-form-item label="鎮h�呰瘖鏂細" prop="leavediagname">
+            <el-input
+              v-model="patientqueryParams.leavediagname"
+              placeholder="璇疯緭鍏ユ偅鑰呰瘖鏂�"
+              clearable
+              @keyup.enter.native="handleSearch"
+              style="width: 200px"
+            />
+          </el-form-item>
+
+          <el-form-item>
+            <el-button
+              type="primary"
+              icon="el-icon-search"
+              @click="handleSearch"
+              :loading="loading"
+            >
+              鎼滅储
+            </el-button>
+            <el-button icon="el-icon-refresh" @click="handleReset">
+              閲嶇疆
+            </el-button>
+          </el-form-item>
+        </el-form>
+
+        <!-- 鎮h�呭垪琛ㄨ〃鏍� -->
+        <el-table
+          v-loading="loading"
+          :data="logsheetlist"
+          style="width: 100%"
+          :border="true"
+          class="patient-table"
+        >
+          <el-table-column
+            prop="sendname"
+            label="濮撳悕"
+            align="center"
+            width="100"
+          />
+
+          <el-table-column
+            prop="taskName"
+            label="浠诲姟鍚嶇О"
+            align="center"
+            width="200"
+            show-overflow-tooltip
+          />
+
+          <el-table-column
+            prop="sendstate"
+            label="浠诲姟鐘舵��"
+            align="center"
+            width="120"
+          >
+            <template slot-scope="{ row }">
+              <div v-if="row.sendstate == 1">
+                <el-tag type="primary" size="small">琛ㄥ崟宸查鍙�</el-tag>
+              </div>
+              <div v-if="row.sendstate == 2">
+                <el-tag type="primary" size="small">寰呴殢璁�</el-tag>
+              </div>
+              <div v-if="row.sendstate == 3">
+                <el-tag type="success" size="small">琛ㄥ崟宸插彂閫�</el-tag>
+              </div>
+              <div v-if="row.sendstate == 4">
+                <el-tag type="info" size="small">涓嶆墽琛�</el-tag>
+              </div>
+              <div v-if="row.sendstate == 5">
+                <el-tag type="danger" size="small">鍙戦�佸け璐�</el-tag>
+              </div>
+              <div v-if="row.sendstate == 6">
+                <el-tag type="success" size="small">宸插畬鎴�</el-tag>
+              </div>
+            </template>
+          </el-table-column>
+
+          <el-table-column
+            prop="visitTime"
+            label="搴旈殢璁挎椂闂�"
+            align="center"
+            width="180"
+            show-overflow-tooltip
+          />
+
+          <el-table-column
+            prop="finishtime"
+            label="闅忚瀹屾垚鏃堕棿"
+            align="center"
+            width="180"
+            show-overflow-tooltip
+          >
+            <template slot-scope="{ row }">
+              <span v-if="row.finishtime">{{ row.finishtime }}</span>
+              <span v-else style="color: #f56c6c">鏈畬鎴�</span>
+            </template>
+          </el-table-column>
+
+          <el-table-column
+            label="鍑洪櫌鏃ユ湡"
+            width="120"
+            align="center"
+            key="endtime"
+            prop="endtime"
+          >
+            <template slot-scope="{ row }">
+              <span v-if="row.endtime">{{ formatTime(row.endtime) }}</span>
+              <span v-else>-</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="{ row }">
+              <dict-tag
+                :options="dict.type.sys_yujing"
+                :value="row.excep"
+                size="small"
+              />
+            </template>
+          </el-table-column>
+
+          <el-table-column
+            label="澶勭悊鎰忚"
+            align="center"
+            key="suggest"
+            prop="suggest"
+            width="120"
+          >
+            <template slot-scope="{ row }">
+              <dict-tag
+                :options="dict.type.sys_suggest"
+                :value="row.suggest"
+                size="small"
+              />
+            </template>
+          </el-table-column>
+
+          <el-table-column
+            prop="templatename"
+            label="鏈嶅姟妯℃澘"
+            width="150"
+            align="center"
+            show-overflow-tooltip
+          />
+
+          <el-table-column
+            prop="remark"
+            label="鏈嶅姟璁板綍"
+            width="150"
+            align="center"
+            show-overflow-tooltip
+          />
+
+          <el-table-column
+            prop="bankcardno"
+            label="鍛煎彨鐘舵��"
+            width="120"
+            align="center"
+          />
+
+          <el-table-column
+            label="鎿嶄綔"
+            fixed="right"
+            align="center"
+            width="100"
+          >
+            <template slot-scope="{ row }">
+              <el-button
+                type="text"
+                size="small"
+                @click="handleViewDetail(row)"
+              >
+                <i class="el-icon-view"></i> 鏌ョ湅
+              </el-button>
+            </template>
+          </el-table-column>
+        </el-table>
+
+        <!-- 鍒嗛〉 -->
+        <div class="pagination" v-if="patienttotal > 0">
+          <el-pagination
+            background
+            layout="total, sizes, prev, pager, next, jumper"
+            :current-page="patientqueryParams.pn"
+            :page-size="patientqueryParams.ps"
+            :page-sizes="[10, 20, 30]"
+            :total="patienttotal"
+            @size-change="handleSizeChange"
+            @current-change="handlePageChange"
+          />
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import { selectTimelyRate } from "@/api/system/user";
+
+export default {
+  name: 'SeedetailsDialog',
+  dicts: ['sys_yujing', 'sys_suggest'],
+  props: {
+    rowData: {
+      type: Object,
+      default: () => ({})
+    },
+    queryParams: {
+      type: Object,
+      default: () => ({})
+    }
+  },
+  data() {
+    return {
+      // 鏌ヨ鍙傛暟
+      patientqueryParams: {
+        pn: 1,
+        ps: 10,
+        name: '',
+        leavediagname: ''
+      },
+
+      // 鍔犺浇鐘舵��
+      loading: false,
+
+      // 鎮h�呭垪琛�
+      logsheetlist: [],
+
+      // 鎬绘潯鏁�
+      patienttotal: 0
+    };
+  },
+
+  mounted() {
+    this.loadData();
+  },
+
+  methods: {
+    // 鍔犺浇鏁版嵁
+    async loadData() {
+      this.loading = true;
+      try {
+        const params = {
+          ...this.patientqueryParams,
+          deptcode: this.rowData.deptcode || '',
+          starttime: this.queryParams.dateRange?.[0] ? this.parseTime(this.queryParams.dateRange[0]) : '',
+          endtime: this.queryParams.dateRange?.[1] ? this.parseTime(this.queryParams.dateRange[1]) : ''
+        };
+
+        const response = await selectTimelyRate(params);
+        this.logsheetlist = response.data?.detail || [];
+        this.patienttotal = response.data?.total || 0;
+      } catch (error) {
+        console.error('鑾峰彇鏈強鏃堕殢璁胯鎯呭け璐�:', error);
+        this.$message.error('鑾峰彇鏁版嵁澶辫触');
+      } finally {
+        this.loading = false;
+      }
+    },
+
+    // 澶勭悊鎼滅储
+    handleSearch() {
+      this.patientqueryParams.pn = 1;
+      this.loadData();
+    },
+
+    // 澶勭悊閲嶇疆
+    handleReset() {
+      this.patientqueryParams = {
+        pn: 1,
+        ps: 10,
+        name: '',
+        leavediagname: ''
+      };
+      this.loadData();
+    },
+
+    // 澶勭悊鍒嗛〉澶у皬鍙樺寲
+    handleSizeChange(size) {
+      this.patientqueryParams.ps = size;
+      this.patientqueryParams.pn = 1;
+      this.loadData();
+    },
+
+    // 澶勭悊椤电爜鍙樺寲
+    handlePageChange(page) {
+      this.patientqueryParams.pn = page;
+      this.loadData();
+    },
+
+    // 鏍煎紡鍖栨椂闂�
+    formatTime(time) {
+      if (!time) return '-';
+      return time;
+    },
+
+    // 瑙f瀽鏃堕棿
+    parseTime(time) {
+      if (!time) return '';
+      return time;
+    },
+
+    // 鏌ョ湅璇︽儏
+    handleViewDetail(row) {
+      this.$emit('close');
+
+      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
+          }
+        });
+      }, 300);
+    }
+  }
+};
+</script>
+
+<style lang="scss" scoped>
+.seedetails-dialog {
+  .detail-query-form {
+    margin-bottom: 20px;
+    padding-bottom: 20px;
+    border-bottom: 1px solid #f0f0f0;
+
+    ::v-deep .el-form-item {
+      margin-bottom: 0;
+      margin-right: 20px;
+    }
+  }
+
+  .patient-table {
+    margin-bottom: 20px;
+
+    ::v-deep .el-table__header-wrapper th {
+      background-color: #f8f9fa;
+      font-weight: 600;
+      color: #333;
+    }
+  }
+
+  .pagination {
+    display: flex;
+    justify-content: flex-end;
+    padding-top: 20px;
+    border-top: 1px solid #f0f0f0;
+  }
+}
+</style>
diff --git a/src/views/Satisfaction/sfstatistics/components/components/TopicDialog.vue b/src/views/Satisfaction/sfstatistics/components/components/TopicDialog.vue
new file mode 100644
index 0000000..c0f9faf
--- /dev/null
+++ b/src/views/Satisfaction/sfstatistics/components/components/TopicDialog.vue
@@ -0,0 +1,151 @@
+<template>
+  <div class="topic-dialog">
+    <div class="topicdia">
+      <div style="overflow-x: hidden; overflow-y: auto; max-height: 65vh">
+        <div
+          v-for="(item, index) in topiclist"
+          :key="index"
+          class="ttaabbcc"
+        >
+          <div class="describe">
+            绗瑊{ index + 1 }}棰橈細 {{ item.scriptContent }}?
+            <span>[{{ item.scriptType == 1 ? "鍗曢�夐" : "澶氶�夐" }}]</span>
+          </div>
+          <div>
+            <el-table :data="item.details" style="width: 100%">
+              <el-table-column
+                prop="optionText"
+                label="闂閫夐」"
+                align="center"
+                min-width="200"
+              />
+              <el-table-column
+                prop="chosenQuantity"
+                label="閫夋嫨浜烘暟"
+                align="center"
+                min-width="120"
+              />
+              <el-table-column
+                prop="chosenPercentage"
+                label="姣斾緥"
+                align="center"
+                min-width="120"
+              >
+                <template slot-scope="{ row }">
+                  <span v-if="row.chosenPercentage !== null && row.chosenPercentage !== undefined">
+                    {{ formatPercent(row.chosenPercentage) }}
+                  </span>
+                  <span v-else>-</span>
+                </template>
+              </el-table-column>
+            </el-table>
+          </div>
+        </div>
+      </div>
+    </div>
+
+    <div slot="footer" class="dialog-footer" style="text-align: center; padding-top: 20px;">
+      <el-button @click="handleClose">鍏� 闂�</el-button>
+    </div>
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'TopicDialog',
+  props: {
+    rowData: {
+      type: Object,
+      default: () => ({})
+    },
+    queryParams: {
+      type: Object,
+      default: () => ({})
+    }
+  },
+  data() {
+    return {
+      topiclist: []
+    };
+  },
+
+  mounted() {
+    this.loadData();
+  },
+
+  methods: {
+    // 鍔犺浇鏁版嵁
+    async loadData() {
+      try {
+        // 杩欓噷浠庣埗缁勪欢浼犻�掓暟鎹紝涓嶉渶瑕侀噸鏂拌皟鐢ˋPI
+        this.topiclist = this.$parent.topiclist || [];
+      } catch (error) {
+        console.error('鍔犺浇棰樼洰璇︽儏澶辫触:', error);
+        this.$message.error('鍔犺浇棰樼洰璇︽儏澶辫触');
+      }
+    },
+
+    // 鏍煎紡鍖栫櫨鍒嗘瘮
+    formatPercent(value) {
+      if (value === null || value === undefined) return '-';
+      const num = parseFloat(value);
+      if (isNaN(num)) return '-';
+      return `${(num * 100).toFixed(2)}%`;
+    },
+
+    // 鍏抽棴瀵硅瘽妗�
+    handleClose() {
+      this.$emit('close');
+    }
+  }
+};
+</script>
+
+<style lang="scss" scoped>
+.topic-dialog {
+  .topicdia {
+    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
+      "Helvetica Neue", Arial, sans-serif;
+    color: #333;
+  }
+
+  .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;
+  }
+
+  ::v-deep .el-table {
+    border-radius: 4px;
+    overflow: hidden;
+    font-size: 14px;
+  }
+
+  ::v-deep .el-table th {
+    background-color: #f1f5f9;
+    color: #333;
+    font-weight: 600;
+  }
+
+  ::v-deep .el-table td {
+    border-bottom: 1px solid #f0f0f0;
+    padding: 12px 0;
+  }
+}
+</style>
diff --git a/src/views/Satisfaction/sfstatistics/index.vue b/src/views/Satisfaction/sfstatistics/index.vue
new file mode 100644
index 0000000..96bda01
--- /dev/null
+++ b/src/views/Satisfaction/sfstatistics/index.vue
@@ -0,0 +1,63 @@
+<!-- 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="satisfaction">
+        <satisfaction-statistics
+          v-if="activeTab === 'satisfaction'"
+          ref="satisfactionRef"
+        />
+      </el-tab-pane>
+    </el-tabs>
+  </div>
+</template>
+
+<script>
+import FollowupStatistics from './components/FollowupStatistics.vue';
+import SatisfactionStatistics from './components/SatisfactionStatistics.vue';
+
+export default {
+  name: 'StatisticsMain',
+  components: {
+    FollowupStatistics,
+    SatisfactionStatistics
+  },
+  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/followvisit/Continue/index.vue b/src/views/followvisit/Continue/index.vue
index 3148049..18949b8 100644
--- a/src/views/followvisit/Continue/index.vue
+++ b/src/views/followvisit/Continue/index.vue
@@ -354,9 +354,14 @@
                   >鍙戦�佸け璐�</el-tag
                 >
               </div>
-              <div v-if="scope.row.sendstate == 6">
+            <div v-if="scope.row.sendstate == 6">
                 <el-tag type="success" :disable-transitions="false"
                   >宸插畬鎴�</el-tag
+                >
+              </div>
+              <div v-if="scope.row.sendstate == 7">
+                <el-tag type="danger" :disable-transitions="false"
+                  >瓒呮椂</el-tag
                 >
               </div>
             </el-tooltip>
@@ -411,11 +416,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
@@ -1183,7 +1188,7 @@
           value: 4,
           label: "涓嶆墽琛�",
         },
-        {
+         {
           value: 5,
           label: "鍙戦�佸け璐�",
         },
@@ -1191,6 +1196,10 @@
           value: 6,
           label: "宸插畬鎴�",
         },
+         {
+          value: 7,
+          label: "瓒呮椂",
+        },
       ],
       sextype: [
         {
diff --git a/src/views/followvisit/HistoricalFollow/index.vue b/src/views/followvisit/HistoricalFollow/index.vue
index 1ce4a79..4b5b99a 100644
--- a/src/views/followvisit/HistoricalFollow/index.vue
+++ b/src/views/followvisit/HistoricalFollow/index.vue
@@ -201,11 +201,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
@@ -662,7 +662,7 @@
           value: 4,
           label: "涓嶆墽琛�",
         },
-        {
+         {
           value: 5,
           label: "鍙戦�佸け璐�",
         },
@@ -670,6 +670,10 @@
           value: 6,
           label: "宸插畬鎴�",
         },
+         {
+          value: 7,
+          label: "瓒呮椂",
+        },
       ],
       topicoptionsyj: [
         {
diff --git a/src/views/followvisit/OutpatientAgain/index.vue b/src/views/followvisit/OutpatientAgain/index.vue
index 07ec46f..43c9daf 100644
--- a/src/views/followvisit/OutpatientAgain/index.vue
+++ b/src/views/followvisit/OutpatientAgain/index.vue
@@ -180,7 +180,7 @@
         <el-col :span="1.5">
           <el-button
             type="primary"
-                        icon="el-icon-plus"
+            icon="el-icon-plus"
             size="medium"
             @click="handleAdd"
             >鏂板</el-button
@@ -325,9 +325,14 @@
                   >鍙戦�佸け璐�</el-tag
                 >
               </div>
-              <div v-if="scope.row.sendstate == 6">
+            <div v-if="scope.row.sendstate == 6">
                 <el-tag type="success" :disable-transitions="false"
                   >宸插畬鎴�</el-tag
+                >
+              </div>
+              <div v-if="scope.row.sendstate == 7">
+                <el-tag type="danger" :disable-transitions="false"
+                  >瓒呮椂</el-tag
                 >
               </div>
             </el-tooltip>
@@ -382,11 +387,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
@@ -644,7 +649,7 @@
             </el-form-item>
           </el-col>
         </el-row>
-<el-row >
+        <el-row>
           <el-col :span="8">
             <el-form-item label="杩囨护鍖荤敓" width="100" prop="filterDrname">
               <el-input
@@ -1002,7 +1007,7 @@
         visitCount: 2,
         scopetype: [],
         visitDeptCodes: [],
-        leaveldeptcodes:[],
+        // leaveldeptcodes:[],
         leavehospitaldistrictcodes: [],
       },
       propss: { multiple: true },
@@ -1029,13 +1034,17 @@
           value: 4,
           label: "涓嶆墽琛�",
         },
-        {
+         {
           value: 5,
           label: "鍙戦�佸け璐�",
         },
         {
           value: 6,
           label: "宸插畬鎴�",
+        },
+         {
+          value: 7,
+          label: "瓒呮椂",
         },
       ],
       sextype: [
@@ -1141,9 +1150,9 @@
         this.topqueryParams.visitDeptCodes = store.getters.belongDepts.map(
           (obj) => obj.deptCode
         );
-        this.topqueryParams.leaveldeptcodes = store.getters.belongDepts.map(
-          (obj) => obj.deptCode
-        );
+        // this.topqueryParams.leaveldeptcodes = store.getters.belongDepts.map(
+        //   (obj) => obj.deptCode
+        // );
         this.topqueryParams.leavehospitaldistrictcodes =
           store.getters.belongWards.map((obj) => obj.districtCode);
       }
@@ -1157,9 +1166,9 @@
       this.loading = true;
       if (
         this.topqueryParams.leavehospitaldistrictcodes[0] &&
-        this.topqueryParams.visitDeptCodes[0]&&this.topqueryParams.leaveldeptcodes[0]
+        this.topqueryParams.visitDeptCodes[0]
       ) {
-        this.topqueryParams.deptOrDistrict = 2;
+        this.topqueryParams.deptOrDistrict = 4;
       } else {
         this.topqueryParams.deptOrDistrict = 1;
       }
@@ -1204,7 +1213,7 @@
       });
     },
     affiliation() {
-      this.topqueryParams.managementDoctorCode= store.getters.hisUserId;
+      this.topqueryParams.managementDoctorCode = store.getters.hisUserId;
 
       this.getList(1);
     },
@@ -1222,9 +1231,9 @@
         this.topqueryParams.visitDeptCodes = store.getters.belongDepts.map(
           (obj) => obj.deptCode
         );
-          this.topqueryParams.leaveldeptcodes = store.getters.belongDepts.map(
-          (obj) => obj.deptCode
-        );
+        //   this.topqueryParams.leaveldeptcodes = store.getters.belongDepts.map(
+        //   (obj) => obj.deptCode
+        // );
         this.topqueryParams.leavehospitaldistrictcodes =
           store.getters.belongWards.map((obj) => obj.districtCode);
       }
@@ -1241,7 +1250,7 @@
           this.topqueryParams.leavehospitaldistrictcodes,
         sendstates: [2, 3],
         visitDeptCodes: this.topqueryParams.visitDeptCodes,
-        leaveldeptcodes: this.topqueryParams.leaveldeptcodes,
+        // leaveldeptcodes: this.topqueryParams.leaveldeptcodes,
       };
       buidegetTasklist(obj).then((response) => {
         this.userList = response.rows[0].serviceSubtaskList;
@@ -1341,9 +1350,9 @@
         this.topqueryParams.visitDeptCodes = store.getters.belongDepts.map(
           (obj) => obj.deptCode
         );
-        this.topqueryParams.leaveldeptcodes = store.getters.belongDepts.map(
-          (obj) => obj.deptCode
-        );
+        // this.topqueryParams.leaveldeptcodes = store.getters.belongDepts.map(
+        //   (obj) => obj.deptCode
+        // );
         this.topqueryParams.leavehospitaldistrictcodes =
           store.getters.belongWards.map((obj) => obj.districtCode);
       }
@@ -1361,16 +1370,16 @@
       let code = value.slice(-1)[0];
       this.topqueryParams.leavehospitaldistrictcodes = [];
       this.topqueryParams.visitDeptCodes = [];
-      this.topqueryParams.leaveldeptcodes = [];
+      // this.topqueryParams.leaveldeptcodes = [];
       if (type == 1) {
         this.topqueryParams.visitDeptCodes.push(code);
-        this.topqueryParams.leaveldeptcodes.push(code);
+        // this.topqueryParams.leaveldeptcodes.push(code);
         this.topqueryParams.leavehospitaldistrictcodes = [];
         this.topqueryParams.searchscope = 1;
       } else if (type == 2) {
         this.topqueryParams.leavehospitaldistrictcodes.push(code);
         this.topqueryParams.visitDeptCodes = [];
-        this.topqueryParams.leaveldeptcodes = [];
+        // this.topqueryParams.leaveldeptcodes = [];
         this.topqueryParams.searchscope = 2;
       } else {
         this.topqueryParams.searchscope = 3;
@@ -1390,7 +1399,7 @@
         visitCount: 2,
         scopetype: [],
         visitDeptCodes: [],
-        leaveldeptcodes:[],
+        // leaveldeptcodes:[],
         leavehospitaldistrictcodes: [],
       };
       this.handleQuery(1);
@@ -1478,7 +1487,7 @@
             .then((response) => {
               console.log(response);
             })
-              .then(() => {
+            .then(() => {
               this.getList(1);
               this.$modal.msgSuccess("鎮h�呰繃婊ゆ垚鍔�");
             });
@@ -1547,11 +1556,11 @@
     },
     // 璺宠浆璇︽儏椤�
     Seedetails(row) {
-    let type = "";
+      let type = "";
       console.log(row, "rwo");
-        if (row.type == 1) {
-          type = 1;
-        }
+      if (row.type == 1) {
+        type = 1;
+      }
       this.$router.push({
         path: "/followvisit/record/detailpage/",
         query: {
@@ -1777,11 +1786,11 @@
   }
 }
 ::v-deep.leftvlue .el-card__body {
-  background: #F2F8FF;
-  color: #324A9B;
+  background: #f2f8ff;
+  color: #324a9b;
 }
 ::v-deep.leftvlue .el-card__body:hover {
-  background: #3664D9;
+  background: #3664d9;
   color: #fff;
   cursor: pointer; /* 榧犳爣鎮诞鏃跺彉涓烘墜褰� */
 }
diff --git a/src/views/followvisit/SpecificDisease/index.vue b/src/views/followvisit/SpecificDisease/index.vue
index c5131a7..ac905dc 100644
--- a/src/views/followvisit/SpecificDisease/index.vue
+++ b/src/views/followvisit/SpecificDisease/index.vue
@@ -324,11 +324,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
@@ -892,7 +892,7 @@
           value: 4,
           label: "涓嶆墽琛�",
         },
-        {
+         {
           value: 5,
           label: "鍙戦�佸け璐�",
         },
@@ -900,6 +900,10 @@
           value: 6,
           label: "宸插畬鎴�",
         },
+         {
+          value: 7,
+          label: "瓒呮椂",
+        },
       ],
       topicoptionsyj: [
         {
diff --git a/src/views/followvisit/Tracking/index.vue b/src/views/followvisit/Tracking/index.vue
index 0fbea2e..bcc1d04 100644
--- a/src/views/followvisit/Tracking/index.vue
+++ b/src/views/followvisit/Tracking/index.vue
@@ -264,9 +264,14 @@
                   >鍙戦�佸け璐�</el-tag
                 >
               </div>
-              <div v-if="scope.row.sendstate == 6">
+            <div v-if="scope.row.sendstate == 6">
                 <el-tag type="success" :disable-transitions="false"
                   >宸插畬鎴�</el-tag
+                >
+              </div>
+              <div v-if="scope.row.sendstate == 7">
+                <el-tag type="danger" :disable-transitions="false"
+                  >瓒呮椂</el-tag
                 >
               </div>
             </el-tooltip>
@@ -321,11 +326,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
@@ -968,7 +973,7 @@
           value: 4,
           label: "涓嶆墽琛�",
         },
-        {
+         {
           value: 5,
           label: "鍙戦�佸け璐�",
         },
@@ -976,6 +981,10 @@
           value: 6,
           label: "宸插畬鎴�",
         },
+         {
+          value: 7,
+          label: "瓒呮椂",
+        },
       ],
       sextype: [
         {
diff --git a/src/views/followvisit/again/index.vue b/src/views/followvisit/again/index.vue
index a6aed6b..b045ccf 100644
--- a/src/views/followvisit/again/index.vue
+++ b/src/views/followvisit/again/index.vue
@@ -325,9 +325,14 @@
                   >鍙戦�佸け璐�</el-tag
                 >
               </div>
-              <div v-if="scope.row.sendstate == 6">
+            <div v-if="scope.row.sendstate == 6">
                 <el-tag type="success" :disable-transitions="false"
                   >宸插畬鎴�</el-tag
+                >
+              </div>
+              <div v-if="scope.row.sendstate == 7">
+                <el-tag type="danger" :disable-transitions="false"
+                  >瓒呮椂</el-tag
                 >
               </div>
             </el-tooltip>
@@ -382,11 +387,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
@@ -1003,7 +1008,7 @@
         visitCount: 2,
         scopetype: [],
         visitDeptCodes: [],
-        leaveldeptcodes:[],
+        // leaveldeptcodes:[],
         leavehospitaldistrictcodes: [],
       },
       propss: { multiple: true },
@@ -1030,13 +1035,17 @@
           value: 4,
           label: "涓嶆墽琛�",
         },
-        {
+         {
           value: 5,
           label: "鍙戦�佸け璐�",
         },
         {
           value: 6,
           label: "宸插畬鎴�",
+        },
+         {
+          value: 7,
+          label: "瓒呮椂",
         },
       ],
       sextype: [
@@ -1142,9 +1151,9 @@
         this.topqueryParams.visitDeptCodes = store.getters.belongDepts.map(
           (obj) => obj.deptCode
         );
-        this.topqueryParams.leaveldeptcodes = store.getters.belongDepts.map(
-          (obj) => obj.deptCode
-        );
+        // this.topqueryParams.leaveldeptcodes = store.getters.belongDepts.map(
+        //   (obj) => obj.deptCode
+        // );
         this.topqueryParams.leavehospitaldistrictcodes =
           store.getters.belongWards.map((obj) => obj.districtCode);
       }
@@ -1158,9 +1167,9 @@
       this.loading = true;
       if (
         this.topqueryParams.leavehospitaldistrictcodes[0] &&
-        this.topqueryParams.visitDeptCodes[0]&&this.topqueryParams.leaveldeptcodes[0]
+        this.topqueryParams.visitDeptCodes[0]
       ) {
-        this.topqueryParams.deptOrDistrict = 2;
+        this.topqueryParams.deptOrDistrict = 4;
       } else {
         this.topqueryParams.deptOrDistrict = 1;
       }
@@ -1223,9 +1232,9 @@
         this.topqueryParams.visitDeptCodes = store.getters.belongDepts.map(
           (obj) => obj.deptCode
         );
-          this.topqueryParams.leaveldeptcodes = store.getters.belongDepts.map(
-          (obj) => obj.deptCode
-        );
+        //   this.topqueryParams.leaveldeptcodes = store.getters.belongDepts.map(
+        //   (obj) => obj.deptCode
+        // );
         this.topqueryParams.leavehospitaldistrictcodes =
           store.getters.belongWards.map((obj) => obj.districtCode);
       }
@@ -1242,7 +1251,7 @@
           this.topqueryParams.leavehospitaldistrictcodes,
         sendstates: [2, 3],
         visitDeptCodes: this.topqueryParams.visitDeptCodes,
-        leaveldeptcodes: this.topqueryParams.leaveldeptcodes,
+        // leaveldeptcodes: this.topqueryParams.leaveldeptcodes,
       };
       buidegetTasklist(obj).then((response) => {
         this.userList = response.rows[0].serviceSubtaskList;
@@ -1342,9 +1351,9 @@
         this.topqueryParams.visitDeptCodes = store.getters.belongDepts.map(
           (obj) => obj.deptCode
         );
-        this.topqueryParams.leaveldeptcodes = store.getters.belongDepts.map(
-          (obj) => obj.deptCode
-        );
+        // this.topqueryParams.leaveldeptcodes = store.getters.belongDepts.map(
+        //   (obj) => obj.deptCode
+        // );
         this.topqueryParams.leavehospitaldistrictcodes =
           store.getters.belongWards.map((obj) => obj.districtCode);
       }
@@ -1362,16 +1371,16 @@
       let code = value.slice(-1)[0];
       this.topqueryParams.leavehospitaldistrictcodes = [];
       this.topqueryParams.visitDeptCodes = [];
-      this.topqueryParams.leaveldeptcodes = [];
+      // this.topqueryParams.leaveldeptcodes = [];
       if (type == 1) {
         this.topqueryParams.visitDeptCodes.push(code);
-        this.topqueryParams.leaveldeptcodes.push(code);
+        // this.topqueryParams.leaveldeptcodes.push(code);
         this.topqueryParams.leavehospitaldistrictcodes = [];
         this.topqueryParams.searchscope = 1;
       } else if (type == 2) {
         this.topqueryParams.leavehospitaldistrictcodes.push(code);
         this.topqueryParams.visitDeptCodes = [];
-        this.topqueryParams.leaveldeptcodes = [];
+        // this.topqueryParams.leaveldeptcodes = [];
         this.topqueryParams.searchscope = 2;
       } else {
         this.topqueryParams.searchscope = 3;
@@ -1391,7 +1400,7 @@
         visitCount: 2,
         scopetype: [],
         visitDeptCodes: [],
-        leaveldeptcodes:[],
+        // leaveldeptcodes:[],
         leavehospitaldistrictcodes: [],
       };
       this.handleQuery(1);
diff --git a/src/views/followvisit/complaint/index.vue b/src/views/followvisit/complaint/index.vue
index 116f649..9a05c21 100644
--- a/src/views/followvisit/complaint/index.vue
+++ b/src/views/followvisit/complaint/index.vue
@@ -335,9 +335,14 @@
                   >鍙戦�佸け璐�</el-tag
                 >
               </div>
-              <div v-if="scope.row.sendstate == 6">
+            <div v-if="scope.row.sendstate == 6">
                 <el-tag type="success" :disable-transitions="false"
                   >宸插畬鎴�</el-tag
+                >
+              </div>
+              <div v-if="scope.row.sendstate == 7">
+                <el-tag type="danger" :disable-transitions="false"
+                  >瓒呮椂</el-tag
                 >
               </div>
             </el-tooltip>
@@ -1123,7 +1128,7 @@
           value: 4,
           label: "涓嶆墽琛�",
         },
-        {
+         {
           value: 5,
           label: "鍙戦�佸け璐�",
         },
@@ -1131,6 +1136,10 @@
           value: 6,
           label: "宸插畬鎴�",
         },
+         {
+          value: 7,
+          label: "瓒呮椂",
+        },
       ],
       sextype: [
         {
diff --git a/src/views/followvisit/discharge/index.vue b/src/views/followvisit/discharge/index.vue
index 593b275..fb620ef 100644
--- a/src/views/followvisit/discharge/index.vue
+++ b/src/views/followvisit/discharge/index.vue
@@ -405,6 +405,11 @@
                   >宸插畬鎴�</el-tag
                 >
               </div>
+              <div v-if="scope.row.sendstate == 7">
+                <el-tag type="danger" :disable-transitions="false"
+                  >瓒呮椂</el-tag
+                >
+              </div>
             </el-tooltip>
           </template>
         </el-table-column>
@@ -457,13 +462,14 @@
           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
           label="涓绘不鍖荤敓"
           width="120"
@@ -1249,7 +1255,8 @@
       topqueryParams: {
         pageNum: 1,
         pageSize: 10,
-        sendstate: 2,
+        sendstate:
+          localStorage.getItem("orgname") == "鐪佺珛鍚屽痉缈犺嫅闄㈠尯" ? null : 2,
         sort: localStorage.getItem("orgname") == "涓芥按甯備腑鍖婚櫌" ? 8 : 2, //0 鍑洪櫌鏃堕棿(姝e簭)    1 鍑洪櫌鏃堕棿(鍊掑簭)   2 鍙戦�佹椂闂�(姝e簭)    3 鍙戦�佹椂闂�(鍊掑簭)  7搴旈殢璁挎棩鏈�(鍊掑簭) 搴旈殢璁挎棩鏈�(姝e簭)
         serviceType: 2,
         searchscope: 3,
@@ -1290,6 +1297,10 @@
         {
           value: 6,
           label: "宸插畬鎴�",
+        },
+         {
+          value: 7,
+          label: "瓒呮椂",
         },
       ],
       sextype: [
@@ -1359,12 +1370,25 @@
       rules: {},
     };
   },
-  watch: {},
+  watch: {
+    // 鐩戝惉璺敱鍙傛暟鍙樺寲
+    "$route.query": {
+      handler(newQuery, oldQuery) {
+        if (newQuery.errtype !== oldQuery.errtype) {
+          console.log(22);
+
+          this.loadData(); // 閲嶆柊鍔犺浇鏁版嵁
+        }
+      },
+      immediate: true,
+    },
+  },
   created() {
     this.serviceState = store.getters.serviceState;
     this.checkboxlist = store.getters.checkboxlist;
-    this.errtype = this.$route.query.errtype;
     this.orgname = localStorage.getItem("orgname");
+    this.errtype = this.$route.query.errtype;
+
     this.leavehospitaldistrictcode =
       this.$route.query.leavehospitaldistrictcode;
     this.sourcetype[0].children = store.getters.belongDepts.map((dept) => {
@@ -1379,8 +1403,20 @@
         value: dept.districtCode,
       };
     });
-    if (this.errtype) {
+    if (this.errtype == 1) {
       this.toleadExport(2);
+    } else if (this.errtype == 2) {
+      // 寰呴殢璁�
+      this.toleadExport(3);
+    } else if (this.errtype == 3) {
+      // 澶辫触
+      this.toleadExport(4);
+    } else if (this.errtype == 4) {
+      // 寮傚父
+      this.toleadExport(2);
+    } else if (this.errtype == 5) {
+      // 鍏ㄩ儴
+      this.toleadExport(5);
     } else {
       this.getList(1);
     }
@@ -1389,7 +1425,24 @@
     });
   },
   activated() {
-    this.getList(1);
+    this.errtype = this.$route.query.errtype;
+    if (this.errtype == 1) {
+      this.toleadExport(2);
+    } else if (this.errtype == 2) {
+      // 寰呴殢璁�
+      this.toleadExport(3);
+    } else if (this.errtype == 3) {
+      // 澶辫触
+      this.toleadExport(4);
+    } else if (this.errtype == 4) {
+      // 寮傚父
+      this.toleadExport(2);
+    } else if (this.errtype == 5) {
+      // 鍏ㄩ儴
+      this.toleadExport(5);
+    } else {
+      this.getList(1);
+    }
   },
   methods: {
     /** 鏌ヨ闅忚鏈嶅姟鍒楄〃 */
@@ -1414,7 +1467,6 @@
         this.topqueryParams.leavehospitaldistrictcodes.push(
           this.leavehospitaldistrictcode
         );
-        console.log(this.topqueryParams.leavehospitaldistrictcodes, "11");
       }
       this.loading = true;
       if (
@@ -1430,7 +1482,9 @@
         this.total = response.total;
         if (refresh) {
           this.cardlist[0].value =
-            Number(response.rows[0].wzx) + Number(response.rows[0].ysf);
+            Number(response.rows[0].wzx) +
+            Number(response.rows[0].ysf) +
+            Number(response.rows[0].fssb);
           // this.cardlist[1].value = response.rows[0].wzx;
           this.cardlist[1].value = response.rows[0].ysf;
           this.ycvalue = response.rows[0].yc;
@@ -1465,6 +1519,26 @@
         });
         this.total = response.total;
       });
+    },
+    loadData() {
+      this.errtype = this.$route.query.errtype;
+      if (this.errtype == 1) {
+        this.toleadExport(2);
+      } else if (this.errtype == 2) {
+        // 寰呴殢璁�
+        this.toleadExport(3);
+      } else if (this.errtype == 3) {
+        // 澶辫触
+        this.toleadExport(4);
+      } else if (this.errtype == 4) {
+        // 寮傚父
+        this.toleadExport(2);
+      } else if (this.errtype == 5) {
+        // 鍏ㄩ儴
+        this.toleadExport(5);
+      } else {
+        this.getList(1);
+      }
     },
     // 鏃堕棿
     getEndOfDay() {
@@ -1618,10 +1692,13 @@
           store.getters.belongWards.map((obj) => obj.districtCode);
       }
       this.topqueryParams.pageNum = 1;
-      this.topqueryParams.startOutHospTime = this.dateRange[0];
-      this.topqueryParams.endOutHospTime = this.dateRange[1];
-      this.topqueryParams.startSendDateTime = this.dateRangefs[0];
-      this.topqueryParams.endSendDateTime = this.dateRangefs[1];
+      // 鍒ゆ柇鏄笉鏄伐浣滃彴蹇嵎鏌ヨ
+      if (this.errtype != 2) {
+        this.topqueryParams.startOutHospTime = this.dateRange[0];
+        this.topqueryParams.endOutHospTime = this.dateRange[1];
+        this.topqueryParams.startSendDateTime = this.dateRangefs[0];
+        this.topqueryParams.endSendDateTime = this.dateRangefs[1];
+      }
       this.getList(refresh);
     },
     // 鎮h�呰寖鍥村鐞�
@@ -1929,11 +2006,31 @@
     },
     // 渚挎嵎鎸夐挳
     toleadExport(too) {
+      console.log(too, "too");
+
       if (too == 1) {
         this.topqueryParams.sendstate = 4;
         this.topqueryParams.excep = null;
       } else if (too == 2) {
         this.topqueryParams.excep = 1;
+        this.topqueryParams.sendstate = null;
+      } else if (too == 3) {
+        this.topqueryParams.endSendDateTime = this.formatDateToYYYYMMDDHHMMSS(
+          this.getEndOfDay()
+        );
+        console.log(1111, this.topqueryParams.endSendDateTime);
+
+        this.topqueryParams.excep = null;
+        this.topqueryParams.sendstate = 2;
+        this.topqueryParams.scopetype = null;
+      } else if (too == 4) {
+        this.topqueryParams.excep = null;
+        this.topqueryParams.sendstate = 5;
+        this.topqueryParams.scopetype = null;
+      } else if (too == 5) {
+        this.topqueryParams.excep = null;
+        this.topqueryParams.sendstate = null;
+        this.topqueryParams.scopetype = null;
       }
       this.handleQuery(1);
     },
diff --git a/src/views/followvisit/discharge/outpatientService.vue b/src/views/followvisit/discharge/outpatientService.vue
index 53a4c79..c914289 100644
--- a/src/views/followvisit/discharge/outpatientService.vue
+++ b/src/views/followvisit/discharge/outpatientService.vue
@@ -331,9 +331,14 @@
                   >鍙戦�佸け璐�</el-tag
                 >
               </div>
-              <div v-if="scope.row.sendstate == 6">
+            <div v-if="scope.row.sendstate == 6">
                 <el-tag type="success" :disable-transitions="false"
                   >宸插畬鎴�</el-tag
+                >
+              </div>
+              <div v-if="scope.row.sendstate == 7">
+                <el-tag type="danger" :disable-transitions="false"
+                  >瓒呮椂</el-tag
                 >
               </div>
             </el-tooltip>
@@ -389,11 +394,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
@@ -1016,7 +1021,7 @@
           value: 4,
           label: "涓嶆墽琛�",
         },
-        {
+         {
           value: 5,
           label: "鍙戦�佸け璐�",
         },
@@ -1024,6 +1029,10 @@
           value: 6,
           label: "宸插畬鎴�",
         },
+         {
+          value: 7,
+          label: "瓒呮椂",
+        },
       ],
       sextype: [
         {
diff --git a/src/views/followvisit/mzsatisfaction/index.vue b/src/views/followvisit/mzsatisfaction/index.vue
index 0fbc077..751fcbe 100644
--- a/src/views/followvisit/mzsatisfaction/index.vue
+++ b/src/views/followvisit/mzsatisfaction/index.vue
@@ -334,9 +334,14 @@
                   >鍙戦�佸け璐�</el-tag
                 >
               </div>
-              <div v-if="scope.row.sendstate == 6">
+            <div v-if="scope.row.sendstate == 6">
                 <el-tag type="success" :disable-transitions="false"
                   >宸插畬鎴�</el-tag
+                >
+              </div>
+              <div v-if="scope.row.sendstate == 7">
+                <el-tag type="danger" :disable-transitions="false"
+                  >瓒呮椂</el-tag
                 >
               </div>
             </el-tooltip>
@@ -1167,7 +1172,7 @@
           value: 4,
           label: "涓嶆墽琛�",
         },
-        {
+         {
           value: 5,
           label: "鍙戦�佸け璐�",
         },
@@ -1175,6 +1180,10 @@
           value: 6,
           label: "宸插畬鎴�",
         },
+         {
+          value: 7,
+          label: "瓒呮椂",
+        },
       ],
       sextype: [
         {
diff --git a/src/views/followvisit/outpatient/index.vue b/src/views/followvisit/outpatient/index.vue
index f253049..e571a3a 100644
--- a/src/views/followvisit/outpatient/index.vue
+++ b/src/views/followvisit/outpatient/index.vue
@@ -334,11 +334,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
@@ -803,7 +803,7 @@
           value: 4,
           label: "涓嶆墽琛�",
         },
-        {
+         {
           value: 5,
           label: "鍙戦�佸け璐�",
         },
@@ -811,6 +811,10 @@
           value: 6,
           label: "宸插畬鎴�",
         },
+         {
+          value: 7,
+          label: "瓒呮椂",
+        },
       ],
       topicoptionsyj: [
         {
diff --git a/src/views/followvisit/record/detailpage/index.vue b/src/views/followvisit/record/detailpage/index.vue
index d30067d..360bc90 100644
--- a/src/views/followvisit/record/detailpage/index.vue
+++ b/src/views/followvisit/record/detailpage/index.vue
@@ -128,6 +128,11 @@
                   >宸插畬鎴�</el-tag
                 >
               </div>
+              <div v-if="scope.row.sendstate == 7">
+                <el-tag type="danger" :disable-transitions="false"
+                  >瓒呮椂</el-tag
+                >
+              </div>
             </template>
           </el-table-column>
           <el-table-column
@@ -2449,7 +2454,9 @@
           form.finishtime = "";
           if (form.resource) {
             if (form.resource == 2) {
-              form.visitDeptCode = localStorage.getItem("deptCode");
+              form.visitDeptCode = localStorage.getItem("deptCode")
+                ? localStorage.getItem("deptCode")
+                : form.deptcode;
               form.visitDeptName = "闅忚涓績";
             } else {
               form.visitDeptCode = form.deptcode;
diff --git a/src/views/followvisit/record/index.vue b/src/views/followvisit/record/index.vue
index 570f552..17d4c6b 100644
--- a/src/views/followvisit/record/index.vue
+++ b/src/views/followvisit/record/index.vue
@@ -372,11 +372,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
@@ -968,7 +968,7 @@
           value: 4,
           label: "涓嶆墽琛�",
         },
-        {
+         {
           value: 5,
           label: "鍙戦�佸け璐�",
         },
@@ -976,6 +976,10 @@
           value: 6,
           label: "宸插畬鎴�",
         },
+         {
+          value: 7,
+          label: "瓒呮椂",
+        },
       ],
       topicoptionsyj: [
         {
diff --git a/src/views/followvisit/technology/index.vue b/src/views/followvisit/technology/index.vue
index 5691b3e..feef9ea 100644
--- a/src/views/followvisit/technology/index.vue
+++ b/src/views/followvisit/technology/index.vue
@@ -337,11 +337,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
@@ -905,7 +905,7 @@
           value: 4,
           label: "涓嶆墽琛�",
         },
-        {
+         {
           value: 5,
           label: "鍙戦�佸け璐�",
         },
@@ -913,6 +913,10 @@
           value: 6,
           label: "宸插畬鎴�",
         },
+         {
+          value: 7,
+          label: "瓒呮椂",
+        },
       ],
       topicoptionsyj: [
         {
diff --git a/src/views/followvisit/zbAgain/index.vue b/src/views/followvisit/zbAgain/index.vue
index 75cd9fe..a002030 100644
--- a/src/views/followvisit/zbAgain/index.vue
+++ b/src/views/followvisit/zbAgain/index.vue
@@ -325,9 +325,14 @@
                   >鍙戦�佸け璐�</el-tag
                 >
               </div>
-              <div v-if="scope.row.sendstate == 6">
+            <div v-if="scope.row.sendstate == 6">
                 <el-tag type="success" :disable-transitions="false"
                   >宸插畬鎴�</el-tag
+                >
+              </div>
+              <div v-if="scope.row.sendstate == 7">
+                <el-tag type="danger" :disable-transitions="false"
+                  >瓒呮椂</el-tag
                 >
               </div>
             </el-tooltip>
@@ -382,11 +387,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
@@ -1019,7 +1024,7 @@
           value: 4,
           label: "涓嶆墽琛�",
         },
-        {
+         {
           value: 5,
           label: "鍙戦�佸け璐�",
         },
@@ -1027,6 +1032,10 @@
           value: 6,
           label: "宸插畬鎴�",
         },
+         {
+          value: 7,
+          label: "瓒呮椂",
+        },
       ],
       sextype: [
         {
diff --git a/src/views/followvisit/zysatisfaction/index.vue b/src/views/followvisit/zysatisfaction/index.vue
index 6b8edd4..779cdb3 100644
--- a/src/views/followvisit/zysatisfaction/index.vue
+++ b/src/views/followvisit/zysatisfaction/index.vue
@@ -333,9 +333,14 @@
                   >鍙戦�佸け璐�</el-tag
                 >
               </div>
-              <div v-if="scope.row.sendstate == 6">
+            <div v-if="scope.row.sendstate == 6">
                 <el-tag type="success" :disable-transitions="false"
                   >宸插畬鎴�</el-tag
+                >
+              </div>
+              <div v-if="scope.row.sendstate == 7">
+                <el-tag type="danger" :disable-transitions="false"
+                  >瓒呮椂</el-tag
                 >
               </div>
             </el-tooltip>
@@ -1126,7 +1131,7 @@
           value: 4,
           label: "涓嶆墽琛�",
         },
-        {
+         {
           value: 5,
           label: "鍙戦�佸け璐�",
         },
@@ -1134,6 +1139,10 @@
           value: 6,
           label: "宸插畬鎴�",
         },
+         {
+          value: 7,
+          label: "瓒呮椂",
+        },
       ],
       sextype: [
         {
diff --git a/src/views/login-sy.vue b/src/views/login-sy.vue
index 9de6d08..0408a34 100644
--- a/src/views/login-sy.vue
+++ b/src/views/login-sy.vue
@@ -36,7 +36,7 @@
           />
         </el-input>
       </el-form-item>
-      <!-- 涓�===================姘� -->
+      <!-- 甯備竴===================涓� -->
       <el-form-item prop="medicalCode">
         <el-select
           style="width: 100%"
diff --git a/src/views/patient/patient/indexls.vue b/src/views/patient/patient/indexls.vue
index 01ed808..7eedda4 100644
--- a/src/views/patient/patient/indexls.vue
+++ b/src/views/patient/patient/indexls.vue
@@ -143,7 +143,7 @@
           value: 4,
           label: "涓嶆墽琛�",
         },
-        {
+         {
           value: 5,
           label: "鍙戦�佸け璐�",
         },
@@ -151,6 +151,10 @@
           value: 6,
           label: "宸插畬鎴�",
         },
+         {
+          value: 7,
+          label: "瓒呮椂",
+        },
       ],
       topicoptionsyj: [
         {
diff --git a/src/views/patient/physical/index.vue b/src/views/patient/physical/index.vue
index f92b961..ea58a31 100644
--- a/src/views/patient/physical/index.vue
+++ b/src/views/patient/physical/index.vue
@@ -334,11 +334,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
@@ -803,7 +803,7 @@
           value: 4,
           label: "涓嶆墽琛�",
         },
-        {
+         {
           value: 5,
           label: "鍙戦�佸け璐�",
         },
@@ -811,6 +811,10 @@
           value: 6,
           label: "宸插畬鎴�",
         },
+         {
+          value: 7,
+          label: "瓒呮椂",
+        },
       ],
       topicoptionsyj: [
         {
diff --git a/src/views/patient/propaganda/index.vue b/src/views/patient/propaganda/index.vue
index fa455f6..cf89a0c 100644
--- a/src/views/patient/propaganda/index.vue
+++ b/src/views/patient/propaganda/index.vue
@@ -776,7 +776,7 @@
           value: 4,
           label: "涓嶆墽琛�",
         },
-        {
+         {
           value: 5,
           label: "鍙戦�佸け璐�",
         },
@@ -784,6 +784,10 @@
           value: 6,
           label: "宸插畬鎴�",
         },
+         {
+          value: 7,
+          label: "瓒呮椂",
+        },
       ],
       topicoptionsyj: [
         {
diff --git a/src/views/patient/questionnaire/index.vue b/src/views/patient/questionnaire/index.vue
index ee15c93..bc6774b 100644
--- a/src/views/patient/questionnaire/index.vue
+++ b/src/views/patient/questionnaire/index.vue
@@ -303,11 +303,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
@@ -789,7 +789,7 @@
           value: 4,
           label: "涓嶆墽琛�",
         },
-        {
+         {
           value: 5,
           label: "鍙戦�佸け璐�",
         },
@@ -797,6 +797,10 @@
           value: 6,
           label: "宸插畬鎴�",
         },
+         {
+          value: 7,
+          label: "瓒呮椂",
+        },
       ],
       topicoptionsyj: [
         {
diff --git a/src/views/patient/shadow/index.vue b/src/views/patient/shadow/index.vue
index 01325d6..41991e7 100644
--- a/src/views/patient/shadow/index.vue
+++ b/src/views/patient/shadow/index.vue
@@ -303,11 +303,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
@@ -789,7 +789,7 @@
           value: 4,
           label: "涓嶆墽琛�",
         },
-        {
+         {
           value: 5,
           label: "鍙戦�佸け璐�",
         },
@@ -797,6 +797,10 @@
           value: 6,
           label: "宸插畬鎴�",
         },
+         {
+          value: 7,
+          label: "瓒呮椂",
+        },
       ],
       topicoptionsyj: [
         {
diff --git a/src/views/patient/subsequent/index.vue b/src/views/patient/subsequent/index.vue
index 43936c8..ed7c07e 100644
--- a/src/views/patient/subsequent/index.vue
+++ b/src/views/patient/subsequent/index.vue
@@ -334,11 +334,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
@@ -803,7 +803,7 @@
           value: 4,
           label: "涓嶆墽琛�",
         },
-        {
+         {
           value: 5,
           label: "鍙戦�佸け璐�",
         },
@@ -811,6 +811,10 @@
           value: 6,
           label: "宸插畬鎴�",
         },
+         {
+          value: 7,
+          label: "瓒呮椂",
+        },
       ],
       topicoptionsyj: [
         {
diff --git a/src/views/sfstatistics/percentage/index.vue b/src/views/sfstatistics/percentage/index.vue
index b7a5a1b..03f5de7 100644
--- a/src/views/sfstatistics/percentage/index.vue
+++ b/src/views/sfstatistics/percentage/index.vue
@@ -356,6 +356,7 @@
                   prop="leavehospitaldistrictname"
                   width="150"
                   :show-overflow-tooltip="true"
+                  :sort-method="sortChineseNumber"
                 />
                 <el-table-column
                   label="绉戝"
@@ -1508,13 +1509,48 @@
       delete params.leavehospitaldistrictcodes.all;
       delete params.deptcodes.all;
       getSfStatistics(params).then((response) => {
-        console.log(response);
         this.loading = false;
 
         // this.total = response.total;
         this.userList = this.customSort(response.data);
       });
     },
+    sortChineseNumber(a, b) {
+      // 鎻愬彇涓枃鏁板瓧
+      const chineseNumbers = [
+        "涓�",
+        "浜�",
+        "涓�",
+        "鍥�",
+        "浜�",
+        "鍏�",
+        "涓�",
+        "鍏�",
+        "涔�",
+        "鍗�",
+        "鍗佷竴",
+        "鍗佷簩",
+      ];
+
+      // 浠庡瓧绗︿覆涓彁鍙栫梾鍖烘暟瀛楋紝濡�"鍥涚梾鍖�" -> "鍥�"
+      const getNumberFromText = (text) => {
+        if (!text) return -1;
+        const match = text.match(/^([涓�浜屼笁鍥涗簲鍏竷鍏節鍗乚+)/);
+        if (match && match[1]) {
+          return chineseNumbers.indexOf(match[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瀽鐨勬斁鍒板悗闈�
+
+      return numA - numB;
+    },
     // 鎼滅储澶勭悊鍑芥暟
     handleSearch() {
       if (!this.searchName.trim()) {
diff --git a/src/views/sfstatistics/percentage/satisfaction.vue b/src/views/sfstatistics/percentage/satisfaction.vue
index 8a9b19e..be3d69b 100644
--- a/src/views/sfstatistics/percentage/satisfaction.vue
+++ b/src/views/sfstatistics/percentage/satisfaction.vue
@@ -552,12 +552,7 @@
 </template>
 
 <script>
-import {
-  toamendtag,
-  addapitag,
-  deletetag,
-  changetagcategory,
-} from "@/api/system/label";
+
 import store from "@/store";
 import {
   getSfStatisticsJoy,
@@ -773,12 +768,14 @@
           ? this.allDeptCodes
           : this.queryParams.deptcodes,
       };
+      this.loading = true;
 
       // 绉婚櫎鍙兘瀛樺湪鐨�"all"鍊�
       delete params.leavehospitaldistrictcodes.all;
       delete params.deptcodes.all;
       getSfStatisticsJoy(params).then((response) => {
-        console.log(response);
+        this.loading = false;
+
         this.total = response.total;
         this.userList = response.data;
       });
@@ -921,27 +918,6 @@
         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({
@@ -971,22 +947,7 @@
       };
       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;
@@ -1017,27 +978,7 @@
       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() {
diff --git a/src/views/system/user/index.vue b/src/views/system/user/index.vue
index 71bb1b1..7b132b3 100644
--- a/src/views/system/user/index.vue
+++ b/src/views/system/user/index.vue
@@ -907,7 +907,7 @@
             updateUser(this.form).then((response) => {
               this.$modal.msgSuccess("淇敼鎴愬姛");
               this.open = false;
-              this.adduserdept();
+              // this.adduserdept();
             });
           } else {
             addUser(this.form).then((response) => {
@@ -916,7 +916,7 @@
               this.form.userId = response.data;
               console.log("寮�濮嬪姞閮ㄩ棬");
 
-              this.adduserdept();
+              // this.adduserdept();
             });
           }
         }
diff --git a/vue.config.js b/vue.config.js
index 7ce923e..79d9dfb 100644
--- a/vue.config.js
+++ b/vue.config.js
@@ -37,9 +37,9 @@
       [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:8094`,//鐪佺珛鍚屽痉
         // target: `http://192.168.100.10:8095`,//鏂板崕
-        target:`http://localhost:8095`,
+        // target:`http://localhost:8095`,
         // target:`http://35z1t16164.qicp.vip`,
         // target: `http://192.168.100.172:8095`,
         // target: `http://192.168.101.166:8093`,

--
Gitblit v1.9.3