修改类型
This commit is contained in:
@@ -60,9 +60,10 @@
|
||||
<el-table-column prop="priceUnit" label="单位" width="110" show-overflow-tooltip>
|
||||
<template #default="{ row }"><cell-text v-model="row.priceUnit" :edit="editable" /></template>
|
||||
</el-table-column>
|
||||
<el-table-column v-if="editable" label="操作" width="70" align="center">
|
||||
<el-table-column v-if="editable" label="操作" width="120" align="center" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<el-button link type="danger" @click="removeRow(pane.item.weightBands, row)">删除</el-button>
|
||||
<el-button link type="primary" :loading="isRowSaving(row)" @click="saveBandRow(pane, row)">保存</el-button>
|
||||
<el-button link type="danger" :disabled="!!savingRowKey" @click="removeRow(pane.item.weightBands, row)">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
@@ -82,8 +83,27 @@
|
||||
<el-button v-if="editable" size="small" type="primary" plain @click="addFee(pane)">添加附加费</el-button>
|
||||
</div>
|
||||
<el-table :data="pageFees(pane)" border size="small" max-height="360" empty-text="没有附加费">
|
||||
<el-table-column prop="feeName" label="附加费用" min-width="160" show-overflow-tooltip>
|
||||
<template #default="{ row }"><cell-text v-model="row.feeName" :edit="editable" /></template>
|
||||
<el-table-column prop="feeName" label="附加费用" min-width="180" show-overflow-tooltip>
|
||||
<template #default="{ row }">
|
||||
<el-select
|
||||
v-if="editable"
|
||||
v-model="row.feeName"
|
||||
filterable
|
||||
clearable
|
||||
size="small"
|
||||
style="width: 100%"
|
||||
:placeholder="'请选择附加费'"
|
||||
@change="name => onFeeNameChange(row, name)"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in feeNameOptions(row)"
|
||||
:key="item"
|
||||
:label="item"
|
||||
:value="item"
|
||||
/>
|
||||
</el-select>
|
||||
<span v-else>{{ row.feeName || '-' }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="zoneName" label="地区" min-width="160" show-overflow-tooltip>
|
||||
<template #default="{ row }"><cell-text v-model="row.zoneName" :edit="editable" /></template>
|
||||
@@ -94,10 +114,52 @@
|
||||
<span v-else>{{ money(row.amount) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="货币" width="120" show-overflow-tooltip>
|
||||
<el-table-column label="币种" width="110" show-overflow-tooltip>
|
||||
<template #default="{ row }">
|
||||
<cell-text v-if="editable" v-model="row.priceUnit" :edit="true" />
|
||||
<span v-else>{{ row.priceUnit || row.currency || '-' }}</span>
|
||||
<el-select
|
||||
v-if="editable"
|
||||
:model-value="feeCurrencyOf(row)"
|
||||
filterable
|
||||
allow-create
|
||||
default-first-option
|
||||
clearable
|
||||
size="small"
|
||||
style="width: 100%"
|
||||
:placeholder="'币种'"
|
||||
@update:model-value="value => setFeeCurrency(row, value)"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in currencyOptions"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
<span v-else>{{ feeCurrencyOf(row) || '-' }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="单位" width="110" show-overflow-tooltip>
|
||||
<template #default="{ row }">
|
||||
<el-select
|
||||
v-if="editable"
|
||||
:model-value="feeUnitOf(row)"
|
||||
filterable
|
||||
allow-create
|
||||
default-first-option
|
||||
clearable
|
||||
size="small"
|
||||
style="width: 100%"
|
||||
:placeholder="'单位'"
|
||||
@update:model-value="value => setFeeUnit(row, value)"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in feeUnitOptions"
|
||||
:key="item"
|
||||
:label="item"
|
||||
:value="item"
|
||||
/>
|
||||
</el-select>
|
||||
<span v-else>{{ feeUnitOf(row) || '-' }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="收费标准" min-width="180" show-overflow-tooltip>
|
||||
@@ -119,13 +181,21 @@
|
||||
</el-table-column>
|
||||
<el-table-column prop="calcParam" label="条件参数" min-width="220" show-overflow-tooltip>
|
||||
<template #default="{ row }">
|
||||
<div>{{ feeCondition(row) }}</div>
|
||||
<cell-text v-if="editable" v-model="row.calcParam" :edit="editable" />
|
||||
<span v-if="!editable">{{ feeCondition(row) }}</span>
|
||||
<template v-else>
|
||||
<div v-if="conditionHint(row)" class="pay-cond-hint">{{ conditionHint(row) }}</div>
|
||||
<cell-text
|
||||
v-if="showCalcParamEditor(row)"
|
||||
v-model="row.calcParam"
|
||||
:edit="true"
|
||||
/>
|
||||
</template>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column v-if="editable" label="操作" width="70" align="center">
|
||||
<el-table-column v-if="editable" label="操作" width="120" align="center" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<el-button link type="danger" @click="removeRow(pane.item.surcharges, row)">删除</el-button>
|
||||
<el-button link type="primary" :loading="isRowSaving(row)" @click="saveFeeRow(pane, row)">保存</el-button>
|
||||
<el-button link type="danger" :disabled="!!savingRowKey" @click="removeRow(pane.item.surcharges, row)">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
@@ -163,8 +233,9 @@
|
||||
|
||||
<script setup>
|
||||
// 重量段和附加费。传入 products 时一次展示全部产品。
|
||||
import { h } from 'vue'
|
||||
import { h, onMounted } from 'vue'
|
||||
import { ElInput } from 'element-plus'
|
||||
import { listSurchargeOptions } from '@/api/price/surcharge'
|
||||
|
||||
const props = defineProps({
|
||||
product: {
|
||||
@@ -178,9 +249,140 @@ const props = defineProps({
|
||||
editable: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
savingRowKey: {
|
||||
type: [String, Number],
|
||||
default: ''
|
||||
}
|
||||
})
|
||||
|
||||
const emit = defineEmits(['save-row'])
|
||||
|
||||
function rowKeyOf(row) {
|
||||
if (!row) return ''
|
||||
if (row.surchargeId != null) return 'fee-' + row.surchargeId
|
||||
if (row.bandId != null) return 'band-' + row.bandId
|
||||
if (row.__rowKey) return row.__rowKey
|
||||
row.__rowKey = 'tmp-' + Date.now() + '-' + Math.random().toString(36).slice(2, 8)
|
||||
return row.__rowKey
|
||||
}
|
||||
|
||||
function isRowSaving(row) {
|
||||
return props.savingRowKey && String(props.savingRowKey) === String(rowKeyOf(row))
|
||||
}
|
||||
|
||||
function saveBandRow(pane, row) {
|
||||
emit('save-row', { kind: 'band', product: pane.item, row, rowKey: rowKeyOf(row) })
|
||||
}
|
||||
|
||||
function saveFeeRow(pane, row) {
|
||||
emit('save-row', { kind: 'fee', product: pane.item, row, rowKey: rowKeyOf(row) })
|
||||
}
|
||||
|
||||
const surchargeOptions = ref([])
|
||||
const { bms_currency } = useDict('bms_currency')
|
||||
const currencyOptions = computed(() => (bms_currency.value || []).map(item => ({
|
||||
label: item.label || item.value,
|
||||
value: item.value
|
||||
})))
|
||||
const feeUnitOptions = ['ITEM', 'KG', 'PCS', 'PARCEL', '%']
|
||||
|
||||
function parseFeeUnit(priceUnit) {
|
||||
const text = String(priceUnit || '').trim()
|
||||
if (!text) return ''
|
||||
if (text === '%') return '%'
|
||||
const slash = text.lastIndexOf('/')
|
||||
if (slash >= 0) {
|
||||
return text.slice(slash + 1).trim().toUpperCase()
|
||||
}
|
||||
if (/^[A-Za-z]{3}$/.test(text)) return ''
|
||||
return text.toUpperCase()
|
||||
}
|
||||
|
||||
function feeCurrencyOf(row) {
|
||||
const currency = String(row?.currency || '').trim()
|
||||
if (currency) return currency.toUpperCase()
|
||||
const text = String(row?.priceUnit || '').trim()
|
||||
const match = text.match(/^([A-Za-z]{3})(?:\/|$)/)
|
||||
return match ? match[1].toUpperCase() : ''
|
||||
}
|
||||
|
||||
function feeUnitOf(row) {
|
||||
return parseFeeUnit(row?.priceUnit)
|
||||
}
|
||||
|
||||
function syncFeePriceUnit(row, unitOverride) {
|
||||
const currency = feeCurrencyOf(row)
|
||||
const unit = unitOverride != null ? String(unitOverride || '').trim().toUpperCase() : feeUnitOf(row)
|
||||
if (unit === '%') {
|
||||
row.priceUnit = '%'
|
||||
return
|
||||
}
|
||||
if (currency && unit) {
|
||||
row.priceUnit = currency + '/' + unit
|
||||
return
|
||||
}
|
||||
if (currency) {
|
||||
row.priceUnit = currency
|
||||
return
|
||||
}
|
||||
row.priceUnit = unit || ''
|
||||
}
|
||||
|
||||
function setFeeCurrency(row, value) {
|
||||
const currency = String(value || '').trim().toUpperCase()
|
||||
row.currency = currency
|
||||
syncFeePriceUnit(row)
|
||||
}
|
||||
|
||||
function setFeeUnit(row, value) {
|
||||
syncFeePriceUnit(row, value)
|
||||
}
|
||||
|
||||
function loadSurchargeOptions() {
|
||||
return listSurchargeOptions({ ssCode: 'on' }).then(res => {
|
||||
surchargeOptions.value = res.data || []
|
||||
}).catch(() => {
|
||||
surchargeOptions.value = []
|
||||
})
|
||||
}
|
||||
|
||||
function feeNameOptions(row) {
|
||||
const names = []
|
||||
const seen = new Set()
|
||||
for (const item of surchargeOptions.value || []) {
|
||||
const name = String(item?.scName || '').trim()
|
||||
if (!name || seen.has(name)) continue
|
||||
seen.add(name)
|
||||
names.push(name)
|
||||
}
|
||||
const current = String(row?.feeName || '').trim()
|
||||
if (current && !seen.has(current)) {
|
||||
names.unshift(current)
|
||||
}
|
||||
return names
|
||||
}
|
||||
|
||||
function onFeeNameChange(row, name) {
|
||||
const matched = (surchargeOptions.value || []).find(item => String(item?.scName || '').trim() === String(name || '').trim())
|
||||
if (!matched) {
|
||||
row.scId = undefined
|
||||
return
|
||||
}
|
||||
row.scId = matched.scId
|
||||
const currency = matched.currency || feeCurrencyOf(row)
|
||||
if (currency) {
|
||||
setFeeCurrency(row, currency)
|
||||
}
|
||||
if (!feeUnitOf(row)) {
|
||||
setFeeUnit(row, 'ITEM')
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
loadSurchargeOptions()
|
||||
})
|
||||
|
||||
const CellText = {
|
||||
props: { modelValue: { default: '' }, edit: Boolean },
|
||||
emits: ['update:modelValue'],
|
||||
@@ -210,7 +412,7 @@ function calcRuleLabel(value) {
|
||||
return calcRules.find(item => item.value === value)?.label || '人工确认'
|
||||
}
|
||||
|
||||
function feeCondition(row) {
|
||||
function conditionHint(row) {
|
||||
const parts = []
|
||||
const hasMin = row.weightMin != null && row.weightMin !== ''
|
||||
const hasMax = row.weightMax != null && row.weightMax !== ''
|
||||
@@ -220,9 +422,24 @@ function feeCondition(row) {
|
||||
if (row.postcodeParam) {
|
||||
parts.push(`邮编 ${row.postcodeParam}`)
|
||||
}
|
||||
if (row.calcParam && row.calcParam !== row.postcodeParam) {
|
||||
parts.push(String(row.calcParam))
|
||||
}
|
||||
return parts.join(';')
|
||||
}
|
||||
|
||||
function hasCalcParam(row) {
|
||||
const text = String(row?.calcParam ?? '').trim()
|
||||
if (!text) return false
|
||||
return text !== String(row?.postcodeParam ?? '').trim()
|
||||
}
|
||||
|
||||
function showCalcParamEditor(row) {
|
||||
return hasCalcParam(row) || !conditionHint(row)
|
||||
}
|
||||
|
||||
function feeCondition(row) {
|
||||
const parts = []
|
||||
const hint = conditionHint(row)
|
||||
if (hint) parts.push(hint)
|
||||
if (hasCalcParam(row)) parts.push(String(row.calcParam).trim())
|
||||
return parts.join(';') || '-'
|
||||
}
|
||||
|
||||
@@ -261,7 +478,19 @@ function addBand(pane) {
|
||||
|
||||
function addFee(pane) {
|
||||
if (!pane.item.surcharges) pane.item.surcharges = []
|
||||
pane.item.surcharges.push({ feeName: '', zoneName: '', chargeText: '', amount: '', priceUnit: '', currency: '', feeDesc: '', calcRule: 'MANUAL', calcParam: '' })
|
||||
const currency = String(pane.item.currency || 'EUR').trim().toUpperCase() || 'EUR'
|
||||
pane.item.surcharges.push({
|
||||
feeName: '',
|
||||
scId: undefined,
|
||||
zoneName: '',
|
||||
chargeText: '',
|
||||
amount: '',
|
||||
priceUnit: currency + '/ITEM',
|
||||
currency,
|
||||
feeDesc: '',
|
||||
calcRule: 'MANUAL',
|
||||
calcParam: ''
|
||||
})
|
||||
pane.feePageNo = Math.ceil(pane.item.surcharges.length / pageSize) || 1
|
||||
}
|
||||
|
||||
@@ -384,6 +613,10 @@ function statusText(status) {
|
||||
margin-top: 8px;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
.pay-cond-hint {
|
||||
line-height: 1.5;
|
||||
color: var(--el-text-color-regular);
|
||||
}
|
||||
.limit-tag {
|
||||
margin-right: 6px;
|
||||
}
|
||||
|
||||
@@ -134,13 +134,31 @@
|
||||
</el-table>
|
||||
</el-drawer>
|
||||
|
||||
<el-drawer v-model="detailVisible" :title="detailTitle" size="78%" destroy-on-close>
|
||||
<pay-config-detail v-loading="detailLoading" :product="detail" :editable="editing" />
|
||||
<el-drawer
|
||||
v-model="detailVisible"
|
||||
:title="detailTitle"
|
||||
size="78%"
|
||||
append-to-body
|
||||
:close-on-click-modal="false"
|
||||
@closed="editing = false"
|
||||
>
|
||||
<pay-config-detail
|
||||
v-loading="detailLoading || !!savingRowKey"
|
||||
:product="detail"
|
||||
:editable="editing"
|
||||
:saving-row-key="savingRowKey"
|
||||
@save-row="saveProductRow"
|
||||
/>
|
||||
<template #footer>
|
||||
<el-button v-if="detail" @click="downloadSource(detail)" v-hasPermi="['price:pay:query']">下载源文件</el-button>
|
||||
<el-button v-if="!editing" type="primary" @click="editing = true" v-hasPermi="['price:pay:import']">编辑</el-button>
|
||||
<el-button v-else type="primary" :loading="saving" @click="saveDetail">保存</el-button>
|
||||
<el-button @click="detailVisible = false">关闭</el-button>
|
||||
<el-button v-if="detail" @click="downloadSource(detail)" v-hasPermi="['price:pay:query']">下载源文件</el-button>
|
||||
<el-button
|
||||
v-if="!editing"
|
||||
type="primary"
|
||||
@click="editing = true"
|
||||
v-hasPermi="['price:pay:import']"
|
||||
>编辑</el-button>
|
||||
<el-button v-else @click="editing = false">完成</el-button>
|
||||
</template>
|
||||
</el-drawer>
|
||||
</div>
|
||||
@@ -157,7 +175,7 @@ const importRef = ref()
|
||||
const detailVisible = ref(false)
|
||||
const detailLoading = ref(false)
|
||||
const editing = ref(false)
|
||||
const saving = ref(false)
|
||||
const savingRowKey = ref('')
|
||||
const detail = ref(null)
|
||||
const historyVisible = ref(false)
|
||||
const historyLoading = ref(false)
|
||||
@@ -275,6 +293,7 @@ function handleDelete(ids) {
|
||||
function openDetail(row) {
|
||||
detailVisible.value = true
|
||||
editing.value = false
|
||||
savingRowKey.value = ''
|
||||
detailLoading.value = true
|
||||
detail.value = null
|
||||
getPay(row.versionProductId || row.productId).then(res => {
|
||||
@@ -284,15 +303,24 @@ function openDetail(row) {
|
||||
})
|
||||
}
|
||||
|
||||
function saveDetail() {
|
||||
function saveProductRow(payload) {
|
||||
if (!detail.value || savingRowKey.value) return
|
||||
cleanMoney(detail.value)
|
||||
saving.value = true
|
||||
;(detail.value.surcharges || []).forEach(row => {
|
||||
if (row.amount === '') row.amount = null
|
||||
})
|
||||
const productId = detail.value.productId
|
||||
savingRowKey.value = payload?.rowKey || 'row'
|
||||
updatePay(detail.value).then(() => {
|
||||
proxy.$modal.msgSuccess('已保存这一版。产品编号不变,绑定该产品的渠道按有效期取价')
|
||||
editing.value = false
|
||||
tableRef.value.refresh()
|
||||
proxy.$modal.msgSuccess('该行已保存')
|
||||
if (!productId) return
|
||||
return getPay(productId).then(res => {
|
||||
if (res.data) detail.value = res.data
|
||||
})
|
||||
}).then(() => {
|
||||
tableRef.value?.refresh()
|
||||
}).finally(() => {
|
||||
saving.value = false
|
||||
savingRowKey.value = ''
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user