|
@@ -0,0 +1,451 @@
|
|
|
+<template>
|
|
|
+ <div>
|
|
|
+ <el-scrollbar>
|
|
|
+ <el-drawer
|
|
|
+ v-model="drawerVisible"
|
|
|
+ size="800"
|
|
|
+ :close-on-click-modal="false"
|
|
|
+ >
|
|
|
+ <template #header>
|
|
|
+ <h4>填报检验报告</h4>
|
|
|
+ </template>
|
|
|
+ <template #default>
|
|
|
+ <el-form
|
|
|
+ ref="baseInfoRef"
|
|
|
+ :model="saleForm"
|
|
|
+ label-width="120"
|
|
|
+ :rules="rules"
|
|
|
+ style="max-width: 600px"
|
|
|
+ >
|
|
|
+ <el-form-item label="抽样数量" prop="seqNum">
|
|
|
+ <el-input v-model="saleForm.seqNum" />
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="温度" prop="temperature">
|
|
|
+ <el-input v-model="saleForm.temperature"></el-input>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="湿度" prop="humidity">
|
|
|
+ <el-input v-model="saleForm.humidity" />
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="检验依据/技术要求" prop="pursuant">
|
|
|
+ <el-input v-model="saleForm.pursuant" />
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="主要测试仪器及设备" prop="device">
|
|
|
+ <el-input v-model="saleForm.device" />
|
|
|
+ </el-form-item>
|
|
|
+
|
|
|
+ <!-- 动态增删的表单部分 -->
|
|
|
+ <div class="dynamic-form-section">
|
|
|
+ <div
|
|
|
+ v-for="(item, index) in projectInfo"
|
|
|
+ :key="index"
|
|
|
+ class="dynamic-item"
|
|
|
+ >
|
|
|
+ <el-form-item
|
|
|
+ :label="'检验项目' + (index + 1)"
|
|
|
+ :prop="'projectInfo.' + index + '.checkProject'"
|
|
|
+ >
|
|
|
+ <el-input
|
|
|
+ v-model="item.checkProject"
|
|
|
+ placeholder="请输入检验项目"
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+
|
|
|
+ <el-form-item
|
|
|
+ :label="'检验要求' + (index + 1)"
|
|
|
+ :prop="'projectInfo.' + index + '.checkRequired'"
|
|
|
+ >
|
|
|
+ <el-input
|
|
|
+ v-model="item.checkRequired"
|
|
|
+ placeholder="请输入检验要求"
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+
|
|
|
+ <el-form-item
|
|
|
+ :label="'检验结果/实测数据' + (index + 1)"
|
|
|
+ :prop="'projectInfo.' + index + '.checkResult'"
|
|
|
+ >
|
|
|
+ <el-input
|
|
|
+ v-model="item.checkResult"
|
|
|
+ placeholder="请输入检验结果"
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+
|
|
|
+ <div class="item-actions">
|
|
|
+ <el-button
|
|
|
+ type="danger"
|
|
|
+ @click="removeItem(index)"
|
|
|
+ :disabled="projectInfo.length <= 1"
|
|
|
+ size="small"
|
|
|
+ >
|
|
|
+ 删除
|
|
|
+ </el-button>
|
|
|
+ <el-button
|
|
|
+ type="primary"
|
|
|
+ @click="addItem"
|
|
|
+ v-if="index === projectInfo.length - 1"
|
|
|
+ size="small"
|
|
|
+ >
|
|
|
+ 添加
|
|
|
+ </el-button>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </el-form>
|
|
|
+
|
|
|
+ <el-form
|
|
|
+ ref="remark1Ref"
|
|
|
+ :model="remark1"
|
|
|
+ label-width="120"
|
|
|
+ :rules="rules1"
|
|
|
+ style="max-width: 600px"
|
|
|
+ >
|
|
|
+ <el-form-item label="检验结论" prop="content">
|
|
|
+ <el-input v-model="remark1.content" type="textarea" />
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="填表人" prop="user">
|
|
|
+ <el-tree-select
|
|
|
+ v-model="remark1.user"
|
|
|
+ :data="userList"
|
|
|
+ filterable
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="检验人" prop="user1">
|
|
|
+ <el-tree-select
|
|
|
+ v-model="remark1.user1"
|
|
|
+ :data="userList"
|
|
|
+ filterable
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="日期" prop="time">
|
|
|
+ <el-date-picker
|
|
|
+ v-model="remark1.time"
|
|
|
+ type="date"
|
|
|
+ placeholder="请选择日期"
|
|
|
+ clearable
|
|
|
+ format="YYYY年MM月DD日"
|
|
|
+ value-format="YYYY年MM月DD日"
|
|
|
+ style="width: 100%"
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="备注" prop="notes">
|
|
|
+ <el-input v-model="remark1.notes" type="textarea" />
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="下一步处理人" prop="nextRemarkUser">
|
|
|
+ <el-tree-select
|
|
|
+ v-model="remark1.nextRemarkUser"
|
|
|
+ :data="userList"
|
|
|
+ filterable
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+ </el-form>
|
|
|
+ </template>
|
|
|
+ <template #footer>
|
|
|
+ <div class="drawer-bottom">
|
|
|
+ <el-button @click="cancelClick">取消</el-button>
|
|
|
+ <el-button type="primary" @click="confirmClick">提交</el-button>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ </el-drawer>
|
|
|
+ </el-scrollbar>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script setup>
|
|
|
+import {
|
|
|
+ updateInspectionData,
|
|
|
+ getInspectionDetail,
|
|
|
+} from "@/api/statistic/inspectionReport";
|
|
|
+import { getOrderList } from "@/api/sales/index";
|
|
|
+import { getUserTree } from "@/api/user/index";
|
|
|
+import { useDictionaryStore } from "@/store";
|
|
|
+import { ref, reactive } from "vue";
|
|
|
+
|
|
|
+const drawerVisible = ref(false);
|
|
|
+const disabledDate = (time) => {
|
|
|
+ return time.getTime() < Date.now() - 8.64e7;
|
|
|
+};
|
|
|
+const disabledDate1 = (time) => {
|
|
|
+ return time.getTime() > Date.now() - 8.64e7;
|
|
|
+};
|
|
|
+
|
|
|
+const { dicts } = useDictionaryStore();
|
|
|
+const auditTypes = dicts.unqualified_audit_type;
|
|
|
+const levelTypes = ref([
|
|
|
+ { dictValue: "0", dictLabel: "一级" },
|
|
|
+ { dictValue: "1", dictLabel: "二级" },
|
|
|
+]);
|
|
|
+
|
|
|
+const baseInfoRef = ref(null);
|
|
|
+const saleForm = reactive({
|
|
|
+ id: "",
|
|
|
+ seqNum: "",
|
|
|
+ temperature: "",
|
|
|
+ humidity: "",
|
|
|
+ pursuant: "",
|
|
|
+ device: "",
|
|
|
+});
|
|
|
+
|
|
|
+// 动态表单数据
|
|
|
+const projectInfo = ref([
|
|
|
+ {
|
|
|
+ checkProject: "",
|
|
|
+ checkRequired: "",
|
|
|
+ checkResult: "",
|
|
|
+ },
|
|
|
+]);
|
|
|
+
|
|
|
+// 动态表单验证规则
|
|
|
+const dynamicRules = {
|
|
|
+ checkProject: [
|
|
|
+ { required: true, message: "请输入检验项目", trigger: "blur" },
|
|
|
+ ],
|
|
|
+ checkRequired: [
|
|
|
+ { required: true, message: "请输入检验要求", trigger: "blur" },
|
|
|
+ ],
|
|
|
+ checkResult: [{ required: true, message: "请输入检验结果", trigger: "blur" }],
|
|
|
+};
|
|
|
+
|
|
|
+// 添加项目
|
|
|
+const addItem = () => {
|
|
|
+ projectInfo.value.push({
|
|
|
+ checkProject: "",
|
|
|
+ checkRequired: "",
|
|
|
+ checkResult: "",
|
|
|
+ });
|
|
|
+};
|
|
|
+
|
|
|
+// 删除项目
|
|
|
+const removeItem = (index) => {
|
|
|
+ if (projectInfo.value.length > 1) {
|
|
|
+ projectInfo.value.splice(index, 1);
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+// 顾客投诉或建议
|
|
|
+const remark1Ref = ref(null);
|
|
|
+
|
|
|
+const remark1 = reactive({
|
|
|
+ content: "",
|
|
|
+ user: "",
|
|
|
+ user1: "",
|
|
|
+ time: "",
|
|
|
+ notes: "",
|
|
|
+ nextRemarkUser: "",
|
|
|
+});
|
|
|
+
|
|
|
+const rules = {
|
|
|
+ seqNum: [{ required: true, message: "请输入抽样数量", trigger: "blur" }],
|
|
|
+ temperature: [{ required: true, message: "请输入温度", trigger: "blur" }],
|
|
|
+ humidity: [{ required: true, message: "请输入湿度", trigger: "blur" }],
|
|
|
+ pursuant: [{ required: true, message: "请输入检验依据", trigger: "blur" }],
|
|
|
+ device: [
|
|
|
+ { required: true, message: "请输入测试仪器及设备", trigger: "blur" },
|
|
|
+ ],
|
|
|
+};
|
|
|
+
|
|
|
+const rules1 = {
|
|
|
+ content: [
|
|
|
+ {
|
|
|
+ required: true,
|
|
|
+ message: "请输入不合格现象(质量问题)描述",
|
|
|
+ trigger: "blur",
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ user: [{ required: true, message: "请输入姓名", trigger: "blur" }],
|
|
|
+ user1: [{ required: true, message: "检验人员不能为空", trigger: "blur" }],
|
|
|
+ time: [{ required: true, message: "请选择日期", trigger: "change" }],
|
|
|
+ nextRemarkUser: [
|
|
|
+ { required: true, message: "请选择处理人", trigger: "change" },
|
|
|
+ ],
|
|
|
+};
|
|
|
+
|
|
|
+// 订单相关信息
|
|
|
+const orders = ref([]);
|
|
|
+const opOptions = ref([...dicts.spc_operation]);
|
|
|
+const typeList = dicts.sales_info_type;
|
|
|
+const selectedOrder = ref({});
|
|
|
+const selectOrderCode = ref("");
|
|
|
+const getOrders = async () => {
|
|
|
+ const res = await getOrderList({
|
|
|
+ pageNo: 0,
|
|
|
+ pageSize: 200,
|
|
|
+ });
|
|
|
+ orders.value = res.data.records;
|
|
|
+ if (orders.value.length > 0) {
|
|
|
+ // selectOrderCode.value = orders.value[0].orderCode;
|
|
|
+ // selectedOrder.value = orders.value[0];
|
|
|
+ }
|
|
|
+};
|
|
|
+const orderSelect = (value) => {
|
|
|
+ selectedOrder.value = value;
|
|
|
+ seqList.value = selectedOrder.value.seqs.map((item, index) => ({
|
|
|
+ value: item,
|
|
|
+ label: item,
|
|
|
+ }));
|
|
|
+ saleForm.seqs = [];
|
|
|
+};
|
|
|
+
|
|
|
+const seqList = ref([]);
|
|
|
+
|
|
|
+// 用户信息
|
|
|
+const userInfo = ref({});
|
|
|
+const userList = ref([]);
|
|
|
+const getUserInfo = async () => {
|
|
|
+ getUserTree().then((data) => {
|
|
|
+ userList.value = data.data;
|
|
|
+ });
|
|
|
+};
|
|
|
+
|
|
|
+const showDrawer = (row) => {
|
|
|
+ getUserInfo();
|
|
|
+ getInspectionDetail(row.id).then((res) => {
|
|
|
+ saleForm.id = res.data.id;
|
|
|
+ saleForm.batchNum = res.data.batchNum;
|
|
|
+ saleForm.seqNum = res.data.seqNum;
|
|
|
+ saleForm.temperature = res.data.temperature;
|
|
|
+ saleForm.humidity = res.data.humidity;
|
|
|
+ saleForm.pursuant = res.data.pursuant;
|
|
|
+ saleForm.device = res.data.device;
|
|
|
+
|
|
|
+ // 处理动态表单数据
|
|
|
+ if (res.data.projectInfo) {
|
|
|
+ projectInfo.value = JSON.parse(res.data.projectInfo);
|
|
|
+ } else {
|
|
|
+ // 兼容旧数据
|
|
|
+ projectInfo.value = [
|
|
|
+ {
|
|
|
+ checkProject: res.data.checkProject || "",
|
|
|
+ checkRequired: res.data.checkRequired || "",
|
|
|
+ checkResult: res.data.checkResult || "",
|
|
|
+ },
|
|
|
+ ];
|
|
|
+ }
|
|
|
+
|
|
|
+ remark1.content = res.data.remark3
|
|
|
+ ? JSON.parse(res.data.remark3).content
|
|
|
+ : "";
|
|
|
+ remark1.user = res.data.remark3 ? JSON.parse(res.data.remark3).user : "";
|
|
|
+ remark1.user1 = res.data.remark3 ? JSON.parse(res.data.remark3).user1 : "";
|
|
|
+ remark1.time = res.data.remark3 ? JSON.parse(res.data.remark3).time : "";
|
|
|
+ remark1.notes = res.data.remark3 ? JSON.parse(res.data.remark3).notes : "";
|
|
|
+ remark1.nextRemarkUser = res.data.remark4
|
|
|
+ ? JSON.parse(res.data.remark4).user
|
|
|
+ : "";
|
|
|
+ });
|
|
|
+ drawerVisible.value = true;
|
|
|
+};
|
|
|
+
|
|
|
+defineExpose({ showDrawer });
|
|
|
+
|
|
|
+const cancelClick = () => {
|
|
|
+ drawerVisible.value = false;
|
|
|
+ baseInfoRef.value?.resetFields();
|
|
|
+ remark1Ref.value?.resetFields();
|
|
|
+ selectedOrder.value = {};
|
|
|
+ // 重置动态表单
|
|
|
+ projectInfo.value = [
|
|
|
+ {
|
|
|
+ checkProject: "",
|
|
|
+ checkRequired: "",
|
|
|
+ checkResult: "",
|
|
|
+ },
|
|
|
+ ];
|
|
|
+};
|
|
|
+
|
|
|
+const feedBackEmit = defineEmits(["finish"]);
|
|
|
+
|
|
|
+const confirmClick = () => {
|
|
|
+ // 验证基础表单
|
|
|
+ baseInfoRef.value.validate((valid) => {
|
|
|
+ if (!valid) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 验证动态表单
|
|
|
+ let dynamicValid = true;
|
|
|
+ projectInfo.value.forEach((item, index) => {
|
|
|
+ if (!item.checkProject || !item.checkRequired || !item.checkResult) {
|
|
|
+ dynamicValid = false;
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ if (!dynamicValid) {
|
|
|
+ ElMessage.error("请填写完整的检验项目信息");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 验证备注表单
|
|
|
+ remark1Ref.value.validate((valid) => {
|
|
|
+ if (valid) {
|
|
|
+ let remark1Copy = {
|
|
|
+ content: remark1.content,
|
|
|
+ user: remark1.user,
|
|
|
+ user1: remark1.user1,
|
|
|
+ time: remark1.time,
|
|
|
+ notes: remark1.notes,
|
|
|
+ };
|
|
|
+ let remark2 = {
|
|
|
+ content: "",
|
|
|
+ user2: remark1.nextRemarkUser,
|
|
|
+ time: "",
|
|
|
+ };
|
|
|
+
|
|
|
+ let p = {
|
|
|
+ ...saleForm,
|
|
|
+ state: 1, // 待处理
|
|
|
+ currentUserName: remark1.nextRemarkUser,
|
|
|
+ remark3: JSON.stringify(remark1Copy),
|
|
|
+ remark4: JSON.stringify(remark2),
|
|
|
+ projectInfo: JSON.stringify(projectInfo.value), // 保存动态表单数据
|
|
|
+ };
|
|
|
+
|
|
|
+ updateInspectionData(p)
|
|
|
+ .then(() => {
|
|
|
+ ElMessage.success("提交成功");
|
|
|
+ feedBackEmit("finish");
|
|
|
+ cancelClick();
|
|
|
+ })
|
|
|
+ .catch((err) => {
|
|
|
+ ElMessage.error("提交失败: " + err.message);
|
|
|
+ });
|
|
|
+ }
|
|
|
+ });
|
|
|
+ });
|
|
|
+};
|
|
|
+</script>
|
|
|
+
|
|
|
+<style scoped lang="scss">
|
|
|
+.drawer-bottom {
|
|
|
+ display: flex;
|
|
|
+ justify-content: flex-start;
|
|
|
+ align-items: center;
|
|
|
+ margin-top: 20px;
|
|
|
+}
|
|
|
+
|
|
|
+.dynamic-form-section {
|
|
|
+ margin: 20px 0;
|
|
|
+}
|
|
|
+
|
|
|
+.dynamic-item {
|
|
|
+ padding: 15px;
|
|
|
+ margin-bottom: 15px;
|
|
|
+ border-radius: 4px;
|
|
|
+ position: relative;
|
|
|
+
|
|
|
+ &:hover {
|
|
|
+ border-color: #c0c4cc;
|
|
|
+ box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.item-actions {
|
|
|
+ display: flex;
|
|
|
+ justify-content: flex-end;
|
|
|
+ gap: 10px;
|
|
|
+ margin-top: 10px;
|
|
|
+}
|
|
|
+
|
|
|
+:deep(.el-form-item) {
|
|
|
+ margin-bottom: 18px;
|
|
|
+}
|
|
|
+</style>
|