gongchunyi
4 天以前 6f1acfd2086a1f8c2cb80afd3db4e534e44d545e
src/views/safeProduction/dangerInvestigation/index.vue
@@ -55,52 +55,82 @@
                         width="60" />
        <el-table-column label="隐患编号"
                         prop="hiddenCode"
                         width="180"
                         show-overflow-tooltip />
                         width="150"
                         align="center"
                         show-overflow-tooltip>
          <template #default="scope">
            <el-button class="hidden-code-link"
                       link
                       type="primary"
                       @click="openForm('detail', scope.row)">
              {{ scope.row.hiddenCode }}
            </el-button>
          </template>
        </el-table-column>
        <el-table-column label="隐患描述"
                         prop="hiddenDesc"
                         width="150"
                         align="center"
                         show-overflow-tooltip />
        <el-table-column label="隐患具体位置"
                         prop="location"
                         width="150"
                         align="center"
                         show-overflow-tooltip />
        <el-table-column label="上报人"
                         prop="createUserName"
                         width="180"
                         width="150"
                         align="center"
                         show-overflow-tooltip />
        <el-table-column label="上报时间"
                         prop="createTime"
                         width="180"
                         align="center"
                         show-overflow-tooltip />
        <el-table-column label="整改完成期限"
                         prop="rectifyTime"
                         width="120"
                         align="center"
                         show-overflow-tooltip />
        <el-table-column label="整改责任人"
                         prop="rectifyUserName"
                         width="120"
                         align="center"
                         show-overflow-tooltip />
        <el-table-column label="整改责任人联系方式"
                         prop="rectifyUserMobile"
                         width="120"
                         width="160"
                         align="center"
                         show-overflow-tooltip />
        <el-table-column label="整改具体措施"
                         prop="rectifyMeasures"
                         width="120"
                         align="center"
                         show-overflow-tooltip />
        <el-table-column label="实际整改完成时间"
                         prop="rectifyActualTime"
                         width="180"
                         align="center"
                         show-overflow-tooltip />
        <el-table-column label="验收人"
                         prop="verifyUserName"
                         width="120"
                         align="center"
                         show-overflow-tooltip />
        <el-table-column label="验收意见"
                         prop="verifyRemark"
                         width="120"
                         align="center"
                         show-overflow-tooltip />
        <el-table-column label="验收时间"
                         prop="verifyTime"
                         width="120"
                         align="center"
                         show-overflow-tooltip />
        <el-table-column label="验收结果"
                         prop="verifyResult"
                         width="120"
                         align="center"
                         show-overflow-tooltip>
          <template #default="scope">
            <el-tag v-if="scope.row.verifyResult"
@@ -130,7 +160,7 @@
            <el-button link
                       type="primary"
                       size="small"
                       :disabled="!scope.row.rectifyActualTime || scope.row.verifyTime"
                       :disabled="!scope.row.rectifyActualTime || scope.row.verifyTime || scope.row.isVerify"
                       @click="openForm('edit3', scope.row)">验收</el-button>
          </template>
        </el-table-column>
@@ -268,11 +298,11 @@
          </el-col>
        </el-row>
      </el-form>
      <div v-if="operationType === 'edit2' || operationType === 'edit3'"
      <div v-if="showHiddenDetail"
           class="classtitle">隐患详情</div>
      <el-descriptions :column="2"
                       style="margin-bottom: 20px;"
                       v-if="operationType === 'edit2' || operationType === 'edit3'"
                       v-if="showHiddenDetail"
                       border>
        <el-descriptions-item label="隐患编号">
          <span class="detail-title">{{ form.hiddenCode }}</span>
@@ -309,11 +339,11 @@
        </el-descriptions-item>
      </el-descriptions>
      <div class="classtitle"
           v-if="operationType === 'edit3'"
           v-if="showRectifyDetail"
           style="margin-top: 40px;">整改详情</div>
      <el-descriptions :column="2"
                       style="margin-bottom: 20px;"
                       v-if="operationType === 'edit3'"
                       v-if="showRectifyDetail"
                       border>
        <el-descriptions-item label="整改具体措施"
                              :span="2">
@@ -351,6 +381,20 @@
                              type="date"
                              placeholder="请选择"
                              clearable />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="验收人:"
                          prop="verifyUserId">
              <el-select v-model="form2.verifyUserId"
                         placeholder="请选择"
                         filterable
                         clearable>
                <el-option v-for="item in userList"
                           :key="item.userId"
                           :label="item.nickName"
                           :value="item.userId" />
              </el-select>
            </el-form-item>
          </el-col>
        </el-row>
@@ -402,8 +446,9 @@
            <el-form-item label="验收人:"
                          prop="verifyUserId">
              <el-select v-model="form3.verifyUserId"
                         disabled
                         :disabled="!!form3.verifyUserId"
                         placeholder="请选择"
                         filterable
                         clearable>
                <el-option v-for="item in userList"
                           :key="item.userId"
@@ -414,18 +459,75 @@
          </el-col>
        </el-row>
      </el-form>
      <div class="classtitle"
           v-if="showVerifyDetail"
           style="margin-top: 40px;">验收详情</div>
      <el-descriptions :column="2"
                       style="margin-bottom: 20px;"
                       v-if="showVerifyDetail"
                       border>
        <el-descriptions-item label="验收人">
          <span class="detail-title">{{ getVerifyUserName() }}</span>
        </el-descriptions-item>
        <el-descriptions-item label="验收时间">
          <span class="detail-title">{{ form3.verifyTime }}</span>
        </el-descriptions-item>
        <el-descriptions-item label="验收结果">
          <el-tag v-if="form3.verifyResult"
                  :type="form3.verifyResult === '通过' ? 'success' : 'danger'">
            {{ form3.verifyResult }}
          </el-tag>
        </el-descriptions-item>
        <el-descriptions-item label="验收意见"
                              :span="2">
          <span class="detail-title">{{ form3.verifyRemark }}</span>
        </el-descriptions-item>
      </el-descriptions>
      <div class="classtitle"
           v-if="operationType === 'detail'"
           style="margin-top: 40px;">附件</div>
      <div v-if="operationType === 'detail'"
           v-loading="detailAttachmentLoading"
           class="detail-attachment-preview-list">
        <el-empty v-if="!detailAttachmentLoading && detailAttachmentList.length === 0"
                  description="暂无附件"
                  :image-size="80" />
        <div v-for="item in detailAttachmentList"
             :key="item.storageAttachmentId || item.id || getAttachmentPreviewUrl(item)"
             class="detail-attachment-preview-card">
          <div class="detail-attachment-header">
            <span class="detail-attachment-name">{{ getAttachmentName(item) }}</span>
            <el-button link
                       type="primary"
                       size="small"
                       @click="downloadDetailAttachment(item)">下载</el-button>
          </div>
          <el-image v-if="isImageAttachment(item)"
                    class="detail-attachment-image"
                    :src="getAttachmentPreviewUrl(item)"
                    :preview-src-list="detailPreviewImageUrls"
                    :initial-index="getImagePreviewIndex(item)"
                    fit="contain"
                    preview-teleported />
          <iframe v-else-if="isPdfAttachment(item)"
                  class="detail-attachment-frame"
                  :src="getAttachmentPreviewUrl(item)" />
          <div v-else
               class="detail-attachment-placeholder">
            <span>该文件类型暂不支持内嵌预览</span>
            <el-button link
                       type="primary"
                       @click="downloadDetailAttachment(item)">下载查看</el-button>
          </div>
        </div>
      </div>
    </FormDialog>
  <!--  todo 附件预览相关 -->
    <FileListDialog ref="fileListRef"
                    v-model="fileListDialogVisible"
                    :show-upload-button="true"
                    :show-delete-button="true"
                    :is-show-pagination="true"
                    :page="filePagination"
                    :upload-method="handleUpload"
                    :delete-method="handleFileDelete"
                    @pagination="paginationSearch"
                    title="附件列表" />
    <FileListDialog
        v-if="fileListDialogVisible"
        :record-id="currentRecordId"
        record-type="safe_hidden"
        v-model:visible="fileListDialogVisible"/>
  </div>
</template>
@@ -436,22 +538,18 @@
  import { ElMessageBox, ElMessage } from "element-plus";
  import useUserStore from "@/store/modules/user";
  import { userListNoPage } from "@/api/system/user.js";
  import FileListDialog from "@/components/Dialog/FileListDialog.vue";
  import FormDialog from "@/components/Dialog/FormDialog.vue";
  import { getQuotationList } from "@/api/salesManagement/salesQuotation.js";
  import { attachmentList } from "@/api/basicData/storageAttachment.js";
  import {
    dangerInvestigationListPage,
    safeHiddenAdd,
    safeHiddenUpdate,
    safeHiddenDel,
    fileListPage,
    safeHiddenFileAdd,
    safeHiddenFileDel,
  } from "@/api/safeProduction/dangerInvestigation.js";
  import useFormData from "@/hooks/useFormData.js";
  import request from "@/utils/request";
  import dayjs from "dayjs";
  import { get } from "@vueuse/core";
  const userStore = useUserStore();
  const { proxy } = getCurrentInstance();
@@ -459,6 +557,9 @@
  const selectedRows = ref([]);
  const userList = ref([]);
  const tableLoading = ref(false);
  const detailAttachmentList = ref([]);
  const detailAttachmentLoading = ref(false);
  const currentRecordId = ref(0);
  const page = reactive({
    current: 1,
    size: 100,
@@ -473,6 +574,8 @@
      return "整改页面";
    } else if (type === "edit3") {
      return "验收页面";
    } else if (type === "detail") {
      return "隐患详情";
    }
  };
  // 获取类型标签类型
@@ -520,11 +623,13 @@
  const rules2 = {
    rectifyActualTime: [{ required: true, message: "请选择", trigger: "blur" }],
    rectifyMeasures: [{ required: true, message: "请输入", trigger: "blur" }],
    verifyUserId: [{ required: true, message: "请选择", trigger: "change" }],
  };
  const rules3 = {
    verifyTime: [{ required: true, message: "请选择", trigger: "blur" }],
    verifyRemark: [{ required: true, message: "请输入", trigger: "blur" }],
    verifyResult: [{ required: true, message: "请选择", trigger: "change" }],
    verifyUserId: [{ required: true, message: "请选择", trigger: "change" }],
    acceptDesc: [{ required: true, message: "请输入", trigger: "blur" }],
  };
  const { hidden_danger_type } = proxy.useDict("hidden_danger_type");
@@ -536,6 +641,7 @@
  const form2 = ref({
    rectifyActualTime: "", // 实际整改完成时间
    rectifyMeasures: "", // 整改具体措施
    verifyUserId: "", // 验收人
  });
  const form3 = ref({
    verifyTime: "", // 验收时间
@@ -545,6 +651,21 @@
    verifyUserName: "",
    verifyResult: "", // 验收结果
  });
  const showHiddenDetail = computed(() => ["edit2", "edit3", "detail"].includes(operationType.value));
  const showRectifyDetail = computed(
    () =>
      operationType.value === "edit3" ||
      (operationType.value === "detail" && (form2.value.rectifyMeasures || form2.value.rectifyActualTime))
  );
  const showVerifyDetail = computed(
    () =>
      operationType.value === "detail" &&
      (form3.value.verifyUserId ||
        form3.value.verifyUserName ||
        form3.value.verifyRemark ||
        form3.value.verifyTime ||
        form3.value.verifyResult)
  );
  const riskLevelList = ref([
    {
      value: "重大风险",
@@ -581,6 +702,60 @@
      form.value.rectifyUserName = selectedUser.nickName;
      form.value.rectifyUserMobile = selectedUser.phonenumber;
    }
  };
  const hasUserId = userId => userId !== null && userId !== undefined && userId !== "" && userId !== "null";
  const normalizeUserId = userId => (hasUserId(userId) ? Number(userId) : "");
  const getVerifyUserName = () => {
    if (form3.value.verifyUserName) {
      return form3.value.verifyUserName;
    }
    const selectedUser = userList.value.find(user => Number(user.userId) === Number(form3.value.verifyUserId));
    return selectedUser?.nickName || selectedUser?.userName || "";
  };
  const getAttachmentName = row => row?.originalFilename || row?.fileName || row?.name || "";
  const getAttachmentPreviewUrl = row => row?.previewURL || row?.previewUrl || row?.url || row?.downloadURL || row?.downloadUrl || "";
  const getAttachmentDownloadUrl = row => row?.downloadURL || row?.downloadUrl || row?.previewURL || row?.previewUrl || row?.url || "";
  const getAttachmentTypeText = row => `${getAttachmentName(row)} ${getAttachmentPreviewUrl(row)}`.toLowerCase().split("?")[0];
  const isImageAttachment = row => /\.(jpg|jpeg|png|gif|bmp|webp|svg)$/.test(getAttachmentTypeText(row));
  const isPdfAttachment = row => /\.pdf$/.test(getAttachmentTypeText(row));
  const isRectifiedRecord = row =>
    !!(row?.rectifyActualTime || row?.rectifyMeasures || row?.verifyTime || row?.verifyResult || row?.verifyRemark);
  const detailPreviewImageUrls = computed(() =>
    detailAttachmentList.value
      .filter(isImageAttachment)
      .map(getAttachmentPreviewUrl)
      .filter(Boolean)
  );
  const getImagePreviewIndex = row => {
    const index = detailPreviewImageUrls.value.indexOf(getAttachmentPreviewUrl(row));
    return index > -1 ? index : 0;
  };
  const loadDetailAttachments = recordId => {
    detailAttachmentLoading.value = true;
    detailAttachmentList.value = [];
    return attachmentList({
      recordType: "safe_hidden",
      recordId,
    })
      .then(res => {
        detailAttachmentList.value = res?.data || [];
      })
      .catch(() => {
        detailAttachmentList.value = [];
        ElMessage.error("附件加载失败");
      })
      .finally(() => {
        detailAttachmentLoading.value = false;
      });
  };
  const downloadDetailAttachment = row => {
    const url = getAttachmentDownloadUrl(row);
    if (!url) {
      ElMessage.warning("文件地址无效,无法下载");
      return;
    }
    window.open(url, "_blank");
  };
  // 导入相关
@@ -666,6 +841,7 @@
          } else {
            item.isRectify = false;
          }
          item.isVerify = hasUserId(item.verifyUserId) && Number(item.verifyUserId) != Number(currentUserId.value);
        });
        return res;
      })
@@ -698,15 +874,18 @@
  const openForm = async (type, row) => {
    console.log("row", row);
    operationType.value = type;
    detailAttachmentList.value = [];
    form3.value = {
      verifyTime: "", // 验收时间
      verifyRemark: "", // 验收备注
      verifyResult: "", // 验收描述
      verifyUserId: "", // 验收人
      verifyUserName: "",
    };
    form2.value = {
      rectifyActualTime: "", // 实际整改完成时间
      rectifyMeasures: "", // 整改具体措施
      verifyUserId: "", // 验收人
    };
    if (type === "add") {
      form.value = {
@@ -758,6 +937,7 @@
      form2.value = {
        rectifyActualTime: row.rectifyActualTime, // 实际整改完成时间
        rectifyMeasures: row.rectifyMeasures, // 整改具体措施
        verifyUserId: normalizeUserId(row.verifyUserId), // 验收人
      };
    } else if (type === "edit3") {
      form.value = {
@@ -783,15 +963,41 @@
        verifyTime: row.verifyTime, // 验收时间
        verifyRemark: row.verifyRemark, // 验收备注
        verifyResult: row.verifyResult, // 验收描述
        verifyUserId: row.verifyUserId, // 验收人
        verifyUserId: normalizeUserId(row.verifyUserId), // 验收人
        verifyUserName: row.verifyUserName,
      };
      console.log("form3.value", form3.value);
      if (!form3.value.verifyUserId || form3.value.verifyUserId === "null") {
        form3.value.verifyUserId = Number(currentUserId.value); // 验收人
      }
      if (!form3.value.verifyTime || form3.value.verifyTime === "null") {
        form3.value.verifyTime = dayjs().format("YYYY-MM-DD"); // 验收描述
      }
    } else if (type === "detail") {
      form.value = {
        id: row.id,
        hiddenCode: row.hiddenCode, // 隐患编号
        location: row.location, // 隐患位置
        hiddenDesc: row.hiddenDesc, // 隐患描述
        createUser: row.createUser, // 上报人
        createUserName: row.createUserName,
        createTime: row.createTime, // 上报时间
        rectifyUserId: row.rectifyUserId, // 整改责任人
        rectifyUserName: row.rectifyUserName,
        rectifyTime: row.rectifyTime, // 整改完成期限
        rectifyUserMobile: row.rectifyUserMobile, // 整改责任人手机号
        riskLevel: row.riskLevel, // 隐患风险等级
        type: row.type, // 隐患类型
      };
      form2.value = {
        rectifyActualTime: row.rectifyActualTime, // 实际整改完成时间
        rectifyMeasures: row.rectifyMeasures, // 整改具体措施
        verifyUserId: normalizeUserId(row.verifyUserId), // 验收人
      };
      form3.value = {
        verifyTime: row.verifyTime, // 验收时间
        verifyRemark: row.verifyRemark, // 验收备注
        verifyResult: row.verifyResult, // 验收描述
        verifyUserId: normalizeUserId(row.verifyUserId), // 验收人
        verifyUserName: row.verifyUserName,
      };
      loadDetailAttachments(row.id);
    }
    dialogFormVisible.value = true;
  };
@@ -854,9 +1060,9 @@
      proxy.$refs["formRef3"].validate(valid => {
        if (valid) {
          safeHiddenUpdate({
            ...form3.value,
            ...form2.value,
            ...form.value,
            ...form3.value,
          }).then(res => {
            proxy.$modal.msgSuccess("提交成功");
            closeDia();
@@ -870,6 +1076,9 @@
  const closeDia = () => {
    proxy.resetForm("formRef");
    proxy.resetForm("formRef2");
    proxy.resetForm("formRef3");
    detailAttachmentList.value = [];
    detailAttachmentLoading.value = false;
    dialogFormVisible.value = false;
  };
  // 关闭产品弹框
@@ -881,12 +1090,18 @@
  const handleDelete = () => {
    let ids = [];
    if (selectedRows.value.length > 0) {
      const rectifiedRows = selectedRows.value.filter(isRectifiedRecord);
      if (rectifiedRows.length > 0) {
        const hiddenCodes = rectifiedRows.map(item => item.hiddenCode).filter(Boolean).join("、");
        proxy.$modal.msgWarning(`已整改的隐患不能删除${hiddenCodes ? `:${hiddenCodes}` : ""}`);
        return;
      }
      ids = selectedRows.value.map(item => item.id);
    } else {
      proxy.$modal.msgWarning("请选择数据");
      return;
    }
    ElMessageBox.confirm("选中的内容将被删除,是否确认删除?", "导出", {
    ElMessageBox.confirm("选中的未整改隐患及其附件将被删除,是否确认删除?", "提示", {
      confirmButtonText: "确认",
      cancelButtonText: "取消",
      type: "warning",
@@ -943,18 +1158,8 @@
  const fileListDialogVisible = ref(false);
  const currentFileRow = ref(null);
  const downLoadFile = row => {
    currentFileRow.value = row;
    fileListPage({
      safeHiddenId: row.id,
      current: filePagination.value.current,
      size: filePagination.value.size,
    }).then(res => {
      if (fileListRef.value) {
        fileListRef.value.open(res.data.records || []);
        console.log("res.data", res.data);
        filePagination.value.total = res.data.total || 0;
      }
    });
    currentRecordId.value = row.id;
    fileListDialogVisible.value = true;
  };
  const currentUserId = ref("");
  const currentUserName = ref("");
@@ -983,154 +1188,13 @@
    return "";
  };
  onMounted(() => {
    getCurrentFactoryName();
  onMounted(async () => {
    await getCurrentFactoryName();
    getList();
    userListNoPage().then(res => {
      userList.value = res.data;
    });
  });
  // 上传附件
  const handleUpload = async () => {
    if (!currentFileRow.value) {
      proxy.$modal.msgWarning("请先选择数据");
      return null;
    }
    return new Promise(resolve => {
      // 创建一个隐藏的文件输入元素
      const input = document.createElement("input");
      input.type = "file";
      input.style.display = "none";
      input.onchange = async e => {
        const file = e.target.files[0];
        if (!file) {
          resolve(null);
          return;
        }
        try {
          // 使用 FormData 上传文件
          const formData = new FormData();
          formData.append("file", file);
          const uploadRes = await request({
            url: "/file/upload",
            method: "post",
            data: formData,
            headers: {
              "Content-Type": "multipart/form-data",
              Authorization: `Bearer ${getToken()}`,
            },
          });
          if (uploadRes.code === 200) {
            // 保存附件信息
            const fileData = {
              safeHiddenId: currentFileRow.value.id,
              name: uploadRes.data.originalName || file.name,
              url: uploadRes.data.tempPath || uploadRes.data.url,
            };
            const saveRes = await safeHiddenFileAdd(fileData);
            if (saveRes.code === 200) {
              proxy.$modal.msgSuccess("文件上传成功");
              // 重新加载文件列表
              const listRes = await fileListPage({
                safeHiddenId: currentFileRow.value.id,
                current: filePagination.value.current,
                size: filePagination.value.size,
              });
              if (listRes.code === 200 && fileListRef.value) {
                const fileList = (listRes.data?.records || []).map(item => ({
                  name: item.name,
                  url: item.url,
                  id: item.id,
                  ...item,
                }));
                fileListRef.value.setList(fileList);
                filePagination.value.total = listRes.data?.total || 0;
              }
              // 返回新文件信息
              resolve({
                name: fileData.name,
                url: fileData.url,
                id: saveRes.data?.id,
              });
            } else {
              proxy.$modal.msgError(saveRes.msg || "文件保存失败");
              resolve(null);
            }
          } else {
            proxy.$modal.msgError(uploadRes.msg || "文件上传失败");
            resolve(null);
          }
        } catch (error) {
          proxy.$modal.msgError("文件上传失败");
          resolve(null);
        } finally {
          document.body.removeChild(input);
        }
      };
      document.body.appendChild(input);
      input.click();
    });
  };
  // 分页查询文件列表
  const paginationSearch = async (page, size) => {
    filePagination.value.current = page;
    filePagination.value.size = size;
    const listRes = await fileListPage({
      safeHiddenId: currentFileRow.value.id,
      current: filePagination.value.current,
      size: filePagination.value.size,
    });
    if (listRes.code === 200) {
      const fileList = (listRes.data?.records || []).map(item => ({
        name: item.name,
        url: item.url,
        id: item.id,
        ...item,
      }));
      fileListRef.value.setList(fileList);
      filePagination.value.total = listRes.data?.total || 0;
    }
  };
  // 删除附件
  const handleFileDelete = async row => {
    try {
      const res = await safeHiddenFileDel([row.id]);
      if (res.code === 200) {
        proxy.$modal.msgSuccess("删除成功");
        // 重新加载文件列表
        if (currentFileRow.value && fileListRef.value) {
          const listRes = await fileListPage({
            safeHiddenId: currentFileRow.value.id,
            current: filePagination.value.current,
            size: filePagination.value.size,
          });
          if (listRes.code === 200) {
            const fileList = (listRes.data?.records || []).map(item => ({
              name: item.name,
              url: item.url,
              id: item.id,
              ...item,
            }));
            fileListRef.value.setList(fileList);
            filePagination.value.total = listRes.data?.total || 0;
          }
        }
        return true; // 返回 true 表示删除成功,组件会更新列表
      } else {
        proxy.$modal.msgError(res.msg || "删除失败");
        return false;
      }
    } catch (error) {
      proxy.$modal.msgError("删除失败");
      return false;
    }
  };
</script>
<style scoped lang="scss">
@@ -1163,6 +1227,71 @@
    justify-content: space-between;
    margin-bottom: 10px;
  }
  .hidden-code-link {
    height: auto;
    padding: 0;
    font-weight: 500;
  }
  .detail-attachment-preview-list {
    min-height: 120px;
    margin-bottom: 20px;
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(220px, 260px));
    gap: 12px;
    align-items: start;
  }
  .detail-attachment-preview-card {
    border: 1px solid #e5eaf3;
    border-radius: 6px;
    overflow: hidden;
    background: #fff;
  }
  .detail-attachment-header {
    min-height: 36px;
    padding: 6px 12px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    border-bottom: 1px solid #e5eaf3;
    background: #f7f9fc;
  }
  .detail-attachment-name {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-weight: 500;
    color: #303133;
  }
  .detail-attachment-image {
    width: 100%;
    height: 160px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: #fafafa;
  }
  .detail-attachment-frame {
    width: 100%;
    height: 180px;
    border: 0;
    display: block;
    background: #fafafa;
  }
  .detail-attachment-placeholder {
    min-height: 120px;
    padding: 12px;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 12px;
    color: #606266;
    background: #fafafa;
  }
  .detail-attachment-preview-list :deep(.el-empty) {
    grid-column: 1 / -1;
  }
  .print-preview-dialog {
    .el-dialog__body {
      padding: 0;