pms-aomei/src/views/modules/pms/order/components/order--edit.vue

969 lines
32 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<el-dialog
class="order--edit_dialog"
:fullscreen="fullscreen"
:visible="visible"
@close="handleClose"
@closed="$emit('destroy')"
:close-on-click-modal="false"
v-loading="optionsLoading || formLoading">
<div slot="title" class="dialog-title">
<h2 class="">
{{ mode.includes("detail") ? "查看详情" : dataForm.id ? "修改订单" : "新增订单" }}
</h2>
</div>
<!-- form -->
<el-form ref="dataForm" :model="dataForm" size="small">
<InputsArea title="生产订单">
<el-row :gutter="20">
<el-col :span="6">
<el-form-item label="订单状态" prop="statusDictValue" :rules="null">
<span style="display: block; margin-top: 32px">
{{
["等待", "确认", "生产", "暂停", "结束", "接受", "拒绝", "已下发"][
dataForm.statusDictValue
]
}}
</span>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item
label="订单号"
prop="code"
:rules="{ required: true, message: '必填项不能为空', trigger: 'blur' }">
<el-input
v-model="dataForm.code"
:disabled="mode.includes('detail')"
v-bind="{ placeholder: '输入订单号' }"></el-input>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item
label="订单子号"
prop="cate"
:rules="[
{ required: true, message: '必填项不能为空', trigger: 'blur' },
{
type: 'number',
message: '输入正确的数字类型',
trigger: 'blur',
transform: (val) => Number(val),
},
]">
<el-input
v-model="dataForm.cate"
:disabled="mode.includes('detail')"
v-bind="{ placeholder: '输入订单子号' }"></el-input>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="计划开始时间" prop="planStartTime">
<el-date-picker
v-model="dataForm.planStartTime"
v-bind="{
placeholder: '选择计划开始时间',
type: 'datetime',
'value-format': 'yyyy-MM-ddTHH:mm:ss',
}"
:disabled="mode.includes('detail')"></el-date-picker>
</el-form-item>
</el-col>
</el-row>
</InputsArea>
<InputsArea title="设备与参数">
<el-row :gutter="20">
<el-col :span="6">
<el-form-item
label="压机"
prop="press"
:rules="{ required: true, message: '必填项不能为空', trigger: 'blur' }">
<el-select
v-model="dataForm.press"
filterable
clearable
:disabled="mode.includes('detail')"
v-bind="{ placeholder: '选择压机', filterable: true }">
<el-option
v-for="opt in pressOptions"
:key="opt.label + opt.value"
:label="opt.label"
:value="opt.value">
<span>{{ opt.label }}</span>
<span
v-if="requestList[0].extraLabel"
style="display: inline-block; margin-left: 12px; font-size: 0.9em">
{{ opt.code }}
</span>
</el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item
label="混料机号"
prop="blender"
:rules="{ required: true, message: '必填项不能为空', trigger: 'blur' }">
<el-select
v-model="dataForm.blender"
filterable
clearable
:disabled="mode.includes('detail')"
v-bind="{ placeholder: '选择混料机', filterable: true }">
<el-option
v-for="opt in blenderOptions"
:key="opt.label + opt.value"
:label="opt.label"
:value="opt.value">
<span>{{ opt.label }}</span>
<span
v-if="requestList[1].extraLabel"
style="display: inline-block; margin-left: 12px; font-size: 0.9em">
{{ opt.code }}
</span>
</el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="隧道窑号" prop="kiln" :rules="null">
<el-select
v-model="dataForm.kiln"
filterable
clearable
:disabled="mode.includes('detail')"
v-bind="{ placeholder: '选择隧道窑', filterable: true }">
<el-option
v-for="opt in kilnOptions"
:key="opt.label + opt.value"
:label="opt.label"
:value="opt.value">
<span>{{ opt.label }}</span>
<span
v-if="requestList[2].extraLabel"
style="display: inline-block; margin-left: 12px; font-size: 0.9em">
{{ opt.code }}
</span>
</el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="Add on" prop="sapParam1" :rules="null">
<el-input
v-model="dataForm.sapParam1"
:disabled="mode.includes('detail')"
v-bind="{ placeholder: '输入addon' }"></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="6">
<el-form-item label="配方号" prop="bomId" :rules="null">
<el-select
v-model="dataForm.bomId"
filterable
clearable
:disabled="mode.includes('detail')"
@change="handleBomChange"
v-bind="{ placeholder: '选择配方号', filterable: true }">
<el-option
v-for="opt in bomOptions"
:key="opt.label + opt.value"
:label="opt.label"
:value="opt.value"
style="display: flex; align-items: center">
<span style="display: inline-block; width: 128px; text-overflow: ellipsis">
{{ opt.label }}
</span>
<span
v-if="requestList[3].extraLabel"
style="display: inline-block; margin-left: 12px; font-size: 0.9em">
{{ opt.name }}
</span>
</el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="牌号" prop="brand" :rules="null">
<span style="display: block; margin-top: 32px">{{ dataForm.brand }}</span>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="版本号" prop="ai" :rules="null">
<!-- <span style="display: block; margin-top: 32px">{{ dataForm.ai }}</span> -->
<el-select
v-model="dataForm.ai"
filterable
clearable
:disabled="mode.includes('detail')"
v-bind="{ placeholder: '请选择版本' }"
@change="handleVersionChange">
<el-option
v-for="opt in versionList"
:key="opt.label + opt.value"
:label="opt.label"
:value="opt.value">
<span>{{ opt.label }}</span>
</el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="包装代码" prop="packTech" :rules="null">
<el-select
v-model="dataForm.packTech"
filterable
clearable
:disabled="mode.includes('detail')"
v-bind="{ placeholder: '选择包装代码', filterable: true }">
<el-option
v-for="opt in packOptions"
:key="opt.label + opt.value"
:label="opt.label"
:value="opt.value">
<span>{{ opt.label }}</span>
<span
v-if="requestList[4].extraLabel"
style="display: inline-block; margin-left: 12px; font-size: 0.9em">
{{ opt.code }}
</span>
</el-option>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="6">
<el-form-item label="物料" prop="productId" :rules="null">
<el-select
v-model="dataForm.productId"
filterable
clearable
:disabled="mode.includes('detail')"
v-bind="{ placeholder: '选择物料', filterable: true }">
<el-option
v-for="opt in productOptions"
:key="opt.label + opt.value"
:label="opt.label"
:value="opt.value">
<span>{{ opt.label }}</span>
<span
v-if="requestList[5].extraLabel"
style="display: inline-block; margin-left: 12px; font-size: 0.9em">
{{ opt.code }}
</span>
</el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="砖型" prop="shape" :rules="null">
<el-select
v-model="dataForm.shape"
filterable
clearable
:disabled="mode.includes('detail')"
v-bind="{ placeholder: '选择砖型', filterable: true }">
<el-option
v-for="opt in shapeOptions"
:key="opt.label + opt.value"
:label="opt.label"
:value="opt.value">
<span>{{ opt.label }}</span>
<span
v-if="requestList[6].extraLabel"
style="display: inline-block; margin-left: 12px; font-size: 0.9em">
{{ opt.code }}
</span>
</el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="6">
<!-- <el-form-item
label="烧成温度"
prop="sapParam6"
:rules="[
{ required: true, message: '必填项不能为空', trigger: 'blur' },
{
type: 'number',
message: '输入正确的数字类型',
trigger: 'blur',
transform: (val) => Number(val),
},
]">
<el-input
v-model="dataForm.sapParam6"
:disabled="mode.includes('detail')"
v-bind="{ placeholder: '输入烧成温度' }"></el-input>
</el-form-item> -->
</el-col>
<el-col :span="6">
<!-- <el-form-item
label="烧成时间 H"
prop="sapParam7"
:rules="[
{ required: true, message: '必填项不能为空', trigger: 'blur' },
{
type: 'number',
message: '输入正确的数字类型',
trigger: 'blur',
transform: (val) => Number(val),
},
]">
<el-input
v-model="dataForm.sapParam7"
:disabled="mode.includes('detail')"
v-bind="{ placeholder: '输入烧成时间' }"></el-input>
</el-form-item> -->
</el-col>
</el-row>
</InputsArea>
<InputsArea title="其他">
<el-row :gutter="20">
<el-col :span="6">
<el-form-item label="生产订单类型" prop="specifications" :rules="null">
<el-input
v-model="dataForm.specifications"
:disabled="mode.includes('detail')"
v-bind="{ placeholder: '输入生产订单类型' }"></el-input>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item
label="生产订单砖数"
prop="prodqty"
:rules="[
{ required: true, message: '必填项不能为空', trigger: 'blur' },
{
type: 'number',
message: '输入正确的数字类型',
trigger: 'blur',
transform: (val) => Number(val),
},
]">
<el-input
v-model="dataForm.prodqty"
:disabled="mode.includes('detail')"
v-bind="{ placeholder: '输入要求生产的数量' }"></el-input>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item
label="已生产数"
prop="yieldqty"
:rules="[
{
type: 'number',
message: '输入正确的数字类型',
trigger: 'blur',
transform: (val) => Number(val),
},
]">
<el-input
v-model="dataForm.yieldqty"
:disabled="mode.includes('detail')"
v-bind="{ placeholder: '输入已经生产的数量' }"></el-input>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item
label="托盘码放砖数"
prop="pcsKilnCar"
:rules="[
{ required: true, message: '必填项不能为空', trigger: 'blur' },
{
type: 'number',
message: '输入正确的数字类型',
trigger: 'blur',
transform: (val) => Number(val),
},
]">
<el-input
v-model="dataForm.pcsKilnCar"
:disabled="mode.includes('detail')"
v-bind="{ placeholder: '输入托盘码放砖数' }"></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="6">
<el-form-item label="销售订单号" prop="saleNo">
<!-- :rules="{ required: true, message: '必填项不能为空', trigger: 'blur' }"> -->
<el-input
v-model="dataForm.saleNo"
:disabled="mode.includes('detail')"
v-bind="{ placeholder: '输入销售订单号' }"></el-input>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="销售订单item号" prop="saleOrderItem" :rules="null">
<el-input
v-model="dataForm.saleOrderItem"
:disabled="mode.includes('detail')"
v-bind="{ placeholder: '输入销售订单item号' }"></el-input>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item
label="销售订单砖数"
prop="soqty"
:rules="[
// { required: true, message: '必填项不能为空', trigger: 'blur' },
{
type: 'number',
message: '输入正确的数字类型',
trigger: 'blur',
transform: (val) => Number(val),
},
]">
<el-input
v-model="dataForm.soqty"
:disabled="mode.includes('detail')"
v-bind="{ placeholder: '输入销售订单砖数' }"></el-input>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="销售时间" prop="deliveryTime">
<!-- :rules="{ required: true, message: '必填项不能为空', trigger: 'blur' }"> -->
<el-date-picker
v-model="dataForm.deliveryTime"
:disabled="mode.includes('detail')"
v-bind="{ placeholder: '选择销售时间' }"></el-date-picker>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="6">
<el-form-item
label="客户"
prop="customerId"
:rules="{ required: true, message: '必填项不能为空', trigger: 'blur' }">
<el-select
v-model="dataForm.customerId"
filterable
clearable
:disabled="mode.includes('detail')"
v-bind="{ placeholder: '选择客户' }">
<el-option
v-for="opt in clientOptions"
:key="opt.label + opt.value"
:label="opt.label"
:value="opt.value">
<span>{{ opt.label }}</span>
<span
v-if="requestList[7].extraLabel"
style="display: inline-block; margin-left: 12px; font-size: 0.9em">
{{ opt.name }}
</span>
</el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="喷码描述" prop="shortDesc" :rules="null">
<span style="display: block; margin-top: 32px">{{ dataForm.shortDesc }}</span>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="托盘类型" prop="palletType">
<!-- :rules="[{ required: true, message: '请选择托盘类型', trigger: 'blur' }]"> -->
<el-select
v-model="dataForm.palletType"
filterable
clearable
:disabled="mode.includes('detail')"
v-bind="{ placeholder: '选择托盘类型' }">
<el-option
v-for="pt in palletType"
:key="pt.dictValue"
:label="pt.dictLabel"
:value="pt.dictValue"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item
label="贴纸板"
prop="paperboard"
:rules="[{ required: true, message: '请选择贴纸板', trigger: 'blur' }]">
<el-select
v-model="dataForm.paperboard"
filterable
clearable
:disabled="mode.includes('detail')"
v-bind="{ placeholder: '选择贴纸板' }">
<el-option label="否" value="0"></el-option>
<el-option label="是" value="1"></el-option>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col>
<el-form-item label="备注" prop="remark" :rules="null">
<el-input
v-model="dataForm.remark"
:disabled="mode.includes('detail')"
v-bind="{ placeholder: '备注' }"></el-input>
</el-form-item>
</el-col>
</el-row>
</InputsArea>
</el-form>
<!-- footer -->
<div slot="footer">
<!-- TODO: permission 相关内容 未添加 -->
<el-button
v-if="mode.includes('create')"
type="primary"
@click="handleSave('POST')"
:loading="btnLoading">
保存
</el-button>
<el-button
v-if="mode.includes('edit')"
type="primary"
@click="handleSave('PUT')"
:loading="btnLoading">
更新
</el-button>
<el-button v-if="mode.includes('reset')" type="warning" @click="handleReset">重置</el-button>
<el-button @click="handleClose">取消</el-button>
</div>
</el-dialog>
</template>
<script>
import { pick as __pick } from "@/utils/filters";
// import moment from "moment";
import InputsArea from "./InputsArea.vue";
import { getDictDataList } from "@/utils";
export default {
name: "DialogJustForm",
components: { InputsArea },
props: {
fullscreen: {
type: Boolean,
default: false,
},
},
inject: ["urls"],
data() {
return {
mode: "#edit#reset",
formLoading: false,
optionsLoading: false,
pressOptions: [], // 压机列表
blenderOptions: [], // 混料机列表
kilnOptions: [], // 窑炉列表
bomOptions: [], // 牌号列表
packOptions: [], // 包装代码列表
productOptions: [], // 物料代码
shapeOptions: [], // 砖型代码
clientOptions: [], // 客户礼拜
versionList: [], // 版本列表
cachedList: {}, // 用来缓存请求回来的原始列表数据
dataForm: {
statusDictValue: null,
code: null,
cate: null,
planStartTime: null,
press: null,
blender: null,
kiln: null,
sapParam1: null,
bomId: null,
brand: null, // 牌号
ai: null, // 版本号
packTech: null,
productId: null,
shape: null,
sapParam6: null,
sapParam7: null,
specifications: null,
prodqty: null,
yieldqty: null,
pcsKilnCar: null,
saleNo: null,
saleOrderItem: null,
soqty: null,
deliveryTime: null,
customerId: null,
shortDesc: null,
remark: null,
},
visible: false,
requestList: [
{
url: "/pms/equipment/search",
params: {
equipmentTypeCode: "Press",
},
method: "get",
target: "pressOptions",
label: "code",
},
{
url: "/pms/equipment/search",
params: {
equipmentTypeCode: "Mix",
},
method: "get",
target: "blenderOptions",
label: "code",
},
{
url: "/pms/equipment/search",
params: {
equipmentTypeCode: "Kiln",
},
method: "get",
target: "kilnOptions",
label: "code",
},
{
url: "/pms/bom/pageById",
params: {
limit: 999,
page: 1,
key: "",
id: "", // 编辑时传 bomId
},
method: "get",
target: "bomOptions",
label: "code",
extraLabel: "name",
cache: true,
},
{
url: "/pms/equipmentTech/pageView",
params: {
limit: 999,
page: 1,
key: "",
shape: "",
wsId: 5,
},
method: "post",
target: "packOptions",
label: "code",
},
{
url: "/pms/product/page",
params: {
limit: 999,
page: 1,
key: "",
},
method: "get",
target: "productOptions",
label: "code",
},
{
url: "/pms/shape/page",
params: {
limit: 999,
page: 1,
key: "",
},
method: "get",
target: "shapeOptions",
label: "code",
},
{
url: "/pms/customer/page",
params: {
limit: 999,
page: 1,
name: "",
},
method: "get",
target: "clientOptions",
label: "name",
},
],
promiseList: [],
bomId: null,
btnLoading: false,
};
},
computed: {
palletType() {
return getDictDataList("pallet_type");
},
},
methods: {
/**
* 打开弹窗后,准备下拉选项数据
* 复用方式:
* 1. 在 data 里定义 requestList
* 2. 复制本方法到组件中去
* 3. requestList 参考上面的 data
*/
async prepareSelectOptions() {
this.optionsLoading = true;
this.requestList.forEach((req) => {
this.promiseList.push(async () => {
const { data: res } = await this.$http[req.method](
req.url,
req.method.toLowerCase() == "post" ? req.params : { params: req.params }
);
if (res.code == 0) {
if ("list" in res.data) {
// 从 target 中抽取缓存名称
if (req.cache) this.cachedList[req.target.replace(/options/i, "")] = res.data.list;
this[req.target] = res.data.list.map((item) =>
req.extraLabel
? {
[req.extraLabel]: item[req.extraLabel],
label: item[req.label],
value: item.id,
}
: {
label: item[req.label],
value: item.id,
}
);
} else if (Array.isArray(res.data)) {
if (req.cache) this.cachedList[req.target.replace(/options/i, "")] = res.data;
this[req.target] = res.data.map((item) =>
req.extraLabel
? {
[req.extraLabel]: item[req.extraLabel],
label: item[req.label],
value: item.id,
}
: {
label: item[req.label],
value: item.id,
}
);
}
}
});
});
try {
await Promise.all(this.promiseList.map((fn) => fn()));
} catch (err) {
this.$message.error("获取数据失败,请刷新页面重试");
this.optionsLoading = false;
}
this.optionsLoading = false;
},
/**
* 向这种select上的监听事件
* 不自动生成
* 因为每个页面也许有独立的需求链
*/
handleBomChange(bomID) {
console.log("[handleBomChange] val is: ", bomID);
const target = this.cachedList.bom.find((item) => item.id === bomID);
// 这个单独的 bomId 是个极其特殊的需求,所以不放在 dataForm 里
this.bomId = bomID;
this.getBomVersionList(target);
this.$set(this.dataForm, "brand", target.name);
this.$set(this.dataForm, "ai", target.version);
},
async getBomVersionList(bom) {
try {
const { data: res } = await this.$http.get("/pms/bom/pageVersion", { params: { key: bom.code } });
console.log("[bom version list]", res.data.list);
this.versionList = res.data.list.map((item) => ({
label: item.version,
value: item.version,
id: item.id,
}));
} catch (err) {
this.$message.error("获取数据失败,请刷新页面重试");
}
},
/**
* 版本 变化,更新 bomList
* @param {*} v
*/
handleVersionChange(v) {
const targetBom = this.versionList.find((item) => item.value === v);
// this.bomId 用于在提交的时候置换 this.dataForm.bomId
this.bomId = targetBom.id;
console.log("[handleVersionChange] new bomID", this.bomId);
},
async init(id, detail_mode) {
this.visible = true;
this.mode = detail_mode ? "#detail" : id ? "#edit#reset" : "#create#reset";
await this.prepareSelectOptions();
if (this.$refs.dataForm) {
this.$refs.dataForm.clearValidate();
}
this.$nextTick(() => {
this.dataForm.id = id || null;
if (this.dataForm.id) {
// 如果是编辑
this.formLoading = true;
// 获取基本信息
this.$http
.get(this.urls.base + `/${this.dataForm.id}`)
.then(({ data: res }) => {
if (res && res.code === 0) {
this.dataForm = __pick(res.data, Object.keys(this.dataForm));
return res.data.bomId; // 特殊需求:编辑页面,还要根据 bomId 来更新配方号
} else {
this.$message({
message: `${res.code}: ${res.msg}`,
type: "error",
duration: 1500,
});
}
})
.then((bomId) => {
return this.$http({
url: "/pms/bom/pageById",
method: "get",
params: {
limit: 999,
page: 1,
key: "",
id: bomId,
},
});
})
.then(({ data: res }) => {
if (res.code == 0) {
this.bomOptions = res.data.list.map((item) => ({
name: item.name,
label: item.code,
value: item.id,
}));
}
this.formLoading = false;
})
.catch((err) => {
this.formLoading = false;
this.$message({
message: `${err}`,
type: "error",
duration: 1500,
});
});
} else {
// 如果不是编辑
this.formLoading = false;
}
});
},
/** handlers */
handleSelectChange(col, eventValue) {
this.$forceUpdate();
},
handleSave(method = "POST") {
this.$refs.dataForm.validate(async (valid) => {
if (valid) {
this.btnLoading = true;
try {
const { data: res } = await this.$http({
url: this.urls.base,
method,
data: {
...this.dataForm,
bomId: this.bomId != null ? this.bomId : this.dataForm.bomId,
brand: null, // 这两项都不需要后端通过BOM ID可以唯一确定
ai: null, // 这两项都不需要后端通过BOM ID可以唯一确定
},
});
console.log("herer.......", res);
if (res && res.code == 0) {
this.$message.success("添加成功");
this.$emit("refreshDataList");
this.handleClose();
this.btnLoading = false;
} else {
throw new Error("请求出错");
}
} catch (err) {
this.$message.error("参数错误:" + "msg" in err ? err.msg : err);
this.btnLoading = false;
}
}
});
},
handleReset() {
this.bomId = null;
Object.keys(this.dataForm).forEach((k) => {
this.dataForm[k] = null;
});
},
handleClose() {
this.visible = false;
},
},
};
</script>
<style scoped>
.order--edit_dialog >>> .el-dialog {
display: flex;
flex-direction: column;
overflow: hidden;
border-radius: 12px;
}
.order--edit_dialog >>> .el-dialog__header {
padding: 0 20px 0;
/* background: linear-gradient(to bottom, #eee, #ccc, #eee); */
background: #eeec;
border-bottom: 1px solid #dddc;
}
.order--edit_dialog >>> .el-dialog__body {
/* padding-top: 16px !important;
padding-bottom: 16px !important; */
/* transform: scale(0.95); */
padding-top: 24px !important;
padding-bottom: 0 !important;
flex: 1;
overflow-y: auto;
}
.order--edit_dialog >>> .el-dialog__footer {
border-top: 1px solid #dddc;
background-color: #eeec;
padding: 10px 20px;
}
.el-select,
.el-cascader,
.el-date-editor {
width: 100% !important;
}
.h0 {
height: 0;
width: 0;
}
</style>