增加一个渠道绑定
This commit is contained in:
@@ -23,24 +23,21 @@
|
||||
<el-tabs v-model="pane.tab">
|
||||
<el-tab-pane :label="`重量段(${(pane.item.weightBands || []).length})`" name="band">
|
||||
<el-input v-model="pane.bandKeyword" clearable placeholder="筛选国家、分区、重量段、费用项" class="pay-filter" @input="pane.bandPageNo = 1" />
|
||||
<div v-if="editable" class="pay-edit-bar">
|
||||
<el-button size="small" type="primary" plain @click="addBand(pane)">添加重量段</el-button>
|
||||
</div>
|
||||
<el-table :data="pageBands(pane)" border size="small" max-height="360" empty-text="没有重量段或起重配置">
|
||||
<el-table :data="pageBands(pane)" border size="small" empty-text="没有重量段或起重配置">
|
||||
<el-table-column prop="sectionName" label="区块" min-width="110" show-overflow-tooltip>
|
||||
<template #default="{ row }"><cell-text v-model="row.sectionName" :edit="editable" /></template>
|
||||
<template #default="{ row }"><cell-text v-model="row.sectionName" :edit="isRowEditing(row)" /></template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="countryName" label="国家" min-width="120" show-overflow-tooltip>
|
||||
<template #default="{ row }"><cell-text v-model="row.countryName" :edit="editable" /></template>
|
||||
<template #default="{ row }"><cell-text v-model="row.countryName" :edit="isRowEditing(row)" /></template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="countryCode" label="代码" width="80" show-overflow-tooltip>
|
||||
<template #default="{ row }"><cell-text v-model="row.countryCode" :edit="editable" /></template>
|
||||
<template #default="{ row }"><cell-text v-model="row.countryCode" :edit="isRowEditing(row)" /></template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="zoneName" label="分区" min-width="140" show-overflow-tooltip>
|
||||
<template #default="{ row }"><cell-text v-model="row.zoneName" :edit="editable" /></template>
|
||||
<template #default="{ row }"><cell-text v-model="row.zoneName" :edit="isRowEditing(row)" /></template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="weightLabel" label="重量段" min-width="120" show-overflow-tooltip>
|
||||
<template #default="{ row }"><cell-text v-model="row.weightLabel" :edit="editable" /></template>
|
||||
<template #default="{ row }"><cell-text v-model="row.weightLabel" :edit="isRowEditing(row)" /></template>
|
||||
</el-table-column>
|
||||
<el-table-column label="下限KG" width="90" align="right">
|
||||
<template #default="{ row }">{{ money(row.weightMin) }}</template>
|
||||
@@ -49,21 +46,22 @@
|
||||
<template #default="{ row }">{{ money(row.weightMax) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="chargeName" label="费用项" min-width="120" show-overflow-tooltip>
|
||||
<template #default="{ row }"><cell-text v-model="row.chargeName" :edit="editable" /></template>
|
||||
<template #default="{ row }"><cell-text v-model="row.chargeName" :edit="isRowEditing(row)" /></template>
|
||||
</el-table-column>
|
||||
<el-table-column label="单价" width="110" align="right">
|
||||
<template #default="{ row }">
|
||||
<el-input v-if="editable" v-model="row.price" size="small" />
|
||||
<el-input v-if="isRowEditing(row)" v-model="row.price" size="small" />
|
||||
<span v-else>{{ money(row.price) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="priceUnit" label="单位" width="110" show-overflow-tooltip>
|
||||
<template #default="{ row }"><cell-text v-model="row.priceUnit" :edit="editable" /></template>
|
||||
<template #default="{ row }"><cell-text v-model="row.priceUnit" :edit="isRowEditing(row)" /></template>
|
||||
</el-table-column>
|
||||
<el-table-column v-if="editable" label="操作" width="120" align="center" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<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>
|
||||
<el-button v-if="!isRowEditing(row)" link type="primary" :disabled="rowBusy" @click="startEdit(row)">修改</el-button>
|
||||
<el-button v-else link type="primary" :disabled="rowBusy" @click="saveBandRow(pane, row)">保存</el-button>
|
||||
<el-button link type="danger" :disabled="rowBusy" @click="removeRow(pane.item.weightBands, row)">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
@@ -82,11 +80,11 @@
|
||||
<el-input v-model="pane.feeKeyword" clearable placeholder="筛选附加费用、地区、价格、货币或费用解释" class="pay-filter" @input="pane.feePageNo = 1" />
|
||||
<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 :data="pageFees(pane)" border size="small" empty-text="没有附加费">
|
||||
<el-table-column prop="feeName" label="附加费用" min-width="180" show-overflow-tooltip>
|
||||
<template #default="{ row }">
|
||||
<el-select
|
||||
v-if="editable"
|
||||
v-if="isRowEditing(row)"
|
||||
v-model="row.feeName"
|
||||
filterable
|
||||
clearable
|
||||
@@ -106,18 +104,18 @@
|
||||
</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>
|
||||
<template #default="{ row }"><cell-text v-model="row.zoneName" :edit="isRowEditing(row)" /></template>
|
||||
</el-table-column>
|
||||
<el-table-column label="价格" width="110" align="right">
|
||||
<template #default="{ row }">
|
||||
<el-input v-if="editable" v-model="row.amount" size="small" />
|
||||
<el-input v-if="isRowEditing(row)" v-model="row.amount" size="small" />
|
||||
<span v-else>{{ money(row.amount) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="币种" width="110" show-overflow-tooltip>
|
||||
<template #default="{ row }">
|
||||
<el-select
|
||||
v-if="editable"
|
||||
v-if="isRowEditing(row)"
|
||||
:model-value="feeCurrencyOf(row)"
|
||||
filterable
|
||||
allow-create
|
||||
@@ -141,7 +139,7 @@
|
||||
<el-table-column label="单位" width="110" show-overflow-tooltip>
|
||||
<template #default="{ row }">
|
||||
<el-select
|
||||
v-if="editable"
|
||||
v-if="isRowEditing(row)"
|
||||
:model-value="feeUnitOf(row)"
|
||||
filterable
|
||||
allow-create
|
||||
@@ -164,16 +162,16 @@
|
||||
</el-table-column>
|
||||
<el-table-column label="收费标准" min-width="180" show-overflow-tooltip>
|
||||
<template #default="{ row }">
|
||||
<cell-text v-if="editable && (!row.chargeText || feeNote(row))" v-model="row.chargeText" :edit="true" />
|
||||
<cell-text v-if="isRowEditing(row) && (!row.chargeText || feeNote(row))" v-model="row.chargeText" :edit="true" />
|
||||
<span v-else>{{ feeNote(row) || '-' }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="feeDesc" label="费用解释" min-width="240" show-overflow-tooltip>
|
||||
<template #default="{ row }"><cell-text v-model="row.feeDesc" :edit="editable" /></template>
|
||||
<template #default="{ row }"><cell-text v-model="row.feeDesc" :edit="isRowEditing(row)" /></template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="calcRule" label="计费条件" width="140">
|
||||
<template #default="{ row }">
|
||||
<el-select v-if="editable" v-model="row.calcRule" size="small" placeholder="人工确认">
|
||||
<el-select v-if="isRowEditing(row)" v-model="row.calcRule" size="small" placeholder="人工确认">
|
||||
<el-option v-for="item in calcRules" :key="item.value" :label="item.label" :value="item.value" />
|
||||
</el-select>
|
||||
<span v-else>{{ calcRuleLabel(row.calcRule) }}</span>
|
||||
@@ -181,7 +179,7 @@
|
||||
</el-table-column>
|
||||
<el-table-column prop="calcParam" label="条件参数" min-width="220" show-overflow-tooltip>
|
||||
<template #default="{ row }">
|
||||
<span v-if="!editable">{{ feeCondition(row) }}</span>
|
||||
<span v-if="!isRowEditing(row)">{{ feeCondition(row) }}</span>
|
||||
<template v-else>
|
||||
<div v-if="conditionHint(row)" class="pay-cond-hint">{{ conditionHint(row) }}</div>
|
||||
<cell-text
|
||||
@@ -194,8 +192,9 @@
|
||||
</el-table-column>
|
||||
<el-table-column v-if="editable" label="操作" width="120" align="center" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<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>
|
||||
<el-button v-if="!isRowEditing(row)" link type="primary" :disabled="rowBusy" @click="startEdit(row)">修改</el-button>
|
||||
<el-button v-else link type="primary" :disabled="rowBusy" @click="saveFeeRow(pane, row)">保存</el-button>
|
||||
<el-button link type="danger" :disabled="rowBusy" @click="removeRow(pane.item.surcharges, row)">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
@@ -212,7 +211,7 @@
|
||||
<el-tab-pane v-if="postcodeLines(pane).length" :label="`邮编分区(${postcodeLines(pane).length})`" name="postcode">
|
||||
<p class="pay-hint">{{ postcodeHint(pane) }}</p>
|
||||
<el-input v-model="pane.postKeyword" clearable placeholder="筛选邮编、州、城市或分区" class="pay-filter" @input="pane.postPageNo = 1" />
|
||||
<el-table :data="pagePostcodes(pane)" border size="small" max-height="360" empty-text="没有邮编">
|
||||
<el-table :data="pagePostcodes(pane)" border size="small" empty-text="没有邮编">
|
||||
<el-table-column v-for="(title, index) in postcodeTitles(pane)" :key="title" :label="title" min-width="110" show-overflow-tooltip>
|
||||
<template #default="{ row }">{{ row.parts[index] || '-' }}</template>
|
||||
</el-table-column>
|
||||
@@ -233,7 +232,7 @@
|
||||
|
||||
<script setup>
|
||||
// 重量段和附加费。传入 products 时一次展示全部产品。
|
||||
import { h, onMounted } from 'vue'
|
||||
import { h, onMounted, watch } from 'vue'
|
||||
import { ElInput } from 'element-plus'
|
||||
import { listSurchargeOptions } from '@/api/price/surcharge'
|
||||
|
||||
@@ -258,6 +257,12 @@ const props = defineProps({
|
||||
|
||||
const emit = defineEmits(['save-row'])
|
||||
|
||||
const editingKeys = ref(new Set())
|
||||
|
||||
watch(() => props.product, () => {
|
||||
editingKeys.value = new Set()
|
||||
})
|
||||
|
||||
function rowKeyOf(row) {
|
||||
if (!row) return ''
|
||||
if (row.surchargeId != null) return 'fee-' + row.surchargeId
|
||||
@@ -267,16 +272,58 @@ function rowKeyOf(row) {
|
||||
return row.__rowKey
|
||||
}
|
||||
|
||||
function isRowSaving(row) {
|
||||
return props.savingRowKey && String(props.savingRowKey) === String(rowKeyOf(row))
|
||||
function isRowEditing(row) {
|
||||
return editingKeys.value.has(rowKeyOf(row))
|
||||
}
|
||||
|
||||
function startEdit(row) {
|
||||
const next = new Set(editingKeys.value)
|
||||
next.add(rowKeyOf(row))
|
||||
editingKeys.value = next
|
||||
}
|
||||
|
||||
function stopEdit(row) {
|
||||
const next = new Set(editingKeys.value)
|
||||
next.delete(rowKeyOf(row))
|
||||
editingKeys.value = next
|
||||
}
|
||||
|
||||
const localSavingKey = ref('')
|
||||
const rowBusy = computed(() => !!(props.savingRowKey || localSavingKey.value))
|
||||
|
||||
function finishSave(row, ok) {
|
||||
localSavingKey.value = ''
|
||||
if (ok !== false) stopEdit(row)
|
||||
}
|
||||
|
||||
function runSave(kind, pane, row) {
|
||||
if (localSavingKey.value || props.savingRowKey) return
|
||||
const rowKey = rowKeyOf(row)
|
||||
localSavingKey.value = rowKey
|
||||
let settled = false
|
||||
const done = (ok) => {
|
||||
if (settled) return
|
||||
settled = true
|
||||
finishSave(row, ok)
|
||||
}
|
||||
try {
|
||||
emit('save-row', { kind, product: pane.item, row, rowKey, done })
|
||||
} catch (e) {
|
||||
done(false)
|
||||
return
|
||||
}
|
||||
// Parent must call done(); hard stop UI lock if it does not.
|
||||
window.setTimeout(() => {
|
||||
if (!settled) done(false)
|
||||
}, 8000)
|
||||
}
|
||||
|
||||
function saveBandRow(pane, row) {
|
||||
emit('save-row', { kind: 'band', product: pane.item, row, rowKey: rowKeyOf(row) })
|
||||
runSave('band', pane, row)
|
||||
}
|
||||
|
||||
function saveFeeRow(pane, row) {
|
||||
emit('save-row', { kind: 'fee', product: pane.item, row, rowKey: rowKeyOf(row) })
|
||||
runSave('fee', pane, row)
|
||||
}
|
||||
|
||||
const surchargeOptions = ref([])
|
||||
@@ -470,16 +517,10 @@ function filteredFees(pane) {
|
||||
return filterRows(pane.item.surcharges || [], pane.feeKeyword, ['feeName', 'zoneName', 'chargeText', 'amount', 'currency', 'priceUnit', 'feeDesc', 'calcRule', 'calcParam', 'postcodeParam'])
|
||||
}
|
||||
|
||||
function addBand(pane) {
|
||||
if (!pane.item.weightBands) pane.item.weightBands = []
|
||||
pane.item.weightBands.push({ sectionName: '', countryName: '', countryCode: '', zoneName: '', weightLabel: '', chargeName: '', price: '', priceUnit: '' })
|
||||
pane.bandPageNo = Math.ceil(pane.item.weightBands.length / pageSize) || 1
|
||||
}
|
||||
|
||||
function addFee(pane) {
|
||||
if (!pane.item.surcharges) pane.item.surcharges = []
|
||||
const currency = String(pane.item.currency || 'EUR').trim().toUpperCase() || 'EUR'
|
||||
pane.item.surcharges.push({
|
||||
const row = {
|
||||
feeName: '',
|
||||
scId: undefined,
|
||||
zoneName: '',
|
||||
@@ -490,7 +531,9 @@ function addFee(pane) {
|
||||
feeDesc: '',
|
||||
calcRule: 'MANUAL',
|
||||
calcParam: ''
|
||||
})
|
||||
}
|
||||
pane.item.surcharges.push(row)
|
||||
startEdit(row)
|
||||
pane.feePageNo = Math.ceil(pane.item.surcharges.length / pageSize) || 1
|
||||
}
|
||||
|
||||
|
||||
@@ -140,25 +140,17 @@
|
||||
size="78%"
|
||||
append-to-body
|
||||
:close-on-click-modal="false"
|
||||
@closed="editing = false"
|
||||
>
|
||||
<pay-config-detail
|
||||
v-loading="detailLoading || !!savingRowKey"
|
||||
v-loading="detailLoading"
|
||||
:product="detail"
|
||||
:editable="editing"
|
||||
:editable="true"
|
||||
:saving-row-key="savingRowKey"
|
||||
@save-row="saveProductRow"
|
||||
/>
|
||||
<template #footer>
|
||||
<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>
|
||||
@@ -174,7 +166,6 @@ const tableRef = ref()
|
||||
const importRef = ref()
|
||||
const detailVisible = ref(false)
|
||||
const detailLoading = ref(false)
|
||||
const editing = ref(false)
|
||||
const savingRowKey = ref('')
|
||||
const detail = ref(null)
|
||||
const historyVisible = ref(false)
|
||||
@@ -292,7 +283,6 @@ function handleDelete(ids) {
|
||||
|
||||
function openDetail(row) {
|
||||
detailVisible.value = true
|
||||
editing.value = false
|
||||
savingRowKey.value = ''
|
||||
detailLoading.value = true
|
||||
detail.value = null
|
||||
@@ -303,25 +293,34 @@ function openDetail(row) {
|
||||
})
|
||||
}
|
||||
|
||||
function saveProductRow(payload) {
|
||||
if (!detail.value || savingRowKey.value) return
|
||||
async function saveProductRow(payload) {
|
||||
if (!detail.value || savingRowKey.value) {
|
||||
payload?.done?.(false)
|
||||
return
|
||||
}
|
||||
cleanMoney(detail.value)
|
||||
;(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(() => {
|
||||
let ok = false
|
||||
try {
|
||||
await updatePay(detail.value)
|
||||
ok = true
|
||||
proxy.$modal.msgSuccess('该行已保存')
|
||||
if (!productId) return
|
||||
return getPay(productId).then(res => {
|
||||
if (res.data) detail.value = res.data
|
||||
})
|
||||
}).then(() => {
|
||||
tableRef.value?.refresh()
|
||||
}).finally(() => {
|
||||
} catch (e) {
|
||||
ok = false
|
||||
} finally {
|
||||
savingRowKey.value = ''
|
||||
})
|
||||
payload?.done?.(ok)
|
||||
}
|
||||
if (!ok || !productId) return
|
||||
try {
|
||||
const res = await getPay(productId)
|
||||
if (res.data) detail.value = res.data
|
||||
tableRef.value?.refresh()
|
||||
} catch (e) {}
|
||||
}
|
||||
|
||||
function cleanMoney(product) {
|
||||
|
||||
Reference in New Issue
Block a user