|
@@ -206,6 +206,11 @@
|
|
|
<div style="padding-left:50px">
|
|
|
<div style="margin-bottom:10px;">
|
|
|
<TitleInfo content='BOM单:'></TitleInfo>
|
|
|
+ <div v-if="route.query.flowKey=='contract_update_flow'" style="margin-top:10px">
|
|
|
+ <el-button type="primary" @click="openDialog(scope.$index,1)" plain>主材</el-button>
|
|
|
+ <el-button type="primary" @click="openDialog(scope.$index,2)" plain>工艺</el-button>
|
|
|
+ <el-button type="primary" @click="openDialog(scope.$index,3)" plain>辅材</el-button>
|
|
|
+ </div>
|
|
|
</div>
|
|
|
<el-table :data="scope.row.contractProductBomList" style="width: 100%;" border class="bom-table" row-key="materialId">
|
|
|
<el-table-column label="图片" width="80">
|
|
@@ -226,8 +231,32 @@
|
|
|
</template>
|
|
|
</el-table-column>
|
|
|
<el-table-column prop="productColor" label="颜色" width="170" />
|
|
|
- <el-table-column prop="standardDosage" label="标准用量" width="100" />
|
|
|
- <el-table-column prop="lossRate" label="损耗率(%)" width="100" />
|
|
|
+ <el-table-column prop="standardDosage" label="标准用量" width="110">
|
|
|
+ <template #default="{ row, $index }">
|
|
|
+ <div style="width: 100%">
|
|
|
+ <el-form-item v-if="route.query.flowKey=='contract_update_flow'"
|
|
|
+ :prop="'contractProductList.' + scope.$index + '.contractProductBomList.' + $index + '.standardDosage'"
|
|
|
+ :rules="rules.standardDosage" :inline-message="true" class="margin-b-0 wid100">
|
|
|
+ <el-input-number onmousewheel="return false;" v-model="row.standardDosage" placeholder="请输入" style="width: 100%"
|
|
|
+ :precision="0" :controls="false" :min="1" @change="calculationAmount(true)" />
|
|
|
+ </el-form-item>
|
|
|
+ <span v-else>{{row.standardDosage}}</span>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column prop="lossRate" label="损耗率(%)" width="110">
|
|
|
+ <template #default="{ row, $index }">
|
|
|
+ <div style="width: 100%">
|
|
|
+ <el-form-item v-if="route.query.flowKey=='contract_update_flow'"
|
|
|
+ :prop="'contractProductList.' + scope.$index + '.contractProductBomList.' + $index + '.lossRate'"
|
|
|
+ :rules="rules.lossRate" :inline-message="true" class="margin-b-0 wid100">
|
|
|
+ <el-input-number onmousewheel="return false;" v-model="row.lossRate" placeholder="请输入" style="width: 100%" :precision="2"
|
|
|
+ :controls="false" :min="0" @change="calculationAmount(true)" />
|
|
|
+ </el-form-item>
|
|
|
+ <span v-else>{{row.lossRate}}</span>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
<el-table-column prop="quantity" label="数量" width="130">
|
|
|
<template #default="{ row, $index }">
|
|
|
<div style="width: 100%">
|
|
@@ -571,6 +600,20 @@
|
|
|
</template>
|
|
|
</el-dialog>
|
|
|
|
|
|
+ <el-dialog :title="'原材料选择'" v-model="openSelectRawMaterial" width="90%" destroy-on-close>
|
|
|
+ <SelectMaterial :ancestors="110" @selectMaterial="selectRawMaterial"></SelectMaterial>
|
|
|
+ <template #footer>
|
|
|
+ <el-button @click="openSelectRawMaterial = false" size="defualt" v-debounce>取 消</el-button>
|
|
|
+ </template>
|
|
|
+ </el-dialog>
|
|
|
+
|
|
|
+ <el-dialog :title="'工艺选择'" v-model="openSelectTechnology" width="90%" destroy-on-close>
|
|
|
+ <SelectTechnology :isSelect="true" @selectTechnology="selectTechnology"></SelectTechnology>
|
|
|
+ <template #footer>
|
|
|
+ <el-button @click="openSelectTechnology = false" size="defualt" v-debounce>取 消</el-button>
|
|
|
+ </template>
|
|
|
+ </el-dialog>
|
|
|
+
|
|
|
<el-dialog :title="'物料选择'" v-model="openSelectMaterial" width="90%" destroy-on-close>
|
|
|
<SelectMaterial :isNeRawMaterial="'1'" @selectMaterial="selectMaterial"></SelectMaterial>
|
|
|
<template #footer>
|
|
@@ -589,6 +632,7 @@
|
|
|
import byForm from "@/components/byForm/index";
|
|
|
import SelectProduct from "@/components/product/SelectProduct.vue";
|
|
|
import SelectMaterial from "@/components/product/SelectMaterial.vue";
|
|
|
+import SelectTechnology from "@/views/production/project/technology/index.vue";
|
|
|
import Editor from "@/components/Editor/index.vue";
|
|
|
import selectCity from "@/components/selectCity/index.vue";
|
|
|
import { useRoute } from "vue-router";
|
|
@@ -597,7 +641,6 @@ import SelectSample from "@/components/contractCom/selectSample.vue";
|
|
|
import * as echarts from "echarts";
|
|
|
import $bus from "@/bus/index.js";
|
|
|
import { v4 as uuidv4 } from "uuid";
|
|
|
-import { async } from "@antv/x6/lib/registry/marker/main";
|
|
|
const route = useRoute();
|
|
|
const { proxy } = getCurrentInstance();
|
|
|
// 接收父组件的传值
|
|
@@ -628,9 +671,13 @@ const settlementWay = computed(
|
|
|
const frontLinesData = computed(
|
|
|
() => proxy.useUserStore().allDict["front_lines"]
|
|
|
);
|
|
|
+const qualityLevel = computed(
|
|
|
+ () => proxy.useUserStore().allDict["quality_level"]
|
|
|
+);
|
|
|
const accountList = ref([]);
|
|
|
const customerList = ref([]);
|
|
|
const templateList = ref([]);
|
|
|
+const sealUseData = ref([]);
|
|
|
const userList = ref([]);
|
|
|
const corporationList = ref([]);
|
|
|
const customerUserList = ref([]);
|
|
@@ -833,6 +880,29 @@ const formConfig = computed(() => {
|
|
|
itemWidth: 50,
|
|
|
},
|
|
|
{
|
|
|
+ type: "select",
|
|
|
+ prop: "placeOrderType",
|
|
|
+ label: "是否首单",
|
|
|
+ data: [
|
|
|
+ {
|
|
|
+ dictKey: "10",
|
|
|
+ dictValue: "首单",
|
|
|
+ },
|
|
|
+ {
|
|
|
+ dictKey: "20",
|
|
|
+ dictValue: "返单",
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ itemWidth: 50,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ type: "select",
|
|
|
+ prop: "qualityLv",
|
|
|
+ label: "品质等级",
|
|
|
+ data: qualityLevel.value,
|
|
|
+ itemWidth: 50,
|
|
|
+ },
|
|
|
+ {
|
|
|
type: "title",
|
|
|
title: "贸易信息",
|
|
|
haveLine: true,
|
|
@@ -1254,6 +1324,14 @@ const formConfig = computed(() => {
|
|
|
},
|
|
|
},
|
|
|
{
|
|
|
+ type: "select",
|
|
|
+ prop: "sealUseId",
|
|
|
+ label: "用印流水号",
|
|
|
+ data: sealUseData.value,
|
|
|
+ itemWidth: 50,
|
|
|
+ fn: (val) => {},
|
|
|
+ },
|
|
|
+ {
|
|
|
type: "slot",
|
|
|
slotName: "templateContent",
|
|
|
prop: "templateContent",
|
|
@@ -1392,7 +1470,10 @@ const getaccountList = (val) => {
|
|
|
});
|
|
|
};
|
|
|
const isFormDetail = ref(false);
|
|
|
-if (route.query && route.query.processType && route.query.processType == 20) {
|
|
|
+if (
|
|
|
+ (route.query && route.query.processType && route.query.processType == 20) ||
|
|
|
+ route.query.currentContractId
|
|
|
+) {
|
|
|
isFormDetail.value = true;
|
|
|
}
|
|
|
|
|
@@ -1411,6 +1492,19 @@ const getDict = () => {
|
|
|
});
|
|
|
|
|
|
proxy
|
|
|
+ .post("/sealUse/page", {
|
|
|
+ pageNum: 1,
|
|
|
+ pageSize: 999,
|
|
|
+ isLinkContract: isFormDetail.value == true ? "" : 0,
|
|
|
+ })
|
|
|
+ .then((res) => {
|
|
|
+ sealUseData.value = res.rows.map((x) => ({
|
|
|
+ label: x.code,
|
|
|
+ value: x.id,
|
|
|
+ }));
|
|
|
+ });
|
|
|
+
|
|
|
+ proxy
|
|
|
.post("/customer/selPage", {
|
|
|
pageNum: 1,
|
|
|
pageSize: 50,
|
|
@@ -1741,6 +1835,37 @@ const selectProduct = async (goods) => {
|
|
|
}
|
|
|
};
|
|
|
|
|
|
+// const selectMaterial = (goods) => {
|
|
|
+// let flag = formData.data.contractProductList[
|
|
|
+// indexValue.value
|
|
|
+// ].contractProductBomList.some((x) => x.materialId == goods.id);
|
|
|
+// if (!flag) {
|
|
|
+// let fileUrl = "";
|
|
|
+// if (goods.fileList && goods.fileList.length > 0) {
|
|
|
+// fileUrl = goods.fileList[0].fileUrl;
|
|
|
+// }
|
|
|
+// formData.data.contractProductList[
|
|
|
+// indexValue.value
|
|
|
+// ].contractProductBomList.push({
|
|
|
+// fileUrl: fileUrl,
|
|
|
+// materialId: goods.id,
|
|
|
+// productName: goods.name,
|
|
|
+// productCode: goods.customCode,
|
|
|
+// productLength: goods["length"],
|
|
|
+// productWidth: goods.width,
|
|
|
+// productHeight: goods.height,
|
|
|
+// quantity: null,
|
|
|
+// price: goods.price || null,
|
|
|
+// amount: "",
|
|
|
+// fileList: [],
|
|
|
+// type: 2,
|
|
|
+// });
|
|
|
+// proxy.msgTip("选择成功");
|
|
|
+// } else {
|
|
|
+// proxy.msgTip("该物料已选择", 2);
|
|
|
+// }
|
|
|
+// };
|
|
|
+
|
|
|
const selectMaterial = (goods) => {
|
|
|
let flag = formData.data.contractProductList[
|
|
|
indexValue.value
|
|
@@ -1760,8 +1885,12 @@ const selectMaterial = (goods) => {
|
|
|
productLength: goods["length"],
|
|
|
productWidth: goods.width,
|
|
|
productHeight: goods.height,
|
|
|
+ productColor: goods.color,
|
|
|
quantity: null,
|
|
|
- price: goods.price || null,
|
|
|
+ standardDosage: 1,
|
|
|
+ lossRate: null,
|
|
|
+ remark: "",
|
|
|
+ price: null,
|
|
|
amount: "",
|
|
|
fileList: [],
|
|
|
type: 2,
|
|
@@ -1851,16 +1980,19 @@ const calculationAmount = (flag = false) => {
|
|
|
Number(formData.data.contractProductList[i].businessCostPrice)
|
|
|
).toFixed(2);
|
|
|
let row = formData.data.contractProductList[i];
|
|
|
- if (flag) {
|
|
|
+ if (flag && row.quantity) {
|
|
|
for (let j = 0; j < row.contractProductBomList.length; j++) {
|
|
|
let jrow = row.contractProductBomList[j];
|
|
|
- jrow.quantity = Math.ceil(
|
|
|
- Number(
|
|
|
- parseFloat(
|
|
|
- (row.quantity / jrow.standardDosage) * (1 + jrow.lossRate / 100)
|
|
|
- ).toFixed(2)
|
|
|
- )
|
|
|
- );
|
|
|
+ if (jrow.standardDosage && jrow.lossRate != null) {
|
|
|
+ jrow.quantity = Math.ceil(
|
|
|
+ Number(
|
|
|
+ parseFloat(
|
|
|
+ (row.quantity / jrow.standardDosage) *
|
|
|
+ (1 + jrow.lossRate / 100)
|
|
|
+ ).toFixed(2)
|
|
|
+ )
|
|
|
+ );
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|
|
@@ -2044,7 +2176,11 @@ const handleSubmit = async (isStag = false) => {
|
|
|
) {
|
|
|
for (let i = 0; i < formData.data.contractProductList.length; i++) {
|
|
|
const ele = formData.data.contractProductList[i];
|
|
|
- if (ele.isShowProductFile && ele.fileListOne.length > 0) {
|
|
|
+ if (
|
|
|
+ ele.isShowProductFile &&
|
|
|
+ ele.fileListOne &&
|
|
|
+ ele.fileListOne.length > 0
|
|
|
+ ) {
|
|
|
ele.prodFileList = ele.fileListOne;
|
|
|
}
|
|
|
}
|
|
@@ -2147,6 +2283,97 @@ const handleClickUploadOne = (index) => {
|
|
|
}
|
|
|
};
|
|
|
|
|
|
+const dialogOpenType = ref(-1);
|
|
|
+const openSelectRawMaterial = ref(false);
|
|
|
+const openSelectTechnology = ref(false);
|
|
|
+const openDialog = (index, type) => {
|
|
|
+ indexValue.value = index;
|
|
|
+ dialogOpenType.value = type;
|
|
|
+ if (type == 1) {
|
|
|
+ openSelectRawMaterial.value = true;
|
|
|
+ }
|
|
|
+ if (type == 2) {
|
|
|
+ openSelectTechnology.value = true;
|
|
|
+ }
|
|
|
+ if (type == 3) {
|
|
|
+ handleClickSelectMaterial(index);
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+const selectRawMaterial = (row) => {
|
|
|
+ if (dialogOpenType.value == 1) {
|
|
|
+ let flag = formData.data.contractProductList[
|
|
|
+ indexValue.value
|
|
|
+ ].contractProductBomList.some((x) => x.materialId == row.id);
|
|
|
+ if (!flag) {
|
|
|
+ formData.data.contractProductList[
|
|
|
+ indexValue.value
|
|
|
+ ].contractProductBomList.unshift({
|
|
|
+ materialId: row.id,
|
|
|
+ type: 1,
|
|
|
+ productName: row.name,
|
|
|
+ productCode: row.customCode,
|
|
|
+ productLength: row["length"],
|
|
|
+ productWidth: row.width,
|
|
|
+ productHeight: row.height,
|
|
|
+ productColor: row.color,
|
|
|
+ quantity: null,
|
|
|
+ standardDosage: 1,
|
|
|
+ lossRate: null,
|
|
|
+ remark: "",
|
|
|
+ price: null,
|
|
|
+ amount: "",
|
|
|
+ fileList: [],
|
|
|
+ });
|
|
|
+ proxy.msgTip("选择成功");
|
|
|
+ } else {
|
|
|
+ proxy.msgTip("该物料已选择", 2);
|
|
|
+ }
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+const selectTechnology = (row) => {
|
|
|
+ if (
|
|
|
+ dialogOpenType.value == 2 &&
|
|
|
+ row.processRouteList &&
|
|
|
+ row.processRouteList.length > 0
|
|
|
+ ) {
|
|
|
+ formData.data.contractProductList[indexValue.value].technologyId = row.id;
|
|
|
+ formData.data.contractProductList[indexValue.value].contractProductBomList =
|
|
|
+ formData.data.contractProductList[
|
|
|
+ indexValue.value
|
|
|
+ ].contractProductBomList.filter((x) => x.type != 3);
|
|
|
+ let index = formData.data.contractProductList[
|
|
|
+ indexValue.value
|
|
|
+ ].contractProductBomList.findIndex((x) => x.type == 2);
|
|
|
+ let arr = row.processRouteList.map((x) => ({
|
|
|
+ type: 3,
|
|
|
+ materialId: x.id,
|
|
|
+ productName: x.name,
|
|
|
+ productCode: x.code,
|
|
|
+ quantity: null,
|
|
|
+ standardDosage: 1,
|
|
|
+ lossRate: null,
|
|
|
+ remark: "",
|
|
|
+ }));
|
|
|
+
|
|
|
+ if (index >= 0) {
|
|
|
+ formData.data.contractProductList[
|
|
|
+ indexValue.value
|
|
|
+ ].contractProductBomList.splice(index, 0, ...arr);
|
|
|
+ } else {
|
|
|
+ let arrLength =
|
|
|
+ formData.data.contractProductList[indexValue.value]
|
|
|
+ .contractProductBomList.length;
|
|
|
+ formData.data.contractProductList[
|
|
|
+ indexValue.value
|
|
|
+ ].contractProductBomList.splice(arrLength ? arrLength : 0, 0, ...arr);
|
|
|
+ }
|
|
|
+ openSelectTechnology.value = false;
|
|
|
+ return proxy.msgTip("选择成功", 1);
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
const getAllData = (businessId) => {
|
|
|
proxy.post("/contract/detail", { id: businessId }).then(async (res) => {
|
|
|
res.countryId = res.buyCountryId;
|
|
@@ -2333,6 +2560,7 @@ const getPriceSheetData = (id) => {
|
|
|
// companyId: res.companyId,
|
|
|
ofCompanyId: res.ofCompanyId,
|
|
|
deptId: res.deptId,
|
|
|
+ qualityLv: res.qualityLv,
|
|
|
buyCorporationId: res.buyCorporationId,
|
|
|
buyAddress: res.buyAddress,
|
|
|
buyPostalCode: res.buyPostalCode,
|
|
@@ -2350,6 +2578,7 @@ const getPriceSheetData = (id) => {
|
|
|
// } else {
|
|
|
// formData.data.contractType = "1";
|
|
|
// }
|
|
|
+
|
|
|
formData.data.contractProductList = res.quotationProductList.map((x) => ({
|
|
|
quotationProductId: x.id,
|
|
|
fileUrl: "",
|