完善租客等级免押与积分管理

This commit is contained in:
yml2213
2026-07-26 18:07:10 +08:00
parent 379536e5c5
commit c594b543d1
24 changed files with 1296 additions and 178 deletions
@@ -11,6 +11,9 @@ export interface AdminUserItem {
risk_status: RiskStatus
credit_score: number
deposit_free_quota_cent: number
deposit_free_manual_quota_cent: number
deposit_free_level_quota_cent: number
deposit_free_effective_quota_cent: number
deposit_free_used_cent: number
deposit_free_remaining_cent: number
renter_growth_points: number
@@ -34,6 +37,11 @@ export interface AdminWalletAdjustPayload {
reference_no?: string
}
export interface AdminGrowthPointsAdjustPayload {
target_points: number
reason: string
}
export interface AdminUserQuery {
keyword?: string
status?: '' | UserStatus
@@ -74,6 +82,17 @@ export async function setAdminUserDepositFreeQuota(id: number, amountCent: numbe
return data.data
}
export async function adjustAdminUserGrowthPoints(
id: number,
payload: AdminGrowthPointsAdjustPayload
) {
const { data } = await apiClient.post<ApiResponse<AdminUserItem>>(
`/admin/users/${id}/growth-points`,
payload
)
return data.data
}
export async function revokeAdminUserRealname(id: number, reason: string) {
const { data } = await apiClient.post<ApiResponse<AdminUserItem>>(
`/admin/users/${id}/revoke-realname`,
@@ -0,0 +1,92 @@
export interface RenterGrowthLevelRule {
code: 'normal' | 'platinum' | 'diamond' | 'peak'
name: string
min_points: number
discount_bps: number
deposit_free_quota_cent: number
}
export interface RenterGrowthConfig {
enabled: boolean
points_per_yuan: number
levels: RenterGrowthLevelRule[]
}
export const defaultRenterGrowthConfig: RenterGrowthConfig = {
enabled: true,
points_per_yuan: 1,
levels: [
{
code: 'normal',
name: '普通',
min_points: 0,
discount_bps: 10000,
deposit_free_quota_cent: 0,
},
{
code: 'platinum',
name: '铂金',
min_points: 300,
discount_bps: 9900,
deposit_free_quota_cent: 50000,
},
{
code: 'diamond',
name: '钻石',
min_points: 1000,
discount_bps: 9800,
deposit_free_quota_cent: 100000,
},
{
code: 'peak',
name: '巅峰',
min_points: 5000,
discount_bps: 9500,
deposit_free_quota_cent: 150000,
},
],
}
export function parseRenterGrowthConfig(raw: string): RenterGrowthConfig {
const parsed = parseRawConfig(raw)
const incomingLevels = Array.isArray(parsed.levels) ? parsed.levels : []
return {
enabled: typeof parsed.enabled === 'boolean' ? parsed.enabled : true,
points_per_yuan: positiveInteger(parsed.points_per_yuan, 1),
levels: defaultRenterGrowthConfig.levels.map(defaultLevel => {
const incoming = incomingLevels.find(level => level?.code === defaultLevel.code)
return {
code: defaultLevel.code,
name: defaultLevel.name,
min_points: nonNegativeInteger(incoming?.min_points, defaultLevel.min_points),
discount_bps: positiveInteger(incoming?.discount_bps, defaultLevel.discount_bps),
deposit_free_quota_cent: nonNegativeInteger(
incoming?.deposit_free_quota_cent,
defaultLevel.deposit_free_quota_cent
),
}
}),
}
}
function parseRawConfig(raw: string): Partial<RenterGrowthConfig> {
try {
return JSON.parse(raw) as Partial<RenterGrowthConfig>
} catch {
return {}
}
}
export function cloneRenterGrowthConfig(config: RenterGrowthConfig): RenterGrowthConfig {
return JSON.parse(JSON.stringify(config)) as RenterGrowthConfig
}
function positiveInteger(value: unknown, fallback: number) {
const number = Number(value)
return Number.isInteger(number) && number > 0 ? number : fallback
}
function nonNegativeInteger(value: unknown, fallback: number) {
const number = Number(value)
return Number.isInteger(number) && number >= 0 ? number : fallback
}