<template> <div> <div v-if="loading" v-loading="true" class="view-window" element-loading-text="Loading..." element-loading-background="rgba(0, 0, 0, 0.3)" ></div> <div class="flex fixed-button-area"> <!-- <el-button @click="() => generatePDF()">generatePDF</el-button> --> <el-button type="info" @click="formVisible = !formVisible" > <el-icon size="18px" color="#fff" > <Switch /> </el-icon> {{ formVisible ? 'Preview PDF' : 'Show Form' }} </el-button> <el-button type="primary" :disabled="!formVisible" @click="checkForm(mainForm)" > <el-icon size="20px" color="#fff" > <FolderAdd /> </el-icon> Save & Attach </el-button> </div> <div v-show="formVisible" class="screen" > <div class="flex justify-between page-title-wrap"> <div class="flex"> <el-icon size="36px" :color="variables.mainColor" > <ShoppingCart /> </el-icon> <div class="page-title">New Purchase Order</div> </div> </div> <el-form ref="mainForm" :model="form" :rules="formRule" label-width="120px" > <div class="flex items-start"> <div class="layout-left"> <el-form-item prop="Order_Type" label="Order Type" label-width="130px" > <el-radio-group v-model="form.Order_Type"> <el-radio v-for="(item, index) in orderTypeList" :key="index" :label="item.label" :value="item.label" > {{ item.label }} </el-radio> </el-radio-group> </el-form-item> <el-form-item label="Artwork Link" prop="Artwork_Link" label-width="130px" > <el-input v-model="form.Artwork_Link" placeholder="Please input" type="textarea" :rows="3" ></el-input> </el-form-item> <el-form-item label="Currency" label-width="130px" > <el-select v-model="form.Currency" style="width: 100%" placeholder="please select currency" > <el-option v-for="(item, index) in currencyList" :key="index" :label="item.label" :value="item.label" /> </el-select> </el-form-item> <el-form-item v-if="recommandVendor.length" label="Suggest Supplier" label-width="130px" > <div class="flex flex-col items-start"> <div v-for="(item, index) in recommandVendor" :key="index" class="btn-quick-vendor" :class="{ active: item.id === form.currentVendor }" @click="quickSelectSupplier(item)" > {{ item.name || '' }} </div> </div> </el-form-item> </div> <div class="layout-right flex-auto"> <div style="position: absolute; right: 24px; top: 0"> <el-form-item label="Template:"> <el-select v-model="currentCompany" style="width: 150px" @change="onCompanyTemplateChange" > <el-option v-for="company in computedCompanyList" :key="company.id" :value="company.id" :label="company.label" ></el-option> </el-select> </el-form-item> </div> <div class="company-info"> <div class="company-name">{{ computedCompany.name }}</div> <div class="flex justify-center"> <div class="company-addr"> 地址: {{ computedCompany.addr }} </div> <div class="company-phone"> | 电话: {{ computedCompany.phone }} </div> <div v-show="computedCompany.fax" class="company-fax" > | 传真: {{ computedCompany.fax }} </div> </div> </div> <div class="pdf-title">采购合同</div> <div class="pdf-title-bg"> <div class="left"></div> <div class="right"></div> </div> <div class="flex items-start justify-between form-area"> <div class="form-area-left"> <div class=""> <span style="color: #f56c6c">*</span> 供应商(乙方) : </div> <div>{{ computedVendor.Primary_Contact_name }}</div> <el-form-item label-width="0" prop="currentVendor" > <el-select v-model="form.currentVendor" :remote-method="utils.debounce(getSupplierLists, 1000)" remote style="width: 100%" :loading="vendorLoading" filterable clearable > <el-option v-for="option in vendorList" :key="option.value" :value="option.value" :label="option.label" ></el-option> </el-select> </el-form-item> <div v-if="typeof computedCompany.taxReimbursement === 'undefined'" style="white-space: pre-wrap" > {{ computedVendor.PDF_display }} </div> <div v-else style="white-space: pre-wrap" > {{ computedVendor.PDF_display2 }} </div> </div> <div class="form-area-right"> <el-form-item label="采购订单 #:"> Generate once PO submitted </el-form-item> <el-form-item label="订单号 # :"> <el-input v-model="form.Reference" disabled ></el-input> </el-form-item> <el-form-item label="日期:" prop="PO_Date" > <el-date-picker v-model="form.PO_Date" format="YYYY-MM-DD" value-format="YYYY-MM-DD" style="width: 100%" type="date" ></el-date-picker> </el-form-item> <el-form-item label="付款方式 :"> <el-select v-model="form.Supplier_Payment_Terms" style="width: 100%" > <el-option v-for="(item, index) in supplierPaymentTermsLists" :key="index" :value="item.label" :label="item.label" ></el-option> </el-select> </el-form-item> <el-form-item label="参考 :"> <el-input v-model="form.Title"></el-input> </el-form-item> <!-- 退税版没有这几项 --> <template v-if="typeof computedCompany.taxReimbursement === 'undefined'" > <el-form-item label="收货详情 :"> <el-select v-model="form.field9" style="width: 100%" > <el-option v-for="(item, index) in addressList" :key="index" :value="item.label" :label="item.label" ></el-option> </el-select> </el-form-item> <el-form-item label="收件人 :" prop="field7" > <el-input v-model="form.field7"></el-input> </el-form-item> <el-form-item label="联系电话 :" prop="field8" > <el-input v-model="form.field8"></el-input> </el-form-item> </template> <el-form-item label="工厂交货日期 :" prop="field6" > <el-date-picker v-model="form.field6" style="width: 100%" format="YYYY-MM-DD" value-format="YYYY-MM-DD" ></el-date-picker> </el-form-item> <el-form-item label="送货备注 :"> <el-input v-model="form.Delivery_Details"></el-input> </el-form-item> </div> </div> <div class="product-table-separator"></div> <div class="product-table"> <table border="0" cellspacing="0" > <tr> <th class="product">品名</th> <th class="quantity">数量</th> <th class="rate">价格 ({{ currentCurrency.label }})</th> <th class="requirement">中文品目|要求</th> <th class="amount">金额</th> <th class="discount">折扣</th> <th class="warehouse">Warehouse</th> <th class="action">操作</th> </tr> <tr v-for="(product, index) in form.productList" :key="index" > <td class="product"> <el-form-item label-width="0" :prop="'productList.' + index + '.id'" :rules="{ required: true, message: '必填项', trigger: ['blur', 'change'], }" > <el-select-v2 v-model="product.id" popper-class="product-select" style="width: 100%; margin-bottom: 4pt" :options="product.candidate" :loading="productLoading" :remote-method=" (e: string) => getProductList(e, product) " remote filterable clearable @change="(e) => onProductSelect(e, product)" ></el-select-v2> </el-form-item> <el-input v-if="userInfo.Organization !== 'PrimePac'" v-model="product.desc" type="textarea" placeholder="Free text" ></el-input> </td> <td class="quantity"> <el-form-item label-width="0" :prop="'productList.' + index + '.quantity'" :rules="{ required: true, message: '必填项', trigger: ['blur', 'change'], }" > <el-input v-model="product.quantity" type="number" min="1" @change="(e) => onInputChange(e, product, 'quantity')" ></el-input> </el-form-item> </td> <td class="rate"> <el-form-item label-width="0" :prop="'productList.' + index + '.rate'" :rules="{ required: true, message: '必填项', trigger: ['blur', 'change'], }" > <el-input v-model="product.rate" type="number" @change="(e) => onInputChange(e, product, 'rate')" ></el-input> </el-form-item> </td> <td class="requirement"> <el-input v-model="product.requirement" :rows="userInfo.Organization !== 'PrimePac' ? 4 : 5" type="textarea" placeholder="Free text" ></el-input> </td> <td class="amount"> <el-input v-model="product.amount" type="number" disabled ></el-input> </td> <td class="discount"> <el-input v-model="product.discount" type="number" @change="(e) => onInputChange(e, product, 'discount')" ></el-input> </td> <td class=""> <el-form-item label-width="0" :prop="'productList.' + index + '.Warehouse'" :rules="{ required: product.CF_Product_Type === 'Stock', message: '必填项', trigger: ['blur', 'change'], }" > <el-select v-model="product.Warehouse" clearable > <el-option v-for="v in warehouseList" :key="v" :label="v" :value="v" ></el-option> </el-select> </el-form-item> </td> <td class="action"> <el-button size="small" type="danger" plain @click="form.productList.splice(index, 1)" > Delete </el-button> </td> </tr> </table> </div> <div> <el-button type="primary" size="small" plain @click="addRow" > Add Row </el-button> </div> <div class="flex justify-end"> <div class="product-total-table"> <div class="total-item"> <div class="label">Sub Total</div> <div class="value">{{ toFixed(subTotal, 2) }}</div> </div> <div class="total-item"> <div class="label">Total Discount</div> <div class="value"> {{ toFixed(totalDiscount, 2) }} </div> </div> <div class="total-item"> <div class="label">Adjustment</div> <div class="value"> <el-input v-model="adjustment" style="width: 100%" type="number" ></el-input> </div> </div> <div class="total-item"> <div class="label">Grand Total</div> <div class="value"> {{ toFixed(grandTotal, 2) }} </div> </div> </div> </div> <div v-if="userInfo.Organization !== 'PrimePac'" class="note-form-area" > <div class="sub-form-title">注意事项:</div> <el-form-item label="印刷质量:"> <el-input v-model="form.field12" type="textarea" :rows="3" ></el-input> </el-form-item> <el-form-item label="产品质量:"> <el-input v-model="form.field13" type="textarea" :rows="3" ></el-input> </el-form-item> <el-form-item label="质量承诺:"> <el-input v-model="form.field10" type="textarea" :rows="3" ></el-input> </el-form-item> <el-form-item label="箱子箱唛:"> <el-input v-model="form.field11" type="textarea" :rows="3" ></el-input> </el-form-item> </div> <div class="sub-form-title">服务条款</div> <template v-if="currentCompany === 'PangeaTaxReimbursement'"> <div class="rule-item flex"> 一、合同价为含税价,税率为: <span style="color: #f56c6c">*</span> <el-form-item label-width="10" prop="field4" :rules="{ required: true, message: '必填项', trigger: ['blur', 'change'], }" > <el-input v-model="form.field4" size="small" style="width: 120px" > <template #append>%</template> </el-input> </el-form-item> </div> <div class="rule-item flex"> 二、运费条款: <span style="color: #f56c6c">*</span> <el-form-item label-width="10"> <el-select v-model="form.field5" size="small" style="width: 110px" > <el-option v-for="(item, index) in field5_lists" :key="index" :label="item.label" :value="item.label" ></el-option> </el-select> </el-form-item> </div> </template> <template v-if="['PrimePacCommon', 'PrimePacSoft'].includes(currentCompany)" > <div class="rule-item"> 一、本采购订单签署原件一式两份,双方各持一份。经双方代表签字或盖章即可生效,并具有同等法律效力。 </div> <div class="rule-item flex nowrap"> 二、以上价格已含所有产品的制作费、包装费;由 <div class="attention flex nowrap"> <span style="color: #f56c6c">*</span> <el-form-item label-width="10"> <el-select v-model="form.field5" size="small" style="width: 110px" > <el-option v-for="(item, index) in field5_lists" :key="index" :label="item.label" :value="item.label" ></el-option> </el-select> </el-form-item> </div> 运费送货到广州甲方指定的卸货地点,不含税,运费届时实报实销。 </div> <div class="rule-item"> 三、印刷及工艺要求:乙方需按照甲方图稿或指定样品进行生产,颜色对照潘通色卡或指定样品。 </div> <div class="rule-item"> 四、付款形式: <span class="attention">{{ form.Supplier_Payment_Terms }}</span> 。甲方在乙方完成大货时,先寄大货样品给乙方确认,确认后付清剩余尾款。甲方通过银行转帐的方式付款,乙方账户信息如上。 </div> <div class="rule-item"> 五、出货标准:五层出口空白硬纸箱,箱内套防潮袋。如实际出货包装与合约要求不符,甲方有权拒收整批货物。 </div> <div class="rule-item"> 六、订货时间:自合同成立,甲方支付定金并确认图稿后算起。 </div> <div class="rule-item"> 七、交货期限:自确认图稿时间算起,乙方应于 <span class="attention">{{ form.field6 }}</span> 前生产好产品,甲方确认并支付剩余款项后,乙方在约定时间内安排发出剩余产品到甲方收货地址。 </div> </template> <div v-for="(item, index) in currentServiceRule" :key="index" class="rule-item" :class="[{ sub: typeof item === 'object' }]" v-html="typeof item === 'object' ? item.value : item" ></div> <template v-if="['PrimePacCommon', 'PrimePacSoft'].includes(currentCompany)" > <div class="sub-form-title">附录</div> <div v-for="(item, index) in appendixData" :key="index" class="rule-item" :class="[{ sub: typeof item === 'object' }]" v-html="typeof item === 'object' ? item.value : item" ></div> </template> <div v-if="currentCompany === 'PrimePacCommon'" class="flex items-stretch PrimePac-table" > <div class="flex flex-col items-stretch"> <div class="column-item flex justify-center">制作要求</div> <div class="flex-auto column-item flex justify-center"> 产品外观要求 </div> </div> <div class="flex-auto flex flex-col items-stretch"> <div v-for="(item, index) in PrimePacCommonRuleTableData" :key="index" class="flex items-stretch flex-auto" > <div class="column-item flex justify-center"> {{ item.project }} </div> <div class="column-item flex-auto flex justify-center"> {{ item.method }} </div> </div> </div> </div> <div v-if="currentCompany === 'PrimePacSoft'" class="flex flex-col items-stretch PrimePac-table" > <div class="flex items-stretch"> <div class="flex flex-col items-stretch"> <div class="column-item flex-auto flex justify-center"> 制作要求 </div> </div> <div class="flex-auto flex flex-col items-stretch"> <div v-for="(item, index) in PrimePacSoftRuleTableData1" :key="index" class="flex items-stretch flex-auto" > <div class="column-item flex justify-center"> {{ item.project }} </div> <div class="column-item flex-auto flex justify-center"> {{ item.method }} </div> </div> </div> </div> <div class="flex items-stretch"> <div class="flex flex-col items-stretch"> <div class="column-item flex-auto flex justify-center"> 产品技术要求 </div> </div> <div class="flex-auto flex flex-col items-stretch"> <div v-for="(item, index) in PrimePacSoftRuleTableData2" :key="index" class="flex items-stretch flex-auto" > <div class="column-item flex justify-center"> {{ item.project }} </div> <div class="column-item flex-auto flex justify-center"> {{ item.method }} </div> </div> </div> </div> </div> </div> </div> </el-form> <br /> </div> <div class="print" :class="{ hidden: formVisible && !loading }" > <div class="pdf-wrap"> <div id="pdfElement" ref="pdfElement" class="preview-area" > <div class="company-info"> <div class="company-name">{{ computedCompany.name }}</div> <div class="flex justify-center"> <div class="company-addr"> 地址: {{ computedCompany.addr }} </div> <div class="company-phone"> | 电话: {{ computedCompany.phone }} </div> <div v-show="computedCompany.fax" class="company-fax" > | 传真: {{ computedCompany.fax }} </div> </div> </div> <div> <table class="pdf-title-bg"> <tr> <td class="left"> <div> </div> </td> <td class="center"> <div class="pdf-title">采购合同</div> </td> <td class="right"> <div> </div> </td> </tr> </table> </div> <div class="form-area flex items-start"> <div class="flex-auto"> <div>供应商(乙方) :</div> <div v-if="computedVendor.Primary_Contact_name" class="column-vendor" > {{ computedVendor.Primary_Contact_name }} </div> <div class="column-vendor"> {{ computedVendor.label }} </div> <div v-if="typeof computedCompany.taxReimbursement === 'undefined'" class="column-vendor" > {{ computedVendor.PDF_display }} </div> <div v-else class="column-vendor" > {{ computedVendor.PDF_display2 }} </div> </div> <div class="flex-auto"> <div class="flex"> <div class="column-form-label">采购订单 #:</div> <div class="column-form-value"> {{ longPONumber || '' }} </div> </div> <div class="flex"> <div class="column-form-label">订单号 # :</div> <div class="column-form-value"> {{ form.Reference }} </div> </div> <div class="flex"> <div class="column-form-label">日期 :</div> <div class="column-form-value"> {{ form.PO_Date }} </div> </div> <div class="flex"> <div class="column-form-label">付款方式 :</div> <div class="column-form-value"> {{ form.Supplier_Payment_Terms !== '-None-' ? form.Supplier_Payment_Terms : '' }} </div> </div> <div class="flex items-start"> <div class="column-form-label">参考 :</div> <div class="column-form-value"> {{ form.Title }} </div> </div> <template v-if="typeof computedCompany.taxReimbursement === 'undefined'" > <div class="flex items-start"> <div class="column-form-label">收货详情 :</div> <div class="column-form-value"> {{ form.field9 }} </div> </div> <div class="flex"> <div class="column-form-label">收件人 :</div> <div class="column-form-value"> {{ form.field7 }} </div> </div> <div class="flex"> <div class="column-form-label">联系电话 :</div> <div class="column-form-value"> {{ form.field8 }} </div> </div> </template> <div class="flex"> <div class="column-form-label">工厂交货日期 :</div> <div class="column-form-value"> {{ form.field6 }} </div> </div> <div class="flex"> <div class="column-form-label">送货备注 :</div> <div class="column-form-value"> {{ form.Delivery_Details }} </div> </div> </div> </div> <div class="product-table-separator"></div> <div class="product-table"> <table border="0" cellspacing="0" > <tr> <th class="row-index">#</th> <th>品名</th> <th v-if="userInfo.Organization !== 'PrimePac'"> 中文品目|要求 </th> <th>数量</th> <th>价格 ({{ currentCurrency.label }})</th> <th>金额</th> </tr> <tr v-for="(product, index) in form.productList" :key="index" > <td class="row-index">{{ index + 1 }}.</td> <td> <div class="product-name">{{ product.name }}</div> <div v-if="userInfo.Organization !== 'PrimePac'" class="desc" > {{ product.desc }} </div> <div v-else class="desc" > {{ product.requirement }} </div> </td> <td v-if="userInfo.Organization !== 'PrimePac'"> {{ product.requirement }} </td> <td> {{ product.quantity }} </td> <td> {{ currentCurrency.country }}{{ currentCurrency.symbol }} {{ toFixed(Number(product.rate), computedDeci) }} </td> <td> {{ currentCurrency.country }}{{ currentCurrency.symbol }} {{ toFixed(Number(product.amount), computedDeci) }} </td> </tr> </table> </div> <!-- <br /> --> <div class="flex justify-between items-start"> <div v-if="userInfo.Organization !== 'PrimePac'" class="note-form-area" > <div class="sub-form-title">注意事项:</div> <div class=""> <div class="label">印刷质量:</div> <div class="value">{{ form.field12 }}</div> </div> <div class=""> <div class="label">产品质量:</div> <div class="value">{{ form.field13 }}</div> </div> <div class=""> <div class="label">质量承诺:</div> <div class="value">{{ form.field10 }}</div> </div> <div class=""> <div class="label">箱子箱唛:</div> <div class="value">{{ form.field11 }}</div> </div> </div> <div v-else></div> <div class="product-total-table"> <div class="total-item flex"> <div class="label">小计 </div> <div class="value"> {{ currentCurrency.country }}{{ currentCurrency.symbol }} {{ toFixed(subTotal, computedDeci) }} </div> </div> <div class="total-item flex"> <div class="label">合计 </div> <div class="value"> {{ currentCurrency.country }}{{ currentCurrency.symbol }} {{ toFixed(grandTotal, computedDeci) }} </div> </div> </div> </div> <br /> <div class="sub-form-title">服务条款</div> <template v-if="currentCompany === 'PangeaTaxReimbursement'"> <div class="rule-item"> 一、合同价为含税价,税率为: {{ form.field4 }} % </div> <div class="rule-item">二、运费条款: {{ form.field5 }}</div> </template> <template v-if="['PrimePacCommon', 'PrimePacSoft'].includes(currentCompany)" > <div class="rule-item"> 一、本采购订单签署原件一式两份,双方各持一份。经双方代表签字或盖章即可生效,并具有同等法律效力。 </div> <div class="rule-item flex nowrap"> 二、以上价格已含所有产品的制作费、包装费;由 <span class="attention">{{ form.field5 }}</span> 运费送货到广州甲方指定的卸货地点,不含税,运费届时实报实销。 </div> <div class="rule-item"> 三、印刷及工艺要求:乙方需按照甲方图稿或指定样品进行生产,颜色对照潘通色卡或指定样品。 </div> <div class="rule-item"> 四、付款形式: <span class="attention">{{ form.Supplier_Payment_Terms }}</span> 。甲方在乙方完成大货时,先寄大货样品给乙方确认,确认后付清剩余尾款。甲方通过银行转帐的方式付款,乙方账户信息如上。 </div> <div class="rule-item"> 五、出货标准:五层出口空白硬纸箱,箱内套防潮袋。如实际出货包装与合约要求不符,甲方有权拒收整批货物。 </div> <div class="rule-item"> 六、订货时间:自合同成立,甲方支付定金并确认图稿后算起。 </div> <div class="rule-item"> 七、交货期限:自确认图稿时间算起,乙方应于 <span class="attention">{{ form.field6 }}</span> 前生产好产品,甲方确认并支付剩余款项后,乙方在约定时间内安排发出剩余产品到甲方收货地址。 </div> </template> <div v-for="(item, index) in currentServiceRule" :key="index" class="rule-item" :class="[{ sub: typeof item === 'object' }]" v-html="typeof item === 'object' ? item.value : item" ></div> <template v-if="['PrimePacCommon', 'PrimePacSoft'].includes(currentCompany)" > <div class="sub-form-title">附录</div> <div v-for="(item, index) in appendixData" :key="index" class="rule-item" :class="[{ sub: typeof item === 'object' }]" v-html="typeof item === 'object' ? item.value : item" ></div> </template> <div v-if="currentCompany === 'PrimePacCommon'" class="flex items-stretch PrimePac-table" > <div class="flex flex-col items-stretch"> <div class="column-item flex justify-center">制作要求</div> <div class="flex-auto column-item flex justify-center"> 产品外观要求 </div> </div> <div class="flex-auto flex flex-col items-stretch"> <div v-for="(item, index) in PrimePacCommonRuleTableData" :key="index" class="flex items-stretch flex-auto" > <div class="column-item flex justify-center"> {{ item.project }} </div> <div class="column-item flex-auto flex justify-center"> {{ item.method }} </div> </div> </div> </div> <div v-if="currentCompany === 'PrimePacSoft'" class="flex flex-col items-stretch PrimePac-table" > <div class="flex items-stretch"> <div class="flex flex-col items-stretch"> <div class="column-item flex-auto flex justify-center"> 制作要求 </div> </div> <div class="flex-auto flex flex-col items-stretch"> <div v-for="(item, index) in PrimePacSoftRuleTableData1" :key="index" class="flex items-stretch flex-auto" > <div class="column-item flex justify-center"> {{ item.project }} </div> <div class="column-item flex-auto flex justify-center"> {{ item.method }} </div> </div> </div> </div> <div class="flex items-stretch"> <div class="flex flex-col items-stretch"> <div class="column-item flex-auto flex justify-center"> 产品技术要求 </div> </div> <div class="flex-auto flex flex-col items-stretch"> <div v-for="(item, index) in PrimePacSoftRuleTableData2" :key="index" class="flex items-stretch flex-auto" > <div class="column-item flex justify-center"> {{ item.project }} </div> <div class="column-item flex-auto flex justify-center"> {{ item.method }} </div> </div> </div> </div> </div> <br /> <div class="signature-area"> <div class="company-seal"></div> <div style="align-items: flex-end" :class="{ flex: ['PrimePacCommon', 'PrimePacSoft'].includes( currentCompany, ), between: ['PrimePacCommon', 'PrimePacSoft'].includes( currentCompany, ), }" > <div class="first-party"> <div class="flex" style="align-items: flex-end" > <div v-show="!computedCompany.label.includes('Pangea')"> 甲方(盖章): </div> <div class="sign-wrap" :class="{ pangea: computedCompany.label.includes('Pangea'), }" > <img v-if="computedCompany.signPath" :src="computedCompany.signPath" /> </div> </div> <div class="">代表人: {{ userInfo.full_name }}</div> <div class="">日期: {{ form.PO_Date }}</div> </div> <div class="second-party"> <div class="">乙方(盖章):</div> </div> </div> </div> </div> </div> <div v-if="computedCompany.taxReimbursement && false" class="pdf-wrap" > <div ref="pdfElement2" class="preview-area2" > <div class="supplier-name"> {{ computedVendor.Suppliers_Name || computedVendor.Vendor_Name }} </div> <div class="billing-addr"> {{ computedVendor.Billing_Address || '' }} </div> <div class="flex justify-around contact-info"> <div class="flex"> <div>Tel No.:</div> <div> {{ computedVendor.Phone }}</div> </div> <div class="flex justify-center"> <div>E-mail:</div> <div class=""> {{ computedVendor.Email }}</div> </div> </div> <div class="base-info-area"> <div class="flex"> <div class="flex items-start left"> <div class="base-info-label">TO:</div> <div v-if="currentCompany === 'AZYTaxReimbursement'" class="base-info-value" > Azy Trading Pty Ltd </div> <div v-else-if="currentCompany === 'FOTTaxReimbursement'" class="base-info-value" > Fair Ocean Trading Australia Pty Ltd </div> </div> <div class="right flex"> <div class="base-info-label">Date:</div> <div class="base-info-value">{{ form.PO_Date }}</div> </div> </div> <div class="flex items-start"> <div class="left flex items-start"> <div class="base-info-label">ADD:</div> <div> <div v-if="currentCompany === 'AZYTaxReimbursement'" class="base-info-value" > UNIT 12,21/F WAYSON COMM BLDG NO 28 CONNAUGHT RD WEST SHEUNG WAN, HK </div> <div v-else-if="currentCompany === 'FOTTaxReimbursement'" class="base-info-value" > 15/10 Chilvers Road, Thornleigh, NSW 2120 </div> </div> </div> <div class="right flex"> <div class="base-info-label">P/I. NO.</div> <div class="base-info-value">{{ longPONumber }}</div> </div> </div> <div class="flex items-start"> <div class="left flex"> <div class="base-info-label">ATTN:</div> <div class="base-info-value">Accounts</div> </div> <div class="right flex"> <div class="base-info-label">Reference:</div> <div class="base-info-value">{{ PONumber }}</div> </div> </div> <div class="flex items-start"> <div class="flex left"> <template v-if="currentCompany === 'FOTTaxReimbursement'"> <div class="base-info-label">TEL NO:</div> <div class="base-info-value">02 9008 1322</div> </template> <div v-else></div> </div> <div class="right flex"> <div class="base-info-label">Payment Term:</div> <div class="base-info-value"> {{ computedVendor.Supplier_Payment_Terms }} </div> </div> </div> </div> <div class="table-title">PROFORMA INVOICE</div> <div class="product-table"> <table cellspacing="0"> <tr> <th>ITEM</th> <th>DESCRIPTION</th> <th>QTY(pcs)</th> <th>UNIT PRICE</th> <th>TOPTAL VALUE</th> </tr> <tr v-for="(product, index) in form.productList" :key="index" > <td> <div>{{ product.name }}</div> </td> <td> <div class="desc">{{ product.desc }}</div> </td> <td> {{ product.quantity }} </td> <td> {{ currentCurrency.country }}{{ currentCurrency.symbol }} {{ toFixed(Number(product.rate), computedDeci) }} </td> <td> {{ currentCurrency.country }}{{ currentCurrency.symbol }} {{ toFixed(Number(product.amount), computedDeci) }} </td> </tr> </table> <div class="flex justify-end"> <div class="flex" style="margin-top: 10pt" > <div style="margin: 0 100pt 0 0">TOTAL</div> <div> {{ currentCurrency.country }}{{ currentCurrency.symbol }} {{ subTotal }} </div> </div> </div> </div> <br /> <div class="bank-info-area"> <div class="flex"> <div>Bank Information</div> <div></div> </div> <div class="flex"> <div class="bank-info-label">Beneficiary:</div> <div class="bank-info-value"> {{ computedVendor.Suppliers_Name }}dd </div> </div> <div class="flex"> <div class="bank-info-label">Bank:</div> <div class="bank-info-value"> {{ computedVendor.Bank_Branch_Name }} </div> </div> <div class="flex"> <div class="bank-info-label">Bank Add:</div> <div class="bank-info-value">{{}}</div> </div> <div class="flex"> <div class="bank-info-label">A/C No.:</div> <div class="bank-info-value"> {{ computedVendor.Bank_Account }} </div> </div> <div class="flex"> <div class="bank-info-label">Bank Code:</div> <div class="bank-info-value">{{}}</div> </div> <div class="flex"> <div class="bank-info-label">SWIFT CODE:</div> <div class="bank-info-value"> {{ computedVendor.Swift_Code_IBAN }} </div> </div> <div class="flex"> <div class="bank-info-label">Add:</div> <div class="bank-info-value">{{}}</div> </div> </div> <br /> <div class="flex justify-between items-start"> <div class=""> <div class="">BUYERS' SIGNATURE</div> <div class="sign-wrap"> <img v-if="computedCompany.signPath" :src="computedCompany.signPath" /> </div> </div> <div class=""> <div class="">SELLER'S SIGNATURE</div> </div> </div> </div> </div> </div> </div> </template> <script lang="ts" setup> import { computed, defineComponent, ref, unref, watch } from 'vue' import { useRoute } from 'vue-router' import { ElButton, ElSelectV2, ElSelect, ElOption, ElIcon, ElInput, ElForm, ElFormItem, ElDatePicker, ElMessage, ElNotification, ElRadioGroup, ElRadio, ElMessageBox, } from 'element-plus' import type { FormInstance } from 'element-plus' import { ShoppingCart, FolderAdd, Switch } from '@element-plus/icons-vue' import request from '@/utils/axios' import dayjs from 'dayjs' import jspdf from 'jspdf' import html2canvas from 'html2canvas' import utils from '@/utils/index' import variables from '@/assets/css/var.module.scss' import { ServiceTypeKeyEnum, ISelectItem, IProductItem, IUser, IVendorItem, IRecommandVendor, IForm, } from '@/interface' import { currencyList, orderTypeList, formRule, emptyProductItem, PrimePacList, companyList, serviceRule, appendixData, warehouseList, productBlackList, PrimePacSoftRuleTableData2, PrimePacSoftRuleTableData1, PrimePacCommonRuleTableData, } from './const' defineComponent({ name: 'PurchaseOrderEdit', }) computed(() => { return variables }) const formVisible = ref(true) const loading = ref(false) // 订单ID. 例如 5757019000000683001, 不是串号. const POID = ref('') // po 串号. 例如 PO2025 const PONumber = ref('') // po 长串号. 例如 ZCPO2025 const longPONumber = ref('') const mainForm = ref<FormInstance>() const checkForm = function (formEl: FormInstance | undefined) { if (!formEl) return formEl.validate((valid, fields) => { if (valid) { submit() } else { console.log('check form has not pass!', fields) ElMessage.error('请检查表单必填项') } }) } const submit = () => { loading.value = true createPurchaseOrders() .then(() => { // console.log(res) getPurchaseOrdersData() .then(() => { generatePDF() .then(() => { ElNotification({ duration: 0, type: 'success', title: '任务已成功处理', message: '本页面将自动跳转', }) const url = import.meta.env.VITE_PO_PATH + POID.value + import.meta.env.VITE_PO_APPEND setTimeout(() => { window.location.replace(url) }, 1000) }) .finally(() => { loading.value = false }) }) .catch(() => { // loading.value = false const msg = '获取PO详情失败, 未能正确生成PDF' console.log(msg) ElNotification({ duration: 0, title: msg, type: 'error' }) }) }) .catch(() => { // loading.value = false const msg = '创建PO失败' console.log(msg) ElNotification({ duration: 0, title: msg, type: 'error' }) }) } const pdfElement = ref() const pdfElement2 = ref() const generatePDF = (ele = pdfElement, isFirstTime = true) => { const A4_WIDTH = 592.28 const A4_HEIGHT = 841.89 let imageWrapper = unref(ele) // 获取DOM // let pageHeight = (imageWrapper.scrollWidth / A4_WIDTH) * A4_HEIGHT let pageHeight = (imageWrapper.clientWidth / A4_WIDTH) * A4_HEIGHT let lableListID = imageWrapper.querySelectorAll('#pdfElement > div') // 进行分割操作,当dom内容已超出a4的高度,则将该dom前插入一个空dom,把他挤下去,分割 for (let i = 0; i < lableListID.length; i++) { let multiple = Math.ceil( (lableListID[i].offsetTop + lableListID[i].offsetHeight) / pageHeight, ) if (isSplit(lableListID, i, multiple * pageHeight)) { let divParent = lableListID[i].parentNode // 获取该div的父节点 let newNode = document.createElement('div') newNode.className = 'empty-div' newNode.style.background = '#fff' let _H = multiple * pageHeight - (lableListID[i].offsetTop + lableListID[i].offsetHeight) //留白 newNode.style.height = _H + 40 + 'px' newNode.style.width = '100%' let next = lableListID[i].nextSibling // 获取div的下一个兄弟节点 // 判断兄弟节点是否存在 if (next) { // 存在则将新节点插入到div的下一个兄弟节点之前,即div之后 divParent.insertBefore(newNode, next) } else { // 不存在则直接添加到最后,appendChild默认添加到divParent的最后 divParent.appendChild(newNode) } } } return new Promise((resolve) => { html2canvas(imageWrapper, { allowTaint: true, useCORS: true, backgroundColor: '#fff', //一定要设背景颜色,否则有的浏览器就会变花~,比如Edge scale: 3, // 缩放倍率调整清晰度 }).then((canvas) => { let pdf = new jspdf('p', 'mm', 'a4') //A4纸,纵向 let ctx = canvas.getContext('2d'), a4ContentWidth = 190, a4ContentHeight = 277, //A4大小,210mm x 297mm,四边各保留10mm的边距,显示区域190x277 imgHeight = Math.floor( (a4ContentHeight / a4ContentWidth) * canvas.width, ), //按A4显示比例换算一页图像的像素高度 renderedHeight = 0 while (renderedHeight < canvas.height) { let page = document.createElement('canvas') page.width = canvas.width page.height = Math.min(imgHeight, canvas.height - renderedHeight) //可能内容不足一页 //用getImageData剪裁指定区域,并画到前面创建的canvas对象中 // @ts-ignore: Object is possibly 'null'. page .getContext('2d') .putImageData( ctx!.getImageData( 0, renderedHeight, canvas.width, Math.min(imgHeight, canvas.height - renderedHeight), ), 0, 0, ) // document.body.appendChild(page) pdf.addImage( page.toDataURL('image/jpeg', 0.5), 'JPEG', 10, 10, a4ContentWidth, Math.min( a4ContentHeight, a4ContentWidth * (page.height / page.width), ), ) //添加图像到页面,保留10mm边距 renderedHeight += imgHeight if (renderedHeight < canvas.height) pdf.addPage() //如果后面还有内容,添加一个空页 } const prefix = `${PONumber.value}-${computedVendor.value.label}` + (form.value.Title?.length ? `-${form.value.Title}` : '') const fileName = isFirstTime ? prefix : prefix + '_2' // sendPDF(pdf.output('datauristring'), fileName) // .then(() => { resolve(true) // }) // 本地备份一下 pdf.save(fileName + '.pdf') }) }) } const isSplit = function (nodes: any, index: number, pageHeight: number) { // 计算当前这块dom是否跨越了a4大小,以此分割 if ( nodes[index].offsetTop + nodes[index].offsetHeight < pageHeight && nodes[index + 1] && nodes[index + 1].offsetTop + nodes[index + 1].offsetHeight > pageHeight ) { return true } return false } // const sendPDF = function (file: string, filename = `attachment_file`) { // const temp = file.split(',') // // @ts-ignore: Object is possibly 'null'. // const mimeType = temp[0].match(/:(.*?);/)[1] // let extName = mimeType.split('/')[1] // let bstr = window.atob(temp[1]) // let n = bstr.length // let result = new Uint8Array(n) // while (n--) { // result[n] = bstr.charCodeAt(n) // } // const data = { // id: POID.value, // file: new File([result], `${filename}.${extName}`, { type: mimeType }), // } // return new Promise((resolve, reject) => { // request // .post('/Purchase_orders/uploadAttachmentFile', data, { // headers: { // 'Content-Type': 'multipart/form-data', // }, // }) // .then((response) => { // if (response.data.code !== 1) { // const msg = '自动创建附件失败' // ElNotification({ duration: 0, title: msg, type: 'error' }) // reject(msg) // return // } // ElNotification({ // duration: 0, // title: '自动创建 PDF 成功', // type: 'success', // }) // resolve(true) // }) // .catch((e) => { // reject(e) // }) // }) // } const createPurchaseOrders = function () { const data = JSON.parse(JSON.stringify(unref(form))) data.Status = 'Created' data.Sub_Total = subTotal.value data.Total_Taxes = 0 data.Total_Discount = totalDiscount.value data.Adjustment = Number(adjustment.value) data.Grand_Total = grandTotal.value data.Subject = '这里不用填' data.Created_By = { id: userInfo.value.users_id || route.query.user, name: userInfo.value.full_name || '', } data.Owner = { id: userInfo.value.users_id || route.query.user, name: userInfo.value.full_name || '', email: userInfo.value.email || '', } data.Vendor_Name = { id: computedVendor.value.value, name: computedVendor.value.label, } data.Related_Sales_Order = { id: form.value.saleOrderId, name: form.value.Title, } data.Purchase_Items = data.productList.map((item: any) => { return { Warehouse: item.Warehouse || '', Quantity: item.quantity, Discount: item.discount || 0, List_Price: item.rate, Tax: 0, total: item.amount, total_after_discount: Number(item.amount) - Number(item.discount), Net_Total: Number(item.amount) - Number(item.discount), Description: item.desc, Requirement: item.requirement, line_tax: [], // book: '', // id: item.id, product: { // name: item.name, id: item.id, // Product_Code: item.Product_Code, }, Product_Name: { id: item.id, }, // 这两个是crm有的, 但是文档没有 List_Price_Non_Currency: item.rate, Price_Book_Name: '', } }) if (data.productList) delete data.productList return new Promise((resolve, reject) => { request .post('/Purchase_orders/createPurchaseOrders', data, {}) .then((response) => { if (response.data.code !== 1) return const res = response.data.result if (res.data && res.data.length && res.data[0].code === 'SUCCESS') { POID.value = res.data[0].details?.id || '' resolve(res.data[0].details?.id) ElNotification({ duration: 0, title: '创建 Purchase Order 成功', type: 'success', }) } else { ElNotification({ duration: 0, title: '未能成功创建PO, 请稍后重试或者联系管理员', type: 'error', }) } reject('未能成功创建PO') }) .catch((e) => { reject(e) }) }) } const getPurchaseOrdersData = function () { return new Promise((resolve, reject) => { request .post('/purchase_orders/getPurchaseOrdersData', { id: POID.value, }) .then((response) => { if (response.data.code !== 1) { reject(false) return } const res = Array.isArray(response.data.result) ? response.data.result[0] : response.data.result longPONumber.value = res.PO_Number || '' PONumber.value = res.Purchase_Order_Number || '' resolve(true) }) .catch((e) => { reject(e) }) }) } const currentCurrency = computed(() => { const temp = currencyList.value.filter((i) => i.label === form.value.Currency) // 2是人民币 return temp.length ? temp[0] : temp[2] }) const form = ref<IForm>({ Order_Type: '', Artwork_Link: '', Currency: 'CNY', // 订单号 saleOrderId: '', Reference: '', // 日期 PO_Date: '', // 付款方式 Supplier_Payment_Terms: '-None-', // 参考, so的job name Title: '', // 收货地址 field9: '广州市越秀区八旗二马路广东航运大厦1904室 邮编510110', // 收件人 field7: '', // 联系电话 field8: '18925020659', // 工厂交货日期 field6: '', productList: [ { name: '', id: '', quantity: '', rate: '', requirement: '', desc: '', amount: 0, discount: '', candidate: [], }, ] as IProductItem[], // 印刷质量 field12: '', // 产品质量 field13: '', // 质量承诺 field10: '', // 箱子箱唛 field11: '', // 税率 field4: '0', // 运费条款 field5: '供应商承担', currentVendor: '', Delivery_Details: '', }) const addRow = function () { form.value.productList.push(JSON.parse(JSON.stringify(emptyProductItem))) } const keyNeedCompute = ['quantity', 'rate'] const onInputChange = function (e: any, obj: IProductItem, key: string) { if (typeof e === 'string') { if (e.length) { // 强制转换为数字类型 obj[key] = Math.round(utils.multiply(Number(e), 1000)) / 1000 // 计算每行的总额 if (keyNeedCompute.includes(key)) { obj.amount = utils.multiply(Number(obj.quantity), Number(obj.rate)) } } else { // obj[key] = minValue } } } const onProductSelect = function (e: any, product: IProductItem) { if (e) { const temp = product.candidate.filter((i) => i.value === e) if (temp.length) { product.name = temp[0].label product.Product_Code = temp[0].Product_Code // 没有传出去, 实际上没用, 在本页面处于废弃状态 } getProductData(product.id).then((ctx) => { product.requirement = userInfo.value.Organization === 'PrimePac' ? '产品名称:\n尺寸:\n材质:\n工艺:\n颜色:\n其他备注:' : ctx.CF3 || '' product.CF_Product_Type = ctx.CF_Product_Type || '' }) } else { product.name = '' } } // 小计 const subTotal = computed(() => { return form.value.productList.reduce((total, current) => { total = total + Number(current.amount) return total }, 0) }) // 总优惠额度 const totalDiscount = computed(() => { return form.value.productList.reduce((total, current) => { total = total + Number(current.discount) return total }, 0) }) // 价格统计修正值 const adjustment = ref<number | string>('') // 总计 const grandTotal = computed(() => { return subTotal.value - totalDiscount.value + Number(adjustment.value) }) const productLoading = ref(false) const getProductList = utils.debounce( (keyword: string, target: IProductItem) => { const key = keyword.trim() if (!key.length) return productLoading.value = true const data = { value: key, name: 'Products', api_name: 'Product_Name', contains: 'contains', page: 1, limit: 20, } getSearchData(data) .then((response) => { if (response.data.code !== 1) return const res = response.data.result target.candidate = res.data.map((item: any) => { return { ...item, label: item.Product_Name, value: item.products_id || item.id, } }) }) .finally(() => { productLoading.value = false }) }, 1000, ) const toFixed = function (value: number, ratio = 2) { let r = 100 if (ratio === 3) { r = 1000 } return utils.toFixed(value, r) } const vendorList = ref<IVendorItem[]>([]) const computedVendor = computed(() => { const temp = vendorList.value.filter( (i) => i.value === form.value.currentVendor, ) return temp.length ? temp[0] : { Primary_Contact_name: '', PDF_display: '', PDF_display2: '', label: '', value: '', Payment_Terms: '', High_Risk_Supplier: false } }) watch(computedVendor, () => { if ( computedVendor.value.Payment_Terms && computedVendor.value.Payment_Terms.length ) { form.value.Supplier_Payment_Terms = computedVendor.value.Payment_Terms } }) const vendorLoading = ref(false) const getSupplierLists = function (string: string) { return new Promise((resolve, reject) => { const keyword = string.trim() || '' if (!keyword.length) { reject('false') return } const data = { value: keyword, name: 'Vendors', api_name: 'Vendor_Name', contains: 'contains', page: 1, limit: 100, } vendorLoading.value = true getSearchData(data) .then((response) => { if (response.data.code !== 1) return false const res = response.data.result || { data: [] } vendorList.value = res.data .filter((i: any) => !i.Hide_Record) .map((i: any) => { return { ...i, label: i.Suppliers_Name || i.Vendor_Name, value: i.supplier_id || i.id, Primary_Contact_name: i.Primary_Contact_name || '', PDF_display: i.PDF_display || '', PDF_display2: i.PDF_display2 || '', } }) if ( vendorList.value.length === 1 && vendorList.value[0].High_Risk_Supplier === true ) { ElMessageBox.alert( '请注意该供应商在我们黑名单中。<br>Please note that this supplier is in our black list.', 'Alert', { dangerouslyUseHTMLString: true, }, ) } vendorLoading.value = false loading.value = false resolve(true) }) .catch((e) => reject(e)) }) } const quickSelectSupplier = function (item: IRecommandVendor) { form.value.currentVendor = item.id loading.value = true getSupplierLists(item.name) } const getSearchData = async function (p: any) { return await request .post('/common/getPublicLists', p, { headers: { 'Content-Type': 'multipart/form-data' }, }) .then((response) => { return response }) } const computedCompanyList = computed(() => { return userInfo.value.Organization === 'PrimePac' ? PrimePacList.value : companyList.value }) // 切换模版后的处理 const onCompanyTemplateChange = function () { // 重置这两个字段 form.value.field5 = '供应商承担' form.value.field4 = '' if (typeof computedCompany.value.taxReimbursement === 'undefined') { form.value.field7 = soOwner.value form.value.field8 = '18925020659' form.value.field9 = '广州市越秀区八旗二马路广东航运大厦1904室 邮编510110' } else { // 退税版没有这三个表单项, 直接重置值. 相应的, 非退税版要重新赋值. form.value.field7 = '' form.value.field8 = '' form.value.field9 = '' } } const currentServiceRule = computed(() => { if (currentCompany.value === 'PrimePacSoft') { return serviceRule.value['PrimePacCommon'] } return serviceRule.value[currentCompany.value as ServiceTypeKeyEnum] }) const currentCompany = ref('PC') const computedCompany = computed(() => { const result = computedCompanyList.value.filter( (i) => i.id === currentCompany.value, ) return result.length ? result[0] : computedCompanyList.value[0] }) // 格式化输出价格的小数位数. 退税版需要显示三位小数, 其他只需要两位小数 const computedDeci = computed(() => { return typeof computedCompany.value.taxReimbursement !== 'undefined' ? 3 : 2 }) // 候选 收货地址 let addressList = ref<ISelectItem[]>([]) // 候选 运费条款. 目前只有庞吉亚退税版用到, 其他模版默认供应商承担 let field5_lists = ref<ISelectItem[]>([]) let supplierPaymentTermsLists = ref<ISelectItem[]>([]) loading.value = true // 获取下拉框非动态候选数据 const p1 = request .post('/common/getfieldsData') .then((response: any) => { const res = response.data.result orderTypeList.value = res.Order_Type_lists.map((i: string) => { return { label: i, } }).filter((i: any) => i.label !== '-None-') addressList.value = res.field9_lists.map((i: any) => { return { label: i, } }) field5_lists.value = res.field5_lists .filter((i: string) => !/^-?[Nn]one-?$/.test(i)) .map((i: any) => { return { label: i, } }) supplierPaymentTermsLists.value = res.Supplier_Payment_Terms_lists.map( (i: any) => { return { label: i, } }, ) }) .catch((e) => { console.log(e, '下拉框') ElMessage.error('获取下拉框数据出错, 请联系管理员.') }) const route = useRoute() const soOwner = ref('') // 获取销售订单详情 const p2 = request .post('/common/getSalesOrdersData', { id: route.params.id }) .then((response) => { return response }) // 获取对 该so对应客户的标注 并弹窗提醒 const getAccountsData = async (id: string) => request.post('/common/getAccountsData', { id }).then((response) => { const res = response.data if (res.code !== 1) return if (res.result.User_Notes && res.result.User_Notes.length) { ElMessageBox.confirm(res.result.User_Notes, '', { confirmButtonText: '将此备注添加到合同', cancelButtonText: '已知悉', type: 'warning', showClose: false, closeOnPressEscape: false, closeOnClickModal: false, autofocus: false, }) .then(() => { // 迭代3 需求. 固定填充一行. form.value.productList.push( Object.assign({}, emptyProductItem, { requirement: res.result.User_Notes || '', quantity: 1, rate: 0, id: '4791186000172849436', name: 'User Notes', CF_Product_Type: '', candidate: [ { label: 'User Notes', value: '4791186000172849436', }, ], }), ) }) .catch(() => {}) } }) const getProductData = async (id: string) => request.post('/common/getProductsData', { id }).then((response) => { const res = response.data if (res.code !== 1) return // 推荐供应商. 用来快速选择供应商的. if ( Array.isArray(res.result.SUPPLIER_PRICING) && res.result.SUPPLIER_PRICING.length ) { for (const item of res.result.SUPPLIER_PRICING) { if ( item.Supplier?.id && !computedRecommandVendorID.value.includes(item.Supplier.id) ) { console.log(item, 'item') recommandVendor.value.push({ id: item.Supplier.id, name: item.Supplier.name, }) } } } return res.result }) const recommandVendor = ref<IRecommandVendor[]>([]) // 用来去重 const computedRecommandVendorID = computed(() => recommandVendor.value.map((i: any) => i.id), ) // 根据url传递过来的用户ID获取的用户身份信息 const userInfo = ref({} as IUser) const p3 = request .post('/common/getUsersData', { id: route.query.user }) .then((response) => { const res = response.data if (res.code !== 1) return if (res.result.users && res.result.users.length) { userInfo.value = res.result.users[0] } else if (res.result.id) { userInfo.value = res.result || {} } else if (Array.isArray(res.result) && res.result.length) { userInfo.value = res.result[0] || {} } else { ElMessage.error('获取当前用户身份异常, 请联系管理员') } // 根据用户 ‘组织’ 切换模版默认选中项 if (userInfo.value.Organization === 'PrimePac') { currentCompany.value = 'PrimePacCommon' } else { currentCompany.value = 'PC' } }) Promise.all([p1, p2, p3, getAccountsData]) .then((array: any[]) => { // p2的数据处理逻辑从原本的p2then移动到这里处理. // 因为要根据p3用户数据的Organization 来填充产品列表里面的 requirement, 这步处理必须放在p3后面, 而p2 p3是并发操作. if (array[1].data.code !== 1) return const res = array[1].data.result if (res.Account_Name && res.Account_Name.id) { getAccountsData(res.Account_Name.id) } form.value.field7 = res.Owner_name || res.Owner.name || '' soOwner.value = res.Owner_name || res.Owner.name || '' form.value.Title = res.Contract_Title || res.Sales_Order_Title_Job_Name || '' form.value.saleOrderId = res.sales_orders_id || res.id || '' form.value.PO_Date = dayjs(new Date()).format('YYYY-MM-DD') form.value.Reference = res.Reference || '' form.value.Artwork_Link = res.Artwork_Link || '' let temp = [] if (res.details) { temp = res.details.filter( (item: any) => !productBlackList.includes(item.product_id), ) } else if (res.Product_Details) { temp = res.Product_Details.filter( (item: any) => !productBlackList.includes(item.product.id), ) } if (!temp.length) return form.value.productList = [] recommandVendor.value = [] temp.forEach((item: any) => { getProductData(item.product.id).then((ctx) => { console.log(ctx, 'product ctx') form.value.productList.push( Object.assign({}, emptyProductItem, { candidate: [ { Product_Code: item.product_Product_Code, label: item.product.name, value: item.product.id, }, ], Product_Code: item.product.Product_Code, id: item.product.id, name: item.product.name, label: item.product.name, value: item.product.id, desc: item.product_description || '', quantity: Number(item.quantity), requirement: userInfo.value.Organization === 'PrimePac' ? '产品名称:\n尺寸:\n材质:\n工艺:\n颜色:\n其他备注:' : ctx.CF3 || '', CF_Product_Type: ctx.CF_Product_Type, }), ) }) }) }) .finally(() => { loading.value = false }) </script> <style lang="scss"> input[type='number'] { -moz-appearance: textfield; appearance: textfield; &:hover { -moz-appearance: textfield; appearance: textfield; &::-webkit-inner-spin-button, &::-webkit-outer-spin-button { -webkit-appearance: none; margin: 0; } } &::-webkit-inner-spin-button, &::-webkit-outer-spin-button { -webkit-appearance: none; margin: 0; } } .product-select { .el-select-dropdown, .el-select-dropdown__list { min-width: 400px; max-width: 500px; } } </style> <style lang="scss" scoped> @import './style.scss'; </style>