<template>
|
<div class="app-container">
|
<div class="search_form">
|
<div>
|
<span class="search_title">产品大类:</span>
|
<el-tree-select
|
v-model="searchForm.productCategory"
|
:data="productOptions"
|
placeholder="请选择"
|
clearable
|
check-strictly
|
:render-after-expand="false"
|
style="width: 240px"
|
@change="handleQuery"
|
/>
|
<span class="search_title ml10">录入日期:</span>
|
<el-date-picker v-model="searchForm.registerDate" value-format="YYYY-MM-DD" format="YYYY-MM-DD" type="daterange"
|
placeholder="请选择" clearable @change="changeDaterange" />
|
<el-button type="primary" @click="handleQuery" style="margin-left: 10px"
|
>搜索</el-button
|
>
|
</div>
|
<div>
|
<el-button type="primary" @click="openDialog('create')">新增订单</el-button>
|
<el-button @click="handleOut">导出</el-button>
|
</div>
|
</div>
|
<div class="table_list">
|
<PIMTable
|
rowKey="id"
|
:column="tableColumn"
|
:tableData="tableData"
|
:page="page"
|
:tableLoading="tableLoading"
|
@pagination="pagination"
|
>
|
<template #action="{ row }">
|
<el-button type="primary" link @click="handleEdit(row)">编辑</el-button>
|
<el-button type="danger" link @click="handleDelete(row)">删除</el-button>
|
</template>
|
</PIMTable>
|
</div>
|
<el-dialog v-model="dialogVisible" :title="dialogTitle" width="40%" @close="closeDialog">
|
<el-form ref="formRef" :model="form" :rules="formRules" label-width="100px">
|
<el-form-item label="录入日期" prop="registerDate">
|
<el-date-picker v-model="form.registerDate" type="date" value-format="YYYY-MM-DD" format="YYYY-MM-DD" placeholder="请选择录入日期" style="width: 100%"/>
|
</el-form-item>
|
<el-form-item label="产品大类" prop="productCategory">
|
<el-tree-select
|
v-model="form.productCategory"
|
:data="productOptions"
|
placeholder="请选择产品大类"
|
clearable
|
check-strictly
|
:render-after-expand="false"
|
style="width: 100%"
|
@change="handleCategoryChange"
|
/>
|
</el-form-item>
|
<el-form-item label="规格型号" prop="productModelId">
|
<el-select v-model="form.productModelId" placeholder="请选择规格型号" style="width: 100%" @change="handleModelChange">
|
<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="form.unit" placeholder="自动带出" disabled/>
|
</el-form-item>
|
<el-form-item label="数量" prop="quantity">
|
<el-input-number v-model="form.quantity" :min="0" :step="0.1" style="width: 100%"/>
|
</el-form-item>
|
</el-form>
|
<template #footer>
|
<div class="dialog-footer">
|
<el-button type="primary" @click="submitForm">确认</el-button>
|
<el-button @click="closeDialog">取消</el-button>
|
</div>
|
</template>
|
</el-dialog>
|
</div>
|
</template>
|
|
<script setup>
|
import {onMounted, ref, reactive, toRefs, getCurrentInstance} from "vue";
|
import { ElMessageBox } from "element-plus";
|
import dayjs from "dayjs";
|
import {schedulingListPage, addProductionOrder, updateProductionOrder, deleteProductionOrder} from "@/api/productionManagement/productionOrder.js";
|
import {productTreeList, modelList} from "@/api/basicData/product.js";
|
const { proxy } = getCurrentInstance();
|
|
const tableColumn = ref([
|
{
|
label: "录入日期",
|
prop: "registerDate",
|
width: 120,
|
},
|
{
|
label: "生产订单号",
|
prop: "orderNo",
|
},
|
{
|
label: "产品大类",
|
prop: "productCategory",
|
},
|
{
|
label: "规格型号",
|
prop: "specificationModel",
|
},
|
{
|
label: "单位",
|
prop: "unit",
|
},
|
{
|
label: "数量",
|
prop: "quantity",
|
},
|
// {
|
// label: "排产数量",
|
// prop: "schedulingNum",
|
// width: 100,
|
// },
|
// {
|
// label: "完工数量",
|
// prop: "successNum",
|
// width: 100,
|
// },
|
{
|
label: "操作",
|
prop: "action",
|
width: 120,
|
fixed: "right",
|
dataType: "slot",
|
align: "center",
|
slot: "action"
|
}
|
]);
|
const tableData = ref([]);
|
const tableLoading = ref(false);
|
const page = ref({
|
current: 1,
|
size: 100,
|
total: 0,
|
});
|
const dialogVisible = ref(false);
|
const dialogTitle = ref("");
|
const dialogMode = ref(""); // 'create' 或 'edit'
|
const formRef = ref();
|
const productOptions = ref([]);
|
const modelOptions = ref([]);
|
const form = reactive({
|
id: null,
|
registerDate: dayjs().format("YYYY-MM-DD"),
|
productCategory: "",
|
productCategoryName: "",
|
productModelId: "",
|
specificationModel: "",
|
unit: "",
|
quantity: null,
|
});
|
const formRules = {
|
registerDate: [{ required: true, message: "请选择录入日期", trigger: "change" }],
|
productCategory: [{ required: true, message: "请选择产品大类", trigger: "change" }],
|
productModelId: [{ required: true, message: "请选择规格型号", trigger: "change" }],
|
quantity: [{ required: true, message: "请输入数量", trigger: "blur" }],
|
};
|
|
const data = reactive({
|
searchForm: {
|
productCategory: "",
|
registerDate: null, // 录入日期
|
entryDateStart: undefined,
|
entryDateEnd: undefined,
|
},
|
});
|
const { searchForm } = toRefs(data);
|
|
const openDialog = (mode, row = null) => {
|
dialogMode.value = mode;
|
if (mode === 'create') {
|
dialogTitle.value = "新增生产订单";
|
resetForm();
|
} else if (mode === 'edit') {
|
dialogTitle.value = "编辑生产订单";
|
resetForm();
|
|
console.log('编辑数据:', row);
|
|
// 填充编辑数据
|
form.id = row.id;
|
form.registerDate = row.registerDate;
|
form.productCategoryName = row.productCategory;
|
form.specificationModel = row.specificationModel;
|
form.unit = row.unit;
|
form.quantity = row.quantity;
|
|
// 先加载产品选项,然后根据名称查找对应的ID
|
if (productOptions.value.length === 0) {
|
getProductOptions().then(() => {
|
findAndSetProductCategory(row.productCategory);
|
});
|
} else {
|
findAndSetProductCategory(row.productCategory);
|
}
|
}
|
|
dialogVisible.value = true;
|
if (productOptions.value.length === 0) {
|
getProductOptions();
|
}
|
};
|
|
const closeDialog = () => {
|
dialogVisible.value = false;
|
};
|
|
const resetForm = () => {
|
form.id = null;
|
form.registerDate = dayjs().format("YYYY-MM-DD");
|
form.productCategory = "";
|
form.productCategoryName = "";
|
form.productModelId = "";
|
form.specificationModel = "";
|
form.unit = "";
|
form.quantity = null;
|
modelOptions.value = [];
|
};
|
|
const handleCategoryChange = (value) => {
|
form.productCategory = value;
|
form.productCategoryName = findNodeById(productOptions.value, value) || "";
|
form.productModelId = "";
|
form.specificationModel = "";
|
form.unit = "";
|
modelOptions.value = [];
|
if (value) {
|
getModels(value);
|
}
|
};
|
|
const handleModelChange = (value) => {
|
form.productModelId = value;
|
const selected = modelOptions.value.find(item => item.id === value);
|
if (selected) {
|
form.specificationModel = selected.model;
|
form.unit = selected.unit || "";
|
} else {
|
form.specificationModel = "";
|
form.unit = "";
|
}
|
};
|
|
const submitForm = () => {
|
formRef.value?.validate(async (valid) => {
|
if (!valid) return;
|
if (!form.unit) {
|
proxy.$modal.msgWarning("请先选择规格型号以带出单位");
|
return;
|
}
|
try {
|
const payload = {
|
registerDate: form.registerDate,
|
productCategory: form.productCategoryName,
|
specificationModel: form.specificationModel,
|
unit: form.unit,
|
quantity: form.quantity,
|
};
|
|
if (dialogMode.value === 'create') {
|
await addProductionOrder(payload);
|
proxy.$modal.msgSuccess("新增成功");
|
} else if (dialogMode.value === 'edit') {
|
payload.id = form.id;
|
await updateProductionOrder(payload);
|
proxy.$modal.msgSuccess("编辑成功");
|
}
|
|
closeDialog();
|
getList();
|
} catch (err) {
|
console.error(`${dialogMode.value === 'create' ? '新增' : '编辑'}失败`, err);
|
proxy.$modal.msgError(`${dialogMode.value === 'create' ? '新增' : '编辑'}失败,请重试`);
|
}
|
});
|
};
|
|
// 编辑方法
|
const handleEdit = (row) => {
|
openDialog('edit', row);
|
};
|
|
// 删除方法
|
const handleDelete = (row) => {
|
proxy.$modal.confirm(`确定要删除生产订单"${row.orderNo}"吗?`, "删除确认", {
|
confirmButtonText: "确定",
|
cancelButtonText: "取消",
|
type: "warning",
|
}).then(async () => {
|
try {
|
await deleteProductionOrder([row.id]);
|
proxy.$modal.msgSuccess("删除成功");
|
getList(); // 刷新列表
|
} catch (err) {
|
console.error("删除失败", err);
|
proxy.$modal.msgError("删除失败,请重试");
|
}
|
}).catch(() => {
|
proxy.$modal.msg("已取消删除");
|
});
|
};
|
|
const getProductOptions = () => {
|
return productTreeList().then((res) => {
|
productOptions.value = convertIdToValue(res || []);
|
});
|
};
|
|
const getModels = (value) => {
|
return modelList({ id: value }).then((res) => {
|
modelOptions.value = res || [];
|
});
|
};
|
|
const 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;
|
});
|
};
|
|
const findNodeById = (nodes, value) => {
|
for (let i = 0; i < nodes.length; i++) {
|
if (nodes[i].value === value) {
|
return nodes[i].label;
|
}
|
if (nodes[i].children && nodes[i].children.length > 0) {
|
const label = findNodeById(nodes[i].children, value);
|
if (label) return label;
|
}
|
}
|
return null;
|
};
|
|
const findNodeByLabel = (nodes, label) => {
|
for (let i = 0; i < nodes.length; i++) {
|
if (nodes[i].label === label) {
|
return nodes[i].value;
|
}
|
if (nodes[i].children && nodes[i].children.length > 0) {
|
const value = findNodeByLabel(nodes[i].children, label);
|
if (value) return value;
|
}
|
}
|
return null;
|
};
|
|
const findAndSetProductCategory = (categoryName) => {
|
const categoryId = findNodeByLabel(productOptions.value, categoryName);
|
if (categoryId) {
|
form.productCategory = categoryId;
|
// 加载对应的规格型号选项
|
getModels(categoryId).then(() => {
|
// 根据规格型号名称查找对应的ID
|
const modelItem = modelOptions.value.find(item => item.model === form.specificationModel);
|
if (modelItem) {
|
form.productModelId = modelItem.id;
|
}
|
});
|
}
|
};
|
|
// 查询列表
|
/** 搜索按钮操作 */
|
const handleQuery = () => {
|
page.value.current = 1;
|
getList();
|
};
|
const pagination = (obj) => {
|
page.value.current = obj.page;
|
page.value.size = obj.limit;
|
getList();
|
};
|
const changeDaterange = (value) => {
|
if (value) {
|
searchForm.value.entryDateStart = value[0];
|
searchForm.value.entryDateEnd = value[1];
|
} else {
|
searchForm.value.entryDateStart = undefined;
|
searchForm.value.entryDateEnd = undefined;
|
}
|
handleQuery();
|
};
|
const getList = () => {
|
tableLoading.value = true;
|
// 构造一个新的对象,不包含entryDate字段
|
const params = { ...searchForm.value, ...page.value };
|
params.registerDate = undefined
|
if (params.productCategory) {
|
// 如果是对象类型,获取其label(名称)而不是value(ID)
|
if (typeof params.productCategory === "object") {
|
params.productCategory = findNodeById(productOptions.value, params.productCategory) || params.productCategory;
|
}
|
// 如果是ID,转换为名称
|
else if (typeof params.productCategory === "string" || typeof params.productCategory === "number") {
|
const categoryName = findNodeById(productOptions.value, params.productCategory);
|
if (categoryName) {
|
params.productCategory = categoryName;
|
}
|
}
|
}
|
schedulingListPage(params).then((res) => {
|
console.log('params---', res)
|
tableLoading.value = false;
|
tableData.value = res.data.data.records;
|
page.value.total = res.data.data.total;
|
}).catch(() => {
|
tableLoading.value = false;
|
})
|
};
|
|
// 导出
|
const handleOut = () => {
|
ElMessageBox.confirm("选中的内容将被导出,是否确认导出?", "导出", {
|
confirmButtonText: "确认",
|
cancelButtonText: "取消",
|
type: "warning",
|
})
|
.then(() => {
|
proxy.download("/salesLedger/scheduling/export", {}, "生产订单.xlsx");
|
})
|
.catch(() => {
|
proxy.$modal.msg("已取消");
|
});
|
};
|
|
onMounted(() => {
|
getList();
|
getProductOptions();
|
});
|
</script>
|
|
<style scoped lang="scss"></style>
|