产品列表配置附加费
This commit is contained in:
@@ -19,6 +19,31 @@ export function getSurcharge(scId) {
|
||||
})
|
||||
}
|
||||
|
||||
/** 查询指定产品的附加费关联(非分页,含附加费与明细展示字段) */
|
||||
export function listSurchargeByProduct(productCode) {
|
||||
return request({
|
||||
url: '/price/surcharge/byProduct/' + productCode,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
/** 绑定附加费到产品/明细(scId + productCode + detailId) */
|
||||
export function addSurchargeRel(data) {
|
||||
return request({
|
||||
url: '/price/surcharge/rel',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
/** 解绑附加费关联 */
|
||||
export function delSurchargeRel(relIds) {
|
||||
return request({
|
||||
url: '/price/surcharge/rel/' + relIds,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
|
||||
/** 新增附加费配置 */
|
||||
export function addSurcharge(data) {
|
||||
return request({
|
||||
|
||||
@@ -40,6 +40,7 @@
|
||||
|
||||
<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="Money" @click="openSurcharges(row)" v-hasPermi="['price:surcharge:query']">附加费</el-button>
|
||||
<el-button :disabled="isProductActive(row)" :title="isProductActive(row) ? '已生效不可编辑' : ''" link type="primary" icon="Edit" @click="handleUpdate(row)" v-hasPermi="['price:product:edit']">编辑</el-button>
|
||||
<el-button :disabled="isProductActive(row)" :title="isProductActive(row) ? '已生效不可删除' : ''" link type="primary" icon="Delete" @click="handleDelete(row.productId)" v-hasPermi="['price:product:remove']">删除</el-button>
|
||||
</template>
|
||||
@@ -149,6 +150,75 @@
|
||||
</el-table>
|
||||
</el-drawer>
|
||||
|
||||
<el-drawer v-model="surchargeOpen" size="920px" :title="surchargeTitle" append-to-body>
|
||||
<div class="mb8" style="display: flex; justify-content: space-between">
|
||||
<el-button type="primary" plain icon="Plus" @click="handleRelAdd" v-hasPermi="['price:surcharge:add']">新增关联</el-button>
|
||||
</div>
|
||||
<el-table v-loading="surchargeLoading" :data="surchargeList" border max-height="calc(100vh - 160px)" empty-text="该产品暂无关联附加费">
|
||||
<el-table-column label="附加费名称" prop="scName" min-width="140" show-overflow-tooltip />
|
||||
<el-table-column label="计费方式" width="110" align="center">
|
||||
<template #default="{ row }">{{ chargeTypeLabel(row.chargeType) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="计费数值" width="140" align="right">
|
||||
<template #default="{ row }">
|
||||
<span class="charge-value">{{ formatChargeValue(row) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="取值方式" width="100" align="center">
|
||||
<template #default="{ row }">{{ roundModeLabel(row.roundMode) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="适用国家" width="110" align="center">
|
||||
<template #default="{ row }">{{ countryLabel(row.countryCode) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="作用范围" width="170" align="center">
|
||||
<template #default="{ row }">
|
||||
<el-tag v-if="row.detailId == null" type="primary" size="small" effect="plain">产品级 · 全部明细</el-tag>
|
||||
<el-tag v-else type="warning" size="small" effect="plain">{{ row.countryName || '-' }} · {{ row.weightMin }}-{{ row.weightMax }}kg</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="状态" width="80" align="center">
|
||||
<template #default="{ row }">
|
||||
<el-tag :type="String(row.ssCode).toLowerCase() === 'on' ? 'success' : 'info'" size="small">
|
||||
{{ String(row.ssCode).toLowerCase() === 'on' ? '有效' : '停用' }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="备注" prop="scNote" min-width="120" show-overflow-tooltip />
|
||||
<el-table-column label="操作" width="90" align="center" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<el-button link type="danger" icon="Delete" @click="handleRelDelete(row.relId)" v-hasPermi="['price:surcharge:remove']">解绑</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-drawer>
|
||||
|
||||
<el-dialog :title="relTitle" v-model="relOpen" width="560px" append-to-body>
|
||||
<el-form ref="relFormRef" :model="relForm" :rules="relRules" label-width="100px">
|
||||
<el-form-item label="附加费" prop="scId">
|
||||
<el-select v-model="relForm.scId" placeholder="请选择附加费" filterable style="width: 100%">
|
||||
<el-option v-for="s in surchargePool" :key="s.scId" :label="s.scName" :value="s.scId" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="作用范围" prop="scope">
|
||||
<el-radio-group v-model="relForm.scope">
|
||||
<el-radio value="PRODUCT">产品级(全部明细)</el-radio>
|
||||
<el-radio value="DETAIL">明细级(指定国家×重量段)</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item v-if="relForm.scope === 'DETAIL'" label="明细" prop="detailId">
|
||||
<el-select v-model="relForm.detailId" placeholder="请选择明细" filterable style="width: 100%">
|
||||
<el-option v-for="d in countryList" :key="d.detailId" :label="detailLabel(d)" :value="d.detailId" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button type="primary" @click="submitRel">确 定</el-button>
|
||||
<el-button @click="relOpen = false">取 消</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<excel-import-dialog
|
||||
ref="importRef"
|
||||
title="产品 Excel 导入"
|
||||
@@ -163,9 +233,12 @@
|
||||
<script setup name="PriceProduct">
|
||||
import ExcelImportDialog from '@/components/ExcelImportDialog'
|
||||
import { listProduct, getProduct, addProduct, updateProduct, delProduct, listProductCountries } from '@/api/price/product'
|
||||
import { listSurchargeByProduct, listSurcharge, addSurchargeRel, delSurchargeRel } from '@/api/price/surcharge'
|
||||
import { listRegionOptions } from '@/api/data/region'
|
||||
import { onMounted } from 'vue'
|
||||
|
||||
const { proxy } = getCurrentInstance()
|
||||
const { bms_product_effect_status, bms_tax_mode } = useDict('bms_product_effect_status', 'bms_tax_mode')
|
||||
const { bms_product_effect_status, bms_tax_mode, bms_round_mode, bms_charge_type } = useDict('bms_product_effect_status', 'bms_tax_mode', 'bms_round_mode', 'bms_charge_type')
|
||||
const tableRef = ref()
|
||||
const importRef = ref()
|
||||
const formRef = ref()
|
||||
@@ -176,6 +249,18 @@ const countryTitle = ref('')
|
||||
const countryLoading = ref(false)
|
||||
const countryList = ref([])
|
||||
const countryKeyword = ref('')
|
||||
|
||||
const surchargeOpen = ref(false)
|
||||
const surchargeTitle = ref('')
|
||||
const surchargeLoading = ref(false)
|
||||
const surchargeList = ref([])
|
||||
const currentProduct = ref(null)
|
||||
const regionOptions = ref([])
|
||||
|
||||
const surchargePool = ref([])
|
||||
const relOpen = ref(false)
|
||||
const relTitle = ref('')
|
||||
const relFormRef = ref()
|
||||
const filteredCountryList = computed(() => {
|
||||
const kw = countryKeyword.value.trim().toLowerCase()
|
||||
if (!kw) return countryList.value
|
||||
@@ -194,9 +279,10 @@ const columns = [
|
||||
{ prop: 'taxMode', label: '税模式', width: 90, align: 'center', dict: 'bms_tax_mode' },
|
||||
{ prop: 'effectiveDate', label: '生效日期', width: 120, align: 'center' },
|
||||
{ prop: 'countryCount', label: '国家数', width: 80, align: 'center' },
|
||||
{ prop: 'surchargeCount', label: '附加费数', width: 90, align: 'center' },
|
||||
{ prop: 'status', label: '状态', width: 90, align: 'center', slot: 'status' },
|
||||
{ prop: 'updateNote', label: '更新内容', minWidth: 160, showOverflowTooltip: true },
|
||||
{ prop: 'action', label: '操作', width: 240, fixed: 'right', slot: 'action' }
|
||||
{ prop: 'action', label: '操作', width: 300, fixed: 'right', slot: 'action' }
|
||||
]
|
||||
|
||||
const searchColumns = [
|
||||
@@ -343,9 +429,124 @@ function countrySpanMethod({ column, rowIndex }) {
|
||||
while (rowIndex + count < list.length && list[rowIndex + count]?.countryCode === cur) count++
|
||||
return { rowspan: count, colspan: 1 }
|
||||
}
|
||||
|
||||
// ===== 产品附加费关联 =====
|
||||
const relData = reactive({
|
||||
relForm: {},
|
||||
relRules: {
|
||||
scId: [{ required: true, message: '请选择附加费', trigger: 'change' }]
|
||||
}
|
||||
})
|
||||
const { relForm, relRules } = toRefs(relData)
|
||||
|
||||
function openSurcharges(row) {
|
||||
currentProduct.value = row
|
||||
surchargeTitle.value = `${row.productCode} · ${row.productName} · 附加费关联`
|
||||
surchargeOpen.value = true
|
||||
loadSurcharges()
|
||||
}
|
||||
|
||||
function loadSurcharges() {
|
||||
if (!currentProduct.value) return
|
||||
surchargeLoading.value = true
|
||||
listSurchargeByProduct(currentProduct.value.productCode).then(res => {
|
||||
surchargeList.value = res.data || []
|
||||
}).finally(() => {
|
||||
surchargeLoading.value = false
|
||||
})
|
||||
}
|
||||
|
||||
function loadSurchargePool() {
|
||||
return listSurcharge({ ssCode: 'on', pageNum: 1, pageSize: 1000 }).then(res => {
|
||||
surchargePool.value = res.rows || []
|
||||
})
|
||||
}
|
||||
|
||||
function resetRelForm() {
|
||||
relForm.value = {
|
||||
scId: undefined,
|
||||
scope: 'PRODUCT',
|
||||
detailId: undefined
|
||||
}
|
||||
relFormRef.value && relFormRef.value.resetFields()
|
||||
}
|
||||
|
||||
function handleRelAdd() {
|
||||
resetRelForm()
|
||||
relTitle.value = '新增附加费关联'
|
||||
relOpen.value = true
|
||||
loadSurchargePool()
|
||||
}
|
||||
|
||||
function submitRel() {
|
||||
relFormRef.value.validate(valid => {
|
||||
if (!valid) return
|
||||
if (relForm.value.scope === 'DETAIL' && !relForm.value.detailId) {
|
||||
proxy.$modal.msgError('请选择明细')
|
||||
return
|
||||
}
|
||||
const payload = {
|
||||
scId: relForm.value.scId,
|
||||
productId: currentProduct.value ? currentProduct.value.productId : undefined,
|
||||
productCode: currentProduct.value ? currentProduct.value.productCode : undefined,
|
||||
detailId: relForm.value.scope === 'DETAIL' ? relForm.value.detailId : null
|
||||
}
|
||||
addSurchargeRel(payload).then(() => {
|
||||
proxy.$modal.msgSuccess('关联成功')
|
||||
relOpen.value = false
|
||||
loadSurcharges()
|
||||
tableRef.value.refresh()
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
function handleRelDelete(relId) {
|
||||
proxy.$modal.confirm('是否确认解绑该附加费?').then(() => {
|
||||
return delSurchargeRel(relId)
|
||||
}).then(() => {
|
||||
proxy.$modal.msgSuccess('解绑成功')
|
||||
loadSurcharges()
|
||||
tableRef.value.refresh()
|
||||
}).catch(() => {})
|
||||
}
|
||||
|
||||
function detailLabel(d) {
|
||||
const w = d.weightMin != null && d.weightMax != null ? `${d.weightMin}-${d.weightMax}kg` : '-'
|
||||
return `${d.countryName || d.countryCode || '-'} · ${w}`
|
||||
}
|
||||
|
||||
function chargeTypeLabel(val) {
|
||||
const found = bms_charge_type.value.find(c => c.value === val)
|
||||
return found ? found.label : (val || '-')
|
||||
}
|
||||
|
||||
function roundModeLabel(val) {
|
||||
const found = bms_round_mode.value.find(d => d.value === val)
|
||||
return found ? found.label : (val || '-')
|
||||
}
|
||||
|
||||
function formatChargeValue(row) {
|
||||
if (row.chargeValue == null) return '-'
|
||||
const v = Number(row.chargeValue)
|
||||
if (row.chargeType === 'RATE') return (v * 100).toFixed(2) + '%'
|
||||
return v + ' ' + (row.currency || 'CNY')
|
||||
}
|
||||
|
||||
function countryLabel(code) {
|
||||
if (!code) return '全部'
|
||||
const found = regionOptions.value.find(r => r.countryCode2 === code)
|
||||
return found ? (found.countryNameCn || found.countryNameEn || code) : code
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
listRegionOptions().then(res => {
|
||||
regionOptions.value = res.data || []
|
||||
})
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.mb16 { margin-bottom: 16px; }
|
||||
.pre-wrap { white-space: pre-wrap; font-size: 12px; line-height: 1.4; }
|
||||
.charge-value { font-weight: 600; color: #d63031; }
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user