- 新增初始上分备注(日常上分/开户赠金/自定义)及前后台校验与展示 - 优化钱包流水类型与备注显示,区分管理员/代理/玩家上下分 - 修复登录后语言被后端覆盖的问题,登录时同步当前语言到服务端 - 后台代理/玩家表格操作栏重构,充值订单增加备注列 - 前台个人中心、充值、账单与验证码组件体验优化 Co-authored-by: Cursor <cursoragent@cursor.com>
146 lines
3.8 KiB
TypeScript
146 lines
3.8 KiB
TypeScript
import type { InitialDepositRemarkKind } from '@thebet365/shared';
|
|
import { FormValidationError } from '../../i18n/form-validation';
|
|
import { buildInitialDepositRemark } from '../../utils/initial-depositRemark';
|
|
import { assertPlayerUsername } from '../user-form';
|
|
|
|
export interface AgentPlayerCreateForm {
|
|
username: string;
|
|
password: string;
|
|
confirmPassword: string;
|
|
phone: string;
|
|
email: string;
|
|
initialDeposit: number;
|
|
initialDepositRemarkKind: InitialDepositRemarkKind | '';
|
|
initialDepositRemarkCustom: string;
|
|
}
|
|
|
|
export interface AgentPlayerRow {
|
|
id: string;
|
|
username: string;
|
|
status: string;
|
|
createdAt: string;
|
|
inviteCode?: string | null;
|
|
cashbackRate?: string;
|
|
wallet?: { availableBalance: string; frozenBalance?: string };
|
|
}
|
|
|
|
export interface AgentPlayerDetail {
|
|
id: string;
|
|
username: string;
|
|
status: string;
|
|
phone: string | null;
|
|
email: string | null;
|
|
managedPassword: string | null;
|
|
availableBalance: string;
|
|
frozenBalance: string;
|
|
lastLoginAt: string | null;
|
|
loginFailCount: number;
|
|
betCount: number;
|
|
totalStake: string;
|
|
totalReturn: string;
|
|
createdAt: string;
|
|
}
|
|
|
|
export interface AgentPlayerEditForm {
|
|
id: string;
|
|
username: string;
|
|
status: string;
|
|
phone: string;
|
|
email: string;
|
|
managedPassword: string | null;
|
|
newPassword: string;
|
|
availableBalance: string;
|
|
frozenBalance: string;
|
|
betCount: number;
|
|
totalStake: string;
|
|
totalReturn: string;
|
|
lastLoginAt: string | null;
|
|
loginFailCount: number;
|
|
}
|
|
|
|
export function emptyAgentPlayerCreateForm(): AgentPlayerCreateForm {
|
|
return {
|
|
username: '',
|
|
password: '',
|
|
confirmPassword: '',
|
|
phone: '',
|
|
email: '',
|
|
initialDeposit: 0,
|
|
initialDepositRemarkKind: '',
|
|
initialDepositRemarkCustom: '',
|
|
};
|
|
}
|
|
|
|
export function buildAgentCreatePlayerPayload(form: AgentPlayerCreateForm) {
|
|
assertPlayerUsername(form.username);
|
|
if (form.password.length < 8) throw new FormValidationError('err.password_min');
|
|
if (form.password !== form.confirmPassword) throw new FormValidationError('err.password_mismatch');
|
|
if (form.initialDeposit < 0) throw new FormValidationError('err.amount_negative');
|
|
|
|
return {
|
|
username: form.username.trim(),
|
|
password: form.password,
|
|
phone: form.phone.trim() || undefined,
|
|
email: form.email.trim() || undefined,
|
|
initialDeposit: form.initialDeposit > 0 ? form.initialDeposit : undefined,
|
|
remark: buildInitialDepositRemark(
|
|
form.initialDeposit,
|
|
form.initialDepositRemarkKind,
|
|
form.initialDepositRemarkCustom,
|
|
'agent',
|
|
),
|
|
};
|
|
}
|
|
|
|
export function emptyAgentPlayerEditForm(): AgentPlayerEditForm {
|
|
return {
|
|
id: '',
|
|
username: '',
|
|
status: 'ACTIVE',
|
|
phone: '',
|
|
email: '',
|
|
managedPassword: null,
|
|
newPassword: '',
|
|
availableBalance: '0',
|
|
frozenBalance: '0',
|
|
betCount: 0,
|
|
totalStake: '0',
|
|
totalReturn: '0',
|
|
lastLoginAt: null,
|
|
loginFailCount: 0,
|
|
};
|
|
}
|
|
|
|
export function editFormFromAgentDetail(d: AgentPlayerDetail): AgentPlayerEditForm {
|
|
return {
|
|
id: d.id,
|
|
username: d.username,
|
|
status: d.status,
|
|
phone: d.phone ?? '',
|
|
email: d.email ?? '',
|
|
managedPassword: d.managedPassword,
|
|
newPassword: '',
|
|
availableBalance: d.availableBalance,
|
|
frozenBalance: d.frozenBalance,
|
|
betCount: d.betCount,
|
|
totalStake: d.totalStake,
|
|
totalReturn: d.totalReturn,
|
|
lastLoginAt: d.lastLoginAt,
|
|
loginFailCount: d.loginFailCount,
|
|
};
|
|
}
|
|
|
|
export function buildAgentUpdatePlayerPayload(form: AgentPlayerEditForm) {
|
|
assertPlayerUsername(form.username);
|
|
if (form.newPassword && form.newPassword.length < 8) {
|
|
throw new FormValidationError('err.password_min');
|
|
}
|
|
|
|
return {
|
|
username: form.username.trim(),
|
|
phone: form.phone.trim() || undefined,
|
|
email: form.email.trim() || undefined,
|
|
password: form.newPassword.trim() || undefined,
|
|
};
|
|
}
|