WXL (wul)
3 天以前 dac4393e8af2646f544f6e1ca24dab11b40c8492
src/views/Satisfaction/configurationmyd/batch.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,922 @@
<template>
  <div class="batch-process">
    <!-- é¡µé¢æ ‡é¢˜ -->
    <div class="page-header">
      <div class="header-content">
        <h2 class="page-title">异常批量处理</h2>
        <p class="page-description">批量处理选中的异常反馈</p>
        <div class="header-actions">
          <el-button
            type="primary"
            icon="el-icon-check"
            @click="handleBatchSubmit"
            :loading="batchProcessing"
          >
            æ‰¹é‡æäº¤å¤„理
          </el-button>
          <el-button type="warning" icon="el-icon-back" @click="handleGoBack">
            è¿”回异常列表
          </el-button>
        </div>
      </div>
    </div>
    <!-- å¼‚常列表 -->
    <div class="list-section">
      <el-card shadow="never">
        <div class="filter-section">
          <el-form
            :model="filterParams"
            :inline="true"
            size="medium"
            class="filter-form"
          >
            <el-form-item label="负责科室">
              <el-select
                v-model="filterParams.deptId"
                placeholder="请选择科室"
                clearable
                style="width: 200px"
              >
                <el-option
                  v-for="dept in deptList"
                  :key="dept.id"
                  :label="dept.name"
                  :value="dept.id"
                />
              </el-select>
            </el-form-item>
            <el-form-item label="处理状态">
              <el-select
                v-model="filterParams.status"
                placeholder="请选择状态"
                clearable
                style="width: 200px"
              >
                <el-option label="待处理" :value="0" />
                <el-option label="处理中" :value="1" />
                <el-option label="已处理" :value="2" />
              </el-select>
            </el-form-item>
            <el-form-item>
              <el-button
                type="primary"
                icon="el-icon-search"
                @click="handleFilter"
              >
                ç­›é€‰
              </el-button>
              <el-button icon="el-icon-refresh" @click="handleResetFilter">
                é‡ç½®
              </el-button>
            </el-form-item>
          </el-form>
        </div>
        <el-table
          v-loading="loading"
          :data="exceptionList"
          :border="true"
          style="width: 100%"
          @selection-change="handleSelectionChange"
          class="exception-table"
        >
          <el-table-column type="selection" width="55" align="center" />
          <el-table-column
            label="序号"
            type="index"
            width="60"
            align="center"
          />
          <el-table-column
            label="负责科室"
            prop="responsibilityDept"
            width="120"
            align="center"
          >
            <template slot-scope="{ row }">
              <el-tag type="primary">{{ row.responsibilityDept }}</el-tag>
            </template>
          </el-table-column>
          <el-table-column
            label="不满意详情"
            prop="unsatisfactoryDetail"
            min-width="200"
            align="center"
          >
            <template slot-scope="{ row }">
              <div class="detail-content">
                {{ row.unsatisfactoryDetail }}
              </div>
            </template>
          </el-table-column>
          <el-table-column label="患者信息" 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>
                <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>
              </div>
            </template>
          </el-table-column>
          <el-table-column label="出院信息" width="250" align="center">
            <template slot-scope="{ row }">
              <div class="discharge-info">
                <div class="info-item">
                  <span class="label">科室:</span>
                  <span class="value">{{ row.dischargeDept }}</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>
              </div>
            </template>
          </el-table-column>
          <el-table-column
            label="处理状态"
            prop="processStatus"
            width="100"
            align="center"
          >
            <template slot-scope="{ row }">
              <el-tag :type="getStatusTagType(row.processStatus)" effect="dark">
                {{ getStatusText(row.processStatus) }}
              </el-tag>
            </template>
          </el-table-column>
          <el-table-column
            label="操作"
            width="210"
            align="center"
            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"
                icon="el-icon-edit"
                @click="handleProcess(row)"
                :disabled="row.processStatus === 2"
              >
                å¤„理
              </el-button>
            </template>
          </el-table-column>
        </el-table>
        <!-- åˆ†é¡µ -->
        <div class="pagination-section">
          <el-pagination
            background
            layout="total, sizes, prev, pager, next, jumper"
            :current-page="filterParams.pageNum"
            :page-size="filterParams.pageSize"
            :page-sizes="[10, 20, 30, 50]"
            :total="total"
            @size-change="handleSizeChange"
            @current-change="handlePageChange"
          />
        </div>
      </el-card>
    </div>
    <!-- å¤„理对话框 -->
    <el-dialog
      title="处理异常反馈"
      :visible.sync="processDialogVisible"
      width="600px"
      center
    >
      <el-form
        :model="processForm"
        :rules="processRules"
        ref="processForm"
        label-width="100px"
        size="medium"
      >
        <el-form-item label="处理状态" prop="status">
          <el-select
            v-model="processForm.status"
            placeholder="请选择处理状态"
            style="width: 100%"
          >
            <el-option label="处理中" :value="1" />
            <el-option label="已处理" :value="2" />
            <el-option label="已驳回" :value="3" />
          </el-select>
        </el-form-item>
        <el-form-item label="报备科室" prop="reportDepts">
          <el-select
            v-model="processForm.reportDepts"
            placeholder="请选择报备科室"
            multiple
            filterable
            collapse-tags
            style="width: 100%"
          >
            <el-option
              v-for="dept in deptList"
              :key="dept.id"
              :label="dept.name"
              :value="dept.id"
            />
          </el-select>
        </el-form-item>
        <el-form-item label="处理备注" prop="remark">
          <el-input
            v-model="processForm.remark"
            type="textarea"
            :rows="4"
            placeholder="请输入处理备注(最多500字)"
            maxlength="500"
            show-word-limit
          />
        </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">
              æ”¯æŒä¸Šä¼ å›¾ç‰‡ã€æ–‡æ¡£ç­‰é™„件,单个文件不超过10MB
            </div>
          </el-upload>
        </el-form-item>
      </el-form>
      <span slot="footer" class="dialog-footer">
        <el-button @click="processDialogVisible = false">取消</el-button>
        <el-button type="primary" @click="submitProcess" :loading="processing">
          æäº¤å¤„理
        </el-button>
      </span>
    </el-dialog>
    <!-- æ‰¹é‡å¤„理对话框 -->
    <el-dialog
      title="批量处理异常反馈"
      :visible.sync="batchDialogVisible"
      width="600px"
      center
    >
      <el-form
        :model="batchProcessForm"
        :rules="processRules"
        ref="batchProcessForm"
        label-width="100px"
        size="medium"
      >
        <el-form-item label="处理状态" prop="status">
          <el-select
            v-model="batchProcessForm.status"
            placeholder="请选择处理状态"
            style="width: 100%"
          >
            <el-option label="处理中" :value="1" />
            <el-option label="已处理" :value="2" />
            <el-option label="已驳回" :value="3" />
          </el-select>
        </el-form-item>
        <el-form-item label="报备科室" prop="reportDepts">
          <el-select
            v-model="batchProcessForm.reportDepts"
            placeholder="请选择报备科室"
            multiple
            filterable
            collapse-tags
            style="width: 100%"
          >
            <el-option
              v-for="dept in deptList"
              :key="dept.id"
              :label="dept.name"
              :value="dept.id"
            />
          </el-select>
        </el-form-item>
        <el-form-item label="处理备注" prop="remark">
          <el-input
            v-model="batchProcessForm.remark"
            type="textarea"
            :rows="4"
            placeholder="请输入处理备注(最多500字)"
            maxlength="500"
            show-word-limit
          />
        </el-form-item>
      </el-form>
      <span slot="footer" class="dialog-footer">
        <el-button @click="batchDialogVisible = false">取消</el-button>
        <el-button
          type="primary"
          @click="submitBatchProcess"
          :loading="batchProcessing"
        >
          æ‰¹é‡æäº¤
        </el-button>
      </span>
    </el-dialog>
    <!-- å¼‚常详情弹框 -->
    <Details-anomaly
      :visible="detailDialogVisible"
      :record-id="selectedRecordId"
      :title="detailDialogTitle"
      @update:visible="handleDetailDialogClose"
      @processed="handleProcessed"
      @close="handleDetailDialogClose"
    />
  </div>
</template>
<script>
import DetailsAnomaly from "./components/DetailsAnomaly.vue";
export default {
  name: "BatchProcess",
  components: {
    DetailsAnomaly,
  },
  data() {
    return {
      // æ·»åŠ ä»¥ä¸‹æ•°æ®
      detailDialogVisible: false,
      selectedRecordId: null,
      detailDialogTitle: "异常反馈详情",
      // å½“前处理的异常ID
      currentExceptionId: null,
      // æ‰¹é‡é€‰ä¸­çš„异常ID
      selectedExceptionIds: [],
      // è¿‡æ»¤å‚æ•°
      filterParams: {
        deptId: "",
        status: "",
        pageNum: 1,
        pageSize: 10,
      },
      // åŠ è½½çŠ¶æ€
      loading: false,
      processing: false,
      batchProcessing: 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: "内分泌科" },
      ],
      // å¼‚常列表数据
      exceptionList: [],
      total: 0,
      // å¤„理对话框
      processDialogVisible: false,
      processForm: {
        status: "",
        reportDepts: [],
        remark: "",
      },
      processRules: {
        status: [
          { required: true, message: "请选择处理状态", trigger: "change" },
        ],
        remark: [
          { required: true, message: "请输入处理备注", trigger: "blur" },
          {
            min: 5,
            max: 500,
            message: "备注长度在 5 åˆ° 500 ä¸ªå­—符",
            trigger: "blur",
          },
        ],
      },
      fileList: [],
      // æ‰¹é‡å¤„理对话框
      batchDialogVisible: false,
      batchProcessForm: {
        status: "",
        reportDepts: [],
        remark: "",
      },
    };
  },
  mounted() {
    this.loadExceptionList();
  },
  methods: {
    // åŠ è½½å¼‚å¸¸åˆ—è¡¨
    async loadExceptionList() {
      this.loading = true;
      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);
        });
      } finally {
        this.loading = false;
      }
    },
    // èŽ·å–çŠ¶æ€æ ‡ç­¾ç±»åž‹
    getStatusTagType(status) {
      switch (status) {
        case 0:
          return "warning"; // å¾…处理
        case 1:
          return "primary"; // å¤„理中
        case 2:
          return "success"; // å·²å¤„理
        default:
          return "info";
      }
    },
    // èŽ·å–çŠ¶æ€æ–‡æœ¬
    getStatusText(status) {
      switch (status) {
        case 0:
          return "待处理";
        case 1:
          return "处理中";
        case 2:
          return "已处理";
        default:
          return "未知";
      }
    },
    // å¤„理筛选
    handleFilter() {
      this.filterParams.pageNum = 1;
      this.loadExceptionList();
    },
    // é‡ç½®ç­›é€‰
    handleResetFilter() {
      this.filterParams = {
        deptId: "",
        status: "",
        pageNum: 1,
        pageSize: 10,
      };
      this.loadExceptionList();
    },
    // å¤„理选择变化
    handleSelectionChange(selection) {
      this.selectedExceptionIds = selection.map((item) => item.id);
    },
    // å¤„理批量提交
    handleBatchSubmit() {
      if (this.selectedExceptionIds.length === 0) {
        this.$message.warning("请先选择要处理的异常反馈");
        return;
      }
      this.batchDialogVisible = true;
    },
    // è¿”回异常列表
    handleGoBack() {
      this.$router.push("/satisfaction/exception/list");
    },
    // æŸ¥çœ‹è¯¦æƒ…
    handleViewDetail(row) {
      this.selectedRecordId = row.id;
      this.detailDialogTitle = `${row.patientName} - å¼‚常反馈详情`;
      this.detailDialogVisible = true;
    },
    // å¤„理详情弹框关闭
    handleDetailDialogClose() {
      this.detailDialogVisible = false;
      this.selectedRecordId = null;
    }, // å¤„理完成后的回调
    handleProcessed() {
      // é‡æ–°åŠ è½½æ•°æ®
      this.loadExceptionList();
    },
    // å¤„理单个异常
    handleProcess(row) {
      this.currentExceptionId = row.id;
      this.processForm = {
        status: row.processStatus === 0 ? 1 : row.processStatus,
        reportDepts: [],
        remark: "",
      };
      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));
            this.$message.success("处理提交成功");
            this.processDialogVisible = false;
            this.loadExceptionList();
          } finally {
            this.processing = false;
          }
        }
      });
    },
    // æäº¤æ‰¹é‡å¤„理
    async submitBatchProcess() {
      this.$refs.batchProcessForm.validate(async (valid) => {
        if (valid) {
          this.batchProcessing = true;
          try {
            // Mock API调用
            await new Promise((resolve) => setTimeout(resolve, 1500));
            this.$message.success(
              `已批量处理 ${this.selectedExceptionIds.length} æ¡å¼‚常反馈`
            );
            this.batchDialogVisible = false;
            this.selectedExceptionIds = [];
            this.loadExceptionList();
          } finally {
            this.batchProcessing = false;
          }
        }
      });
    },
    // åˆ†é¡µå¤§å°å˜åŒ–
    handleSizeChange(size) {
      this.filterParams.pageSize = size;
      this.filterParams.pageNum = 1;
      this.loadExceptionList();
    },
    // é¡µç å˜åŒ–
    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
        } ä¸ªæ–‡ä»¶`
      );
    },
  },
};
</script>
<style lang="scss" scoped>
.batch-process {
  padding: 20px;
  background-color: #f5f7fa;
  min-height: 100vh;
  .page-header {
    margin-bottom: 20px;
    padding: 20px;
    background: linear-gradient(135deg, #5788fe 0%, #66b1ff 100%);
    border-radius: 8px;
    color: white;
    .header-content {
      .page-title {
        margin: 0 0 8px 0;
        font-size: 20px;
        font-weight: 600;
      }
      .page-description {
        margin: 0 0 20px 0;
        opacity: 0.9;
        font-size: 14px;
      }
      .header-actions {
        display: flex;
        gap: 10px;
      }
    }
  }
  .list-section {
    .filter-section {
      margin-bottom: 20px;
      .filter-form {
        display: flex;
        flex-wrap: wrap;
        align-items: center;
        ::v-deep .el-form-item {
          margin-bottom: 0;
          margin-right: 20px;
          &:last-child {
            margin-right: 0;
          }
        }
      }
    }
    .exception-table {
      ::v-deep .el-table__header-wrapper {
        th {
          background-color: #f8f9fa;
          font-weight: 600;
          color: #333;
        }
      }
      .detail-content {
        font-size: 13px;
        color: #606266;
        line-height: 1.5;
        text-align: left;
      }
      .patient-info {
        .patient-item {
          display: flex;
          justify-content: space-between;
          align-items: center;
          margin-bottom: 5px;
          padding: 2px 0;
          .label {
            font-size: 12px;
            color: #606266;
            min-width: 40px;
          }
          .value {
            font-size: 13px;
            color: #333;
            font-weight: 500;
            text-align: right;
            flex: 1;
          }
        }
      }
      .discharge-info {
        .info-item {
          display: flex;
          justify-content: space-between;
          align-items: center;
          margin-bottom: 5px;
          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;
            }
          }
        }
      }
    }
    .pagination-section {
      display: flex;
      justify-content: center;
      padding: 20px 0 0 0;
    }
  }
}
@media (max-width: 768px) {
  .batch-process {
    padding: 10px;
    .page-header {
      .header-actions {
        flex-direction: column;
        align-items: stretch;
      }
    }
    .list-section {
      .filter-section {
        .filter-form {
          ::v-deep .el-form-item {
            width: 100%;
            margin-right: 0;
            margin-bottom: 10px;
          }
        }
      }
    }
  }
}
</style>