huminmin
12 小时以前 168e8d7c28ef162e28171392a37df09cdc1187c2
Merge branch 'dev_衡阳_鹏创电子' of http://114.132.189.42:9002/r/product-inventory-management into dev_衡阳_鹏创电子
已添加3个文件
613 ■■■■■ 文件已修改
src/api/qualityManagement/productInspectionRecord.js 54 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/qualityManagement/productInspectionRecord/components/formDia.vue 301 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/qualityManagement/productInspectionRecord/index.vue 258 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/qualityManagement/productInspectionRecord.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,54 @@
import request from '@/utils/request'
// å·¡æ£€è®°å½• åˆ†é¡µæŸ¥è¯¢
export function productInspectionRecordListPage(query) {
    return request({
        url: '/productInspectionRecord/listPage',
        method: 'get',
        params: query,
    })
}
// å·¡æ£€è®°å½• æ–°å¢ž
export function addProductInspectionRecord(data) {
    return request({
        url: '/productInspectionRecord/addProductInspectionRecord',
        method: 'post',
        data: data,
    })
}
// å·¡æ£€è®°å½• ä¿®æ”¹
export function updProductInspectionRecord(data) {
    return request({
        url: '/productInspectionRecord/updProductInspectionRecord',
        method: 'put',
        data: data,
    })
}
// å·¡æ£€è®°å½• åˆ é™¤
export function delProductInspectionRecord(ids) {
    return request({
        url: `/productInspectionRecord/${ids}`,
        method: 'delete',
    })
}
// å·¡æ£€è®°å½• é€šçŸ¥
export function notifyProductInspectionRecord(ids) {
    return request({
        url: '/productInspectionRecord/notify',
        method: 'post',
        data: ids,
    })
}
// æ ¹æ®å·¥åºå’Œæ£€éªŒç±»åž‹èŽ·å–æ£€æµ‹é¡¹ç›®
export function getParameterItemByProcessOrCategory(params) {
    return request({
        url: '/qualityTestStandard/getParameterItemByProcessOrCategory',
        method: 'get',
        params: params,
    })
}
src/views/qualityManagement/productInspectionRecord/components/formDia.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,301 @@
<template>
  <el-dialog
      v-model="dialogFormVisible"
      :title="operationType === 'add' ? '新增巡检记录' : '编辑巡检记录'"
      width="700px"
      @close="closeDia"
  >
    <el-form :model="form" label-width="140px" label-position="top" :rules="rules" ref="formRef">
      <el-row :gutter="20">
        <el-col :span="12">
          <el-form-item label="工序:" prop="processId">
            <el-select v-model="form.processId" placeholder="请选择工序" clearable @change="handleProcessChange" style="width: 100%">
              <el-option
                  v-for="item in processList"
                  :key="item.id"
                  :label="item.processName || item.name"
                  :value="item.id"
              />
            </el-select>
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="巡检时间:" prop="inspectionTime">
            <el-date-picker
                v-model="form.inspectionTime"
                value-format="YYYY-MM-DD HH:mm:ss"
                format="YYYY-MM-DD HH:mm:ss"
                type="datetime"
                placeholder="请选择巡检时间"
                style="width: 100%"
            />
          </el-form-item>
        </el-col>
      </el-row>
      <el-row :gutter="20">
        <el-col :span="12">
          <el-form-item label="巡检员:" prop="inspector">
            <el-input v-model="form.inspector" placeholder="请输入巡检员" />
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="检测项:" prop="inspectionItem">
            <el-select v-model="form.inspectionItem" placeholder="请选择检测项" clearable @change="handleInspectionItemChange" style="width: 100%">
              <el-option v-for="item in inspectionItemList" :key="item.parameterItem" :label="item.parameterItem" :value="item.parameterItem" />
            </el-select>
          </el-form-item>
        </el-col>
      </el-row>
      <el-row :gutter="20">
        <el-col :span="12">
          <el-form-item label="标准要求:" prop="standardRequirement">
            <el-input v-model="form.standardRequirement" placeholder="标准要求" readonly />
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="实测值:" prop="actualValue">
            <el-input v-model="form.actualValue" placeholder="请输入实测值" />
          </el-form-item>
        </el-col>
      </el-row>
      <el-row :gutter="20">
        <el-col :span="12">
          <el-form-item label="判定:" prop="judgement">
            <el-select v-model="form.judgement" placeholder="请选择" clearable style="width: 100%">
              <el-option label="合格" value="yes" />
              <el-option label="不合格" value="no" />
            </el-select>
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="不合格订单:" prop="unqualifiedOrder">
            <el-input v-model="form.unqualifiedOrder" placeholder="请输入不合格订单" />
          </el-form-item>
        </el-col>
      </el-row>
      <el-row :gutter="20">
        <el-col :span="24">
          <el-form-item label="备注:" prop="remark">
            <el-input v-model="form.remark" type="textarea" :rows="3" placeholder="请输入备注" />
          </el-form-item>
        </el-col>
      </el-row>
    </el-form>
    <template #footer>
      <div class="dialog-footer">
        <el-button type="primary" @click="submitForm">确认</el-button>
        <el-button @click="closeDia">取消</el-button>
      </div>
    </template>
  </el-dialog>
</template>
<script setup>
import { ref, reactive } from "vue";
import { ElMessage } from "element-plus";
import { addProductInspectionRecord, updProductInspectionRecord, getParameterItemByProcessOrCategory } from "@/api/qualityManagement/productInspectionRecord.js";
import { processList as getProcessList } from "@/api/productionManagement/productionProcess.js";
import useUserStore from "@/store/modules/user";
const userStore = useUserStore();
const dialogFormVisible = ref(false);
const operationType = ref("add");
const formRef = ref(null);
const form = reactive({
  id: undefined,
  processId: undefined,
  process: "",
  checkDate: undefined,
  inspector: "",
  inspectionTime: undefined,
  inspectionItem: "",
  standardRequirement: "",
  actualValue: "",
  judgement: "",
  unqualifiedOrder: "",
  remark: "",
  createUser: "",
  createTime: undefined,
});
const processList = ref([]);
const inspectionItemList = ref([]);
/** å·¥åº id ä¸ŽåŽç«¯å¯èƒ½ä¸º number/string,统一比较 */
const sameProcessId = (a, b) => a != null && b != null && String(a) === String(b);
/** ä»Žå·¥åºåˆ—表取与 row åŒ¹é…çš„ id(保证与 el-option çš„ value ç±»åž‹ä¸€è‡´ï¼Œé¿å…å›žæ˜¾æˆçº¯æ•°å­—) */
const resolveProcessIdFromRow = (row) => {
  let pid = row.processId ?? row.process_id;
  if (pid != null && pid !== "") {
    const hit = processList.value.find((item) => sameProcessId(item.id, pid));
    return hit ? hit.id : pid;
  }
  // éƒ¨åˆ†æŽ¥å£æŠŠå·¥åº id å­˜åœ¨ process å­—段里
  const p = row.process;
  if (p != null && p !== "" && /^\d+$/.test(String(p).trim())) {
    const hit = processList.value.find((item) => sameProcessId(item.id, p));
    return hit ? hit.id : p;
  }
  return undefined;
};
const getProcessLabel = (item) => item?.processName || item?.name || "";
const rules = {
  processId: [{ required: true, message: "请选择工序", trigger: "change" }],
  checkDate: [{ required: true, message: "请选择巡检日期", trigger: "change" }],
};
const loadProcessList = async () => {
  try {
    const res = await getProcessList({ current: 1, size: 1000 });
    processList.value = res.data || [];
  } catch (error) {
    console.error("加载工序列表失败", error);
  }
};
/**
 * @param processId å·¥åº id
 * @param options.preserveInspection ä¸º true æ—¶ä¿ç•™å·²æœ‰æ£€æµ‹é¡¹/标准(编辑回显)
 */
const handleProcessChange = async (processId, options = {}) => {
  const { preserveInspection = false } = options;
  if (!preserveInspection) {
    form.process = "";
    form.inspectionItem = "";
    form.standardRequirement = "";
  }
  inspectionItemList.value = [];
  if (!processId) {
    return;
  }
  const process = processList.value.find((item) => sameProcessId(item.id, processId));
  if (process) {
    form.process = getProcessLabel(process);
  }
  try {
    const { data } = await getParameterItemByProcessOrCategory({
      id: processId,
      inspectType: 3,
    });
    if (data && data.length > 0) {
      inspectionItemList.value = data;
      if (preserveInspection && form.inspectionItem) {
        const cur = data.find((i) => i.parameterItem === form.inspectionItem);
        form.standardRequirement = cur?.standardValue ?? form.standardRequirement ?? "";
      } else {
        const firstItem = data[0];
        form.inspectionItem = firstItem.parameterItem;
        form.standardRequirement = firstItem.standardValue || "";
      }
    }
  } catch (error) {
    console.error("加载检测项目失败", error);
  }
};
const handleInspectionItemChange = (val) => {
  if (!val) {
    form.standardRequirement = "";
    return;
  }
  const item = inspectionItemList.value.find(i => i.parameterItem === val);
  if (item) {
    form.standardRequirement = item.standardValue || "";
  }
};
const open = async (type, row) => {
  operationType.value = type;
  await loadProcessList();
  if (type === "edit" && row) {
    Object.assign(form, row);
    const resolvedId = resolveProcessIdFromRow(row);
    if (resolvedId != null && resolvedId !== "") {
      form.processId = resolvedId;
      const processItem = processList.value.find((item) => sameProcessId(item.id, resolvedId));
      if (processItem) {
        form.process = getProcessLabel(processItem);
      } else if (row.process && !/^\d+$/.test(String(row.process).trim())) {
        form.process = row.process;
      }
    }
    if (form.processId != null && form.processId !== "") {
      await handleProcessChange(form.processId, { preserveInspection: true });
    }
  } else {
    resetForm();
  }
  dialogFormVisible.value = true;
};
const formatDateTime = () => {
  const now = new Date();
  const year = now.getFullYear();
  const month = String(now.getMonth() + 1).padStart(2, '0');
  const day = String(now.getDate()).padStart(2, '0');
  const hours = String(now.getHours()).padStart(2, '0');
  const minutes = String(now.getMinutes()).padStart(2, '0');
  const seconds = String(now.getSeconds()).padStart(2, '0');
  return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
};
const resetForm = () => {
  form.id = undefined;
  form.processId = undefined;
  form.process = "";
  form.checkDate = undefined;
  form.inspector = "";
  form.inspectionTime = formatDateTime();
  form.inspectionItem = "";
  form.standardRequirement = "";
  form.actualValue = "";
  form.judgement = "";
  form.unqualifiedOrder = "";
  form.remark = "";
  form.createUser = "";
  form.createTime = undefined;
  inspectionItemList.value = [];
};
const closeDia = () => {
  dialogFormVisible.value = false;
  resetForm();
};
const submitForm = async () => {
  const valid = await formRef.value.validate().catch(() => false);
  if (!valid) return;
  const p = processList.value.find((item) => sameProcessId(item.id, form.processId));
  form.process = getProcessLabel(p);
  try {
    if (operationType.value === "add") {
      await addProductInspectionRecord(form);
      ElMessage.success("新增成功");
    } else {
      await updProductInspectionRecord(form);
      ElMessage.success("修改成功");
    }
    closeDia();
    emit("close");
  } catch (error) {
    console.error(error);
  }
};
const emit = defineEmits(["close"]);
defineExpose({
  open,
});
</script>
<style scoped>
</style>
src/views/qualityManagement/productInspectionRecord/index.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,258 @@
<template>
  <div class="app-container">
    <div class="search_form">
      <div>
        <span class="search_title">工序:</span>
        <el-input
            v-model="searchForm.process"
            style="width: 240px"
            placeholder="请输入工序搜索"
            @change="handleQuery"
            clearable
        />
        <span style="margin-left: 10px" class="search_title">巡检日期:</span>
        <el-date-picker v-model="searchForm.checkDate"
                        value-format="YYYY-MM-DD HH:mm:ss"
                        format="YYYY-MM-DD HH:mm:ss"
                        type="datetimerange"
                        placeholder="请选择"
                        clearable
                        @change="changeDaterange" />
        <el-button type="primary" @click="handleQuery" style="margin-left: 10px"
        >搜索</el-button
        >
      </div>
      <div>
        <el-button type="primary" @click="openForm('add')">新增</el-button>
        <el-button type="danger" plain @click="handleDelete">删除</el-button>
        <el-button type="success" plain @click="handleNotify">通知</el-button>
      </div>
    </div>
    <div class="table_list">
      <PIMTable
          rowKey="id"
          :column="tableColumn"
          :tableData="tableData"
          :page="page"
          :isSelection="true"
          @selection-change="handleSelectionChange"
          :tableLoading="tableLoading"
          @pagination="pagination"
          :total="page.total"
      ></PIMTable>
    </div>
    <FormDia ref="formDia" @close="handleQuery"></FormDia>
  </div>
</template>
<script setup>
import { onMounted, ref, reactive, toRefs } from "vue";
import FormDia from "./components/formDia.vue";
import {ElMessage, ElMessageBox} from "element-plus";
import {
  productInspectionRecordListPage,
  delProductInspectionRecord,
  notifyProductInspectionRecord
} from "@/api/qualityManagement/productInspectionRecord.js";
const data = reactive({
  searchForm: {
    keyword: "",
    checkDate: undefined,
    checkDateStart: undefined,
    checkDateEnd: undefined,
  },
});
const { searchForm } = toRefs(data);
const tableData = ref([]);
const tableLoading = ref(false);
const page = reactive({
  current: 1,
  size: 10,
  total: 0,
});
const ids = ref([]);
const tableColumn = ref([
  {
    label: "工序",
    prop: "process",
  },
  {
    label: "检测项",
    prop: "inspectionItem",
  },
  {
    label: "标准要求",
    prop: "standardRequirement",
  },
  {
    label: "实测值",
    prop: "actualValue",
  },
  {
    label: "判定",
    prop: "judgement",
    dataType: "tag",
    formatData: (params) => {
      if (params === 'yes') {
        return "合格";
      } else if (params === 'no') {
        return "不合格";
      }
      return params;
    },
    formatType: (params) => {
      if (params === 'yes') {
        return "success";
      } else if (params === 'no') {
        return "danger";
      }
      return null;
    },
  },
  {
    label: "不合格订单",
    prop: "unqualifiedOrder",
  },
  {
    label: "巡检日期",
    prop: "inspectionTime",
    width: 160
  },
  {
    label: "巡检员",
    prop: "inspector",
  },
  {
    label: "创建人",
    prop: "createUser",
  },
  {
    label: "创建时间",
    prop: "createTime",
    width: 160
  },
  {
    dataType: "action",
    label: "操作",
    align: "center",
    fixed: "right",
    width: 150,
    operation: [
      {
        name: "编辑",
        type: "text",
        clickFun: (row) => {
          openForm("edit", row);
        },
      },
      {
        name: "删除",
        type: "text",
        clickFun: (row) => {
          handleDelete(row);
        },
      },
    ],
  },
]);
const formDia = ref(null);
const openForm = (type, row) => {
  formDia.value.open(type, row);
};
const changeDaterange = (val) => {
  if (val) {
    searchForm.value.startTime = val[0];
    searchForm.value.endTime = val[1];
  } else {
    searchForm.value.startTime = undefined;
    searchForm.value.endTime = undefined;
  }
  handleQuery();
};
const handleQuery = () => {
  page.current = 1;
  getList();
};
const pagination = (obj) => {
  page.current = obj.page;
  page.size = obj.limit;
  getList();
};
const getList = async () => {
  tableLoading.value = true;
  try {
    const res = await productInspectionRecordListPage({
      ...searchForm.value,
      current: page.current,
      size: page.size,
    });
    tableData.value = res.data.records || [];
    page.total = res.data.total || 0;
  } finally {
    tableLoading.value = false;
  }
};
const handleSelectionChange = (selection) => {
  ids.value = selection.map((item) => item.id);
};
const handleDelete = (row) => {
  const _ids = row ? [row.id] : ids.value;
  if (_ids.length === 0) {
    ElMessage.warning("请选择要删除的数据");
    return;
  }
  ElMessageBox.confirm("是否确认删除选中的数据?", "警告", {
    confirmButtonText: "确定",
    cancelButtonText: "取消",
    type: "warning",
  }).then(async () => {
    await delProductInspectionRecord(_ids);
    ElMessage.success("删除成功");
    getList();
  });
};
const handleNotify = () => {
  if (ids.value.length === 0) {
    ElMessage.warning("请选择要通知的数据");
    return;
  }
  ElMessageBox.confirm("是否确认发送通知?", "警告", {
    confirmButtonText: "确定",
    cancelButtonText: "取消",
    type: "warning",
  }).then(async () => {
    await notifyProductInspectionRecord(ids.value);
    ElMessage.success("发送通知成功");
  })
};
onMounted(() => {
  getList();
});
</script>
<style scoped lang="scss">
.search_form {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 16px;
}
.search_title {
  font-size: 14px;
  color: #606266;
}
</style>