分销后台前端对接与结算明细接口
- 新增 GET /admin/distribution/settlement-batches/:id/items 明细查询 - distribution-admin 重构为 react-router 多页面:仪表盘/网站/规则(启停)/订单(筛选分页)/结算(创建/明细/结算)/支付通道(绑定解绑)/账号展示(上下架) - axios 统一 401 提示,引导回主站后台登录;金额统一整数分格式化 - npm run build(tsc 严格模式) 通过
This commit is contained in:
@@ -0,0 +1,242 @@
|
||||
import axios from 'axios'
|
||||
import { Modal } from 'antd'
|
||||
|
||||
const api = axios.create({ baseURL: '/api', withCredentials: true })
|
||||
|
||||
interface ApiResponse<T> { data: T; code?: number; message?: string }
|
||||
|
||||
let authNoticeShown = false
|
||||
|
||||
api.interceptors.response.use(
|
||||
(resp) => resp,
|
||||
(error) => {
|
||||
// 后台鉴权依赖主站 HttpOnly cookie;401 说明未登录或会话过期。
|
||||
if (error?.response?.status === 401 && !authNoticeShown) {
|
||||
authNoticeShown = true
|
||||
Modal.warning({
|
||||
title: '登录状态失效',
|
||||
content: '请先在主站后台登录管理员账号,再返回本页面。',
|
||||
onOk: () => { authNoticeShown = false },
|
||||
})
|
||||
}
|
||||
return Promise.reject(error)
|
||||
},
|
||||
)
|
||||
|
||||
export function extract<T>(resp: { data: ApiResponse<T> }): T {
|
||||
return resp.data.data
|
||||
}
|
||||
|
||||
export function formatMoney(cent: number | undefined | null): string {
|
||||
return `¥${((cent ?? 0) / 100).toFixed(2)}`
|
||||
}
|
||||
|
||||
export interface Site {
|
||||
id: number
|
||||
site_code: string
|
||||
site_name: string
|
||||
domain: string
|
||||
status: string
|
||||
display_account_enabled: boolean
|
||||
tax_enabled: boolean
|
||||
tax_rate_bps: number
|
||||
created_at: string
|
||||
}
|
||||
|
||||
export interface Rule {
|
||||
id: number
|
||||
site_id?: number
|
||||
mode: string
|
||||
version: number
|
||||
status: string
|
||||
platform_receive_ratio: number
|
||||
platform_sell_ratio: number
|
||||
distributor_receive_ratio: number
|
||||
distributor_sell_ratio: number
|
||||
distributor_a_ratio: number
|
||||
distributor_b_ratio: number
|
||||
service_fee_value: number
|
||||
service_fee_unit: string
|
||||
payment_fee_bps: number
|
||||
tax_enabled: boolean
|
||||
tax_rate_bps: number
|
||||
effective_from: string
|
||||
effective_to?: string
|
||||
}
|
||||
|
||||
export interface DistributionOrder {
|
||||
order_id: number
|
||||
order_no: string
|
||||
site_id: number
|
||||
status: string
|
||||
refund_status: string
|
||||
settlement_status: string
|
||||
distribution_mode: string
|
||||
net_paid_amount_cent: number
|
||||
payment_fee_cent: number
|
||||
service_fee_cent: number
|
||||
markup_amount_cent: number
|
||||
tax_amount_cent: number
|
||||
split_base_amount_cent: number
|
||||
rounding_adjustment_cent: number
|
||||
created_at: string
|
||||
}
|
||||
|
||||
export interface OrderPage {
|
||||
items: DistributionOrder[]
|
||||
total: number
|
||||
page: number
|
||||
page_size: number
|
||||
}
|
||||
|
||||
export interface AccountDisplay {
|
||||
id: number
|
||||
site_id: number
|
||||
account_id: number
|
||||
listing_id: number
|
||||
display_status: string
|
||||
}
|
||||
|
||||
export interface PaymentChannel {
|
||||
id: number
|
||||
site_id: number
|
||||
config_id: number
|
||||
priority: number
|
||||
status: string
|
||||
}
|
||||
|
||||
export interface SettlementBatch {
|
||||
id: number
|
||||
site_id: number
|
||||
batch_no: string
|
||||
period_start: string
|
||||
period_end: string
|
||||
total_amount_cent: number
|
||||
status: string
|
||||
}
|
||||
|
||||
export interface SettlementItem {
|
||||
id: number
|
||||
order_id: number
|
||||
party_role: string
|
||||
amount_cent: number
|
||||
status: string
|
||||
}
|
||||
|
||||
export async function listSites(): Promise<Site[]> {
|
||||
const resp = await api.get<ApiResponse<{ items: Site[] }>>('/admin/distribution/sites')
|
||||
return extract(resp).items ?? []
|
||||
}
|
||||
|
||||
export async function listRules(siteID?: number, mode?: string): Promise<Rule[]> {
|
||||
const resp = await api.get<ApiResponse<{ items: Rule[] }>>('/admin/distribution/rules', {
|
||||
params: { site_id: siteID || undefined, mode: mode || undefined },
|
||||
})
|
||||
return extract(resp).items ?? []
|
||||
}
|
||||
|
||||
export interface CreateRulePayload {
|
||||
site_id?: number
|
||||
mode: string
|
||||
distributor_receive_ratio?: number
|
||||
platform_sell_ratio?: number
|
||||
distributor_sell_ratio?: number
|
||||
platform_receive_ratio?: number
|
||||
distributor_a_ratio?: number
|
||||
distributor_b_ratio?: number
|
||||
service_fee_value: number
|
||||
service_fee_unit: string
|
||||
payment_fee_bps: number
|
||||
tax_enabled: boolean
|
||||
tax_rate_bps: number
|
||||
effective_from?: string
|
||||
}
|
||||
|
||||
export async function createRule(payload: CreateRulePayload): Promise<Rule> {
|
||||
const resp = await api.post<ApiResponse<Rule>>('/admin/distribution/rules', payload)
|
||||
return extract(resp)
|
||||
}
|
||||
|
||||
export async function updateRuleStatus(id: number, status: string): Promise<Rule> {
|
||||
const resp = await api.put<ApiResponse<Rule>>(`/admin/distribution/rules/${id}/status`, { status })
|
||||
return extract(resp)
|
||||
}
|
||||
|
||||
export async function listOrders(params: {
|
||||
kind?: string
|
||||
status?: string
|
||||
siteID?: number
|
||||
page?: number
|
||||
pageSize?: number
|
||||
}): Promise<OrderPage> {
|
||||
const resp = await api.get<ApiResponse<OrderPage>>('/admin/distribution/orders', {
|
||||
params: {
|
||||
kind: params.kind || undefined,
|
||||
status: params.status || undefined,
|
||||
site_id: params.siteID || undefined,
|
||||
page: params.page || 1,
|
||||
page_size: params.pageSize || 20,
|
||||
},
|
||||
})
|
||||
return extract(resp)
|
||||
}
|
||||
|
||||
export async function listAccountDisplays(siteID: number, status?: string): Promise<AccountDisplay[]> {
|
||||
const resp = await api.get<ApiResponse<{ items: AccountDisplay[] }>>('/admin/distribution/accounts', {
|
||||
params: { site_id: siteID, status: status || undefined },
|
||||
})
|
||||
return extract(resp).items ?? []
|
||||
}
|
||||
|
||||
export async function updateAccountDisplay(id: number, displayStatus: string): Promise<AccountDisplay> {
|
||||
const resp = await api.put<ApiResponse<AccountDisplay>>(`/admin/distribution/accounts/${id}/display`, {
|
||||
display_status: displayStatus,
|
||||
})
|
||||
return extract(resp)
|
||||
}
|
||||
|
||||
export async function listPaymentChannels(siteID: number): Promise<PaymentChannel[]> {
|
||||
const resp = await api.get<ApiResponse<{ items: PaymentChannel[] }>>('/admin/distribution/payment-channels', {
|
||||
params: { site_id: siteID },
|
||||
})
|
||||
return extract(resp).items ?? []
|
||||
}
|
||||
|
||||
export async function bindPaymentChannel(siteID: number, configID: number, priority: number): Promise<PaymentChannel> {
|
||||
const resp = await api.post<ApiResponse<PaymentChannel>>(
|
||||
'/admin/distribution/payment-channels',
|
||||
{ config_id: configID, priority },
|
||||
{ params: { site_id: siteID } },
|
||||
)
|
||||
return extract(resp)
|
||||
}
|
||||
|
||||
export async function unbindPaymentChannel(id: number): Promise<void> {
|
||||
await api.delete(`/admin/distribution/payment-channels/${id}`)
|
||||
}
|
||||
|
||||
export async function listSettlementBatches(siteID: number): Promise<SettlementBatch[]> {
|
||||
const resp = await api.get<ApiResponse<{ items: SettlementBatch[] }>>('/admin/distribution/settlement-batches', {
|
||||
params: { site_id: siteID },
|
||||
})
|
||||
return extract(resp).items ?? []
|
||||
}
|
||||
|
||||
export async function createSettlementBatch(siteID: number, periodStart: string, periodEnd: string): Promise<SettlementBatch> {
|
||||
const resp = await api.post<ApiResponse<SettlementBatch>>('/admin/distribution/settlement-batches', {
|
||||
site_id: siteID,
|
||||
period_start: periodStart,
|
||||
period_end: periodEnd,
|
||||
})
|
||||
return extract(resp)
|
||||
}
|
||||
|
||||
export async function settleBatch(id: number): Promise<SettlementBatch> {
|
||||
const resp = await api.post<ApiResponse<SettlementBatch>>(`/admin/distribution/settlement-batches/${id}/settle`)
|
||||
return extract(resp)
|
||||
}
|
||||
|
||||
export async function listSettlementItems(batchID: number): Promise<SettlementItem[]> {
|
||||
const resp = await api.get<ApiResponse<{ items: SettlementItem[] }>>(`/admin/distribution/settlement-batches/${batchID}/items`)
|
||||
return extract(resp).items ?? []
|
||||
}
|
||||
Reference in New Issue
Block a user