feat: add finance logs page, banner upload, and admin withdraw fix

## 财务流水
- 新增 FinanceLogs.vue(/finance-logs):额度流水 + 上下分流水双 Tab,支持时间/代理/玩家/操作人筛选与分页
- 管理员与代理共用页面,API 按角色自动切换(/admin/* 或 /agent/*)
- 侧栏「财务流水」替代原「额度流水」;代理侧栏同步新增入口
- /agent-credit-transactions 重定向至 /finance-logs?tab=credit,旧链接仍可用
- 后端:新增 GET /admin/wallet/transfer-transactions;增强额度/上下分列表筛选
- 代理端:新增 GET /agent/credit-transactions;GET /agent/wallet-transactions 支持分页与筛选
- 修复:管理员下分改为 adminWithdrawFromPlayer(),下分后重算上级代理 usedCredit

## 内容管理 Banner
- Contents.vue:各语言 Banner 支持本地上传、媒体库选择、手动填 URL(≤5MB)
- vite 开发代理 /uploads;生产 nginx 反代 /uploads/ 至 API

## 玩家端 Banner
- BannerCarousel:外链无协议时自动补 https://
- defaultBanner:API 加载中不闪默认图,仅空列表时展示默认 Banner

## 其他
- AgentManager:查看额度流水链接改为 /finance-logs
- i18n:finance.*、nav.finance_logs、content.upload.*(中/英/马来)

未纳入本次提交:.pnpm-store/、release/ 部署包、uploads/banners/ 下测试上传图片

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-06-10 10:02:53 +08:00
parent df20444be9
commit 6124313369
17 changed files with 1233 additions and 25 deletions

View File

@@ -56,7 +56,9 @@ function onBannerClick(banner: BannerItem) {
return;
}
if (banner.linkType === 'URL' && banner.linkTarget) {
window.open(banner.linkTarget, '_blank');
let url = banner.linkTarget.trim();
if (!/^https?:\/\//i.test(url)) url = `https://${url}`;
window.open(url, '_blank');
}
}

View File

@@ -21,7 +21,10 @@ function pickImageUrl(url?: string | null): string {
}
export function resolveBanners(banners: BannerItem[] | undefined | null): BannerItem[] {
const fromApi = (banners ?? []).map((banner) => ({
// API 数据尚未到达(加载中),返回空数组避免闪烁默认图
if (banners == null) return [];
const fromApi = banners.map((banner) => ({
...banner,
translation: {
...banner.translation,
@@ -31,6 +34,7 @@ export function resolveBanners(banners: BannerItem[] | undefined | null): Banner
if (fromApi.length > 0) return fromApi;
// API 返回了但列表为空,展示默认 Banner
const defaultSlide: BannerItem = {
...DEFAULT_BANNER,
translation: {