应付配置的附加费配置完善
This commit is contained in:
@@ -172,21 +172,21 @@ export function delPay(productIds) {
|
||||
})
|
||||
}
|
||||
|
||||
/** 当前版本的附加费计费条件 */
|
||||
export function listPaySurchargeRule(productId, termId) {
|
||||
/** 产品上的附加费计费条件,不按价格版本拆开 */
|
||||
export function listPaySurchargeRule(productId) {
|
||||
return request({
|
||||
url: '/price/pay/surchargeRule',
|
||||
method: 'get',
|
||||
params: { productId, termId }
|
||||
params: { productId }
|
||||
})
|
||||
}
|
||||
|
||||
/** 上一版计费条件,复制到当前页编辑 */
|
||||
export function previousPaySurchargeRule(productId) {
|
||||
/** 这一版产品上的附加费配置操作记录 */
|
||||
export function listPaySurchargeRuleLog(productId, termId) {
|
||||
return request({
|
||||
url: '/price/pay/surchargeRule/previous',
|
||||
url: '/price/pay/surchargeRule/log',
|
||||
method: 'get',
|
||||
params: { productId }
|
||||
params: { productId, termId }
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -74,6 +74,7 @@
|
||||
:size="size"
|
||||
:height="height"
|
||||
:max-height="maxHeight"
|
||||
:scrollbar-always-on="scrollbarAlwaysOn"
|
||||
:default-sort="defaultSort"
|
||||
:span-method="spanMethod"
|
||||
@selection-change="handleSelectionChange"
|
||||
@@ -291,6 +292,8 @@ const props = defineProps({
|
||||
// 表格高度
|
||||
height: { type: [String, Number], default: undefined },
|
||||
maxHeight: { type: [String, Number], default: undefined },
|
||||
// 横向、纵向滚动条一直显示
|
||||
scrollbarAlwaysOn: { type: Boolean, default: false },
|
||||
// 默认排序(透传 el-table default-sort,如 { prop: 'createTime', order: 'descending' })
|
||||
defaultSort: {
|
||||
type: Object,
|
||||
|
||||
@@ -78,6 +78,14 @@
|
||||
<el-tab-pane :label="feeTabLabel(pane)" name="fee">
|
||||
<div class="pay-edit-bar">
|
||||
<el-input v-model="pane.feeKeyword" clearable placeholder="筛选附加费用、地区、价格、货币或费用解释" class="pay-filter" @input="pane.feePageNo = 1" />
|
||||
<el-select v-model="pane.feeBill" clearable placeholder="计费条件" class="pay-bill-filter" @change="pane.feePageNo = 1">
|
||||
<el-option label="需要计费" value="BILL">
|
||||
<span class="bill-need-text">需要计费</span>
|
||||
</el-option>
|
||||
<el-option label="暂不计费" value="MANUAL">
|
||||
<span class="bill-hold-text">暂不计费</span>
|
||||
</el-option>
|
||||
</el-select>
|
||||
<el-button v-if="editable" size="small" type="primary" plain @click="openFeePicker(pane)">添加附加费</el-button>
|
||||
<el-button
|
||||
v-if="editable"
|
||||
@@ -101,7 +109,7 @@
|
||||
<el-checkbox :model-value="row._checked === true" @update:model-value="v => { row._checked = !!v }" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="feeName" label="附加费用" min-width="180" show-overflow-tooltip>
|
||||
<el-table-column prop="feeName" label="附加费用" min-width="180" show-overflow-tooltip fixed="left">
|
||||
<template #default="{ row }">
|
||||
<el-select
|
||||
v-if="isRowEditing(row)"
|
||||
@@ -189,13 +197,25 @@
|
||||
<el-table-column prop="feeDesc" label="费用解释" min-width="240" show-overflow-tooltip>
|
||||
<template #default="{ row }"><cell-text v-model="row.feeDesc" :edit="isRowEditing(row)" /></template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="calcRule" label="计费条件" width="140">
|
||||
<el-table-column prop="calcRule" label="计费条件" width="140" align="center">
|
||||
<template #default="{ row }">
|
||||
<el-select v-if="isRowEditing(row)" :model-value="feeBillFlag(row)" size="small" @change="value => setFeeBill(row, value)">
|
||||
<el-option label="需要计费" value="BILL" />
|
||||
<el-option label="暂不计费" value="MANUAL" />
|
||||
<el-select
|
||||
v-if="isRowEditing(row)"
|
||||
:model-value="feeBillFlag(row)"
|
||||
size="small"
|
||||
:class="feeBillFlag(row) === 'BILL' ? 'bill-need' : 'bill-hold'"
|
||||
@change="value => setFeeBill(row, value)"
|
||||
>
|
||||
<el-option label="需要计费" value="BILL">
|
||||
<span class="bill-need-text">需要计费</span>
|
||||
</el-option>
|
||||
<el-option label="暂不计费" value="MANUAL">
|
||||
<span class="bill-hold-text">暂不计费</span>
|
||||
</el-option>
|
||||
</el-select>
|
||||
<span v-else>{{ feeBillFlag(row) === 'BILL' ? '需要计费' : '暂不计费' }}</span>
|
||||
<el-tag v-else :type="feeBillFlag(row) === 'BILL' ? 'success' : 'danger'" size="small" effect="light">
|
||||
{{ feeBillFlag(row) === 'BILL' ? '需要计费' : '暂不计费' }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column v-if="editable" label="操作" width="120" align="center" fixed="right">
|
||||
@@ -483,6 +503,7 @@ watch(source, (list) => {
|
||||
tab: 'band',
|
||||
bandKeyword: '',
|
||||
feeKeyword: '',
|
||||
feeBill: '',
|
||||
postKeyword: '',
|
||||
bandPageNo: 1,
|
||||
feePageNo: 1,
|
||||
@@ -495,7 +516,9 @@ function filteredBands(pane) {
|
||||
}
|
||||
|
||||
function filteredFees(pane) {
|
||||
return filterRows(pane.item.surcharges || [], pane.feeKeyword, ['feeName', 'zoneName', 'chargeText', 'amount', 'currency', 'priceUnit', 'feeDesc', 'calcRule', 'calcParam', 'postcodeParam'])
|
||||
const rows = filterRows(pane.item.surcharges || [], pane.feeKeyword, ['feeName', 'zoneName', 'chargeText', 'amount', 'currency', 'priceUnit', 'feeDesc', 'calcRule', 'calcParam', 'postcodeParam'])
|
||||
if (!pane.feeBill) return rows
|
||||
return rows.filter(row => feeBillFlag(row) === pane.feeBill)
|
||||
}
|
||||
|
||||
function feeTabLabel(pane) {
|
||||
@@ -721,6 +744,9 @@ function statusText(status) {
|
||||
.pay-filter {
|
||||
width: 320px;
|
||||
}
|
||||
.pay-bill-filter {
|
||||
width: 140px;
|
||||
}
|
||||
.pay-edit-bar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@@ -745,4 +771,16 @@ function statusText(status) {
|
||||
.limit-tag {
|
||||
margin-right: 6px;
|
||||
}
|
||||
.bill-need :deep(.el-select__selected-item) {
|
||||
color: var(--el-color-success);
|
||||
}
|
||||
.bill-hold :deep(.el-select__selected-item) {
|
||||
color: var(--el-color-danger);
|
||||
}
|
||||
.bill-need-text {
|
||||
color: var(--el-color-success);
|
||||
}
|
||||
.bill-hold-text {
|
||||
color: var(--el-color-danger);
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<div class="rule-title">绑定产品</div>
|
||||
<div class="rule-products">
|
||||
<el-tag v-for="item in products" :key="item.key" closable class="rule-tag" @close="removeProduct(item)">
|
||||
{{ item.productName }} · 第 {{ item.versionNo || 1 }} 版
|
||||
{{ item.productName }}
|
||||
</el-tag>
|
||||
<span v-if="!products.length" class="rule-empty">还没有产品。勾选列表后打开,或在下面查询后加入。</span>
|
||||
</div>
|
||||
@@ -25,7 +25,7 @@
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<p class="rule-hint">配置写到每个产品当前生效的版本。同一版本再次保存会覆盖原来的一份。</p>
|
||||
<p class="rule-hint">配置跟产品走,不跟价格版本。计算时用这个产品当前生效版本上的附加费。</p>
|
||||
</div>
|
||||
|
||||
<div class="rule-block">
|
||||
@@ -36,8 +36,6 @@
|
||||
<el-switch v-model="enabled[rule.value]" @change="value => toggleRule(rule.value, value)" />
|
||||
</div>
|
||||
</div>
|
||||
<p v-if="enabled.POSTCODE" class="rule-hint">打开后,用订单目的国去应付邮编配置里对国家和邮编。邮编前缀和完整邮编都会判断,命中偏远或岛屿才加这笔附加费。</p>
|
||||
<p v-if="enabled.ZONE" class="rule-hint">打开后,用订单目的国和邮编去应付邮编配置里对上分区,再加这一档附加费。</p>
|
||||
</div>
|
||||
|
||||
<div v-for="rule in openedRules" :key="rule.value" class="rule-block">
|
||||
@@ -55,209 +53,310 @@
|
||||
<div v-if="rule.value === 'SIZE'" class="rule-grid">
|
||||
<div class="field">
|
||||
<span class="label">命中方式</span>
|
||||
<el-select v-model="row.matchMode" size="small">
|
||||
<el-option label="任一命中" value="ANY" />
|
||||
<el-option label="全部命中" value="ALL" />
|
||||
</el-select>
|
||||
<div class="control">
|
||||
<el-select v-model="row.matchMode" size="small">
|
||||
<el-option label="任一命中" value="ANY" />
|
||||
<el-option label="全部命中" value="ALL" />
|
||||
</el-select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<span class="label">重量前提 kg</span>
|
||||
<el-input v-model="row.weightMin" size="small" placeholder="下限" />
|
||||
<span class="sep">至</span>
|
||||
<el-input v-model="row.weightMax" size="small" placeholder="上限" />
|
||||
<div class="control">
|
||||
<el-input v-model="row.weightMin" size="small" placeholder="下限" />
|
||||
<span class="sep">至</span>
|
||||
<el-input v-model="row.weightMax" size="small" placeholder="上限" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<span class="label">最长边 cm</span>
|
||||
<el-input v-model="row.longestMin" size="small" placeholder="下限" />
|
||||
<span class="sep">至</span>
|
||||
<el-input v-model="row.longestMax" size="small" placeholder="上限" />
|
||||
<div class="control">
|
||||
<el-input v-model="row.longestMin" size="small" placeholder="下限" />
|
||||
<span class="sep">至</span>
|
||||
<el-input v-model="row.longestMax" size="small" placeholder="上限" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<span class="label">次长边 cm</span>
|
||||
<el-input v-model="row.secondMin" size="small" placeholder="下限" />
|
||||
<span class="sep">至</span>
|
||||
<el-input v-model="row.secondMax" size="small" placeholder="上限" />
|
||||
<div class="control">
|
||||
<el-input v-model="row.secondMin" size="small" placeholder="下限" />
|
||||
<span class="sep">至</span>
|
||||
<el-input v-model="row.secondMax" size="small" placeholder="上限" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<span class="label">三边之和 cm</span>
|
||||
<el-input v-model="row.sumMin" size="small" placeholder="下限" />
|
||||
<span class="sep">至</span>
|
||||
<el-input v-model="row.sumMax" size="small" placeholder="上限" />
|
||||
<div class="control">
|
||||
<el-input v-model="row.sumMin" size="small" placeholder="下限" />
|
||||
<span class="sep">至</span>
|
||||
<el-input v-model="row.sumMax" size="small" placeholder="上限" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<span class="label">围长 cm</span>
|
||||
<el-input v-model="row.girthMin" size="small" placeholder="下限" />
|
||||
<span class="sep">至</span>
|
||||
<el-input v-model="row.girthMax" size="small" placeholder="上限" />
|
||||
<div class="control">
|
||||
<el-input v-model="row.girthMin" size="small" placeholder="下限" />
|
||||
<span class="sep">至</span>
|
||||
<el-input v-model="row.girthMax" size="small" placeholder="上限" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<span class="label">箱规 cm</span>
|
||||
<el-select v-model="row.boxMode" size="small" class="mode">
|
||||
<el-option label="任一边超过" value="OVER" />
|
||||
<el-option label="小于最小尺寸" value="UNDER" />
|
||||
</el-select>
|
||||
<el-input v-model="row.boxLength" size="small" placeholder="长" />
|
||||
<el-input v-model="row.boxWidth" size="small" placeholder="宽" />
|
||||
<el-input v-model="row.boxHeight" size="small" placeholder="高" />
|
||||
<div class="control">
|
||||
<el-select v-model="row.boxMode" size="small" class="mode">
|
||||
<el-option label="任一边超过" value="OVER" />
|
||||
<el-option label="小于最小尺寸" value="UNDER" />
|
||||
</el-select>
|
||||
<el-input v-model="row.boxLength" class="num" size="small" placeholder="长" />
|
||||
<el-input v-model="row.boxWidth" class="num" size="small" placeholder="宽" />
|
||||
<el-input v-model="row.boxHeight" class="num" size="small" placeholder="高" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<span class="label">体积 m³</span>
|
||||
<el-input v-model="row.volumeMin" size="small" placeholder="下限" />
|
||||
<span class="sep">至</span>
|
||||
<el-input v-model="row.volumeMax" size="small" placeholder="上限" />
|
||||
<div class="control">
|
||||
<el-input v-model="row.volumeMin" size="small" placeholder="下限" />
|
||||
<span class="sep">至</span>
|
||||
<el-input v-model="row.volumeMax" size="small" placeholder="上限" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<span class="label">长×宽×高上限 cm³</span>
|
||||
<el-input v-model="row.cubicMax" size="small" placeholder="例如 432000" />
|
||||
<div class="control">
|
||||
<el-input v-model="row.cubicMax" size="small" placeholder="例如 432000" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<span class="label">每超出 cm</span>
|
||||
<el-input v-model="row.exceedStepCm" size="small" placeholder="例如 10" />
|
||||
<div class="control">
|
||||
<el-input v-model="row.exceedStepCm" size="small" placeholder="例如 10" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<span class="label">运费加收比例 %</span>
|
||||
<el-input v-model="row.exceedRatio" size="small" placeholder="例如 35" />
|
||||
<div class="control">
|
||||
<el-input v-model="row.exceedRatio" size="small" placeholder="例如 35" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="field span-2">
|
||||
<div class="field">
|
||||
<span class="label">说明</span>
|
||||
<el-input v-model="row.remark" size="small" placeholder="这一档的补充说明" />
|
||||
<div class="control">
|
||||
<el-input v-model="row.remark" size="small" placeholder="这一档的补充说明" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-else-if="rule.value === 'WEIGHT'" class="rule-grid">
|
||||
<div class="field">
|
||||
<span class="label">重量 kg</span>
|
||||
<el-input v-model="row.weightMin" size="small" placeholder="下限" />
|
||||
<span class="sep">至</span>
|
||||
<el-input v-model="row.weightMax" size="small" placeholder="上限" />
|
||||
<div class="control">
|
||||
<el-input v-model="row.weightMin" size="small" placeholder="下限" />
|
||||
<span class="sep">至</span>
|
||||
<el-input v-model="row.weightMax" size="small" placeholder="上限" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<span class="label">重量口径</span>
|
||||
<el-select v-model="row.weightBasis" size="small">
|
||||
<el-option label="实重" value="ACTUAL" />
|
||||
<el-option label="计费重" value="CHARGE" />
|
||||
</el-select>
|
||||
<div class="control">
|
||||
<el-select v-model="row.weightBasis" size="small">
|
||||
<el-option label="实重" value="ACTUAL" />
|
||||
<el-option label="计费重" value="CHARGE" />
|
||||
</el-select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<span class="label">每超出 kg</span>
|
||||
<el-input v-model="row.stepKg" size="small" placeholder="超过上限后按每公斤" />
|
||||
<div class="control">
|
||||
<el-input v-model="row.stepKg" size="small" placeholder="超过上限后按每公斤" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<span class="label">最低消费</span>
|
||||
<el-input v-model="row.minCharge" size="small" placeholder="没有就空着" />
|
||||
<div class="control">
|
||||
<el-input v-model="row.minCharge" size="small" placeholder="没有就空着" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<span class="label">运费加收比例 %</span>
|
||||
<el-input v-model="row.exceedRatio" size="small" placeholder="按运费比例加收时填写" />
|
||||
<div class="control">
|
||||
<el-input v-model="row.exceedRatio" size="small" placeholder="按运费比例加收时填写" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<span class="label">说明</span>
|
||||
<el-input v-model="row.remark" size="small" />
|
||||
<div class="control">
|
||||
<el-input v-model="row.remark" size="small" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-else-if="rule.value === 'EXTRA_KG'" class="rule-grid">
|
||||
<div class="field">
|
||||
<span class="label">超过 kg</span>
|
||||
<el-input v-model="row.thresholdKg" size="small" placeholder="超过这个重量后开始续收" />
|
||||
<div class="control">
|
||||
<el-input v-model="row.thresholdKg" size="small" placeholder="超过这个重量后开始续收" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<span class="label">每超出 kg</span>
|
||||
<el-input v-model="row.stepKg" size="small" placeholder="例如 1" />
|
||||
<div class="control">
|
||||
<el-input v-model="row.stepKg" size="small" placeholder="例如 1" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<span class="label">重量口径</span>
|
||||
<el-select v-model="row.weightBasis" size="small">
|
||||
<el-option label="实重" value="ACTUAL" />
|
||||
<el-option label="计费重" value="CHARGE" />
|
||||
</el-select>
|
||||
<div class="control">
|
||||
<el-select v-model="row.weightBasis" size="small">
|
||||
<el-option label="实重" value="ACTUAL" />
|
||||
<el-option label="计费重" value="CHARGE" />
|
||||
</el-select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<span class="label">最低消费</span>
|
||||
<el-input v-model="row.minCharge" size="small" placeholder="例如 17.5" />
|
||||
<div class="control">
|
||||
<el-input v-model="row.minCharge" size="small" placeholder="例如 17.5" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="field span-2">
|
||||
<div class="field">
|
||||
<span class="label">邮编</span>
|
||||
<el-input v-model="row.postcodes" size="small" type="textarea" :rows="2" placeholder="续收还要限定邮编时填写,支持 KA27-28 这种区间" />
|
||||
<div class="control">
|
||||
<el-input v-model="row.postcodes" size="small" type="textarea" :rows="2" placeholder="续收还要限定邮编时填写,支持 KA27-28 这种区间" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-else-if="rule.value === 'POSTCODE' || rule.value === 'ZONE'" class="rule-grid">
|
||||
<div class="field">
|
||||
<span class="label">分区</span>
|
||||
<div class="control">
|
||||
<el-select v-model="row.zoneName" filterable size="small" placeholder="选择附加费里的高、中、低区">
|
||||
<el-option v-for="zone in zoneOptions" :key="zone" :label="zone" :value="zone" />
|
||||
</el-select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<span class="label">邮编前缀</span>
|
||||
<div class="control">
|
||||
<el-input v-model="row.postcodes" size="small" type="textarea" :rows="2" placeholder="多个用逗号或换行。前缀、完整邮编、1000-1099、KA27-28 都可以" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<span class="label">国家</span>
|
||||
<div class="control">
|
||||
<el-input v-model="row.country" size="small" placeholder="不填则不限,例如 DE 或 德国" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-else-if="rule.value === 'ALWAYS'" class="rule-grid">
|
||||
<div class="field">
|
||||
<span class="label">费用项</span>
|
||||
<div class="control">
|
||||
<el-select v-model="row.feeName" filterable size="small" placeholder="选择这一条要每票收取的费用" @change="(name) => pickFee(row, name)">
|
||||
<el-option v-for="item in feeOptions" :key="item.feeName" :label="item.feeName" :value="item.feeName" />
|
||||
</el-select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<span class="label">计费方式</span>
|
||||
<el-select v-model="row.rateMode" size="small">
|
||||
<el-option label="固定金额" value="FIXED" />
|
||||
<el-option label="按比例" value="RATIO" />
|
||||
</el-select>
|
||||
<div class="control">
|
||||
<el-select v-model="row.rateMode" size="small">
|
||||
<el-option label="固定金额" value="FIXED" />
|
||||
<el-option label="按比例" value="RATIO" />
|
||||
</el-select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<span class="label">比例 %</span>
|
||||
<el-input v-model="row.ratio" size="small" placeholder="燃油、战争附加费这类" />
|
||||
<div class="control">
|
||||
<el-input v-model="row.ratio" size="small" placeholder="燃油、战争附加费这类" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<span class="label">计费基数</span>
|
||||
<el-select v-model="row.chargeBase" size="small" clearable placeholder="按比例时选择">
|
||||
<el-option label="处理费" value="HANDLE" />
|
||||
<el-option label="派送费" value="DELIVERY" />
|
||||
<el-option label="运费加附加费" value="FREIGHT_FEE" />
|
||||
</el-select>
|
||||
<div class="control">
|
||||
<el-select v-model="row.chargeBase" size="small" clearable placeholder="按比例时选择">
|
||||
<el-option label="处理费" value="HANDLE" />
|
||||
<el-option label="派送费" value="DELIVERY" />
|
||||
<el-option label="运费加附加费" value="FREIGHT_FEE" />
|
||||
</el-select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<span class="label">生效日期</span>
|
||||
<el-input v-model="row.periodStart" size="small" placeholder="开始,如 11-01" />
|
||||
<span class="sep">至</span>
|
||||
<el-input v-model="row.periodEnd" size="small" placeholder="结束,如 12-23" />
|
||||
<div class="control">
|
||||
<el-date-picker v-model="row.periodStart" type="date" value-format="YYYY-MM-DD" placeholder="开始日期" size="small" clearable />
|
||||
<span class="sep">至</span>
|
||||
<el-date-picker v-model="row.periodEnd" type="date" value-format="YYYY-MM-DD" placeholder="结束日期" size="small" clearable />
|
||||
</div>
|
||||
</div>
|
||||
<div class="field span-2">
|
||||
<div class="field">
|
||||
<span class="label">说明</span>
|
||||
<el-input v-model="row.remark" size="small" placeholder="例如每年 11、12 月固定收取" />
|
||||
<div class="control">
|
||||
<el-input v-model="row.remark" size="small" placeholder="例如每年 11、12 月固定收取" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-else class="rule-grid">
|
||||
<div class="field">
|
||||
<span class="label">退回方式</span>
|
||||
<el-select v-model="row.chargeMode" size="small">
|
||||
<el-option label="同正向运费" value="SAME" />
|
||||
<el-option label="空运退回" value="AIR" />
|
||||
<el-option label="陆运退回" value="ROAD" />
|
||||
<el-option label="固定金额" value="FIXED" />
|
||||
</el-select>
|
||||
<div class="control">
|
||||
<el-select v-model="row.chargeMode" size="small">
|
||||
<el-option label="同正向运费" value="SAME" />
|
||||
<el-option label="空运退回" value="AIR" />
|
||||
<el-option label="陆运退回" value="ROAD" />
|
||||
<el-option label="固定金额" value="FIXED" />
|
||||
</el-select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<span class="label">重量 kg</span>
|
||||
<el-input v-model="row.weightMin" size="small" placeholder="下限" />
|
||||
<span class="sep">至</span>
|
||||
<el-input v-model="row.weightMax" size="small" placeholder="上限" />
|
||||
<div class="control">
|
||||
<el-input v-model="row.weightMin" size="small" placeholder="下限" />
|
||||
<span class="sep">至</span>
|
||||
<el-input v-model="row.weightMax" size="small" placeholder="上限" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<span class="label">尺寸命中</span>
|
||||
<el-select v-model="row.matchMode" size="small" clearable placeholder="退件还看尺寸时选择">
|
||||
<el-option label="任一命中" value="ANY" />
|
||||
<el-option label="全部命中" value="ALL" />
|
||||
</el-select>
|
||||
<div class="control">
|
||||
<el-select v-model="row.matchMode" size="small" clearable placeholder="退件还看尺寸时选择">
|
||||
<el-option label="任一命中" value="ANY" />
|
||||
<el-option label="全部命中" value="ALL" />
|
||||
</el-select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<span class="label">最长边 cm</span>
|
||||
<el-input v-model="row.longestMin" size="small" placeholder="下限" />
|
||||
<span class="sep">至</span>
|
||||
<el-input v-model="row.longestMax" size="small" placeholder="上限" />
|
||||
<div class="control">
|
||||
<el-input v-model="row.longestMin" size="small" placeholder="下限" />
|
||||
<span class="sep">至</span>
|
||||
<el-input v-model="row.longestMax" size="small" placeholder="上限" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<span class="label">围长 cm</span>
|
||||
<el-input v-model="row.girthMin" size="small" placeholder="下限" />
|
||||
<span class="sep">至</span>
|
||||
<el-input v-model="row.girthMax" size="small" placeholder="上限" />
|
||||
<div class="control">
|
||||
<el-input v-model="row.girthMin" size="small" placeholder="下限" />
|
||||
<span class="sep">至</span>
|
||||
<el-input v-model="row.girthMax" size="small" placeholder="上限" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<span class="label">三边之和 cm</span>
|
||||
<el-input v-model="row.sumMin" size="small" placeholder="下限" />
|
||||
<span class="sep">至</span>
|
||||
<el-input v-model="row.sumMax" size="small" placeholder="上限" />
|
||||
<div class="control">
|
||||
<el-input v-model="row.sumMin" size="small" placeholder="下限" />
|
||||
<span class="sep">至</span>
|
||||
<el-input v-model="row.sumMax" size="small" placeholder="上限" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="field span-2">
|
||||
<div class="field">
|
||||
<span class="label">说明</span>
|
||||
<el-input v-model="row.remark" size="small" placeholder="例如拒收、地址错误退回" />
|
||||
<div class="control">
|
||||
<el-input v-model="row.remark" size="small" placeholder="例如拒收、地址错误退回" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -265,7 +364,6 @@
|
||||
</div>
|
||||
|
||||
<template #footer>
|
||||
<el-button :disabled="!products.length" :loading="copying" @click="copyPrevious">复制上一版本</el-button>
|
||||
<el-button @click="visible = false">取消</el-button>
|
||||
<el-button type="primary" :loading="saving" @click="save">保存</el-button>
|
||||
</template>
|
||||
@@ -273,7 +371,7 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { listPay, listPaySurchargeRule, previousPaySurchargeRule, savePaySurchargeRule } from '@/api/price/pay'
|
||||
import { getPay, listPay, listPaySurchargeRule, savePaySurchargeRule } from '@/api/price/pay'
|
||||
|
||||
const { proxy } = getCurrentInstance()
|
||||
|
||||
@@ -293,12 +391,20 @@ const ruleDefs = [
|
||||
label: '超重续收',
|
||||
hint: '超过某个重量后只收超出部分。偏远按公斤且有最低消费的,把邮编和最低消费写在这一条。'
|
||||
},
|
||||
{ value: 'POSTCODE', label: '命中邮编', switchOnly: true },
|
||||
{ value: 'ZONE', label: '命中分区', switchOnly: true },
|
||||
{
|
||||
value: 'POSTCODE',
|
||||
label: '命中邮编',
|
||||
hint: '按附加费里的高、中、低区填写邮编前缀。订单邮编命中这一区,才加这一区的附加费。前缀、完整邮编和区间都认。国家不填则不限目的国。'
|
||||
},
|
||||
{
|
||||
value: 'ZONE',
|
||||
label: '命中分区',
|
||||
hint: '写法和命中邮编一样,表示这些邮编属于哪个地区。命中后按该地区的附加费收取。运费用的地区仍按应付邮编配置。'
|
||||
},
|
||||
{
|
||||
value: 'ALWAYS',
|
||||
label: '每票都收',
|
||||
hint: '燃油、去碳、道路通行、旺季这类。按比例的填写比例和基数,旺季填写生效日期。'
|
||||
hint: '每一条都要选费用项,没被选中的费用不会按每票收取。燃油、去碳按比例填写比例和基数,旺季再填生效日期。'
|
||||
},
|
||||
{
|
||||
value: 'RETURN',
|
||||
@@ -309,11 +415,12 @@ const ruleDefs = [
|
||||
|
||||
const visible = ref(false)
|
||||
const saving = ref(false)
|
||||
const copying = ref(false)
|
||||
const searching = ref(false)
|
||||
const keyword = ref('')
|
||||
const found = ref([])
|
||||
const products = ref([])
|
||||
const feeOptions = ref([])
|
||||
const zoneOptions = ref([])
|
||||
const enabled = reactive({})
|
||||
const groups = reactive({})
|
||||
|
||||
@@ -327,8 +434,11 @@ function blank(rule) {
|
||||
if (rule === 'EXTRA_KG') {
|
||||
return { thresholdKg: '', stepKg: '1', weightBasis: 'ACTUAL', minCharge: '', postcodes: '' }
|
||||
}
|
||||
if (rule === 'POSTCODE' || rule === 'ZONE') {
|
||||
return { zoneName: '', postcodes: '', country: '' }
|
||||
}
|
||||
if (rule === 'ALWAYS') {
|
||||
return { rateMode: 'FIXED', ratio: '', chargeBase: '', periodStart: '', periodEnd: '', remark: '' }
|
||||
return { feeName: '', scId: '', rateMode: 'FIXED', ratio: '', chargeBase: '', periodStart: '', periodEnd: '', remark: '' }
|
||||
}
|
||||
return { chargeMode: 'SAME', weightMin: '', weightMax: '', matchMode: '', longestMin: '', longestMax: '', girthMin: '', girthMax: '', sumMin: '', sumMax: '', remark: '' }
|
||||
}
|
||||
@@ -344,9 +454,10 @@ function reset() {
|
||||
keyword.value = ''
|
||||
found.value = []
|
||||
products.value = []
|
||||
feeOptions.value = []
|
||||
zoneOptions.value = []
|
||||
blankGroups()
|
||||
saving.value = false
|
||||
copying.value = false
|
||||
searching.value = false
|
||||
}
|
||||
|
||||
@@ -357,32 +468,82 @@ function open(rows) {
|
||||
for (const row of rows || []) addProduct(row, skipped)
|
||||
if (skipped.length) proxy.$modal.msgWarning('有产品还没有生效版本,未带入:' + skipped.join('、'))
|
||||
const first = products.value[0]
|
||||
if (first) loadRules(first.productId, first.termId)
|
||||
if (first) loadRules(first.productId)
|
||||
}
|
||||
|
||||
function versionOf(row) {
|
||||
return {
|
||||
key: String(row.versionProductId || row.productId) + ':' + String(row.termId || ''),
|
||||
productId: row.versionProductId || row.productId,
|
||||
termId: row.termId,
|
||||
versionNo: row.versionNo,
|
||||
key: String(row.productId),
|
||||
productId: row.productId,
|
||||
feeProductId: row.versionProductId || row.productId,
|
||||
productName: row.productName || '未命名产品'
|
||||
}
|
||||
}
|
||||
|
||||
function addProduct(row, skipped) {
|
||||
const item = versionOf(row)
|
||||
if (!item.productId || !item.termId) {
|
||||
if (!item.productId) {
|
||||
if (skipped) skipped.push(item.productName)
|
||||
else proxy.$modal.msgWarning(item.productName + '还没有生效版本,不能绑定')
|
||||
else proxy.$modal.msgWarning(item.productName + '不能绑定')
|
||||
return
|
||||
}
|
||||
if (products.value.some(product => product.key === item.key)) return
|
||||
products.value.push(item)
|
||||
loadFees()
|
||||
}
|
||||
|
||||
function removeProduct(item) {
|
||||
products.value = products.value.filter(product => product.key !== item.key)
|
||||
loadFees()
|
||||
}
|
||||
|
||||
let feeToken = 0
|
||||
|
||||
function loadFees() {
|
||||
const token = ++feeToken
|
||||
const bound = products.value.slice()
|
||||
if (!bound.length) {
|
||||
feeOptions.value = []
|
||||
zoneOptions.value = keepZones([])
|
||||
return
|
||||
}
|
||||
Promise.all(bound.map(item => getPay(item.feeProductId || item.productId).catch(() => null))).then(results => {
|
||||
if (token !== feeToken) return
|
||||
const map = new Map()
|
||||
const zones = new Set()
|
||||
results.forEach(res => {
|
||||
const rows = res?.data?.surcharges || []
|
||||
rows.forEach(fee => {
|
||||
const name = String(fee.feeName || '').trim()
|
||||
const zone = String(fee.zoneName || '').trim()
|
||||
if (zone) zones.add(zone)
|
||||
if (!name || map.has(name)) return
|
||||
map.set(name, { feeName: name, scId: fee.scId || '' })
|
||||
})
|
||||
})
|
||||
zoneOptions.value = keepZones([...zones])
|
||||
for (const row of groups.ALWAYS || []) {
|
||||
const name = String(row.feeName || '').trim()
|
||||
if (name && !map.has(name)) map.set(name, { feeName: name, scId: row.scId || '' })
|
||||
}
|
||||
feeOptions.value = [...map.values()]
|
||||
})
|
||||
}
|
||||
|
||||
function keepZones(zones) {
|
||||
const set = new Set(zones)
|
||||
for (const rule of ['POSTCODE', 'ZONE']) {
|
||||
for (const row of groups[rule] || []) {
|
||||
const zone = String(row.zoneName || '').trim()
|
||||
if (zone) set.add(zone)
|
||||
}
|
||||
}
|
||||
return [...set]
|
||||
}
|
||||
|
||||
function pickFee(row, name) {
|
||||
const found = feeOptions.value.find(item => item.feeName === name)
|
||||
row.scId = found?.scId || ''
|
||||
}
|
||||
|
||||
function termText(row) {
|
||||
@@ -422,7 +583,8 @@ function applyRules(list) {
|
||||
const row = blank(rule)
|
||||
const detail = item.detail || {}
|
||||
Object.keys(row).forEach(key => {
|
||||
if (detail[key] !== undefined && detail[key] !== null) row[key] = String(detail[key])
|
||||
if (detail[key] === undefined || detail[key] === null) return
|
||||
row[key] = key === 'periodStart' || key === 'periodEnd' ? asDate(detail[key]) : String(detail[key])
|
||||
})
|
||||
groups[rule].push(row)
|
||||
}
|
||||
@@ -430,10 +592,26 @@ function applyRules(list) {
|
||||
if (rule.switchOnly) continue
|
||||
if (enabled[rule.value] && !groups[rule.value].length) groups[rule.value].push(blank(rule.value))
|
||||
}
|
||||
const map = new Map(feeOptions.value.map(item => [item.feeName, item]))
|
||||
for (const row of groups.ALWAYS || []) {
|
||||
const name = String(row.feeName || '').trim()
|
||||
if (name && !map.has(name)) map.set(name, { feeName: name, scId: row.scId || '' })
|
||||
}
|
||||
feeOptions.value = [...map.values()]
|
||||
zoneOptions.value = keepZones(zoneOptions.value)
|
||||
}
|
||||
|
||||
function loadRules(productId, termId) {
|
||||
listPaySurchargeRule(productId, termId).then(res => applyRules(res.data || []))
|
||||
function asDate(value) {
|
||||
const text = String(value).trim()
|
||||
if (/^\d{4}-\d{2}-\d{2}/.test(text)) return text.slice(0, 10)
|
||||
const monthDay = text.match(/^(\d{1,2})-(\d{1,2})$/)
|
||||
if (!monthDay) return ''
|
||||
const year = new Date().getFullYear()
|
||||
return `${year}-${monthDay[1].padStart(2, '0')}-${monthDay[2].padStart(2, '0')}`
|
||||
}
|
||||
|
||||
function loadRules(productId) {
|
||||
listPaySurchargeRule(productId).then(res => applyRules(res.data || []))
|
||||
}
|
||||
|
||||
const openedRules = computed(() => ruleDefs.filter(rule => enabled[rule.value] && !rule.switchOnly))
|
||||
@@ -465,39 +643,45 @@ function payloadRules() {
|
||||
return rules
|
||||
}
|
||||
|
||||
function copyPrevious() {
|
||||
const first = products.value[0]
|
||||
if (!first) return
|
||||
copying.value = true
|
||||
previousPaySurchargeRule(first.productId).then(res => {
|
||||
const list = res.data || []
|
||||
if (!list.length) {
|
||||
proxy.$modal.msgWarning('上一版本没有计费条件')
|
||||
return
|
||||
}
|
||||
applyRules(list)
|
||||
proxy.$modal.msgSuccess('已带入上一版本,保存后写到当前版本')
|
||||
}).finally(() => {
|
||||
copying.value = false
|
||||
})
|
||||
}
|
||||
|
||||
function save() {
|
||||
if (!products.value.length) {
|
||||
proxy.$modal.msgError('请选择要绑定的产品')
|
||||
return
|
||||
}
|
||||
for (const rule of ['POSTCODE', 'ZONE']) {
|
||||
if (!enabled[rule]) continue
|
||||
const label = rule === 'POSTCODE' ? '命中邮编' : '命中分区'
|
||||
for (const row of groups[rule]) {
|
||||
if (!String(row.zoneName || '').trim() || !String(row.postcodes || '').trim()) {
|
||||
proxy.$modal.msgError(label + '要选择分区,并填写邮编前缀')
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
if (enabled.ALWAYS) {
|
||||
const names = new Set()
|
||||
for (const row of groups.ALWAYS) {
|
||||
const name = String(row.feeName || '').trim()
|
||||
if (!name) {
|
||||
proxy.$modal.msgError('每票都收要选择费用项')
|
||||
return
|
||||
}
|
||||
if (names.has(name)) {
|
||||
proxy.$modal.msgError('每票都收的费用项不能重复:' + name)
|
||||
return
|
||||
}
|
||||
names.add(name)
|
||||
}
|
||||
}
|
||||
saving.value = true
|
||||
savePaySurchargeRule({
|
||||
products: products.value.map(item => ({
|
||||
productId: item.productId,
|
||||
termId: item.termId,
|
||||
versionNo: item.versionNo,
|
||||
productName: item.productName
|
||||
})),
|
||||
rules: payloadRules()
|
||||
}).then(() => {
|
||||
proxy.$modal.msgSuccess('已保存到当前版本')
|
||||
proxy.$modal.msgSuccess('已保存,计算时按当前生效版本上的附加费执行')
|
||||
visible.value = false
|
||||
}).finally(() => {
|
||||
saving.value = false
|
||||
@@ -519,12 +703,16 @@ defineExpose({ open })
|
||||
.rule-switches { display: flex; flex-wrap: wrap; gap: 12px 20px; margin-top: 8px; }
|
||||
.rule-switch { display: flex; align-items: center; gap: 8px; }
|
||||
.rule-bar, .rule-card-bar { display: flex; align-items: center; justify-content: space-between; }
|
||||
.rule-card { border: 1px solid var(--el-border-color); border-radius: 6px; padding: 8px 12px 12px; margin-bottom: 10px; }
|
||||
.rule-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 8px 16px; }
|
||||
.field { display: flex; align-items: center; gap: 6px; min-width: 0; }
|
||||
.field .label { width: 118px; flex: none; font-size: 13px; color: var(--el-text-color-regular); }
|
||||
.field .el-input, .field .el-select { flex: 1; min-width: 0; }
|
||||
.field .sep { flex: none; color: var(--el-text-color-secondary); }
|
||||
.field .mode { flex: 0 0 118px; }
|
||||
.span-2 { grid-column: 1 / -1; }
|
||||
.rule-card { border: 1px solid var(--el-border-color); border-radius: 6px; padding: 12px 20px 12px 28px; margin-bottom: 10px; overflow: visible; }
|
||||
.rule-grid { display: grid; grid-template-columns: 1fr 1fr; column-gap: 48px; row-gap: 12px; align-items: center; }
|
||||
.field { display: grid; grid-template-columns: 104px minmax(0, 1fr); column-gap: 8px; align-items: center; min-width: 0; }
|
||||
.field .label { width: 104px; min-width: 0; justify-self: end; text-align: right; white-space: nowrap; overflow: visible; font-size: 13px; line-height: 24px; color: var(--el-text-color-regular); }
|
||||
.control { display: flex; align-items: center; gap: 6px; min-width: 0; }
|
||||
.control :deep(.el-input),
|
||||
.control :deep(.el-select),
|
||||
.control :deep(.el-textarea),
|
||||
.control :deep(.el-date-editor) { flex: 1 1 0; width: 0 !important; min-width: 0; max-width: none; }
|
||||
.control :deep(.mode) { flex: 1.7 1 0; }
|
||||
.control :deep(.num) { flex: 0.75 1 0; }
|
||||
.field .sep { flex: none; color: var(--el-text-color-secondary); line-height: 24px; }
|
||||
</style>
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
:search-per-row="4"
|
||||
search-action-align="right"
|
||||
row-key="productId"
|
||||
scrollbar-always-on
|
||||
>
|
||||
<template #toolbar="{ selection, ids }">
|
||||
<el-col :span="1.5">
|
||||
@@ -87,31 +88,34 @@
|
||||
<el-table-column label="生效结束" width="110" align="center">
|
||||
<template #default="{ row }">{{ dayText(row.effectiveEnd) || '不限' }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="状态" width="100" align="center">
|
||||
<template #default="{ row }">
|
||||
<el-switch
|
||||
v-if="row.termId"
|
||||
:model-value="row.status === '1' ? '1' : '2'"
|
||||
active-value="1"
|
||||
inactive-value="2"
|
||||
inline-prompt
|
||||
active-text="生效"
|
||||
inactive-text="失效"
|
||||
@change="(val) => changeStatus(row, 'status', val)"
|
||||
v-hasPermi="['price:pay:edit']"
|
||||
/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="210" align="center">
|
||||
<el-table-column label="操作" width="220" align="center">
|
||||
<template #default="{ row }">
|
||||
<el-button link type="primary" @click="downloadSource(row)" v-hasPermi="['price:pay:query']">下载</el-button>
|
||||
<el-button link type="primary" @click="openTermDialog(row)" v-hasPermi="['price:pay:edit']">修改有效期</el-button>
|
||||
<el-button link type="primary" @click="openRuleLog(row)" v-hasPermi="['price:pay:query']">附加费记录</el-button>
|
||||
<el-button link type="primary" @click="openDetail(row)" v-hasPermi="['price:pay:query']">查看</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-drawer>
|
||||
|
||||
<el-dialog v-model="ruleLogVisible" :title="ruleLogTitle" width="860px" append-to-body>
|
||||
<el-table v-loading="ruleLogLoading" :data="ruleLogRows" border size="small" empty-text="这一版还没有附加费配置记录">
|
||||
<el-table-column label="操作" width="70" align="center">
|
||||
<template #default="{ row }">{{ ruleLogAction(row.operationType) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="更改前" min-width="220" show-overflow-tooltip>
|
||||
<template #default="{ row }">{{ ruleLogSide(row, 'before') }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="更改后" min-width="220" show-overflow-tooltip>
|
||||
<template #default="{ row }">{{ ruleLogSide(row, 'after') }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="createBy" label="操作人" width="100" align="center" />
|
||||
<el-table-column label="操作时间" width="160" align="center">
|
||||
<template #default="{ row }">{{ row.createTime || '-' }}</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog v-model="termVisible" title="修改有效期" width="460px" append-to-body>
|
||||
<el-form label-width="90px">
|
||||
<el-form-item label="生效开始" required>
|
||||
@@ -188,7 +192,7 @@
|
||||
</template>
|
||||
|
||||
<script setup name="PricePay">
|
||||
import { listPay, getPay, delPay, updatePay, listPayTerm, updatePayTerm, changePayTermStatus, comparePay } from '@/api/price/pay'
|
||||
import { listPay, getPay, delPay, updatePay, listPayTerm, updatePayTerm, changePayTermStatus, comparePay, listPaySurchargeRuleLog } from '@/api/price/pay'
|
||||
import PayImportDialog from './components/PayImportDialog.vue'
|
||||
import PayConfigDetail from './components/PayConfigDetail.vue'
|
||||
import PaySurchargeRuleDialog from './components/PaySurchargeRuleDialog.vue'
|
||||
@@ -207,6 +211,10 @@ const historyRows = ref([])
|
||||
const historyTitle = ref('价格版本')
|
||||
const historyProductId = ref(null)
|
||||
const historyPicked = ref([])
|
||||
const ruleLogVisible = ref(false)
|
||||
const ruleLogLoading = ref(false)
|
||||
const ruleLogRows = ref([])
|
||||
const ruleLogTitle = ref('附加费配置记录')
|
||||
const compareVisible = ref(false)
|
||||
const compareLoading = ref(false)
|
||||
const compareTitle = ref('版本比对')
|
||||
@@ -233,8 +241,7 @@ const statusOptions = [
|
||||
]
|
||||
|
||||
const columns = [
|
||||
{ label: '产品编号', prop: 'productId', align: 'center', width: 90 },
|
||||
{ label: '产品名称', prop: 'productName', align: 'center', minWidth: 150, showOverflowTooltip: true },
|
||||
{ label: '产品名称', prop: 'productName', align: 'center', minWidth: 180, showOverflowTooltip: true, fixed: 'left' },
|
||||
{ label: '价卡归属', prop: 'supplierName', align: 'center', width: 100 },
|
||||
{ label: '国家/口岸', prop: 'countryScope', align: 'center', minWidth: 120, showOverflowTooltip: true },
|
||||
{ label: '费用类型', prop: 'chargeType', align: 'center', width: 110 },
|
||||
@@ -384,9 +391,43 @@ function termText(row) {
|
||||
return `${start || '不限'} 至 ${end || '不限'}`
|
||||
}
|
||||
|
||||
function openRuleLog(row) {
|
||||
ruleLogTitle.value = `${row.productName || '产品'} 第 ${row.versionNo || '-'} 版的附加费配置记录`
|
||||
ruleLogRows.value = []
|
||||
ruleLogVisible.value = true
|
||||
ruleLogLoading.value = true
|
||||
listPaySurchargeRuleLog(row.productId, row.termId).then(res => {
|
||||
ruleLogRows.value = res.data || []
|
||||
}).finally(() => {
|
||||
ruleLogLoading.value = false
|
||||
})
|
||||
}
|
||||
|
||||
function ruleLogAction(type) {
|
||||
if (type === '1') return '新增'
|
||||
if (type === '2') return '修改'
|
||||
if (type === '3') return '删除'
|
||||
return '-'
|
||||
}
|
||||
|
||||
function ruleLogSide(row, side) {
|
||||
let content = row.changeContent
|
||||
if (typeof content === 'string') {
|
||||
try {
|
||||
content = JSON.parse(content)
|
||||
} catch (error) {
|
||||
return side === 'after' ? content : '-'
|
||||
}
|
||||
}
|
||||
const values = content?.[side]
|
||||
if (!values || typeof values !== 'object') return '-'
|
||||
const text = Object.entries(values).map(([label, value]) => `${label}:${value}`).join(';')
|
||||
return text || '-'
|
||||
}
|
||||
|
||||
function openHistory(row) {
|
||||
historyProductId.value = row.productId
|
||||
historyTitle.value = `${row.productName || '产品'}(编号 ${row.productId})的价格版本`
|
||||
historyTitle.value = `${row.productName || '产品'}的价格版本`
|
||||
historyPicked.value = []
|
||||
historyVisible.value = true
|
||||
loadHistory()
|
||||
|
||||
Reference in New Issue
Block a user