From 61f0c5d3a9308d1eaefd8890a46b3c569707e050 Mon Sep 17 00:00:00 2001
From: WXL (wul) <wl_5969728@163.com>
Date: 星期四, 09 四月 2026 09:24:47 +0800
Subject: [PATCH] 测试完成

---
 /dev/null                                                                 |    0 
 dist.zip                                                                  |    0 
 src/api/AiCentre/satisfactionse.js                                        |   25 
 src/views/Satisfaction/sfstatistics/components/SatisfactionStatistics.vue |   70 
 vue.config.js                                                             |    4 
 src/views/followvisit/HistoricalFollow/index.vue                          |    6 
 src/components/AudioPlayer/index.vue                                      |  964 +++++++++++++++
 src/views/Satisfaction/configurationmyd/batch.vue                         |  989 ++++++++++-----
 src/views/Satisfaction/configurationmyd/components/DetailsAnomaly.vue     | 1272 ++++++++++++--------
 src/views/Satisfaction/configurationmyd/dispose.vue                       |  422 ++----
 10 files changed, 2,606 insertions(+), 1,146 deletions(-)

diff --git a/dist.zip b/dist.zip
index 71249fa..978792a 100644
--- a/dist.zip
+++ b/dist.zip
Binary files differ
diff --git a/sltd.zip b/sltd.zip
deleted file mode 100644
index 37ef9e2..0000000
--- a/sltd.zip
+++ /dev/null
Binary files differ
diff --git a/src/api/AiCentre/satisfactionse.js b/src/api/AiCentre/satisfactionse.js
index e9901b0..fef0537 100644
--- a/src/api/AiCentre/satisfactionse.js
+++ b/src/api/AiCentre/satisfactionse.js
@@ -35,6 +35,31 @@
     method: "get",
   });
 }
+// 寮傚父澶勭悊鍒楄〃
+export function tracedeallist(data) {
+  return request({
+    url: "/smartor/trace/tracedeallist",
+    method: "post",
+    data: data,
+  });
+}
+// 鎵归噺澶勭悊鍒楄〃
+export function tracelist(data) {
+  return request({
+    url: "/smartor/trace/list",
+    method: "post",
+    data: data,
+  });
+}
+// 浠诲姟鍒楄〃淇敼澶勭悊
+export function traceedit(data) {
+  return request({
+    url: "/smartor/trace/edit",
+    method: "post",
+    data: data,
+  });
+}
+
 
 
 
diff --git a/src/components/AudioPlayer/index.vue b/src/components/AudioPlayer/index.vue
new file mode 100644
index 0000000..0524c1f
--- /dev/null
+++ b/src/components/AudioPlayer/index.vue
@@ -0,0 +1,964 @@
+<template>
+  <div class="audio-player">
+    <!-- 涓绘挱鏀惧櫒 -->
+    <div class="audio-container" v-if="showDefaultPlayer">
+      <audio
+        ref="audioElement"
+        :src="audioSource"
+        preload="metadata"
+        @timeupdate="updateTime"
+        @loadedmetadata="updateDuration"
+        @play="handlePlay"
+        @pause="handlePause"
+        @ended="handleEnded"
+        @error="handleError"
+        style="display: none"
+      ></audio>
+
+      <!-- 鎾斁鎺у埗 -->
+      <div class="audio-controls">
+        <el-button
+          v-if="!isPlaying"
+          type="text"
+          icon="el-icon-video-play"
+          class="play-btn"
+          @click="playAudio"
+          :loading="loading"
+        ></el-button>
+        <el-button
+          v-else
+          type="text"
+          icon="el-icon-video-pause"
+          class="pause-btn"
+          @click="pauseAudio"
+        ></el-button>
+
+        <!-- 杩涘害鏉� -->
+        <div class="progress-container" @click="seekAudio" @mousemove="updateHoverTime">
+          <div class="progress-background">
+            <!-- 缂撳啿杩涘害 -->
+            <div
+              v-if="buffered.length > 0"
+              class="buffered-progress"
+              :style="{ width: `${bufferedPercent}%` }"
+            ></div>
+
+            <!-- 鎾斁杩涘害 -->
+            <div
+              class="played-progress"
+              :style="{ width: `${progressPercent}%` }"
+            ></div>
+
+            <!-- 鎮仠棰勮 -->
+            <div
+              v-if="showHoverPreview"
+              class="hover-preview"
+              :style="{ left: `${hoverPercent}%` }"
+            >
+              <span class="hover-time">{{ formatTime(hoverTime) }}</span>
+            </div>
+
+            <!-- 鎾斁鐐� -->
+            <div
+              class="playhead"
+              :style="{ left: `${progressPercent}%` }"
+            ></div>
+          </div>
+        </div>
+
+        <!-- 鏃堕棿鏄剧ず -->
+        <div class="time-display">
+          <span class="current-time">{{ formatTime(currentTime) }}</span>
+          <span class="time-separator">/</span>
+          <span class="duration">{{ formatTime(duration) }}</span>
+        </div>
+
+        <!-- 闊抽噺鎺у埗 -->
+        <div class="volume-control" v-if="showVolumeControl">
+          <el-popover
+            placement="top"
+            width="40"
+            trigger="hover"
+            popper-class="volume-popover"
+          >
+            <div class="volume-slider-container" @click.stop>
+              <el-slider
+                v-model="volume"
+                vertical
+                height="100px"
+                :show-tooltip="false"
+                @input="changeVolume"
+              ></el-slider>
+            </div>
+
+            <el-button
+              slot="reference"
+              type="text"
+              :icon="volumeIcon"
+              class="volume-btn"
+              @click.stop
+            ></el-button>
+          </el-popover>
+        </div>
+
+        <!-- 鎾斁閫熷害 -->
+        <el-select
+          v-if="showPlaybackRate"
+          v-model="playbackRate"
+          size="mini"
+          class="playback-rate"
+          @change="changePlaybackRate"
+        >
+          <el-option
+            v-for="rate in playbackRates"
+            :key="rate"
+            :label="`${rate}x`"
+            :value="rate"
+          ></el-option>
+        </el-select>
+
+        <!-- 涓嬭浇鎸夐挳 -->
+        <el-button
+          v-if="showDownload"
+          type="text"
+          icon="el-icon-download"
+          class="download-btn"
+          @click="downloadAudio"
+          title="涓嬭浇闊抽"
+        ></el-button>
+
+        <!-- 鏇村鍔熻兘鎸夐挳 -->
+        <el-dropdown
+          v-if="showMoreOptions"
+          trigger="click"
+          class="more-options"
+        >
+          <el-button type="text" icon="el-icon-more" class="more-btn"></el-button>
+          <el-dropdown-menu slot="dropdown">
+            <el-dropdown-item @click.native="loopAudio = !loopAudio">
+              <i :class="loopAudio ? 'el-icon-refresh' : 'el-icon-refresh-left'"></i>
+              {{ loopAudio ? '鍏抽棴寰幆' : '寮�鍚惊鐜�' }}
+            </el-dropdown-item>
+            <el-dropdown-item @click.native="resetAudio">
+              <i class="el-icon-refresh-right"></i>
+              閲嶇疆
+            </el-dropdown-item>
+            <el-dropdown-item v-if="showDetails" @click.native="showAudioInfo">
+              <i class="el-icon-info"></i>
+              闊抽淇℃伅
+            </el-dropdown-item>
+          </el-dropdown-menu>
+        </el-dropdown>
+      </div>
+    </div>
+
+    <!-- 闊抽淇℃伅瀵硅瘽妗� -->
+    <el-dialog
+      v-if="showDetailsDialog"
+      title="闊抽淇℃伅"
+      :visible.sync="showDetailsDialog"
+      width="400px"
+    >
+      <div class="audio-info">
+        <div class="info-item">
+          <span class="label">鏂囦欢澶у皬锛�</span>
+          <span class="value">{{ fileSize }}</span>
+        </div>
+        <div class="info-item">
+          <span class="label">闊抽鏃堕暱锛�</span>
+          <span class="value">{{ formatTime(duration) }}</span>
+        </div>
+        <div class="info-item">
+          <span class="label">鏂囦欢鏍煎紡锛�</span>
+          <span class="value">{{ audioFormat }}</span>
+        </div>
+        <div class="info-item">
+          <span class="label">闊抽鍦板潃锛�</span>
+          <a :href="audioSource" target="_blank" class="audio-url">{{ truncateUrl(audioSource) }}</a>
+        </div>
+      </div>
+    </el-dialog>
+
+    <!-- 绠�鏄撴挱鏀惧櫒锛堜粎鏄剧ず鎾斁鎸夐挳锛� -->
+    <div v-else class="simple-player">
+      <el-button
+        v-if="!isPlaying"
+        type="text"
+        icon="el-icon-video-play"
+        size="small"
+        class="simple-play-btn"
+        @click="playAudio"
+        :loading="loading"
+      >
+        鎾斁褰曢煶
+      </el-button>
+      <el-button
+        v-else
+        type="text"
+        icon="el-icon-video-pause"
+        size="small"
+        class="simple-pause-btn"
+        @click="pauseAudio"
+      >
+        鏆傚仠鎾斁
+      </el-button>
+    </div>
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'AudioPlayer',
+  props: {
+    // 闊抽婧愬湴鍧�
+    audioSource: {
+      type: String,
+      default: ''
+    },
+
+    // 鏄惁鏄剧ず瀹屾暣鎾斁鍣�
+    showDefaultPlayer: {
+      type: Boolean,
+      default: true
+    },
+
+    // 鏄惁鏄剧ず闊抽噺鎺у埗
+    showVolumeControl: {
+      type: Boolean,
+      default: true
+    },
+
+    // 鏄惁鏄剧ず鎾斁閫熷害鎺у埗
+    showPlaybackRate: {
+      type: Boolean,
+      default: true
+    },
+
+    // 鏄惁鏄剧ず涓嬭浇鎸夐挳
+    showDownload: {
+      type: Boolean,
+      default: true
+    },
+
+    // 鏄惁鏄剧ず鏇村閫夐」
+    showMoreOptions: {
+      type: Boolean,
+      default: true
+    },
+
+    // 鏄惁鏄剧ず闊抽淇℃伅
+    showDetails: {
+      type: Boolean,
+      default: true
+    },
+
+    // 鍒濆闊抽噺锛�0-100锛�
+    initialVolume: {
+      type: Number,
+      default: 80,
+      validator: (value) => value >= 0 && value <= 100
+    },
+
+    // 鍒濆鎾斁閫熷害
+    initialPlaybackRate: {
+      type: Number,
+      default: 1.0
+    },
+
+    // 鑷姩鎾斁
+    autoplay: {
+      type: Boolean,
+      default: false
+    },
+
+    // 寰幆鎾斁
+    loop: {
+      type: Boolean,
+      default: false
+    }
+  },
+
+  data() {
+    return {
+      // 鎾斁鐘舵��
+      isPlaying: false,
+      isLoading: false,
+      loading: false,
+      error: false,
+
+      // 鏃堕棿鐩稿叧
+      currentTime: 0,
+      duration: 0,
+      buffered: [],
+
+      // 闊抽噺
+      volume: this.initialVolume,
+      isMuted: false,
+
+      // 鎾斁閫熷害
+      playbackRate: this.initialPlaybackRate,
+      playbackRates: [0.5, 0.75, 1.0, 1.25, 1.5, 2.0],
+
+      // 寰幆鎾斁
+      loopAudio: this.loop,
+
+      // 杩涘害鏉℃偓鍋�
+      hoverTime: 0,
+      hoverPercent: 0,
+      showHoverPreview: false,
+
+      // 闊抽淇℃伅
+      showDetailsDialog: false,
+      fileSize: '鏈煡',
+      audioFormat: '鏈煡',
+
+      // 鐩戝惉鍣ㄥ紩鐢�
+      resizeObserver: null
+    };
+  },
+
+  computed: {
+    // 鎾斁杩涘害鐧惧垎姣�
+    progressPercent() {
+      if (this.duration <= 0) return 0;
+      return (this.currentTime / this.duration) * 100;
+    },
+
+    // 缂撳啿杩涘害鐧惧垎姣�
+    bufferedPercent() {
+      if (this.duration <= 0) return 0;
+      if (this.buffered.length === 0) return 0;
+
+      const bufferedEnd = this.buffered.end(this.buffered.length - 1);
+      return (bufferedEnd / this.duration) * 100;
+    },
+
+    // 闊抽噺鍥炬爣
+    volumeIcon() {
+      if (this.isMuted || this.volume === 0) {
+        return 'el-icon-turn-off-microphone';
+      } else if (this.volume <= 30) {
+        return 'el-icon-microphone';
+      } else if (this.volume <= 70) {
+        return 'el-icon-microphone';
+      } else {
+        return 'el-icon-microphone';
+      }
+    }
+  },
+
+  watch: {
+    // 鐩戝惉闊抽婧愬彉鍖�
+    audioSource(newSource) {
+      if (newSource) {
+        this.resetAudio();
+        this.loadAudio();
+      }
+    },
+
+    // 鐩戝惉鑷姩鎾斁
+    autoplay(newVal) {
+      if (newVal && this.audioSource) {
+        this.playAudio();
+      }
+    },
+
+    // 鐩戝惉寰幆鎾斁
+    loopAudio(newVal) {
+      this.$emit('loop-change', newVal);
+    }
+  },
+
+  mounted() {
+    if (this.audioSource) {
+      this.loadAudio();
+    }
+
+    // 鐩戝惉绐楀彛澶у皬鍙樺寲
+    this.resizeObserver = new ResizeObserver(() => {
+      this.updateBuffered();
+    });
+
+    if (this.$refs.audioElement) {
+      this.resizeObserver.observe(this.$refs.audioElement);
+    }
+  },
+
+  beforeDestroy() {
+    if (this.resizeObserver) {
+      this.resizeObserver.disconnect();
+    }
+
+    // 鍋滄闊抽鎾斁
+    this.pauseAudio();
+  },
+
+  methods: {
+    // 鍔犺浇闊抽
+    async loadAudio() {
+      this.loading = true;
+      this.error = false;
+
+      try {
+        const audio = this.$refs.audioElement;
+        if (!audio) return;
+
+        // 璁剧疆闊抽噺
+        audio.volume = this.volume / 100;
+        audio.playbackRate = this.playbackRate;
+        audio.loop = this.loopAudio;
+
+        // 灏濊瘯鑾峰彇鏂囦欢淇℃伅
+        this.getAudioInfo();
+
+        // 濡傛灉璁剧疆浜嗚嚜鍔ㄦ挱鏀撅紝寮�濮嬫挱鏀�
+        if (this.autoplay) {
+          await this.playAudio();
+        }
+      } catch (error) {
+        console.error('鍔犺浇闊抽澶辫触:', error);
+        this.error = true;
+        this.$emit('error', error);
+      } finally {
+        this.loading = false;
+      }
+    },
+
+    // 鎾斁闊抽
+    async playAudio() {
+      try {
+        const audio = this.$refs.audioElement;
+        if (!audio) return;
+
+        await audio.play();
+        this.isPlaying = true;
+        this.$emit('play');
+      } catch (error) {
+        console.error('鎾斁澶辫触:', error);
+        this.error = true;
+        this.isPlaying = false;
+        this.$emit('error', error);
+
+        // 濡傛灉鏄敤鎴蜂氦浜掑紩璧风殑閿欒锛屾彁绀虹敤鎴�
+        if (error.name === 'NotAllowedError') {
+          this.$message.warning('璇锋墜鍔ㄧ偣鍑绘挱鏀炬寜閽紑濮嬫挱鏀�');
+        }
+      }
+    },
+
+    // 鏆傚仠闊抽
+    pauseAudio() {
+      const audio = this.$refs.audioElement;
+      if (!audio) return;
+
+      audio.pause();
+      this.isPlaying = false;
+      this.$emit('pause');
+    },
+
+    // 璺宠浆鍒版寚瀹氭椂闂�
+    seekAudio(event) {
+      const audio = this.$refs.audioElement;
+      if (!audio || this.duration <= 0) return;
+
+      const progressContainer = event.currentTarget;
+      const rect = progressContainer.getBoundingClientRect();
+      const x = event.clientX - rect.left;
+      const width = rect.width;
+
+      const percent = Math.max(0, Math.min(1, x / width));
+      const time = percent * this.duration;
+
+      audio.currentTime = time;
+      this.currentTime = time;
+      this.$emit('seek', time);
+    },
+
+    // 鏇存柊鎮仠鏃堕棿
+    updateHoverTime(event) {
+      const progressContainer = event.currentTarget;
+      const rect = progressContainer.getBoundingClientRect();
+      const x = event.clientX - rect.left;
+      const width = rect.width;
+
+      const percent = Math.max(0, Math.min(1, x / width));
+      this.hoverPercent = percent * 100;
+      this.hoverTime = percent * this.duration;
+      this.showHoverPreview = true;
+    },
+
+    // 闅愯棌鎮仠棰勮
+    hideHoverPreview() {
+      this.showHoverPreview = false;
+    },
+
+    // 鏇存柊鏃堕棿
+    updateTime() {
+      const audio = this.$refs.audioElement;
+      if (!audio) return;
+
+      this.currentTime = audio.currentTime;
+      this.$emit('timeupdate', this.currentTime);
+    },
+
+    // 鏇存柊鎬绘椂闀�
+    updateDuration() {
+      const audio = this.$refs.audioElement;
+      if (!audio) return;
+
+      this.duration = audio.duration;
+      this.updateBuffered();
+      this.$emit('loadedmetadata', this.duration);
+    },
+
+    // 鏇存柊缂撳啿鏁版嵁
+    updateBuffered() {
+      const audio = this.$refs.audioElement;
+      if (!audio) return;
+
+      this.buffered = audio.buffered;
+    },
+
+    // 澶勭悊鎾斁
+    handlePlay() {
+      this.isPlaying = true;
+      this.$emit('play');
+    },
+
+    // 澶勭悊鏆傚仠
+    handlePause() {
+      this.isPlaying = false;
+      this.$emit('pause');
+    },
+
+    // 澶勭悊鎾斁缁撴潫
+    handleEnded() {
+      this.isPlaying = false;
+      this.currentTime = 0;
+      this.$emit('ended');
+    },
+
+    // 澶勭悊閿欒
+    handleError(event) {
+      console.error('闊抽鎾斁閿欒:', event);
+      this.error = true;
+      this.isPlaying = false;
+      this.$emit('error', event);
+    },
+
+    // 鏀瑰彉闊抽噺
+    changeVolume(value) {
+      const audio = this.$refs.audioElement;
+      if (!audio) return;
+
+      audio.volume = value / 100;
+      this.volume = value;
+      this.isMuted = value === 0;
+      this.$emit('volume-change', value);
+    },
+
+    // 闈欓煶/鍙栨秷闈欓煶
+    toggleMute() {
+      const audio = this.$refs.audioElement;
+      if (!audio) return;
+
+      this.isMuted = !this.isMuted;
+      audio.muted = this.isMuted;
+      this.$emit('mute-change', this.isMuted);
+    },
+
+    // 鏀瑰彉鎾斁閫熷害
+    changePlaybackRate(rate) {
+      const audio = this.$refs.audioElement;
+      if (!audio) return;
+
+      audio.playbackRate = rate;
+      this.playbackRate = rate;
+      this.$emit('playbackrate-change', rate);
+    },
+
+    // 閲嶇疆闊抽
+    resetAudio() {
+      const audio = this.$refs.audioElement;
+      if (!audio) return;
+
+      audio.currentTime = 0;
+      this.currentTime = 0;
+      this.pauseAudio();
+      this.$emit('reset');
+    },
+
+    // 涓嬭浇闊抽
+    downloadAudio() {
+      if (!this.audioSource) {
+        this.$message.warning('闊抽鍦板潃鏃犳晥');
+        return;
+      }
+
+      const link = document.createElement('a');
+      link.href = this.audioSource;
+      link.download = this.getFileNameFromUrl(this.audioSource);
+      document.body.appendChild(link);
+      link.click();
+      document.body.removeChild(link);
+
+      this.$emit('download');
+    },
+
+    // 鏄剧ず闊抽淇℃伅
+    async showAudioInfo() {
+      this.showDetailsDialog = true;
+      await this.getAudioInfo();
+    },
+
+    // 鑾峰彇闊抽淇℃伅
+    async getAudioInfo() {
+      if (!this.audioSource) return;
+
+      try {
+        // 鑾峰彇鏂囦欢澶у皬
+        const response = await fetch(this.audioSource, { method: 'HEAD' });
+        const contentLength = response.headers.get('content-length');
+
+        if (contentLength) {
+          this.fileSize = this.formatFileSize(contentLength);
+        }
+
+        // 鑾峰彇鏂囦欢鏍煎紡
+        const url = this.audioSource.toLowerCase();
+        if (url.endsWith('.mp3')) this.audioFormat = 'MP3';
+        else if (url.endsWith('.wav')) this.audioFormat = 'WAV';
+        else if (url.endsWith('.ogg')) this.audioFormat = 'OGG';
+        else if (url.endsWith('.m4a')) this.audioFormat = 'M4A';
+        else if (url.endsWith('.aac')) this.audioFormat = 'AAC';
+        else this.audioFormat = '鏈煡鏍煎紡';
+
+      } catch (error) {
+        console.error('鑾峰彇闊抽淇℃伅澶辫触:', error);
+        this.fileSize = '鏈煡';
+        this.audioFormat = '鏈煡';
+      }
+    },
+
+    // 鏍煎紡鍖栨椂闂�
+    formatTime(time) {
+      if (isNaN(time) || time < 0) return '00:00';
+
+      const hours = Math.floor(time / 3600);
+      const minutes = Math.floor((time % 3600) / 60);
+      const seconds = Math.floor(time % 60);
+
+      if (hours > 0) {
+        return `${hours.toString().padStart(2, '0')}:${minutes
+          .toString()
+          .padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;
+      } else {
+        return `${minutes.toString().padStart(2, '0')}:${seconds
+          .toString()
+          .padStart(2, '0')}`;
+      }
+    },
+
+    // 鏍煎紡鍖栨枃浠跺ぇ灏�
+    formatFileSize(bytes) {
+      if (bytes === 0) return '0 B';
+
+      const k = 1024;
+      const sizes = ['B', 'KB', 'MB', 'GB'];
+      const i = Math.floor(Math.log(bytes) / Math.log(k));
+
+      return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
+    },
+
+    // 鎴柇URL鏄剧ず
+    truncateUrl(url, maxLength = 40) {
+      if (!url) return '';
+      if (url.length <= maxLength) return url;
+
+      const start = url.substring(0, maxLength / 2 - 3);
+      const end = url.substring(url.length - maxLength / 2 + 3);
+      return start + '...' + end;
+    },
+
+    // 浠嶶RL鑾峰彇鏂囦欢鍚�
+    getFileNameFromUrl(url) {
+      if (!url) return 'audio';
+
+      const fileName = url.split('/').pop();
+      return fileName || 'audio';
+    }
+  }
+};
+</script>
+
+<style lang="scss" scoped>
+.audio-player {
+  width: 100%;
+  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
+
+  .audio-container {
+    background: #fff;
+    border-radius: 8px;
+    padding: 12px 16px;
+    box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
+    border: 1px solid #ebeef5;
+
+    .audio-controls {
+      display: flex;
+      align-items: center;
+      gap: 12px;
+
+      .play-btn,
+      .pause-btn {
+        width: 36px;
+        height: 36px;
+        padding: 0;
+        font-size: 20px;
+        color: #409EFF;
+
+        &:hover {
+          color: #66b1ff;
+        }
+
+        &:active {
+          color: #3a8ee6;
+        }
+      }
+
+      .progress-container {
+        flex: 1;
+        height: 36px;
+        display: flex;
+        align-items: center;
+        cursor: pointer;
+
+        .progress-background {
+          position: relative;
+          width: 100%;
+          height: 6px;
+          background: #e4e7ed;
+          border-radius: 3px;
+          overflow: visible;
+
+          .buffered-progress {
+            position: absolute;
+            top: 0;
+            left: 0;
+            height: 100%;
+            background: #c0c4cc;
+            border-radius: 3px;
+            transition: width 0.2s ease;
+          }
+
+          .played-progress {
+            position: absolute;
+            top: 0;
+            left: 0;
+            height: 100%;
+            background: #409EFF;
+            border-radius: 3px;
+            transition: width 0.2s ease;
+            z-index: 2;
+          }
+
+          .hover-preview {
+            position: absolute;
+            top: -30px;
+            width: 1px;
+            height: 20px;
+            background: #909399;
+            transform: translateX(-50%);
+            z-index: 3;
+            pointer-events: none;
+
+            .hover-time {
+              position: absolute;
+              bottom: 100%;
+              left: 50%;
+              transform: translateX(-50%);
+              background: rgba(0, 0, 0, 0.8);
+              color: white;
+              padding: 2px 6px;
+              border-radius: 3px;
+              font-size: 12px;
+              white-space: nowrap;
+            }
+
+            &::after {
+              content: '';
+              position: absolute;
+              top: 100%;
+              left: 50%;
+              transform: translateX(-50%);
+              width: 0;
+              height: 0;
+              border-left: 4px solid transparent;
+              border-right: 4px solid transparent;
+              border-top: 4px solid rgba(0, 0, 0, 0.8);
+            }
+          }
+
+          .playhead {
+            position: absolute;
+            top: 50%;
+            width: 12px;
+            height: 12px;
+            background: #fff;
+            border: 2px solid #409EFF;
+            border-radius: 50%;
+            transform: translate(-50%, -50%);
+            z-index: 4;
+            cursor: pointer;
+            transition: all 0.2s ease;
+
+            &:hover {
+              transform: translate(-50%, -50%) scale(1.2);
+              box-shadow: 0 0 8px rgba(64, 158, 255, 0.5);
+            }
+          }
+        }
+
+        &:hover {
+          .progress-background {
+            height: 8px;
+
+            .playhead {
+              transform: translate(-50%, -50%) scale(1.1);
+            }
+          }
+        }
+      }
+
+      .time-display {
+        min-width: 100px;
+        font-size: 12px;
+        color: #606266;
+        display: flex;
+        align-items: center;
+        gap: 2px;
+
+        .current-time {
+          color: #303133;
+          font-weight: 500;
+        }
+
+        .time-separator {
+          opacity: 0.6;
+        }
+
+        .duration {
+          opacity: 0.8;
+        }
+      }
+
+      .volume-control {
+        .volume-btn {
+          padding: 0;
+          width: 24px;
+          height: 24px;
+          font-size: 16px;
+          color: #606266;
+
+          &:hover {
+            color: #409EFF;
+          }
+        }
+      }
+
+      .playback-rate {
+        width: 60px;
+
+        ::v-deep .el-input__inner {
+          height: 24px;
+          line-height: 24px;
+          padding: 0 5px;
+          font-size: 12px;
+        }
+      }
+
+      .download-btn,
+      .more-btn {
+        padding: 0;
+        width: 24px;
+        height: 24px;
+        font-size: 16px;
+        color: #606266;
+
+        &:hover {
+          color: #409EFF;
+        }
+      }
+    }
+  }
+
+  .simple-player {
+    .simple-play-btn,
+    .simple-pause-btn {
+      padding: 4px 8px;
+      font-size: 12px;
+      color: #409EFF;
+
+      &:hover {
+        color: #66b1ff;
+      }
+    }
+  }
+
+  .audio-info {
+    .info-item {
+      margin-bottom: 12px;
+      display: flex;
+
+      .label {
+        width: 80px;
+        font-weight: 500;
+        color: #303133;
+      }
+
+      .value {
+        flex: 1;
+        color: #606266;
+      }
+
+      .audio-url {
+        color: #409EFF;
+        text-decoration: none;
+
+        &:hover {
+          text-decoration: underline;
+        }
+      }
+    }
+  }
+}
+
+// 闊抽噺寮圭獥鏍峰紡
+::v-deep .volume-popover {
+  padding: 10px;
+  min-width: 40px;
+
+  .volume-slider-container {
+    height: 100px;
+    display: flex;
+    justify-content: center;
+
+    .el-slider {
+      height: 100%;
+
+      .el-slider__runway {
+        background: #e4e7ed;
+      }
+
+      .el-slider__bar {
+        background: #409EFF;
+      }
+
+      .el-slider__button {
+        border-color: #409EFF;
+        width: 12px;
+        height: 12px;
+      }
+    }
+  }
+}
+</style>
diff --git a/src/views/Satisfaction/configurationmyd/batch.vue b/src/views/Satisfaction/configurationmyd/batch.vue
index 10d6619..8e6d01a 100644
--- a/src/views/Satisfaction/configurationmyd/batch.vue
+++ b/src/views/Satisfaction/configurationmyd/batch.vue
@@ -11,8 +11,9 @@
             icon="el-icon-check"
             @click="handleBatchSubmit"
             :loading="batchProcessing"
+            :disabled="selectedExceptionIds.length === 0"
           >
-            鎵归噺鎻愪氦澶勭悊
+            鎵归噺鎻愪氦澶勭悊 ({{ selectedExceptionIds.length }})
           </el-button>
           <el-button type="warning" icon="el-icon-back" @click="handleGoBack">
             杩斿洖寮傚父鍒楄〃
@@ -33,29 +34,40 @@
           >
             <el-form-item label="璐熻矗绉戝">
               <el-select
-                v-model="filterParams.deptId"
+                v-model="filterParams.todeptcode"
                 placeholder="璇烽�夋嫨绉戝"
                 clearable
+                filterable
                 style="width: 200px"
               >
                 <el-option
                   v-for="dept in deptList"
-                  :key="dept.id"
-                  :label="dept.name"
-                  :value="dept.id"
+                  :key="dept.deptCode"
+                  :label="dept.label"
+                  :value="dept.deptCode"
                 />
               </el-select>
             </el-form-item>
             <el-form-item label="澶勭悊鐘舵��">
               <el-select
-                v-model="filterParams.status"
+                v-model="filterParams.handleFlag"
                 placeholder="璇烽�夋嫨鐘舵��"
                 clearable
                 style="width: 200px"
               >
-                <el-option label="寰呭鐞�" :value="0" />
-                <el-option label="澶勭悊涓�" :value="1" />
-                <el-option label="宸插鐞�" :value="2" />
+                <el-option label="鏈鐞�" :value="'0'" />
+                <el-option label="宸插鐞�" :value="'1'" />
+              </el-select>
+            </el-form-item>
+            <el-form-item label="妯℃澘绫诲瀷">
+              <el-select
+                v-model="filterParams.templateType"
+                placeholder="璇烽�夋嫨妯℃澘绫诲瀷"
+                clearable
+                style="width: 200px"
+              >
+                <el-option label="璇煶妯℃澘" :value="1" />
+                <el-option label="闂嵎妯℃澘" :value="2" />
               </el-select>
             </el-form-item>
             <el-form-item>
@@ -79,6 +91,7 @@
           :border="true"
           style="width: 100%"
           @selection-change="handleSelectionChange"
+          row-key="id"
           class="exception-table"
         >
           <el-table-column type="selection" width="55" align="center" />
@@ -92,24 +105,30 @@
 
           <el-table-column
             label="璐熻矗绉戝"
-            prop="responsibilityDept"
-            width="120"
+            prop="todeptname"
+            width="200"
             align="center"
           >
             <template slot-scope="{ row }">
-              <el-tag type="primary">{{ row.responsibilityDept }}</el-tag>
+              <el-tag type="primary" v-if="row.todeptname">{{
+                row.todeptname
+              }}</el-tag>
+              <span v-else class="no-data">鏈垎閰�</span>
             </template>
           </el-table-column>
 
-          <el-table-column
-            label="涓嶆弧鎰忚鎯�"
-            prop="unsatisfactoryDetail"
-            min-width="200"
-            align="center"
-          >
+          <el-table-column label="涓嶆弧鎰忚鎯�" min-width="250" align="center">
             <template slot-scope="{ row }">
               <div class="detail-content">
-                {{ row.unsatisfactoryDetail }}
+                <div class="question-text">
+                  <strong>闂锛�</strong>{{ row.questiontext }}
+                </div>
+                <div class="answer-text">
+                  <strong>鍥炵瓟锛�</strong>{{ row.asrtext || "鏃犲洖绛�" }}
+                </div>
+                <div class="matched-text" v-if="row.matchedtext">
+                  <strong>瑙f瀽鍊硷細</strong>{{ row.matchedtext }}
+                </div>
               </div>
             </template>
           </el-table-column>
@@ -117,42 +136,50 @@
           <el-table-column label="鎮h�呬俊鎭�" width="300" align="center">
             <template slot-scope="{ row }">
               <div class="patient-info">
-                <div class="patient-item">
-                  <span class="label">濮撳悕锛�</span>
-                  <span class="value">{{ row.patientName }}</span>
+                <div class="patient-row">
+                  <div class="patient-item">
+                    <span class="label">濮撳悕锛�</span>
+                    <span class="value">{{ row.patientName }}</span>
+                  </div>
+                  <div class="patient-item">
+                    <span class="label">鎬у埆锛�</span>
+                    <span class="value">{{
+                      row.gender === 1 ? "鐢�" : "濂�"
+                    }}</span>
+                  </div>
+                  <div class="patient-item">
+                    <span class="label">骞撮緞锛�</span>
+                    <span class="value">{{ row.age }}宀�</span>
+                  </div>
                 </div>
-                <div class="patient-item">
-                  <span class="label">鎬у埆锛�</span>
-                  <span class="value">{{
-                    row.gender === 1 ? "鐢�" : "濂�"
-                  }}</span>
-                </div>
-                <div class="patient-item">
-                  <span class="label">骞撮緞锛�</span>
-                  <span class="value">{{ row.age }}宀�</span>
-                </div>
-                <div class="patient-item">
-                  <span class="label">鐢佃瘽锛�</span>
-                  <span class="value">{{ row.phone }}</span>
+                <div class="patient-row">
+                  <div class="patient-item full-width">
+                    <span class="label">鐢佃瘽锛�</span>
+                    <span class="value">{{ row.phone }}</span>
+                  </div>
                 </div>
               </div>
             </template>
           </el-table-column>
 
-          <el-table-column label="鍑洪櫌淇℃伅" width="250" align="center">
+          <el-table-column label="濉啓淇℃伅" width="180" align="center">
             <template slot-scope="{ row }">
-              <div class="discharge-info">
+              <div class="fill-info">
                 <div class="info-item">
-                  <span class="label">绉戝锛�</span>
-                  <span class="value">{{ row.dischargeDept }}</span>
+                  <span class="label">濉姤鏃堕棿锛�</span>
+                  <span class="value time">{{
+                    formatDateTime(row.createTime)
+                  }}</span>
                 </div>
-                <div class="info-item">
-                  <span class="label">鐥呭尯锛�</span>
-                  <span class="value">{{ row.dischargeWard }}</span>
-                </div>
-                <div class="info-item">
-                  <span class="label">濉啓鏃堕棿锛�</span>
-                  <span class="value time">{{ row.fillTime }}</span>
+                <div v-if="row.recordurl" class="info-item">
+                  <el-button
+                    type="text"
+                    size="small"
+                    @click="handlePlayAudio(row.recordurl)"
+                    icon="el-icon-headset"
+                  >
+                    鎾斁褰曢煶
+                  </el-button>
                 </div>
               </div>
             </template>
@@ -160,14 +187,36 @@
 
           <el-table-column
             label="澶勭悊鐘舵��"
-            prop="processStatus"
+            prop="handleFlag"
             width="100"
             align="center"
           >
             <template slot-scope="{ row }">
-              <el-tag :type="getStatusTagType(row.processStatus)" effect="dark">
-                {{ getStatusText(row.processStatus) }}
+              <el-tag :type="getStatusTagType(row.handleFlag)" effect="dark">
+                {{ getStatusText(row.handleFlag) }}
               </el-tag>
+            </template>
+          </el-table-column>
+
+          <el-table-column label="鏈�鏂板鐞嗕俊鎭�" width="180" align="center">
+            <template slot-scope="{ row }">
+              <div v-if="row.handleTime" class="handle-info">
+                <div class="info-item">
+                  <span class="label">澶勭悊浜猴細</span>
+                  <span class="value">{{ row.handleBy || "绯荤粺" }}</span>
+                </div>
+                <div class="info-item">
+                  <span class="label">澶勭悊鏃堕棿锛�</span>
+                  <span class="value time">{{
+                    formatDateTime(row.handleTime)
+                  }}</span>
+                </div>
+                <div class="info-item">
+                  <span class="label">澶勭悊璇存槑锛�</span>
+                  <span class="value">{{ row.handledesc }}</span>
+                </div>
+              </div>
+              <span v-else class="no-data">鏈鐞�</span>
             </template>
           </el-table-column>
 
@@ -191,7 +240,7 @@
                 size="small"
                 icon="el-icon-edit"
                 @click="handleProcess(row)"
-                :disabled="row.processStatus === 2"
+                :disabled="row.handleFlag === '1'"
               >
                 澶勭悊
               </el-button>
@@ -229,63 +278,76 @@
         label-width="100px"
         size="medium"
       >
-        <el-form-item label="澶勭悊鐘舵��" prop="status">
+        <el-form-item label="澶勭悊鐘舵��" prop="handleFlag">
           <el-select
-            v-model="processForm.status"
+            v-model="processForm.handleFlag"
             placeholder="璇烽�夋嫨澶勭悊鐘舵��"
             style="width: 100%"
           >
-            <el-option label="澶勭悊涓�" :value="1" />
-            <el-option label="宸插鐞�" :value="2" />
-            <el-option label="宸查┏鍥�" :value="3" />
+            <el-option label="宸插鐞�" :value="'1'" />
+            <el-option label="鍙栨秷澶勭悊" :value="'0'" />
           </el-select>
         </el-form-item>
 
-        <el-form-item label="鎶ュ绉戝" prop="reportDepts">
+        <el-form-item label="鎶ュ绉戝" prop="ccdepts">
           <el-select
-            v-model="processForm.reportDepts"
+            v-model="processForm.ccdepts"
             placeholder="璇烽�夋嫨鎶ュ绉戝"
             multiple
             filterable
             collapse-tags
             style="width: 100%"
+            :disabled="processForm.handleFlag !== '1'"
           >
             <el-option
               v-for="dept in deptList"
-              :key="dept.id"
-              :label="dept.name"
-              :value="dept.id"
+              :key="dept.deptCode"
+              :label="dept.label"
+              :value="dept.deptCode"
             />
           </el-select>
         </el-form-item>
 
-        <el-form-item label="澶勭悊澶囨敞" prop="remark">
+        <el-form-item label="澶勭悊缁撴灉" prop="handleresult">
+          <el-select
+            v-model="processForm.handleresult"
+            placeholder="璇烽�夋嫨澶勭悊缁撴灉"
+            style="width: 100%"
+            :disabled="processForm.handleFlag !== '1'"
+          >
+            <el-option label="宸茶В鍐�" value="resolved" />
+            <el-option label="宸茶В閲�" value="explained" />
+            <el-option label="宸茶浆浜�" value="transferred" />
+            <el-option label="闇�鏀硅繘" value="improvement" />
+            <el-option label="宸查┏鍥�" value="rejected" />
+          </el-select>
+        </el-form-item>
+
+        <el-form-item label="澶勭悊璇存槑" prop="handledesc">
           <el-input
-            v-model="processForm.remark"
+            v-model="processForm.handledesc"
             type="textarea"
             :rows="4"
-            placeholder="璇疯緭鍏ュ鐞嗗娉紙鏈�澶�500瀛楋級"
+            placeholder="璇疯緭鍏ュ鐞嗚鏄庯紙鏈�澶�500瀛楋級"
             maxlength="500"
             show-word-limit
+            :disabled="processForm.handleFlag !== '1'"
           />
         </el-form-item>
 
-        <el-form-item label="闄勪欢涓婁紶">
-          <el-upload
-            class="upload-demo"
-            action="#"
-            :on-preview="handlePreview"
-            :on-remove="handleRemove"
-            :before-remove="beforeRemove"
-            :limit="3"
-            :on-exceed="handleExceed"
-            :file-list="fileList"
-          >
-            <el-button size="small" type="primary">鐐瑰嚮涓婁紶</el-button>
-            <div slot="tip" class="el-upload__tip">
-              鏀寔涓婁紶鍥剧墖銆佹枃妗g瓑闄勪欢锛屽崟涓枃浠朵笉瓒呰繃10MB
-            </div>
-          </el-upload>
+        <el-form-item
+          label="鏈�缁堟剰瑙�"
+          prop="finaloption"
+          v-if="hasQualityPermission"
+        >
+          <el-input
+            v-model="processForm.finaloption"
+            type="textarea"
+            :rows="3"
+            placeholder="璇疯緭鍏ユ渶缁堝鐞嗘剰瑙侊紙鏈�澶�300瀛楋級"
+            maxlength="300"
+            show-word-limit
+          />
         </el-form-item>
       </el-form>
       <span slot="footer" class="dialog-footer">
@@ -310,44 +372,60 @@
         label-width="100px"
         size="medium"
       >
-        <el-form-item label="澶勭悊鐘舵��" prop="status">
+        <el-form-item label="澶勭悊鐘舵��" prop="handleFlag">
           <el-select
-            v-model="batchProcessForm.status"
+            v-model="batchProcessForm.handleFlag"
             placeholder="璇烽�夋嫨澶勭悊鐘舵��"
             style="width: 100%"
           >
-            <el-option label="澶勭悊涓�" :value="1" />
-            <el-option label="宸插鐞�" :value="2" />
-            <el-option label="宸查┏鍥�" :value="3" />
+            <el-option label="宸插鐞�" :value="'1'" />
+            <el-option label="鍙栨秷澶勭悊" :value="'0'" />
           </el-select>
         </el-form-item>
 
-        <el-form-item label="鎶ュ绉戝" prop="reportDepts">
+        <el-form-item label="鎶ュ绉戝" prop="ccdepts">
           <el-select
-            v-model="batchProcessForm.reportDepts"
+            v-model="batchProcessForm.ccdepts"
             placeholder="璇烽�夋嫨鎶ュ绉戝"
             multiple
             filterable
             collapse-tags
             style="width: 100%"
+            :disabled="batchProcessForm.handleFlag !== '1'"
           >
             <el-option
               v-for="dept in deptList"
-              :key="dept.id"
-              :label="dept.name"
-              :value="dept.id"
+              :key="dept.deptCode"
+              :label="dept.label"
+              :value="dept.deptCode"
             />
           </el-select>
         </el-form-item>
 
-        <el-form-item label="澶勭悊澶囨敞" prop="remark">
+        <el-form-item label="澶勭悊缁撴灉" prop="handleresult">
+          <el-select
+            v-model="batchProcessForm.handleresult"
+            placeholder="璇烽�夋嫨澶勭悊缁撴灉"
+            style="width: 100%"
+            :disabled="batchProcessForm.handleFlag !== '1'"
+          >
+            <el-option label="宸茶В鍐�" value="resolved" />
+            <el-option label="宸茶В閲�" value="explained" />
+            <el-option label="宸茶浆浜�" value="transferred" />
+            <el-option label="闇�鏀硅繘" value="improvement" />
+            <el-option label="宸查┏鍥�" value="rejected" />
+          </el-select>
+        </el-form-item>
+
+        <el-form-item label="澶勭悊璇存槑" prop="handledesc">
           <el-input
-            v-model="batchProcessForm.remark"
+            v-model="batchProcessForm.handledesc"
             type="textarea"
             :rows="4"
-            placeholder="璇疯緭鍏ュ鐞嗗娉紙鏈�澶�500瀛楋級"
+            placeholder="璇疯緭鍏ュ鐞嗚鏄庯紙鏈�澶�500瀛楋級"
             maxlength="500"
             show-word-limit
+            :disabled="batchProcessForm.handleFlag !== '1'"
           />
         </el-form-item>
       </el-form>
@@ -358,24 +436,56 @@
           @click="submitBatchProcess"
           :loading="batchProcessing"
         >
-          鎵归噺鎻愪氦
+          鎵归噺鎻愪氦 ({{ selectedExceptionIds.length }})
         </el-button>
       </span>
+    </el-dialog>
+    <!-- 杩涘害瀵硅瘽妗� -->
+    <el-dialog
+      title="鎵归噺澶勭悊杩涘害"
+      :visible.sync="batchProgress.visible"
+      width="400px"
+      :close-on-click-modal="false"
+      :show-close="false"
+      :close-on-press-escape="false"
+    >
+      <div class="progress-content">
+        <el-progress
+          :percentage="batchProgress.percentage"
+          :status="batchProgress.percentage === 100 ? 'success' : ''"
+        />
+        <div class="progress-info">
+          宸插鐞� {{ batchProgress.processed }}/{{ batchProgress.total }} 鏉¤褰�
+        </div>
+      </div>
     </el-dialog>
     <!-- 寮傚父璇︽儏寮规 -->
     <Details-anomaly
       :visible="detailDialogVisible"
       :record-id="selectedRecordId"
       :title="detailDialogTitle"
+      :record-data="selectedRecordData"
       @update:visible="handleDetailDialogClose"
       @processed="handleProcessed"
       @close="handleDetailDialogClose"
+    />
+
+    <!-- 褰曢煶鎾斁鍣� -->
+    <audio
+      v-if="audioUrl"
+      :src="audioUrl"
+      ref="audioPlayer"
+      controls
+      style="display: none"
     />
   </div>
 </template>
 
 <script>
 import DetailsAnomaly from "./components/DetailsAnomaly.vue";
+import { tracelist, traceedit } from "@/api/AiCentre/index";
+import { deptTreeSelect } from "@/api/system/user";
+
 export default {
   name: "BatchProcess",
   components: {
@@ -383,10 +493,15 @@
   },
   data() {
     return {
-      // 娣诲姞浠ヤ笅鏁版嵁
+      // 璇︽儏寮规鐩稿叧
       detailDialogVisible: false,
       selectedRecordId: null,
+      selectedRecordData: null,
       detailDialogTitle: "寮傚父鍙嶉璇︽儏",
+
+      // 闊抽鎾斁
+      audioUrl: "",
+
       // 褰撳墠澶勭悊鐨勫紓甯窱D
       currentExceptionId: null,
 
@@ -395,8 +510,10 @@
 
       // 杩囨护鍙傛暟
       filterParams: {
-        deptId: "",
-        status: "",
+        todeptcode: "",
+        handleFlag: "",
+        templateType: "",
+        scriptid: null,
         pageNum: 1,
         pageSize: 10,
       },
@@ -406,19 +523,11 @@
       processing: false,
       batchProcessing: false,
 
+      // 鏉冮檺鎺у埗
+      hasQualityPermission: false, // 鏄惁鍏锋湁璐ㄧ鏉冮檺
+
       // 绉戝鍒楄〃
-      deptList: [
-        { id: 1, name: "蹇冭绠″唴绉�" },
-        { id: 2, name: "绁炵粡鍐呯" },
-        { id: 3, name: "鏅绉�" },
-        { id: 4, name: "楠ㄧ" },
-        { id: 5, name: "濡囦骇绉�" },
-        { id: 6, name: "鍎跨" },
-        { id: 7, name: "鎬ヨ瘖绉�" },
-        { id: 8, name: "鍛煎惛鍐呯" },
-        { id: 9, name: "娑堝寲鍐呯" },
-        { id: 10, name: "鍐呭垎娉岀" },
-      ],
+      deptList: [],
 
       // 寮傚父鍒楄〃鏁版嵁
       exceptionList: [],
@@ -427,183 +536,164 @@
       // 澶勭悊瀵硅瘽妗�
       processDialogVisible: false,
       processForm: {
-        status: "",
-        reportDepts: [],
-        remark: "",
+        handleFlag: "",
+        ccdepts: [],
+        handleresult: "",
+        handledesc: "",
+        finaloption: "",
+      },
+      batchProgress: {
+        visible: false,
+        percentage: 0,
+        processed: 0,
+        total: 0,
       },
       processRules: {
-        status: [
+        handleFlag: [
           { required: true, message: "璇烽�夋嫨澶勭悊鐘舵��", trigger: "change" },
         ],
-        remark: [
-          { required: true, message: "璇疯緭鍏ュ鐞嗗娉�", trigger: "blur" },
+        handleresult: [
           {
-            min: 5,
-            max: 500,
-            message: "澶囨敞闀垮害鍦� 5 鍒� 500 涓瓧绗�",
+            required: true,
+            message: "璇烽�夋嫨澶勭悊缁撴灉",
+            trigger: "change",
+            validator: (rule, value, callback) => {
+              if (this.processForm.handleFlag === "1" && !value) {
+                callback(new Error("璇烽�夋嫨澶勭悊缁撴灉"));
+              } else {
+                callback();
+              }
+            },
+          },
+        ],
+        handledesc: [
+          {
+            required: true,
+            message: "璇疯緭鍏ュ鐞嗚鏄�",
             trigger: "blur",
+            validator: (rule, value, callback) => {
+              if (
+                this.processForm.handleFlag === "1" &&
+                (!value || value.trim().length < 3)
+              ) {
+                callback(new Error("澶勭悊璇存槑鑷冲皯3涓瓧绗�"));
+              } else {
+                callback();
+              }
+            },
           },
         ],
       },
-      fileList: [],
 
       // 鎵归噺澶勭悊瀵硅瘽妗�
       batchDialogVisible: false,
       batchProcessForm: {
-        status: "",
-        reportDepts: [],
-        remark: "",
+        handleFlag: "",
+        ccdepts: [],
+        handleresult: "",
+        handledesc: "",
       },
     };
   },
 
+  created() {
+    // 浠庤矾鐢卞弬鏁拌幏鍙栭棶棰業D
+    if (this.$route.query.questionId) {
+      this.filterParams.scriptid = this.$route.query.questionId || null;
+      this.filterParams.scriptids = null;
+    } else if (this.$route.query.questionIds) {
+      this.filterParams.scriptids = this.$route.query.questionIds;
+      this.filterParams.scriptid=null;
+    }
+    this.hasQualityPermission = this.checkQualityPermission();
+  },
+
   mounted() {
     this.loadExceptionList();
+    this.getDeptOptions();
   },
 
   methods: {
-    // 鍔犺浇寮傚父鍒楄〃
-    async loadExceptionList() {
-      this.loading = true;
+    // 鏍煎紡鍖栨棩鏈熸椂闂�
+    formatDateTime(dateTime) {
+      if (!dateTime) return "";
       try {
-        // Mock 鏁版嵁
-        await new Promise((resolve) => {
-          setTimeout(() => {
-            this.exceptionList = [
-              {
-                id: 1,
-                responsibilityDept: "蹇冭绠″唴绉�",
-                unsatisfactoryDetail:
-                  "鍖荤敓鏌ユ埧鏃堕棿澶煭锛屾矡閫氫笉澶熷厖鍒嗭紝瀵圭梾鎯呰В閲婁笉澶熻缁�",
-                patientName: "寮犲厛鐢�",
-                gender: 1,
-                age: 45,
-                phone: "138****1234",
-                dischargeDept: "蹇冭绠″唴绉�",
-                dischargeWard: "鍐呯涓�鐥呭尯",
-                fillTime: "2024-01-15 10:30:25",
-                processStatus: 0,
-                questionnaireId: 1001,
-              },
-              {
-                id: 2,
-                responsibilityDept: "绁炵粡鍐呯",
-                unsatisfactoryDetail:
-                  "鎶ゅ+鎵撻拡鎶�鏈笉浣筹紝鎵庝簡涓夋鎵嶆垚鍔燂紝涓旀�佸害涓嶅鑰愬績",
-                patientName: "鏉庡コ澹�",
-                gender: 0,
-                age: 38,
-                phone: "139****5678",
-                dischargeDept: "绁炵粡鍐呯",
-                dischargeWard: "鍐呯浜岀梾鍖�",
-                fillTime: "2024-01-14 16:20:10",
-                processStatus: 0,
-                questionnaireId: 1002,
-              },
-              {
-                id: 3,
-                responsibilityDept: "鏅绉�",
-                unsatisfactoryDetail: "鏈悗鎹㈣嵂涓嶅強鏃讹紝浼ゅ彛鐤肩棝鏃舵病鏈夊強鏃跺鐞�",
-                patientName: "鐜嬪厛鐢�",
-                gender: 1,
-                age: 52,
-                phone: "137****9012",
-                dischargeDept: "鏅绉�",
-                dischargeWard: "澶栫涓�鐥呭尯",
-                fillTime: "2024-01-13 09:15:45",
-                processStatus: 1,
-                questionnaireId: 1003,
-              },
-              {
-                id: 4,
-                responsibilityDept: "楠ㄧ",
-                unsatisfactoryDetail: "搴峰鎸囧涓嶅涓撲笟锛屽鎭㈠杩囩▼鎻忚堪涓嶆竻妤�",
-                patientName: "鍒樺コ澹�",
-                gender: 0,
-                age: 65,
-                phone: "136****3456",
-                dischargeDept: "楠ㄧ",
-                dischargeWard: "澶栫浜岀梾鍖�",
-                fillTime: "2024-01-12 14:40:30",
-                processStatus: 0,
-                questionnaireId: 1004,
-              },
-              {
-                id: 5,
-                responsibilityDept: "濡囦骇绉�",
-                unsatisfactoryDetail:
-                  "浜у墠妫�鏌ユ帓闃熸椂闂磋繃闀匡紝绛夊緟鏈熼棿娌℃湁浼戞伅搴т綅",
-                patientName: "闄堝コ澹�",
-                gender: 0,
-                age: 28,
-                phone: "135****7890",
-                dischargeDept: "濡囦骇绉�",
-                dischargeWard: "濡囦骇绉戠梾鍖�",
-                fillTime: "2024-01-11 11:25:15",
-                processStatus: 2,
-                questionnaireId: 1005,
-              },
-              {
-                id: 6,
-                responsibilityDept: "鍎跨",
-                unsatisfactoryDetail:
-                  "鍎跨鐢ㄨ嵂鍓傞噺浜や唬涓嶆竻鏅帮紝鐢ㄨ嵂娉ㄦ剰浜嬮」娌℃湁璇存槑",
-                patientName: "璧靛疂瀹�",
-                gender: 1,
-                age: 5,
-                phone: "134****1234",
-                dischargeDept: "鍎跨",
-                dischargeWard: "鍎跨鐥呭尯",
-                fillTime: "2024-01-10 15:50:20",
-                processStatus: 0,
-                questionnaireId: 1006,
-              },
-              {
-                id: 7,
-                responsibilityDept: "鎬ヨ瘖绉�",
-                unsatisfactoryDetail: "鎬ヨ瘖绛夊緟鏃堕棿杩囬暱锛岀梾鎯呮病鏈夊緱鍒板強鏃惰瘎浼�",
-                patientName: "瀛欏厛鐢�",
-                gender: 1,
-                age: 40,
-                phone: "133****5678",
-                dischargeDept: "鎬ヨ瘖绉�",
-                dischargeWard: "鎬ヨ瘖鐥呭尯",
-                fillTime: "2024-01-09 10:15:40",
-                processStatus: 0,
-                questionnaireId: 1007,
-              },
-              {
-                id: 8,
-                responsibilityDept: "鍛煎惛鍐呯",
-                unsatisfactoryDetail: "鍖荤敓寮�鑽緝澶氾紝璐圭敤杈冮珮锛屾病鏈夎鏄庡繀瑕佹��",
-                patientName: "鍛ㄥコ澹�",
-                gender: 0,
-                age: 55,
-                phone: "132****9012",
-                dischargeDept: "鍛煎惛鍐呯",
-                dischargeWard: "鍐呯涓�鐥呭尯",
-                fillTime: "2024-01-08 13:30:55",
-                processStatus: 1,
-                questionnaireId: 1008,
-              },
-            ];
-            this.total = this.exceptionList.length;
-            resolve();
-          }, 500);
+        const date = new Date(dateTime);
+        if (isNaN(date.getTime())) {
+          return dateTime;
+        }
+        return (
+          date.toLocaleDateString().replace(/\//g, "-") +
+          " " +
+          date.toTimeString().split(" ")[0]
+        );
+      } catch (error) {
+        console.error("鏃ユ湡鏍煎紡鍖栭敊璇�:", error);
+        return dateTime;
+      }
+    },
+    /** 鏌ヨ绉戝鍒楄〃 */
+    getDeptOptions() {
+      deptTreeSelect()
+        .then((res) => {
+          if (res.code == 200) {
+            this.deptList = this.flattenArray(res.data) || [];
+          }
+        })
+        .catch((error) => {
+          console.error("鑾峰彇绉戝鍒楄〃澶辫触:", error);
+          this.$message.error("鑾峰彇绉戝鍒楄〃澶辫触");
         });
-      } finally {
-        this.loading = false;
+    },
+    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;
+    },
+    // 瑙f瀽鎮h�呮弿杩颁俊鎭�
+    parsePatDesc(patdesc) {
+      if (!patdesc) return [];
+
+      try {
+        const parts = patdesc.split("|");
+        const items = [];
+
+        if (parts[0]) items.push({ label: "濮撳悕", value: parts[0] });
+        if (parts[1]) items.push({ label: "鐢佃瘽", value: parts[1] });
+        if (parts[2]) items.push({ label: "绉戝", value: parts[2] });
+
+        return items;
+      } catch (error) {
+        console.error("瑙f瀽鎮h�呬俊鎭け璐�:", error);
+        return [];
       }
     },
 
+    // 妫�鏌ヨ川绠℃潈闄�
+    checkQualityPermission() {
+      // 杩欓噷鍙互鏍规嵁瀹為檯鏉冮檺绯荤粺瀹炵幇
+      const userRoles = this.$store.getters.roles || [];
+      return (
+        userRoles.includes("quality_manager") || userRoles.includes("admin")
+      );
+    },
+
     // 鑾峰彇鐘舵�佹爣绛剧被鍨�
-    getStatusTagType(status) {
-      switch (status) {
-        case 0:
-          return "warning"; // 寰呭鐞�
-        case 1:
-          return "primary"; // 澶勭悊涓�
-        case 2:
+    getStatusTagType(handleFlag) {
+      switch (handleFlag) {
+        case "0":
+          return "warning"; // 鏈鐞�
+        case "1":
           return "success"; // 宸插鐞�
         default:
           return "info";
@@ -611,16 +701,79 @@
     },
 
     // 鑾峰彇鐘舵�佹枃鏈�
-    getStatusText(status) {
-      switch (status) {
-        case 0:
-          return "寰呭鐞�";
-        case 1:
-          return "澶勭悊涓�";
-        case 2:
+    getStatusText(handleFlag) {
+      switch (handleFlag) {
+        case "0":
+          return "鏈鐞�";
+        case "1":
           return "宸插鐞�";
         default:
           return "鏈煡";
+      }
+    },
+
+    // 鎾斁褰曢煶
+    handlePlayAudio(url) {
+      this.audioUrl = url;
+      this.$nextTick(() => {
+        const audioPlayer = this.$refs.audioPlayer;
+        if (audioPlayer) {
+          audioPlayer.play().catch((error) => {
+            console.error("鎾斁澶辫触:", error);
+            this.$message.error("闊抽鎾斁澶辫触");
+          });
+        }
+      });
+    },
+
+    // 鏋勫缓鏌ヨ鍙傛暟
+    buildQueryParams() {
+      const params = {
+        pageNum: this.filterParams.pageNum,
+        pageSize: this.filterParams.pageSize,
+      };
+
+      if (this.filterParams.todeptcode) {
+        params.todeptcode = this.filterParams.todeptcode;
+      }
+
+      if (this.filterParams.handleFlag !== "") {
+        params.handleFlag = this.filterParams.handleFlag;
+      }
+
+      if (this.filterParams.templateType) {
+        params.templateType = this.filterParams.templateType;
+      }
+
+      if (this.filterParams.scriptid) {
+        params.scriptid = this.filterParams.scriptid;
+      }
+
+      return params;
+    },
+
+    // 鍔犺浇寮傚父鍒楄〃
+    async loadExceptionList() {
+      this.loading = true;
+      try {
+        const params = this.buildQueryParams();
+        const response = await tracelist(params);
+
+        if (response && response.code === 200) {
+          this.exceptionList = response.rows || [];
+          this.total = response.total || 0;
+        } else {
+          this.exceptionList = [];
+          this.total = 0;
+          this.$message.error(response?.msg || "鍔犺浇寮傚父鍒楄〃澶辫触");
+        }
+      } catch (error) {
+        console.error("鍔犺浇寮傚父鍒楄〃澶辫触:", error);
+        this.$message.error("鍔犺浇寮傚父鍒楄〃澶辫触锛岃绋嶅悗閲嶈瘯");
+        this.exceptionList = [];
+        this.total = 0;
+      } finally {
+        this.loading = false;
       }
     },
 
@@ -633,11 +786,14 @@
     // 閲嶇疆绛涢��
     handleResetFilter() {
       this.filterParams = {
-        deptId: "",
-        status: "",
+        todeptcode: "",
+        handleFlag: "",
+        templateType: "",
+        scriptid: null, // 淇濈暀闂ID
         pageNum: 1,
         pageSize: 10,
       };
+      this.selectedExceptionIds = [];
       this.loadExceptionList();
     },
 
@@ -652,6 +808,15 @@
         this.$message.warning("璇峰厛閫夋嫨瑕佸鐞嗙殑寮傚父鍙嶉");
         return;
       }
+
+      // 閲嶇疆鎵归噺澶勭悊琛ㄥ崟
+      this.batchProcessForm = {
+        handleFlag: "",
+        ccdepts: [],
+        handleresult: "",
+        handledesc: "",
+      };
+
       this.batchDialogVisible = true;
     },
 
@@ -663,44 +828,84 @@
     // 鏌ョ湅璇︽儏
     handleViewDetail(row) {
       this.selectedRecordId = row.id;
-      this.detailDialogTitle = `${row.patientName} - 寮傚父鍙嶉璇︽儏`;
+      this.selectedRecordData = row;
+
+      // 鐢熸垚寮规鏍囬
+      let title = "寮傚父鍙嶉璇︽儏";
+      if (row.patdesc) {
+        const patientName = row.patdesc.split("|")[0];
+        if (patientName) {
+          title = `${patientName} - ${title}`;
+        }
+      }
+      this.detailDialogTitle = title;
+
       this.detailDialogVisible = true;
     },
+
     // 澶勭悊璇︽儏寮规鍏抽棴
     handleDetailDialogClose() {
       this.detailDialogVisible = false;
       this.selectedRecordId = null;
-    }, // 澶勭悊瀹屾垚鍚庣殑鍥炶皟
+      this.selectedRecordData = null;
+    },
+
+    // 澶勭悊瀹屾垚鍚庣殑鍥炶皟
     handleProcessed() {
-      // 閲嶆柊鍔犺浇鏁版嵁
       this.loadExceptionList();
     },
+
     // 澶勭悊鍗曚釜寮傚父
     handleProcess(row) {
       this.currentExceptionId = row.id;
+
+      // 鍒濆鍖栬〃鍗曟暟鎹�
       this.processForm = {
-        status: row.processStatus === 0 ? 1 : row.processStatus,
-        reportDepts: [],
-        remark: "",
+        handleFlag: row.handleFlag === "0" ? "1" : "0",
+        ccdepts: row.ccdepts ? row.ccdepts.split(",") : [],
+        handleresult: row.handleresult || "",
+        handledesc: row.handledesc || "",
+        finaloption: row.finaloption || "",
       };
+
       this.processDialogVisible = true;
     },
 
     // 鎻愪氦澶勭悊
     async submitProcess() {
       this.$refs.processForm.validate(async (valid) => {
-        if (valid) {
-          this.processing = true;
-          try {
-            // Mock API璋冪敤
-            await new Promise((resolve) => setTimeout(resolve, 1000));
+        if (!valid) {
+          return;
+        }
 
-            this.$message.success("澶勭悊鎻愪氦鎴愬姛");
-            this.processDialogVisible = false;
-            this.loadExceptionList();
-          } finally {
-            this.processing = false;
-          }
+        this.processing = true;
+
+        try {
+          // 鍑嗗鎻愪氦鏁版嵁
+          const submitData = {
+            id: this.currentExceptionId,
+            handleFlag: this.processForm.handleFlag,
+            handleresult: this.processForm.handleresult,
+            handledesc: this.processForm.handledesc,
+            finaloption: this.processForm.finaloption,
+            // 灏嗘暟缁勮浆鎹负閫楀彿鍒嗛殧鐨勫瓧绗︿覆
+            ccdepts: Array.isArray(this.processForm.ccdepts)
+              ? this.processForm.ccdepts.join(",")
+              : this.processForm.ccdepts,
+          };
+          // TODO: 杩欓噷闇�瑕佽皟鐢ㄥ疄闄呯殑澶勭悊鎺ュ彛
+          await traceedit(submitData);
+
+          // await new Promise((resolve) => setTimeout(resolve, 1000));
+
+          this.$message.success("澶勭悊鎻愪氦鎴愬姛");
+          this.processDialogVisible = false;
+          this.loadExceptionList();
+        } catch (error) {
+          console.error("澶勭悊鎻愪氦澶辫触:", error);
+          this.$message.error("澶勭悊鎻愪氦澶辫触锛岃绋嶅悗閲嶈瘯");
+        } finally {
+          this.processing = false;
         }
       });
     },
@@ -708,21 +913,111 @@
     // 鎻愪氦鎵归噺澶勭悊
     async submitBatchProcess() {
       this.$refs.batchProcessForm.validate(async (valid) => {
-        if (valid) {
-          this.batchProcessing = true;
-          try {
-            // Mock API璋冪敤
-            await new Promise((resolve) => setTimeout(resolve, 1500));
+        if (!valid) {
+          return;
+        }
 
-            this.$message.success(
-              `宸叉壒閲忓鐞� ${this.selectedExceptionIds.length} 鏉″紓甯稿弽棣坄
+        this.batchProcessing = true;
+        // 鏄剧ず杩涘害鏉�
+        this.batchProgress = {
+          visible: true,
+          percentage: 0,
+          processed: 0,
+          total: this.selectedExceptionIds.length,
+        };
+        try {
+          // 鍑嗗鎵归噺鎻愪氦鏁版嵁
+          const processData = {
+            handleFlag: this.batchProcessForm.handleFlag,
+            handleresult: this.batchProcessForm.handleresult,
+            handledesc: this.batchProcessForm.handledesc,
+            ccdepts: Array.isArray(this.batchProcessForm.ccdepts)
+              ? this.batchProcessForm.ccdepts.join(",")
+              : this.batchProcessForm.ccdepts,
+          };
+
+          // 鎺у埗骞跺彂鏁�
+          const CONCURRENT_LIMIT = 10; // 鍚屾椂鏈�澶�3涓姹�
+          const totalCount = this.selectedExceptionIds.length;
+          const results = [];
+          let successCount = 0;
+          let failCount = 0;
+
+          this.$message.info(`寮�濮嬫壒閲忓鐞� ${totalCount} 鏉¤褰�...`);
+
+          // 鍒嗙粍澶勭悊
+          for (
+            let i = 0;
+            i < this.selectedExceptionIds.length;
+            i += CONCURRENT_LIMIT
+          ) {
+            const batchIds = this.selectedExceptionIds.slice(
+              i,
+              i + CONCURRENT_LIMIT
             );
-            this.batchDialogVisible = false;
-            this.selectedExceptionIds = [];
-            this.loadExceptionList();
-          } finally {
-            this.batchProcessing = false;
+
+            // 骞跺彂澶勭悊褰撳墠鎵规
+            const batchPromises = batchIds.map((id) =>
+              traceedit({
+                id: id,
+                ...processData,
+              })
+                .then((result) => ({
+                  id,
+                  success: result && result.code === 200,
+                  error: result?.msg,
+                }))
+                .catch((error) => ({
+                  id,
+                  success: false,
+                  error: error.message,
+                }))
+            );
+
+            const batchResults = await Promise.all(batchPromises);
+            results.push(...batchResults);
+
+            // 鏇存柊缁熻
+            batchResults.forEach((result) => {
+              if (result.success) {
+                successCount++;
+              } else {
+                failCount++;
+                console.error(`澶勭悊璁板綍 ${result.id} 澶辫触:`, result.error);
+              }
+            });
+            // 鏇存柊杩涘害
+            this.batchProgress.processed = i + 1;
+            this.batchProgress.percentage = Math.round(
+              ((i + 1) / totalCount) * 100
+            );
+            // 鏄剧ず杩涘害
+            console.log(
+              `杩涘害: ${Math.min(
+                i + CONCURRENT_LIMIT,
+                totalCount
+              )}/${totalCount}`
+            );
           }
+
+          // 澶勭悊缁撴灉鎻愮ず
+          if (successCount === totalCount) {
+            this.$message.success(`宸叉垚鍔熷鐞嗗叏閮� ${totalCount} 鏉″紓甯稿弽棣坄);
+          } else {
+            this.$message.warning(
+              `宸插鐞� ${successCount} 鏉★紝澶辫触 ${failCount} 鏉″紓甯稿弽棣坄
+            );
+          }
+
+          this.batchDialogVisible = false;
+          this.selectedExceptionIds = [];
+          this.loadExceptionList();
+        } catch (error) {
+          console.error("鎵归噺澶勭悊澶辫触:", error);
+          this.$message.error("鎵归噺澶勭悊澶辫触锛岃绋嶅悗閲嶈瘯");
+        } finally {
+          this.batchProcessing = false;
+          this.batchProgress.visible = false;
         }
       });
     },
@@ -738,27 +1033,6 @@
     handlePageChange(page) {
       this.filterParams.pageNum = page;
       this.loadExceptionList();
-    },
-
-    // 鏂囦欢涓婁紶鐩稿叧鏂规硶
-    handlePreview(file) {
-      console.log("棰勮鏂囦欢:", file);
-    },
-
-    handleRemove(file, fileList) {
-      console.log("绉婚櫎鏂囦欢:", file, fileList);
-    },
-
-    beforeRemove(file) {
-      return this.$confirm(`纭畾绉婚櫎 ${file.name}锛焋);
-    },
-
-    handleExceed(files, fileList) {
-      this.$message.warning(
-        `褰撳墠闄愬埗閫夋嫨 3 涓枃浠讹紝鏈閫夋嫨浜� ${files.length} 涓枃浠讹紝鍏遍�夋嫨浜� ${
-          files.length + fileList.length
-        } 涓枃浠禶
-      );
     },
   },
 };
@@ -827,37 +1101,78 @@
       }
 
       .detail-content {
-        font-size: 13px;
-        color: #606266;
-        line-height: 1.5;
         text-align: left;
+        font-size: 12px;
+        line-height: 1.5;
+
+        .question-text {
+          color: #303133;
+          margin-bottom: 5px;
+          font-weight: 500;
+        }
+
+        .answer-text {
+          color: #f56c6c;
+          margin-bottom: 5px;
+        }
+
+        .matched-text {
+          color: #e6a23c;
+          font-style: italic;
+        }
+
+        strong {
+          color: #606266;
+          font-weight: 600;
+        }
       }
 
       .patient-info {
-        .patient-item {
+        .patient-row {
           display: flex;
           justify-content: space-between;
           align-items: center;
-          margin-bottom: 5px;
-          padding: 2px 0;
+          margin-bottom: 8px;
 
-          .label {
-            font-size: 12px;
-            color: #606266;
-            min-width: 40px;
+          &:last-child {
+            margin-bottom: 0;
           }
 
-          .value {
-            font-size: 13px;
-            color: #333;
-            font-weight: 500;
-            text-align: right;
+          .patient-item {
             flex: 1;
+            display: flex;
+            justify-content: space-between;
+            align-items: center;
+            padding: 0 5px;
+
+            &.full-width {
+              flex: 1 0 100%;
+              margin-left: 0;
+              margin-right: 0;
+            }
+
+            .label {
+              font-size: 12px;
+              color: #606266;
+              margin-right: 5px;
+              white-space: nowrap;
+            }
+
+            .value {
+              font-size: 12px;
+              color: #333;
+              font-weight: 500;
+              text-align: right;
+              word-break: break-all;
+            }
           }
         }
       }
 
-      .discharge-info {
+      .fill-info,
+      .handle-info {
+        font-size: 12px;
+
         .info-item {
           display: flex;
           justify-content: space-between;
@@ -866,25 +1181,29 @@
           padding: 2px 0;
 
           .label {
-            font-size: 12px;
             color: #606266;
             min-width: 50px;
           }
 
           .value {
-            font-size: 13px;
             color: #333;
             font-weight: 500;
             text-align: right;
             flex: 1;
 
             &.time {
-              font-size: 12px;
               color: #909399;
+              font-size: 11px;
             }
           }
         }
       }
+
+      .no-data {
+        color: #909399;
+        font-style: italic;
+        font-size: 12px;
+      }
     }
 
     .pagination-section {
diff --git a/src/views/Satisfaction/configurationmyd/components/DetailsAnomaly.vue b/src/views/Satisfaction/configurationmyd/components/DetailsAnomaly.vue
index 57b4dff..d25ddf7 100644
--- a/src/views/Satisfaction/configurationmyd/components/DetailsAnomaly.vue
+++ b/src/views/Satisfaction/configurationmyd/components/DetailsAnomaly.vue
@@ -13,147 +13,286 @@
       <el-row :gutter="20">
         <el-col :span="8">
           <div class="info-item">
-            <span class="label">鎮h�呭鍚嶏細</span>
-            <span class="value">{{ currentRecord.patientName }}</span>
+            <span class="label">闂鍐呭锛�</span>
+            <span class="value">{{ currentRecord.questiontext || '鏃�' }}</span>
           </div>
         </el-col>
         <el-col :span="8">
           <div class="info-item">
-            <span class="label">鎬у埆锛�</span>
-            <span class="value">{{ currentRecord.gender === 1 ? '鐢�' : '濂�' }}</span>
+            <span class="label">鍥炵瓟鍐呭锛�</span>
+            <span class="value">{{ currentRecord.asrtext || '鏃犲洖绛�' }}</span>
           </div>
         </el-col>
         <el-col :span="8">
           <div class="info-item">
-            <span class="label">骞撮緞锛�</span>
-            <span class="value">{{ currentRecord.age }}宀�</span>
-          </div>
-        </el-col>
-        <el-col :span="8">
-          <div class="info-item">
-            <span class="label">鑱旂郴鏂瑰紡锛�</span>
-            <span class="value">{{ currentRecord.phone }}</span>
-          </div>
-        </el-col>
-        <el-col :span="8">
-          <div class="info-item">
-            <span class="label">鍑洪櫌绉戝锛�</span>
-            <span class="value">{{ currentRecord.dischargeDept }}</span>
-          </div>
-        </el-col>
-        <el-col :span="8">
-          <div class="info-item">
-            <span class="label">鍑洪櫌鐥呭尯锛�</span>
-            <span class="value">{{ currentRecord.dischargeWard }}</span>
-          </div>
-        </el-col>
-        <el-col :span="8">
-          <div class="info-item">
-            <span class="label">濉啓鏃堕棿锛�</span>
-            <span class="value">{{ currentRecord.fillTime }}</span>
+            <span class="label">瑙f瀽鍊硷細</span>
+            <span class="value">{{ currentRecord.matchedtext || '鏃�' }}</span>
           </div>
         </el-col>
         <el-col :span="8">
           <div class="info-item">
             <span class="label">璐熻矗绉戝锛�</span>
-            <el-tag type="primary">{{ currentRecord.responsibilityDept }}</el-tag>
+            <el-tag v-if="currentRecord.todeptname" type="primary">{{ currentRecord.todeptname }}</el-tag>
+            <span v-else class="value">鏈垎閰�</span>
           </div>
         </el-col>
         <el-col :span="8">
           <div class="info-item">
             <span class="label">澶勭悊鐘舵�侊細</span>
             <el-tag
-              :type="getStatusTagType(currentRecord.processStatus)"
+              :type="getStatusTagType(currentRecord.handleFlag)"
               effect="dark"
             >
-              {{ getStatusText(currentRecord.processStatus) }}
+              {{ getStatusText(currentRecord.handleFlag) }}
             </el-tag>
+          </div>
+        </el-col>
+        <el-col :span="8">
+          <div class="info-item">
+            <span class="label">妯℃澘绫诲瀷锛�</span>
+            <el-tag :type="currentRecord.templateType === 1 ? 'primary' : 'success'">
+              {{ currentRecord.templateType === 1 ? '璇煶妯℃澘' : '闂嵎妯℃澘' }}
+            </el-tag>
+          </div>
+        </el-col>
+        <el-col :span="8">
+          <div class="info-item">
+            <span class="label">鍒涘缓鏃堕棿锛�</span>
+            <span class="value">{{ formatDateTime(currentRecord.createTime) }}</span>
+          </div>
+        </el-col>
+        <el-col :span="8">
+          <div class="info-item">
+            <span class="label">澶勭悊鏃堕棿锛�</span>
+            <span class="value">{{ currentRecord.handleTime ? formatDateTime(currentRecord.handleTime) : '鏈鐞�' }}</span>
+          </div>
+        </el-col>
+        <el-col :span="8">
+          <div class="info-item">
+            <span class="label">澶勭悊浜猴細</span>
+            <span class="value">{{ currentRecord.handleBy || '鏈鐞�' }}</span>
+          </div>
+        </el-col>
+        <el-col :span="24" v-if="currentRecord.patdesc">
+          <div class="info-item">
+            <span class="label">鎮h�呬俊鎭細</span>
+            <span class="value">{{ currentRecord.patdesc }}</span>
+          </div>
+        </el-col>
+        <el-col :span="8" v-if="currentRecord.handleresult">
+          <div class="info-item">
+            <span class="label">澶勭悊缁撴灉锛�</span>
+            <span class="value">{{ getHandleresultText(currentRecord.handleresult) }}</span>
+          </div>
+        </el-col>
+        <el-col :span="16" v-if="currentRecord.handledesc">
+          <div class="info-item">
+            <span class="label">澶勭悊璇存槑锛�</span>
+            <span class="value">{{ currentRecord.handledesc }}</span>
+          </div>
+        </el-col>
+        <el-col :span="24" v-if="currentRecord.finaloption">
+          <div class="info-item">
+            <span class="label">鏈�缁堟剰瑙侊細</span>
+            <span class="value">{{ currentRecord.finaloption }}</span>
+          </div>
+        </el-col>
+        <el-col :span="8" v-if="currentRecord.recordurl">
+          <div class="info-item">
+            <span class="label">褰曢煶鍦板潃锛�</span>
+            <el-button
+              type="text"
+              size="small"
+              icon="el-icon-headset"
+              @click="handlePlayAudio(currentRecord.recordurl)"
+            >
+              鎾斁褰曢煶
+            </el-button>
+          </div>
+        </el-col>
+        <el-col :span="8" v-if="currentRecord.ccdepts">
+          <div class="info-item">
+            <span class="label">鎶勯�佺瀹わ細</span>
+            <span class="value">{{ currentRecord.ccdepts }}</span>
           </div>
         </el-col>
       </el-row>
     </div>
 
-    <!-- 闂嵎璇︽儏 -->
-    <div class="questionnaire-section">
-      <div class="section-title">闂嵎濉啓璇︽儏</div>
-      <div class="questionnaire-content">
-        <div class="question-item" v-for="(question, index) in questionnaireData" :key="index">
-          <div class="question-header">
-            <span class="question-index">{{ index + 1 }}.</span>
-            <span class="question-text">{{ question.question }}</span>
-            <el-tag
-              size="mini"
-              :type="question.type === 1 ? 'primary' : 'success'"
-              class="question-type"
-            >
-              {{ question.type === 1 ? '鍗曢�夐' : '澶氶�夐' }}
-            </el-tag>
-          </div>
-          <div class="question-options">
-            <el-radio-group
-              v-model="question.answer"
-              v-if="question.type === 1"
-              disabled
-            >
-              <el-radio
-                v-for="option in question.options"
-                :key="option.value"
-                :label="option.value"
-                :class="{ 'unsatisfactory-option': isUnsatisfactoryOption(option.value) }"
+    <!-- 闂嵎/璇煶璇︽儏 -->
+    <div class="content-container" v-if="templateData.length > 0">
+      <el-tabs v-model="activeName" type="border-card">
+        <!-- 闂嵎闅忚璇︽儏 -->
+        <el-tab-pane name="wj" v-if="currentRecord.templateType === 2">
+          <span slot="label"><i class="el-icon-notebook-1"></i> 闂嵎闅忚璇︽儏</span>
+          <div class="CONTENT">
+            <div class="title">{{ currentRecord.questiontext || '闂嵎璇︽儏' }}</div>
+            <div class="preview-left" v-if="!isVoiceTemplate">
+              <div
+                class="topic-dev"
+                v-for="(item, index) in templateData"
+                :key="item.id"
               >
-                {{ option.text }}
-              </el-radio>
-            </el-radio-group>
-            <el-checkbox-group
-              v-model="question.answer"
-              v-else
-              disabled
-            >
-              <el-checkbox
-                v-for="option in question.options"
-                :key="option.value"
-                :label="option.value"
-                :class="{ 'unsatisfactory-option': isUnsatisfactoryOption(option.value) }"
-              >
-                {{ option.text }}
-              </el-checkbox>
-            </el-checkbox-group>
+                <!-- 鍗曢�� -->
+                <div
+                  :class="getTopicClass(item)"
+                  :key="index"
+                  v-if="item.scriptType == 1 && !item.astrict"
+                >
+                  <div class="dev-text">
+                    {{ index + 1 }}銆乕鍗曢�塢<span>{{ item.scriptContent }}</span>
+                  </div>
+                  <div class="dev-xx">
+                    <el-radio-group v-model="item.scriptResult" disabled>
+                      <el-radio
+                        v-for="(option, optionIndex) in item.svyTaskTemplateTargetoptions"
+                        :class="getOptionClass(option)"
+                        :key="optionIndex"
+                        :label="option.optioncontent"
+                      >{{ option.optioncontent }}</el-radio>
+                    </el-radio-group>
+                  </div>
+                  <div
+                    v-if="item.showAppendInput || item.answerps"
+                    class="append-input-container"
+                  >
+                    <el-input
+                      type="textarea"
+                      :rows="2"
+                      placeholder="璇疯緭鍏ュ叿浣撲俊鎭�"
+                      v-model="item.answerps"
+                      readonly
+                    ></el-input>
+                  </div>
+                  <div v-show="item.prompt">
+                    <el-alert :title="item.prompt" type="warning"></el-alert>
+                  </div>
+                </div>
+                <!-- 澶氶�� -->
+                <div
+                  :class="item.isabnormal ? 'scriptTopic-isabnormal' : 'scriptTopic-dev'"
+                  :key="index"
+                  v-if="item.scriptType == 2 && !item.astrict"
+                >
+                  <div class="dev-text">
+                    {{ index + 1 }}銆乕澶氶�塢<span>{{ item.scriptContent }}</span>
+                  </div>
+                  <div class="dev-xx">
+                    <el-checkbox-group v-model="item.scriptResult" disabled>
+                      <el-checkbox
+                        :class="option.isabnormal ? 'red-star' : ''"
+                        v-for="(option, optionIndex) in item.svyTaskTemplateTargetoptions"
+                        :key="optionIndex"
+                        :label="option.optioncontent"
+                      >
+                        {{ option.optioncontent }}
+                      </el-checkbox>
+                    </el-checkbox-group>
+                  </div>
+                  <div v-show="item.prompt && item.scriptResult[0]">
+                    <el-alert :title="item.prompt" type="warning"></el-alert>
+                  </div>
+                </div>
+                <!-- 濉┖ -->
+                <div
+                  class="scriptTopic-dev"
+                  :key="index"
+                  v-if="item.scriptType == 4 && !item.astrict"
+                >
+                  <div class="dev-text">
+                    {{ index + 1 }}銆乕闂瓟]<span>{{ item.scriptContent }}</span>
+                    <span v-if="item.valueType == 3">(鍙兘杈撳叆鏁板瓧)</span>
+                  </div>
+                  <div class="dev-xx" v-if="item.valueType == 3">
+                    <el-input
+                      type="text"
+                      placeholder="璇疯緭鍏ョ瓟妗�"
+                      v-model="item.scriptResult"
+                      readonly
+                    ></el-input>
+                  </div>
+                  <div class="dev-xx" v-else>
+                    <el-input
+                      type="textarea"
+                      :rows="2"
+                      placeholder="璇疯緭鍏ョ瓟妗�"
+                      v-model="item.scriptResult"
+                      readonly
+                    ></el-input>
+                  </div>
+                </div>
+              </div>
+            </div>
           </div>
-          <div v-if="question.additional" class="additional-remark">
-            <div class="remark-label">琛ュ厖璇存槑锛�</div>
-            <div class="remark-content">{{ question.additional }}</div>
+        </el-tab-pane>
+
+        <!-- 璇煶闅忚璇︽儏 -->
+        <el-tab-pane name="yy" v-if="currentRecord.templateType === 1">
+          <span slot="label"><i class="el-icon-headset"></i> 璇煶闅忚璇︽儏</span>
+          <div class="borderdiv">
+            <div class="title">{{ taskName }}</div>
+            <div class="voice-audio" v-if="voiceAudioUrl">
+              瀹屾暣璇煶锛�
+              <audio-player
+                :audio-source="voiceAudioUrl"
+              ></audio-player>
+            </div>
+            <div class="preview-left" v-if="voiceData.length > 0">
+              <div v-for="(item, index) in voiceData" :key="index">
+                <div class="leftside">
+                  <i class="el-icon-phone-outline"></i>
+                  <span>{{ item.questiontext || '闂鍐呭' }}</span>
+                </div>
+                <div class="offside">
+                  <i class="el-icon-user"></i>
+                  <div class="offside-value">
+                    <el-input
+                      type="textarea"
+                      :autosize="{ minRows: 1 }"
+                      v-model="item.asrtext"
+                      readonly
+                    ></el-input>
+                    <div v-if="item.questionvoice">
+                      <audio-player
+                        :audio-source="item.questionvoice"
+                      ></audio-player>
+                    </div>
+                  </div>
+                </div>
+              </div>
+            </div>
           </div>
-        </div>
-      </div>
+        </el-tab-pane>
+      </el-tabs>
     </div>
 
     <!-- 澶勭悊璁板綍 -->
-    <div class="process-section">
+    <div class="process-section" v-if="processRecords.length > 0">
       <div class="section-title">澶勭悊璁板綍</div>
-      <div class="process-timeline" v-if="processRecords.length > 0">
+      <div class="process-timeline">
         <el-timeline>
           <el-timeline-item
             v-for="(record, index) in processRecords"
             :key="index"
-            :timestamp="record.time"
+            :timestamp="formatDateTime(record.handleTime || record.createTime)"
             placement="top"
           >
             <el-card>
               <div class="process-item">
                 <div class="process-header">
-                  <span class="process-user">{{ record.user }}</span>
+                  <span class="process-user">{{ record.handleBy || '绯荤粺' }}</span>
                   <el-tag
                     size="small"
-                    :type="getStatusTagType(record.status)"
+                    :type="getStatusTagType(record.handleFlag)"
                   >
-                    {{ getStatusText(record.status) }}
+                    {{ getStatusText(record.handleFlag) }}
                   </el-tag>
                 </div>
                 <div class="process-content">
-                  <div v-if="record.reportDepts && record.reportDepts.length > 0" class="process-depts">
-                    <span class="label">鎶ュ绉戝锛�</span>
+                  <div v-if="record.ccdepts" class="process-depts">
+                    <span class="label">鎶勯�佺瀹わ細</span>
                     <el-tag
-                      v-for="dept in record.reportDepts"
+                      v-for="dept in getDeptArray(record.ccdepts)"
                       :key="dept"
                       size="small"
                       type="info"
@@ -162,31 +301,23 @@
                       {{ dept }}
                     </el-tag>
                   </div>
-                  <div v-if="record.remark" class="process-remark">
-                    <span class="label">澶勭悊澶囨敞锛�</span>
-                    <span class="content">{{ record.remark }}</span>
+                  <div v-if="record.handleresult" class="process-remark">
+                    <span class="label">澶勭悊缁撴灉锛�</span>
+                    <span class="content">{{ getHandleresultText(record.handleresult) }}</span>
                   </div>
-                  <div v-if="record.attachments && record.attachments.length > 0" class="process-attachments">
-                    <span class="label">闄勪欢锛�</span>
-                    <el-button
-                      v-for="file in record.attachments"
-                      :key="file.id"
-                      type="text"
-                      size="small"
-                      icon="el-icon-document"
-                      @click="handlePreviewFile(file)"
-                    >
-                      {{ file.name }}
-                    </el-button>
+                  <div v-if="record.handledesc" class="process-remark">
+                    <span class="label">澶勭悊璇存槑锛�</span>
+                    <span class="content">{{ record.handledesc }}</span>
+                  </div>
+                  <div v-if="record.finaloption" class="process-remark">
+                    <span class="label">鏈�缁堟剰瑙侊細</span>
+                    <span class="content">{{ record.finaloption }}</span>
                   </div>
                 </div>
               </div>
             </el-card>
           </el-timeline-item>
         </el-timeline>
-      </div>
-      <div v-else class="no-record">
-        鏆傛棤澶勭悊璁板綍
       </div>
     </div>
 
@@ -195,7 +326,7 @@
         type="primary"
         icon="el-icon-edit"
         @click="handleProcess"
-        v-if="currentRecord.processStatus !== 2"
+        v-if="currentRecord.handleFlag !== '1'"
       >
         澶勭悊寮傚父
       </el-button>
@@ -217,61 +348,72 @@
         label-width="100px"
         size="medium"
       >
-        <el-form-item label="澶勭悊鐘舵��" prop="status">
+        <el-form-item label="澶勭悊鐘舵��" prop="handleFlag">
           <el-select
-            v-model="processForm.status"
+            v-model="processForm.handleFlag"
             placeholder="璇烽�夋嫨澶勭悊鐘舵��"
             style="width: 100%"
           >
-            <el-option label="澶勭悊涓�" :value="1" />
-            <el-option label="宸插鐞�" :value="2" />
-            <el-option label="宸查┏鍥�" :value="3" />
+            <el-option label="宸插鐞�" :value="'1'" />
+            <el-option label="鍙栨秷澶勭悊" :value="'0'" />
           </el-select>
         </el-form-item>
 
-        <el-form-item label="鎶ュ绉戝" prop="reportDepts">
+        <el-form-item label="鎶勯�佺瀹�" prop="ccdepts">
           <el-select
-            v-model="processForm.reportDepts"
-            placeholder="璇烽�夋嫨鎶ュ绉戝"
+            v-model="processForm.ccdepts"
+            placeholder="璇烽�夋嫨鎶勯�佺瀹�"
             multiple
             filterable
             collapse-tags
             style="width: 100%"
+            :disabled="processForm.handleFlag !== '1'"
           >
             <el-option
               v-for="dept in deptList"
-              :key="dept.id"
-              :label="dept.name"
-              :value="dept.id"
+              :key="dept.deptCode"
+              :label="dept.label"
+              :value="dept.deptCode"
             />
           </el-select>
         </el-form-item>
 
-        <el-form-item label="澶勭悊澶囨敞" prop="remark">
+        <el-form-item label="澶勭悊缁撴灉" prop="handleresult">
+          <el-select
+            v-model="processForm.handleresult"
+            placeholder="璇烽�夋嫨澶勭悊缁撴灉"
+            style="width: 100%"
+            :disabled="processForm.handleFlag !== '1'"
+          >
+            <el-option label="宸茶В鍐�" value="resolved" />
+            <el-option label="宸茶В閲�" value="explained" />
+            <el-option label="宸茶浆浜�" value="transferred" />
+            <el-option label="闇�鏀硅繘" value="improvement" />
+            <el-option label="宸查┏鍥�" value="rejected" />
+          </el-select>
+        </el-form-item>
+
+        <el-form-item label="澶勭悊璇存槑" prop="handledesc">
           <el-input
-            v-model="processForm.remark"
+            v-model="processForm.handledesc"
             type="textarea"
             :rows="4"
-            placeholder="璇疯緭鍏ュ鐞嗗娉紙鏈�澶�500瀛楋級"
+            placeholder="璇疯緭鍏ュ鐞嗚鏄庯紙鏈�澶�500瀛楋級"
             maxlength="500"
             show-word-limit
+            :disabled="processForm.handleFlag !== '1'"
           />
         </el-form-item>
 
-        <el-form-item label="闄勪欢涓婁紶">
-          <el-upload
-            class="upload-demo"
-            action="#"
-            :on-preview="handleFilePreview"
-            :on-remove="handleFileRemove"
-            :before-remove="beforeFileRemove"
-            :limit="3"
-            :on-exceed="handleFileExceed"
-            :file-list="fileList"
-          >
-            <el-button size="small" type="primary">鐐瑰嚮涓婁紶</el-button>
-            <div slot="tip" class="el-upload__tip">鏀寔涓婁紶鍥剧墖銆佹枃妗g瓑闄勪欢锛屽崟涓枃浠朵笉瓒呰繃10MB</div>
-          </el-upload>
+        <el-form-item label="鏈�缁堟剰瑙�" prop="finaloption" v-if="hasQualityPermission">
+          <el-input
+            v-model="processForm.finaloption"
+            type="textarea"
+            :rows="3"
+            placeholder="璇疯緭鍏ユ渶缁堝鐞嗘剰瑙侊紙鏈�澶�300瀛楋級"
+            maxlength="300"
+            show-word-limit
+          />
         </el-form-item>
       </el-form>
       <span slot="footer" class="dialog-footer">
@@ -285,24 +427,42 @@
         </el-button>
       </span>
     </el-dialog>
+
+    <!-- 褰曢煶鎾斁鍣� -->
+    <audio
+      v-if="audioUrl"
+      :src="audioUrl"
+      ref="audioPlayer"
+      controls
+      style="display: none"
+    />
   </el-dialog>
 </template>
 
 <script>
+import { traceedit } from "@/api/AiCentre/index";
+import { getsearchrResults, getPersonVoices, getTaskservelist } from "@/api/AiCentre/index";
+import { deptTreeSelect } from "@/api/system/user";
+import AudioPlayer from "@/components/AudioPlayer"; // 闇�瑕佸垱寤鸿繖涓煶棰戞挱鏀剧粍浠�
+
 export default {
   name: 'ExceptionDetailDialog',
+  components: {
+    AudioPlayer
+  },
   props: {
-    // 鏄惁鏄剧ず瀵硅瘽妗�
     visible: {
       type: Boolean,
       default: false
     },
-    // 璁板綍ID
     recordId: {
       type: [Number, String],
       default: null
     },
-    // 瀵硅瘽妗嗘爣棰�
+    recordData: {
+      type: Object,
+      default: () => ({})
+    },
     title: {
       type: String,
       default: '寮傚父鍙嶉璇︽儏'
@@ -313,45 +473,71 @@
       // 褰撳墠璁板綍
       currentRecord: {},
 
-      // 闂嵎鏁版嵁
-      questionnaireData: [],
+      // 闂嵎/璇煶鏁版嵁
+      activeName: 'wj',
+      taskName: '',
+      templateData: [],
+      voiceData: [],
+      voiceAudioUrl: '',
 
       // 澶勭悊璁板綍
       processRecords: [],
 
       // 绉戝鍒楄〃
-      deptList: [
-        { id: 1, name: '蹇冭绠″唴绉�' },
-        { id: 2, name: '绁炵粡鍐呯' },
-        { id: 3, name: '鏅绉�' },
-        { id: 4, name: '楠ㄧ' },
-        { id: 5, name: '濡囦骇绉�' },
-        { id: 6, name: '鍎跨' },
-        { id: 7, name: '鎬ヨ瘖绉�' },
-        { id: 8, name: '鍛煎惛鍐呯' }
-      ],
+      deptList: [],
 
       // 澶勭悊瀵硅瘽妗�
       processDialogVisible: false,
       processing: false,
       processForm: {
-        status: '',
-        reportDepts: [],
-        remark: ''
+        handleFlag: '',
+        ccdepts: [],
+        handleresult: '',
+        handledesc: '',
+        finaloption: ''
       },
       processRules: {
-        status: [
+        handleFlag: [
           { required: true, message: '璇烽�夋嫨澶勭悊鐘舵��', trigger: 'change' }
         ],
-        remark: [
-          { required: true, message: '璇疯緭鍏ュ鐞嗗娉�', trigger: 'blur' },
-          { min: 5, max: 500, message: '澶囨敞闀垮害鍦� 5 鍒� 500 涓瓧绗�', trigger: 'blur' }
+        handleresult: [
+          {
+            required: true,
+            message: '璇烽�夋嫨澶勭悊缁撴灉',
+            trigger: 'change',
+            validator: (rule, value, callback) => {
+              if (this.processForm.handleFlag === '1' && !value) {
+                callback(new Error('璇烽�夋嫨澶勭悊缁撴灉'));
+              } else {
+                callback();
+              }
+            }
+          }
+        ],
+        handledesc: [
+          {
+            required: true,
+            message: '璇疯緭鍏ュ鐞嗚鏄�',
+            trigger: 'blur',
+            validator: (rule, value, callback) => {
+              if (this.processForm.handleFlag === '1' && (!value || value.trim().length < 3)) {
+                callback(new Error('澶勭悊璇存槑鑷冲皯3涓瓧绗�'));
+              } else {
+                callback();
+              }
+            }
+          }
         ]
       },
-      fileList: [],
+
+      // 闊抽鎾斁
+      audioUrl: '',
 
       // 鍔犺浇鐘舵��
-      loading: false
+      loading: false,
+
+      // 鏉冮檺鎺у埗
+      hasQualityPermission: false
     };
   },
 
@@ -363,6 +549,10 @@
       set(val) {
         this.$emit('update:visible', val);
       }
+    },
+
+    isVoiceTemplate() {
+      return this.currentRecord.templateType === 1;
     }
   },
 
@@ -370,237 +560,293 @@
     visible: {
       immediate: true,
       handler(val) {
-        if (val && this.recordId) {
+        if (val) {
           this.loadData();
+        } else {
+          this.resetData();
+        }
+      }
+    },
+
+    recordData: {
+      immediate: true,
+      handler(val) {
+        if (val && Object.keys(val).length > 0) {
+          this.currentRecord = { ...val };
         }
       }
     }
   },
 
   methods: {
-    // 鍔犺浇鏁版嵁
-    async loadData() {
-      this.loading = true;
+    // 鏍煎紡鍖栨棩鏈熸椂闂�
+    formatDateTime(dateTime) {
+      if (!dateTime) return '';
       try {
-        await Promise.all([
-          this.loadRecordDetail(),
-          this.loadQuestionnaireData(),
-          this.loadProcessRecords()
-        ]);
-      } finally {
-        this.loading = false;
+        const date = new Date(dateTime);
+        if (isNaN(date.getTime())) {
+          return dateTime;
+        }
+        return date.toLocaleDateString().replace(/\//g, '-') + ' ' +
+               date.toTimeString().split(' ')[0];
+      } catch (error) {
+        console.error('鏃ユ湡鏍煎紡鍖栭敊璇�:', error);
+        return dateTime;
       }
     },
 
-    // 鍔犺浇璁板綍璇︽儏
-    async loadRecordDetail() {
-      return new Promise(resolve => {
-        setTimeout(() => {
-          // 鏍规嵁涓嶅悓鐨剅ecordId杩斿洖涓嶅悓鐨刴ock鏁版嵁
-          const mockRecords = {
-            1: {
-              id: 1,
-              patientName: '寮犲厛鐢�',
-              gender: 1,
-              age: 45,
-              phone: '13800138000',
-              dischargeDept: '蹇冭绠″唴绉�',
-              dischargeWard: '鍐呯涓�鐥呭尯',
-              fillTime: '2024-01-15 10:30:25',
-              responsibilityDept: '蹇冭绠″唴绉�',
-              processStatus: 0
-            },
-            2: {
-              id: 2,
-              patientName: '鏉庡コ澹�',
-              gender: 0,
-              age: 38,
-              phone: '13900139000',
-              dischargeDept: '绁炵粡鍐呯',
-              dischargeWard: '鍐呯浜岀梾鍖�',
-              fillTime: '2024-01-14 16:20:10',
-              responsibilityDept: '绁炵粡鍐呯',
-              processStatus: 0
-            },
-            3: {
-              id: 3,
-              patientName: '鐜嬪厛鐢�',
-              gender: 1,
-              age: 52,
-              phone: '13700137000',
-              dischargeDept: '鏅绉�',
-              dischargeWard: '澶栫涓�鐥呭尯',
-              fillTime: '2024-01-13 09:15:45',
-              responsibilityDept: '鏅绉�',
-              processStatus: 1
-            }
-          };
-
-          this.currentRecord = mockRecords[this.recordId] || {
-            id: 1,
-            patientName: '寮犲厛鐢�',
-            gender: 1,
-            age: 45,
-            phone: '13800138000',
-            dischargeDept: '蹇冭绠″唴绉�',
-            dischargeWard: '鍐呯涓�鐥呭尯',
-            fillTime: '2024-01-15 10:30:25',
-            responsibilityDept: '蹇冭绠″唴绉�',
-            processStatus: 0
-          };
-          resolve();
-        }, 300);
-      });
+    // 妫�鏌ヨ川绠℃潈闄�
+    checkQualityPermission() {
+      const userRoles = this.$store.getters.roles || [];
+      return userRoles.includes('quality_manager') || userRoles.includes('admin');
     },
 
-    // 鍔犺浇闂嵎鏁版嵁
-    async loadQuestionnaireData() {
-      return new Promise(resolve => {
-        setTimeout(() => {
-          this.questionnaireData = [
-            {
-              question: '鎮ㄥ鍖绘姢浜哄憳鐨勬湇鍔℃�佸害鏄惁婊℃剰锛�',
-              type: 1,
-              options: [
-                { value: '闈炲父婊℃剰', text: '闈炲父婊℃剰' },
-                { value: '婊℃剰', text: '婊℃剰' },
-                { value: '涓�鑸�', text: '涓�鑸�' },
-                { value: '涓嶆弧鎰�', text: '涓嶆弧鎰�' },
-                { value: '闈炲父涓嶆弧鎰�', text: '闈炲父涓嶆弧鎰�' }
-              ],
-              answer: '涓嶆弧鎰�',
-              additional: '鍖荤敓鏌ユ埧鏃堕棿澶煭锛屾矡閫氫笉澶熷厖鍒嗭紝瀵圭梾鎯呰В閲婁笉澶熻缁�'
-            },
-            {
-              question: '鎮ㄥ鍖荤敓鐨勮瘖鐤楁按骞冲拰鎶�鏈兘鍔涜瘎浠峰浣曪紵',
-              type: 1,
-              options: [
-                { value: '闈炲父涓撲笟', text: '闈炲父涓撲笟' },
-                { value: '姣旇緝涓撲笟', text: '姣旇緝涓撲笟' },
-                { value: '涓�鑸�', text: '涓�鑸�' },
-                { value: '涓嶅涓撲笟', text: '涓嶅涓撲笟' },
-                { value: '闈炲父涓嶄笓涓�', text: '闈炲父涓嶄笓涓�' }
-              ],
-              answer: '姣旇緝涓撲笟',
-              additional: ''
-            },
-            {
-              question: '鎮ㄥ鍖婚櫌鐨勭幆澧冨拰鍗敓鐘跺喌鏄惁婊℃剰锛�',
-              type: 1,
-              options: [
-                { value: '闈炲父婊℃剰', text: '闈炲父婊℃剰' },
-                { value: '婊℃剰', text: '婊℃剰' },
-                { value: '涓�鑸�', text: '涓�鑸�' },
-                { value: '涓嶆弧鎰�', text: '涓嶆弧鎰�' },
-                { value: '闈炲父涓嶆弧鎰�', text: '闈炲父涓嶆弧鎰�' }
-              ],
-              answer: '涓�鑸�',
-              additional: ''
-            },
-            {
-              question: '鎮ㄨ涓哄尰鎶や汉鍛樹笌鎮ㄧ殑娌熼�氭槸鍚﹀厖鍒嗭紵',
-              type: 1,
-              options: [
-                { value: '闈炲父鍏呭垎', text: '闈炲父鍏呭垎' },
-                { value: '姣旇緝鍏呭垎', text: '姣旇緝鍏呭垎' },
-                { value: '涓�鑸�', text: '涓�鑸�' },
-                { value: '涓嶅鍏呭垎', text: '涓嶅鍏呭垎' },
-                { value: '闈炲父涓嶅厖鍒�', text: '闈炲父涓嶅厖鍒�' }
-              ],
-              answer: '涓嶅鍏呭垎',
-              additional: '鍖荤敓璁茶В鐥呮儏鏃惰閫熷お蹇紝娌℃湁缁欒冻澶熺殑鏃堕棿鎻愰棶'
-            },
-            {
-              question: '鎮ㄥ绛夊緟灏辫瘖鍜屾不鐤楃殑鏃堕棿鏄惁婊℃剰锛�',
-              type: 1,
-              options: [
-                { value: '闈炲父婊℃剰', text: '闈炲父婊℃剰' },
-                { value: '婊℃剰', text: '婊℃剰' },
-                { value: '涓�鑸�', text: '涓�鑸�' },
-                { value: '涓嶆弧鎰�', text: '涓嶆弧鎰�' },
-                { value: '闈炲父涓嶆弧鎰�', text: '闈炲父涓嶆弧鎰�' }
-              ],
-              answer: '涓嶆弧鎰�',
-              additional: '棰勭害鐨�9鐐癸紝瀹為檯10鐐规墠瑙佸埌鍖荤敓'
-            }
-          ];
-          resolve();
-        }, 300);
-      });
+    // 鑾峰彇绉戝鍒楄〃
+    async getDeptOptions() {
+      try {
+        const res = await deptTreeSelect();
+        if (res.code == 200) {
+          this.deptList = this.flattenArray(res.data) || [];
+        }
+      } catch (error) {
+        console.error('鑾峰彇绉戝鍒楄〃澶辫触:', error);
+      }
     },
 
-    // 鍔犺浇澶勭悊璁板綍
-    async loadProcessRecords() {
-      return new Promise(resolve => {
-        setTimeout(() => {
-          this.processRecords = [
-            {
-              id: 1,
-              time: '2024-01-15 14:20:30',
-              user: '寮犲尰鐢�',
-              status: 1, // 澶勭悊涓�
-              reportDepts: ['鍖诲姟绉�', '鎶ょ悊閮�'],
-              remark: '宸叉敹鍒板弽棣堬紝姝e湪瀹夋帓鐩稿叧浜哄憳鏍告煡鎯呭喌',
-              attachments: [
-                { id: 1, name: '鍒濇璋冩煡璁板綍.docx' },
-                { id: 2, name: '鎮h�呮矡閫氳褰�.jpg' }
-              ]
-            },
-            {
-              id: 2,
-              time: '2024-01-15 10:45:12',
-              user: '绯荤粺',
-              status: 0, // 寰呭鐞�
-              remark: '绯荤粺鑷姩璇嗗埆涓哄紓甯稿弽棣堬紝宸插垎閰嶅埌璐d换绉戝',
-              attachments: []
-            }
-          ];
-          resolve();
-        }, 300);
-      });
-    },
+    // 灞曞钩鏁扮粍
+    flattenArray(multiArray) {
+      let result = [];
 
-    // 鍒ゆ柇鏄惁涓轰笉婊℃剰閫夐」
-    isUnsatisfactoryOption(value) {
-      const unsatisfactoryValues = [
-        '涓嶆弧鎰�',
-        '闈炲父涓嶆弧鎰�',
-        '涓嶅涓撲笟',
-        '闈炲父涓嶄笓涓�',
-        '涓嶅鍏呭垎',
-        '闈炲父涓嶅厖鍒�'
-      ];
-      return unsatisfactoryValues.includes(value);
+      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;
     },
 
     // 鑾峰彇鐘舵�佹爣绛剧被鍨�
-    getStatusTagType(status) {
-      switch (status) {
-        case 0: return 'warning'; // 寰呭鐞�
-        case 1: return 'primary'; // 澶勭悊涓�
-        case 2: return 'success'; // 宸插鐞�
-        case 3: return 'danger';  // 宸查┏鍥�
+    getStatusTagType(handleFlag) {
+      switch (handleFlag) {
+        case '0': return 'warning'; // 鏈鐞�
+        case '1': return 'success'; // 宸插鐞�
         default: return 'info';
       }
     },
 
     // 鑾峰彇鐘舵�佹枃鏈�
-    getStatusText(status) {
-      switch (status) {
-        case 0: return '寰呭鐞�';
-        case 1: return '澶勭悊涓�';
-        case 2: return '宸插鐞�';
-        case 3: return '宸查┏鍥�';
+    getStatusText(handleFlag) {
+      switch (handleFlag) {
+        case '0': return '鏈鐞�';
+        case '1': return '宸插鐞�';
         default: return '鏈煡';
+      }
+    },
+
+    // 鑾峰彇澶勭悊缁撴灉鏂囨湰
+    getHandleresultText(handleresult) {
+      const map = {
+        'resolved': '宸茶В鍐�',
+        'explained': '宸茶В閲�',
+        'transferred': '宸茶浆浜�',
+        'improvement': '闇�鏀硅繘',
+        'rejected': '宸查┏鍥�'
+      };
+      return map[handleresult] || handleresult;
+    },
+
+    // 鑾峰彇绉戝鏁扮粍
+    getDeptArray(ccdepts) {
+      if (!ccdepts) return [];
+      return ccdepts.split(',');
+    },
+
+    // 鎾斁闊抽
+    handlePlayAudio(url) {
+      this.audioUrl = url;
+      this.$nextTick(() => {
+        const audioPlayer = this.$refs.audioPlayer;
+        if (audioPlayer) {
+          audioPlayer.play().catch(error => {
+            console.error('鎾斁澶辫触:', error);
+            this.$message.error('闊抽鎾斁澶辫触');
+          });
+        }
+      });
+    },
+
+    // 鑾峰彇涓婚鏍峰紡绫�
+    getTopicClass(item) {
+      if (item.isabnormal == 1) {
+        return "scriptTopic-isabnormal";
+      } else if (item.isabnormal == 2) {
+        return "scriptTopic-warning";
+      } else {
+        return "scriptTopic-dev";
+      }
+    },
+
+    // 鑾峰彇閫夐」鏍峰紡绫�
+    getOptionClass(items) {
+      if (items.isabnormal == 1) {
+        return "red-star";
+      } else if (items.isabnormal == 2) {
+        return "yellow-star";
+      }
+      return "";
+    },
+
+    // 鍔犺浇鏁版嵁
+    async loadData() {
+      this.loading = true;
+      try {
+        this.hasQualityPermission = this.checkQualityPermission();
+        await this.getDeptOptions();
+
+        if (Object.keys(this.currentRecord).length === 0) {
+          this.currentRecord = this.recordData || {};
+        }
+
+        // 濡傛灉褰撳墠璁板綍鏄闊虫ā鏉匡紝鍔犺浇璇煶鏁版嵁
+        if (this.currentRecord.templateType === 1) {
+          await this.loadVoiceData();
+          this.activeName = 'yy';
+        } else if (this.currentRecord.templateType === 2) {
+          await this.loadQuestionnaireData();
+          this.activeName = 'wj';
+        }
+
+        await this.loadProcessRecords();
+      } catch (error) {
+        console.error('鍔犺浇璇︽儏鏁版嵁澶辫触:', error);
+        this.$message.error('鍔犺浇鏁版嵁澶辫触');
+      } finally {
+        this.loading = false;
+      }
+    },
+
+    // 閲嶇疆鏁版嵁
+    resetData() {
+      this.currentRecord = {};
+      this.templateData = [];
+      this.voiceData = [];
+      this.processRecords = [];
+      this.voiceAudioUrl = '';
+      this.taskName = '';
+      this.activeName = 'wj';
+    },
+
+    // 鍔犺浇闂嵎鏁版嵁
+    async loadQuestionnaireData() {
+      try {
+        // 杩欓噷闇�瑕佹牴鎹疄闄呮儏鍐佃皟鐢ㄦ帴鍙h幏鍙栭棶鍗锋暟鎹�
+        // 濡傛灉recordData涓凡缁忓寘鍚簡闂嵎鏁版嵁锛屽彲浠ョ洿鎺ヤ娇鐢�
+        if (this.currentRecord.taskid && this.currentRecord.patid) {
+          const params = {
+            taskid: this.currentRecord.taskid,
+            patid: this.currentRecord.patid,
+            subId: this.currentRecord.subId || this.currentRecord.id,
+            isFinish: true
+          };
+
+          const res = await getsearchrResults(params);
+          if (res.code === 200 && res.data) {
+            this.templateData = res.data.scriptResult || [];
+            this.taskName = res.data.taskName || '';
+
+            // 澶勭悊鏁版嵁鏍煎紡
+            this.templateData.forEach((item) => {
+              if (item.scriptType == 2) item.scriptResult = [];
+              if (item.scriptResultId && item.scriptType != 2) {
+                item.isoption = 3;
+                item.scriptResult = item.scriptResult;
+              } else if (item.scriptResultId && item.scriptType == 2) {
+                item.scriptResult = item.scriptResult.split("&");
+                item.isoption = 3;
+              }
+            });
+
+            this.overdata();
+          }
+        }
+      } catch (error) {
+        console.error('鍔犺浇闂嵎鏁版嵁澶辫触:', error);
+      }
+    },
+
+    // 澶勭悊寮傚父鏁版嵁
+    overdata() {
+      this.templateData.forEach((item, index) => {
+        var obj = item.svyTaskTemplateTargetoptions.find(
+          (items) => items.optioncontent == item.scriptResult
+        );
+        if (obj && obj.isabnormal) {
+          this.templateData[index].isabnormal = obj.isabnormal;
+        }
+        this.$forceUpdate();
+      });
+    },
+
+    // 鍔犺浇璇煶鏁版嵁
+    async loadVoiceData() {
+      try {
+        if (this.currentRecord.taskid && this.currentRecord.patid) {
+          const params = {
+            taskid: this.currentRecord.taskid,
+            patid: this.currentRecord.patid,
+            subId: this.currentRecord.subId || this.currentRecord.id
+          };
+
+          const res = await getPersonVoices(params);
+          if (res.code == 200) {
+            this.voiceData = res.data.serviceSubtaskDetails || [];
+            this.voiceAudioUrl = res.data.voice || '';
+            this.taskName = res.data.taskName || '';
+            this.templateData = res.data.filteredDetails || [];
+
+            this.templateData.forEach((item) => {
+              if (item.targetvalue) {
+                item.scriptResult = item.targetvalue.split("&");
+              } else {
+                item.scriptResult = [];
+              }
+            });
+          }
+        }
+      } catch (error) {
+        console.error('鍔犺浇璇煶鏁版嵁澶辫触:', error);
+      }
+    },
+
+    // 鍔犺浇澶勭悊璁板綍
+    async loadProcessRecords() {
+      try {
+        // 杩欓噷鍙互鏍规嵁recordId鍔犺浇澶勭悊鍘嗗彶
+        // 鏆傛椂浣跨敤褰撳墠璁板綍鐨勫鐞嗕俊鎭�
+        if (this.currentRecord.handleTime) {
+          this.processRecords = [{
+            ...this.currentRecord,
+            time: this.currentRecord.handleTime
+          }];
+        }
+      } catch (error) {
+        console.error('鍔犺浇澶勭悊璁板綍澶辫触:', error);
       }
     },
 
     // 澶勭悊寮傚父
     handleProcess() {
       this.processForm = {
-        status: this.currentRecord.processStatus === 0 ? 1 : this.currentRecord.processStatus,
-        reportDepts: [],
-        remark: ''
+        handleFlag: this.currentRecord.handleFlag === '0' ? '1' : '0',
+        ccdepts: this.currentRecord.ccdepts ? this.currentRecord.ccdepts.split(',') : [],
+        handleresult: this.currentRecord.handleresult || '',
+        handledesc: this.currentRecord.handledesc || '',
+        finaloption: this.currentRecord.finaloption || ''
       };
       this.processDialogVisible = true;
     },
@@ -608,52 +854,56 @@
     // 鎻愪氦澶勭悊
     async submitProcess() {
       this.$refs.processForm.validate(async (valid) => {
-        if (valid) {
-          this.processing = true;
-          try {
-            // Mock API璋冪敤
-            await new Promise(resolve => setTimeout(resolve, 1000));
+        if (!valid) {
+          return;
+        }
 
-            this.$message.success('澶勭悊鎻愪氦鎴愬姛');
+        this.processing = true;
+        try {
+          const submitData = {
+            id: this.currentRecord.id,
+            handleFlag: this.processForm.handleFlag,
+            handleresult: this.processForm.handleresult,
+            handledesc: this.processForm.handledesc,
+            finaloption: this.processForm.finaloption,
+            ccdepts: Array.isArray(this.processForm.ccdepts)
+              ? this.processForm.ccdepts.join(",")
+              : this.processForm.ccdepts
+          };
+
+          const res = await traceedit(submitData);
+          if (res.code === 200) {
+            this.$message.success("澶勭悊鎻愪氦鎴愬姛");
             this.processDialogVisible = false;
 
-            // 閲嶆柊鍔犺浇鏁版嵁
-            await this.loadData();
+            // 鏇存柊褰撳墠璁板綍
+            this.currentRecord = {
+              ...this.currentRecord,
+              ...submitData,
+              handleBy: this.$store.getters.name, // 褰撳墠鐢ㄦ埛
+              handleTime: new Date().toISOString().replace('T', ' ').substr(0, 19)
+            };
+
+            // 閲嶆柊鍔犺浇澶勭悊璁板綍
+            await this.loadProcessRecords();
 
             // 瑙﹀彂鐖剁粍浠跺埛鏂�
             this.$emit('processed');
-          } finally {
-            this.processing = false;
+          } else {
+            this.$message.error(res.msg || "澶勭悊鎻愪氦澶辫触");
           }
+        } catch (error) {
+          console.error("澶勭悊鎻愪氦澶辫触:", error);
+          this.$message.error("澶勭悊鎻愪氦澶辫触锛岃绋嶅悗閲嶈瘯");
+        } finally {
+          this.processing = false;
         }
       });
-    },
-
-    // 棰勮鏂囦欢
-    handlePreviewFile(file) {
-      this.$message.info(`棰勮鏂囦欢: ${file.name}`);
     },
 
     // 澶勭悊瀵硅瘽妗嗗叧闂�
     handleClose() {
       this.$emit('close');
-    },
-
-    // 鏂囦欢涓婁紶鐩稿叧鏂规硶
-    handleFilePreview(file) {
-      console.log('棰勮鏂囦欢:', file);
-    },
-
-    handleFileRemove(file, fileList) {
-      console.log('绉婚櫎鏂囦欢:', file, fileList);
-    },
-
-    beforeFileRemove(file) {
-      return this.$confirm(`纭畾绉婚櫎 ${file.name}锛焋);
-    },
-
-    handleFileExceed(files, fileList) {
-      this.$message.warning(`褰撳墠闄愬埗閫夋嫨 3 涓枃浠讹紝鏈閫夋嫨浜� ${files.length} 涓枃浠讹紝鍏遍�夋嫨浜� ${files.length + fileList.length} 涓枃浠禶);
     }
   }
 };
@@ -705,116 +955,137 @@
         font-size: 14px;
         color: #303133;
         font-weight: 500;
+        flex: 1;
       }
     }
   }
 
-  .questionnaire-section {
+  .content-container {
     margin-bottom: 20px;
-    padding: 20px;
-    background: #fff;
-    border-radius: 8px;
-    border: 1px solid #ebeef5;
 
-    .section-title {
-      font-size: 16px;
-      font-weight: 600;
-      color: #303133;
-      margin-bottom: 15px;
-      padding-bottom: 10px;
-      border-bottom: 2px solid #409EFF;
+    ::v-deep .el-tabs__content {
+      padding: 20px;
+      background: #fff;
+      border-radius: 0 0 4px 4px;
     }
 
-    .questionnaire-content {
-      .question-item {
-        margin-bottom: 20px;
-        padding: 15px;
-        border-radius: 6px;
-        border: 1px solid #ebeef5;
-        transition: all 0.3s;
+    .CONTENT, .borderdiv {
+      padding: 20px;
+      background: #fff;
+      border-radius: 6px;
 
-        &:hover {
-          border-color: #409EFF;
-          box-shadow: 0 2px 12px 0 rgba(64, 158, 255, 0.1);
+      .title {
+        font-size: 18px;
+        font-weight: 600;
+        color: #303133;
+        margin-bottom: 20px;
+        padding-bottom: 10px;
+        border-bottom: 2px solid #409EFF;
+      }
+
+      .voice-audio {
+        margin-bottom: 20px;
+        display: flex;
+        align-items: center;
+        gap: 10px;
+
+        .audio-player {
+          flex: 1;
+        }
+      }
+
+      .preview-left {
+        .topic-dev {
+          margin-bottom: 20px;
+          padding: 15px;
+          border-radius: 6px;
+          border: 1px solid #ebeef5;
+          background: #fff;
+
+          .dev-text {
+            font-size: 15px;
+            font-weight: 500;
+            color: #303133;
+            margin-bottom: 15px;
+            line-height: 1.5;
+
+            span {
+              color: #606266;
+            }
+          }
+
+          .dev-xx {
+            ::v-deep .el-radio-group,
+            ::v-deep .el-checkbox-group {
+              display: flex;
+              flex-direction: column;
+              gap: 10px;
+            }
+
+            ::v-deep .el-radio,
+            ::v-deep .el-checkbox {
+              margin: 0;
+              padding: 8px 12px;
+              border-radius: 4px;
+              border: 1px solid #ebeef5;
+              transition: all 0.3s;
+
+              &:hover {
+                background: #f5f7fa;
+              }
+
+              &.red-star {
+                border-color: #f56c6c;
+                background: #fef0f0;
+              }
+
+              &.yellow-star {
+                border-color: #e6a23c;
+                background: #fdf6ec;
+              }
+            }
+          }
+
+          .append-input-container {
+            margin-top: 15px;
+          }
+
+          .el-alert {
+            margin-top: 10px;
+          }
         }
 
-        .question-header {
+        .leftside {
           display: flex;
           align-items: center;
-          margin-bottom: 15px;
-          padding-bottom: 10px;
-          border-bottom: 1px dashed #dcdfe6;
+          gap: 10px;
+          margin-bottom: 10px;
+          font-size: 15px;
+          font-weight: 500;
+          color: #303133;
 
-          .question-index {
-            font-weight: 600;
+          i {
             color: #409EFF;
-            margin-right: 8px;
-            font-size: 15px;
+          }
+        }
+
+        .offside {
+          display: flex;
+          align-items: flex-start;
+          gap: 10px;
+          margin-bottom: 20px;
+
+          i {
+            color: #67C23A;
+            margin-top: 8px;
           }
 
-          .question-text {
+          .offside-value {
             flex: 1;
-            font-size: 15px;
-            color: #303133;
-            font-weight: 500;
-            line-height: 1.5;
-          }
 
-          .question-type {
-            margin-left: 10px;
-          }
-        }
-
-        .question-options {
-          ::v-deep .el-radio-group {
-            display: flex;
-            flex-direction: column;
-            gap: 10px;
-          }
-
-          ::v-deep .el-checkbox-group {
-            display: flex;
-            flex-wrap: wrap;
-            gap: 15px;
-          }
-
-          ::v-deep .el-radio,
-          ::v-deep .el-checkbox {
-            margin: 0;
-            padding: 8px 12px;
-            border-radius: 4px;
-            border: 1px solid #ebeef5;
-            transition: all 0.3s;
-
-            &:hover {
-              background: #f5f7fa;
+            .el-textarea {
+              margin-bottom: 10px;
             }
-
-            &.unsatisfactory-option {
-              border-color: #e6a23c;
-              background: #fdf6ec;
-            }
-          }
-        }
-
-        .additional-remark {
-          margin-top: 15px;
-          padding: 12px;
-          background: #f0f9ff;
-          border-radius: 6px;
-          border-left: 4px solid #409EFF;
-
-          .remark-label {
-            font-size: 13px;
-            color: #606266;
-            font-weight: 500;
-            margin-bottom: 5px;
-          }
-
-          .remark-content {
-            font-size: 14px;
-            color: #303133;
-            line-height: 1.6;
           }
         }
       }
@@ -886,30 +1157,8 @@
               line-height: 1.5;
             }
           }
-
-          .process-attachments {
-            .label {
-              font-size: 13px;
-              color: #606266;
-              margin-right: 5px;
-            }
-
-            ::v-deep .el-button {
-              margin-right: 8px;
-              margin-bottom: 5px;
-            }
-          }
         }
       }
-    }
-
-    .no-record {
-      text-align: center;
-      padding: 40px 0;
-      color: #909399;
-      font-style: italic;
-      background: #f8f9fa;
-      border-radius: 6px;
     }
   }
 
@@ -920,4 +1169,15 @@
     gap: 10px;
   }
 }
+
+// 寮傚父鏍峰紡
+.scriptTopic-isabnormal {
+  border-color: #f56c6c !important;
+  background: #fef0f0 !important;
+}
+
+.scriptTopic-warning {
+  border-color: #e6a23c !important;
+  background: #fdf6ec !important;
+}
 </style>
diff --git a/src/views/Satisfaction/configurationmyd/dispose.vue b/src/views/Satisfaction/configurationmyd/dispose.vue
index 8a59106..8de73b1 100644
--- a/src/views/Satisfaction/configurationmyd/dispose.vue
+++ b/src/views/Satisfaction/configurationmyd/dispose.vue
@@ -19,9 +19,9 @@
           label-width="120px"
           class="search-form"
         >
-          <el-form-item label="婊℃剰搴︽ā鏉�" prop="templateId">
+          <el-form-item label="婊℃剰搴︾被鍨�" prop="templateid">
             <el-select
-              v-model="queryParams.templateId"
+              v-model="queryParams.templateid"
               placeholder="璇烽�夋嫨妯℃澘"
               clearable
               style="width: 200px"
@@ -35,9 +35,9 @@
             </el-select>
           </el-form-item>
 
-          <el-form-item label="璐d换绉戝" prop="deptIds">
+          <el-form-item label="璐d换绉戝" prop="todeptcode">
             <el-select
-              v-model="queryParams.deptIds"
+              v-model="queryParams.todeptcode"
               placeholder="璇烽�夋嫨璐d换绉戝"
               clearable
               filterable
@@ -47,21 +47,21 @@
             >
               <el-option
                 v-for="dept in deptList"
-                :key="dept.id"
-                :label="dept.name"
-                :value="dept.id"
+                :key="dept.deptCode"
+                :label="dept.deptName"
+                :value="dept.deptCode"
               />
             </el-select>
           </el-form-item>
 
-          <el-form-item label="缁熻鏃堕棿" prop="dateRange">
+          <el-form-item label="澶勭悊鏃堕棿" prop="handleTimeRange">
             <el-date-picker
-              v-model="queryParams.dateRange"
-              type="daterange"
+              v-model="queryParams.handleTimeRange"
+              type="datetimerange"
               range-separator="鑷�"
-              start-placeholder="寮�濮嬫棩鏈�"
-              end-placeholder="缁撴潫鏃ユ湡"
-              value-format="yyyy-MM-dd"
+              start-placeholder="寮�濮嬫椂闂�"
+              end-placeholder="缁撴潫鏃堕棿"
+              value-format="yyyy-MM-dd HH:mm:ss"
               :picker-options="pickerOptions"
               style="width: 380px"
             />
@@ -117,7 +117,7 @@
     <!-- 寮傚父缁熻姒傝 -->
     <div class="overview-section">
       <el-row :gutter="20">
-        <el-col :span="6">
+        <el-col :span="8">
           <el-card shadow="never" class="stat-card">
             <div class="stat-content">
               <div class="stat-icon" style="background: #f0f9ff;">
@@ -130,7 +130,7 @@
             </div>
           </el-card>
         </el-col>
-        <el-col :span="6">
+        <el-col :span="8">
           <el-card shadow="never" class="stat-card">
             <div class="stat-content">
               <div class="stat-icon" style="background: #f0f9ff;">
@@ -143,7 +143,7 @@
             </div>
           </el-card>
         </el-col>
-        <el-col :span="6">
+        <el-col :span="8">
           <el-card shadow="never" class="stat-card">
             <div class="stat-content">
               <div class="stat-icon" style="background: #f0f9ff;">
@@ -152,19 +152,6 @@
               <div class="stat-info">
                 <div class="stat-title">宸插鐞嗗紓甯�</div>
                 <div class="stat-value">{{ overviewData.processedCount }}</div>
-              </div>
-            </div>
-          </el-card>
-        </el-col>
-        <el-col :span="6">
-          <el-card shadow="never" class="stat-card">
-            <div class="stat-content">
-              <div class="stat-icon" style="background: #f0f9ff;">
-                <i class="el-icon-s-order" style="color: #909399;"></i>
-              </div>
-              <div class="stat-info">
-                <div class="stat-title">浠婃棩澶勭悊鏁�</div>
-                <div class="stat-value">{{ overviewData.todayProcessedCount }}</div>
               </div>
             </div>
           </el-card>
@@ -198,25 +185,19 @@
 
           <el-table-column
             label="棰樼洰鍐呭"
-            prop="questionContent"
+            prop="questiontext"
             min-width="300"
             align="center"
           >
             <template slot-scope="{ row }">
               <div class="question-content">
-                <span class="question-text">{{ row.questionContent }}</span>
+                <span class="question-text">{{ row.questiontext }}</span>
                 <div class="question-tags">
                   <el-tag
                     size="mini"
-                    :type="getQuestionTypeTag(row.questionType)"
+                    :type="getTemplateTypeTag(row.templateType)"
                   >
-                    {{ row.questionType === 1 ? '鍗曢�夐' : '澶氶�夐' }}
-                  </el-tag>
-                  <el-tag
-                    size="mini"
-                    type="info"
-                  >
-                    {{ row.templateName }}
+                    {{ row.templateType === 1 ? '璇煶妯℃澘' : '闂嵎妯℃澘' }}
                   </el-tag>
                 </div>
               </div>
@@ -225,20 +206,20 @@
 
           <el-table-column
             label="璐熻矗绉戝"
-            prop="responsibilityDepts"
+            prop="responsibleDept"
             width="180"
             align="center"
           >
             <template slot-scope="{ row }">
               <div class="dept-list">
                 <el-tag
-                  v-for="dept in row.responsibilityDepts"
-                  :key="dept.id"
+                  v-for="dept in row.responsibleDept"
+                  :key="dept.deptCode"
                   size="small"
                   type="primary"
                   class="dept-tag"
                 >
-                  {{ dept.name }}
+                  {{ dept.deptName }}
                 </el-tag>
               </div>
             </template>
@@ -253,11 +234,11 @@
               <div class="fill-statistics">
                 <div class="stat-item">
                   <span class="stat-label">鏈夋晥濉啓锛�</span>
-                  <span class="stat-value">{{ row.validFillCount }}</span>
+                  <span class="stat-value">{{ row.fillSituation.effectiveFillNum }}</span>
                 </div>
                 <div class="stat-item">
                   <span class="stat-label">寮傚父濉啓锛�</span>
-                  <span class="stat-value exception-count">{{ row.exceptionFillCount }}</span>
+                  <span class="stat-value exception-count">{{ row.fillSituation.exceptionFillNum }}</span>
                 </div>
               </div>
             </template>
@@ -272,15 +253,15 @@
               <div class="exception-tasks">
                 <div class="task-category">
                   <div class="task-title">宸插鐞�</div>
-                  <div class="task-count processed">{{ row.processedCount }}</div>
+                  <div class="task-count processed">{{ row.exceptionQuesNum.yesDeal }}</div>
                 </div>
                 <div class="task-category">
                   <div class="task-title">寰呭鐞�</div>
-                  <div class="task-count pending">{{ row.pendingCount }}</div>
+                  <div class="task-count pending">{{ row.exceptionQuesNum.noDeal }}</div>
                 </div>
                 <div class="task-category">
                   <div class="task-title">寮傚父鎬绘暟</div>
-                  <div class="task-count total">{{ row.totalExceptionCount }}</div>
+                  <div class="task-count total">{{ row.exceptionQuesNum.all }}</div>
                 </div>
               </div>
             </template>
@@ -288,14 +269,14 @@
 
           <el-table-column
             label="鏈�杩戝鐞�"
-            prop="lastProcessTime"
+            prop="handleTime"
             width="180"
             align="center"
           >
             <template slot-scope="{ row }">
-              <div v-if="row.lastProcessTime" class="last-process">
-                <div class="process-time">{{ row.lastProcessTime }}</div>
-                <div class="process-user">{{ row.lastProcessUser }}</div>
+              <div v-if="row.handleTime" class="last-process">
+                <div class="process-time">{{ formatDateTime(row.handleTime) }}</div>
+                <div class="process-user">{{ row.handleBy || '绯荤粺澶勭悊' }}</div>
               </div>
               <span v-else class="no-process">鏆傛棤澶勭悊璁板綍</span>
             </template>
@@ -308,14 +289,6 @@
             fixed="right"
           >
             <template slot-scope="{ row }">
-              <!-- <el-button
-                type="primary"
-                size="small"
-                icon="el-icon-view"
-                @click="handleViewDetail(row)"
-              >
-                璇︽儏
-              </el-button> -->
               <el-button
                 type="warning"
                 size="small"
@@ -347,15 +320,20 @@
 </template>
 
 <script>
+import { tracedeallist } from "@/api/AiCentre/index";
+
 export default {
   name: 'ExceptionList',
   data() {
     return {
       // 鏌ヨ鍙傛暟
       queryParams: {
-        templateId: '',
-        deptIds: [],
-        dateRange: [],
+        todeptcode: [], // 澶勭悊绉戝缂栧彿鏁扮粍
+        todeptname: '', // 澶勭悊绉戝鍚嶇О
+        templateid: '', // 浠诲姟妯℃澘ID
+        handleStartTime: '', // 澶勭悊寮�濮嬫椂闂�
+        handleEndTime: '', // 澶勭悊缁撴潫鏃堕棿
+        handleTimeRange: [], // 鏃堕棿鑼冨洿锛岀敤浜庣晫闈㈠睍绀�
         pageNum: 1,
         pageSize: 10
       },
@@ -368,26 +346,26 @@
 
       // 妯℃澘鍒楄〃
       templateList: [
-        { id: 1, name: '鍑洪櫌婊℃剰搴﹂棶鍗�' },
-        { id: 2, name: '浣忛櫌婊℃剰搴﹂棶鍗�' },
-        { id: 3, name: '闂ㄨ瘖婊℃剰搴﹂棶鍗�' },
-        { id: 4, name: '甯哥敤婊℃剰搴﹂棶鍗�' }
+        { id: 1, name: '璇煶妯℃澘' },
+        { id: 2, name: '闂嵎妯℃澘' }
+        // 浣犲彲浠ユ牴鎹疄闄呮儏鍐典粠鎺ュ彛鑾峰彇妯℃澘鍒楄〃
       ],
 
       // 绉戝鍒楄〃
       deptList: [
-        { id: 1, name: '蹇冭绠″唴绉�' },
-        { id: 2, name: '绁炵粡鍐呯' },
-        { id: 3, name: '鏅绉�' },
-        { id: 4, name: '楠ㄧ' },
-        { id: 5, name: '濡囦骇绉�' },
-        { id: 6, name: '鍎跨' },
-        { id: 7, name: '鎬ヨ瘖绉�' },
-        { id: 8, name: '鍛煎惛鍐呯' },
-        { id: 9, name: '娑堝寲鍐呯' },
-        { id: 10, name: '鍐呭垎娉岀' },
-        { id: 11, name: '鑲惧唴绉�' },
-        { id: 12, name: '鑲跨槫绉�' }
+        // 浣犲彲浠ヤ粠鎺ュ彛鑾峰彇绉戝鍒楄〃锛岃繖閲屽厛鐢ㄩ潤鎬佹暟鎹�
+        { deptCode: '001', deptName: '蹇冭绠″唴绉�' },
+        { deptCode: '002', deptName: '绁炵粡鍐呯' },
+        { deptCode: '003', deptName: '鏅绉�' },
+        { deptCode: '004', deptName: '楠ㄧ' },
+        { deptCode: '005', deptName: '濡囦骇绉�' },
+        { deptCode: '006', deptName: '鍎跨' },
+        { deptCode: '007', deptName: '鎬ヨ瘖绉�' },
+        { deptCode: '008', deptName: '鍛煎惛鍐呯' },
+        { deptCode: '009', deptName: '娑堝寲鍐呯' },
+        { deptCode: '010', deptName: '鍐呭垎娉岀' },
+        { deptCode: '011', deptName: '鑲惧唴绉�' },
+        { deptCode: '012', deptName: '鑲跨槫绉�' }
       ],
 
       // 寮傚父鍒楄〃鏁版嵁
@@ -445,6 +423,46 @@
   },
 
   methods: {
+    // 鏍煎紡鍖栨棩鏈熸椂闂�
+    formatDateTime(dateTime) {
+      if (!dateTime) return '';
+      const date = new Date(dateTime);
+      return date.toLocaleDateString().replace(/\//g, '-') + ' ' +
+             date.toTimeString().split(' ')[0];
+    },
+
+    // 鑾峰彇妯℃澘绫诲瀷鏍囩鏍峰紡
+    getTemplateTypeTag(type) {
+      return type === 1 ? 'primary' : 'success';
+    },
+
+    // 鏋勫缓鏌ヨ鍙傛暟
+    buildQueryParams() {
+      const params = {
+        pageNum: this.queryParams.pageNum,
+        pageSize: this.queryParams.pageSize
+      };
+
+      // 澶勭悊绉戝缂栧彿
+      if (this.queryParams.todeptcode && this.queryParams.todeptcode.length > 0) {
+        // 鎺ュ彛鍙兘闇�瑕佸瓧绗︿覆鏍煎紡鐨勭瀹ょ紪鍙凤紝鏍规嵁瀹為檯鎯呭喌璋冩暣
+        params.todeptcode = this.queryParams.todeptcode.join(',');
+      }
+
+      // 妯℃澘ID
+      if (this.queryParams.templateid) {
+        params.templateid = this.queryParams.templateid;
+      }
+
+      // 澶勭悊鏃堕棿鑼冨洿
+      if (this.queryParams.handleTimeRange && this.queryParams.handleTimeRange.length === 2) {
+        params.handleStartTime = this.queryParams.handleTimeRange[0];
+        params.handleEndTime = this.queryParams.handleTimeRange[1];
+      }
+
+      return params;
+    },
+
     // 鍔犺浇鏁版嵁
     async loadData() {
       this.loading = true;
@@ -460,185 +478,62 @@
 
     // 鍔犺浇寮傚父鍒楄〃
     async loadExceptionList() {
-      return new Promise((resolve) => {
-        setTimeout(() => {
-          // Mock 鏁版嵁
-          this.exceptionList = [
-            {
-              id: 1,
-              questionId: 101,
-              questionContent: '鎮ㄥ鍖绘姢浜哄憳鐨勬湇鍔℃�佸害鏄惁婊℃剰锛�',
-              questionType: 1, // 1: 鍗曢�夐, 2: 澶氶�夐
-              templateName: '鍑洪櫌婊℃剰搴﹂棶鍗�',
-              responsibilityDepts: [
-                { id: 1, name: '蹇冭绠″唴绉�' },
-                { id: 2, name: '绁炵粡鍐呯' }
-              ],
-              validFillCount: 145,
-              exceptionFillCount: 8,
-              processedCount: 5,
-              pendingCount: 3,
-              totalExceptionCount: 8,
-              lastProcessTime: '2024-01-15 10:30:25',
-              lastProcessUser: '寮犲尰鐢�'
-            },
-            {
-              id: 2,
-              questionId: 102,
-              questionContent: '鎮ㄥ鍖荤敓鐨勮瘖鐤楁按骞冲拰鎶�鏈兘鍔涜瘎浠峰浣曪紵',
-              questionType: 1,
-              templateName: '浣忛櫌婊℃剰搴﹂棶鍗�',
-              responsibilityDepts: [
-                { id: 3, name: '鏅绉�' },
-                { id: 4, name: '楠ㄧ' }
-              ],
-              validFillCount: 120,
-              exceptionFillCount: 12,
-              processedCount: 8,
-              pendingCount: 4,
-              totalExceptionCount: 12,
-              lastProcessTime: '2024-01-14 16:20:10',
-              lastProcessUser: '鏉庢姢澹暱'
-            },
-            {
-              id: 3,
-              questionId: 103,
-              questionContent: '鎮ㄥ鍖婚櫌鐨勭幆澧冨拰鍗敓鐘跺喌鏄惁婊℃剰锛�',
-              questionType: 1,
-              templateName: '闂ㄨ瘖婊℃剰搴﹂棶鍗�',
-              responsibilityDepts: [
-                { id: 5, name: '濡囦骇绉�' },
-                { id: 6, name: '鍎跨' },
-                { id: 7, name: '鎬ヨ瘖绉�' }
-              ],
-              validFillCount: 180,
-              exceptionFillCount: 15,
-              processedCount: 10,
-              pendingCount: 5,
-              totalExceptionCount: 15,
-              lastProcessTime: '2024-01-13 09:15:45',
-              lastProcessUser: '鐜嬩富浠�'
-            },
-            {
-              id: 4,
-              questionId: 104,
-              questionContent: '鎮ㄨ涓哄尰鎶や汉鍛樹笌鎮ㄧ殑娌熼�氭槸鍚﹀厖鍒嗭紵',
-              questionType: 1,
-              templateName: '甯哥敤婊℃剰搴﹂棶鍗�',
-              responsibilityDepts: [
-                { id: 8, name: '鍛煎惛鍐呯' },
-                { id: 9, name: '娑堝寲鍐呯' }
-              ],
-              validFillCount: 95,
-              exceptionFillCount: 6,
-              processedCount: 4,
-              pendingCount: 2,
-              totalExceptionCount: 6,
-              lastProcessTime: '2024-01-12 14:40:30',
-              lastProcessUser: '璧靛尰鐢�'
-            },
-            {
-              id: 5,
-              questionId: 105,
-              questionContent: '鎮ㄥ绛夊緟灏辫瘖鍜屾不鐤楃殑鏃堕棿鏄惁婊℃剰锛�',
-              questionType: 1,
-              templateName: '浣忛櫌婊℃剰搴﹂棶鍗�',
-              responsibilityDepts: [
-                { id: 10, name: '鍐呭垎娉岀' },
-                { id: 11, name: '鑲惧唴绉�' }
-              ],
-              validFillCount: 200,
-              exceptionFillCount: 25,
-              processedCount: 15,
-              pendingCount: 10,
-              totalExceptionCount: 25,
-              lastProcessTime: '2024-01-11 11:25:15',
-              lastProcessUser: '瀛欐姢澹�'
-            },
-            {
-              id: 6,
-              questionId: 106,
-              questionContent: '鎮ㄥ鍖婚櫌鏀惰垂鐨勯�忔槑搴﹀拰鍚堢悊鎬ц瘎浠峰浣曪紵',
-              questionType: 1,
-              templateName: '闂ㄨ瘖婊℃剰搴﹂棶鍗�',
-              responsibilityDepts: [
-                { id: 12, name: '鑲跨槫绉�' }
-              ],
-              validFillCount: 160,
-              exceptionFillCount: 18,
-              processedCount: 12,
-              pendingCount: 6,
-              totalExceptionCount: 18,
-              lastProcessTime: '2024-01-10 15:50:20',
-              lastProcessUser: '鍛ㄥ尰鐢�'
-            },
-            {
-              id: 7,
-              questionId: 107,
-              questionContent: '鎮ㄤ細鍚戜翰鍙嬫帹鑽愭垜浠尰闄㈠悧锛�',
-              questionType: 1,
-              templateName: '鍑洪櫌婊℃剰搴﹂棶鍗�',
-              responsibilityDepts: [
-                { id: 1, name: '蹇冭绠″唴绉�' },
-                { id: 8, name: '鍛煎惛鍐呯' }
-              ],
-              validFillCount: 110,
-              exceptionFillCount: 7,
-              processedCount: 5,
-              pendingCount: 2,
-              totalExceptionCount: 7,
-              lastProcessTime: '2024-01-09 10:15:40',
-              lastProcessUser: '鍚翠富浠�'
-            },
-            {
-              id: 8,
-              questionId: 108,
-              questionContent: '鎮ㄥ浠ヤ笅鍝簺鏂归潰姣旇緝婊℃剰锛堝閫夛級锛�',
-              questionType: 2,
-              templateName: '甯哥敤婊℃剰搴﹂棶鍗�',
-              responsibilityDepts: [
-                { id: 2, name: '绁炵粡鍐呯' },
-                { id: 3, name: '鏅绉�' },
-                { id: 5, name: '濡囦骇绉�' }
-              ],
-              validFillCount: 135,
-              exceptionFillCount: 9,
-              processedCount: 6,
-              pendingCount: 3,
-              totalExceptionCount: 9,
-              lastProcessTime: '2024-01-08 13:30:55',
-              lastProcessUser: '閮戝尰鐢�'
-            }
-          ];
-          this.total = this.exceptionList.length;
-          resolve();
-        }, 500);
-      });
+      try {
+        const params = this.buildQueryParams();
+        const response = await tracedeallist(params);
+
+        if (response.code==200) {
+          this.exceptionList = response.rows.detailTraceDealDTOList || [];
+          this.overviewData.totalExceptionCount=response.rows.totalException
+          this.overviewData.pendingCount=response.rows.noDealException
+          this.overviewData.processedCount=response.rows.yesDealException
+          this.total = response.total || 0;
+        } else {
+          this.exceptionList = [];
+          this.total = 0;
+        }
+      } catch (error) {
+        console.error('鍔犺浇寮傚父鍒楄〃澶辫触:', error);
+        this.$message.error('鍔犺浇寮傚父鍒楄〃澶辫触锛岃绋嶅悗閲嶈瘯');
+        this.exceptionList = [];
+        this.total = 0;
+      }
     },
 
     // 鍔犺浇姒傝鏁版嵁
     async loadOverviewData() {
-      return new Promise((resolve) => {
-        setTimeout(() => {
-          // 璁$畻缁熻鏁版嵁
-          const totalExceptionCount = this.exceptionList.reduce((sum, item) => sum + item.totalExceptionCount, 0);
-          const pendingCount = this.exceptionList.reduce((sum, item) => sum + item.pendingCount, 0);
-          const processedCount = this.exceptionList.reduce((sum, item) => sum + item.processedCount, 0);
+      try {
+        // 浠庢帴鍙f暟鎹绠楃粺璁℃暟鎹�
+        const totalExceptionCount = this.exceptionList.reduce((sum, item) =>
+          sum + (item.exceptionQuesNum?.all || 0), 0);
+        const pendingCount = this.exceptionList.reduce((sum, item) =>
+          sum + (item.exceptionQuesNum?.noDeal || 0), 0);
+        const processedCount = this.exceptionList.reduce((sum, item) =>
+          sum + (item.exceptionQuesNum?.yesDeal || 0), 0);
 
-          this.overviewData = {
-            totalExceptionCount,
-            pendingCount,
-            processedCount,
-            todayProcessedCount: 8 // 浠婃棩澶勭悊鏁� mock
-          };
-          resolve();
-        }, 300);
-      });
-    },
+        // 璁$畻浠婃棩澶勭悊鏁帮紙杩欓噷鍙互鏍规嵁瀹為檯闇�姹傝皟鏁撮�昏緫锛�
+        const today = new Date().toISOString().split('T')[0];
+        const todayProcessedCount = this.exceptionList.filter(item => {
+          if (!item.handleTime) return false;
+          const handleDate = new Date(item.handleTime).toISOString().split('T')[0];
+          return handleDate === today;
+        }).length;
 
-    // 鑾峰彇棰樼洰绫诲瀷鏍囩鏍峰紡
-    getQuestionTypeTag(type) {
-      return type === 1 ? 'primary' : 'success';
+        this.overviewData = {
+          totalExceptionCount,
+          pendingCount,
+          processedCount,
+          todayProcessedCount
+        };
+      } catch (error) {
+        console.error('鍔犺浇姒傝鏁版嵁澶辫触:', error);
+        this.overviewData = {
+          totalExceptionCount: 0,
+          pendingCount: 0,
+          processedCount: 0,
+          todayProcessedCount: 0
+        };
+      }
     },
 
     // 澶勭悊鏌ヨ
@@ -650,8 +545,9 @@
     // 澶勭悊閲嶇疆
     handleReset() {
       this.$refs.queryForm.resetFields();
-      this.queryParams.dateRange = [];
+      this.queryParams.handleTimeRange = [];
       this.queryParams.pageNum = 1;
+      this.queryParams.todeptcode = []; // 閲嶇疆绉戝閫夋嫨
       this.loadData();
     },
 
@@ -664,7 +560,7 @@
 
       // 璺宠浆鍒版壒閲忓鐞嗛〉闈�
       this.$router.push({
-        path: '/satisfaction/exception/batch-process',
+        path: '/Intelligentcenter/batch',
         query: {
           questionIds: this.selectedIds.join(',')
         }
@@ -684,17 +580,7 @@
 
     // 澶勭悊閫夋嫨鍙樺寲
     handleSelectionChange(selection) {
-      this.selectedIds = selection.map(item => item.questionId);
-    },
-
-    // 澶勭悊鏌ョ湅璇︽儏
-    handleViewDetail(row) {
-      this.$router.push({
-        path: '/satisfaction/exception/detail',
-        query: {
-          id: row.questionId
-        }
-      });
+      this.selectedIds = selection.map(item => item.scriptid);
     },
 
     // 澶勭悊鍗曚釜棰樼洰鎵归噺澶勭悊
@@ -702,7 +588,8 @@
       this.$router.push({
         path: '/Intelligentcenter/batch',
         query: {
-          questionId: row.questionId
+          questionId: row.scriptid,
+          questionText: encodeURIComponent(row.questiontext)
         }
       });
     },
@@ -838,12 +725,13 @@
           color: #303133;
           margin-bottom: 8px;
           line-height: 1.5;
+          text-align: left;
         }
 
         .question-tags {
           display: flex;
           gap: 5px;
-          justify-content: center;
+          justify-content: flex-start;
         }
       }
 
diff --git a/src/views/Satisfaction/sfstatistics/components/SatisfactionStatistics.vue b/src/views/Satisfaction/sfstatistics/components/SatisfactionStatistics.vue
index c1d3a0a..2d78fdf 100644
--- a/src/views/Satisfaction/sfstatistics/components/SatisfactionStatistics.vue
+++ b/src/views/Satisfaction/sfstatistics/components/SatisfactionStatistics.vue
@@ -414,7 +414,7 @@
                   </template>
                 </el-table-column>
 
-                <el-table-column
+                <!-- <el-table-column
                   label="瓒嬪娍"
                   prop="trend"
                   align="center"
@@ -446,7 +446,7 @@
                       }}</span>
                     </div>
                   </template>
-                </el-table-column>
+                </el-table-column> -->
 
                 <el-table-column
                   label="鎿嶄綔"
@@ -790,11 +790,11 @@
       Object.entries(apiData.rows).forEach(([typeName, typeStat]) => {
         const sendCount = typeStat.subidAll || 0;
         const receiveCount = typeStat.fillCountAll || 0;
-        const recoveryRate = typeStat.receiveRate || 0;
+        const recoveryRate = typeStat.receiveRate.toFixed(2) || 0;
 
         chartData.push({
           name: typeName,
-          value: recoveryRate * 100, // 杞崲涓虹櫨鍒嗘瘮
+          value: (recoveryRate * 100).toFixed(2), // 杞崲涓虹櫨鍒嗘瘮
           sendCount: sendCount,
           receiveCount: receiveCount,
           averageScore: typeStat.averageScore || 0,
@@ -914,7 +914,9 @@
         const response = await satisfactionGraph(params);
 
         if (response.code === 200) {
-          this.processTypeDetailData(response.data);
+          this.processTypeDetailData(response);
+          console.log(11);
+
         } else {
           this.$message.error(response.msg || "鑾峰彇绫诲瀷鏄庣粏鏁版嵁澶辫触");
           const mockData = await this.generateMockTypeDetail();
@@ -944,7 +946,7 @@
       Object.entries(apiData.rows).forEach(([typeName, typeStat], index) => {
         const sendCount = typeStat.subidAll || 0;
         const receiveCount = typeStat.fillCountAll || 0;
-        const recoveryRate = typeStat.receiveRate || 0;
+        const recoveryRate = typeStat.receiveRate.toFixed(2) || 0;
         const averageScore = typeStat.averageScore || 0;
 
         typeDetail.push({
@@ -963,6 +965,8 @@
       });
 
       this.typeDetailData = typeDetail;
+      console.log(this.typeDetailData,'this.typeDetailData');
+
       this.calculateTypeSummary(typeDetail);
     },
 
@@ -972,7 +976,7 @@
       if (score >= 4.0) return "鑹ソ";
       if (score >= 3.0) return "涓�鑸�";
       if (score >= 2.0) return "杈冨樊";
-      return "宸�";
+      return "鏈煡";
     },
 
     // 鑾峰彇瓒嬪娍
@@ -1041,24 +1045,24 @@
     // 娓叉煋鍥捐〃
     renderChart(chartData) {
       if (!this.barChart) return;
- if (!chartData || chartData.length === 0) {
-    const emptyOption = {
-      title: {
-        text: "鏆傛棤鏁版嵁",
-        left: "center",
-        top: "center",
-        textStyle: {
-          color: "#999",
-          fontSize: 16,
-          fontWeight: "normal"
-        }
-      },
-      xAxis: { show: false },
-      yAxis: { show: false }
-    };
-    this.barChart.setOption(emptyOption);
-    return;
-  }
+      if (!chartData || chartData.length === 0) {
+        const emptyOption = {
+          title: {
+            text: "鏆傛棤鏁版嵁",
+            left: "center",
+            top: "center",
+            textStyle: {
+              color: "#999",
+              fontSize: 16,
+              fontWeight: "normal",
+            },
+          },
+          xAxis: { show: false },
+          yAxis: { show: false },
+        };
+        this.barChart.setOption(emptyOption);
+        return;
+      }
       const option = {
         title: {
           text: "",
@@ -1079,7 +1083,7 @@
                 <span style="display:inline-block;width:10px;height:10px;border-radius:2px;background:${
                   data.color
                 };margin-right:5px;"></span>
-                濉姤姣斾緥: <strong>${data.value.toFixed(1)}%</strong>
+                濉姤姣斾緥: <strong>${data.value}%</strong>
               </div>
               <div style="margin: 2px 0;">
                 <span style="display:inline-block;width:10px;height:10px;border-radius:2px;background:#eee;margin-right:5px;"></span>
@@ -1437,12 +1441,12 @@
 
     // 鏍煎紡鍖栫櫨鍒嗘瘮
     formatPercent(value) {
-   if (value === null || value === undefined) return "-";
-  const num = parseFloat(value);
-  if (isNaN(num)) return "-";
-  // 濡傛灉鍊煎皬浜�1锛岃涓烘槸灏忔暟姣斾緥锛岄渶瑕佷箻浠�100
-  const percentValue = num < 1 ? num * 100 : num;
-  return `${percentValue.toFixed(2)}%`;
+      if (value === null || value === undefined) return "-";
+      const num = parseFloat(value);
+      if (isNaN(num)) return "-";
+      // 濡傛灉鍊煎皬浜�1锛岃涓烘槸灏忔暟姣斾緥锛岄渶瑕佷箻浠�100
+      const percentValue = num < 1 ? num * 100 : num;
+      return `${percentValue.toFixed(2)}%`;
     },
 
     // 鑾峰彇鍥炴敹鐜囨牱寮忕被
@@ -1459,7 +1463,7 @@
         鑹ソ: "primary",
         涓�鑸�: "warning",
         杈冨樊: "danger",
-        宸�: "info",
+        鏈煡: "info",
       };
       return levelMap[level] || "info";
     },
diff --git a/src/views/followvisit/HistoricalFollow/index.vue b/src/views/followvisit/HistoricalFollow/index.vue
index 4b5b99a..3abdee2 100644
--- a/src/views/followvisit/HistoricalFollow/index.vue
+++ b/src/views/followvisit/HistoricalFollow/index.vue
@@ -662,7 +662,7 @@
           value: 4,
           label: "涓嶆墽琛�",
         },
-         {
+        {
           value: 5,
           label: "鍙戦�佸け璐�",
         },
@@ -670,7 +670,7 @@
           value: 6,
           label: "宸插畬鎴�",
         },
-         {
+        {
           value: 7,
           label: "瓒呮椂",
         },
@@ -1147,7 +1147,7 @@
     /** 瀵煎嚭鎸夐挳鎿嶄綔 */
     handleExport() {
       console.log(this.topqueryParams);
-
+      this.topqueryParams.pageSize = null;
       this.download(
         // "smartor/serviceSubtask/export",
         "smartor/serviceSubtask/getSubtaskByDiagnameExport",
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