<template> <div style="width: 100%; padding: 0px 15px"> <byForm :formConfig="formConfig" :formOption="formOption" v-model="formData.data" :rules="rules" ref="submit" > <template #buyer> <div style="width: 100%"> <el-form-item prop="buyCorporationId"> <el-select v-model="formData.data.buyCorporationId" style="width: 100%" @change="changeBuyCorporation" > <el-option v-for="item in corporationList" :key="item.value" :label="item.label" :value="item.value" /> </el-select> </el-form-item> <el-row style="margin-top: 20px; width: 100%"> <el-col :span="8"> <el-form-item label="地址" prop="buyCountryName"> <el-input v-model="formData.data.buyCountryName" placeholder="请输入国家" @change="changeAddress" /> </el-form-item> </el-col> <el-col :span="8"> <el-form-item label=" " prop="buyProvinceName"> <el-input v-model="formData.data.buyProvinceName" placeholder="请输入省/州" @change="changeAddress" /> </el-form-item> </el-col> <el-col :span="8"> <el-form-item label=" " prop="buyCityName"> <el-input v-model="formData.data.buyCityName" placeholder="请输入城市" @change="changeAddress" /> </el-form-item> </el-col> </el-row> <el-row style="margin-top: 20px; width: 100%"> <el-col :span="24"> <el-form-item prop="buyAddress"> <el-input v-model="formData.data.buyAddress" type="textarea" @change="changeAddress" /> </el-form-item> </el-col> </el-row> <el-row style="margin-top: 20px; width: 100%"> <el-col :span="8"> <el-form-item label="联系人" prop="buyContactName"> <el-input v-model="formData.data.buyContactName" placeholder="请输入联系人" /> </el-form-item> </el-col> <el-col :span="16"> <el-form-item label=" " prop="buyContactNumber"> <el-input v-model="formData.data.buyContactNumber" placeholder="请输入联系人电话" /> </el-form-item> </el-col> </el-row> </div> </template> <template #seller> <div style="width: 100%"> <div style="width: 100%"> <el-form-item prop="sellCorporationId"> <el-select v-model="formData.data.sellCorporationId" style="width: 100%" filterable remote reserve-keyword placeholder="请输入关键字" remote-show-suffix :remote-method="remoteMethod" :loading="loadingSearch" @input="remoteMethod" @change="changeSupplier" > <el-option v-for="item in supplierList" :key="item.value" :label="item.label" :value="item.value" /> </el-select> </el-form-item> <el-row style="margin-top: 20px; width: 100%"> <el-col :span="6"> <el-form-item label="地址" prop="countryId"> <el-select v-model="formData.data.countryId" placeholder="国家" filterable @change="(val) => changeSellAddress(val, '20')" > <el-option v-for="item in countryData" :label="item.chineseName" :value="item.id" > </el-option> </el-select> </el-form-item> </el-col> <el-col :span="6"> <el-form-item label=" " prop="provinceName"> <selectCity placeholder="省/洲" @change="(val) => changeSellAddress(val, '30')" addressId="provinceId" addressName="provinceName" v-model="formData.data" :data="provinceData" > </selectCity> </el-form-item> </el-col> <el-col :span="6"> <el-form-item label=" " prop="cityName"> <selectCity placeholder="城市" addressId="cityId" addressName="cityName" v-model="formData.data" :data="cityData" @change="changeAddress" > </selectCity> </el-form-item> </el-col> <el-col :span="6"> <el-form-item label=" " prop="sellPostalCode"> <el-input v-model="formData.data.sellPostalCode" placeholder="请输入邮编" /> </el-form-item> </el-col> </el-row> <el-row style="margin-top: 20px; width: 100%"> <el-col :span="24"> <el-form-item prop="sellAddress"> <el-input v-model="formData.data.sellAddress" type="textarea" @change="changeAddress" /> </el-form-item> </el-col> </el-row> <el-row style="margin-top: 20px; width: 100%"> <el-col :span="8"> <el-form-item label="联系人" prop="sellContactName"> <el-input v-model="formData.data.sellContactName" placeholder="请输入联系人" /> </el-form-item> </el-col> <el-col :span="16"> <el-form-item label=" " prop="sellContactNumber"> <el-input v-model="formData.data.sellContactNumber" placeholder="请输入联系人电话" /> </el-form-item> </el-col> </el-row> </div> </div> </template> <template #payment> <div style="width: 100%"> <el-row style="margin-top: 20px; width: 100%"> <el-col :span="6"> <el-form-item label="付款方式" prop="paymentMethod"> <el-select v-model="formData.data.paymentMethod" placeholder="请选择付款方式" style="width: 100%" > <el-option v-for="item in fundsPaymentMethod" :key="item.value" :label="item.label" :value="item.value" /> </el-select> </el-form-item> </el-col> <el-col :span="6"> <el-form-item label="发票类型" prop="invoiceType"> <el-select v-model="formData.data.invoiceType" placeholder="请选择发票类型" style="width: 100%" > <el-option v-for="item in invoiceType" :key="item.value" :label="item.label" :value="item.value" /> </el-select> </el-form-item> </el-col> </el-row> </div> </template> <template #delivery> <div style="width: 100%"> <el-row style="margin-top: 20px; width: 100%"> <el-col :span="12"> <el-form-item label="交货类型" prop="deliveryType"> <el-radio-group v-model="formData.data.deliveryType" @change="changeAddress" > <el-radio v-for="(item, index) in deliveryType" :key="index" :label="item.value" border >{{ item.label }}</el-radio > </el-radio-group> </el-form-item> </el-col> </el-row> <el-row style="margin-top: 20px; width: 100%"> <el-col :span="12"> <el-form-item label="详细地址" prop="address"> <el-input v-model="formData.data.address" :rows="2" type="textarea" placeholder="请输入详细地址" /> </el-form-item> </el-col> </el-row> <el-row style="margin-top: 20px; width: 100%"> <el-col :span="6"> <el-form-item label="交付日期" prop="deliveryTime"> <el-date-picker v-model="formData.data.deliveryTime" type="date" placeholder="请选择交付日期" value-format="YYYY-MM-DD" /> </el-form-item> </el-col> <el-col :span="6"> <el-form-item label="质保期 (天)" prop="warranty"> <el-input-number onmousewheel="return false;" v-model="formData.data.warranty" placeholder="请输入质保期" style="width: 100%" :precision="0" :controls="false" :min="0" /> </el-form-item> </el-col> </el-row> </div> </template> <template #commodity> <div style="width: 100%; padding: 15px; border: 1px solid #eee" v-if=" formData.data.purchaseProductList && formData.data.purchaseProductList.length > 0 " > <el-row style=" margin-bottom: 15px; background: #eeeeee; font-weight: 700; padding: 10px; " > <el-col :span="14">货品信息</el-col> <el-col :span="4" >订单总数:{{ formData.data.purchaseProductList.length }}</el-col > <el-col :span="6">订单总金额:{{ getTotalAmount() }}</el-col> </el-row> <template v-for="(item, index) in formData.data.purchaseProductList" :key="index" > <div style="width: 100%"> <el-table :data="item.purchaseProductMountingsList" :style=" index !== formData.data.purchaseProductList.length - 1 ? 'margin-bottom: 15px' : '' " > <!-- :span-method=" ({ rowIndex, columnIndex }) => objectSpanMethod(rowIndex, columnIndex, item) " --> <el-table-column label="货品信息" align="left"> <template #default="{ row }"> <div style="display: flex; align-items: center"> <div style="width: 50px; height: 50px"> <img v-if="row.fileUrl" :src="row.fileUrl" class="pic" @click="onPicture(row.fileUrl)" /> </div> <div style="margin-left: 20px"> <div>{{ row.productName }}</div> <div style="display: flex; color: #999999"> <span >类型: {{ dictValueLabel(row.productType, productType) }}</span ><span style="margin-left: 20px" >尺寸:{{ row.productModel }}</span > </div> </div> </div> </template> </el-table-column> <el-table-column label="数量" align="left" prop="quantity" width="180" > <template #default="{ row, $index }"> <div style="width: 100%" class="removePadding"> <el-form-item :prop=" 'purchaseProductList.' + index + '.purchaseProductMountingsList.' + $index + '.quantity' " :rules="rules.quantity" :inline-message="true" @change=" () => { return changeProductMaterial(index, $index); } " > <el-input-number onmousewheel="return false;" v-model="row.quantity" placeholder="请输入数量" :precision="0" :controls="false" :min="0" /> </el-form-item> </div> </template> </el-table-column> <el-table-column label="单价" align="left" prop="price" width="180" > <template #default="{ row, $index }"> <div style="width: 100%" class="removePadding"> <el-form-item :prop=" 'purchaseProductList.' + index + '.purchaseProductMountingsList.' + $index + '.price' " :rules="rules.price" :inline-message="true" @change=" () => { return changeProductMaterial(index, $index); } " > <el-input-number onmousewheel="return false;" v-model="row.price" placeholder="请输入单价" :precision="2" :controls="false" :min="0" /> </el-form-item> </div> </template> </el-table-column> <el-table-column label="金额小计" align="left" width="140" prop="amount" /> <el-table-column label="操作" align="center" width="100"> <template #default="{ row, $index }"> <div v-if="$index === 0"> <div> <el-button type="primary" text @click="handleHandover(item, index)" >备注</el-button > </div> <div> <el-button type="primary" text @click="handleMaterial(index)" >添加配件</el-button > </div> </div> <div v-else> <el-button type="primary" link @click="handleRemove(index, $index)" >删除</el-button > </div> </template> </el-table-column> </el-table> </div> </template> </div> <!-- <div style="width: 100%" v-if=" formData.data.purchaseProductList && formData.data.purchaseProductList.length > 0 " > <div :style=" index !== formData.data.purchaseProductList.length - 1 ? 'margin-bottom: 20px' : '' " v-for="(item, index) in formData.data.purchaseProductList" :key="item.dataResourceId" > <div style=" border: 1px solid #ccc; padding: 20px 10px 0 10px; width: 100%; " > <el-row style="width: 100%" :gutter="5" type="flex" align="middle" > <el-col :span="2" style="text-align: center"> <img v-if="item.fileUrl" :src="item.fileUrl" class="pic" @click="onPicture(item.fileUrl)" /> </el-col> <el-col :span="5"> <span>产品名称: {{ item.productName }}</span> </el-col> <el-col :span="4"> <span>尺寸: {{ item.productModel }}</span> </el-col> <el-col :span="3"> <span>数量: {{ item.quantity }}</span> </el-col> <el-col :span="3"> <span>单价: {{ item.price }}</span> </el-col> <el-col :span="2"> <el-button type="primary" text @click="handleHandover(item, index)" >编辑备注</el-button > </el-col> <el-col :span="2"> <el-button type="primary" text @click="handleMaterial(index)" >添加配件</el-button > </el-col> <el-col :span="3"> <span>金额小计: {{ item.amount }}</span> </el-col> </el-row> <el-collapse v-model="item.activeName" class="hideCollapse" accordion > <el-collapse-item title="" :name="true"> <div style="padding: 0 40px"> <el-table :data="item.purchaseProductMountingsList" style="width: 100%" > <el-table-column label="图片" align="center" width="80"> <template #default="{ row }"> <img v-if="row.fileUrl" :src="row.fileUrl" class="pic" @click="onPicture(row.fileUrl)" /> </template> </el-table-column> <el-table-column label="类型" align="center" width="80"> <template #default="{ row }"> <div> {{ dictValueLabel(row.productType, productType) }} </div> </template> </el-table-column> <el-table-column label="产品名称" prop="productName" min-width="180" /> <el-table-column label="尺寸" prop="productModel" min-width="140" /> <el-table-column label="单价" width="140"> <template #default="{ row, $index }"> <div style="width: 100%" class="removePadding"> <el-form-item :prop=" 'purchaseProductList.' + index + '.purchaseProductMountingsList.' + $index + '.price' " :rules="rules.price" :inline-message="true" @change=" () => { return changeProductMaterial(index, $index); } " > <el-input-number onmousewheel="return false;" v-model="row.price" placeholder="请输入单价" :precision="2" :controls="false" :min="0" /> </el-form-item> </div> </template> </el-table-column> <el-table-column label="数量" width="140"> <template #default="{ row, $index }"> <div style="width: 100%" class="removePadding"> <el-form-item :prop=" 'purchaseProductList.' + index + '.purchaseProductMountingsList.' + $index + '.quantity' " :rules="rules.quantity" :inline-message="true" @change=" () => { return changeProductMaterial(index, $index); } " > <el-input-number onmousewheel="return false;" v-model="row.quantity" placeholder="请输入数量" :precision="0" :controls="false" :min="0" /> </el-form-item> </div> </template> </el-table-column> <el-table-column label="金额" prop="amount" width="100" /> <el-table-column label="操作" align="center" width="80" fixed="right" > <template #default="{ $index }"> <el-button type="primary" v-if="$index !== 0" link @click="handleRemove(index, $index)" >删除</el-button > </template> </el-table-column> </el-table> </div> </el-collapse-item> </el-collapse> <div style="text-align: center; margin-top: -18px"> <el-button type="primary" @click="item.activeName = !item.activeName" style="margin-bottom: -28px" text > <span v-if="item.activeName"> <span style="vertical-align: middle">收起明细</span> <el-icon style=" margin-left: 8px; transform: rotate(-90deg); vertical-align: middle; " ><DArrowRight /></el-icon> </span> <span v-else> <span style="vertical-align: middle">查看明细</span> <el-icon style=" margin-left: 8px; transform: rotate(90deg); vertical-align: middle; " ><DArrowRight /></el-icon> </span> </el-button> </div> </div> </div> </div> --> </template> <template #otherCharge> <div style="width: 100%"> <el-button type="primary" @click="clickAdd()">添加行</el-button> <el-table :data="formData.data.purchaseProjectList" style="width: 100%; margin-top: 16px" > <el-table-column label="收费项目" width="220"> <template #default="{ row, $index }"> <div style="width: 100%"> <el-form-item :prop="'purchaseProjectList.' + $index + '.payName'" :rules="rules.payName" :inline-message="true" > <el-autocomplete v-model="row.payName" :fetch-suggestions="querySearch" clearable class="inline-input w-50" placeholder="请输入收费项目" /> </el-form-item> </div> </template> </el-table-column> <el-table-column label="备注"> <template #default="{ row, $index }"> <div style="width: 100%"> <el-form-item :prop="'purchaseProjectList.' + $index + '.remark'" > <el-input v-model="row.remark" placeholder="请输入备注" /> </el-form-item> </div> </template> </el-table-column> <el-table-column label="金额" width="130"> <template #default="{ row, $index }"> <div style="width: 100%"> <el-form-item :prop="'purchaseProjectList.' + $index + '.amount'" :rules="rules.amount" :inline-message="true" class="shrinkPadding" @change="changeProject" > <el-input-number onmousewheel="return false;" v-model="row.amount" placeholder="请输入金额" style="width: 100%" :precision="2" :controls="false" :min="0" /> </el-form-item> </div> </template> </el-table-column> <el-table-column label="操作" width="60" align="center" fixed="right" > <template #default="{ $index }"> <el-button type="primary" link @click="handleDelete($index)" >删除</el-button > </template> </el-table-column> </el-table> </div> </template> <template #offerMoney> <div style="width: 100%; display: flex"> <div style="width: calc(100% - 190px)"></div> <div style="width: 130px; padding: 0 12px"> <el-form-item label="合同总金额" prop="amount" class="shrinkPadding" > <el-input v-model="formData.data.amount" placeholder="合同总金额" disabled /> </el-form-item> </div> </div> </template> <template #contractClause> <div style="width: 100%"> <el-row style="margin-top: 20px; width: 100%"> <el-col :span="8"> <el-form-item label="合同模板" prop="contractTemplateId"> <el-select v-model="formData.data.contractTemplateId" style="width: 100%" @change="changeContractTemplate" > <el-option v-for="item in templateList" :key="item.value" :label="item.label" :value="item.value" /> </el-select> </el-form-item> </el-col> </el-row> <div style="margin-top: 20px; width: 100%"> <el-form-item label="条款内容" prop="remark"> <div v-if="judgeStatus()"> <div v-html="getHtmlVal(formData.data.remark)"></div> </div> <Editor v-else style="width: 100%" :value="formData.data.remark" @updateValue="updateContent" ref="remarkEditor" /> </el-form-item> </div> </div> </template> <template #shipment> <div style="width: 100%"> <el-table :data="formData.data.purchaseArrivalList" style="width: 100%; margin-top: 16px" > <el-table-column prop="productCode" label="商品编码" width="120" /> <el-table-column prop="productName" label="商品名称" /> <el-table-column label="到货日期" width="220"> <template #default="{ row, $index }"> <div style="width: 100%"> <el-form-item :prop="'purchaseArrivalList.' + $index + '.arrivalTime'" :rules="rules.arrivalTime" :inline-message="true" > <el-date-picker v-model="row.arrivalTime" type="date" placeholder="请选择到货日期" value-format="YYYY-MM-DD" /> </el-form-item> </div> </template> </el-table-column> <el-table-column label="到货数量" width="160"> <template #default="{ row, $index }"> <div style="width: 100%"> <el-form-item :prop="'purchaseArrivalList.' + $index + '.quantity'" :inline-message="true" > <el-input-number onmousewheel="return false;" v-model="row.quantity" placeholder="请输入到货数量" style="width: 100%" :precision="0" :controls="false" :min="0" /> </el-form-item> </div> </template> </el-table-column> <el-table-column align="center" label="操作" width="120" fixed="right" > <template #default="{ row, $index }"> <el-button type="primary" link @click="clickSplit(row)" >拆分</el-button > <el-button type="primary" link @click="clickDelete($index)" >删除</el-button > </template> </el-table-column> </el-table> </div> </template> </byForm> <el-dialog v-if="openMaterialCompany" v-model="openMaterialCompany" title="公司产品库" width="90%" append-to-body > <ProductMaterial :selectStatus="true" @selectMaterial="selectMaterial" ></ProductMaterial> </el-dialog> <el-dialog title="备注" v-if="openHandover" v-model="openHandover" width="800" > <byForm :formConfig="formHandoverConfig" :formOption="formOption" v-model="productRow.data" > <template #file> <div style="width: 100%"> <el-upload v-model:fileList="fileList" action="https://winfaster.obs.cn-south-1.myhuaweicloud.com" :data="uploadData" multiple :before-upload="uploadFile" :on-success="handleSuccess" :on-preview="onPreviewFile" > <el-button>选择</el-button> </el-upload> </div> </template> <template #remark> <div style="width: 100%"> <Editor :value="productRow.data.remark" @updateValue="updateHandover" /> </div> </template> </byForm> <template #footer> <el-button @click="openHandover = false" size="large">取 消</el-button> <el-button type="primary" @click="submitHandoverForm()" size="large" >确 定</el-button > </template> </el-dialog> </div> </template> <script setup> import byForm from "@/components/byForm/index"; import ProductMaterial from "@/views/product/material/index"; import { ElMessage } from "element-plus"; import selectCity from "@/components/selectCity/index.vue"; import Editor from "@/components/Editor/index.vue"; import { useRoute } from "vue-router"; const route = useRoute(); const { proxy } = getCurrentInstance(); const invoiceType = ref([]); const fundsPaymentMethod = ref([]); const templateList = ref([]); const corporationList = ref([]); const supplierList = ref([]); const countryData = ref([]); const provinceData = ref([]); const cityData = ref([]); const openMaterialCompany = ref(false); const formData = reactive({ data: { deliveryType: 1, remark: "", amount: undefined, purchaseArrivalList: [], purchaseProductList: [], purchaseProjectList: [], }, }); const submit = ref(null); const deliveryType = ref([ { label: "买方地址", value: 1, }, { label: "工厂交付", value: 2, }, { label: "其他", value: 3, }, ]); const productType = ref([ { label: "产品", value: 1, }, { label: "物料", value: 2, }, ]); const judgeStatus = () => { if (route.query.processType == 20 || route.query.processType == 10) { return true; } if (props.queryData.recordList && props.queryData.recordList.length > 0) { let data = props.queryData.recordList.filter( (item) => item.status === 2 && item.nodeType !== 1 ); if (data && data.length > 0) { return true; } } return false; }; const formOption = reactive({ inline: true, labelWidth: 100, itemWidth: 100, rules: [], disabled: false, }); const formConfig = computed(() => { return [ { type: "slot", slotName: "buyer", label: "买方信息", itemWidth: 50, }, { type: "slot", slotName: "seller", label: "卖方信息", itemWidth: 50, }, { type: "slot", slotName: "payment", label: "付款信息", }, { type: "slot", slotName: "delivery", label: "交付信息", }, { type: "slot", slotName: "commodity", label: "采购明细", }, { type: "slot", slotName: "otherCharge", label: "其他收费项目", }, { type: "slot", slotName: "offerMoney", }, { type: "slot", slotName: "contractClause", label: "合同条款", }, { type: "slot", slotName: "shipment", label: "到货要求", }, ]; }); const rules = ref({ buyCorporationId: [ { required: true, message: "请选择买方公司", trigger: "change" }, ], sellCorporationId: [ { required: true, message: "请选择卖方公司", trigger: "change" }, ], countryId: [{ required: true, message: "请选择国家", trigger: "change" }], sellAddress: [{ required: true, message: "请输入详细地址", trigger: "blur" }], buyAddress: [{ required: true, message: "请输入详细地址", trigger: "blur" }], sellContactName: [ { required: true, message: "请输入联系人", trigger: "blur" }, ], sellContactNumber: [ { required: true, message: "请输入联系电话", trigger: "blur" }, ], quantity: [{ required: true, message: "请输入数量", trigger: "blur" }], price: [{ required: true, message: "请输入单价", trigger: "blur" }], amount: [{ required: true, message: "请输入金额", trigger: "blur" }], payName: [ { required: true, message: "请输入收费项目", trigger: ["change", "blur"] }, ], warranty: [{ required: true, message: "请输入质保期", trigger: "blur" }], deliveryType: [ { required: true, message: "请选择交货类型", trigger: "change" }, ], address: [{ required: true, message: "请输入详细地址", trigger: "blur" }], deliveryTime: [ { required: true, message: "请选择交付日期", trigger: "change" }, ], paymentMethod: [ { required: true, message: "请选择付款方式", trigger: "change" }, ], invoiceType: [ { required: true, message: "请选择发票类型", trigger: "change" }, ], contractTemplateId: [ { required: true, message: "请选择合同模板", trigger: "change" }, ], remark: [{ required: true, message: "请输入条款内容", trigger: "change" }], }); const getDict = () => { proxy.getDictOne(["invoice_type", "funds_payment_method"]).then((res) => { invoiceType.value = res["invoice_type"].map((x) => ({ label: x.dictValue, value: x.dictKey, })); fundsPaymentMethod.value = res["funds_payment_method"].map((x) => ({ label: x.dictValue, value: x.dictKey, })); }); proxy .post("/contractTemplate/page", { pageNum: 1, pageSize: 999 }) .then((res) => { templateList.value = res.rows.map((item) => { return { ...item, label: item.templateName, value: item.id, }; }); }); proxy.post("/corporation/page", { pageNum: 1, pageSize: 999 }).then((res) => { corporationList.value = res.rows.map((item) => { return { ...item, label: item.name, value: item.id, }; }); }); proxy.post("/supplierInfo/page", { pageNum: 1, pageSize: 50 }).then((res) => { supplierList.value = res.rows.map((item) => { return { ...item, label: item.name, value: item.id, }; }); }); }; getDict(); const getCityData = (id, type, isChange) => { return proxy.post("/customizeArea/list", { parentId: id }).then((res) => { if (type === "20") { provinceData.value = res; if (isChange) { formData.data.provinceId = ""; formData.data.provinceName = ""; formData.data.cityId = ""; formData.data.cityName = ""; } } else if (type === "30") { cityData.value = res; if (isChange) { formData.data.cityId = ""; formData.data.cityName = ""; } } else { countryData.value = res; } }); }; getCityData("0"); const changeBuyCorporation = (val) => { formData.data.buyCountryName = ""; formData.data.buyProvinceName = ""; formData.data.buyCityName = ""; formData.data.buyAddress = ""; if (val) { proxy.post("/corporation/detail", { id: val }).then((res) => { formData.data.buyAddress = res.address; Promise.all([ getBuyCountryName(res.countryId), getBuyProvinceName(res.provinceId, res.countryId), getBuyCityName(res.cityId, res.provinceId), ]).then(() => { changeAddress(); }); }); } }; const changeAddress = () => { if (formData.data.deliveryType === 1) { let buyCountryName = ""; if (formData.data.buyCountryName) { buyCountryName = formData.data.buyCountryName; } let buyProvinceName = ""; if (formData.data.buyProvinceName) { buyProvinceName = formData.data.buyProvinceName; } let buyCityName = ""; if (formData.data.buyCityName) { buyCityName = formData.data.buyCityName; } let buyAddress = ""; if (formData.data.buyAddress) { buyAddress = formData.data.buyAddress; } formData.data.address = buyCountryName + ", " + buyProvinceName + ", " + buyCityName + "," + buyAddress; } else if (formData.data.deliveryType === 2) { let countryName = ""; if (formData.data.countryId) { let data = countryData.value.filter( (item) => item.id === formData.data.countryId ); if (data && data.length > 0) countryName = data[0].chineseName; } let provinceName = ""; if (formData.data.provinceId) { let data = provinceData.value.filter( (item) => item.id === formData.data.provinceId ); if (data && data.length > 0) provinceName = data[0].name; } else { if (formData.data.provinceName) { provinceName = formData.data.provinceName; } } let cityName = ""; if (formData.data.cityId) { let data = cityData.value.filter( (item) => item.id === formData.data.cityId ); if (data && data.length > 0) cityName = data[0].name; } else { if (formData.data.cityName) { cityName = formData.data.cityName; } } let sellAddress = ""; if (formData.data.sellAddress) { sellAddress = formData.data.sellAddress; } formData.data.address = countryName + ", " + provinceName + ", " + cityName + "," + sellAddress; } else if (formData.data.deliveryType === 3) { formData.data.address = ""; } }; const changeSellAddress = (val, index) => { Promise.all([getCityData(val, index, true)]).then(() => { changeAddress(); }); }; const getBuyCountryName = (val) => { return proxy .post("/customizeArea/list", { parentId: "0" }) .then((resCountry) => { let buyCountryData = resCountry.filter((item) => item.id === val); if (buyCountryData && buyCountryData.length > 0) { formData.data.buyCountryName = buyCountryData[0].chineseName; } else { formData.data.buyCountryName = ""; } }); }; const getBuyProvinceName = (val, countryId) => { if (val) { return proxy .post("/customizeArea/list", { parentId: countryId }) .then((resProvince) => { let buyProvinceData = resProvince.filter((item) => item.id === val); if (buyProvinceData && buyProvinceData.length > 0) { formData.data.buyProvinceName = buyProvinceData[0].name; } else { formData.data.buyProvinceName = ""; } }); } else { formData.data.buyProvinceName = ""; return; } }; const getBuyCityName = (val, provinceId) => { if (val) { return proxy .post("/customizeArea/list", { parentId: provinceId }) .then((resCity) => { let buyCityData = resCity.filter((item) => item.id === val); if (buyCityData && buyCityData.length > 0) { formData.data.buyCityName = buyCityData[0].name; } else { formData.data.buyCityName = ""; } }); } else { formData.data.buyCityName = ""; return; } }; const changeSupplier = (val) => { formData.data.countryId = ""; formData.data.provinceId = ""; formData.data.cityId = ""; formData.data.sellPostalCode = ""; formData.data.sellAddress = ""; formData.data.sellContactName = ""; formData.data.sellContactNumber = ""; if (val) { let data = supplierList.value.filter((item) => item.id === val); if (data && data.length > 0) { formData.data.countryId = data[0].countryId; formData.data.provinceId = data[0].provinceId; formData.data.cityId = data[0].cityId; formData.data.sellAddress = data[0].areaDetail; formData.data.sellContactName = data[0].contactPerson; formData.data.sellContactNumber = data[0].contactNumber; if (formData.data.provinceId) { Promise.all([ getCityData(formData.data.countryId, "20"), getCityData(formData.data.provinceId, "30"), ]).then(() => { changeAddress(); }); } else { Promise.all([getCityData(formData.data.countryId, "20")]).then(() => { changeAddress(); }); } } const ids = formData.data.purchaseProductList.map((x) => x.productId); getAuxiliaryData(val, ids); } }; const onPicture = (path) => { window.open(path, "_blank"); }; const changeProject = () => { nextTick(() => { calculationAllAmount(); }); }; const calculationAllAmount = () => { let amount = 0; if ( formData.data.purchaseProductList && formData.data.purchaseProductList.length > 0 ) { for (let i = 0; i < formData.data.purchaseProductList.length; i++) { if (formData.data.purchaseProductList[i].amount) { amount = Number( parseFloat( Number(amount) + Number(formData.data.purchaseProductList[i].amount) ).toFixed(2) ); } } } if ( formData.data.purchaseProjectList && formData.data.purchaseProjectList.length > 0 ) { for (let i = 0; i < formData.data.purchaseProjectList.length; i++) { if (formData.data.purchaseProjectList[i].amount) { amount = Number( parseFloat( Number(amount) + Number(formData.data.purchaseProjectList[i].amount) ).toFixed(2) ); } } } formData.data.amount = amount; }; const calculationProductAmount = (index) => { if ( formData.data.purchaseProductList && formData.data.purchaseProductList.length > 0 && formData.data.purchaseProductList[index].purchaseProductMountingsList && formData.data.purchaseProductList[index].purchaseProductMountingsList .length > 0 ) { let amount = 0; for ( let i = 0; i < formData.data.purchaseProductList[index].purchaseProductMountingsList .length; i++ ) { if ( formData.data.purchaseProductList[index].purchaseProductMountingsList[i] .amount ) { amount = Number( parseFloat( Number(amount) + Number( formData.data.purchaseProductList[index] .purchaseProductMountingsList[i].amount ) ).toFixed(2) ); } } formData.data.purchaseProductList[index].amount = amount; let price = 0; if (formData.data.purchaseProductList[index].quantity && amount) { price = Number( parseFloat( Number(amount) / Number(formData.data.purchaseProductList[index].quantity) ).toFixed(4) ); } formData.data.purchaseProductList[index].price = price; } nextTick(() => { calculationAllAmount(); }); }; const changeProductMaterial = (index, indexTwo) => { nextTick(() => { if ( formData.data.purchaseProductList && formData.data.purchaseProductList.length > 0 && formData.data.purchaseProductList[index].purchaseProductMountingsList && formData.data.purchaseProductList[index].purchaseProductMountingsList .length > 0 ) { if ( indexTwo === 0 && formData.data.purchaseProductList[index].purchaseProductMountingsList[ indexTwo ].quantity ) { formData.data.purchaseProductList[index].quantity = formData.data.purchaseProductList[index].purchaseProductMountingsList[ indexTwo ].quantity; } if ( formData.data.purchaseProductList[index].purchaseProductMountingsList[ indexTwo ].quantity && formData.data.purchaseProductList[index].purchaseProductMountingsList[ indexTwo ].price ) { formData.data.purchaseProductList[index].purchaseProductMountingsList[ indexTwo ].amount = Number( parseFloat( Number( formData.data.purchaseProductList[index] .purchaseProductMountingsList[indexTwo].quantity ) * Number( formData.data.purchaseProductList[index] .purchaseProductMountingsList[indexTwo].price ) ).toFixed(2) ); } else { formData.data.purchaseProductList[index].purchaseProductMountingsList[ indexTwo ].amount = 0; } } nextTick(() => { calculationProductAmount(index); }); }); }; const handleRemove = async (index, indexTwo) => { await formData.data.purchaseProductList[ index ].purchaseProductMountingsList.splice(indexTwo, 1); nextTick(() => { calculationProductAmount(index); }); }; const clickAdd = () => { if ( formData.data.purchaseProjectList && formData.data.purchaseProjectList.length > 0 ) { formData.data.purchaseProjectList.push({ payName: "", amount: undefined, remark: "", }); } else { formData.data.purchaseProjectList = [ { payName: "", amount: undefined, remark: "" }, ]; } }; const handleDelete = async (index) => { await formData.data.purchaseProjectList.splice(index, 1); nextTick(() => { calculationAllAmount(); }); }; const querySearch = (queryString, callback) => { proxy.post("/quotationPay/page", { payName: queryString }).then((res) => { if (res.rows && res.rows.length > 0) { res.rows = res.rows.map((item) => { return { ...item, value: item.payName, }; }); callback(res.rows); } else { callback([]); } }); }; const handleSubmit = async () => { let status = await submit.value.handleSubmit(() => {}); if (status) { if ( formData.data.purchaseArrivalList && formData.data.purchaseArrivalList.length > 0 ) { for (let i = 0; i < formData.data.purchaseProductList.length; i++) { let data = formData.data.purchaseArrivalList.filter( (item) => item.productId === formData.data.purchaseProductList[i].productId ); if (data && data.length > 0) { let quantity = 0; for (let j = 0; j < data.length; j++) { quantity = parseFloat(Number(quantity) + Number(data[j].quantity)); } if (quantity > formData.data.purchaseProductList[i].quantity) { ElMessage("到货数量不能大于采购数量"); return false; } } } } return true; } else { setTimeout(() => { const errorDiv = document.getElementsByClassName("is-error"); errorDiv[0].scrollIntoView(); }, 0); } return status; }; // 接收父组件的传值 const props = defineProps({ queryData: Object, }); watch( props.queryData, () => { formOption.disabled = judgeStatus(); return; if ( props.queryData && ["10", "20", "30"].includes(route.query.processType) ) { for (var text in props.queryData) { formData.data[text] = props.queryData[text]; } if (formData.data.countryId) { getCityData(formData.data.countryId, "20"); } if (formData.data.provinceId) { getCityData(formData.data.provinceId, "30"); } const ids = formData.data.purchaseProductList.map((x) => x.productId); if (formData.data.sellCorporationId && ids.length > 0) { getAuxiliaryData(formData.data.sellCorporationId, ids); } } }, { deep: true, } ); const getFormData = () => { return proxy.deepClone(formData.data); }; // 向父组件暴露 defineExpose({ getFormData, handleSubmit, }); onMounted(() => { if (props.queryData.ids) { proxy.post("/delivery/page", { ids: props.queryData.ids }).then((res) => { formData.data.dataResource = props.queryData.type; if (res.rows && res.rows.length > 0) { formData.data.purchaseProductList = res.rows.map((item) => { return { productId: item.productId, contractId: item.contractId, productName: item.productName, productModel: item.productModel, quantity: item.expendQuantity, price: "", amount: "", remark: "", json: "", fileUrl: "", dataResource: props.queryData.type, dataResourceId: item.id, purchaseProductMountingsList: [ { productId: item.productId, productType: 1, productName: item.productName, productModel: item.productModel, quantity: item.expendQuantity, price: undefined, amount: "", remark: "", json: "", fileUrl: "", activeName: false, }, ], fileList: [], }; }); formData.data.purchaseArrivalList = res.rows.map((item) => { return { productCode: item.productCode, productId: item.productId, productName: item.productName, arrivalTime: "", quantity: undefined, }; }); let fileIds = formData.data.purchaseProductList.map( (item) => item.productId ); proxy .post("/fileInfo/getList", { businessIdList: fileIds }) .then((resFile) => { for (let i = 0; i < formData.data.purchaseProductList.length; i++) { if ( resFile[formData.data.purchaseProductList[i].productId] && resFile[formData.data.purchaseProductList[i].productId].length > 0 ) { formData.data.purchaseProductList[i].fileUrl = resFile[ formData.data.purchaseProductList[i].productId ][0].fileUrl; formData.data.purchaseProductList[ i ].purchaseProductMountingsList[0].fileUrl = resFile[ formData.data.purchaseProductList[i].productId ][0].fileUrl; } } }); } else { formData.data.purchaseProductList = []; } }); } formOption.disabled = judgeStatus(); if (route.query && route.query.processType) { let businessId = route.query.businessId; proxy.post("/ehsdPurchase/detail", { id: businessId }).then((res) => { res.purchaseProductList = res.ehsdPurchaseProductList || []; if (!res.fileList) { res.fileList = []; } res.countryId = res.sellCountryId; res.provinceId = res.sellProvinceId; res.cityId = res.sellCityId; for (const key in res) { formData.data[key] = res[key]; } proxy .post("/fileInfo/getList", { businessIdList: [businessId], }) .then((fileObj) => { if (fileObj[businessId]) { formData.data.fileList = fileObj[businessId] .filter((x) => x.businessType === "1") .map((x) => ({ raw: x, name: x.fileName, url: x.fileUrl })); formData.data.packageFileList = fileObj[businessId] .filter((x) => x.businessType === "2") .map((x) => ({ raw: x, name: x.fileName, url: x.fileUrl })); } }); if ( formData.data.purchaseProductList && formData.data.purchaseProductList.length > 0 ) { let ids = formData.data.purchaseProductList.map((x) => x.productId); proxy .post("/fileInfo/getList", { businessIdList: ids, }) .then((fileObj) => { for (let i = 0; i < formData.data.purchaseProductList.length; i++) { const e = formData.data.purchaseProductList[i]; for (const key in fileObj) { if (e.productId === key) { e.fileList = fileObj[key] || []; if (e.fileList && e.fileList.length > 0) { e.fileUrl = e.fileList[0].fileUrl; } } } } }); } if (formData.data.countryId) { getCityData(formData.data.countryId, "20"); } if (formData.data.provinceId) { getCityData(formData.data.provinceId, "30"); } }); } }); const clickSplit = (item) => { formData.data.purchaseArrivalList.push({ productCode: item.code, productId: item.productId, productName: item.productName, arrivalTime: "", remark: "", quantity: undefined, }); }; const clickDelete = (index) => { formData.data.purchaseArrivalList.splice(index, 1); }; const updateContent = (val) => { formData.data.remark = val; }; const remarkEditor = ref(null); const changeContractTemplate = (val) => { if (val) { proxy.post("/contractTemplate/detail", { id: val }).then((res) => { remarkEditor.value.changeHtml(res.templateContent); }); } }; const productRow = reactive({ data: { productName: "", remark: "", }, }); const productIndex = ref(0); const openHandover = ref(false); const fileList = ref([]); const uploadData = ref({}); const formHandoverConfig = computed(() => { return [ { type: "title", title: "产品信息", label: "", }, { type: "input", prop: "productName", label: "产品名称", itemType: "text", disabled: true, }, { type: "input", prop: "productModel", label: "规格型号", itemType: "text", disabled: true, }, { type: "slot", prop: "file", slotName: "file", label: "上传附件", }, { type: "slot", slotName: "remark", label: "备注", }, ]; }); const handleHandover = (row, index) => { productRow.data = { productName: row.productName, remark: row.remark, }; if (row.fileList && row.fileList.length > 0) { fileList.value = row.fileList.map((item) => { return { raw: item, name: item.fileName, url: item.fileUrl, }; }); } else { fileList.value = []; } productIndex.value = index; openHandover.value = true; }; const handleMaterial = (index) => { productIndex.value = index; openMaterialCompany.value = true; }; const uploadFile = async (file) => { const res = await proxy.post("/fileInfo/getSing", { fileName: file.name }); uploadData.value = res.uploadBody; file.id = res.id; file.fileName = res.fileName; file.fileUrl = res.fileUrl; file.uploadState = true; return true; }; const handleSuccess = (any, UploadFile) => { UploadFile.raw.uploadState = false; }; const onPreviewFile = (file) => { window.open(file.raw.fileUrl, "_blank"); }; const updateHandover = (val) => { productRow.data.remark = val; }; const submitHandoverForm = () => { if (fileList.value && fileList.value.length > 0) { for (let i = 0; i < fileList.value.length; i++) { if (fileList.value[i].raw.uploadState) { ElMessage("文件上传中,请稍后提交"); return; } } formData.data.purchaseProductList[productIndex.value].fileList = fileList.value.map((item) => { return { id: item.raw.id, fileName: item.raw.fileName, fileUrl: item.raw.fileUrl, uploadState: item.raw.uploadState, }; }); } else { formData.data.purchaseProductList[productIndex.value].fileList = []; } formData.data.purchaseProductList[productIndex.value].remark = productRow.data.remark; openHandover.value = false; }; const selectMaterial = (goods) => { if (goods && goods.id) { let data = formData.data.purchaseProductList[ productIndex.value ].purchaseProductMountingsList.filter( (item) => item.productId === goods.id ); if (data && data.length > 0) { return ElMessage("该物料已添加"); } let fileUrl = ""; if (goods.fileList && goods.fileList.length > 0) { fileUrl = goods.fileList[0].fileUrl; } formData.data.purchaseProductList[ productIndex.value ].purchaseProductMountingsList.push({ productId: goods.id, productType: 2, productName: goods.name, productModel: goods.spec, quantity: undefined, price: undefined, amount: "", remark: "", json: "", fileUrl: fileUrl, activeName: false, }); ElMessage({ message: "添加成功!", type: "success", }); } else { return ElMessage("选择错误"); } }; const getStyle = (text) => { if (text) { return text.replace(/\n|\r\n/g, "<br>"); } else { return ""; } }; const emit = defineEmits(["auxiliaryChange"]); let auxiliaryData = ref([ { label: "供应商最近采购", data: [], }, { label: "产品价格", data: [], }, ]); const auxiliaryChange = (data) => { emit("auxiliaryChange", data); }; const getAuxiliaryData = (supplyId, productIdList) => { if (supplyId && productIdList.length > 0) { proxy .post("/subscribe/decisionAid", { supplyId: supplyId, productIdList: productIdList, }) .then((res) => { // 获取数组长度 let dataLength = auxiliaryData.value.length; // 供应商最近采购 const recentlyArr = [ { label: "合同编号", value: "", fn: () => {}, num: 1, }, { label: "下单日期", value: "", num: 1, }, { label: "合同金额", value: "", num: 1, }, ]; auxiliaryData.value[dataLength - 2].data = res.purchaseList.map( (x, index) => { return recentlyArr.map((y, sonIndex) => { let obj = { ...y }; let value = ""; if (sonIndex === 0) { value = x.code; } else if (sonIndex === 1) { value = x.createTime; } else { value = x.currency + " " + proxy.moneyFormat(x.amount, 2); } obj.value = value; return obj; }); } ); // 产品价格 const arrConfig = [ { label: "产品名称", value: "", num: 1, }, { label: "最近价格", value: "", num: 1, }, { label: "历史最高", value: "", num: 1, }, { label: "历史最低", value: "", num: 1, }, ]; auxiliaryData.value[dataLength - 1].data = res.productPriceList.map( (x, index) => { return arrConfig.map((y, sonIndex) => { let obj = { ...y }; let value = ""; if (sonIndex === 0) { value = x.name; } else if (sonIndex === 1) { value = x.lastPrice; } else if (sonIndex === 2) { value = x.maxPrice; } else { value = x.minPrice; } obj.value = value; return obj; }); } ); auxiliaryChange(auxiliaryData.value); }); } else { if (props.queryData.type === "handoverSlip" && props.queryData.arr) { let arrConfig = [ { label: "合同编号", value: "", fn: () => {}, num: 1, }, { label: "下单日期", value: "", num: 1, }, ]; auxiliaryData.value[0].data = contractData.value.map((x, index) => { return arrConfig.map((y, sonIndex) => { let obj = { ...y }; let value = ""; if (sonIndex === 0) { value = contractData.value[index].contractCode; } else if (sonIndex === 1) { value = contractData.value[index].claimTime; } obj.value = value; return obj; }); }); auxiliaryChange(auxiliaryData.value); } } }; const getHtmlVal = (val) => { if (val) { return val.replace(/<p>/g, "<div>").replace(/<\/p>/g, "</div>"); } return ""; }; const loadingSearch = ref(false); const remoteMethod = (keyword) => { if (keyword && typeof keyword === "string") { loadingSearch.value = true; proxy.post("/supplierInfo/page", { keyword }).then((res) => { supplierList.value = res.rows.map((item) => { return { ...item, label: item.name, value: item.id, }; }); loadingSearch.value = false; }); } return; }; const objectSpanMethod = (rowIndex, columnIndex, item) => { if (columnIndex === 3) { if (rowIndex === 0) { return { rowspan: item.purchaseProductMountingsList.length, colspan: 1, }; } else { return { rowspan: 0, colspan: 1, }; } } }; const getTotalAmount = () => { const total = formData.data.purchaseProjectList.reduce( (val, x) => (val += Number(x.amount)), 0 ); if (total) { return parseFloat(formData.data.amount - total).toFixed(2); } else { if (formData.data.amount) { return parseFloat(formData.data.amount).toFixed(2); } } }; </script> <style lang="scss" scoped> ::v-deep(.el-input-number .el-input__inner) { text-align: left; } .pic { object-fit: contain; width: 50px; height: 50px; cursor: pointer; vertical-align: middle; } .shrinkPadding { padding-right: 0 !important; } .hideCollapse { margin-top: -28px; border: 0 !important; } ::v-deep(.el-collapse-item__arrow) { display: none !important; } ::v-deep(.el-collapse-item__wrap) { border: 0 !important; } ::v-deep(.el-collapse-item__header) { border: 0 !important; } ::v-deep(.el-collapse-item__content) { padding-bottom: 8px !important; } .pic { object-fit: contain; width: 50px; height: 50px; cursor: pointer; vertical-align: middle; } ::v-deep(.removePadding) { .el-form-item { padding-right: 0 !important; } } </style>