diff --git a/src/components/AdjustBalanceModals.tsx b/src/components/AdjustBalanceModals.tsx
index 8c287b7..c9e0d26 100644
--- a/src/components/AdjustBalanceModals.tsx
+++ b/src/components/AdjustBalanceModals.tsx
@@ -3,7 +3,7 @@
// 调金币 / 调现金弹窗(受控)。列表页与用户详情页共用,避免两处各写一套。
// 每个弹窗自带「增减 / 设为指定值」两种模式;打开时拉一次 360 概览展示当前余额。
import { useEffect, useState } from 'react';
-import { App, Form, Input, InputNumber, Modal, Segmented } from 'antd';
+import { App, Form, Input, InputNumber, Modal, Radio, Segmented } from 'antd';
import { api, errMsg } from '@/lib/api';
import { yuan } from '@/lib/format';
import type { UserOverview } from '@/lib/types';
@@ -17,15 +17,19 @@ interface ModalProps {
onDone?: () => void; // 调整成功后回调(刷新余额/列表)
}
-const balanceLine = (balances: { coin: number; cashCents: number } | null) => (
+type Balances = { coin: number; cashCents: number; inviteCashCents: number };
+
+const balanceLine = (balances: Balances | null) => (
- 当前余额:金币 {balances ? balances.coin : '…'} | 现金 {balances ? yuan(balances.cashCents) : '…'}
+ 当前余额:金币 {balances ? balances.coin : '…'} | 现金(金币兑现金){' '}
+ {balances ? yuan(balances.cashCents) : '…'} | 邀请奖励金{' '}
+ {balances ? yuan(balances.inviteCashCents) : '…'}
);
// 弹窗打开时拉一次该用户余额;用户切换/关闭时丢弃过期响应(alive 标记防竞态)。
function useBalances(userId: number | undefined, open: boolean) {
- const [balances, setBalances] = useState<{ coin: number; cashCents: number } | null>(null);
+ const [balances, setBalances] = useState(null);
useEffect(() => {
if (!open || userId == null) {
setBalances(null);
@@ -36,7 +40,12 @@ function useBalances(userId: number | undefined, open: boolean) {
api
.get(`/admin/api/users/${userId}`)
.then((r) => {
- if (alive) setBalances({ coin: r.data.coin_balance, cashCents: r.data.cash_balance_cents });
+ if (alive)
+ setBalances({
+ coin: r.data.coin_balance,
+ cashCents: r.data.cash_balance_cents,
+ inviteCashCents: r.data.invite_cash_balance_cents,
+ });
})
.catch(() => {});
return () => {
@@ -113,39 +122,39 @@ export function AdjustCoinModal({ user, open, onClose, onDone }: ModalProps) {
export function AdjustCashModal({ user, open, onClose, onDone }: ModalProps) {
const { message } = App.useApp();
const [form] = Form.useForm();
- const [mode, setMode] = useState<'delta' | 'set'>('delta');
+ // 操作方式改为表单必选项(无默认、手动选);用 watch 驱动金额栏文案/最小值
+ const mode = Form.useWatch('mode', form) as 'delta' | 'set' | undefined;
const balances = useBalances(user?.id, open);
useEffect(() => {
- if (open) {
- setMode('delta');
- form.resetFields();
- }
+ if (open) form.resetFields(); // 目标账户 / 操作方式 都重置为「未选」
}, [open, form]);
// 输入元,×100 转分后调后端(主要给无现金用户发钱直接测试提现)
const submit = async () => {
if (!user) return;
- const v = await form.validateFields();
+ const v = await form.validateFields(); // 任一必填/必选缺失 → 该项下方红字 + 阻断提交
const amountCents = Math.round(Number(v.amount_yuan) * 100);
- if (mode === 'delta' && amountCents === 0) {
+ if (v.mode === 'delta' && amountCents === 0) {
message.warning('金额不能为 0(且不小于 1 分)');
return;
}
- if (mode === 'set' && amountCents < 0) {
+ if (v.mode === 'set' && amountCents < 0) {
message.warning('目标金额不能为负');
return;
}
+ const acctName = v.account === 'invite_cash' ? '邀请奖励金' : '现金';
try {
await api.post(`/admin/api/users/${user.id}/cash`, {
- mode,
+ account: v.account,
+ mode: v.mode,
amount_cents: amountCents,
reason: v.reason,
});
message.success(
- mode === 'set'
- ? `已设为 ¥${(amountCents / 100).toFixed(2)} 现金`
- : `已${amountCents > 0 ? '发放' : '扣减'} ¥${(Math.abs(amountCents) / 100).toFixed(2)} 现金`,
+ v.mode === 'set'
+ ? `已设为 ¥${(amountCents / 100).toFixed(2)} ${acctName}`
+ : `已${amountCents > 0 ? '发放' : '扣减'} ¥${(Math.abs(amountCents) / 100).toFixed(2)} ${acctName}`,
);
onClose();
onDone?.();
@@ -164,10 +173,20 @@ export function AdjustCashModal({ user, open, onClose, onDone }: ModalProps) {
>
{balanceLine(balances)}
- setMode(v as 'delta' | 'set')}
+
+
+
+
+
@@ -194,7 +213,7 @@ export function AdjustCashModal({ user, open, onClose, onDone }: ModalProps) {
min={mode === 'set' ? 0 : undefined}
/>
-
+
diff --git a/src/lib/types.ts b/src/lib/types.ts
index 5e99d1d..c3a95c9 100644
--- a/src/lib/types.ts
+++ b/src/lib/types.ts
@@ -81,6 +81,7 @@ export interface UserOverview {
user: UserListItem;
coin_balance: number;
cash_balance_cents: number;
+ invite_cash_balance_cents: number; // 邀请奖励金余额(与 cash_balance_cents 物理隔离)
total_coin_earned: number;
comparison_total: number;
comparison_success: number;