修改附加费

This commit is contained in:
wuweihua
2026-09-22 10:40:13 +08:00
parent 465b3e6b6b
commit c860d1666d
8 changed files with 192 additions and 46 deletions
+35
View File
@@ -197,6 +197,41 @@ export function updateSetDetail(data) {
})
}
/**
* Submit async batch write of detail surcharge snapshots and poll until done.
* @returns {Promise<{ task: object }>}
*/
export async function updateSetDetailSurchargeAsync(details, onProgress) {
const submitRes = await request({
url: '/price/set/detail/surcharge/async',
method: 'post',
data: details || []
})
const taskId = pickSaveTaskId(submitRes)
if (!taskId) {
throw new Error('missing surcharge taskId')
}
const started = Date.now()
const maxMs = 30 * 60 * 1000
while (Date.now() - started < maxMs) {
const res = await getPriceSetSaveTask(taskId)
const task = res.data || {}
if (typeof onProgress === 'function') {
onProgress(task)
}
if (task.status === 'SUCCESS') {
return { task }
}
if (task.status === 'FAIL') {
const err = new Error(task.error || task.message || 'surcharge save failed')
err.task = task
throw err
}
await new Promise(resolve => setTimeout(resolve, 800))
}
throw new Error('surcharge save timeout')
}
export function delSetDetail(psdIds) {
return request({
url: '/price/set/detail/' + psdIds,
@@ -73,7 +73,7 @@
</el-table-column>
<el-table-column :label="colSurcharge" width="110" align="center">
<template #default="{ row }">
<surcharge-count-cell :list="row.surcharges || []" @click="pickSurcharge(row)" />
<surcharge-count-cell :list="row.surcharges || []" @remove="s => removeSurcharge(row, s)" />
</template>
</el-table-column>
<el-table-column :label="colAction" width="90" align="center">
@@ -97,7 +97,7 @@ const props = defineProps({
productName: { type: String, default: '' },
rows: { type: Array, default: () => [] }
})
const emit = defineEmits(['update:modelValue', 'pick-surcharge', 'row-change'])
const emit = defineEmits(['update:modelValue', 'pick-surcharge', 'row-change', 'surcharge-change'])
const { proxy } = getCurrentInstance()
@@ -187,6 +187,14 @@ function pickSurcharge(row) {
emit('pick-surcharge', row || null)
}
function removeSurcharge(row, sc) {
if (!row || !sc || sc.scId == null) return
const scId = String(sc.scId)
const next = (row.surcharges || []).filter(s => s && String(s.scId) !== scId)
row.surcharges = next
emit('surcharge-change', row)
}
function countryKey(row) {
return String(row.countryCode || row.countryName || '').toUpperCase()
}
@@ -35,11 +35,6 @@
<dict-tag :options="bms_tax_mode" :value="row.taxMode" />
</template>
</el-table-column> -->
<el-table-column :label="colSurcharge" width="110" align="center">
<template #default="{ row }">
<surcharge-count-cell :list="productSurcharges(row)" @click="openSurcharge(row)" />
</template>
</el-table-column>
<el-table-column :label="colAction" width="220" align="center" fixed="right">
<template #default="{ row }">
<el-button link type="primary" @click="openPrice(row)">编辑价格</el-button>
@@ -76,6 +71,7 @@
:product-name="editName"
:rows="editRows"
@row-change="onRowPriceChange"
@surcharge-change="onRowSurchargeChange"
@pick-surcharge="openSurchargeFromDrawer"
/>
</el-card>
@@ -83,7 +79,6 @@
<script setup name="StepDetails">
import PriceEditDrawer from './PriceEditDrawer.vue'
import SurchargeCountCell from './SurchargeCountCell.vue'
import SurchargePickerDialog from './SurchargePickerDialog.vue'
import { useDetailCascade } from '../../composables/usePriceSetRefData'
import {
@@ -95,7 +90,7 @@ import {
surchargeAppliesToRow,
toDetailPayload
} from '../../utils/priceSet'
import { updateSetDetail, delSetDetail } from '@/api/price/set'
import { updateSetDetail, updateSetDetailSurchargeAsync, delSetDetail } from '@/api/price/set'
const props = defineProps({
details: { type: Array, required: true },
@@ -120,7 +115,6 @@ const colLevel = '时效等级'
const colCargo = '走货属性'
const colRegion = '目的区域'
// const colTax = '税模式'
const colSurcharge = '附加费'
const colAction = '操作'
const colDiscount = '产品折扣'
@@ -181,21 +175,6 @@ const pulling = ref(false)
function noop() {}
/** 该产品所有明细行附加费的并集(按 scId 去重),列表列展示用 */
function productSurcharges(row) {
const seen = new Set()
const list = []
;((row && row.rows) || []).forEach(r => {
(r.surcharges || []).forEach(s => {
const key = s && s.scId != null ? String(s.scId) : (s && s.scName)
if (!key || seen.has(key)) return
seen.add(key)
list.push(s)
})
})
return list
}
/** enter step 3: pull all library products + country prices (skip already added) */
async function pullAllFromLibrary(opts = {}) {
const silent = !!opts.silent
@@ -320,6 +299,17 @@ async function persistDetail(row, withSurcharge) {
await updateSetDetail(payload)
}
/** drawer hover remove surcharge -> write snapshot for this row */
async function onRowSurchargeChange(row) {
if (!row || !row.psdId) return
try {
await persistDetail(row, true)
proxy.$modal.msgSuccess('附加费已移除')
} catch (e) {
proxy.$modal.msgError((e && e.message) ? e.message : '附加费移除失败')
}
}
/** drawer field change -> immediate DB update */
async function onRowPriceChange(row) {
if (!row || !row.psdId) return
@@ -470,17 +460,25 @@ function onSurchargeConfirm(picked) {
proxy.$modal.msgWarning('已勾选但未生效:这些附加费配置了适用国家/重量段,与当前明细行不匹配')
return
}
if (skipped > 0) {
Promise.all(targets.filter(r => r.psdId).map(r => persistDetail(r, true))).finally(() => {
proxy.$modal.msgWarning(`已纳入 ${applied} 项附加费${scopeText};${skipped} 项因适用国家不匹配被跳过(已写库)`)
})
const okText = ids.size
? (skipped > 0
? `已纳入 ${applied} 项附加费${scopeText};${skipped} 项因适用国家不匹配被跳过`
: `已纳入 ${ids.size} 项附加费${scopeText}`)
: `已清空附加费${scopeText}`
const payload = targets.filter(r => r.psdId).map(r => toDetailPayload(r)).map(p => {
p.priceSetId = props.priceSetId
return p
})
scVisible.value = false
if (!payload.length) {
proxy.$modal.msgSuccess(okText)
return
}
const okText = ids.size ? `已纳入 ${ids.size} 项附加费${scopeText}` : `已清空附加费${scopeText}`
Promise.all(targets.filter(r => r.psdId).map(r => persistDetail(r, true))).then(() => {
proxy.$modal.msgSuccess(okText + ',正在后台写入…')
updateSetDetailSurchargeAsync(payload).then(() => {
proxy.$modal.msgSuccess(okText + ',已写入数据库')
}).catch(() => {
proxy.$modal.msgSuccess(okText)
}).catch(e => {
proxy.$modal.msgError((e && e.message) ? e.message : '附加费后台写入失败')
})
}
@@ -5,38 +5,49 @@
placement="top"
:width="380"
trigger="hover"
:hide-after="120"
>
<template #default>
<div class="sc-count__pop-title">已纳入 {{ list.length }} 项附加费</div>
<surcharge-tags :list="list" :popover="false" empty-text="-" />
<div class="sc-count__tags">
<el-tag
v-for="s in list"
:key="s.relId || s.scId || s.scName"
size="small"
type="danger"
effect="plain"
closable
@click.stop
@close="onRemove(s)"
>{{ surchargeTagLabel(s) }}</el-tag>
</div>
</template>
<template #reference>
<el-link type="primary" :underline="false" @click="emit('click')">
{{ list.length }} 项
</el-link>
<span class="sc-count__text">{{ list.length }} 项</span>
</template>
</el-popover>
<el-link v-else type="info" :underline="false" @click="emit('click')">0</el-link>
<span v-else class="sc-count__text is-empty">0</span>
</div>
</template>
<script setup name="SurchargeCountCell">
/**
* 套餐 · 附加费数量单元格(新建第 3 步产品列表 / 价格编辑抽屉共用)
*
* 显示当前数量(默认 0);hover 气泡看具体是哪几项,点击进入勾选弹窗调整。
* Hover shows included surcharges; closable tag removes one item from the row.
*/
import SurchargeTags from '../SurchargeTags.vue'
import { surchargeTagLabel } from '../../utils/priceSet'
defineProps({
/** 该行 / 该产品当前纳入的附加费列表 */
list: {
type: Array,
default: () => []
}
})
const emit = defineEmits(['click'])
const emit = defineEmits(['remove'])
function onRemove(s) {
emit('remove', s)
}
</script>
<style scoped>
@@ -45,10 +56,23 @@ const emit = defineEmits(['click'])
align-items: center;
gap: 4px;
}
.sc-count__text {
color: var(--el-color-primary);
cursor: default;
font-size: 13px;
}
.sc-count__text.is-empty {
color: var(--el-text-color-secondary);
}
.sc-count__pop-title {
margin-bottom: 6px;
font-size: 12px;
font-weight: 600;
color: #606266;
}
.sc-count__tags {
display: flex;
flex-wrap: wrap;
gap: 6px;
}
</style>