WXL
2026-04-25 996206735df06887e3f3e453797b1289a2a793e7
src/views/business/ethicalReview/ethicalReviewInfo.vue
@@ -28,29 +28,26 @@
              <el-input
                v-model="form.initiateTheme"
                placeholder="请输入发起主题"
              />
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="发起人" prop="initiatePerson">
              <el-input v-model="form.initiatePerson"  />
              <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>
@@ -83,21 +78,17 @@
        <el-row :gutter="20">
          <el-col :span="8">
            <el-form-item label="专家姓名" prop="expertName">
              <el-input v-model="form.expertName"  />
              <el-input v-model="form.expertName" />
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="专家编号" prop="expertNo">
              <el-input v-model="form.expertNo"  />
              <el-input v-model="form.expertNo" />
            </el-form-item>
          </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">
          <template slot-scope="scope">
            <div class="file-info">
      <!-- 使用 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">
              <i
                class="el-icon-document"
                style="margin-right: 8px; color: #409EFF;"
              ></i>
              <span>{{ scope.row.fileName }}</span>
            </div>
          </template>
        </el-table-column>
              <span class="file-name">{{ scope.row.fileName }}</span>
            </template>
          </el-table-column>
          <el-table-column label="文件类型" width="100">
            <template slot-scope="scope">
              <el-tag size="small">{{
                getFileType(scope.row.fileName)
              }}</el-tag>
            </template>
          </el-table-column>
          <el-table-column label="创建时间" width="160">
            <template slot-scope="scope">
              <span>{{ formatDateTime(scope.row.createTime) }}</span>
            </template>
          </el-table-column>
          <el-table-column label="操作" width="266">
            <template slot-scope="scope">
              <el-button
                size="mini"
                type="primary"
                @click="handlePreview(scope.row)"
              >
                预览
              </el-button>
              <el-button
                size="mini"
                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>
        <el-table-column label="文件类型" width="100" align="center">
          <template slot-scope="scope">
            <el-tag size="small">{{ getFileType(scope.row.fileName) }}</el-tag>
          </template>
        </el-table-column>
        <el-table-column label="文件大小" width="100" align="center">
          <template slot-scope="scope">
            <span>{{ formatFileSize(scope.row.fileSize) }}</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">
          <template slot-scope="scope">
            <el-button
              size="mini"
              type="text"
              icon="el-icon-view"
              @click="handlePreviewAttachment(scope.row)"
              >预览</el-button
            >
            <el-button
              size="mini"
              type="text"
              icon="el-icon-download"
              @click="handleDownloadAttachment(scope.row)"
              >下载</el-button
            >
          </template>
        </el-table-column>
      </el-table>
      <!-- 空状态 -->
      <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: "",
@@ -571,41 +555,51 @@
        delFlag: "0"
      },
      // 表单验证规则
     rules: {
  initiateTheme: [
    { required: true, message: "发起主题不能为空", trigger: "blur" },
    { min: 2, max: 100, message: "长度在 2 到 100 个字符", trigger: "blur" }
  ],
  initiatePerson: [
    { required: true, message: "发起人不能为空", trigger: "blur" }
  ],
  status: [
    { required: true, message: "审查状态不能为空", trigger: "change" }
  ],
  startTime: [
    { required: true, message: "发起时间不能为空", trigger: "change" }
  ],
  cutOffTime: [
    { required: true, message: "截止时间不能为空", trigger: "change" }
  ],
  expertName: [
    { max: 50, message: "长度不能超过 50 个字符", trigger: "blur" }
  ],
  expertNo: [
    { max: 50, message: "长度不能超过 50 个字符", trigger: "blur" }
  ],
  expertConclusion: [
    { max: 2, message: "长度不能超过 2 个字符", trigger: "change" }
  ],
  remark: [
    { max: 500, message: "长度不能超过 500 个字符", trigger: "blur" }
  ]
},
      rules: {
        initiateTheme: [
          { required: true, message: "发起主题不能为空", trigger: "blur" },
          {
            min: 2,
            max: 100,
            message: "长度在 2 到 100 个字符",
            trigger: "blur"
          }
        ],
        initiatePerson: [
          { required: true, message: "发起人不能为空", trigger: "blur" }
        ],
        status: [
          { required: true, message: "审查状态不能为空", trigger: "change" }
        ],
        startTime: [
          { required: true, message: "发起时间不能为空", trigger: "change" }
        ],
        cutOffTime: [
          { required: true, message: "截止时间不能为空", trigger: "change" }
        ],
        expertName: [
          { max: 50, message: "长度不能超过 50 个字符", trigger: "blur" }
        ],
        expertNo: [
          { max: 50, message: "长度不能超过 50 个字符", trigger: "blur" }
        ],
        expertConclusion: [
          { max: 2, message: "长度不能超过 2 个字符", trigger: "change" }
        ],
        remark: [
          { max: 500, message: "长度不能超过 500 个字符", trigger: "blur" }
        ]
      },
      // 保存加载状态
      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 {