提交价格功能绑定
This commit is contained in:
@@ -57,6 +57,11 @@ const props = defineProps({
|
||||
updateSupportLabel: {
|
||||
type: String,
|
||||
default: '是否更新已经存在的数据'
|
||||
},
|
||||
// 打开时是否默认勾选“更新已存在”
|
||||
defaultUpdateSupport: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
})
|
||||
|
||||
@@ -77,7 +82,7 @@ const templateUrl = computed(() => !!props.templateAction)
|
||||
|
||||
// 打开对话框(供父组件通过 ref 调用)
|
||||
function open() {
|
||||
updateSupport.value = false
|
||||
updateSupport.value = props.defaultUpdateSupport
|
||||
isUploading.value = false
|
||||
visible.value = true
|
||||
nextTick(() => {
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
:closable="false"
|
||||
show-icon
|
||||
class="mb16"
|
||||
title="Excel 导入:上传威狮B2C小包价表.xlsx。仅入库产品目录 + 各产品 sheet 的国家尺寸/尾程/时效;不导入运费、挂号费、退件重派、申报说明、赔偿标准。"
|
||||
title="Excel 导入:上传威狮B2C小包价表.xlsx。入库产品目录 + 各产品 sheet 的国家×重量段(运费/挂号费/尺寸/尾程/时效);不导入退件重派、申报说明、赔偿标准。"
|
||||
/>
|
||||
|
||||
<basic-table
|
||||
@@ -47,7 +47,7 @@
|
||||
</template>
|
||||
|
||||
<template #col-action="{ row }">
|
||||
<el-button link type="primary" icon="View" @click="openCountries(row)" v-hasPermi="['price:product:query']">国家明细</el-button>
|
||||
<el-button link type="primary" icon="View" @click="openCountries(row)" v-hasPermi="['price:product:query']">产品明细</el-button>
|
||||
<el-button link type="primary" icon="Edit" @click="handleUpdate(row)" v-hasPermi="['price:product:edit']">编辑</el-button>
|
||||
<el-button link type="primary" icon="Delete" @click="handleDelete(row.productId)" v-hasPermi="['price:product:remove']">删除</el-button>
|
||||
</template>
|
||||
@@ -122,7 +122,7 @@
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<el-drawer v-model="countryOpen" size="720px" :title="countryTitle" append-to-body>
|
||||
<el-drawer v-model="countryOpen" size="920px" :title="countryTitle" append-to-body>
|
||||
<el-table v-loading="countryLoading" :data="countryList" border empty-text="暂无国家明细">
|
||||
<el-table-column label="国家" prop="countryName" width="90" show-overflow-tooltip />
|
||||
<el-table-column label="ISO2" prop="countryCode" width="60" align="center" />
|
||||
@@ -132,6 +132,8 @@
|
||||
<span v-else>-</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="运费(RMB/KG)" prop="freightPrice" width="110" align="right" />
|
||||
<el-table-column label="挂号费(RMB/票)" prop="registrationFee" width="120" align="right" />
|
||||
<el-table-column label="尺寸限制" prop="sizeLimit" min-width="140">
|
||||
<template #default="{ row }">
|
||||
<span class="pre-wrap">{{ row.sizeLimit }}</span>
|
||||
@@ -150,7 +152,8 @@
|
||||
ref="importRef"
|
||||
title="产品 Excel 导入"
|
||||
action="/price/product/importData"
|
||||
update-support-label="是否更新已经存在的产品(含国家明细覆盖)"
|
||||
:default-update-support="true"
|
||||
update-support-label="是否更新已经存在的产品主数据(国家/运费明细每次导入都会覆盖)"
|
||||
@success="() => tableRef.refresh()"
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
@click="form.setType = 'FIXED'"
|
||||
>
|
||||
<div class="t-title">FIXED 固定价</div>
|
||||
<div class="t-desc">每个产品×国家×重量段独立配置运费单价 + 挂号费,覆盖默认价</div>
|
||||
<div class="t-desc">可不填明细(走产品默认价);有明细则按产品×国家×重量段覆盖运费+挂号费</div>
|
||||
</div>
|
||||
<div
|
||||
class="type-card"
|
||||
@@ -77,7 +77,7 @@
|
||||
:closable="false"
|
||||
show-icon
|
||||
class="mb12"
|
||||
title="FIXED 模式:每个产品 × 国家 × 重量段独立配置运费单价(RMB/KG)+ 挂号费(RMB/票)。命中时直接取该固定价。"
|
||||
title="FIXED 模式:可不填明细(计费取 bms_product_country 默认运费/挂号费);有明细时按产品×国家×重量段覆盖固定价。"
|
||||
/>
|
||||
<el-alert
|
||||
v-else
|
||||
@@ -88,24 +88,57 @@
|
||||
title="DISCOUNT 模式:可不填明细(全部产品适用默认折扣),或按产品限定折扣范围。"
|
||||
/>
|
||||
<el-table :data="form.details" border empty-text="暂无明细,点击添加明细行">
|
||||
<el-table-column label="产品" min-width="150">
|
||||
<el-table-column label="产品" min-width="180">
|
||||
<template #default="{ row }">
|
||||
<el-select v-model="row.productCode" filterable allow-create placeholder="产品" @change="onProductChange(row)">
|
||||
<el-select
|
||||
v-model="row.productCode"
|
||||
filterable
|
||||
clearable
|
||||
placeholder="选择产品"
|
||||
style="width: 100%"
|
||||
@change="onProductChange(row)"
|
||||
>
|
||||
<el-option v-for="p in productOptions" :key="p.value" :label="p.label" :value="p.value" />
|
||||
</el-select>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column v-if="form.setType === 'FIXED'" label="国家" min-width="130">
|
||||
<el-table-column v-if="form.setType === 'FIXED'" label="国家" min-width="140">
|
||||
<template #default="{ row }">
|
||||
<el-select v-model="row.countryCode" filterable allow-create placeholder="国家" @change="onCountryChange(row)">
|
||||
<el-option v-for="c in countryOptions" :key="c.value" :label="c.label" :value="c.value" />
|
||||
<el-select
|
||||
v-model="row._countryKey"
|
||||
filterable
|
||||
clearable
|
||||
placeholder="选择国家"
|
||||
style="width: 100%"
|
||||
:disabled="!row.productCode"
|
||||
@change="onCountryChange(row)"
|
||||
>
|
||||
<el-option
|
||||
v-for="c in countryOptionsOf(row)"
|
||||
:key="c.key"
|
||||
:label="c.label"
|
||||
:value="c.key"
|
||||
/>
|
||||
</el-select>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column v-if="form.setType === 'FIXED'" label="重量段" min-width="150">
|
||||
<template #default="{ row }">
|
||||
<el-select v-model="row.weightLabel" filterable allow-create placeholder="重量段">
|
||||
<el-option v-for="w in weightOptions" :key="w.value" :label="w.label" :value="w.value" />
|
||||
<el-select
|
||||
v-model="row.weightLabel"
|
||||
filterable
|
||||
clearable
|
||||
placeholder="选择重量段"
|
||||
style="width: 100%"
|
||||
:disabled="!row._countryKey"
|
||||
@change="onWeightChange(row)"
|
||||
>
|
||||
<el-option
|
||||
v-for="w in weightOptionsOf(row)"
|
||||
:key="w.value"
|
||||
:label="w.label"
|
||||
:value="w.value"
|
||||
/>
|
||||
</el-select>
|
||||
</template>
|
||||
</el-table-column>
|
||||
@@ -212,6 +245,7 @@
|
||||
|
||||
<script setup name="PriceSetCreate">
|
||||
import { getPriceSet, savePriceSet, validatePriceSet } from '@/api/price/set'
|
||||
import { listProduct, listProductCountries } from '@/api/price/product'
|
||||
|
||||
const { proxy } = getCurrentInstance()
|
||||
const route = useRoute()
|
||||
@@ -219,25 +253,9 @@ const active = ref(0)
|
||||
const saving = ref(false)
|
||||
const formRef = ref()
|
||||
const checkItems = ref([])
|
||||
|
||||
const productOptions = [
|
||||
{ value: 'WSP037', label: 'WSP037 球衣' },
|
||||
{ value: 'WSP038', label: 'WSP038 普货' },
|
||||
{ value: 'WSP034', label: 'WSP034 带电' },
|
||||
{ value: 'WSP035', label: 'WSP035 敏感' },
|
||||
{ value: 'WSP066', label: 'WSP066 鞋盒' }
|
||||
]
|
||||
const countryOptions = [
|
||||
{ value: 'DE', label: '德国 DE' },
|
||||
{ value: 'FR', label: '法国 FR' },
|
||||
{ value: 'IT', label: '意大利 IT' },
|
||||
{ value: 'ES', label: '西班牙 ES' }
|
||||
]
|
||||
const weightOptions = [
|
||||
{ value: '0.01≤W≤0.3', label: '0.01≤W≤0.3' },
|
||||
{ value: '0.3<W≤1', label: '0.3<W≤1' },
|
||||
{ value: '1<W≤2', label: '1<W≤2' }
|
||||
]
|
||||
const productOptions = ref([])
|
||||
/** productCode -> bms_product_country rows */
|
||||
const countryCache = reactive({})
|
||||
|
||||
const form = reactive({
|
||||
priceSetId: undefined,
|
||||
@@ -257,13 +275,93 @@ const rules = {
|
||||
effectiveDate: [{ required: true, message: '生效日期不能为空', trigger: 'change' }]
|
||||
}
|
||||
|
||||
function trimNum(v) {
|
||||
if (v == null || v === '') return ''
|
||||
const n = Number(v)
|
||||
if (Number.isNaN(n)) return String(v)
|
||||
return String(parseFloat(n.toFixed(6)))
|
||||
}
|
||||
|
||||
function formatWeightLabel(min, max) {
|
||||
return `${trimNum(min)}≤W≤${trimNum(max)}`
|
||||
}
|
||||
|
||||
function countryKeyOf(row) {
|
||||
if (!row) return ''
|
||||
if (row.countryCode) return row.countryCode
|
||||
if (row.countryName) return 'N:' + row.countryName
|
||||
return ''
|
||||
}
|
||||
|
||||
function matchCountry(detail, item) {
|
||||
if (detail.countryCode && item.countryCode) {
|
||||
return detail.countryCode === item.countryCode
|
||||
}
|
||||
return detail.countryName && item.countryName === detail.countryName
|
||||
}
|
||||
|
||||
function loadProducts() {
|
||||
return listProduct({ status: '0', pageNum: 1, pageSize: 1000 }).then(res => {
|
||||
const rows = res.rows || []
|
||||
productOptions.value = rows.map(p => ({
|
||||
value: p.productCode,
|
||||
label: `${p.productCode} ${p.productName || ''}`.trim(),
|
||||
name: p.productName
|
||||
}))
|
||||
})
|
||||
}
|
||||
|
||||
function ensureCountries(productCode) {
|
||||
if (!productCode) return Promise.resolve([])
|
||||
if (countryCache[productCode]) return Promise.resolve(countryCache[productCode])
|
||||
return listProductCountries(productCode).then(res => {
|
||||
const rows = res.data || []
|
||||
countryCache[productCode] = rows
|
||||
return rows
|
||||
})
|
||||
}
|
||||
|
||||
function countryOptionsOf(row) {
|
||||
const rows = countryCache[row.productCode] || []
|
||||
const map = new Map()
|
||||
rows.forEach(item => {
|
||||
const key = countryKeyOf(item)
|
||||
if (!key || map.has(key)) return
|
||||
map.set(key, {
|
||||
key,
|
||||
code: item.countryCode || undefined,
|
||||
name: item.countryName,
|
||||
label: item.countryCode ? `${item.countryName} ${item.countryCode}` : item.countryName
|
||||
})
|
||||
})
|
||||
return [...map.values()]
|
||||
}
|
||||
|
||||
function weightOptionsOf(row) {
|
||||
const rows = (countryCache[row.productCode] || []).filter(item => matchCountry(row, item))
|
||||
const map = new Map()
|
||||
rows.forEach(item => {
|
||||
if (item.weightMin == null && item.weightMax == null) return
|
||||
const value = formatWeightLabel(item.weightMin, item.weightMax)
|
||||
if (map.has(value)) return
|
||||
map.set(value, {
|
||||
value,
|
||||
label: value,
|
||||
freightPrice: item.freightPrice,
|
||||
registrationFee: item.registrationFee
|
||||
})
|
||||
})
|
||||
return [...map.values()]
|
||||
}
|
||||
|
||||
function emptyDetail() {
|
||||
return {
|
||||
productCode: undefined,
|
||||
productName: undefined,
|
||||
countryCode: form.setType === 'FIXED' ? 'DE' : undefined,
|
||||
countryName: form.setType === 'FIXED' ? '德国' : undefined,
|
||||
weightLabel: form.setType === 'FIXED' ? '0.3<W≤1' : undefined,
|
||||
countryCode: undefined,
|
||||
countryName: undefined,
|
||||
_countryKey: undefined,
|
||||
weightLabel: undefined,
|
||||
fvValue: undefined,
|
||||
fvRegistrationFee: undefined,
|
||||
discountValue: undefined
|
||||
@@ -288,22 +386,74 @@ function addCustomerRow() {
|
||||
form.customers.push(emptyCustomer())
|
||||
}
|
||||
|
||||
function clearCascadeAfterProduct(row) {
|
||||
row.countryCode = undefined
|
||||
row.countryName = undefined
|
||||
row._countryKey = undefined
|
||||
row.weightLabel = undefined
|
||||
row.fvValue = undefined
|
||||
row.fvRegistrationFee = undefined
|
||||
}
|
||||
|
||||
function onProductChange(row) {
|
||||
const found = productOptions.find(p => p.value === row.productCode)
|
||||
row.productName = found ? found.label.replace(row.productCode + ' ', '') : row.productCode
|
||||
const found = productOptions.value.find(p => p.value === row.productCode)
|
||||
row.productName = found ? found.name : row.productCode
|
||||
clearCascadeAfterProduct(row)
|
||||
if (!row.productCode || form.setType !== 'FIXED') return
|
||||
ensureCountries(row.productCode)
|
||||
}
|
||||
|
||||
function onCountryChange(row) {
|
||||
const found = countryOptions.find(c => c.value === row.countryCode)
|
||||
row.countryName = found ? found.label.replace(' ' + row.countryCode, '') : row.countryCode
|
||||
const opt = countryOptionsOf(row).find(c => c.key === row._countryKey)
|
||||
row.countryCode = opt ? opt.code : undefined
|
||||
row.countryName = opt ? opt.name : undefined
|
||||
row.weightLabel = undefined
|
||||
row.fvValue = undefined
|
||||
row.fvRegistrationFee = undefined
|
||||
}
|
||||
|
||||
function onWeightChange(row) {
|
||||
const opt = weightOptionsOf(row).find(w => w.value === row.weightLabel)
|
||||
if (!opt) return
|
||||
if (opt.freightPrice != null) row.fvValue = Number(opt.freightPrice)
|
||||
if (opt.registrationFee != null) row.fvRegistrationFee = Number(opt.registrationFee)
|
||||
}
|
||||
|
||||
function hydrateDetailRow(d) {
|
||||
const row = {
|
||||
...d,
|
||||
_countryKey: countryKeyOf(d)
|
||||
}
|
||||
// normalize historical weight labels to min≤W≤max when possible
|
||||
if (row.productCode && form.setType === 'FIXED') {
|
||||
ensureCountries(row.productCode).then(rows => {
|
||||
if (!row.weightLabel) return
|
||||
const hit = rows.find(item => {
|
||||
if (!matchCountry(row, item)) return false
|
||||
return formatWeightLabel(item.weightMin, item.weightMax) === row.weightLabel
|
||||
|| row.weightLabel.includes(String(item.weightMin)) && row.weightLabel.includes(String(item.weightMax))
|
||||
})
|
||||
if (hit) {
|
||||
row.weightLabel = formatWeightLabel(hit.weightMin, hit.weightMax)
|
||||
row._countryKey = countryKeyOf(hit)
|
||||
if (!row.countryCode) row.countryCode = hit.countryCode
|
||||
if (!row.countryName) row.countryName = hit.countryName
|
||||
}
|
||||
})
|
||||
}
|
||||
return row
|
||||
}
|
||||
|
||||
function buildPayload(submitFlag) {
|
||||
const details = (form.details || []).filter(d => d.productCode).map(d => ({
|
||||
...d,
|
||||
productCode: d.productCode,
|
||||
productName: d.productName,
|
||||
countryCode: d.countryCode || undefined,
|
||||
countryName: d.countryName || undefined,
|
||||
weightLabel: d.weightLabel || undefined,
|
||||
fvValue: d.fvValue,
|
||||
fvRegistrationFee: d.fvRegistrationFee
|
||||
fvRegistrationFee: d.fvRegistrationFee,
|
||||
discountValue: d.discountValue
|
||||
}))
|
||||
const customers = (form.customers || [])
|
||||
.filter(c => c.customerId)
|
||||
@@ -392,7 +542,7 @@ function checkTag(result) {
|
||||
}
|
||||
|
||||
function checkLabel(result) {
|
||||
const map = { PASS: '? 通过', WARN: '? 待确认', FAIL: '? 失败', INFO: '? 提示' }
|
||||
const map = { PASS: '通过', WARN: '待确认', FAIL: '失败', INFO: '提示' }
|
||||
return map[result] || result
|
||||
}
|
||||
|
||||
@@ -406,18 +556,20 @@ function loadExisting(id) {
|
||||
form.effectiveDate = data.effectiveDate
|
||||
form.expireDate = data.expireDate
|
||||
form.priceSetNote = data.priceSetNote
|
||||
form.details = (data.details || []).map(d => ({ ...d }))
|
||||
form.details = (data.details || []).map(d => hydrateDetailRow(d))
|
||||
form.customers = (data.customers || []).map(c => ({ ...c }))
|
||||
})
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
const id = route.query.priceSetId
|
||||
if (id) {
|
||||
loadExisting(id)
|
||||
} else {
|
||||
addDetailRow()
|
||||
}
|
||||
loadProducts().finally(() => {
|
||||
const id = route.query.priceSetId
|
||||
if (id) {
|
||||
loadExisting(id)
|
||||
} else {
|
||||
addDetailRow()
|
||||
}
|
||||
})
|
||||
})
|
||||
</script>
|
||||
|
||||
|
||||
@@ -126,21 +126,44 @@
|
||||
|
||||
<el-dialog :title="detailTitle" v-model="detailOpen" width="560px" append-to-body>
|
||||
<el-form ref="detailFormRef" :model="detailForm" :rules="detailRules" label-width="120px">
|
||||
<el-form-item label="产品代码" prop="productCode">
|
||||
<el-input v-model="detailForm.productCode" maxlength="10" />
|
||||
</el-form-item>
|
||||
<el-form-item label="产品名称" prop="productName">
|
||||
<el-input v-model="detailForm.productName" maxlength="50" />
|
||||
<el-form-item label="产品" prop="productCode">
|
||||
<el-select
|
||||
v-model="detailForm.productCode"
|
||||
filterable
|
||||
clearable
|
||||
placeholder="选择产品"
|
||||
style="width: 100%"
|
||||
@change="onDetailProductChange"
|
||||
>
|
||||
<el-option v-for="p in productOptions" :key="p.value" :label="p.label" :value="p.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<template v-if="set.setType === 'FIXED'">
|
||||
<el-form-item label="国家代码" prop="countryCode">
|
||||
<el-input v-model="detailForm.countryCode" maxlength="2" />
|
||||
</el-form-item>
|
||||
<el-form-item label="国家名称" prop="countryName">
|
||||
<el-input v-model="detailForm.countryName" maxlength="50" />
|
||||
<el-form-item label="国家" prop="countryCode">
|
||||
<el-select
|
||||
v-model="detailForm._countryKey"
|
||||
filterable
|
||||
clearable
|
||||
placeholder="选择国家"
|
||||
style="width: 100%"
|
||||
:disabled="!detailForm.productCode"
|
||||
@change="onDetailCountryChange"
|
||||
>
|
||||
<el-option v-for="c in detailCountryOptions" :key="c.key" :label="c.label" :value="c.key" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="重量段" prop="weightLabel">
|
||||
<el-input v-model="detailForm.weightLabel" maxlength="50" />
|
||||
<el-select
|
||||
v-model="detailForm.weightLabel"
|
||||
filterable
|
||||
clearable
|
||||
placeholder="选择重量段"
|
||||
style="width: 100%"
|
||||
:disabled="!detailForm._countryKey"
|
||||
@change="onDetailWeightChange"
|
||||
>
|
||||
<el-option v-for="w in detailWeightOptions" :key="w.value" :label="w.label" :value="w.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="运费单价" prop="fvValue">
|
||||
<el-input-number v-model="detailForm.fvValue" :min="0" :precision="4" controls-position="right" style="width: 100%" />
|
||||
@@ -194,19 +217,22 @@ import {
|
||||
addSetDetail, updateSetDetail, delSetDetail,
|
||||
addSetCustomer, updateSetCustomer, delSetCustomer
|
||||
} from '@/api/price/set'
|
||||
import { listProduct, listProductCountries } from '@/api/price/product'
|
||||
import { parseTime } from '@/utils/ruoyi'
|
||||
|
||||
const { proxy } = getCurrentInstance()
|
||||
const route = useRoute()
|
||||
const loading = ref(false)
|
||||
const set = ref({})
|
||||
const productOptions = ref([])
|
||||
const countryCache = reactive({})
|
||||
|
||||
const detailOpen = ref(false)
|
||||
const detailTitle = ref('')
|
||||
const detailFormRef = ref()
|
||||
const detailForm = ref({})
|
||||
const detailRules = {
|
||||
productCode: [{ required: true, message: '产品代码不能为空', trigger: 'blur' }]
|
||||
productCode: [{ required: true, message: '请选择产品', trigger: 'change' }]
|
||||
}
|
||||
|
||||
const customerOpen = ref(false)
|
||||
@@ -218,6 +244,113 @@ const customerRules = {
|
||||
prBegindate: [{ required: true, message: '生效日期不能为空', trigger: 'change' }]
|
||||
}
|
||||
|
||||
function trimNum(v) {
|
||||
if (v == null || v === '') return ''
|
||||
const n = Number(v)
|
||||
if (Number.isNaN(n)) return String(v)
|
||||
return String(parseFloat(n.toFixed(6)))
|
||||
}
|
||||
|
||||
function formatWeightLabel(min, max) {
|
||||
return `${trimNum(min)}≤W≤${trimNum(max)}`
|
||||
}
|
||||
|
||||
function countryKeyOf(row) {
|
||||
if (!row) return ''
|
||||
if (row.countryCode) return row.countryCode
|
||||
if (row.countryName) return 'N:' + row.countryName
|
||||
return ''
|
||||
}
|
||||
|
||||
function matchCountry(detail, item) {
|
||||
if (detail.countryCode && item.countryCode) return detail.countryCode === item.countryCode
|
||||
return detail.countryName && item.countryName === detail.countryName
|
||||
}
|
||||
|
||||
function ensureCountries(productCode) {
|
||||
if (!productCode) return Promise.resolve([])
|
||||
if (countryCache[productCode]) return Promise.resolve(countryCache[productCode])
|
||||
return listProductCountries(productCode).then(res => {
|
||||
const rows = res.data || []
|
||||
countryCache[productCode] = rows
|
||||
return rows
|
||||
})
|
||||
}
|
||||
|
||||
const detailCountryOptions = computed(() => {
|
||||
const rows = countryCache[detailForm.value.productCode] || []
|
||||
const map = new Map()
|
||||
rows.forEach(item => {
|
||||
const key = countryKeyOf(item)
|
||||
if (!key || map.has(key)) return
|
||||
map.set(key, {
|
||||
key,
|
||||
code: item.countryCode || undefined,
|
||||
name: item.countryName,
|
||||
label: item.countryCode ? `${item.countryName} ${item.countryCode}` : item.countryName
|
||||
})
|
||||
})
|
||||
return [...map.values()]
|
||||
})
|
||||
|
||||
const detailWeightOptions = computed(() => {
|
||||
const form = detailForm.value
|
||||
const rows = (countryCache[form.productCode] || []).filter(item => matchCountry(form, item))
|
||||
const map = new Map()
|
||||
rows.forEach(item => {
|
||||
if (item.weightMin == null && item.weightMax == null) return
|
||||
const value = formatWeightLabel(item.weightMin, item.weightMax)
|
||||
if (map.has(value)) return
|
||||
map.set(value, {
|
||||
value,
|
||||
label: value,
|
||||
freightPrice: item.freightPrice,
|
||||
registrationFee: item.registrationFee
|
||||
})
|
||||
})
|
||||
return [...map.values()]
|
||||
})
|
||||
|
||||
function loadProducts() {
|
||||
listProduct({ status: '0', pageNum: 1, pageSize: 1000 }).then(res => {
|
||||
productOptions.value = (res.rows || []).map(p => ({
|
||||
value: p.productCode,
|
||||
label: `${p.productCode} ${p.productName || ''}`.trim(),
|
||||
name: p.productName
|
||||
}))
|
||||
})
|
||||
}
|
||||
|
||||
function onDetailProductChange() {
|
||||
const found = productOptions.value.find(p => p.value === detailForm.value.productCode)
|
||||
detailForm.value.productName = found ? found.name : detailForm.value.productCode
|
||||
detailForm.value.countryCode = undefined
|
||||
detailForm.value.countryName = undefined
|
||||
detailForm.value._countryKey = undefined
|
||||
detailForm.value.weightLabel = undefined
|
||||
detailForm.value.fvValue = undefined
|
||||
detailForm.value.fvRegistrationFee = undefined
|
||||
if (detailForm.value.productCode && set.value.setType === 'FIXED') {
|
||||
ensureCountries(detailForm.value.productCode)
|
||||
}
|
||||
}
|
||||
|
||||
function onDetailCountryChange() {
|
||||
const opt = detailCountryOptions.value.find(c => c.key === detailForm.value._countryKey)
|
||||
detailForm.value.countryCode = opt ? opt.code : undefined
|
||||
detailForm.value.countryName = opt ? opt.name : undefined
|
||||
detailForm.value.weightLabel = undefined
|
||||
detailForm.value.fvValue = undefined
|
||||
detailForm.value.fvRegistrationFee = undefined
|
||||
}
|
||||
|
||||
function onDetailWeightChange() {
|
||||
const opt = detailWeightOptions.value.find(w => w.value === detailForm.value.weightLabel)
|
||||
if (!opt) return
|
||||
if (opt.freightPrice != null) detailForm.value.fvValue = Number(opt.freightPrice)
|
||||
if (opt.registrationFee != null) detailForm.value.fvRegistrationFee = Number(opt.registrationFee)
|
||||
}
|
||||
|
||||
const childEditable = computed(() => ['D', 'R', 'E'].includes(set.value.status))
|
||||
|
||||
const statusLabel = computed(() => {
|
||||
@@ -296,12 +429,16 @@ function onCopy() {
|
||||
}
|
||||
|
||||
function openDetailDialog(row) {
|
||||
detailForm.value = row ? { ...row } : {
|
||||
detailForm.value = row ? {
|
||||
...row,
|
||||
_countryKey: countryKeyOf(row)
|
||||
} : {
|
||||
priceSetId: set.value.priceSetId,
|
||||
productCode: undefined,
|
||||
productName: undefined,
|
||||
countryCode: undefined,
|
||||
countryName: undefined,
|
||||
_countryKey: undefined,
|
||||
weightLabel: undefined,
|
||||
fvValue: undefined,
|
||||
fvRegistrationFee: undefined,
|
||||
@@ -309,12 +446,19 @@ function openDetailDialog(row) {
|
||||
}
|
||||
detailTitle.value = row ? '编辑明细' : '添加明细'
|
||||
detailOpen.value = true
|
||||
if (detailForm.value.productCode && set.value.setType === 'FIXED') {
|
||||
ensureCountries(detailForm.value.productCode)
|
||||
}
|
||||
}
|
||||
|
||||
function submitDetail() {
|
||||
proxy.$refs['detailFormRef'].validate(valid => {
|
||||
if (!valid) return
|
||||
const payload = { ...detailForm.value, priceSetId: set.value.priceSetId }
|
||||
const payload = {
|
||||
...detailForm.value,
|
||||
priceSetId: set.value.priceSetId
|
||||
}
|
||||
delete payload._countryKey
|
||||
const req = payload.psdId ? updateSetDetail(payload) : addSetDetail(payload)
|
||||
req.then(() => {
|
||||
proxy.$modal.msgSuccess('保存成功')
|
||||
@@ -369,6 +513,7 @@ function removeCustomer(row) {
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
loadProducts()
|
||||
load()
|
||||
})
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user