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
@@ -8,6 +8,7 @@ import {
Button,
Form,
Input,
InputNumber,
Row,
Col,
Divider,
@@ -30,6 +31,7 @@ import {
import {
listSites,
updateSiteBranding,
updateSite,
getMe,
type Site,
type SiteBrandingPayload,
@@ -71,6 +73,8 @@ export default function SiteSettings() {
icp: '',
contact: '',
})
const [receiveRatioDelta, setReceiveRatioDelta] = useState(0)
const [savingRatio, setSavingRatio] = useState(false)
const loadSite = useCallback(async (id: number) => {
setLoading(true)
@@ -100,6 +104,7 @@ export default function SiteSettings() {
} catch {
setFooterInfo({})
}
setReceiveRatioDelta(Math.max(0, found.receive_ratio_delta || 0))
}
} catch {
message.error('加载站点设置失败')
@@ -181,6 +186,22 @@ export default function SiteSettings() {
setAnnouncements(announcements.filter((_, i) => i !== index))
}
async function handleSaveReceiveRatio() {
if (!siteID) return
setSavingRatio(true)
try {
const updated = await updateSite(siteID, { receive_ratio_delta: receiveRatioDelta })
setCurrentSite(updated)
setReceiveRatioDelta(Math.max(0, updated.receive_ratio_delta || 0))
message.success('收号比例已保存,本站上传账号将按新比例计价')
} catch (error: unknown) {
const respMessage = (error as { response?: { data?: { message?: string } } })?.response?.data?.message
message.error(respMessage || '保存收号比例失败')
} finally {
setSavingRatio(false)
}
}
async function handleSave() {
if (!siteID) return
setSaving(true)
@@ -249,6 +270,35 @@ export default function SiteSettings() {
</Space>
</div>
<Card loading={loading}>
<Space direction="vertical" style={{ width: '100%' }} size="middle">
<div>
<Typography.Title level={5} style={{ marginBottom: 4 }}>
本站收号比例
</Typography.Title>
<Typography.Text type="secondary">
主站回收比例是上限。下调点数越大,号主底价越高、本站利润空间越大,但不能高于主站比例。0 表示与主站一致。
</Typography.Text>
</div>
<Space wrap align="center">
<Typography.Text>相对主站下调</Typography.Text>
<InputNumber
min={0}
max={20}
step={0.1}
precision={1}
value={receiveRatioDelta}
onChange={(value) => setReceiveRatioDelta(Math.max(0, Number(value || 0)))}
addonAfter="点"
style={{ width: 160 }}
/>
<Button type="primary" icon={<SaveOutlined />} loading={savingRatio} onClick={() => void handleSaveReceiveRatio()}>
保存收号比例
</Button>
</Space>
</Space>
</Card>
<Row gutter={24}>
{/* Left Visual Form Customizer */}
<Col xs={24} lg={14}>