zhang_nuo
2026-08-25 bc79e1fae76dffb3cbc3ddfa9ba23e66e150d098
src/views/qualityManagement/nonconformingManagement/index.vue
@@ -1,41 +1,45 @@
<template>
  <div class="app-container">
    <div class="search_form">
      <div style="display: flex;flex-direction: row;align-items: center;">
        <div>
          <span class="search_title">类型:</span>
          <el-select v-model="searchForm.inspectType" clearable style="width: 240px" @change="handleQuery">
      <el-form :model="searchForm" inline style="margin-bottom: 0;">
        <el-form-item label="类型:">
          <el-select v-model="searchForm.inspectType" clearable style="width: 200px" @change="handleQuery">
            <el-option label="原材料检验" :value="0" />
            <el-option label="过程检验" :value="1" />
            <el-option label="出厂检验" :value="2" />
          </el-select>
        </div>
        <div style="margin-left: 10px">
          <span class="search_title">状态:</span>
          <el-select v-model="searchForm.inspectState" clearable style="width: 240px" @change="handleQuery">
        </el-form-item>
        <el-form-item label="状态:">
          <el-select v-model="searchForm.inspectState" clearable style="width: 200px" @change="handleQuery">
            <el-option label="待处理" :value="0" />
            <el-option label="已处理" :value="1" />
          </el-select>
        </div>
        <div style="margin-left: 10px">
          <span class="search_title">产品名称:</span>
        </el-form-item>
        <el-form-item label="产品名称:">
          <el-input
              v-model="searchForm.productName"
              style="width: 240px"
              style="width: 200px"
              placeholder="请输入产品名称搜索"
              @change="handleQuery"
              clearable
              :prefix-icon="Search"
          />
        </div>
        <el-button type="primary" @click="handleQuery" style="margin-left: 10px">搜索</el-button>
      </div>
      <div>
        </el-form-item>
        <el-form-item label="检测日期:">
          <el-date-picker v-model="searchForm.entryDate" value-format="YYYY-MM-DD" format="YYYY-MM-DD" type="daterange"
                          style="width: 300px"
                          placeholder="请选择" clearable @change="changeDaterange" />
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="handleQuery">搜索</el-button>
        </el-form-item>
      </el-form>
    </div>
    <div class="mb20" style="text-align: right;">
        <el-button type="primary" @click="openForm('add')">新增</el-button>
        <el-button @click="handleOut">导出</el-button>
        <el-button type="danger" plain @click="handleDelete">删除</el-button>
      </div>
    </div>
    <div class="table_list">
      <PIMTable
          rowKey="id"
@@ -51,22 +55,61 @@
    </div>
    <FormDia ref="formDia" @close="handleQuery"></FormDia>
    <InspectionFormDia ref="inspectionFormDia" @close="handleQuery"></InspectionFormDia>
    <el-dialog v-model="uploadDialogVisible" title="拍照上传附件" width="680px">
      <el-form label-width="120px">
        <el-form-item label="不合格图片:">
          <AttachmentUploadImage
            v-model:fileList="uploadPhotoList"
            :limit="6"
            button-text="拍照/上传图片"
            :watermark-text="watermarkText"
          />
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="closeUploadDialog">取消</el-button>
        <el-button type="primary" :loading="uploadSaving" @click="submitUploadDialog">保存</el-button>
      </template>
    </el-dialog>
    <el-dialog v-model="photoPreviewVisible" :title="photoPreviewTitle" width="900px">
      <div v-if="photoPreviewList.length" class="photo-preview-grid">
        <el-image
          v-for="(url, index) in photoPreviewList"
          :key="`${url}-${index}`"
          :src="url"
          fit="cover"
          class="photo-preview-item"
          :preview-src-list="photoPreviewList"
          preview-teleported
        />
      </div>
      <el-empty v-else description="暂无附件照片" />
      <template #footer>
        <el-button @click="photoPreviewVisible = false">关闭</el-button>
      </template>
    </el-dialog>
  </div>
</template>
<script setup>
import { Search } from "@element-plus/icons-vue";
import {onMounted, ref} from "vue";
import { computed, onMounted, ref, reactive, toRefs, nextTick, getCurrentInstance } from "vue";
import FormDia from "@/views/qualityManagement/nonconformingManagement/components/formDia.vue";
import {ElMessageBox} from "element-plus";
import {qualityUnqualifiedDel, qualityUnqualifiedListPage} from "@/api/qualityManagement/nonconformingManagement.js";
import AttachmentUploadImage from "@/components/AttachmentUpload/image/index.vue";
import { ElMessageBox } from "element-plus";
import { getQualityUnqualifiedInfo, qualityUnqualifiedDel, qualityUnqualifiedListPage, qualityUnqualifiedUpdate } from "@/api/qualityManagement/nonconformingManagement.js";
import InspectionFormDia from "@/views/qualityManagement/nonconformingManagement/components/inspectionFormDia.vue";
import useUserStore from "@/store/modules/user";
import dayjs from "dayjs";
const data = reactive({
  searchForm: {
    inspectType: "",
    inspectState: "",
    productName: "",
    entryDate: undefined, // 录入日期
    entryDateStart: undefined,
    entryDateEnd: undefined,
  },
});
const { searchForm } = toRefs(data);
@@ -90,7 +133,7 @@
      } else if (params == '合格') {
        return "success";
      } else {
        return null;
        return 'danger';
      }
    },
  },
@@ -155,6 +198,28 @@
    width: 120
  },
  {
    label: "不合格类型",
    prop: "dealType",
    width: 120,
    formatData: val => {
      if (val === 0) return "轻微返工";
      if (val === 1) return "严重返工";
      if (val === 2) return "报废";
      return "-";
    }
  },
  {
    label: "修理工时",
    prop: "repairWorkHour",
    width: 100
  },
  {
    label: "重生新单",
    prop: "regenerateNewOrder",
    width: 100,
    formatData: val => (val === 1 ? "是" : "否")
  },
  {
    label: "处理人",
    prop: "dealName",
    width: 120
@@ -169,25 +234,26 @@
    label: "操作",
    align: "center",
    fixed: "right",
    width: 120,
    operation: [
      {
        name: "编辑",
        type: "text",
        clickFun: (row) => {
          openForm("edit", row);
      width: 240,
      operation: [
        {
          name: "处理",
          type: "text",
          clickFun: (row) => {
            openInspectionForm("edit", row);
          },
          disabled: (row) => row.inspectState === 1,
        },
      },
      {
        name: "处理",
        type: "text",
        clickFun: (row) => {
          openInspectionForm("edit", row);
        {
          name: "拍照上传",
          type: "text",
          clickFun: (row) => {
            openUploadDialog(row);
          },
        },
      },
    ],
  },
]);
      ],
    },
  ]);
const tableData = ref([]);
const selectedRows = ref([]);
const tableLoading = ref(false);
@@ -198,8 +264,31 @@
});
const formDia = ref()
const inspectionFormDia = ref()
const photoPreviewVisible = ref(false)
const photoPreviewTitle = ref("")
const photoPreviewList = ref([])
const uploadDialogVisible = ref(false)
const uploadSaving = ref(false)
const uploadPhotoList = ref([])
const currentUploadRow = ref(null)
const { proxy } = getCurrentInstance()
const userStore = useUserStore()
const watermarkText = computed(() => {
  const now = new Date();
  const pad = (n) => String(n).padStart(2, "0");
  return `天津市玮苓乐器有限公司
${now.getFullYear()}-${pad(now.getMonth() + 1)}-${pad(now.getDate())} ${pad(now.getHours())}:${pad(now.getMinutes())}:${pad(now.getSeconds())}`;
})
const changeDaterange = (value) => {
  searchForm.value.entryDateStart = undefined;
  searchForm.value.entryDateEnd = undefined;
  if (value) {
    searchForm.value.entryDateStart = dayjs(value[0]).format("YYYY-MM-DD");
    searchForm.value.entryDateEnd = dayjs(value[1]).format("YYYY-MM-DD");
  }
  getList();
};
// 查询列表
/** 搜索按钮操作 */
const handleQuery = () => {
@@ -213,7 +302,9 @@
};
const getList = () => {
  tableLoading.value = true;
  qualityUnqualifiedListPage({...page, ...searchForm.value}).then(res => {
  const params = { ...searchForm.value, ...page };
  params.entryDate = undefined
  qualityUnqualifiedListPage(params).then(res => {
    tableLoading.value = false;
    tableData.value = res.data.records
    page.total = res.data.total;
@@ -228,15 +319,79 @@
// 打开弹框
const openForm = (type, row) => {
  if (type !== 'add' && row?.inspectState === 1) {
    proxy.$modal.msgWarning("已处理的数据不能再编辑");
    return;
  }
  nextTick(() => {
    formDia.value?.openDialog(type, row)
  })
};
// 打开处理弹框
const openInspectionForm = (type, row) => {
  if (row?.inspectState === 1) {
    proxy.$modal.msgWarning("已处理的数据不能再处理");
    return;
  }
  nextTick(() => {
    inspectionFormDia.value?.openDialog(type, row)
  })
};
const openPhotoPreview = row => {
  const urls = String(row.photoUrls || "")
    .split(",")
    .map(item => item.trim())
    .filter(Boolean);
  photoPreviewList.value = urls;
  photoPreviewTitle.value = `附件照片${row.productName ? ` - ${row.productName}` : ""}`;
  photoPreviewVisible.value = true;
};
const openUploadDialog = async (row) => {
  if (!row?.id) {
    proxy.$modal.msgWarning("未找到当前数据");
    return;
  }
  try {
    const res = await getQualityUnqualifiedInfo(row.id);
    const detail = res.data || {};
    currentUploadRow.value = detail;
    uploadPhotoList.value = detail.photoUrls
      ? String(detail.photoUrls).split(",").filter(Boolean).map((url, index) => ({
          name: `image-${index + 1}`,
          url,
        }))
      : [];
    uploadDialogVisible.value = true;
  } catch (e) {
    proxy.$modal.msgError("加载附件信息失败");
  }
};
const closeUploadDialog = () => {
  uploadDialogVisible.value = false;
  uploadSaving.value = false;
  uploadPhotoList.value = [];
  currentUploadRow.value = null;
};
const submitUploadDialog = async () => {
  if (!currentUploadRow.value?.id) {
    proxy.$modal.msgWarning("未找到当前数据");
    return;
  }
  const payload = {
    ...currentUploadRow.value,
    photoUrls: Array.isArray(uploadPhotoList.value)
      ? uploadPhotoList.value.map(item => item.url || item.previewURL || item.previewUrl || item).filter(Boolean).join(",")
      : "",
  };
  uploadSaving.value = true;
  try {
    await qualityUnqualifiedUpdate(payload);
    proxy.$modal.msgSuccess("保存成功");
    closeUploadDialog();
    getList();
  } catch (e) {
    uploadSaving.value = false;
  }
};
// 删除
@@ -282,4 +437,17 @@
});
</script>
<style scoped></style>
<style scoped>
.photo-preview-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
  gap: 12px;
}
.photo-preview-item {
  width: 100%;
  height: 180px;
  border-radius: 8px;
  overflow: hidden;
}
</style>