WXL (wul)
10 小时以前 c65b90aaa3477a90ebc325024927d80227c0c841
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.templateType"
              placeholder="请选择模板"
              clearable
              style="width: 200px"
@@ -35,9 +35,9 @@
            </el-select>
          </el-form-item>
          <el-form-item label="责任科室" prop="deptIds">
          <el-form-item label="责任科室" prop="todeptcode">
            <el-select
              v-model="queryParams.deptIds"
              v-model="queryParams.todeptcode"
              placeholder="请选择责任科室"
              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.label"
                :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"
            />
@@ -96,11 +96,7 @@
          >
            批量处理 ({{ selectedIds.length }})
          </el-button>
          <el-button
            type="info"
            icon="el-icon-download"
            @click="handleExport"
          >
          <el-button type="info" icon="el-icon-download" @click="handleExport">
            导出异常数据
          </el-button>
          <el-button
@@ -117,24 +113,26 @@
    <!-- 异常统计概览 -->
    <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;">
                <i class="el-icon-s-claim" style="color: #5788FE;"></i>
              <div class="stat-icon" style="background: #f0f9ff">
                <i class="el-icon-s-claim" style="color: #5788fe"></i>
              </div>
              <div class="stat-info">
                <div class="stat-title">总异常数量</div>
                <div class="stat-value">{{ overviewData.totalExceptionCount }}</div>
                <div class="stat-value">
                  {{ overviewData.totalExceptionCount }}
                </div>
              </div>
            </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;">
                <i class="el-icon-s-flag" style="color: #E6A23C;"></i>
              <div class="stat-icon" style="background: #f0f9ff">
                <i class="el-icon-s-flag" style="color: #e6a23c"></i>
              </div>
              <div class="stat-info">
                <div class="stat-title">待处理异常</div>
@@ -143,28 +141,15 @@
            </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;">
                <i class="el-icon-check" style="color: #67C23A;"></i>
              <div class="stat-icon" style="background: #f0f9ff">
                <i class="el-icon-check" style="color: #67c23a"></i>
              </div>
              <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>
@@ -183,11 +168,7 @@
          @selection-change="handleSelectionChange"
          class="exception-table"
        >
          <el-table-column
            type="selection"
            width="55"
            align="center"
          />
          <el-table-column type="selection" width="55" align="center" />
          <el-table-column
            label="序号"
@@ -198,25 +179,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,62 +200,64 @@
          <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>
          </el-table-column>
          <el-table-column
            label="填写情况"
            width="200"
            align="center"
          >
          <el-table-column label="填写情况" width="200" align="center">
            <template slot-scope="{ row }">
              <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>
          </el-table-column>
          <el-table-column
            label="异常任务"
            width="280"
            align="center"
          >
          <el-table-column label="异常任务" width="280" align="center">
            <template slot-scope="{ row }">
              <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 +265,16 @@
          <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 +287,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,17 +318,23 @@
</template>
<script>
import { tracedeallist } from "@/api/AiCentre/index";
import { deptTreeSelect } from "@/api/system/user";
export default {
  name: 'ExceptionList',
  name: "ExceptionList",
  data() {
    return {
      // 查询参数
      queryParams: {
        templateId: '',
        deptIds: [],
        dateRange: [],
        todeptcode: [], // 处理科室编号数组
        todeptname: "", // 处理科室名称
        templateType: 2, // 任务模板ID
        handleStartTime: "", // 处理开始时间
        handleEndTime: "", // 处理结束时间
        handleTimeRange: [], // 时间范围,用于界面展示
        pageNum: 1,
        pageSize: 10
        pageSize: 10,
      },
      // 加载状态
@@ -368,27 +345,13 @@
      // 模板列表
      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: '肿瘤科' }
      ],
      deptList: [],
      // 异常列表数据
      exceptionList: [],
@@ -399,60 +362,134 @@
        totalExceptionCount: 0,
        pendingCount: 0,
        processedCount: 0,
        todayProcessedCount: 0
        todayProcessedCount: 0,
      },
      // 日期选择器选项
      pickerOptions: {
        shortcuts: [
          {
            text: '最近一周',
            text: "最近一周",
            onClick(picker) {
              const end = new Date();
              const start = new Date();
              start.setTime(start.getTime() - 3600 * 1000 * 24 * 7);
              picker.$emit('pick', [start, end]);
            }
              picker.$emit("pick", [start, end]);
            },
          },
          {
            text: '最近一个月',
            text: "最近一个月",
            onClick(picker) {
              const end = new Date();
              const start = new Date();
              start.setTime(start.getTime() - 3600 * 1000 * 24 * 30);
              picker.$emit('pick', [start, end]);
            }
              picker.$emit("pick", [start, end]);
            },
          },
          {
            text: '最近三个月',
            text: "最近三个月",
            onClick(picker) {
              const end = new Date();
              const start = new Date();
              start.setTime(start.getTime() - 3600 * 1000 * 24 * 90);
              picker.$emit('pick', [start, end]);
            }
          }
              picker.$emit("pick", [start, end]);
            },
          },
        ],
        disabledDate(time) {
          return time.getTime() > Date.now();
        }
      }
        },
      },
    };
  },
  mounted() {
    this.loadData();
    this.getDeptOptions();
  },
  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.templateType) {
        params.templateType = this.queryParams.templateType;
      }
      // 处理时间范围
      if (
        this.queryParams.handleTimeRange &&
        this.queryParams.handleTimeRange.length === 2
      ) {
        params.handleStartTime = this.queryParams.handleTimeRange[0];
        params.handleEndTime = this.queryParams.handleTimeRange[1];
      }
      return params;
    },
    /** 查询科室列表 */
    getDeptOptions() {
      deptTreeSelect()
        .then((res) => {
          if (res.code == 200) {
            this.deptList = this.flattenArray(res.data) || [];
          }
        })
        .catch((error) => {
          console.error("获取科室列表失败:", error);
          this.$message.error("获取科室列表失败");
        });
    },
    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;
    },
    // 加载数据
    async loadData() {
      this.loading = true;
      try {
        await Promise.all([
          this.loadExceptionList(),
          this.loadOverviewData()
        ]);
        await Promise.all([this.loadExceptionList(), this.loadOverviewData()]);
      } finally {
        this.loading = false;
      }
@@ -460,185 +497,70 @@
    // 加载异常列表
    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 {
        // 从接口数据计算统计数据
        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,60 +572,53 @@
    // 处理重置
    handleReset() {
      this.$refs.queryForm.resetFields();
      this.queryParams.dateRange = [];
      this.queryParams.handleTimeRange = [];
      this.queryParams.pageNum = 1;
      this.queryParams.todeptcode = []; // 重置科室选择
      this.loadData();
    },
    // 处理批量处理
    handleBatchProcess() {
      if (this.selectedIds.length === 0) {
        this.$message.warning('请先选择要处理的异常题目');
        this.$message.warning("请先选择要处理的异常题目");
        return;
      }
      // 跳转到批量处理页面
      this.$router.push({
        path: '/satisfaction/exception/batch-process',
        path: "/Intelligentcenter/batch",
        query: {
          questionIds: this.selectedIds.join(',')
        }
          questionIds: this.selectedIds.join(","),
          type: this.queryParams.templateType,
        },
      });
    },
    // 处理导出
    handleExport() {
      this.$message.success('导出功能开发中...');
      this.$message.success("导出功能开发中...");
    },
    // 刷新数据
    refreshData() {
      this.loadData();
      this.$message.success('数据已刷新');
      this.$message.success("数据已刷新");
    },
    // 处理选择变化
    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);
    },
    // 处理单个题目批量处理
    handleBatchQuestion(row) {
      this.$router.push({
        path: '/Intelligentcenter/batch',
        path: "/Intelligentcenter/batch",
        query: {
          questionId: row.questionId
        }
          questionId: row.scriptid,
          type: this.queryParams.templateType,
        },
      });
    },
@@ -718,8 +633,8 @@
    handlePageChange(page) {
      this.queryParams.pageNum = page;
      this.loadExceptionList();
    }
  }
    },
  },
};
</script>
@@ -732,7 +647,7 @@
  .page-header {
    margin-bottom: 20px;
    padding: 20px;
    background: linear-gradient(135deg, #5788FE 0%, #66b1ff 100%);
    background: linear-gradient(135deg, #5788fe 0%, #66b1ff 100%);
    border-radius: 8px;
    color: white;
@@ -838,12 +753,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;
        }
      }
@@ -915,7 +831,7 @@
            }
            &.total {
              color: #5788FE;
              color: #5788fe;
            }
          }
        }
@@ -930,7 +846,7 @@
        .process-user {
          font-size: 13px;
          color: #5788FE;
          color: #5788fe;
          font-weight: 500;
        }
      }