feat(invitation): 支持分销站点自主配置返利比例与权限隔离
- 后端新增分站专属配置及审计接口(/api/distribution/invitation-config 等),基于分站管理员严格鉴权隔离 - 分销独立后台新增「邀请返利设置」页面(Invitations.tsx),支持分站管理员自主开启/调整返利比例并查看本站流水 - 主站后台邀请接口路径补齐 /admin 前缀,解决 404/401 鉴权作用域问题 - 验证方式:backend 单元测试全数通过,distribution-admin 类型与构建检查通过
This commit is contained in:
@@ -880,3 +880,85 @@ export async function testSiteSMSConfig(siteID: number, payload: TestSiteSMSConf
|
||||
const resp = await api.post<ApiResponse<{ message: string }>>(`/admin/distribution/sites/${siteID}/sms-config/test`, payload)
|
||||
return extract(resp)
|
||||
}
|
||||
|
||||
export interface InvitationRebateConfig {
|
||||
distribution_site_id: number
|
||||
first_month_rate: number
|
||||
second_month_rate: number
|
||||
subsequent_rate: number
|
||||
enabled: boolean
|
||||
updated_at?: string
|
||||
}
|
||||
|
||||
export interface InvitedUserItem {
|
||||
id: number
|
||||
inviter_id: number
|
||||
inviter_phone?: string
|
||||
inviter_nickname?: string
|
||||
invitee_id: number
|
||||
invitee_phone?: string
|
||||
invitee_nickname?: string
|
||||
invite_code: string
|
||||
status: string
|
||||
verified_at?: string
|
||||
created_at: string
|
||||
}
|
||||
|
||||
export interface RebateLedgerItem {
|
||||
id: number
|
||||
order_id: number
|
||||
order_no: string
|
||||
inviter_id: number
|
||||
inviter_phone?: string
|
||||
inviter_nickname?: string
|
||||
invitee_id: number
|
||||
invitee_phone?: string
|
||||
invitee_nickname?: string
|
||||
trade_role: 'buyer' | 'seller'
|
||||
order_profit_basis_cent: number
|
||||
single_side_basis_cent: number
|
||||
rate_applied: number
|
||||
days_since_verified: number
|
||||
cycle_stage: string
|
||||
rebate_amount_cent: number
|
||||
status: string
|
||||
settled_at: string
|
||||
}
|
||||
|
||||
export async function fetchSiteInvitationConfig(siteID?: number): Promise<InvitationRebateConfig> {
|
||||
const url = siteID ? `/distribution/sites/${siteID}/invitation-config` : '/distribution/invitation-config'
|
||||
const resp = await api.get<ApiResponse<InvitationRebateConfig>>(url)
|
||||
return extract(resp)
|
||||
}
|
||||
|
||||
export async function updateSiteInvitationConfig(
|
||||
siteID: number,
|
||||
payload: {
|
||||
first_month_rate: number
|
||||
second_month_rate: number
|
||||
subsequent_rate: number
|
||||
enabled: boolean
|
||||
}
|
||||
): Promise<InvitationRebateConfig> {
|
||||
const url = siteID ? `/distribution/sites/${siteID}/invitation-config` : '/distribution/invitation-config'
|
||||
const resp = await api.put<ApiResponse<InvitationRebateConfig>>(url, payload)
|
||||
return extract(resp)
|
||||
}
|
||||
|
||||
export async function fetchSiteInvitations(
|
||||
siteID: number,
|
||||
params: { page: number; page_size: number; phone?: string; invite_code?: string }
|
||||
): Promise<{ items: InvitedUserItem[]; total: number; page: number; page_size: number }> {
|
||||
const url = siteID ? `/distribution/sites/${siteID}/invitations` : '/distribution/invitations'
|
||||
const resp = await api.get<ApiResponse<{ items: InvitedUserItem[]; total: number; page: number; page_size: number }>>(url, { params })
|
||||
return extract(resp)
|
||||
}
|
||||
|
||||
export async function fetchSiteRebates(
|
||||
siteID: number,
|
||||
params: { page: number; page_size: number; order_no?: string; inviter_phone?: string; invitee_phone?: string }
|
||||
): Promise<{ items: RebateLedgerItem[]; total: number; page: number; page_size: number }> {
|
||||
const url = siteID ? `/distribution/sites/${siteID}/invitation-rebates` : '/distribution/invitation-rebates'
|
||||
const resp = await api.get<ApiResponse<{ items: RebateLedgerItem[]; total: number; page: number; page_size: number }>>(url, { params })
|
||||
return extract(resp)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user