WXL
2026-04-25 996206735df06887e3f3e453797b1289a2a793e7
青岛维护
已修改11个文件
934 ■■■■ 文件已修改
src/api/businessApi/ethicalReview.js 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/business/GetWitness/GetWitnessInfo.vue 104 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/business/affirm/index.vue 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/business/allocation/allocationInfo.vue 168 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/business/allocation/index.vue 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/business/assess/index.vue 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/business/ethicalReview/ethicalReviewInfo.vue 617 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/business/ethicalReview/index.vue 13 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/business/maintain/index.vue 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/project/DonationProcess/index.vue 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/project/donatebaseinfo/index.vue 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/businessApi/ethicalReview.js
@@ -25,9 +25,9 @@
  })
}
// 死亡信息详情
export function ethicalinfoInfo(id) {
export function ethicalreviewInfo(id) {
  return request({
    url: '/project/deathinfo/getInfo/' + id,
    url: '/project/ethicalreviewinitiate/getInfo/' + id,
    method: 'get'
  })
}
src/views/business/GetWitness/GetWitnessInfo.vue
@@ -1,5 +1,7 @@
<template>
  <div class="organ-procurement-detail">
    <case-basic-info :case-id="caseId" :show-attachment="true" />
    <!-- 基本信息 -->
    <el-card class="detail-card">
      <div slot="header" class="clearfix">
@@ -20,100 +22,6 @@
      </div>
      <el-form :model="form" ref="form" :rules="rules" label-width="120px">
        <el-row :gutter="20">
          <el-col :span="8">
            <el-form-item label="住院号" prop="inpatientno">
              <el-input v-model="form.inpatientno" readonly />
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="案例编号" prop="caseNo">
              <el-input v-model="form.caseNo" />
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="捐献者姓名" prop="name">
              <el-input v-model="form.name" />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="20">
          <el-col :span="8">
            <el-form-item label="性别" prop="sex">
              <el-select v-model="form.sex" style="width: 100%">
                <el-option label="男" value="0" />
                <el-option label="女" value="1" />
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="年龄" prop="age">
              <el-input v-model="form.age" />
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="捐献类别" prop="donationcategory">
              <el-select v-model="form.donationcategory" style="width: 100%">
                <el-option
                  v-for="dict in dict.type.sys_DonationCategory || []"
                  :key="dict.value"
                  :label="dict.label"
                  :value="dict.value"
                />
              </el-select>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="20">
          <el-col :span="8">
            <el-form-item label="血型" prop="bloodtype">
              <el-select v-model="form.bloodtype" style="width: 100%">
                <el-option
                  v-for="dict in dict.type.sys_BloodType || []"
                  :key="dict.value"
                  :label="dict.label"
                  :value="dict.value"
                />
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="证件号码" prop="idcardno">
              <el-input v-model="form.idcardno" />
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="记录状态" prop="recordstate">
              <el-input v-model="form.recordstate" />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="疾病诊断" prop="diagnosisname">
              <el-input
                type="textarea"
                :rows="2"
                v-model="form.diagnosisname"
                placeholder="请输入疾病诊断信息"
              />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="死亡时间" prop="deathtime">
              <el-date-picker
                v-model="form.deathtime"
                type="datetime"
                value-format="yyyy-MM-dd HH:mm:ss"
                style="width: 100%"
                :disabled="form.recordstate === 'completed'"
              />
            </el-form-item>
          </el-col>
        </el-row>
        <!-- 手术相关信息 -->
        <el-divider content-position="left">手术信息</el-divider>
@@ -878,18 +786,20 @@
</template>
<script>
import { witnessList, witnessadd, witnessedit } from "@/api/businessApi";
import { witnessList, witnessadd, witnessedit, } from "@/api/businessApi";
import UploadAttachment from "@/components/UploadAttachment";
import CaseBasicInfo from "@/components/CaseBasicInfo";
import dayjs from "dayjs";
export default {
  name: "OrganProcurementDetail",
  components: {
    UploadAttachment
    UploadAttachment,CaseBasicInfo
  },
  dicts: ["sys_BloodType", "sys_DonationCategory", "sys_Organ"],
  data() {
    return {
      caseId: null,
      // 表单数据
      form: {
        id: undefined,
@@ -1041,6 +951,8 @@
    }
  },
  created() {
    this.caseId = this.$route.query.infoid;
    this.initData();
  },
  methods: {
src/views/business/affirm/index.vue
@@ -109,7 +109,6 @@
        v-loading="loading"
        :data="confirmationList"
        @selection-change="handleSelectionChange"
        @row-click="handleRowClick"
      >
        <el-table-column type="selection" width="55" align="center" />
        <el-table-column
src/views/business/allocation/allocationInfo.vue
@@ -1,5 +1,6 @@
<template>
  <div class="organ-allocation-detail">
    <case-basic-info :case-id="caseId" :show-attachment="true" />
    <!-- 基本信息部分 -->
    <el-card class="detail-card">
      <div slot="header" class="clearfix">
@@ -21,85 +22,19 @@
      <el-form :model="form" ref="form" :rules="rules" label-width="120px">
        <el-row :gutter="20">
          <el-col :span="8">
            <el-form-item label="住院号" prop="donorno">
              <el-input v-model="form.donorno" readonly />
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="案例编号" prop="caseNo">
              <el-input v-model="form.caseNo" />
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="捐献者姓名" prop="name">
              <el-input v-model="form.name" />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="20">
          <el-col :span="8">
            <el-form-item label="性别" prop="sex">
              <el-select v-model="form.sex" style="width: 100%">
                <el-option label="男" value="0" />
                <el-option label="女" value="1" />
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="年龄" prop="age">
              <el-input v-model="form.age" />
            </el-form-item>
          </el-col>
          <!-- <el-col :span="8">
            <el-form-item label="捐献类别" prop="donationcategory">
              <el-select v-model="form.donationcategory" style="width: 100%">
                <el-option
                  v-for="dict in dict.type.sys_DonationCategory || []"
                  :key="dict.value"
                  :label="dict.label"
                  :value="dict.value"
                />
              </el-select>
            </el-form-item>
          </el-col> -->
        </el-row>
        <el-row :gutter="20">
          <el-col :span="8">
            <el-form-item label="血型" prop="bloodtype">
              <el-select v-model="form.bloodtype" style="width: 100%">
                <el-option
                  v-for="dict in dict.type.sys_BloodType || []"
                  :key="dict.value"
                  :label="dict.label"
                  :value="dict.value"
                />
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="证件号码" prop="idcardno">
              <el-input v-model="form.idcardno" />
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="记录状态" prop="recordstate">
              <el-input v-model="form.recordstate" />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="疾病诊断" prop="diagnosisname">
              <el-input
                type="textarea"
                :rows="2"
                v-model="form.diagnosisname"
                placeholder="请输入疾病诊断信息"
              />
            <el-form-item label="分配状态" prop="allocationStatus">
              <el-select
                v-model="form.allocationStatus"
                placeholder="请选择分配状态"
              >
                <el-option
                  v-for="dict in dict.type.organ_allocation_status || []"
                  :key="dict.value"
                  :label="dict.label"
                  :value="dict.value"
                ></el-option>
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="12">
@@ -117,27 +52,8 @@
        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="所在医疗机构" prop="treatmenthospitalname">
              <el-input
                v-model="form.treatmenthospitalname"
                placeholder="请输入医疗机构名称"
              />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="医疗机构编码" prop="treatmenthospitalno">
              <el-input
                v-model="form.treatmenthospitalno"
                placeholder="请输入医疗机构编码"
              />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="登记人" prop="registrationName">
              <el-input v-model="form.registrationName" readonly />
              <el-input v-model="form.registrationName" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
@@ -147,7 +63,6 @@
                type="datetime"
                value-format="yyyy-MM-dd HH:mm:ss"
                style="width: 100%"
                readonly
              />
            </el-form-item>
          </el-col>
@@ -410,7 +325,7 @@
        </div>
      </el-form>
      <div class="dialog-footer" v-if="form.allocationStatus !== '1'">
      <!-- <div class="dialog-footer" v-if="form.allocationStatus !== '1'">
        <el-button
          type="primary"
          @click="handleSaveAllocation"
@@ -430,7 +345,7 @@
        >
          确认完成分配
        </el-button>
      </div>
      </div> -->
    </el-card>
    <!-- 附件管理部分优化 -->
@@ -543,8 +458,6 @@
      </div>
    </el-dialog>
    <!-- 附件预览对话框 -->
    <FilePreviewDialog
      :visible="filePreviewVisible"
@@ -559,12 +472,13 @@
import {
  allocationList,
  allocationadd,
  allocationedit
  allocationedit,
  donateorganBaseinfoInfo
} from "@/api/businessApi";
import UploadAttachment from "@/components/UploadAttachment";
import FilePreviewDialog from "@/components/FilePreviewDialog";
import OrgSelecter from "@/views/project/components/orgselect";
import CaseBasicInfo from "@/components/CaseBasicInfo";
import dayjs from "dayjs";
export default {
@@ -572,16 +486,20 @@
  components: {
    UploadAttachment,
    OrgSelecter,
    FilePreviewDialog
    FilePreviewDialog,
    CaseBasicInfo
  },
  dicts: [
    "sys_BloodType",
    "sys_DonationCategory",
    "sys_RecordState",
    "sys_Organ"
    "sys_Organ",
    "organ_allocation_status"
  ],
  data() {
    return {
      caseId: null,
      // 表单数据
      form: {
        id: undefined,
@@ -721,6 +639,7 @@
    }
  },
  created() {
    this.caseId = this.$route.query.infoid;
    this.initData();
  },
  methods: {
@@ -749,7 +668,7 @@
        .substring(0, 19);
      if (infoid) {
        this.getDetail(infoid);
        this.getDetail(infoid, id);
      } else {
        this.generateDonorNo();
      }
@@ -762,9 +681,25 @@
      this.form.donorno = "D" + timestamp.slice(-8);
      this.form.caseNo = "CASE" + timestamp.slice(-6);
    },
    // 解析 filePatch 字段
    parseFilePatch(filePatch) {
      if (!filePatch) {
        this.form.attachments = [];
        return;
      }
      try {
        this.form.attachments = JSON.parse(filePatch);
      } catch (error) {
        console.error("解析 filePatch 字段失败:", error);
        this.form.attachments = [];
      }
    },
    // 获取详情
    async getDetail(infoid) {
    async getDetail(infoid, id) {
      this.loading = true;
      donateorganBaseinfoInfo(id);
      try {
        const response = await allocationList({ infoid });
        if (
@@ -776,6 +711,8 @@
          // 填充表单数据
          Object.assign(this.form, data);
          // 转换附件为集合
            this.parseFilePatch(this.form.fileName);
          // 初始化附件
          if (this.form.attachments) {
@@ -1003,6 +940,13 @@
      }
      return "";
    },
    // 构建 filePatch 字段
    buildFilePatch() {
      if (!this.attachments || this.attachments.length === 0) {
        return "";
      }
      return JSON.stringify(this.attachments);
    },
    // 保存基本信息
    async handleSave() {
      this.$refs.form.validate(async valid => {
@@ -1015,10 +959,14 @@
        try {
          const saveData = {
            ...this.form,
            attachments: this.attachments,
            serviceDonateorganList:
              this.allocationData.serviceDonateorganList || []
          };
          saveData.fileName=this.buildFilePatch();
          saveData.serviceDonateorganList.forEach(item => {
            item.baseid = this.form.id;
            item.infoid = this.form.infoid;
          });
          console.log(this.form.recordstate);
          this.form.recordstate = 1;
          const apiMethod = this.form.id ? allocationedit : allocationadd;
src/views/business/allocation/index.vue
@@ -44,7 +44,7 @@
          >
            <el-option label="全部" value="" />
            <el-option
              v-for="dict in dict.type.allocation_Status"
              v-for="dict in dict.type.organ_allocation_status"
              :key="dict.value"
              :label="dict.label"
              :value="dict.value"
@@ -171,7 +171,7 @@
        >
          <template slot-scope="scope">
            <dict-tag
              :options="dict.type.allocation_Status"
              :options="dict.type.organ_allocation_status"
              :value="scope.row.allocationStatus"
            />
          </template>
@@ -182,13 +182,6 @@
          prop="allocationTime"
          width="160"
        >
          <template slot-scope="scope">
            <span>{{
              scope.row.allocationTime
                ? parseTime(scope.row.allocationTime, "{y}-{m}-{d} {h}:{i}")
                : "-"
            }}</span>
          </template>
        </el-table-column>
        <el-table-column
          label="登记人"
src/views/business/assess/index.vue
@@ -121,7 +121,6 @@
        v-loading="loading"
        :data="assessmentList"
        @selection-change="handleSelectionChange"
        @row-click="handleRowClick"
      >
        <el-table-column type="selection" width="55" align="center" />
        <el-table-column
src/views/business/ethicalReview/ethicalReviewInfo.vue
@@ -28,7 +28,6 @@
              <el-input
                v-model="form.initiateTheme"
                placeholder="请输入发起主题"
              />
            </el-form-item>
          </el-col>
@@ -37,20 +36,18 @@
              <el-input v-model="form.initiatePerson"  />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="20">
          <el-col :span="8">
            <el-form-item label="审查状态" prop="status">
              <el-select
                v-model="form.status"
                style="width: 100%"
              >
                <el-option label="新建" value="0" />
                <el-option label="审查中" value="1" />
                <el-option label="结束" value="2" />
              <el-select v-model="form.status" style="width: 100%">
                <el-option
                  v-for="dict in dict.type.sys_ethical"
                  :key="dict.value"
                  :label="dict.label"
                  :value="dict.value"
                />
              </el-select>
            </el-form-item>
          </el-col>
@@ -61,7 +58,6 @@
                type="datetime"
                value-format="yyyy-MM-dd HH:mm:ss"
                style="width: 100%"
              />
            </el-form-item>
          </el-col>
@@ -72,7 +68,6 @@
                type="datetime"
                value-format="yyyy-MM-dd HH:mm:ss"
                style="width: 100%"
              >
              </el-date-picker>
            </el-form-item>
@@ -93,11 +88,7 @@
          </el-col>
          <el-col :span="8">
            <el-form-item label="专家类型" prop="expertType">
              <el-select
                v-model="form.expertType"
                style="width: 100%"
              >
              <el-select v-model="form.expertType" style="width: 100%">
                <el-option label="普通专家" value="normal" />
                <el-option label="主委专家" value="chief" />
              </el-select>
@@ -108,12 +99,9 @@
        <el-row :gutter="20">
          <el-col :span="8">
            <el-form-item label="专家结论" prop="expertConclusion">
              <el-select
                v-model="form.expertConclusion"
                style="width: 100%"
              >
              <el-select v-model="form.expertConclusion" style="width: 100%">
                <el-option label="同意" value="1" />
                <el-option label="审查中" value="2" />
                <el-option label="不同意" value="0" />
              </el-select>
            </el-form-item>
@@ -125,7 +113,6 @@
                type="datetime"
                value-format="yyyy-MM-dd HH:mm:ss"
                style="width: 100%"
              />
            </el-form-item>
          </el-col>
@@ -136,7 +123,6 @@
                :min="1"
                :max="20"
                style="width: 100%"
              />
            </el-form-item>
          </el-col>
@@ -150,7 +136,6 @@
                :rows="2"
                v-model="form.expertOpinion"
                placeholder="请输入专家意见"
              />
            </el-form-item>
          </el-col>
@@ -164,12 +149,10 @@
                :rows="3"
                v-model="form.remark"
                placeholder="请输入备注信息"
              />
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>
    </el-card>
@@ -177,67 +160,90 @@
    <el-card class="attachment-card">
      <div slot="header" class="clearfix">
        <span class="detail-title">相关附件</span>
        <el-button type="primary" size="mini" @click="handleUploadAttachment">
        <!-- <el-button type="primary" size="mini" @click="openUploadDialog">
          上传附件
        </el-button>
        </el-button> -->
      </div>
      <el-table :data="attachments" style="width: 100%">
        <el-table-column label="文件名称" min-width="200">
      <!-- 使用 UploadAttachment 组件 -->
      <UploadAttachment
        ref="uploadAttachment"
        :file-list="attachmentFileList"
        :limit="10"
        accept=".pdf,.jpg,.jpeg,.png,.doc,.docx,.xls,.xlsx"
        @change="handleAttachmentChange"
        @upload-success="handleUploadSuccess"
        @upload-error="handleUploadError"
        @remove="handleAttachmentRemove"
      />
      <!-- 附件列表 -->
      <div
        class="attachment-list"
        v-if="form.annexfilesList && form.annexfilesList.length > 0"
      >
        <div class="list-title">
          已上传附件 ({{ form.annexfilesList.length }})
        </div>
        <el-table
          :data="form.annexfilesList"
          style="width: 100%"
          size="small"
        >
          <el-table-column label="文件名" min-width="200">
          <template slot-scope="scope">
            <div class="file-info">
              <i
                class="el-icon-document"
                style="margin-right: 8px; color: #409EFF;"
              ></i>
              <span>{{ scope.row.fileName }}</span>
            </div>
              <span class="file-name">{{ scope.row.fileName }}</span>
          </template>
        </el-table-column>
        <el-table-column label="文件类型" width="100" align="center">
          <el-table-column label="文件类型" width="100">
          <template slot-scope="scope">
            <el-tag size="small">{{ getFileType(scope.row.fileName) }}</el-tag>
              <el-tag size="small">{{
                getFileType(scope.row.fileName)
              }}</el-tag>
          </template>
        </el-table-column>
        <el-table-column label="文件大小" width="100" align="center">
          <el-table-column label="创建时间" width="160">
          <template slot-scope="scope">
            <span>{{ formatFileSize(scope.row.fileSize) }}</span>
              <span>{{ formatDateTime(scope.row.createTime) }}</span>
          </template>
        </el-table-column>
        <el-table-column label="上传时间" width="160" align="center">
          <template slot-scope="scope">
            <span>{{ parseTime(scope.row.uploadTime) }}</span>
          </template>
        </el-table-column>
        <el-table-column label="上传人" width="100" align="center">
          <template slot-scope="scope">
            <span>{{ scope.row.uploader }}</span>
          </template>
        </el-table-column>
        <el-table-column label="操作" width="120" align="center">
          <el-table-column label="操作" width="266">
          <template slot-scope="scope">
            <el-button
              size="mini"
              type="text"
              icon="el-icon-view"
              @click="handlePreviewAttachment(scope.row)"
              >预览</el-button
                type="primary"
                @click="handlePreview(scope.row)"
            >
                预览
              </el-button>
            <el-button
              size="mini"
              type="text"
              icon="el-icon-download"
              @click="handleDownloadAttachment(scope.row)"
              >下载</el-button
                type="success"
                @click="handleDownload(scope.row)"
            >
                下载
              </el-button>
              <el-button
                size="mini"
                type="danger"
                @click="handleRemoveAttachment(scope.$index)"
              >
                删除
              </el-button>
          </template>
        </el-table-column>
      </el-table>
      </div>
      <!-- 空状态 -->
      <div v-if="!form.annexfilesList || form.annexfilesList.length === 0" class="empty-attachment">
        <i class="el-icon-folder-opened" style="font-size: 60px; color: #C0C4CC; margin-bottom: 20px;"></i>
        <p style="color: #909399; font-size: 14px;">暂无附件,请上传相关文件</p>
      </div>
    </el-card>
    <!-- 专家审查情况 -->
@@ -472,45 +478,13 @@
      </div>
    </el-dialog>
    <!-- 上传附件对话框 -->
    <el-dialog
      title="上传附件"
      :visible.sync="uploadDialogVisible"
      width="500px"
      :close-on-click-modal="false"
    >
      <el-upload
        ref="uploadRef"
        class="upload-demo"
        drag
        :action="uploadAction"
        :headers="headers"
        multiple
        :file-list="tempFileList"
        :before-upload="beforeUpload"
        :on-change="handleFileChange"
        :on-remove="handleTempRemove"
        :on-success="handleUploadSuccess"
        :auto-upload="false"
      >
        <i class="el-icon-upload"></i>
        <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
        <div class="el-upload__tip" slot="tip">
          支持上传pdf、jpg、png、doc、docx、xls、xlsx格式文件,单个文件不超过10MB
        </div>
      </el-upload>
      <div slot="footer" class="dialog-footer">
        <el-button @click="uploadDialogVisible = false">取消</el-button>
        <el-button
          type="primary"
          @click="submitUpload"
          :loading="uploadLoading"
          :disabled="tempFileList.length === 0"
        >
          确认上传
        </el-button>
      </div>
    </el-dialog>
    <!-- 文件预览弹窗 -->
    <FilePreviewDialog
      :visible="previewVisible"
      :file="currentPreviewFile"
      @close="previewVisible = false"
      @download="handleDownload"
    />
  </div>
</template>
@@ -519,13 +493,18 @@
import {
  reviewinitiateBaseInfoList,
  ethicalreviewedit,
  ethicalreviewadd
  ethicalreviewadd,
  ethicalreviewInfo
} from "@/api/businessApi";
import CaseBasicInfo from "@/components/CaseBasicInfo";
import UploadAttachment from "@/components/UploadAttachment";
import FilePreviewDialog from "@/components/FilePreviewDialog";
import dayjs from "dayjs";
export default {
  name: "EthicsReviewDetail",
  components: { CaseBasicInfo },
  components: { CaseBasicInfo, UploadAttachment, FilePreviewDialog },
  dicts: ["sys_user_sex", "sys_ethical"],
  data() {
    return {
@@ -533,6 +512,7 @@
      isEdit: false,
      // 基本信息
      infoid: undefined,
      id: undefined,
      caseId: null,
      caseNo: "",
@@ -563,6 +543,10 @@
        // 备注
        remark: "",
        // 附件信息
        annexfilesList: [],
        filePatch: "",
        // 系统字段
        createBy: "",
        createTime: "",
@@ -574,7 +558,12 @@
     rules: {
  initiateTheme: [
    { required: true, message: "发起主题不能为空", trigger: "blur" },
    { min: 2, max: 100, message: "长度在 2 到 100 个字符", trigger: "blur" }
          {
            min: 2,
            max: 100,
            message: "长度在 2 到 100 个字符",
            trigger: "blur"
          }
  ],
  initiatePerson: [
    { required: true, message: "发起人不能为空", trigger: "blur" }
@@ -604,8 +593,13 @@
      // 保存加载状态
      saveLoading: false,
      // 附件数据
      attachments: [],
      // 附件相关
      attachmentFileList: [],
      // 预览相关
      previewVisible: false,
      currentPreviewFile: null,
      // 专家审查数据
      expertReviews: [
        // 专家(18位)- 初始状态为申请中
@@ -812,15 +806,6 @@
        content: ""
      },
      // 上传相关
      uploadDialogVisible: false,
      uploadLoading: false,
      tempFileList: [],
      uploadAction: process.env.VUE_APP_BASE_API + "/common/upload",
      headers: {
        Authorization: "Bearer " + getToken()
      },
      // 可用专家列表
      availableExperts: [
        { id: 1, name: "陶昊", type: "normal" },
@@ -919,15 +904,9 @@
  },
  created() {
    this.infoid = this.$route.query.infoid;
    this.id = this.$route.query.id;
    this.caseId = this.$route.query.infoid;
    // const id = this.$route.query.id;
    this.getDetail(this.infoid);
    // if (id && !this.$route.path.includes("/add")) {
    //   this.getDetail(this.infoid);
    // } else if (this.$route.path.includes("/add") && this.infoid) {
    //   this.initNewData();
    // }
    this.getDetail(this.infoid, this.id);
  },
  methods: {
    // 初始化新增数据
@@ -943,16 +922,29 @@
    },
    // 获取详情
    async getDetail(infoid) {
    async getDetail(infoid, id) {
      try {
        this.expertLoading = true;
        const response = await reviewinitiateBaseInfoList({ infoid: infoid });
        let response = {};
        if (id) {
          response = await ethicalreviewInfo(id);
        } else if (infoid) {
          response = await reviewinitiateBaseInfoList({ infoid: infoid });
        }
        if (response.code === 200) {
          let detailData = {};
          if (response.data) {
          if (response.data && id) {
            this.form = response.data;
            // 解析 filePatch 字段
            this.parseFilePatch(this.form.filePatch);
            this.initAttachmentFileList();
          } else if (response.data && infoid) {
            this.form = response.data[0];
            // 解析 filePatch 字段
            this.parseFilePatch(this.form.filePatch);
            this.initAttachmentFileList();
          }
          console.log(this.form, "this.form ");
@@ -971,21 +963,177 @@
      }
    },
    // 解析 filePatch 字段
    parseFilePatch(filePatch) {
      if (!filePatch) {
        this.form.annexfilesList = [];
        return;
      }
      try {
        this.form.annexfilesList = JSON.parse(filePatch);
      } catch (error) {
        console.error("解析 filePatch 字段失败:", error);
        this.form.annexfilesList = [];
      }
    },
    // 初始化附件文件列表
    initAttachmentFileList() {
      if (this.form.annexfilesList && this.form.annexfilesList.length > 0) {
        this.attachmentFileList = this.form.annexfilesList.map(item => ({
          uid: item.id || Math.random().toString(36).substr(2, 9),
          name: item.fileName,
          url: item.path || item.fileUrl,
          status: "success"
        }));
      } else {
        this.attachmentFileList = [];
      }
    },
    // 构建 filePatch 字段
    buildFilePatch() {
      if (!this.form.annexfilesList || this.form.annexfilesList.length === 0) {
        return "";
      }
      return JSON.stringify(this.form.annexfilesList);
    },
    // 附件变化处理
    handleAttachmentChange(fileList) {
      this.attachmentFileList = fileList;
    },
    // 附件移除处理
    handleAttachmentRemove(file) {
      if (file.url) {
        const index = this.form.annexfilesList.findIndex(
          item => item.path === file.url || item.fileUrl === file.url
        );
        if (index > -1) {
          this.form.annexfilesList.splice(index, 1);
        }
      }
    },
    // 手动删除附件
    handleRemoveAttachment(index) {
      this.form.annexfilesList.splice(index, 1);
      this.attachmentFileList.splice(index, 1);
      this.$message.success("附件删除成功");
    },
    // 上传成功处理
    handleUploadSuccess({ file, fileList, response }) {
      if (response.code === 200) {
        const attachmentObj = {
          fileName: file.name,
          path: response.data || file.url,
          fileUrl: response.data || file.url,
          type: this.getFileExtension(file.name),
          createTime: dayjs().format("YYYY-MM-DD HH:mm:ss"),
          infoid: this.infoid,
          delFlag: 0
        };
        this.form.annexfilesList.push(attachmentObj);
        this.$message.success("文件上传成功");
      }
    },
    // 上传错误处理
    handleUploadError({ file, fileList, error }) {
      console.error("附件上传失败:", error);
      this.$message.error("文件上传失败,请重试");
    },
    // 打开上传对话框
    openUploadDialog() {
      this.$refs.uploadAttachment.openUpload();
    },
    // 文件预览
    handlePreview(file) {
      this.currentPreviewFile = {
        fileName: file.fileName,
        fileUrl: file.path || file.fileUrl,
        fileType: this.getFileType(file.fileName)
      };
      this.previewVisible = true;
    },
    // 文件下载
    handleDownload(file) {
      const fileUrl = file.path || file.fileUrl;
      const fileName = file.fileName;
      if (fileUrl) {
        const link = document.createElement("a");
        link.href = fileUrl;
        link.download = fileName;
        link.style.display = "none";
        document.body.appendChild(link);
        link.click();
        document.body.removeChild(link);
        this.$message.success("开始下载文件");
      } else {
        this.$message.warning("文件路径不存在,无法下载");
      }
    },
    // 获取文件类型
    getFileType(fileName) {
      if (!fileName) return "other";
      const extension = fileName
        .split(".")
        .pop()
        .toLowerCase();
      const imageTypes = ["jpg", "jpeg", "png", "gif", "bmp", "webp"];
      const pdfTypes = ["pdf"];
      const officeTypes = ["doc", "docx", "xls", "xlsx", "ppt", "pptx"];
      if (imageTypes.includes(extension)) return "image";
      if (pdfTypes.includes(extension)) return "pdf";
      if (officeTypes.includes(extension)) return "office";
      return "other";
    },
    // 获取文件扩展名
    getFileExtension(filename) {
      return filename
        .split(".")
        .pop()
        .toLowerCase();
    },
    // 日期时间格式化
    formatDateTime(dateTime) {
      if (!dateTime) return "";
      try {
        const date = new Date(dateTime);
        if (isNaN(date.getTime())) return dateTime;
        const year = date.getFullYear();
        const month = String(date.getMonth() + 1).padStart(2, "0");
        const day = String(date.getDate()).padStart(2, "0");
        const hours = String(date.getHours()).padStart(2, "0");
        const minutes = String(date.getMinutes()).padStart(2, "0");
        const seconds = String(date.getSeconds()).padStart(2, "0");
        return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
      } catch (error) {
        return dateTime;
      }
    },
    // 获取专家审查列表
    getExpertReviews(ethicsReviewId) {
      this.expertLoading = true;
      // 模拟数据 - 实际项目中从接口获取
      setTimeout(() => {
        this.expertLoading = false;
      }, 500);
    },
    // 获取附件列表
    getAttachments(ethicsReviewId) {
      this.attachmentLoading = true;
      // 模拟获取附件
      setTimeout(() => {
        this.attachmentLoading = false;
      }, 500);
    },
@@ -1040,7 +1188,9 @@
              ...this.form,
              // 确保必要字段
              infoid: this.infoid,
              caseNo: this.caseNo
              caseNo: this.caseNo,
              // 构建 filePatch 字段
              filePatch: this.buildFilePatch()
            };
            let response = null;
@@ -1158,11 +1308,9 @@
        return;
      }
      // 模拟发送
      this.$message.success("发送成功");
      this.sendDialogVisible = false;
      // 更新专家状态
      this.sendForm.expertIds.forEach(expertId => {
        const index = this.expertReviews.findIndex(
          expert => expert.id === expertId
@@ -1197,7 +1345,6 @@
        }
      })
        .then(({ value }) => {
          // 模拟更新专家审查
          const index = this.expertReviews.findIndex(e => e.id === expert.id);
          if (index !== -1) {
            this.expertReviews[index].expertOpinion = value;
@@ -1236,135 +1383,6 @@
      );
    },
    // 上传附件相关方法
    handleUploadAttachment() {
      this.uploadDialogVisible = true;
    },
    // 上传前校验
    beforeUpload(file) {
      const allowedTypes = [
        "application/pdf",
        "image/jpeg",
        "image/png",
        "application/msword",
        "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
        "application/vnd.ms-excel",
        "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
      ];
      const maxSize = 10 * 1024 * 1024;
      const isTypeOk =
        allowedTypes.includes(file.type) ||
        file.name.endsWith(".pdf") ||
        file.name.endsWith(".jpg") ||
        file.name.endsWith(".jpeg") ||
        file.name.endsWith(".png") ||
        file.name.endsWith(".doc") ||
        file.name.endsWith(".docx") ||
        file.name.endsWith(".xls") ||
        file.name.endsWith(".xlsx");
      if (!isTypeOk) {
        this.$message.error("文件格式不支持");
        return false;
      }
      if (file.size > maxSize) {
        this.$message.error("文件大小不能超过10MB");
        return false;
      }
      return true;
    },
    // 文件选择变化
    handleFileChange(file, fileList) {
      this.tempFileList = fileList;
    },
    // 移除临时文件
    handleTempRemove(file, fileList) {
      this.tempFileList = fileList;
    },
    // 上传成功处理
    handleUploadSuccess(response, file, fileList) {
      if (response.code === 200) {
        this.$message.success("文件上传成功");
        this.uploadDialogVisible = false;
        this.tempFileList = [];
      } else {
        this.$message.error(response.msg || "文件上传失败");
      }
    },
    // 提交上传
    async submitUpload() {
      if (this.tempFileList.length === 0) {
        this.$message.warning("请先选择要上传的文件");
        return;
      }
      this.$refs.uploadRef.submit();
      this.uploadLoading = true;
    },
    // 预览附件
    handlePreviewAttachment(attachment) {
      if (attachment.fileName.endsWith(".pdf")) {
        window.open(attachment.fileUrl, "_blank");
      } else if (attachment.fileName.match(/\.(jpg|jpeg|png)$/i)) {
        this.$alert(
          `<img src="${attachment.fileUrl}" style="max-width: 100%;" alt="${attachment.fileName}">`,
          "图片预览",
          {
            dangerouslyUseHTMLString: true,
            customClass: "image-preview-dialog"
          }
        );
      } else {
        this.$message.info("该文件类型暂不支持在线预览,请下载后查看");
      }
    },
    // 下载附件
    handleDownloadAttachment(attachment) {
      const link = document.createElement("a");
      link.href = attachment.fileUrl;
      link.download = attachment.fileName;
      link.click();
      this.$message.success(`开始下载: ${attachment.fileName}`);
    },
    // 获取文件类型
    getFileType(fileName) {
      const ext = fileName
        .split(".")
        .pop()
        .toLowerCase();
      const typeMap = {
        pdf: "PDF",
        doc: "DOC",
        docx: "DOCX",
        xls: "XLS",
        xlsx: "XLSX",
        jpg: "JPG",
        jpeg: "JPEG",
        png: "PNG"
      };
      return typeMap[ext] || ext.toUpperCase();
    },
    // 文件大小格式化
    formatFileSize(size) {
      if (size === 0) return "0 B";
      const k = 1024;
      const sizes = ["B", "KB", "MB", "GB"];
      const i = Math.floor(Math.log(size) / Math.log(k));
      return parseFloat((size / Math.pow(k, i)).toFixed(2)) + " " + sizes[i];
    },
    // 时间格式化
    parseTime(time) {
      if (!time) return "";
@@ -1385,6 +1403,8 @@
  }
};
</script>
<style scoped>
.ethics-review-detail {
@@ -1496,7 +1516,66 @@
.sent-button {
  color: #67c23a !important;
}
.form-section {
  margin-bottom: 16px;
}
.section-header {
  display: flex;
  align-items: center;
  font-weight: bold;
  color: #303133;
}
.dialog-footer {
  text-align: right;
  padding: 20px 0 0;
}
.attachment-section {
  margin-bottom: 16px;
}
.attachment-header {
  display: flex;
  align-items: center;
  margin-bottom: 16px;
  padding: 8px 0;
  border-bottom: 1px solid #ebeef5;
}
.attachment-title {
  font-weight: bold;
  margin: 0 8px;
}
.attachment-tip {
  font-size: 12px;
  color: #909399;
}
.attachment-list {
  margin-top: 16px;
}
.list-title {
  font-weight: bold;
  margin-bottom: 12px;
  color: #303133;
}
.file-name {
  font-size: 13px;
}
/* 案例信息展示样式 */
.selected-case-info {
  margin-bottom: 20px;
}
.case-info-card {
  border-left: 4px solid #67c23a;
}
/* 响应式设计 */
@media (max-width: 768px) {
  .ethics-review-detail {
src/views/business/ethicalReview/index.vue
@@ -192,7 +192,14 @@
          align="center"
          prop="expertConclusion"
          width="120"
        >
          <template slot-scope="scope">
            <dict-tag
              :options="dict.type.expert_Conclusion"
              :value="scope.row.expertConclusion"
        />
          </template>
        </el-table-column>
        <el-table-column
          label="专家意见"
          align="center"
@@ -273,7 +280,7 @@
export default {
  name: "EthicsReviewList",
  components: { Pagination },
  dicts: ["sys_user_sex", "sys_ethical"],
  dicts: ["sys_user_sex", "sys_ethical",'expert_Conclusion'],
  data() {
    return {
      // 遮罩层
@@ -361,7 +368,7 @@
    handleView(row) {
      this.$router.push({
        path: "/case/ethicalReviewInfo",
        query: { infoid: row.infoid }
        query: { infoid: row.infoid,id:row.id }
      });
    },
    // 新增按钮操作
@@ -373,7 +380,7 @@
      const infoid = row.infoid;
      this.$router.push({
        path: "/case/ethicalReviewInfo",
        query: { infoid: infoid }
        query: { infoid: infoid,id:row.id }
      });
    },
    // 结束审查操作
src/views/business/maintain/index.vue
@@ -111,7 +111,6 @@
        v-loading="loading"
        :data="maintenanceList"
        @selection-change="handleSelectionChange"
        @row-click="handleRowClick"
      >
        <el-table-column type="selection" width="55" align="center" />
        <el-table-column
src/views/project/DonationProcess/index.vue
@@ -172,7 +172,12 @@
        </template>
      </el-table-column>
      <el-table-column label="捐献者姓名" align="center" prop="name" width="100" />
      <el-table-column
        label="捐献者姓名"
        align="center"
        prop="name"
        width="100"
      />
      <el-table-column label="性别" align="center" prop="sex" width="80">
        <template slot-scope="scope">
@@ -463,8 +468,7 @@
        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 - response.data.terminationCase[2];
        this.stats.totalCount = response.total;
        this.allTableData = realData;
        let filteredData = this.applyFrontendFilter(realData);
src/views/project/donatebaseinfo/index.vue
@@ -209,7 +209,7 @@
            style="color: #f56c6c;"
            @click="handleTerminate(scope.row)"
            v-if="
              scope.row.terminationCase === 0 && scope.row.recordstate !== '99'
              scope.row.terminationCase == 0 && scope.row.recordstate !== '99'
            "
          >
            终止
@@ -219,7 +219,7 @@
            type="text"
            style="color: #67c23a;"
            @click="handleRestore(scope.row)"
            v-if="scope.row.terminationCase === 1"
            v-if="scope.row.terminationCase == 1"
          >
            恢复
          </el-button>