| | |
| | | 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" |
| | |
| | | </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 |
| | |
| | | > |
| | | <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" |
| | | /> |
| | |
| | | > |
| | | 批量处理 ({{ 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 |
| | |
| | | <!-- 异常统计概览 --> |
| | | <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> |
| | |
| | | </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> |
| | |
| | | @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="序号" |
| | |
| | | |
| | | <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> |
| | |
| | | |
| | | <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> |
| | |
| | | |
| | | <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> |
| | |
| | | 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" |
| | |
| | | </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, |
| | | }, |
| | | |
| | | // 加载状态 |
| | |
| | | |
| | | // 模板列表 |
| | | 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: [], |
| | |
| | | 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; |
| | | } |
| | |
| | | |
| | | // 加载异常列表 |
| | | 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, |
| | | }; |
| | | } |
| | | }, |
| | | |
| | | // 处理查询 |
| | |
| | | // 处理重置 |
| | | 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, |
| | | }, |
| | | }); |
| | | }, |
| | | |
| | |
| | | handlePageChange(page) { |
| | | this.queryParams.pageNum = page; |
| | | this.loadExceptionList(); |
| | | } |
| | | } |
| | | }, |
| | | }, |
| | | }; |
| | | </script> |
| | | |
| | |
| | | .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; |
| | | |
| | |
| | | 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; |
| | | } |
| | | } |
| | | |
| | |
| | | } |
| | | |
| | | &.total { |
| | | color: #5788FE; |
| | | color: #5788fe; |
| | | } |
| | | } |
| | | } |
| | |
| | | |
| | | .process-user { |
| | | font-size: 13px; |
| | | color: #5788FE; |
| | | color: #5788fe; |
| | | font-weight: 500; |
| | | } |
| | | } |