WXL
2026-01-28 bcb9976e7680ce67fadb6fec7ab5fca36552cdbc
src/views/project/DonationProcess/index.vue
@@ -28,18 +28,29 @@
          />
        </el-form-item>
        <el-form-item label="状态" prop="recordstate">
          <el-select v-model="queryParams.recordstate" placeholder="请选择状态" clearable size="small">
          <el-select
            v-model="queryParams.recordstate"
            placeholder="请选择状态"
            clearable
            size="small"
          >
            <el-option label="全部" value="" />
            <el-option label="待审核" value="0" />
            <el-option label="已审核" value="1" />
            <el-option label="维护中" value="0" />
            <el-option label="已完成" value="1" />
            <el-option label="已终止" value="99" />
          </el-select>
        </el-form-item>
        <el-form-item>
          <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery"
          <el-button
            type="primary"
            icon="el-icon-search"
            size="mini"
            @click="handleQuery"
            >搜索</el-button
          >
          <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
          <el-button icon="el-icon-refresh" size="mini" @click="resetQuery"
            >重置</el-button
          >
        </el-form-item>
      </el-form>
    </el-card>
@@ -63,7 +74,7 @@
            <div class="stat-icon">⏳</div>
            <div class="stat-info">
              <div class="stat-count">{{ stats.pendingCount }}</div>
              <div class="stat-label">待审核</div>
              维护中
            </div>
          </div>
        </el-card>
@@ -74,7 +85,7 @@
            <div class="stat-icon">✅</div>
            <div class="stat-info">
              <div class="stat-count">{{ stats.approvedCount }}</div>
              <div class="stat-label">已审核</div>
              <div class="stat-label">已完成</div>
            </div>
          </div>
        </el-card>
@@ -97,16 +108,28 @@
      v-loading="loading"
      :data="donatebaseinfoList"
      border
      :default-sort="{ prop: 'donatetime', order: 'descending' }"
      :default-sort="{ prop: 'reporttime', order: 'descending' }"
      style="width: 100%; margin-top: 20px;"
    >
      <el-table-column label="上报时间" align="center" prop="donatetime" width="110" fixed="left">
      <el-table-column
        label="上报时间"
        align="center"
        prop="reporttime"
        width="110"
        fixed="left"
      >
        <template slot-scope="scope">
          <span>{{ parseTime(scope.row.donatetime, "{y}-{m}-{d}") }}</span>
          <span>{{ parseTime(scope.row.reporttime, "{y}-{m}-{d}") }}</span>
        </template>
      </el-table-column>
      <el-table-column label="进度" align="center" prop="coreteamassessconclusion" width="100" fixed="left">
      <el-table-column
        label="捐献状态"
        align="center"
        prop="recordstate"
        width="100"
        fixed="left"
      >
        <template slot-scope="scope">
          <el-tag :type="getStatusTag(scope.row.recordstate)">
            {{ getStatusText(scope.row.recordstate) }}
@@ -118,97 +141,173 @@
      <el-table-column label="性别" align="center" prop="sex" width="80">
        <template slot-scope="scope">
          <span>{{ scope.row.sex === 1 ? '男' : '女' }}</span>
          <span>{{ scope.row.sex === "1" ? "男" : "女" }}</span>
        </template>
      </el-table-column>
      <el-table-column label="年龄" align="center" prop="age" width="80" />
      <el-table-column label="证件号码" align="center" prop="idcardno" width="180" />
      <el-table-column
        label="证件号码"
        align="center"
        prop="idcardno"
        width="180"
      />
      <el-table-column label="协调员" align="center" prop="reportername" width="100" />
      <el-table-column
        label="治疗医院"
        align="center"
        prop="treatmenthospitalname"
        width="150"
      />
      <el-table-column label="治疗医院" align="center" prop="treatmenthospitalname" width="150" show-overflow-tooltip />
      <el-table-column
        label="协调员"
        align="center"
        prop="coordinatorName"
        width="100"
      />
      <el-table-column label="转为案例时间" align="center" prop="donatetime" width="110">
        <template slot-scope="scope">
          <span>{{ parseTime(scope.row.donatetime, "{y}-{m}-{d}") }}</span>
        </template>
      </el-table-column>
      <el-table-column
        label="案例编号"
        align="center"
        prop="caseNo"
        width="120"
      />
      <!-- 第一次医学评估 -->
      <el-table-column label="第一次评估结论" align="center" prop="coreteamassessconclusion" width="120">
      <el-table-column
        label="第一次评估结论"
        align="center"
        prop="firstAssessState"
        width="120"
      >
        <template slot-scope="scope">
          <dict-tag
            :options="dict.type.sys_BaseAssessConclusion"
            :value="scope.row.coreteamassessconclusion"
            :value="scope.row.firstAssessState"
          />
        </template>
      </el-table-column>
      <el-table-column label="第一次评估时间" align="center" prop="coreteamassesstime" width="110">
      <el-table-column
        label="第一次评估时间"
        align="center"
        prop="assessFirstTime"
        width="110"
      >
        <template slot-scope="scope">
          <span>{{ parseTime(scope.row.coreteamassesstime, "{y}-{m}-{d}") }}</span>
          <span>{{ parseTime(scope.row.assessFirstTime, "{y}-{m}-{d}") }}</span>
        </template>
      </el-table-column>
      <!-- 第二次医学评估 -->
      <el-table-column label="第二次评估结论" align="center" prop="coreteamassessconclusion" width="120">
      <el-table-column
        label="第二次评估结论"
        align="center"
        prop="secondAssessState"
        width="120"
      >
        <template slot-scope="scope">
          <dict-tag
            :options="dict.type.sys_BaseAssessConclusion"
            :value="scope.row.coreteamassessconclusion"
            :value="scope.row.secondAssessState"
          />
        </template>
      </el-table-column>
      <el-table-column label="第二次评估时间" align="center" prop="coreteamassesstime" width="110">
      <el-table-column
        label="第二次评估时间"
        align="center"
        prop="assessSecondTime"
        width="110"
      >
        <template slot-scope="scope">
          <span>{{ parseTime(scope.row.coreteamassesstime, "{y}-{m}-{d}") }}</span>
          <span>{{
            parseTime(scope.row.assessSecondTime, "{y}-{m}-{d}")
          }}</span>
        </template>
      </el-table-column>
      <el-table-column label="亲属确认时间" align="center" prop="signdate" width="110">
      <el-table-column
        label="亲属确认时间"
        align="center"
        prop="signDate"
        width="110"
      >
        <template slot-scope="scope">
          <span>{{ parseTime(scope.row.signdate, "{y}-{m}-{d}") }}</span>
          <span>{{ parseTime(scope.row.signDate, "{y}-{m}-{d}") }}</span>
        </template>
      </el-table-column>
      <el-table-column label="伦理审查结论" align="center" prop="expertconclusion" width="120">
      <el-table-column
        label="伦理审查结论"
        align="center"
        prop="expertConclusion"
        width="120"
      >
        <template slot-scope="scope">
          <dict-tag
            :options="dict.type.sys_EthicalReview"
            :value="scope.row.expertconclusion"
            :value="scope.row.expertConclusion"
          />
        </template>
      </el-table-column>
      <el-table-column label="伦理审查时间" align="center" prop="conclusiontime" width="110">
      <el-table-column
        label="伦理审查时间"
        align="center"
        prop="expertTime"
        width="110"
      >
        <template slot-scope="scope">
          <span>{{ parseTime(scope.row.conclusiontime, "{y}-{m}-{d}") }}</span>
          <span>{{ parseTime(scope.row.expertTime, "{y}-{m}-{d}") }}</span>
        </template>
      </el-table-column>
      <el-table-column label="器官分配数量" align="center" prop="organcount" width="100" />
      <el-table-column
        label="器官分配数量"
        align="center"
        prop="organCount"
        width="100"
      />
      <el-table-column label="获取见证时间" align="center" prop="operationbegtime" width="110">
      <el-table-column
        label="获取见证时间"
        align="center"
        prop="operationBegTime"
        width="110"
      >
        <template slot-scope="scope">
          <span>{{ parseTime(scope.row.operationbegtime, "{y}-{m}-{d}") }}</span>
          <span>{{
            parseTime(scope.row.operationBegTime, "{y}-{m}-{d}")
          }}</span>
        </template>
      </el-table-column>
      <el-table-column label="完成登记时间" align="center" prop="completetime" width="110">
      <el-table-column
        label="完成登记时间"
        align="center"
        prop="completeTime"
        width="110"
      >
        <template slot-scope="scope">
          <span>{{ parseTime(scope.row.completetime, "{y}-{m}-{d}") }}</span>
          <span>{{ parseTime(scope.row.completeTime, "{y}-{m}-{d}") }}</span>
        </template>
      </el-table-column>
      <el-table-column label="捐献进度" align="center" prop="workflow" width="120" fixed="right">
      <!-- 捐献进度列 -->
      <el-table-column
        label="捐献进度"
        align="center"
        prop="recordstate"
        width="120"
      >
        <template slot-scope="scope">
          <div v-if="!scope.row.terminationCase">
          <div v-if="scope.row.terminationCase == 0">
            <dict-tag
              :options="dict.type.sys_donornode"
              :value="scope.row.workflow"
              :value="scope.row.recordstate"
            />
          </div>
          <div v-else>
@@ -217,23 +316,24 @@
        </template>
      </el-table-column>
      <!-- <el-table-column label="操作" align="center" width="120" fixed="right">
      <!-- 操作列:只保留终止和查看详情 -->
      <el-table-column label="操作" align="center" width="150" fixed="right">
        <template slot-scope="scope">
          <el-button size="mini" type="text" @click="handleDetail(scope.row)"
            >查看详情</el-button
          >
          <el-button
            size="mini"
            type="text"
            icon="el-icon-view"
            @click="handleDetail(scope.row)"
          >详情</el-button>
          <el-button
            v-if="scope.row.recordstate == 0"
            size="mini"
            type="text"
            icon="el-icon-check"
            @click="handleApprove(scope.row)"
          >审核</el-button>
            style="color: #f56c6c;"
            @click="handleTerminate(scope.row)"
            v-if="
              scope.row.terminationCase === 0 && scope.row.recordstate !== '99'
            "
            >终止</el-button
          >
        </template>
      </el-table-column> -->
      </el-table-column>
    </el-table>
    <pagination
@@ -246,7 +346,7 @@
    <!-- 详情弹框 -->
    <el-dialog
      :title="`捐献者详情 - ${currentRecord.name}`"
      :title="`捐献者详情 - ${currentRecord.name || ''}`"
      :visible.sync="detailVisible"
      width="1000px"
      append-to-body
@@ -254,40 +354,32 @@
      <donor-detail :donorData="currentRecord" @close="detailVisible = false" />
    </el-dialog>
    <!-- 审核弹框 -->
    <!-- 终止确认弹框 -->
    <el-dialog
      title="捐献者审核"
      :visible.sync="approveVisible"
      width="500px"
      title="终止确认"
      :visible.sync="terminateVisible"
      width="400px"
      append-to-body
    >
      <el-form ref="approveForm" :model="approveForm" label-width="100px">
        <el-form-item label="审核结果">
          <el-radio-group v-model="approveForm.approveResult">
            <el-radio label="1">通过</el-radio>
            <el-radio label="2">驳回</el-radio>
          </el-radio-group>
        </el-form-item>
        <el-form-item label="审核意见">
          <el-input
            type="textarea"
            v-model="approveForm.approveOpinion"
            placeholder="请输入审核意见"
            :rows="4"
          />
        </el-form-item>
      </el-form>
      <div style="margin-bottom: 20px;">
        <p>
          确定要终止捐献者
          <strong>{{ currentRecord.name }}</strong> 的捐献进程吗?
        </p>
        <p style="color: #f56c6c; font-size: 12px;">
          此操作不可逆,请谨慎操作!
        </p>
      </div>
      <div slot="footer">
        <el-button @click="approveVisible = false">取消</el-button>
        <el-button type="primary" @click="submitApprove">确定</el-button>
        <el-button @click="terminateVisible = false">取消</el-button>
        <el-button type="danger" @click="submitTerminate">确认终止</el-button>
      </div>
    </el-dialog>
  </div>
</template>
<script>
// 导入模拟数据生成工具
import Mock from 'mockjs';
import { courselist, terminateDonor } from "@/api/businessApi";
export default {
  name: "Donatebaseinfo",
@@ -304,8 +396,8 @@
      donatebaseinfoList: [],
      // 详情弹框显示
      detailVisible: false,
      // 审核弹框显示
      approveVisible: false,
      // 终止确认弹框显示
      terminateVisible: false,
      // 当前操作记录
      currentRecord: {},
      // 统计数据
@@ -322,11 +414,6 @@
        name: undefined,
        idcardno: undefined,
        recordstate: undefined
      },
      // 审核表单
      approveForm: {
        approveResult: "1",
        approveOpinion: ""
      }
    };
  },
@@ -334,111 +421,127 @@
    this.getList();
  },
  methods: {
    /** 生成模拟数据 */
    generateMockData() {
      const mockTemplate = {
        'list|15-30': [{
          'id|+1': 1001,
          'name': '@cname',
          'sex|1': [1, 2], // 1:男, 2:女
          'age|18-65': 1,
          'idcardno': /^[1-9]\d{5}(19|20)\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])\d{3}[\dX]$/,
          'reportername': '@cname',
          'treatmenthospitalname': '@ctitle(3, 5)医院',
          'donatetime': '@datetime("yyyy-MM-dd HH:mm:ss")',
          'coreteamassessconclusion|1': ['1', '2', '3'], // 评估结论
          'coreteamassesstime': '@datetime("yyyy-MM-dd HH:mm:ss")',
          'signdate': '@datetime("yyyy-MM-dd HH:mm:ss")',
          'expertconclusion|1': ['1', '2', '3'], // 伦理审查结论
          'conclusiontime': '@datetime("yyyy-MM-dd HH:mm:ss")',
          'organcount|0-5': 1,
          'operationbegtime': '@datetime("yyyy-MM-dd HH:mm:ss")',
          'completetime': '@datetime("yyyy-MM-dd HH:mm:ss")',
          'workflow|1': ['1', '2', '3', '4', '5'], // 工作流状态
          'recordstate|1': ['0', '1', '99'], // 0:待审核, 1:已审核, 99:已终止
          'terminationCase|1': [true, false]
        }]
      };
      return Mock.mock(mockTemplate).list;
    },
    /** 查询捐献基础列表 */
    getList() {
    async getList() {
      this.loading = true;
      try {
        const response = await courselist(this.queryParams);
      // 模拟API调用延迟
      setTimeout(() => {
        // 生成模拟数据
        const mockData = this.generateMockData();
        // 根据实际接口返回结构调整
        let realData = [];
        realData = response.data.donatebaseinfoProgressDTOS;
        this.total = response.total;
        this.stats.pendingCount = response.data.terminationCase[0];
        this.stats.approvedCount = response.data.terminationCase[1];
        this.stats.terminatedCount = response.data.terminationCase[2];
        this.stats.totalCount = response.total;
        // 存储所有数据用于前端筛选和分页
        this.allTableData = realData;
        // 应用筛选条件
        let filteredData = mockData;
        if (this.queryParams.name) {
          filteredData = filteredData.filter(item =>
            item.name.includes(this.queryParams.name)
          );
        }
        if (this.queryParams.idcardno) {
          filteredData = filteredData.filter(item =>
            item.idcardno.includes(this.queryParams.idcardno)
          );
        }
        if (this.queryParams.recordstate) {
          filteredData = filteredData.filter(item =>
            item.recordstate === this.queryParams.recordstate
          );
        }
        // 应用前端筛选条件(如果接口不支持后端筛选)
        let filteredData = this.applyFrontendFilter(realData);
        // 分页处理
        const startIndex = (this.queryParams.pageNum - 1) * this.queryParams.pageSize;
        const endIndex = startIndex + this.queryParams.pageSize;
        this.donatebaseinfoList = filteredData.slice(startIndex, endIndex);
        this.total = filteredData.length;
        // 前端分页处理(如果接口不支持后端分页)
        if (!response.total && !response.data) {
          const startIndex =
            (this.queryParams.pageNum - 1) * this.queryParams.pageSize;
          const endIndex = startIndex + this.queryParams.pageSize;
          this.donatebaseinfoList = filteredData.slice(startIndex, endIndex);
          this.total = filteredData.length;
        } else {
          // 接口已分页,直接使用返回数据
          this.donatebaseinfoList = filteredData;
        }
        // 更新统计数据
        this.updateStats(mockData);
        // this.updateStats(realData);
      } catch (error) {
        console.error("获取数据失败:", error);
        this.$message.error("数据加载失败");
        this.donatebaseinfoList = [];
        this.total = 0;
        // this.updateStats([]);
      } finally {
        this.loading = false;
      }, 500);
      }
    },
    /** 应用前端筛选 */
    applyFrontendFilter(data) {
      let filteredData = data;
      if (this.queryParams.name) {
        filteredData = filteredData.filter(
          item => item.name && item.name.includes(this.queryParams.name)
        );
      }
      if (this.queryParams.idcardno) {
        filteredData = filteredData.filter(
          item =>
            item.idcardno && item.idcardno.includes(this.queryParams.idcardno)
        );
      }
      if (this.queryParams.recordstate) {
        filteredData = filteredData.filter(
          item => item.recordstate === this.queryParams.recordstate
        );
      }
      return filteredData;
    },
    /** 更新统计数据 */
    updateStats(data) {
      this.stats.totalCount = data.length;
      this.stats.pendingCount = data.filter(item => item.recordstate === '0').length;
      this.stats.approvedCount = data.filter(item => item.recordstate === '1').length;
      this.stats.terminatedCount = data.filter(item => item.recordstate === '99').length;
      this.stats.pendingCount = data.filter(
        item => item.recordstate === "0" || item.recordstate === 0
      ).length;
      this.stats.approvedCount = data.filter(
        item => item.recordstate === "1" || item.recordstate === 1
      ).length;
      this.stats.terminatedCount = data.filter(
        item => item.recordstate === "99" || item.recordstate === 99
      ).length;
    },
    /** 获取状态标签样式 */
    getStatusTag(status) {
      const statusMap = {
        '0': 'warning',  // 待审核
        '1': 'success',  // 已审核
        '99': 'danger'   // 已终止
        "0": "warning", // 维护中
        "1": "success", // 已完成
        "99": "danger" // 已终止
      };
      return statusMap[status] || 'info';
      return statusMap[status] || "info";
    },
    /** 获取状态文本 */
    getStatusText(status) {
      const textMap = {
        '0': '待审核',
        '1': '已审核',
        '99': '已终止'
        "0": "维护中",
        "1": "已完成",
        "99": "已终止"
      };
      return textMap[status] || '未知状态';
      return textMap[status] || "未知状态";
    },
    /** 时间格式化 */
    parseTime(time, format) {
      if (!time) return '-';
      const date = new Date(time);
      const year = date.getFullYear();
      const month = (date.getMonth() + 1).toString().padStart(2, '0');
      const day = date.getDate().toString().padStart(2, '0');
      if (!time) return "-";
      if (format === '{y}-{m}-{d}') {
      // 处理时间戳和日期字符串
      const date = new Date(time);
      if (isNaN(date.getTime())) return time;
      const year = date.getFullYear();
      const month = (date.getMonth() + 1).toString().padStart(2, "0");
      const day = date
        .getDate()
        .toString()
        .padStart(2, "0");
      if (format === "{y}-{m}-{d}") {
        return `${year}-${month}-${day}`;
      }
      return time;
@@ -452,13 +555,8 @@
    /** 重置按钮操作 */
    resetQuery() {
      this.queryParams = {
        pageNum: 1,
        pageSize: 10,
        name: undefined,
        idcardno: undefined,
        recordstate: undefined
      };
      this.$refs.queryForm.resetFields();
      this.queryParams.pageNum = 1;
      this.getList();
    },
@@ -468,25 +566,28 @@
      this.detailVisible = true;
    },
    /** 审核操作 */
    handleApprove(row) {
    /** 终止操作 */
    handleTerminate(row) {
      this.currentRecord = { ...row };
      this.approveForm = {
        approveResult: "1",
        approveOpinion: ""
      };
      this.approveVisible = true;
      this.terminateVisible = true;
    },
    /** 提交审核 */
    submitApprove() {
      // 模拟审核提交
      const index = this.donatebaseinfoList.findIndex(item => item.id === this.currentRecord.id);
      if (index !== -1) {
        this.donatebaseinfoList[index].recordstate = this.approveForm.approveResult;
        this.$message.success('审核成功');
        this.approveVisible = false;
        this.getList(); // 重新加载更新统计
    /** 提交终止 */
    async submitTerminate() {
      try {
        // 调用终止接口
        await terminateDonor({
          id: this.currentRecord.id,
          caseNo: this.currentRecord.caseNo,
          terminationReason: "管理员手动终止"
        });
        this.$message.success("终止成功");
        this.terminateVisible = false;
        this.getList(); // 重新加载更新数据
      } catch (error) {
        this.$message.error("终止失败");
        console.error("终止错误:", error);
      }
    }
  }
@@ -512,19 +613,19 @@
}
.stats-card.total {
  border-left: 4px solid #409EFF;
  border-left: 4px solid #409eff;
}
.stats-card.pending {
  border-left: 4px solid #E6A23C;
  border-left: 4px solid #e6a23c;
}
.stats-card.approved {
  border-left: 4px solid #67C23A;
  border-left: 4px solid #67c23a;
}
.stats-card.terminated {
  border-left: 4px solid #F56C6C;
  border-left: 4px solid #f56c6c;
}
.stat-content {
@@ -563,4 +664,9 @@
  background-color: #f5f7fa;
  font-weight: bold;
}
/* 操作按钮样式 */
::v-deep .el-button--text {
  padding: 4px 8px;
}
</style>