<template> <div class="app-container"> <el-form ref="form" :model="form" :rules="rules" label-width="150px"> <products-selector ref="productSelector" v-model="form.productIdList" show-all @setall="isAllProduct = $event" enable-filtered @setFiltered="isAllFilteredProduct = $event" :default-ids="form.productIdList" class="mb-20" /> <routers-selector v-model="selectedRoutes" :type="type" /> <el-card style="margin-bottom: 10px"> <div slot="header" style="font-size: 20px"> {{ $t("价格设置") }} </div> <div :gutter="20"> <el-form-item :label="$t('单价模式')" prop="priceType"> <dict-selector :type="DICT_TYPE.ECW_PRICE_TYPE" v-model="form.priceType" form-type="radio" formatter="number" /> <!--海运才需要是否含阶梯价的选项,空运只有阶梯价就不需要了--> <div v-if="type == 'sea'"> <el-checkbox v-model="form.stepPrice" :true-label="1" :false-label="0" >{{ $t("是否含阶梯价") }}</el-checkbox > </div> </el-form-item> <!--如果是阶梯价--> <template v-if="form.stepPrice"> <!--全包价--> <template v-if="form.priceType == 1"> <div v-for="(item, index) in form.fullPriceStepList" :key="index"> <price-step ref="stepPrice" :index="index" :currency-list="currencyList" :unit-list="unitList" field-prefix="all" :price-name="$t('全包价')" :show-add="index === form.fullPriceStepList.length - 1" :value="item" :step-tips=" !isStepPriceValid(item) ? $t('区间设置不完整,将被忽略') : null " @add="handleAddPrice('fullPriceStepList', $event)" @delete="handleDeletePrice('fullPriceStepList', $event)" @changeUnit=" handleUnitChange(form.fullPriceStepList, index, ...$event) " ></price-step> </div> </template> <el-row v-else :gutter="20" class="mt-20"> <el-col :span="12"> <div v-for="(item, index) in form.freightPriceStepList" :key="index" > <price-step ref="stepPrice" :index="index" :currency-list="currencyList" :unit-list="unitList" field-prefix="transport" :price-name="$t('运费')" :show-add="index === form.freightPriceStepList.length - 1" :value="item" :step-tips=" !isStepPriceValid(item) ? $t('区间设置不完整,将被忽略') : null " @add="handleAddPrice('freightPriceStepList', $event)" @delete="handleDeletePrice('freightPriceStepList', $event)" @changeUnit=" handleUnitChange( form.freightPriceStepList, index, ...$event ) " ></price-step> </div> </el-col> <el-col :span="12"> <div v-for="(item, index) in form.clearancePriceStepList" :key="index" > <price-step ref="stepPrice" :index="index" :currency-list="currencyList" :unit-list="unitList" field-prefix="clearance" :price-name="$t('清关费')" :show-add="index === form.clearancePriceStepList.length - 1" :value="item" :step-tips=" !isStepPriceValid(item) ? $t('区间设置不完整,将被忽略') : null " @add="handleAddPrice('clearancePriceStepList', $event)" @delete=" handleDeletePrice('clearancePriceStepList', $event) " @changeUnit=" handleUnitChange( form.clearancePriceStepList, index, ...$event ) " ></price-step> </div> </el-col> </el-row> </template> <template v-else-if="form.priceType === 1"> <sea-price ref="seaPrice" :currency-list="currencyList" :unit-list="unitList" :value="form" :readonly="readonly" field-prefix="all" :price-name="$t('全包价')" packaging-field="fullPricePackagingList" @changeUnit="handleFormUnitChange($event)" ></sea-price> </template> <template v-else> <el-row :gutter="20"> <el-col :span="12"> <sea-price ref="seaPrice" :currency-list="currencyList" :unit-list="unitList" :value="form" field-prefix="transport" :price-name="$t('运费')" packaging-field="freightPricePackagingList" @changeUnit="handleFormUnitChange($event)" ></sea-price> </el-col> <el-col :span="12"> <sea-price ref="seaPrice" :currency-list="currencyList" :unit-list="unitList" :value="form" field-prefix="clearance" :price-name="$t('清关费')" packaging-field="clearancePricePackagingList" @changeUnit="handleFormUnitChange($event)" ></sea-price> </el-col> </el-row> </template> </div> </el-card> </el-form> <div style="margin: 20px 0"> <el-button @click="submitForm" type="primary" :loading="loading">{{ $t("确认提交") }}</el-button> <el-button type="default" @click="$router.back()">{{ $t("返回上一页") }}</el-button> </div> </div> </template> <script> import RoutersSelector from "@/components/RoutersSelector"; import { batchAddPrice, batchUpdateProductPrice, getProductPrice, } from "@/api/ecw/productPrice"; import { getCurrencyList } from "@/api/ecw/currency"; import { getUnitList } from "@/api/ecw/unit"; import ProductsSelector from "@/components/ProductsSelector"; import Selector from "@/components/Selector"; import Inputor from "@/components/Inputor"; import Decimal from "decimal.js"; import SeaPrice from "@/views/ecw/productPrice/components/SeaPrice.vue"; import Template from "@/views/cms/template/index.vue"; import PriceStep from "@/views/ecw/productPrice/components/PriceStep.vue"; import { getFormData } from "@/views/ecw/productPrice/util"; const DEFAULT_PRICE_UNIT = 1; const DEFAULT_VOLUME_UNIT = 7; const DEFAULT_WEIGHT_UNIT = 7; export default { components: { PriceStep, Template, SeaPrice, RoutersSelector, ProductsSelector, Selector, Inputor, }, data() { return { checkList: [], selectedRoutes: [], // 勾选的路线渠道 form: { priceType: "0", specialList: [], stepPrice: 0, }, isAllProduct: false, // 是否全部商品 isAllFilteredProduct: false, // 是否全部篩選商品 specialProducts: [], rules: {}, product: null, currencyList: [], unitList: [], productTypeList: [], productDisabled: true, lineList: [], //路线数组 loading: false, // 批量加价/减价 quickForm: {}, }; }, computed: { // 类型,默认海运sea,air表示空运 type() { return this.$route.path.split(/[-_]/).pop(); }, // 判断阶梯价是否有效 isStepPriceValid() { return (stepPrice) => { return stepPrice.startNum && stepPrice.endNum; }; }, }, watch: { checkList() { //选择路线 if (this.checkList.length > 0) { this.form.lineChannelList = this.checkList.map((item) => { return { lineId: item, shippingChannelId: 0 }; }); } else { this.form.lineChannelList = []; } }, product() { this.$set(this.form, "productType", this.product.typeId); }, "form.priceType"(priceType) { if (this.form.stepPrice === 1) { this.initStepPrice(); } }, "form.stepPrice"(stepPrice) { if (this.form.stepPrice === 1) { this.initStepPrice(); } this.stepPrice = !!stepPrice; }, }, async created() { this.currencyList = (await getCurrencyList())?.data || []; this.unitList = (await getUnitList())?.data || []; this.getDictDatas(this.DICT_TYPE.ECW_SPECIAL_REQ_FOR_LINE_PRODUCTS).forEach( (item) => { // 没有的才push,已有的可能是从复制模板携带过来的数据 if ( !this.form.specialList.find( (special) => special.specialDictType == item.value ) ) { this.form.specialList.push({ clearancePrice: null, clearancePriceUnit: null, clearanceVolumeUnit: null, specialDictType: item.value, transportPrice: null, transportPriceUnit: null, transportVolumeUnit: null, }); } } ); }, methods: { handleAddPrice(field, fieldPrefix) { if (!this.form[field]) { this.$set(this.form, field, []); } let priceUnit = DEFAULT_PRICE_UNIT; let volumeUnit = DEFAULT_VOLUME_UNIT; let weightUnit = DEFAULT_WEIGHT_UNIT; if (this.form[field].length) { const first = this.form[field][0]; priceUnit = first[`${fieldPrefix}PriceUnit`]; volumeUnit = first[`${fieldPrefix}VolumeUnit`]; weightUnit = first.weightUnit; } console.log("添加价格的默认单位", { priceUnit, volumeUnit, weightUnit, }); this.form[field].push({ [`${fieldPrefix}PriceUnit`]: priceUnit, [`${fieldPrefix}VolumeUnit`]: volumeUnit, weightUnit: weightUnit, specialList: [], }); }, handleDeletePrice(field, index) { this.form[field].splice(index, 1); }, handleUnitChange(stepPriceList, index, data) { console.log("handleUnitChange", ...arguments); if (index > 0) return; const isVolumeUnit = data.field.indexOf("VolumeUnit") > -1; // 如果是重量单位,且不是清关费想换的,则需要同步最小起计量单位 if (isVolumeUnit && data.type != "clearance") { this.form.minWeightUnit = data.value; } stepPriceList.forEach((item) => { item[data.field] = data.value; // 如果是设置体积单位,则还需要同步到阶梯重量单位 if (isVolumeUnit) { item["weightUnit"] = data.value; } if (item.packagingList?.length) { item.packagingList.forEach((p) => { if (data.field.indexOf("PriceUnit") > -1) { p["packagingPriceUnit"] = data.value; } if (data.field.indexOf("VolumeUnit") > -1) { p["packagingVolumeUnit"] = data.value; } }); } if (item.specialList?.length) { item.specialList.forEach((p) => { p[data.field] = data.value; }); } }); }, // 获得用于提交的阶梯价副本 getPriceList(stepList) { if (!stepList?.length) return []; let stepPriceList = JSON.parse(JSON.stringify(stepList)); stepPriceList.forEach((item, index) => { item.rankNum = index + 1; item.packagingList = this.getPackagingPrice(item.packagingList); }); // 过滤掉空的阶梯 return stepPriceList.filter(this.isStepPriceValid); }, // 获取包装类型价 getPackagingPrice(packagingList) { const list = JSON.parse(JSON.stringify(packagingList)); return list .filter((p) => !!p.packagingTypes?.length) .map((p) => { p.packagingTypes = p.packagingTypes.join(","); return p; }); }, // 非阶梯价格更新单位 handleFormUnitChange(data) { // 海运非阶梯价没有重量单位,所以按照体积单位同步最小起计量单位 if ( data.field === "transportVolumeUnit" || data.field == "allVolumeUnit" ) { this.form.minWeightUnit = data.value; } if (this.form.specialList?.length) { this.form.specialList.forEach((p) => { p[data.field] = data.value; }); } // 同步包装的单位 let packingField = { transportVolumeUnit: "freightPricePackagingList", clearanceVolumeUnit: "clearancePricePackagingList", allVolumeUnit: "fullPricePackagingList", transportPriceUnit: "freightPricePackagingList", clearancePriceUnit: "clearancePricePackagingList", }[data.field]; if (!this.form[packingField]?.length) { return false; } this.form[packingField].forEach((item) => { if (data.field.indexOf("PriceUnit") > -1) { item["packagingPriceUnit"] = data.value; } if (data.field.indexOf("VolumeUnit") > -1) { item["packagingVolumeUnit"] = data.value; } }); }, initStepPrice() { if (this.form.priceType == 1 && !this.form.fullPriceStepList?.length) { this.handleAddPrice("fullPriceStepList", "all"); } if (this.form.priceType === 0) { if (!this.form.freightPriceStepList?.length) { this.handleAddPrice("freightPriceStepList", "transport"); } if (!this.form.clearancePriceStepList?.length) { this.handleAddPrice("clearancePriceStepList", "clearance"); } } }, // 检查包装类型价格是否有效 validatePackagingPrice(packagingList, priceName) { if (!packagingList?.length) return true; let valid = true; for (const index in packagingList) { const item = packagingList[index]; if (!item.packagingPrice) { valid = false; const no = parseInt(index) + 1; this.$message.error( this.$t("请设置{priceName}的第{no}包装费", { priceName, no }) ); break; } } return valid; }, submitForm() { this.$refs["form"].validate(async (valid) => { if (!valid) { return; } let data = JSON.parse(JSON.stringify(this.form)); data.isAllProduct = this.isAllProduct ? 1 : 0; data.lineChannelList = this.selectedRoutes; if (!data.lineChannelList?.length) { return this.$message.error(this.$t("请选择需要修改的路线")); } if (!data.productIdList?.length) { return this.$message.error(this.$t("请选择商品") + "!"); } // 如果是阶梯价,需要把阶梯价的数据转换成提交的格式 delete data.freightPriceStepList; delete data.clearancePriceStepList; delete data.fullPriceStepList; delete data.clearancePricePackagingList; delete data.freightPricePackagingList; delete data.fullPricePackagingList; // 阶梯价 if (data.stepPrice) { delete data.specialList; if (data.priceType === 1) { data.fullPriceStepList = this.getPriceList( this.form.fullPriceStepList ); } else { data.freightPriceStepList = this.getPriceList( this.form.freightPriceStepList ); data.clearancePriceStepList = this.getPriceList( this.form.clearancePriceStepList ); } } else { if (data.priceType) { data.fullPricePackagingList = this.getPackagingPrice( this.form.fullPricePackagingList ); if ( !this.validatePackagingPrice( data.fullPricePackagingList, "全包价" ) ) { return false; } } else { data.clearancePricePackagingList = this.getPackagingPrice( this.form.clearancePricePackagingList ); data.freightPricePackagingList = this.getPackagingPrice( this.form.freightPricePackagingList ); if ( !this.validatePackagingPrice( data.freightPricePackagingList, this.$t("运费") ) || !this.validatePackagingPrice( data.clearancePricePackagingList, this.$t("清关费") ) ) { return false; } } data.specialList = data.specialList.filter((item) => { return item.transportPrice || item.clearancePrice; }); } let msg = this.$t("已选择{route}条路线,{product}个商品", { route: data.lineChannelList.length, product: this.isAllProduct ? this.$refs.productSelector.allTotal : data.productIdList.length, }); await this.$confirm(msg + this.$t(";确认提交修改?")); this.loading = true; batchAddPrice(data) .then(async (response) => { await this.$alert(this.$t("操作成功")); this.$store.dispatch("tagsView/delCurrentView"); }) .finally((res) => { this.loading = false; }); }); }, }, }; </script> <style scoped> .w100 { width: 100px; } .mr10 { margin-right: 10px; } </style>