yyb
12 小时以前 65193cc9b4e27aad36a65eca447e6c62f6ee037f
不合格管理:重构详情展示与操作按钮

- 移除原因分析和预防与纠正措施的文本预览功能,替换为详情弹框
- 调整表格列宽,优化操作按钮布局
- 引入新的详情弹框组件以提升用户体验
已添加1个文件
已修改1个文件
288 ■■■■ 文件已修改
src/views/qualityManagement/nonconformingManagement/components/detailDia.vue 219 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/qualityManagement/nonconformingManagement/index.vue 69 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/qualityManagement/nonconformingManagement/components/detailDia.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,219 @@
<template>
  <el-dialog v-model="dialogVisible" title="详情" width="720px">
    <div class="detail-content">
      <el-row :gutter="20" class="detail-row">
        <el-col :span="12">
          <p class="detail-item"><span class="detail-label">状态:</span><span class="detail-value">{{ formatInspectState(detailForm.inspectState) }}</span></p>
        </el-col>
        <el-col :span="12">
          <p class="detail-item"><span class="detail-label">检测日期:</span><span class="detail-value">{{ detailForm.checkTime || "-" }}</span></p>
        </el-col>
      </el-row>
      <el-row :gutter="20" class="detail-row">
        <el-col :span="12">
          <p class="detail-item"><span class="detail-label">类别:</span><span class="detail-value">{{ formatInspectType(detailForm.inspectType) }}</span></p>
        </el-col>
        <el-col :span="12">
          <p class="detail-item"><span class="detail-label">检验员:</span><span class="detail-value">{{ detailForm.checkName || "-" }}</span></p>
        </el-col>
      </el-row>
      <el-row :gutter="20" class="detail-row">
        <el-col :span="12">
          <p class="detail-item"><span class="detail-label">产品名称:</span><span class="detail-value">{{ detailForm.productName || "-" }}</span></p>
        </el-col>
        <el-col :span="12">
          <p class="detail-item"><span class="detail-label">规格型号:</span><span class="detail-value">{{ detailForm.model || "-" }}</span></p>
        </el-col>
      </el-row>
      <el-row :gutter="20" class="detail-row">
        <el-col :span="12">
          <p class="detail-item"><span class="detail-label">单位:</span><span class="detail-value">{{ detailForm.unit || "-" }}</span></p>
        </el-col>
        <el-col :span="12">
          <p class="detail-item"><span class="detail-label">数量:</span><span class="detail-value">{{ detailForm.quantity ?? "-" }}</span></p>
        </el-col>
      </el-row>
      <el-row :gutter="20" class="detail-row">
        <el-col :span="12">
          <p class="detail-item"><span class="detail-label">不合格现象:</span><span class="detail-value">{{ detailForm.defectivePhenomena || "-" }}</span></p>
        </el-col>
        <el-col :span="12">
          <p class="detail-item"><span class="detail-label">处理结果:</span><span class="detail-value">{{ detailForm.dealResult || "-" }}</span></p>
        </el-col>
      </el-row>
      <el-row :gutter="20" class="detail-row">
        <el-col :span="12">
          <p class="detail-item"><span class="detail-label">处理人:</span><span class="detail-value">{{ detailForm.dealName || "-" }}</span></p>
        </el-col>
        <el-col :span="12">
          <p class="detail-item"><span class="detail-label">处理日期:</span><span class="detail-value">{{ detailForm.dealTime || "-" }}</span></p>
        </el-col>
      </el-row>
      <el-row :gutter="20" class="detail-row">
        <el-col :span="12">
          <p class="detail-item"><span class="detail-label">工时损失:</span><span class="detail-value">{{ detailForm.lossWorking ?? "-" }}</span></p>
        </el-col>
        <el-col :span="12">
          <p class="detail-item"><span class="detail-label">材料费损失:</span><span class="detail-value">{{ detailForm.lossMaterial ?? "-" }}</span></p>
        </el-col>
      </el-row>
      <el-row class="detail-row">
        <el-col :span="24">
          <p class="detail-item">
            <span class="detail-label">原因分析:</span>
            <span class="detail-value detail-textarea">{{ detailForm.reasonAnalysis || "-" }}</span>
          </p>
        </el-col>
      </el-row>
      <el-row class="detail-row">
        <el-col :span="24">
          <p class="detail-item">
            <span class="detail-label">预防与纠正措施:</span>
            <span class="detail-value detail-textarea">{{ detailForm.preventiveCorrective || "-" }}</span>
          </p>
        </el-col>
      </el-row>
      <!-- <el-row class="detail-row">
        <el-col :span="24">
          <div class="detail-item">
            <span class="detail-label">附件:</span>
            <div class="detail-value">
              <div v-if="attachmentList.length" class="attachment-list">
                <p
                  v-for="(item, idx) in attachmentList"
                  :key="`${item.url}-${idx}`"
                  :href="item.url"
                  target="_blank"
                  rel="noopener noreferrer"
                  class="attachment-link"
                >
                  {{ item.name }}
                </p>
              </div>
              <span v-else>-</span>
            </div>
          </div>
        </el-col>
      </el-row> -->
    </div>
  </el-dialog>
</template>
<script setup>
import { computed, ref } from "vue";
const dialogVisible = ref(false);
const detailForm = ref({});
const baseApi = import.meta.env.VITE_APP_BASE_API;
const normalizeUrl = (url) => {
  if (!url) return "";
  if (String(url).startsWith("http")) return url;
  return `${baseApi}${url}`;
};
// const attachmentList = computed(() => {
//   const list = [];
//   const commonFileList = Array.isArray(detailForm.value?.commonFileList) ? detailForm.value.commonFileList : [];
//   commonFileList.forEach((item, index) => {
//     const url = normalizeUrl(item?.url || item?.tempPath);
//     if (!url) return;
//     list.push({
//       name: item?.name || `附件${index + 1}`,
//       url,
//     });
//   });
//   if (list.length) return list;
//   const photos = detailForm.value?.defectivePhotos;
//   if (!photos) return [];
//   return String(photos)
//     .split(",")
//     .map((item, index) => {
//       const path = item?.trim();
//       if (!path) return null;
//       return {
//         name: `附件${index + 1}`,
//         url: normalizeUrl(path),
//       };
//     })
//     .filter(Boolean);
// });
const formatInspectState = (value) => {
  if (value == 0) return "待处理";
  if (value == 1) return "已处理";
  return "-";
};
const formatInspectType = (value) => {
  if (value == 0) return "原材料检验";
  if (value == 1) return "过程检验";
  if (value == 2) return "出厂检验";
  return "-";
};
const openDialog = (row) => {
  detailForm.value = { ...(row || {}) };
  dialogVisible.value = true;
};
defineExpose({
  openDialog,
});
</script>
<style scoped>
.detail-content {
  line-height: 1.6;
  color: #606266;
  max-height: 60vh;
  overflow-y: auto;
  overflow-x: hidden;
}
.detail-row {
  margin-bottom: 10px;
}
.detail-item {
  margin: 0;
  display: flex;
  align-items: flex-start;
}
.detail-label {
  flex: 0 0 116px;
  color: #303133;
  font-weight: 600;
}
.detail-value {
  flex: 1;
  min-width: 0;
  overflow-x: hidden;
}
.detail-value-multiline {
  white-space: pre-wrap;
  word-break: break-word;
}
.detail-textarea {
  display: block;
  min-height: 92px;
  max-height: 92px;
  overflow-y: auto;
  overflow-x: hidden;
  padding: 8px 10px;
  border-radius: 4px;
  background: #f5f7fa;
  white-space: pre-wrap;
  word-break: break-word;
  overflow-wrap: anywhere;
}
.attachment-list {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 12px;
}
.attachment-link {
  color: #409eff;
  text-decoration: none;
}
.attachment-link:hover {
  text-decoration: underline;
}
</style>
src/views/qualityManagement/nonconformingManagement/index.vue
@@ -53,35 +53,9 @@
          @pagination="pagination"
          :total="page.total"
      >
        <template #reasonAnalysis="{ row }">
          <el-button
              link
              type="primary"
              @click="openTextPreviewDialog('原因分析', row?.reasonAnalysis)"
          >
            {{ row?.reasonAnalysis}}
          </el-button>
        </template>
        <template #preventiveCorrective="{ row }">
          <el-button
              link
              type="primary"
              @click="openTextPreviewDialog('预防与纠正措施', row?.preventiveCorrective)"
          >
            {{ row?.preventiveCorrective}}
          </el-button>
        </template>
        <template #lossWorking="{ row }">
          <span>{{ row?.lossWorking ?? '-' }}</span>
        </template>
        <template #lossMaterial="{ row }">
          <span>{{ row?.lossMaterial ?? '-' }}</span>
        </template>
      </PIMTable>
    </div>
    <el-dialog v-model="textPreviewDialogVisible" :title="textPreviewTitle" width="600px">
      <div class="text-preview-content">{{ textPreviewContent || "暂无内容" }}</div>
    </el-dialog>
    <DetailDia ref="detailDiaRef" />
    <FormDia ref="formDia" @close="handleQuery"></FormDia>
    <InspectionFormDia ref="inspectionFormDia" @close="handleQuery"></InspectionFormDia>
  </div>
@@ -94,6 +68,7 @@
import {ElMessageBox} from "element-plus";
import {qualityUnqualifiedDel, qualityUnqualifiedListPage} from "@/api/qualityManagement/nonconformingManagement.js";
import InspectionFormDia from "@/views/qualityManagement/nonconformingManagement/components/inspectionFormDia.vue";
import DetailDia from "@/views/qualityManagement/nonconformingManagement/components/detailDia.vue";
import dayjs from "dayjs";
const data = reactive({
@@ -204,16 +179,14 @@
  {
    label: "原因分析",
    prop: "reasonAnalysis",
    dataType: "slot",
    slot: "reasonAnalysis",
    width: 160
    width: 120
  },
  {
    label: "预防与纠正措施",
    prop: "preventiveCorrective",
    dataType: "slot",
    slot: "preventiveCorrective",
    width: 180
    width: 120
  },
  {
    label: "工时损失",
@@ -230,8 +203,15 @@
    label: "操作",
    align: "center",
    fixed: "right",
    width: 100,
    width: 140,
    operation: [
      {
        name: "详情",
        type: "text",
        clickFun: (row) => {
          openDetailDialog(row);
        },
      },
      {
        name: "处理",
        type: "text",
@@ -246,9 +226,6 @@
const tableData = ref([]);
const selectedRows = ref([]);
const tableLoading = ref(false);
const textPreviewDialogVisible = ref(false);
const textPreviewTitle = ref("");
const textPreviewContent = ref("");
const page = reactive({
  current: 1,
  size: 100,
@@ -256,6 +233,7 @@
});
const formDia = ref()
const inspectionFormDia = ref()
const detailDiaRef = ref()
const { proxy } = getCurrentInstance()
const changeDaterange = (value) => {
@@ -315,11 +293,9 @@
    inspectionFormDia.value?.openDialog(type, row)
  })
};
// æŸ¥çœ‹å­—段详情
const openTextPreviewDialog = (title, content) => {
  textPreviewTitle.value = title;
  textPreviewContent.value = content || "";
  textPreviewDialogVisible.value = true;
// æ‰“开详情弹框
const openDetailDialog = (row) => {
  detailDiaRef.value?.openDialog(row);
};
// åˆ é™¤
@@ -366,12 +342,11 @@
</script>
<style scoped>
.text-preview-content {
  white-space: pre-wrap;
  line-height: 1.6;
  color: #606266;
  word-break: break-word;
  max-height: 60vh;
  overflow-y: auto;
.text-ellipsis {
  display: inline-block;
  width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
</style>