<template>
|
<el-dialog v-model="localVisible"
|
:title="dialogTitle"
|
width="800px"
|
@close="handleClose">
|
<!-- 步骤条 -->
|
<el-steps :active="activeStep"
|
finish-status="success"
|
v-if="!props.data.id">
|
<el-step title="选择生产订单" />
|
<el-step title="填写基础信息" />
|
<el-step title="查看工序参数" />
|
<el-step title="填写产量信息" />
|
</el-steps>
|
<!-- 第一步:选择生产订单 -->
|
<div v-if="activeStep === 0">
|
<el-form :model="form"
|
ref="formRef"
|
label-width="120px">
|
<el-form-item label="生产订单"
|
prop="orderId"
|
required>
|
<el-select v-model="orderId"
|
placeholder="请选择生产订单"
|
clearable
|
filterable
|
style="width: 100%"
|
:loading="orderLoading"
|
@change="handleOrderChange">
|
<el-option v-for="order in orderList"
|
:key="order.id"
|
:label="`${order.npsNo} - ${order.productName} ${order.model}`"
|
:value="order.id" />
|
</el-select>
|
</el-form-item>
|
</el-form>
|
</div>
|
<!-- 第二步:填写基础信息 -->
|
<div v-else-if="activeStep === 1">
|
<el-form :model="form"
|
:rules="rules"
|
ref="formRef"
|
label-width="120px">
|
<el-form-item label="生产订单号"
|
prop="npsNo">
|
<el-input disabled
|
v-model="form.npsNo" />
|
</el-form-item>
|
<el-form-item label="班组"
|
prop="teamName"
|
required>
|
<el-select v-model="form.teamName"
|
placeholder="请选择班组"
|
style="width: 100%">
|
<el-option label="白班"
|
value="白班" />
|
<el-option label="夜班"
|
value="夜班" />
|
</el-select>
|
</el-form-item>
|
<el-form-item label="产品编码"
|
prop="materialCode">
|
<el-input disabled
|
v-model="form.materialCode" />
|
</el-form-item>
|
<el-form-item label="产品名称"
|
prop="productName">
|
<el-input disabled
|
v-model="form.productName" />
|
</el-form-item>
|
<el-form-item label="规格"
|
prop="specification">
|
<el-input disabled
|
v-model="form.specification" />
|
</el-form-item>
|
<el-form-item label="创建人"
|
prop="createBy"
|
required>
|
<el-input v-model="form.createBy"
|
placeholder="请输入创建人" />
|
</el-form-item>
|
<el-form-item label="创建时间"
|
prop="createTime">
|
<el-date-picker disabled
|
v-model="form.createTime"
|
type="datetime"
|
placeholder="请选择创建时间"
|
style="width: 100%" />
|
</el-form-item>
|
</el-form>
|
</div>
|
<!-- 第三步:查看工序参数 -->
|
<div v-else-if="activeStep === 2">
|
<!-- 工序Tab页 -->
|
<el-tabs v-model="activeProcessId"
|
@tab-click="handleTabClick">
|
<el-tab-pane v-for="process in processList"
|
:key="process.id"
|
:label="process.processName"
|
:name="process.id + ''">
|
<el-form :model="form"
|
ref="formRef"
|
label-width="120px">
|
<!-- 动态参数 -->
|
<el-form-item v-for="param in params"
|
:key="param.id"
|
:label="param.paramName">
|
<template v-if="param.paramType == '1'">
|
<!-- 数字类型 -->
|
<el-input v-model="form.params[param.id]" />
|
</template>
|
<template v-else-if="param.paramType == '2'">
|
<!-- 文本类型 -->
|
<el-input v-model="form.params[param.id]" />
|
</template>
|
<template v-else-if="param.paramType == '3'">
|
<!-- 字典类型 -->
|
<el-select v-model="form.params[param.id]"
|
placeholder="请选择"
|
style="width: 100%">
|
<el-option v-for="option in dictOptions[param.paramFormat] || []"
|
:key="option.dictValue"
|
:label="option.dictLabel"
|
:value="option.dictValue" />
|
</el-select>
|
</template>
|
<template v-else-if="param.paramType == '4'">
|
<!-- 日期类型 -->
|
<el-date-picker v-model="form.params[param.id]" />
|
</template>
|
<template v-else>
|
<!-- 其他类型 -->
|
<el-input v-model="form.params[param.id]" />
|
</template>
|
</el-form-item>
|
</el-form>
|
</el-tab-pane>
|
</el-tabs>
|
</div>
|
<!-- 第四步:填写产量信息 -->
|
<div v-else-if="activeStep === 3">
|
<el-form :model="form"
|
:rules="rules"
|
ref="formRef"
|
label-width="120px">
|
<el-form-item label="产出方量"
|
prop="outputVolume"
|
required>
|
<el-input-number v-model="form.outputVolume"
|
:min="0"
|
:precision="2"
|
style="width: 100%" />
|
</el-form-item>
|
<el-form-item label="不合格方量"
|
prop="unqualifiedVolume"
|
required>
|
<el-input-number v-model="form.unqualifiedVolume"
|
:min="0"
|
:precision="2"
|
style="width: 100%" />
|
</el-form-item>
|
<el-form-item label="完成方量"
|
prop="completedVolume"
|
required>
|
<el-input-number v-model="form.completedVolume"
|
:min="0"
|
:precision="2"
|
style="width: 100%" />
|
</el-form-item>
|
</el-form>
|
</div>
|
<!-- 编辑模式:直接显示所有信息 -->
|
<div v-if="props.data.id">
|
<el-form :model="form"
|
:rules="rules"
|
ref="formRef"
|
label-width="120px">
|
<el-form-item label="生产订单号"
|
prop="npsNo"
|
disabled>
|
<el-input v-model="form.npsNo" />
|
</el-form-item>
|
<el-form-item label="班组"
|
prop="teamName">
|
<el-select v-model="form.teamName"
|
placeholder="请选择班组"
|
style="width: 100%">
|
<el-option label="白班"
|
value="白班" />
|
<el-option label="夜班"
|
value="夜班" />
|
</el-select>
|
</el-form-item>
|
<el-form-item label="产品编码"
|
prop="materialCode"
|
disabled>
|
<el-input v-model="form.materialCode" />
|
</el-form-item>
|
<el-form-item label="产品名称"
|
prop="productName"
|
disabled>
|
<el-input v-model="form.productName" />
|
</el-form-item>
|
<el-form-item label="规格"
|
prop="specification"
|
disabled>
|
<el-input v-model="form.specification" />
|
</el-form-item>
|
<el-form-item label="创建人"
|
prop="createBy">
|
<el-input v-model="form.createBy"
|
placeholder="请输入创建人" />
|
</el-form-item>
|
<el-form-item label="创建时间"
|
prop="createTime"
|
disabled>
|
<el-date-picker v-model="form.createTime"
|
type="datetime"
|
placeholder="请选择创建时间"
|
style="width: 100%" />
|
</el-form-item>
|
<el-form-item label="产出方量"
|
prop="outputVolume">
|
<el-input-number v-model="form.outputVolume"
|
:min="0"
|
:precision="2"
|
style="width: 100%" />
|
</el-form-item>
|
<el-form-item label="不合格方量"
|
prop="unqualifiedVolume">
|
<el-input-number v-model="form.unqualifiedVolume"
|
:min="0"
|
:precision="2"
|
style="width: 100%" />
|
</el-form-item>
|
<el-form-item label="完成方量"
|
prop="completedVolume">
|
<el-input-number v-model="form.completedVolume"
|
:min="0"
|
:precision="2"
|
style="width: 100%" />
|
</el-form-item>
|
</el-form>
|
<!-- 工序Tab页 -->
|
<el-tabs v-model="activeProcessId"
|
@tab-click="handleTabClick">
|
<el-tab-pane v-for="process in processList"
|
:key="process.id"
|
:label="process.processName"
|
:name="process.id + ''">
|
<el-form :model="form"
|
:rules="rules"
|
ref="formRef"
|
label-width="120px">
|
<!-- 动态参数 -->
|
<el-form-item v-for="param in params"
|
:key="param.id"
|
:label="param.paramName"
|
:prop="`params.${param.id}`"
|
:rules="param.isRequired ? [{ required: true, message: `请输入${param.paramName}`, trigger: 'blur' }] : []">
|
<template v-if="param.paramType == '1'">
|
<!-- 数字类型 -->
|
<el-input-number v-model="form.params[param.id]"
|
:min="0"
|
:precision="getPrecision(param.paramFormat)"
|
style="width: 100%" />
|
</template>
|
<template v-else-if="param.paramType == '2'">
|
<!-- 文本类型 -->
|
<el-input v-model="form.params[param.id]"
|
:placeholder="`请输入${param.paramName}`" />
|
</template>
|
<template v-else-if="param.paramType == '3'">
|
<!-- 字典类型 -->
|
<el-select v-model="form.params[param.id]"
|
placeholder="请选择"
|
style="width: 100%">
|
<el-option v-for="option in dictOptions[param.paramFormat] || []"
|
:key="option.dictValue"
|
:label="option.dictLabel"
|
:value="option.dictValue" />
|
</el-select>
|
</template>
|
<template v-else-if="param.paramType == '4'">
|
<!-- 日期类型 -->
|
<el-date-picker v-model="form.params[param.id]"
|
type="datetime"
|
placeholder="请选择日期时间"
|
style="width: 100%" />
|
</template>
|
<template v-else>
|
<!-- 其他类型 -->
|
<el-input v-model="form.params[param.id]"
|
:placeholder="`请输入${param.paramName}`" />
|
</template>
|
</el-form-item>
|
</el-form>
|
</el-tab-pane>
|
</el-tabs>
|
</div>
|
<template #footer>
|
<span class="dialog-footer">
|
<el-button @click="handleClose">取 消</el-button>
|
<el-button type="primary"
|
v-if="activeStep > 0"
|
@click="activeStep--">上一步</el-button>
|
<el-button type="primary"
|
v-if="activeStep < 3 && !props.data.id"
|
@click="handleNextStep">下一步</el-button>
|
<el-button type="primary"
|
v-if="activeStep === 3 || props.data.id"
|
:loading="submitLoading"
|
@click="handleSubmit">确 认</el-button>
|
</span>
|
</template>
|
</el-dialog>
|
</template>
|
|
<script setup>
|
import { ref, reactive, computed, watch } from "vue";
|
import { ElMessage } from "element-plus";
|
import { getDicts } from "@/api/system/dict/data";
|
import { productOrderListPage } from "@/api/productionManagement/productionOrder.js";
|
import {
|
findProductProcessRouteItemList,
|
findProcessParamListOrder,
|
} from "@/api/productionManagement/productProcessRoute.js";
|
|
const props = defineProps({
|
visible: {
|
type: Boolean,
|
default: false,
|
},
|
data: {
|
type: Object,
|
default: () => ({}),
|
},
|
});
|
|
const emit = defineEmits(["update:visible", "completed"]);
|
|
const dialogTitle = computed(() => (props.data.id ? "编辑报工" : "新增报工"));
|
|
const formRef = ref(null);
|
const submitLoading = ref(false);
|
const orderLoading = ref(false);
|
const processLoading = ref(false);
|
const localVisible = ref(props.visible);
|
const activeStep = ref(0);
|
|
const orderId = ref(props.data.orderId || "");
|
const processId = ref(props.data.processId || "");
|
const activeProcessId = ref("");
|
const orderList = ref([]);
|
const processList = ref([]);
|
const params = ref([]);
|
const dictOptions = ref({});
|
|
const form = reactive({
|
id: props.data.id || undefined,
|
orderId: props.data.orderId || "",
|
npsNo: props.data.npsNo || "",
|
teamName: props.data.teamName || "",
|
materialCode: props.data.materialCode || "",
|
productName: props.data.productName || "",
|
specification: props.data.specification || "",
|
outputVolume: props.data.outputVolume || 0,
|
unqualifiedVolume: props.data.unqualifiedVolume || 0,
|
completedVolume: props.data.completedVolume || 0,
|
createBy: props.data.createBy || "当前登录人",
|
createTime: props.data.createTime || new Date(),
|
params: props.data.params || {},
|
});
|
|
const rules = {
|
teamName: [{ required: true, message: "请选择班组", trigger: "blur" }],
|
outputVolume: [
|
{ required: true, message: "请输入产出方量", trigger: "blur" },
|
],
|
unqualifiedVolume: [
|
{ required: true, message: "请输入不合格方量", trigger: "blur" },
|
],
|
completedVolume: [
|
{ required: true, message: "请输入完成方量", trigger: "blur" },
|
],
|
createBy: [{ required: true, message: "请输入创建人", trigger: "blur" }],
|
};
|
|
// 加载生产订单列表
|
const loadOrders = () => {
|
orderLoading.value = true;
|
productOrderListPage({ pageNum: 1, pageSize: 100 })
|
.then(res => {
|
orderList.value = res.data.records || [];
|
})
|
.finally(() => {
|
orderLoading.value = false;
|
});
|
};
|
|
// 处理生产订单选择
|
const handleOrderChange = val => {
|
if (val) {
|
const order = orderList.value.find(item => item.id === val);
|
if (order) {
|
form.orderId = val;
|
form.npsNo = order.npsNo;
|
form.materialCode = order.materialCode;
|
form.productName = order.productName;
|
form.specification = order.model;
|
}
|
// 加载工序列表
|
loadProcesses(val);
|
} else {
|
form.orderId = "";
|
form.npsNo = "";
|
form.materialCode = "";
|
form.productName = "";
|
form.specification = "";
|
processId.value = "";
|
activeProcessId.value = "";
|
processList.value = [];
|
params.value = [];
|
form.params = {};
|
}
|
};
|
|
// 加载工序列表
|
const loadProcesses = orderId => {
|
processLoading.value = true;
|
findProductProcessRouteItemList({ orderId })
|
.then(res => {
|
processList.value = res.data || [];
|
// 如果有工序,默认选择第一个
|
if (processList.value.length > 0) {
|
const firstProcess = processList.value[0];
|
activeProcessId.value = firstProcess.id + "";
|
processId.value = firstProcess.id;
|
form.processId = firstProcess.id;
|
// 加载第一个工序的参数
|
loadParams(firstProcess.id, orderId);
|
}
|
})
|
.finally(() => {
|
processLoading.value = false;
|
});
|
};
|
|
// 处理tab页点击
|
const handleTabClick = tab => {
|
const selectedProcessId = parseInt(tab.paneName);
|
processId.value = selectedProcessId;
|
form.processId = selectedProcessId;
|
// 加载参数列表
|
loadParams(selectedProcessId, form.orderId);
|
};
|
|
// 获取字典数据
|
const getDictOptions = async dictType => {
|
if (!dictType) return [];
|
if (dictOptions.value[dictType]) return dictOptions.value[dictType];
|
|
try {
|
const res = await getDicts(dictType);
|
if (res.code === 200) {
|
dictOptions.value[dictType] = res.data;
|
return res.data;
|
}
|
return [];
|
} catch (error) {
|
console.error("获取字典数据失败:", error);
|
return [];
|
}
|
};
|
|
// 加载参数列表
|
const loadParams = (processId, orderId) => {
|
findProcessParamListOrder({ orderId, routeItemId: processId }).then(
|
async res => {
|
params.value = res.data || [];
|
// 初始化参数值并获取字典数据
|
for (const param of params.value) {
|
if (!form.params[param.id]) {
|
form.params[param.id] = param.standardValue || "";
|
}
|
// 如果是字典类型参数,获取字典数据
|
if (param.paramType == "3" && param.paramFormat) {
|
await getDictOptions(param.paramFormat);
|
}
|
}
|
}
|
);
|
};
|
|
// 获取小数精度
|
const getPrecision = format => {
|
if (!format) return 2;
|
const match = format.match(/\.(\d+)/);
|
return match ? parseInt(match[1].length) : 2;
|
};
|
|
// 处理下一步
|
const handleNextStep = () => {
|
if (activeStep.value === 0) {
|
// 第一步:验证生产订单选择
|
if (!orderId.value) {
|
ElMessage.error("请选择生产订单");
|
return;
|
}
|
activeStep.value = 1;
|
} else if (activeStep.value === 1) {
|
// 第二步:验证基础信息
|
formRef.value.validate(valid => {
|
if (valid) {
|
activeStep.value = 2;
|
}
|
});
|
} else if (activeStep.value === 2) {
|
// 第三步:直接进入第四步
|
activeStep.value = 3;
|
}
|
};
|
|
// 处理提交
|
const handleSubmit = () => {
|
formRef.value.validate(valid => {
|
if (valid) {
|
submitLoading.value = true;
|
// 这里可以调用API进行提交
|
setTimeout(() => {
|
ElMessage.success(props.data.id ? "修改成功" : "新增成功");
|
localVisible.value = false;
|
emit("completed");
|
submitLoading.value = false;
|
}, 1000);
|
}
|
});
|
};
|
|
// 处理关闭
|
const handleClose = () => {
|
// 重置到初始状态
|
activeStep.value = 0;
|
orderId.value = "";
|
processId.value = "";
|
activeProcessId.value = "";
|
processList.value = [];
|
params.value = [];
|
Object.assign(form, {
|
id: undefined,
|
orderId: "",
|
npsNo: "",
|
teamName: "",
|
materialCode: "",
|
productName: "",
|
specification: "",
|
outputVolume: 0,
|
unqualifiedVolume: 0,
|
completedVolume: 0,
|
createBy: "当前登录人",
|
createTime: new Date(),
|
params: {},
|
});
|
localVisible.value = false;
|
};
|
|
// 初始化
|
const init = () => {
|
if (!props.data.id) {
|
// 新增时加载订单列表
|
loadOrders();
|
// 设置默认创建人和创建时间
|
form.createBy = "当前登录人";
|
form.createTime = new Date();
|
} else {
|
// 编辑时加载相关数据
|
if (props.data.orderId) {
|
orderId.value = props.data.orderId;
|
if (props.data.processId) {
|
processId.value = props.data.processId;
|
activeProcessId.value = props.data.processId + "";
|
loadParams(props.data.processId, props.data.orderId);
|
} else {
|
loadProcesses(props.data.orderId);
|
}
|
} else {
|
loadOrders();
|
}
|
}
|
};
|
|
// 监听props.visible变化
|
watch(
|
() => props.visible,
|
newVal => {
|
localVisible.value = newVal;
|
if (newVal) {
|
init();
|
}
|
}
|
);
|
|
// 监听localVisible变化
|
watch(localVisible, newVal => {
|
emit("update:visible", newVal);
|
});
|
</script>
|
|
<style scoped>
|
.dialog-footer {
|
text-align: right;
|
}
|
</style>
|