| | |
| | | <div class="search_form"> |
| | | <div class="search-row"> |
| | | <div class="search-item"> |
| | | <span class="search_title">工单编号:</span> |
| | | <el-input v-model="searchForm.workOrderNo" |
| | | <span class="search_title">入库日期:</span> |
| | | <el-date-picker v-model="searchForm.timeStr" |
| | | type="date" |
| | | placeholder="请选择日期" |
| | | value-format="YYYY-MM-DD" |
| | | format="YYYY-MM-DD" |
| | | clearable |
| | | @change="handleQuery"/> |
| | | </div> |
| | | <div class="search-item"> |
| | | <span class="search_title">产品大类:</span> |
| | | <el-input v-model="searchForm.productName" |
| | | style="width: 240px" |
| | | placeholder="请输入" |
| | | @change="handleQuery" |
| | | clearable |
| | | prefix-icon="Search" /> |
| | | clearable/> |
| | | </div> |
| | | <div class="search-item"> |
| | | <el-button type="primary" |
| | | @click="handleQuery">搜索</el-button> |
| | | <el-button type="primary" @click="openAddDialog" style="margin-left: 10px;">新增</el-button> |
| | | </div> |
| | | </div> |
| | | </div> |
| | |
| | | :tableData="tableData" |
| | | :page="page" |
| | | :tableLoading="tableLoading" |
| | | @pagination="pagination"> |
| | | <template #completionStatus="{ row }"> |
| | | <el-progress :percentage="toProgressPercentage(row?.completionStatus)" |
| | | :color="progressColor(toProgressPercentage(row?.completionStatus))" |
| | | :status="toProgressPercentage(row?.completionStatus) >= 100 ? 'success' : ''" /> |
| | | </template> |
| | | </PIMTable> |
| | | @pagination="pagination" /> |
| | | </div> |
| | | |
| | | <!-- 流转卡弹窗 --> |
| | |
| | | </el-dialog> |
| | | |
| | | <FilesDia ref="workOrderFilesRef" /> |
| | | |
| | | <!-- 新增工单弹窗 --> |
| | | <el-dialog v-model="addDialogVisible" |
| | | title="新增工单" |
| | | width="500px" |
| | | @close="closeAddDialog"> |
| | | <el-form ref="addFormRef" |
| | | :model="addForm" |
| | | :rules="addFormRules" |
| | | label-width="120px" |
| | | label-position="top"> |
| | | <el-form-item label="产品名称:" |
| | | prop="productId"> |
| | | <el-tree-select v-model="addForm.productId" |
| | | placeholder="请选择产品" |
| | | clearable |
| | | check-strictly |
| | | :data="productOptions" |
| | | :render-after-expand="false" |
| | | style="width: 100%" |
| | | @change="handleProductChange" /> |
| | | </el-form-item> |
| | | <el-form-item label="规格型号:" |
| | | prop="productModelId"> |
| | | <el-select v-model="addForm.productModelId" |
| | | placeholder="请选择规格型号" |
| | | clearable |
| | | style="width: 100%" |
| | | @change="handleModelChange" |
| | | filterable> |
| | | <el-option v-for="item in modelOptions" |
| | | :key="item.id" |
| | | :label="item.model" |
| | | :value="item.id" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="单位:" |
| | | prop="unit"> |
| | | <el-input v-model="addForm.unit" |
| | | placeholder="单位" |
| | | disabled |
| | | style="width: 100%" /> |
| | | </el-form-item> |
| | | <el-form-item label="数量:" |
| | | prop="quantity"> |
| | | <el-input-number v-model="addForm.quantity" |
| | | :min="1" |
| | | :step="1" |
| | | step-strictly |
| | | style="width: 100%" |
| | | placeholder="请输入数量" /> |
| | | </el-form-item> |
| | | </el-form> |
| | | <template #footer> |
| | | <span class="dialog-footer"> |
| | | <el-button type="primary" |
| | | @click="handleAddSubmit">确定</el-button> |
| | | <el-button @click="closeAddDialog">取消</el-button> |
| | | </span> |
| | | </template> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | | |
| | |
| | | downProductWorkOrder, |
| | | } from "@/api/productionManagement/workOrder.js"; |
| | | import { getUserProfile, userListNoPageByTenantId } from "@/api/system/user.js"; |
| | | import { createStockInventory } from "@/api/inventoryManagement/stockInventory.js"; |
| | | import { getStockInRecordListPage } from "@/api/inventoryManagement/stockInRecord.js"; |
| | | import { productTreeList, modelList } from "@/api/basicData/product.js"; |
| | | import { findAllQualifiedStockInRecordTypeOptions } from "@/api/basicData/enum.js"; |
| | | import QRCode from "qrcode"; |
| | | import { getCurrentInstance, reactive, toRefs } from "vue"; |
| | | import FilesDia from "./components/filesDia.vue"; |
| | | const { proxy } = getCurrentInstance(); |
| | | |
| | | // 来源类型选项 |
| | | const stockRecordTypeOptions = ref([]); |
| | | |
| | | const tableColumn = ref([ |
| | | { |
| | | label: "工单类型", |
| | | prop: "workOrderType", |
| | | width: "80", |
| | | label: "入库批次", |
| | | prop: "inboundBatches", |
| | | width: "280", |
| | | }, |
| | | { |
| | | label: "工单编号", |
| | | prop: "workOrderNo", |
| | | width: "140", |
| | | label: "入库时间", |
| | | prop: "createTime", |
| | | width: "160", |
| | | }, |
| | | { |
| | | label: "生产订单号", |
| | | prop: "productOrderNpsNo", |
| | | width: "140", |
| | | }, |
| | | { |
| | | label: "产品名称", |
| | | label: "产品大类", |
| | | prop: "productName", |
| | | width: "140", |
| | | }, |
| | | { |
| | | label: "规格", |
| | | label: "规格型号", |
| | | prop: "model", |
| | | }, |
| | | { |
| | |
| | | prop: "unit", |
| | | }, |
| | | { |
| | | label: "工序名称", |
| | | prop: "processName", |
| | | label: "入库数量", |
| | | prop: "stockInNum", |
| | | }, |
| | | { |
| | | label: "需求数量", |
| | | prop: "planQuantity", |
| | | width: "140", |
| | | label: "入库人", |
| | | prop: "createBy", |
| | | }, |
| | | { |
| | | label: "完成数量", |
| | | prop: "completeQuantity", |
| | | width: "140", |
| | | }, |
| | | { |
| | | label: "完成进度", |
| | | prop: "completionStatus", |
| | | dataType: "slot", |
| | | slot: "completionStatus", |
| | | width: "140", |
| | | }, |
| | | { |
| | | label: "计划开始时间", |
| | | prop: "planStartTime", |
| | | width: "140", |
| | | }, |
| | | { |
| | | label: "计划结束时间", |
| | | prop: "planEndTime", |
| | | width: "140", |
| | | }, |
| | | { |
| | | label: "实际开始时间", |
| | | prop: "actualStartTime", |
| | | width: "140", |
| | | }, |
| | | { |
| | | label: "实际结束时间", |
| | | prop: "actualEndTime", |
| | | width: "140", |
| | | }, |
| | | { |
| | | label: "操作", |
| | | width: "200", |
| | | align: "center", |
| | | dataType: "action", |
| | | fixed: "right", |
| | | operation: [ |
| | | { |
| | | name: "流转卡", |
| | | clickFun: row => { |
| | | downloadAndPrintWorkOrder(row); |
| | | }, |
| | | }, |
| | | { |
| | | name: "附件", |
| | | clickFun: row => { |
| | | openWorkOrderFiles(row); |
| | | }, |
| | | }, |
| | | { |
| | | name: "报工", |
| | | clickFun: row => { |
| | | showReportDialog(row); |
| | | }, |
| | | disabled: row => row.planQuantity <= 0, |
| | | }, |
| | | ], |
| | | label: "来源", |
| | | prop: "recordType", |
| | | formatData: (val) => { |
| | | return stockRecordTypeOptions.value.find(item => item.value === val)?.label || val; |
| | | } |
| | | }, |
| | | ]); |
| | | |
| | |
| | | userId: "", |
| | | productMainId: null, |
| | | }); |
| | | |
| | | // 新增工单相关 |
| | | const addDialogVisible = ref(false); |
| | | const addFormRef = ref(null); |
| | | const productOptions = ref([]); |
| | | const modelOptions = ref([]); |
| | | const addForm = reactive({ |
| | | productId: null, |
| | | productModelId: null, |
| | | productName: "", |
| | | productModelName: "", |
| | | unit: "", |
| | | quantity: 1, |
| | | }); |
| | | |
| | | // 新增表单校验规则 |
| | | const addFormRules = { |
| | | productId: [{ required: true, message: "请选择产品", trigger: "change" }], |
| | | productModelId: [{ required: true, message: "请选择规格型号", trigger: "change" }], |
| | | quantity: [{ required: true, message: "请输入数量", trigger: "blur" }], |
| | | }; |
| | | |
| | | // 本次生产数量验证规则 |
| | | const validateQuantity = (rule, value, callback) => { |
| | |
| | | |
| | | const data = reactive({ |
| | | searchForm: { |
| | | workOrderNo: "", |
| | | timeStr: "", |
| | | productName: "", |
| | | }, |
| | | }); |
| | | const { searchForm } = toRefs(data); |
| | |
| | | |
| | | const getList = () => { |
| | | tableLoading.value = true; |
| | | const params = { ...searchForm.value, ...page }; |
| | | productWorkOrderPage(params) |
| | | const params = { ...page }; |
| | | params.timeStr = searchForm.value.timeStr; |
| | | params.productName = searchForm.value.productName; |
| | | params.recordType = 2; // 默认查询 recordType 为 2(生产报工-合格入库)的数据 |
| | | params.type = '0'; // 合格入库类型 |
| | | getStockInRecordListPage(params) |
| | | .then(res => { |
| | | tableLoading.value = false; |
| | | tableData.value = res.data.records; |
| | |
| | | reportForm.userName = user ? user.nickName : ""; |
| | | }; |
| | | |
| | | // 打开新增弹窗 |
| | | const openAddDialog = () => { |
| | | // 重置表单 |
| | | addForm.productId = null; |
| | | addForm.productModelId = null; |
| | | addForm.productName = ""; |
| | | addForm.productModelName = ""; |
| | | addForm.unit = ""; |
| | | addForm.quantity = 1; |
| | | modelOptions.value = []; |
| | | // 加载产品树 |
| | | getProductOptions(); |
| | | addDialogVisible.value = true; |
| | | }; |
| | | |
| | | // 关闭新增弹窗 |
| | | const closeAddDialog = () => { |
| | | addFormRef.value?.resetFields(); |
| | | addDialogVisible.value = false; |
| | | }; |
| | | |
| | | // 获取产品树 |
| | | const getProductOptions = () => { |
| | | productTreeList().then((res) => { |
| | | productOptions.value = convertIdToValue(res); |
| | | }); |
| | | }; |
| | | |
| | | // 转换产品树数据 |
| | | function convertIdToValue(data) { |
| | | return data.map((item) => { |
| | | const { id, children, ...rest } = item; |
| | | const newItem = { |
| | | ...rest, |
| | | value: id, |
| | | }; |
| | | if (children && children.length > 0) { |
| | | newItem.children = convertIdToValue(children); |
| | | } |
| | | return newItem; |
| | | }); |
| | | } |
| | | |
| | | // 根据ID查找产品名称 |
| | | function findNodeById(nodes, productId) { |
| | | for (let i = 0; i < nodes.length; i++) { |
| | | if (nodes[i].value === productId) { |
| | | return nodes[i].label; |
| | | } |
| | | if (nodes[i].children && nodes[i].children.length > 0) { |
| | | const foundNode = findNodeById(nodes[i].children, productId); |
| | | if (foundNode) { |
| | | return foundNode; |
| | | } |
| | | } |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | // 产品选择变化 |
| | | const handleProductChange = (value) => { |
| | | addForm.productModelId = null; |
| | | addForm.unit = ""; |
| | | addForm.productModelName = ""; |
| | | if (value) { |
| | | addForm.productName = findNodeById(productOptions.value, value); |
| | | // 加载规格型号 |
| | | modelList({ id: value }).then((res) => { |
| | | modelOptions.value = res; |
| | | }); |
| | | } else { |
| | | modelOptions.value = []; |
| | | } |
| | | }; |
| | | |
| | | // 规格型号选择变化 |
| | | const handleModelChange = (value) => { |
| | | if (value) { |
| | | const model = modelOptions.value.find((item) => item.id === value); |
| | | if (model) { |
| | | addForm.unit = model.unit; |
| | | addForm.productModelName = model.model; |
| | | } |
| | | } else { |
| | | addForm.unit = ""; |
| | | addForm.productModelName = ""; |
| | | } |
| | | }; |
| | | |
| | | // 提交新增 |
| | | const handleAddSubmit = () => { |
| | | addFormRef.value?.validate((valid) => { |
| | | if (valid) { |
| | | const params = { |
| | | productId: addForm.productId, |
| | | productModelId: addForm.productModelId, |
| | | productName: addForm.productName, |
| | | productModelName: addForm.productModelName, |
| | | unit: addForm.unit, |
| | | qualitity: addForm.quantity, |
| | | type: "qualified", |
| | | warnNum: 0, |
| | | recordType: 2, |
| | | }; |
| | | createStockInventory(params).then((res) => { |
| | | proxy.$modal.msgSuccess("新增成功"); |
| | | closeAddDialog(); |
| | | getList(); |
| | | }); |
| | | } |
| | | }); |
| | | }; |
| | | |
| | | // 获取来源类型选项 |
| | | const fetchStockRecordTypeOptions = () => { |
| | | findAllQualifiedStockInRecordTypeOptions() |
| | | .then(res => { |
| | | stockRecordTypeOptions.value = res.data; |
| | | }); |
| | | }; |
| | | |
| | | onMounted(() => { |
| | | getList(); |
| | | // 获取用户列表 |
| | |
| | | userOptions.value = res.data; |
| | | } |
| | | }); |
| | | // 获取来源类型选项 |
| | | fetchStockRecordTypeOptions(); |
| | | }); |
| | | </script> |
| | | |