feat(distribution): 分站可下调收号比例且不超过主站上限

让分销站能按自身能力下调收号比例扩大利润,同时把主站回收比例作为硬边界,避免分站把比例加得比主站更高。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
yml2213
2026-09-15 20:35:30 +08:00
co-authored by Cursor
parent 1c86bef765
commit c9d9160ff4
27 changed files with 1159 additions and 106 deletions
@@ -12,6 +12,7 @@ export interface DistributionSite {
tax_rate_bps: number
settlement_hold_days: number
listing_qrcode_url?: string
receive_ratio_delta?: number
created_at: string
}
@@ -152,6 +153,7 @@ export async function updateDistributionSite(
| 'tax_rate_bps'
| 'settlement_hold_days'
| 'listing_qrcode_url'
| 'receive_ratio_delta'
>
>
) {
@@ -10,6 +10,7 @@ import {
Clock,
Picture,
Upload,
Coin,
} from '@element-plus/icons-vue'
import {
fetchDistributionSites,
@@ -45,6 +46,14 @@ const settlementForm = reactive({
settlement_hold_days: defaultSettlementHoldDays.value,
})
const receiveRatioDialogVisible = ref(false)
const receiveRatioSubmitting = ref(false)
const receiveRatioForm = reactive({
site_id: 0,
site_name: '',
receive_ratio_delta: 0,
})
const qrDialogVisible = ref(false)
const qrSubmitting = ref(false)
const qrUploading = ref(false)
@@ -77,6 +86,29 @@ async function handleSettlementSubmit() {
}
}
function handleOpenReceiveRatio(row: DistributionSite) {
receiveRatioForm.site_id = row.id
receiveRatioForm.site_name = row.site_name
receiveRatioForm.receive_ratio_delta = Number(row.receive_ratio_delta || 0)
receiveRatioDialogVisible.value = true
}
async function handleReceiveRatioSubmit() {
receiveRatioSubmitting.value = true
try {
await updateDistributionSite(receiveRatioForm.site_id, {
receive_ratio_delta: Number(receiveRatioForm.receive_ratio_delta),
})
ElMessage.success(`【${receiveRatioForm.site_name}】收号比例下调已更新`)
receiveRatioDialogVisible.value = false
await loadSites()
} catch (err) {
ElMessage.error(readError(err, '更新收号比例失败'))
} finally {
receiveRatioSubmitting.value = false
}
}
function handleOpenQrcode(row: DistributionSite) {
qrForm.site_id = row.id
qrForm.site_name = row.site_name
@@ -257,8 +289,8 @@ onMounted(() => {
<div>
<h2 class="page-title">分销站点管理</h2>
<p class="page-subtitle">
开通分销站、配置结算冷却期与发布群固定二维码。利润按 35% 收号 / 40% 卖出 / 25%
服务费切分。
开通分销站、配置结算冷却期、收号比例上限与发布群固定二维码。利润按 35% 收号 / 40% 卖出 /
25% 服务费切分。
</p>
</div>
<div class="header-actions">
@@ -314,6 +346,17 @@ onMounted(() => {
</el-tag>
</template>
</el-table-column>
<el-table-column label="收号下调" width="110">
<template #default="{ row }">
<el-tag :type="Number(row.receive_ratio_delta || 0) > 0 ? 'warning' : 'info'" size="small">
{{
Number(row.receive_ratio_delta || 0) > 0
? `-${Number(row.receive_ratio_delta).toFixed(1)} 点`
: '与主站一致'
}}
</el-tag>
</template>
</el-table-column>
<el-table-column label="发布群二维码" width="120" align="center">
<template #default="{ row }">
<AuthImage
@@ -331,7 +374,7 @@ onMounted(() => {
{{ formatDateTime(row.created_at) }}
</template>
</el-table-column>
<el-table-column label="操作" width="280" fixed="right">
<el-table-column label="操作" width="340" fixed="right">
<template #default="{ row }">
<el-button
type="primary"
@@ -345,6 +388,9 @@ onMounted(() => {
<el-button type="primary" link :icon="Clock" @click="handleOpenSettlement(row)">
结算设置
</el-button>
<el-button type="primary" link :icon="Coin" @click="handleOpenReceiveRatio(row)">
收号比例
</el-button>
<el-button type="primary" link :icon="Picture" @click="handleOpenQrcode(row)">
二维码
</el-button>
@@ -522,6 +568,43 @@ onMounted(() => {
</template>
</el-dialog>
<!-- 分站收号比例(主站为上限) -->
<el-dialog
v-model="receiveRatioDialogVisible"
title="分站收号比例"
width="520px"
destroy-on-close
>
<el-alert
type="info"
:closable="false"
show-icon
title="主站回收比例是上限。下调点数越大,号主底价越高、分站利润空间越大,但不能高于主站比例。0 表示与主站一致。"
style="margin-bottom: 16px"
/>
<el-form label-width="110px">
<el-form-item label="分销站点">
<el-input :model-value="receiveRatioForm.site_name" disabled />
</el-form-item>
<el-form-item label="相对主站下调">
<el-input-number
v-model="receiveRatioForm.receive_ratio_delta"
:min="0"
:max="20"
:step="0.1"
:precision="1"
/>
<span class="settlement-hint">点(0-20)</span>
</el-form-item>
</el-form>
<template #footer>
<el-button @click="receiveRatioDialogVisible = false">取消</el-button>
<el-button type="primary" :loading="receiveRatioSubmitting" @click="handleReceiveRatioSubmit">
保存设置
</el-button>
</template>
</el-dialog>
<!-- 发布群固定二维码 -->
<el-dialog v-model="qrDialogVisible" title="发布群固定二维码" width="520px" destroy-on-close>
<el-alert