feat(admin): 更新登录表单样式,添加图标并优化用户体验;增强代理线路详情面板,支持直接玩家计数功能
Some checks failed
lotteryadmin CI / build (push) Has been cancelled

This commit is contained in:
2026-06-29 15:27:14 +08:00
parent 1c431ff0ea
commit d7761218ea
6 changed files with 186 additions and 132 deletions

View File

@@ -34,6 +34,8 @@ export type AgentLineDetailPanelProps = {
profileError?: string | null;
childAgents: AgentNodeRow[];
childCountById: Map<number, number>;
directPlayerCount?: number;
onDirectPlayerCountChange?: (count: number) => void;
siteCode: string;
parentName: string | null;
detailTab: AgentDetailTab;
@@ -64,6 +66,8 @@ export function AgentLineDetailPanel({
profileError = null,
childAgents,
childCountById,
directPlayerCount,
onDirectPlayerCountChange,
siteCode,
parentName,
detailTab,
@@ -116,6 +120,7 @@ export function AgentLineDetailPanel({
{
key: "players",
label: t("lineUi.tabPlayers", { defaultValue: "直属玩家" }),
count: directPlayerCount,
visible: canViewPlayersTab,
},
];
@@ -224,6 +229,7 @@ export function AgentLineDetailPanel({
agentNodeId={node.id}
allowCreatePlayer={canCreatePlayerAction}
embedded
onTotalChange={onDirectPlayerCountChange}
/>
) : null}
</div>

View File

@@ -524,6 +524,7 @@ export function AgentsConsole(): React.ReactElement {
const [directPlayerCountById, setDirectPlayerCountById] = useState<Map<number, number>>(
() => new Map(),
);
const [selectedDirectPlayerCount, setSelectedDirectPlayerCount] = useState(0);
const prevSelectedNodeIdRef = useRef<number | null>(null);
@@ -590,6 +591,41 @@ export function AgentsConsole(): React.ReactElement {
});
}, [canShowDownlineTab, canShowPlayersTab, canViewProfileTab, selectedNodeId]);
useEffect(() => {
if (selectedNodeId === null || activeSiteCode.trim() === "") {
setSelectedDirectPlayerCount(0);
return;
}
let cancelled = false;
void getAdminPlayers({
site_code: activeSiteCode.trim(),
agent_node_id: selectedNodeId,
page: 1,
per_page: 1,
})
.then((data) => {
if (cancelled) {
return;
}
setSelectedDirectPlayerCount(data.meta.total);
setDirectPlayerCountById((prev) => {
const next = new Map(prev);
next.set(selectedNodeId, data.meta.total);
return next;
});
})
.catch(() => {
if (!cancelled) {
setSelectedDirectPlayerCount(0);
}
});
return () => {
cancelled = true;
};
}, [activeSiteCode, selectedNodeId]);
useEffect(() => {
if (detailTab !== "downline" || activeSiteCode.trim() === "") {
return;
@@ -1077,6 +1113,8 @@ export function AgentsConsole(): React.ReactElement {
profileError={selectedProfileErr}
childAgents={selectedChildAgents}
childCountById={childCountById}
directPlayerCount={selectedDirectPlayerCount}
onDirectPlayerCountChange={setSelectedDirectPlayerCount}
siteCode={activeSiteCode}
parentName={
selectedNode?.parent_id !== null && selectedNode?.parent_id !== undefined

View File

@@ -146,6 +146,8 @@ type AgentsPlayersPanelProps = {
allowCreatePlayer?: boolean;
/** 嵌入代理线路详情 Tab 时使用紧凑顶栏 */
embedded?: boolean;
/** 列表总数变化时同步 Tab 角标等 */
onTotalChange?: (total: number) => void;
};
export function AgentsPlayersPanel({
@@ -153,6 +155,7 @@ export function AgentsPlayersPanel({
agentNodeId,
allowCreatePlayer,
embedded = false,
onTotalChange,
}: AgentsPlayersPanelProps): React.ReactElement {
const { t } = useTranslation(["agents", "players", "common"]);
const router = useRouter();
@@ -269,6 +272,10 @@ export function AgentsPlayersPanel({
void load();
}, [load]);
useEffect(() => {
onTotalChange?.(total);
}, [onTotalChange, total]);
async function savePlayer(): Promise<void> {
if (siteCode.trim() === "") {
toast.error(t("players:siteCodeRequired", { defaultValue: "请填写主站编号" }));