feat(admin,api,player): 代理层级管理、额度上下分与玩家钱包详情

新增代理管理器与二级代理体系,完善信用额度/上下分上下文与冻结策略;代理端玩家与子代理管理增强;玩家端新增钱包详情页与交易筛选优化。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-06-08 15:34:12 +08:00
parent b2216abd0c
commit 414998ce36
54 changed files with 6641 additions and 481 deletions

View File

@@ -24,6 +24,11 @@ import {
shouldCompactAmount as shouldCompact,
} from '../utils/format-amount';
import AdminTableEmpty from '../components/AdminTableEmpty.vue';
import AgentCreditContext from '../components/AgentCreditContext.vue';
import {
fetchAdminAgentCreditContext,
type AgentCreditAdjustContext,
} from '../utils/agent-credit-context';
const agents = ref<AgentRow[]>([]);
const total = ref(0);
@@ -56,6 +61,8 @@ const detail = ref<AgentDetail | null>(null);
const editingId = ref('');
const creditForm = ref({ amount: 10000, remark: '' });
const creditContext = ref<AgentCreditAdjustContext | null>(null);
const creditContextLoading = ref(false);
onMounted(load);
@@ -130,10 +137,21 @@ async function openEdit(userId: string) {
editVisible.value = true;
}
function openCredit(row: AgentRow) {
async function openCredit(row: AgentRow) {
editingId.value = row.userId;
creditForm.value = { amount: 10000, remark: '' };
creditContext.value = null;
creditVisible.value = true;
creditContextLoading.value = true;
try {
creditContext.value = await fetchAdminAgentCreditContext(row.userId);
} catch (e: unknown) {
const err = e as { response?: { data?: { error?: string } } };
ElMessage.error(err.response?.data?.error ?? t('msg.load_failed'));
creditVisible.value = false;
} finally {
creditContextLoading.value = false;
}
}
async function submitCreate() {
@@ -271,6 +289,7 @@ function creditTypeLabel(type: string) {
</template>
</el-table-column>
<el-table-column prop="directPlayerCount" :label="t('agent.col.direct_players')" width="96" align="center" />
<el-table-column prop="childAgentCount" :label="t('agent.col.sub_agents')" width="96" align="center" />
<el-table-column :label="t('agent.col.cashback')" width="88" align="right">
<template #default="{ row }">{{ row.cashbackRate }}</template>
</el-table-column>
@@ -389,7 +408,12 @@ function creditTypeLabel(type: string) {
</template>
</el-dialog>
<el-dialog v-model="creditVisible" :title="t('agent.dialog.credit')" width="420px" destroy-on-close>
<el-dialog v-model="creditVisible" :title="t('agent.dialog.credit')" width="520px" destroy-on-close>
<AgentCreditContext
:context="creditContext"
:loading="creditContextLoading"
:adjust-amount="creditForm.amount"
/>
<el-form label-width="88px">
<el-form-item :label="t('agent.field.agent_id')">
<el-input :model-value="editingId" disabled />