feat: 手动充值、邀请码注册与后台管理增强

新增玩家手动充值全流程(收款方式配置、充值下单/审核、钱包上分),
支持邀请码注册、邀请历史与专属返水率;完善后台代理/玩家管理与响应式操作栏,
并补充前台注册、充值页及多语言错误码。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-06-11 12:20:11 +08:00
parent 618fb49511
commit 10485ecfaf
98 changed files with 7908 additions and 856 deletions

View File

@@ -26,7 +26,10 @@ import {
shouldCompactAmount as shouldCompact,
} from '../utils/format-amount';
import AdminTableEmpty from '../components/AdminTableEmpty.vue';
import InviteCodePanel from '../components/InviteCodePanel.vue';
import RatePercentInput from '../components/RatePercentInput.vue';
import AgentCreditContext from '../components/AgentCreditContext.vue';
import { formatRatePercent, percentToDecimalRate } from '../utils/rate-percent';
import {
fetchAdminAgentCreditContext,
maxCreditIncreaseAmount,
@@ -186,7 +189,7 @@ async function submitEdit() {
status: editForm.value.status,
phone: editForm.value.phone.trim() || undefined,
email: editForm.value.email.trim() || undefined,
cashbackRate: editForm.value.cashbackRate,
cashbackRate: percentToDecimalRate(editForm.value.cashbackRate),
});
ElMessage.success(t('msg.saved'));
editVisible.value = false;
@@ -298,7 +301,7 @@ function creditTypeLabel(type: string) {
<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>
<template #default="{ row }">{{ formatRatePercent(row.cashbackRate) }}</template>
</el-table-column>
<el-table-column prop="phone" :label="t('agent.col.phone')" min-width="110">
<template #default="{ row }">{{ row.phone ?? '—' }}</template>
@@ -361,14 +364,7 @@ function creditTypeLabel(type: string) {
<div class="field-hint">{{ t('agent.hint.credit_limit') }}</div>
</el-form-item>
<el-form-item :label="t('agent.field.cashback_rate')">
<el-input-number
v-model="createForm.cashbackRate"
:min="0"
:max="1"
:step="0.001"
:precision="4"
style="width: 100%"
/>
<RatePercentInput v-model="createForm.cashbackRate" />
<div class="field-hint">{{ t('agent.hint.cashback_example') }}</div>
</el-form-item>
<el-form-item :label="t('user.field.phone')">
@@ -393,14 +389,7 @@ function creditTypeLabel(type: string) {
</el-radio-group>
</el-form-item>
<el-form-item :label="t('agent.field.cashback_rate')">
<el-input-number
v-model="editForm.cashbackRate"
:min="0"
:max="1"
:step="0.001"
:precision="4"
style="width: 100%"
/>
<RatePercentInput v-model="editForm.cashbackRate" />
</el-form-item>
<el-form-item :label="t('user.field.phone')">
<el-input v-model="editForm.phone" />
@@ -475,7 +464,7 @@ function creditTypeLabel(type: string) {
<el-descriptions-item :label="t('agent.field.sub_agent_exposure')">
{{ formatAmount(detail.childAgentExposure) }}
</el-descriptions-item>
<el-descriptions-item :label="t('agent.col.cashback')">{{ detail.cashbackRate }}</el-descriptions-item>
<el-descriptions-item :label="t('agent.col.cashback')">{{ formatRatePercent(detail.cashbackRate) }}</el-descriptions-item>
<el-descriptions-item :label="t('user.field.phone')">{{ detail.phone ?? '—' }}</el-descriptions-item>
<el-descriptions-item :label="t('user.field.email')">{{ detail.email ?? '—' }}</el-descriptions-item>
<el-descriptions-item :label="t('user.col.last_login')" :span="2">
@@ -486,6 +475,8 @@ function creditTypeLabel(type: string) {
</el-descriptions-item>
</el-descriptions>
<InviteCodePanel :invite-code="detail.inviteCode" compact readonly class="detail-invite" />
<div class="section-title section-title--row">
<span>{{ t('agent.section.credit_log') }}</span>
<el-button