Compare commits

...

3 Commits

798 changed files with 83365 additions and 1344 deletions

BIN
.DS_Store vendored Normal file → Executable file

Binary file not shown.

0
.cookie Normal file → Executable file
View File

View File

@ -1,40 +0,0 @@
# Nakama 服务端集成规划 (修订版4人自动匹配)
根据您的补充需求4人自动匹配、无需手动管理房间我调整了规划如下。我们将继续基于“动物扫雷大作战”项目进行开发。
## 1. 核心流程:自动匹配 (Auto-Matchmaking)
我们将完全屏蔽“房间”概念,采用类似《王者荣耀》或《英雄联盟》的匹配机制:
1. **点击“开始游戏”**: 客户端调用 Nakama Matchmaker API参数设定为 `min_count=4, max_count=4`
2. **服务端排队**: Nakama 自动将请求的玩家放入匹配池。
3. **匹配成功**: 当凑齐 4 人后,服务端自动创建一个权威比赛 (Authoritative Match)。
4. **自动入场**: 客户端收到匹配成功通知 (Match Found),携带 Token 自动加入比赛,进入游戏画面。
## 2. 系统架构与实施
### 第一阶段:基础设施 (不变)
* **动作**: 配置 Docker (Nakama + CockroachDB)。
* **动作**: 前端安装 `nakama-js`
### 第二阶段:服务端逻辑 (TypeScript)
* **Match Handler (比赛控制器)**:
* **硬性限制**: 仅当凑齐 4 人时游戏逻辑才正式开始(或等待超时添加 AI目前先按纯真人规划
* **回合制逻辑**: 维护 4 人行动顺序P1 -> P2 -> P3 -> P4 -> P1...)。
* **状态同步**: 广播 100 个格子的状态、4 名玩家的血量/道具/Buff。
### 第三阶段:前端改造 (针对 4 人匹配)
* **UI 调整**:
* 主界面增加“开始匹配 (4人)”大按钮。
* 增加“匹配中...”的等待状态提示。
* 游戏内固定显示 4 个玩家的头像槽位(如 `App.tsx` 中已有的布局,需确保能动态映射 P1-P4
* **逻辑对接**:
* **Socket 监听**: 监听 `onmatchmakermatched` 事件 -> 自动执行 `joinMatch`
* **游戏开始**: 收到服务端 `OP_GAME_START` 信号后,解锁棋盘交互。
## 3. 下一步执行计划
1. **环境搭建**: 启动 Nakama 服务端。
2. **前端集成**: 实现“点击匹配 -> 等待 -> 自动进入游戏”的完整链路。
3. **逻辑迁移**: 将现有的 Mock 数据替换为服务端数据。
请确认是否开始执行环境搭建?

0
DEPLOYMENT.md Normal file → Executable file
View File

2
app/.env.production Normal file → Executable file
View File

@ -1,5 +1,5 @@
# Production environment configuration
VITE_NAKAMA_HOST=game.1024tool.vip
VITE_NAKAMA_HOST=kdy.1024tool.vip
VITE_NAKAMA_PORT=443
VITE_NAKAMA_SERVER_KEY=defaultkey
VITE_NAKAMA_USE_SSL=true

0
app/.gitignore vendored Normal file → Executable file
View File

0
app/README.md Normal file → Executable file
View File

Binary file not shown.

0
app/eslint.config.js Normal file → Executable file
View File

0
app/index.html Normal file → Executable file
View File

0
app/package-lock.json generated Normal file → Executable file
View File

0
app/package.json Normal file → Executable file
View File

0
app/postcss.config.js Normal file → Executable file
View File

0
app/public/vite.svg Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

0
app/scripts/simulate_bots.ts Normal file → Executable file
View File

0
app/scripts/simulate_bots_fixed.ts Normal file → Executable file
View File

0
app/scripts/simulate_bots_matchmaker.ts Normal file → Executable file
View File

0
app/scripts/test_matchmaker.cjs Normal file → Executable file
View File

0
app/scripts/test_matchmaker.mjs Normal file → Executable file
View File

0
app/src/App.css Normal file → Executable file
View File

177
app/src/App.tsx Normal file → Executable file
View File

@ -17,6 +17,8 @@ interface Player {
revive: boolean;
timeBombTurns: number;
skipTurn: boolean;
// 放大镜透视的格子 {cellIndex: contentType}
revealedCells?: { [cellIndex: number]: string };
}
interface GridCell {
@ -177,73 +179,38 @@ const App: React.FC = () => {
}
};
// 再来一局: 获取新token并重新匹配
// 再来一局: 通知小程序返回游戏入口页面
const refreshAndPlayAgain = async () => {
console.log('🔄 [再来一局] 通知小程序返回游戏入口...');
addLog('system', '🔄 正在返回游戏入口...');
setIsRefreshing(true);
addLog('system', '🔄 正在获取新的游戏凭证...');
try {
const backendUrl = 'https://game.1024tool.vip';
// 从小程序环境获取用户token
let userToken = '';
if ((window as any).uni && (window as any).uni.getStorageSync) {
userToken = (window as any).uni.getStorageSync('token') || '';
}
if (!userToken) {
addLog('system', '❌ 无法获取用户凭证,请返回小程序重新进入');
setIsRefreshing(false);
// 回退到小程序
if ((window as any).uni) {
(window as any).uni.navigateBack();
} else if ((window as any).wx?.miniProgram) {
(window as any).wx.miniProgram.navigateBack();
}
return;
}
const resp = await fetch(`${backendUrl}/api/app/games/enter`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${userToken}`
},
body: JSON.stringify({ game_code: 'minesweeper' })
});
if (!resp.ok) {
const errData = await resp.json().catch(() => ({}));
addLog('system', `❌ 获取游戏凭证失败: ${errData.message || '游戏次数不足'}`);
setIsRefreshing(false);
return;
}
const data = await resp.json();
if (data.game_token) {
addLog('system', '✅ 获取新凭证成功!');
// 重置游戏状态
setGameState(null);
setMatchId(null);
setIsMatching(false);
// 重新初始化 Nakama 并开始匹配
nakamaManager.initClient(data.nakama_server || 'wss://nakama.1024tool.vip', data.nakama_key || 'defaultkey');
await nakamaManager.authenticateWithGameToken(data.game_token);
setIsConnected(true);
addLog('system', '✅ 重新连接成功');
// 自动开始匹配
setTimeout(() => startMatchmaking(), 500);
} else {
addLog('system', '❌ 获取游戏凭证失败');
}
} catch (err) {
console.error('Refresh token error:', err);
addLog('system', '❌ 网络错误,请稍后重试');
// 方案1: 使用 postMessage 通知小程序
if ((window as any).wx?.miniProgram) {
console.log(' -> 使用 wx.miniProgram.postMessage + navigateBack');
(window as any).wx.miniProgram.postMessage({ data: { action: 'playAgain' } });
setTimeout(() => {
(window as any).wx.miniProgram.navigateBack();
}, 100);
return;
}
// 方案2: 使用 uni 的 redirectTo 直接跳转到游戏入口页面
if ((window as any).uni) {
console.log(' -> 使用 uni.navigateBack');
// 先发送消息再返回
(window as any).uni.postMessage({ data: { action: 'playAgain' } });
setTimeout(() => {
(window as any).uni.navigateBack();
}, 100);
return;
}
// 方案3: 浏览器环境 - 刷新页面(需要新token)
console.log(' -> 浏览器环境, 刷新页面');
addLog('system', '❌ 浏览器环境无法自动获取新token请手动刷新页面');
setIsRefreshing(false);
alert('请手动刷新页面或从小程序重新进入游戏');
};
const GuideModal = () => (
@ -321,7 +288,7 @@ const App: React.FC = () => {
// Fetch game config to get match_player_count (使用同域避免 CORS)
try {
const backendUrl = 'https://game.1024tool.vip'; // 通过 Nginx 反向代理到后端
const backendUrl = ''; // 同域请求,走 game.1024tool.vip 的 nginx 代理
const configResp = await fetch(`${backendUrl}/api/internal/game/minesweeper/config`, {
headers: { 'X-Internal-Key': 'bindbox-internal-secret-2024' }
});
@ -346,6 +313,12 @@ const App: React.FC = () => {
setMyUserId(userId);
myUserIdRef.current = userId;
setIsConnected(true);
// Join the lobby channel for online tracking
nakamaManager.joinLobby().catch(err => {
console.warn('Failed to join lobby:', err);
});
addLog('system', '✅ 已连接到服务器');
const socket = nakamaManager.getSocket();
@ -449,8 +422,26 @@ const App: React.FC = () => {
// Special event from server (character abilities, item effects)
const event = data as unknown as { type: string; playerId: string; playerName: string; targetId?: string; targetName?: string; itemId?: string; value?: number; message: string };
const isMe = event.playerId === myUserIdRef.current;
const prefix = isMe ? '你' : (event.playerName?.substring(0, 8) || '对手');
addLog('effect', `${prefix}: ${event.message}`);
const iAmTarget = event.targetId === myUserIdRef.current;
// 翻译道具名称
const itemNames: { [key: string]: string } = {
knife: '🔪飞刀', lightning: '⚡闪电', poison: '☠️毒药',
curse: '👻诅咒', bomb_timer: '💣定时炸弹'
};
const itemDisplayName = event.itemId ? (itemNames[event.itemId] || event.itemId) : '';
// 显示日志
if (isMe) {
addLog('effect', `你: ${event.message}`);
} else if (iAmTarget && event.type === 'damage') {
// 我被别人攻击了 - 特别提示
const attackerName = event.playerName?.substring(0, 8) || '对手';
addLog('effect', `⚠️ 你被 ${attackerName}${itemDisplayName} 攻击了!`);
} else {
const prefix = event.playerName?.substring(0, 8) || '对手';
addLog('effect', `${prefix}: ${event.message}`);
}
// Show floating damage/heal for affected players
if (event.type === 'damage' || event.type === 'item') {
@ -459,7 +450,7 @@ const App: React.FC = () => {
if (isGlobalDamage && event.value) {
// Global damage - show on my screen
spawnLabel(50, 50, `-${event.value}`, 'damage', undefined, myUserIdRef.current || undefined);
} else if (event.targetId === myUserIdRef.current && event.value) {
} else if (iAmTarget && event.value) {
// I'm the target of damage
spawnLabel(50, 50, `-${event.value}`, 'damage', undefined, myUserIdRef.current || undefined);
}
@ -473,7 +464,7 @@ const App: React.FC = () => {
}
};
}
} catch (error) {
} catch {
addLog('system', '连接服务器失败');
}
};
@ -536,16 +527,35 @@ const App: React.FC = () => {
<div className="text-emerald-400 font-bold">
🎮 {matchPlayerCount}
</div>
{matchingTimer > 3 && (
{matchingTimer > 3 && matchingTimer <= 30 && (
<div className="text-yellow-400 text-xs animate-pulse mt-3">
...1-5
</div>
)}
{matchingTimer > 8 && (
{matchingTimer > 30 && matchingTimer <= 60 && (
<div className="text-orange-400 text-xs mt-2">
...
</div>
)}
{matchingTimer > 60 && (
<div className="text-red-400 text-xs mt-2">
</div>
)}
{/* 取消匹配按钮 */}
<button
onClick={() => {
setIsMatching(false);
setMatchingTimer(0);
addLog('system', '已取消匹配');
// 刷新页面以完全重置状态
window.location.reload();
}}
className="mt-4 px-6 py-2 bg-slate-700 hover:bg-slate-600 rounded-lg text-sm text-slate-300 transition-all"
>
</button>
</div>
</div>
) : (
@ -614,10 +624,23 @@ const App: React.FC = () => {
<div className="grid gap-0.5 lg:gap-1 w-full max-w-[500px] aspect-square" style={{ gridTemplateColumns: `repeat(${gameState.gridSize || 10}, 1fr)` }}>
{gameState.grid.map((cell, idx) => {
const showContent = cell.revealed || debugMode;
// 检查当前玩家是否放大镜透视了这个格子
const myRevealedContent = myPlayer?.revealedCells?.[idx];
const hasMagnifierMark = !!myRevealedContent && !cell.revealed;
return (
<div key={idx} onClick={() => handleCellClick(idx)} className={`aspect-square rounded-sm relative flex items-center justify-center text-sm lg:text-2xl border border-white/5 transition-all
${showContent ? (cell.type === 'bomb' ? 'bg-rose-900/50' + (cell.revealed ? ' explosion' : '') : cell.type === 'item' ? `bg-blue-900/40${cell.revealed ? ` item-${cell.itemId || 'generic'}` : ''}` : 'bg-slate-800/50') : 'bg-emerald-900/20 hover:bg-emerald-800/40 cursor-pointer'}
<div key={idx} onClick={() => handleCellClick(idx)} className={`aspect-square rounded-sm relative flex items-center justify-center text-sm lg:text-2xl border transition-all
${showContent ? (cell.type === 'bomb' ? 'bg-rose-900/50' + (cell.revealed ? ' explosion' : '') : cell.type === 'item' ? `bg-blue-900/40${cell.revealed ? ` item-${cell.itemId || 'generic'}` : ''}` : 'bg-slate-800/50') : hasMagnifierMark ? 'bg-purple-900/40 border-purple-500/50 border-dashed' : 'bg-emerald-900/20 hover:bg-emerald-800/40 cursor-pointer border-white/5'}
${debugMode && !cell.revealed ? 'opacity-60 border-dashed border-yellow-500/50' : ''}`}>
{/* 放大镜透视标记 */}
{hasMagnifierMark && (
<div className="absolute inset-0 flex items-center justify-center">
<span className="text-lg lg:text-2xl opacity-80" title={`透视: ${myRevealedContent === 'bomb' ? '💣炸弹' : myRevealedContent === 'empty' ? '✅安全' : `🎁${myRevealedContent}`}`}>
{myRevealedContent === 'bomb' ? '💣' : myRevealedContent === 'empty' ? '✅' : '🎁'}
</span>
<span className="absolute top-0 right-0 text-xs">🔍</span>
</div>
)}
{showContent && (
cell.type === 'bomb' ? '💣' :
cell.type === 'item' ? getItemIcon(cell.itemId) :
@ -677,20 +700,6 @@ const App: React.FC = () => {
>
{isRefreshing ? '🔄 正在准备...' : '🚀 再来一局'}
</button>
<button
onClick={() => {
if ((window as any).uni) {
(window as any).uni.navigateBack();
} else if ((window as any).wx?.miniProgram) {
(window as any).wx.miniProgram.navigateBack();
} else {
window.location.href = 'about:blank';
}
}}
className="w-full mt-2 bg-slate-700 hover:bg-slate-600 text-white font-bold py-2 rounded-xl text-sm"
>
</button>
</div>
</div>
)}

0
app/src/Explosion.css Normal file → Executable file
View File

0
app/src/assets/react.svg Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 4.0 KiB

After

Width:  |  Height:  |  Size: 4.0 KiB

0
app/src/index.css Normal file → Executable file
View File

12
app/src/lib/nakama.ts Normal file → Executable file
View File

@ -101,6 +101,18 @@ class NakamaManager {
return this.socket.joinMatch(matchId, token, metadata);
}
/**
* Join the global minesweeper lobby channel
* This is used to track online users even if they are not in a match
*/
async joinLobby() {
if (!this.socket) throw new Error('Socket not connected');
// 1 = Room, true = Persistence, false = Hidden (we want to be counted)
console.log('Joining minesweeper lobby...');
return this.socket.joinChat('minesweeper_lobby', 1, true, false);
}
async sendMatchState(matchId: string, opCode: number, data: string) {
if (!this.socket) throw new Error('Socket not connected');
return this.socket.sendMatchState(matchId, opCode, data);

0
app/src/main.tsx Normal file → Executable file
View File

0
app/tailwind.config.js Normal file → Executable file
View File

0
app/tsconfig.app.json Normal file → Executable file
View File

0
app/tsconfig.json Normal file → Executable file
View File

0
app/tsconfig.node.json Normal file → Executable file
View File

0
app/vite.config.ts Normal file → Executable file
View File

286
docker-compose.all.yml Normal file → Executable file
View File

@ -1,21 +1,33 @@
# 全量服务部署 (后端 + 游戏服 + 数据库)
# 使用方法: docker-compose -f docker-compose.all.yml up -d
# 全量服务部署 (云端/无源码版)
# 使用方法:
# 1. 确保已将 docker-compose.cloud.yml, configs/, nginx/, loki/ 目录上传到服务器同一目录
# 2. 确保 logs/ 目录存在 (mkdir logs)
# 3. 运行: docker-compose -f docker-compose.cloud.yml up -d
services:
# ----------------------------------------------------
# 1. 业务后端 (Bindbox Game Backend)
# ----------------------------------------------------
bindbox-game:
image: zfc931912343/bindbox-game:v1.12
image: zfc931912343/bindbox-game:v1.23
container_name: bindbox-game
restart: always
ports:
- "9991:9991"
# ports:
# - "9991:9991" (Internal only)
volumes:
- ../bindbox_game/logs:/app/logs
# - ../bindbox_game/configs:/app/configs # 指向 bindbox_game 目录下的配置
# 改为挂载当前目录下的 logs 和 configs
- ./logs:/app/logs
- ./configs:/app/configs
environment:
- ACTIVE_ENV=pro
- TZ=Asia/Shanghai
# MySQL 配置(覆盖编译时的默认值)
- MYSQL_ADDR=mysql:3306
- MYSQL_USER=root
- MYSQL_PASS=bindbox2025kdy
- MYSQL_NAME=bindbox_game
# Redis 配置
- REDIS_ADDR=redis:6379
networks:
- bindbox_net
logging:
@ -23,6 +35,10 @@ services:
options:
max-size: "10m"
max-file: "3"
depends_on:
- mysql
- redis
# ----------------------------------------------------
# 2. 游戏数据库 (CockroachDB for Nakama)
# ----------------------------------------------------
@ -33,9 +49,6 @@ services:
restart: always
volumes:
- nakama-db-data:/var/lib/cockroach
ports:
- "26257:26257"
- "8081:8080"
healthcheck:
test: [ "CMD", "curl", "-f", "http://localhost:8080/health?ready=1" ]
interval: 3s
@ -50,14 +63,14 @@ services:
options:
max-size: "10m"
max-file: "3"
# ----------------------------------------------------
# 3. 游戏服务器 (Nakama)
# ----------------------------------------------------
nakama:
image: zfc931912343/bindbox-saolei:v1.5
image: zfc931912343/bindbox-saolei:v1.6-local
container_name: nakama-server
environment:
# 直接使用服务名访问后端
- MINESWEEPER_BACKEND_URL=http://bindbox-game:9991/api/internal
- TZ=Asia/Shanghai
entrypoint:
@ -72,10 +85,6 @@ services:
condition: service_started
volumes:
- nakama-data:/nakama/data
ports:
- "7350:7350"
- "7351:7351"
- "9100:9100"
healthcheck:
test: [ "CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://bindbox-game:9991/" ]
interval: 10s
@ -88,9 +97,254 @@ services:
options:
max-size: "10m"
max-file: "3"
# ----------------------------------------------------
# 4. MySQL Database
# ----------------------------------------------------
mysql:
image: mysql:8.0
container_name: bindbox-mysql
restart: always
ports:
- "3306:3306" # 临时开放外部访问,用完记得关闭!
environment:
MYSQL_ROOT_PASSWORD: "bindbox2025kdy"
MYSQL_DATABASE: "bindbox_game"
TZ: Asia/Shanghai
command: --default-authentication-plugin=mysql_native_password
volumes:
- mysql_data:/var/lib/mysql
- ./mysql/init:/docker-entrypoint-initdb.d # 初始化脚本
networks:
- bindbox_net
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
# ----------------------------------------------------
# 5. Redis
# ----------------------------------------------------
redis:
image: redis:7.0
container_name: bindbox-redis
restart: always
volumes:
- redis_data:/data
networks:
- bindbox_net
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
# ----------------------------------------------------
# 6. Nginx Gateway (入口)
# ----------------------------------------------------
nginx:
image: nginx:latest
container_name: bindbox-nginx
restart: always
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx/conf.d:/etc/nginx/conf.d
- ./nginx/ssl:/etc/nginx/ssl
- ./nginx/admin:/usr/share/nginx/html/admin
- ./nginx/game:/usr/share/nginx/html/game
depends_on:
- bindbox-game
- nakama
networks:
- bindbox_net
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
# ----------------------------------------------------
# 7. Loki (日志存储)
# ----------------------------------------------------
loki:
image: grafana/loki:3.0.0
container_name: bindbox-loki
restart: always
volumes:
# 必须上传 loki 目录到服务器
- ./loki/loki-config.yaml:/etc/loki/local-config.yaml
- loki_data:/loki
command: -config.file=/etc/loki/local-config.yaml
networks:
- bindbox_net
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
# ----------------------------------------------------
# 8. Promtail (日志采集)
# ----------------------------------------------------
promtail:
image: grafana/promtail:3.0.0
container_name: bindbox-promtail
restart: always
volumes:
- ./loki/promtail-config.yaml:/etc/promtail/config.yaml
- /var/lib/docker/containers:/var/lib/docker/containers:ro
- /var/run/docker.sock:/var/run/docker.sock
# 采集当前目录下的 logs 文件夹
- ./logs:/var/log/bindbox-game:ro
command: -config.file=/etc/promtail/config.yaml
networks:
- bindbox_net
depends_on:
- loki
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
# ----------------------------------------------------
# 9. Grafana (日志界面)
# ----------------------------------------------------
grafana:
image: grafana/grafana:latest
container_name: bindbox-grafana
restart: always
ports:
- "3000:3000"
environment:
- GF_SECURITY_ADMIN_PASSWORD=admin
- GF_USERS_ALLOW_SIGN_UP=false
volumes:
- grafana_data:/var/lib/grafana
networks:
- bindbox_net
depends_on:
- loki
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
# ----------------------------------------------------
# 10. Prometheus (指标采集)
# ----------------------------------------------------
prometheus:
image: prom/prometheus:latest
container_name: bindbox-prometheus
restart: always
volumes:
- ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml
- prometheus_data:/prometheus
command:
- '--config.file=/etc/prometheus/prometheus.yml'
- '--storage.tsdb.path=/prometheus'
- '--web.enable-lifecycle'
networks:
- bindbox_net
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
# ----------------------------------------------------
# 11. Nginx Exporter (Nginx指标导出)
# ----------------------------------------------------
nginx-exporter:
image: nginx/nginx-prometheus-exporter:latest
container_name: bindbox-nginx-exporter
restart: always
command:
- -nginx.scrape-uri=http://nginx:80/nginx_status
networks:
- bindbox_net
depends_on:
- nginx
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
# ----------------------------------------------------
# 12. Redis Exporter (Redis指标导出)
# ----------------------------------------------------
redis-exporter:
image: oliver006/redis_exporter:latest
container_name: bindbox-redis-exporter
restart: always
environment:
- REDIS_ADDR=redis://redis:6379
networks:
- bindbox_net
depends_on:
- redis
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
# ----------------------------------------------------
# 13. MySQL Exporter (MySQL指标导出)
# ----------------------------------------------------
mysql-exporter:
image: prom/mysqld-exporter:latest
container_name: bindbox-mysql-exporter
restart: always
command:
- --config.my-cnf=/etc/.my.cnf
volumes:
- ./mysql/.my.cnf:/etc/.my.cnf:ro
networks:
- bindbox_net
depends_on:
- mysql
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
# ----------------------------------------------------
# 14. Tempo (链路追踪)
# ----------------------------------------------------
tempo:
image: grafana/tempo:latest
container_name: bindbox-tempo
restart: always
command: [ "-config.file=/etc/tempo/tempo-config.yaml" ]
volumes:
- ./tempo/tempo-config.yaml:/etc/tempo/tempo-config.yaml
- tempo_data:/var/tempo
networks:
- bindbox_net
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
volumes:
nakama-db-data:
nakama-data:
mysql_data:
redis_data:
loki_data:
grafana_data:
prometheus_data:
tempo_data:
networks:
bindbox_net:
name: bindbox_net

334
docker-compose.cloud.yml Normal file → Executable file
View File

@ -1,55 +1,351 @@
# 云端部署专用 - 扫雷游戏服务
# 使用方法: docker-compose -f docker-compose.cloud.yml up -d
# 全量服务部署 (云端/无源码版)
# 使用方法:
# 1. 确保已将 docker-compose.cloud.yml, configs/, nginx/, loki/ 目录上传到服务器同一目录
# 2. 确保 logs/ 目录存在 (mkdir logs)
# 3. 运行: docker-compose -f docker-compose.cloud.yml up -d
services:
# ----------------------------------------------------
# 1. 业务后端 (Bindbox Game Backend)
# ----------------------------------------------------
bindbox-game:
image: zfc931912343/bindbox-game:v1.23
container_name: bindbox-game
restart: always
# ports:
# - "9991:9991" (Internal only)
volumes:
# 改为挂载当前目录下的 logs 和 configs
- ./logs:/app/logs
- ./configs:/app/configs
environment:
- ACTIVE_ENV=pro
- TZ=Asia/Shanghai
# MySQL 配置(覆盖编译时的默认值)
- MYSQL_ADDR=mysql:3306
- MYSQL_USER=root
- MYSQL_PASS=bindbox2025kdy
- MYSQL_NAME=bindbox_game
# Redis 配置
- REDIS_ADDR=redis:6379
networks:
- bindbox_net
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
depends_on:
- mysql
- redis
# ----------------------------------------------------
# 2. 游戏数据库 (CockroachDB for Nakama)
# ----------------------------------------------------
nakama-db:
image: cockroachdb/cockroach:latest-v23.1
container_name: nakama-db
command: start-single-node --insecure --store=attrs=ssd,path=/var/lib/cockroach/
command: start-single-node --insecure --store=attrs=ssd,path=/var/lib/cockroach/ --cache=.25 --max-sql-memory=.25
restart: always
volumes:
- nakama-db-data:/var/lib/cockroach
ports:
- "26257:26257"
- "8081:8080"
healthcheck:
test: [ "CMD", "curl", "-f", "http://localhost:8080/health?ready=1" ]
interval: 3s
timeout: 3s
retries: 5
environment:
- TZ=Asia/Shanghai
networks:
- bindbox_net
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
# ----------------------------------------------------
# 3. 游戏服务器 (Nakama)
# ----------------------------------------------------
nakama:
image: zfc931912343/bindbox-saolei:v1.3
image: zfc931912343/bindbox-saolei:v1.6
container_name: nakama-server
environment:
# 使用 Docker 内部网络访问后端服务 (需确保在同一网络下)
- MINESWEEPER_BACKEND_URL=http://blindbox-mms-api:9991/api/internal
- MINESWEEPER_BACKEND_URL=http://bindbox-game:9991/api/internal
- TZ=Asia/Shanghai
entrypoint:
- "/bin/sh"
- "-ecx"
- "/nakama/nakama migrate up --database.address root@nakama-db:26257 && exec /nakama/nakama --name nakama1 --database.address root@nakama-db:26257 --logger.level DEBUG --session.token_expiry_sec 7200 --metrics.prometheus_port 9100 --runtime.path /nakama/modules"
- "/nakama/nakama migrate up --database.address root@nakama-db:26257 && exec /nakama/nakama --name nakama1 --database.address root@nakama-db:26257 --logger.level DEBUG --session.token_expiry_sec 7200 --metrics.prometheus_port 9100 --runtime.path /nakama/modules --matchmaker.interval_sec 1 --matchmaker.max_intervals 5"
restart: always
depends_on:
nakama-db:
condition: service_healthy
bindbox-game:
condition: service_started
volumes:
- nakama-data:/nakama/data
ports:
- "7350:7350"
- "7351:7351"
- "9100:9100"
healthcheck:
test: [ "CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:7350/" ]
test: [ "CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://bindbox-game:9991/" ]
interval: 10s
timeout: 5s
retries: 5
networks:
- bindbox_net
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
# ----------------------------------------------------
# 4. MySQL Database
# ----------------------------------------------------
mysql:
image: mysql:8.0
container_name: bindbox-mysql
restart: always
ports:
- "3306:3306" # 临时开放外部访问,用完记得关闭!
environment:
MYSQL_ROOT_PASSWORD: "bindbox2025kdy"
MYSQL_DATABASE: "bindbox_game"
TZ: Asia/Shanghai
command: --default-authentication-plugin=mysql_native_password
volumes:
- mysql_data:/var/lib/mysql
- ./mysql/init:/docker-entrypoint-initdb.d # 初始化脚本
networks:
- bindbox_net
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
# ----------------------------------------------------
# 5. Redis
# ----------------------------------------------------
redis:
image: redis:7.0
container_name: bindbox-redis
restart: always
volumes:
- redis_data:/data
networks:
- bindbox_net
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
# ----------------------------------------------------
# 6. Nginx Gateway (入口)
# ----------------------------------------------------
nginx:
image: nginx:latest
container_name: bindbox-nginx
restart: always
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx/conf.d:/etc/nginx/conf.d
- ./nginx/ssl:/etc/nginx/ssl
- ./nginx/admin:/usr/share/nginx/html/admin
- ./nginx/game:/usr/share/nginx/html/game
depends_on:
- bindbox-game
- nakama
networks:
- bindbox_net
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
# ----------------------------------------------------
# 7. Loki (日志存储)
# ----------------------------------------------------
loki:
image: grafana/loki:3.0.0
container_name: bindbox-loki
restart: always
volumes:
# 必须上传 loki 目录到服务器
- ./loki/loki-config.yaml:/etc/loki/local-config.yaml
- loki_data:/loki
command: -config.file=/etc/loki/local-config.yaml
networks:
- bindbox_net
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
# ----------------------------------------------------
# 8. Promtail (日志采集)
# ----------------------------------------------------
promtail:
image: grafana/promtail:3.0.0
container_name: bindbox-promtail
restart: always
volumes:
- ./loki/promtail-config.yaml:/etc/promtail/config.yaml
- /var/lib/docker/containers:/var/lib/docker/containers:ro
- /var/run/docker.sock:/var/run/docker.sock
# 采集当前目录下的 logs 文件夹
- ./logs:/var/log/bindbox-game:ro
command: -config.file=/etc/promtail/config.yaml
networks:
- bindbox_net
depends_on:
- loki
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
# ----------------------------------------------------
# 9. Grafana (日志界面)
# ----------------------------------------------------
grafana:
image: grafana/grafana:latest
container_name: bindbox-grafana
restart: always
ports:
- "3000:3000"
environment:
- GF_SECURITY_ADMIN_PASSWORD=admin
- GF_USERS_ALLOW_SIGN_UP=false
volumes:
- grafana_data:/var/lib/grafana
networks:
- bindbox_net
depends_on:
- loki
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
# ----------------------------------------------------
# 10. Prometheus (指标采集)
# ----------------------------------------------------
prometheus:
image: prom/prometheus:latest
container_name: bindbox-prometheus
restart: always
volumes:
- ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml
- prometheus_data:/prometheus
command:
- '--config.file=/etc/prometheus/prometheus.yml'
- '--storage.tsdb.path=/prometheus'
- '--web.enable-lifecycle'
networks:
- bindbox_net
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
# ----------------------------------------------------
# 11. Nginx Exporter (Nginx指标导出)
# ----------------------------------------------------
nginx-exporter:
image: nginx/nginx-prometheus-exporter:latest
container_name: bindbox-nginx-exporter
restart: always
command:
- -nginx.scrape-uri=http://nginx:80/nginx_status
networks:
- bindbox_net
depends_on:
- nginx
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
# ----------------------------------------------------
# 12. Redis Exporter (Redis指标导出)
# ----------------------------------------------------
redis-exporter:
image: oliver006/redis_exporter:latest
container_name: bindbox-redis-exporter
restart: always
environment:
- REDIS_ADDR=redis://redis:6379
networks:
- bindbox_net
depends_on:
- redis
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
# ----------------------------------------------------
# 13. MySQL Exporter (MySQL指标导出)
# ----------------------------------------------------
mysql-exporter:
image: prom/mysqld-exporter:latest
container_name: bindbox-mysql-exporter
restart: always
command:
- --config.my-cnf=/etc/.my.cnf
volumes:
- ./mysql/.my.cnf:/etc/.my.cnf:ro
networks:
- bindbox_net
depends_on:
- mysql
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
# ----------------------------------------------------
# 14. Tempo (链路追踪)
# ----------------------------------------------------
tempo:
image: grafana/tempo:latest
container_name: bindbox-tempo
restart: always
command: [ "-config.file=/etc/tempo/tempo-config.yaml" ]
volumes:
- ./tempo/tempo-config.yaml:/etc/tempo/tempo-config.yaml
- tempo_data:/var/tempo
networks:
- bindbox_net
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
volumes:
nakama-db-data:
nakama-data:
mysql_data:
redis_data:
loki_data:
grafana_data:
prometheus_data:
tempo_data:
# 必须加入后端服务所在的网络才能通过 service_name 访问
networks:
default:
name: ${DOCKER_NETWORK_NAME:-bindbox_default}
external: true
bindbox_net:
name: bindbox_net
driver: bridge

37
docker-compose.test.yml Executable file
View File

@ -0,0 +1,37 @@
version: '3.8'
services:
nakama-db:
image: cockroachdb/cockroach:latest-v23.1
command: start-single-node --insecure --store=attrs=ssd,path=/var/lib/cockroach/,size=20%
restart: "no"
volumes:
- ./cockroach-data:/cockroach/cockroach-data
expose:
- "8080"
- "26257"
ports:
- "8080:8080"
- "26257:26257"
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080/health?ready=1"]
interval: 3s
timeout: 3s
retries: 5
nakama:
image: heroiclabs/nakama:3.21.1
command: >
/bin/sh -ecx '
/nakama/nakama migrate up --database.address root@nakama-db:26257 &&
exec /nakama/nakama --name nakama1 --database.address root@nakama-db:26257 --logger.level DEBUG --session.token_expiry_sec 7200 --metrics.prometheus_port 9100 --runtime.path /nakama/modules --matchmaker.interval_sec 1 --matchmaker.max_intervals 5
'
restart: "no"
depends_on:
nakama-db:
condition: service_healthy
volumes:
- ./server:/nakama/modules
ports:
- "7350:7350"
- "7351:7351"

357
docker-compose.yml Normal file → Executable file
View File

@ -1,52 +1,351 @@
# 全量服务部署 (云端/无源码版)
# 使用方法:
# 1. 确保已将 docker-compose.cloud.yml, configs/, nginx/, loki/ 目录上传到服务器同一目录
# 2. 确保 logs/ 目录存在 (mkdir logs)
# 3. 运行: docker-compose -f docker-compose.cloud.yml up -d
services:
cockroachdb:
image: cockroachdb/cockroach:latest-v23.1
command: start-single-node --insecure --store=attrs=ssd,path=/var/lib/cockroach/
restart: "no"
# ----------------------------------------------------
# 1. 业务后端 (Bindbox Game Backend)
# ----------------------------------------------------
bindbox-game:
image: zfc931912343/bindbox-game:v1.23
container_name: bindbox-game
restart: always
# ports:
# - "9991:9991" (Internal only)
volumes:
- data:/var/lib/cockroach
expose:
- "8080"
- "26257"
ports:
- "26257:26257"
- "8081:8080"
# 改为挂载当前目录下的 logs 和 configs
- ./logs:/app/logs
- ./configs:/app/configs
environment:
- ACTIVE_ENV=pro
- TZ=Asia/Shanghai
# MySQL 配置(覆盖编译时的默认值)
- MYSQL_ADDR=mysql:3306
- MYSQL_USER=root
- MYSQL_PASS=bindbox2025kdy
- MYSQL_NAME=bindbox_game
# Redis 配置
- REDIS_ADDR=redis:6379
networks:
- bindbox_net
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
depends_on:
- mysql
- redis
# ----------------------------------------------------
# 2. 游戏数据库 (CockroachDB for Nakama)
# ----------------------------------------------------
nakama-db:
image: cockroachdb/cockroach:latest-v23.1
container_name: nakama-db
command: start-single-node --insecure --store=attrs=ssd,path=/var/lib/cockroach/ --cache=.25 --max-sql-memory=.25
restart: always
volumes:
- nakama-db-data:/var/lib/cockroach
healthcheck:
test: [ "CMD", "curl", "-f", "http://localhost:8080/health?ready=1" ]
interval: 3s
timeout: 3s
retries: 5
environment:
- TZ=Asia/Shanghai
networks:
- bindbox_net
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
# ----------------------------------------------------
# 3. 游戏服务器 (Nakama)
# ----------------------------------------------------
nakama:
build:
context: ./server
dockerfile: Dockerfile
container_name: wuziqi-nakama-1
image: zfc931912343/bindbox-saolei:v1.6
container_name: nakama-server
environment:
- MINESWEEPER_BACKEND_URL=http://bindbox-game:9991/api/internal
- TZ=Asia/Shanghai
entrypoint:
- "/bin/sh"
- "-ecx"
- >
/nakama/nakama migrate up --database.address root@cockroachdb:26257 && exec /nakama/nakama --name nakama1 --database.address root@cockroachdb:26257 --logger.level DEBUG --session.token_expiry_sec 7200 --metrics.prometheus_port 9100 --runtime.path /nakama/modules
restart: "no"
links:
- "cockroachdb:db"
- "/nakama/nakama migrate up --database.address root@nakama-db:26257 && exec /nakama/nakama --name nakama1 --database.address root@nakama-db:26257 --logger.level DEBUG --session.token_expiry_sec 7200 --metrics.prometheus_port 9100 --runtime.path /nakama/modules --matchmaker.interval_sec 1 --matchmaker.max_intervals 5"
restart: always
depends_on:
cockroachdb:
nakama-db:
condition: service_healthy
bindbox-game:
condition: service_started
volumes:
- nakama-data:/nakama/data
expose:
- "7348"
ports:
- "7350:7350"
- "7351:7351"
- "9100:9100"
healthcheck:
test: [ "CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:7350/" ]
test: [ "CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://bindbox-game:9991/" ]
interval: 10s
timeout: 5s
retries: 5
networks:
- bindbox_net
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
# ----------------------------------------------------
# 4. MySQL Database
# ----------------------------------------------------
mysql:
image: mysql:8.0
container_name: bindbox-mysql
restart: always
ports:
- "3306:3306" # 临时开放外部访问,用完记得关闭!
environment:
MYSQL_ROOT_PASSWORD: "bindbox2025kdy"
MYSQL_DATABASE: "bindbox_game"
TZ: Asia/Shanghai
command: --default-authentication-plugin=mysql_native_password
volumes:
- mysql_data:/var/lib/mysql
- ./mysql/init:/docker-entrypoint-initdb.d # 初始化脚本
networks:
- bindbox_net
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
# ----------------------------------------------------
# 5. Redis
# ----------------------------------------------------
redis:
image: redis:7.0
container_name: bindbox-redis
restart: always
volumes:
- redis_data:/data
networks:
- bindbox_net
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
# ----------------------------------------------------
# 6. Nginx Gateway (入口)
# ----------------------------------------------------
nginx:
image: nginx:latest
container_name: bindbox-nginx
restart: always
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx/conf.d:/etc/nginx/conf.d
- ./nginx/ssl:/etc/nginx/ssl
- ./nginx/admin:/usr/share/nginx/html/admin
- ./nginx/game:/usr/share/nginx/html/game
depends_on:
- bindbox-game
- nakama
networks:
- bindbox_net
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
# ----------------------------------------------------
# 7. Loki (日志存储)
# ----------------------------------------------------
loki:
image: grafana/loki:3.0.0
container_name: bindbox-loki
restart: always
volumes:
# 必须上传 loki 目录到服务器
- ./loki/loki-config.yaml:/etc/loki/local-config.yaml
- loki_data:/loki
command: -config.file=/etc/loki/local-config.yaml
networks:
- bindbox_net
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
# ----------------------------------------------------
# 8. Promtail (日志采集)
# ----------------------------------------------------
promtail:
image: grafana/promtail:3.0.0
container_name: bindbox-promtail
restart: always
volumes:
- ./loki/promtail-config.yaml:/etc/promtail/config.yaml
- /var/lib/docker/containers:/var/lib/docker/containers:ro
- /var/run/docker.sock:/var/run/docker.sock
# 采集当前目录下的 logs 文件夹
- ./logs:/var/log/bindbox-game:ro
command: -config.file=/etc/promtail/config.yaml
networks:
- bindbox_net
depends_on:
- loki
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
# ----------------------------------------------------
# 9. Grafana (日志界面)
# ----------------------------------------------------
grafana:
image: grafana/grafana:latest
container_name: bindbox-grafana
restart: always
ports:
- "3000:3000"
environment:
- GF_SECURITY_ADMIN_PASSWORD=admin
- GF_USERS_ALLOW_SIGN_UP=false
volumes:
- grafana_data:/var/lib/grafana
networks:
- bindbox_net
depends_on:
- loki
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
# ----------------------------------------------------
# 10. Prometheus (指标采集)
# ----------------------------------------------------
prometheus:
image: prom/prometheus:latest
container_name: bindbox-prometheus
restart: always
volumes:
- ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml
- prometheus_data:/prometheus
command:
- '--config.file=/etc/prometheus/prometheus.yml'
- '--storage.tsdb.path=/prometheus'
- '--web.enable-lifecycle'
networks:
- bindbox_net
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
# ----------------------------------------------------
# 11. Nginx Exporter (Nginx指标导出)
# ----------------------------------------------------
nginx-exporter:
image: nginx/nginx-prometheus-exporter:latest
container_name: bindbox-nginx-exporter
restart: always
command:
- -nginx.scrape-uri=http://nginx:80/nginx_status
networks:
- bindbox_net
depends_on:
- nginx
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
# ----------------------------------------------------
# 12. Redis Exporter (Redis指标导出)
# ----------------------------------------------------
redis-exporter:
image: oliver006/redis_exporter:latest
container_name: bindbox-redis-exporter
restart: always
environment:
- REDIS_ADDR=redis://redis:6379
networks:
- bindbox_net
depends_on:
- redis
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
# ----------------------------------------------------
# 13. MySQL Exporter (MySQL指标导出)
# ----------------------------------------------------
mysql-exporter:
image: prom/mysqld-exporter:latest
container_name: bindbox-mysql-exporter
restart: always
command:
- --config.my-cnf=/etc/.my.cnf
volumes:
- ./mysql/.my.cnf:/etc/.my.cnf:ro
networks:
- bindbox_net
depends_on:
- mysql
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
# ----------------------------------------------------
# 14. Tempo (链路追踪)
# ----------------------------------------------------
tempo:
image: grafana/tempo:latest
container_name: bindbox-tempo
restart: always
command: [ "-config.file=/etc/tempo/tempo-config.yaml" ]
volumes:
- ./tempo/tempo-config.yaml:/etc/tempo/tempo-config.yaml
- tempo_data:/var/tempo
networks:
- bindbox_net
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
volumes:
data:
nakama-db-data:
nakama-data:
mysql_data:
redis_data:
loki_data:
grafana_data:
prometheus_data:
tempo_data:
networks:
bindbox_net:
name: bindbox_net
driver: bridge

38
loki/loki-config.yaml Executable file
View File

@ -0,0 +1,38 @@
auth_enabled: false
server:
http_listen_port: 3100
grpc_listen_port: 0
common:
path_prefix: /loki
storage:
filesystem:
chunks_directory: /loki/chunks
rules_directory: /loki/rules
replication_factor: 1
ring:
instance_addr: 127.0.0.1
kvstore:
store: inmemory
schema_config:
configs:
- from: 2020-10-24
store: tsdb
object_store: filesystem
schema: v13
index:
prefix: index_
period: 24h
ruler:
alertmanager_url: http://localhost:9093
# Limit settings to prevent issues with large logs
limits_config:
reject_old_samples: true
reject_old_samples_max_age: 168h
ingestion_rate_mb: 20
ingestion_burst_size_mb: 30
volume_enabled: true

36
loki/promtail-config.yaml Executable file
View File

@ -0,0 +1,36 @@
server:
http_listen_port: 9080
grpc_listen_port: 0
positions:
filename: /tmp/positions.yaml
clients:
- url: http://loki:3100/loki/api/v1/push
scrape_configs:
# 1. Scrape logs from Docker containers via socket (stdout/stderr)
- job_name: docker
docker_sd_configs:
- host: unix:///var/run/docker.sock
refresh_interval: 5s
# filters:
# - name: name
# values: ["bindbox-game"] # Optional: Filter specifically if desired, but user said "all monitor"
relabel_configs:
- source_labels: ['__meta_docker_container_name']
regex: '/(.*)'
target_label: 'container'
- source_labels: ['__meta_docker_container_log_stream']
target_label: 'logstream'
- source_labels: ['__meta_docker_container_label_logging_jobname']
target_label: 'job'
# 2. Scrape logs from mounted log files (application logs)
- job_name: file_logs
static_configs:
- targets:
- localhost
labels:
job: bindbox_app_logs
__path__: /var/log/bindbox-game/*.log

BIN
mysql/.DS_Store vendored Executable file

Binary file not shown.

5
mysql/.my.cnf Executable file
View File

@ -0,0 +1,5 @@
[client]
user = exporter
password = exporter123
host = mysql
port = 3306

View File

@ -0,0 +1,4 @@
-- 创建 MySQL Exporter 监控账号
CREATE USER IF NOT EXISTS 'exporter'@'%' IDENTIFIED BY 'exporter123';
GRANT PROCESS, REPLICATION CLIENT, SELECT ON *.* TO 'exporter'@'%';
FLUSH PRIVILEGES;

0
nginx-cors-config.conf Normal file → Executable file
View File

View File

@ -0,0 +1 @@
<svg viewBox="0 0 400 300" fill="none" xmlns="http://www.w3.org/2000/svg"><mask id="a" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="94" y="34" width="212" height="233"><path d="M306 34H94v233h212V34Z" fill="#fff"/></mask><g mask="url(#a)"><path fill-rule="evenodd" clip-rule="evenodd" d="M234.427 155.64h38.36V69.6h-38.36v86.04ZM113.326 155.64h121.1V69.6h-121.1v86.04Z" fill="#fff"/><path fill-rule="evenodd" clip-rule="evenodd" d="M130.126 155.354h104.2v-72.95h-104.2v72.95ZM236.369 71.05s0 3.3 1.65 5.05c2.33 2.52 7.38-.2 7.38-.2s-1.75 5.15-1.55 10.19c.29 8.24 6.99 9.51 10 4.75 4.56 4.85 8.94-.29 9.52-2.62 4.27 4.76 9.32-.87 9.32-.87v-6.3l-23.99-12.13-12.33 2.13Z" fill="#C7DEFF"/><path fill-rule="evenodd" clip-rule="evenodd" d="M234.429 155.641h-121.1l-15.93 32.11h121.1l15.93-32.11Z" fill="#fff"/><path d="M234.427 69.6h38.46v86.04M113.326 146.52V69.6h121.1M234.429 155.641l-15.93 32.11h-121.1l15.93-32.11h111.39" stroke="#071F4D"/><path fill-rule="evenodd" clip-rule="evenodd" d="M226.37 159.715H116.82l-12.04 23.86H215l11.37-23.86Z" fill="#006EFF"/><path fill-rule="evenodd" clip-rule="evenodd" d="m288.807 187.751-15.92-32.11h-38.46l16.02 32.11h38.36Z" fill="#fff"/><path d="m238.607 163.981 11.84 23.77h38.36l-15.92-32.11h-38.46" stroke="#071F4D"/><path fill-rule="evenodd" clip-rule="evenodd" d="M207.336 223.734c-3.69-13.77-15.44-23.86-29.33-23.86h-8.65s-27.09 14.94-27.09 33.27c0 18.34 25.44 33.18 25.44 33.18h10.4c13.79-.1 25.44-10.19 29.13-23.87 1.75-12.51 0-18.62.1-18.72Z" fill="#C7DEFF"/><path fill-rule="evenodd" clip-rule="evenodd" d="M243.459 240.421c3.98 0 7.28-3.3 7.28-7.27 0-3.98-3.3-7.28-7.28-7.28h-31.08c-3.98 0-7.28 3.3-7.28 7.28 0 3.97 3.3 7.27 7.28 7.27h31.08Z" fill="#C7DEFF"/><path d="M210.342 223.737c-4.08-13.87-16.9-23.96-32.05-23.96H168.972s-29.62 14.94-29.62 33.37 27.87 33.37 27.87 33.37h11.27c15.05-.1 27.77-10.19 31.75-23.96" stroke="#071F4D"/><path d="M212.379 240.421c-3.98 0-7.28-3.3-7.28-7.27m0 0c0-3.98 3.3-7.28 7.28-7.28" stroke="#fff"/><path fill-rule="evenodd" clip-rule="evenodd" d="M168.781 199.777c-18.45 0-33.41 14.94-33.41 33.37s14.96 33.37 33.41 33.37c18.45 0 33.4-14.94 33.4-33.37s-14.95-33.37-33.4-33.37Z" fill="#006EFF"/><path d="M168.781 199.777c-18.45 0-33.41 14.94-33.41 33.37s14.96 33.37 33.41 33.37c18.45 0 33.4-14.94 33.4-33.37s-14.95-33.37-33.4-33.37Z" stroke="#071F4D"/><path fill-rule="evenodd" clip-rule="evenodd" d="M168.775 209.38c-13.14 0-23.79 10.64-23.79 23.77 0 13.12 10.65 23.76 23.79 23.76 13.14 0 23.8-10.64 23.8-23.76 0-13.13-10.66-23.77-23.8-23.77Z" fill="#00E4E5"/><path d="M162.174 223.736a17.48 17.48 0 0 1 14.76-8.05M159.455 231.982c.1-1.36.29-2.62.68-3.88" stroke="#fff"/><path fill-rule="evenodd" clip-rule="evenodd" d="M173.535 209.87c-1.55-.3-3.11-.49-4.76-.49-13.11 0-23.79 10.67-23.79 23.77 0 13.09 10.68 23.76 23.79 23.76 1.65 0 3.21-.19 4.76-.48-10.88-2.23-19.03-11.84-19.03-23.28 0-11.45 8.15-21.05 19.03-23.28Z" fill="#071F4D"/><path d="M219.957 225.774h23.6c4.08 0 7.38 3.3 7.38 7.37m0 0c0 4.08-3.3 7.37-7.38 7.37h-20.1M212.091 225.774h3.3" stroke="#071F4D"/><path d="m248.894 34.485-.19 18.24c0 4.07-.39 5.23-2.14 6.79-8.15 6.88-10.97 9.02-9.22 12.9 1.45 3.2 6.79 2.23 9.61-1.55-.39 4.56-5.24 15.32-.58 18.04 4.37 2.52 6.89-3.49 6.89-3.49s.49 3.49 4.47 3.49c3.69 0 5.24-4.75 5.24-4.75s2.14 3.49 6.22 1.35c3.11-1.55 5.44-7.08 5.44-26.67v-24.35" fill="#fff"/><path d="m248.894 34.485-.19 18.24c0 4.07-.39 5.23-2.14 6.79-8.15 6.88-10.97 9.02-9.22 12.9 1.45 3.2 6.79 2.23 9.61-1.55-.39 4.56-5.24 15.32-.58 18.04 4.37 2.52 6.89-3.49 6.89-3.49s.49 3.49 4.47 3.49c3.69 0 5.24-4.75 5.24-4.75s2.14 3.49 6.22 1.35c3.11-1.55 5.44-7.08 5.44-26.67v-24.35" stroke="#071F4D"/><path d="M255.307 75.71s-.39 5.43-2.04 9.6l2.04-9.6Z" fill="#fff"/><path d="M255.307 75.71s-.39 5.43-2.04 9.6" stroke="#071F4D"/><path d="M264.921 75.323s-.68 5.24-2.04 8.63l2.04-8.63Z" fill="#fff"/><path d="M264.921 75.323s-.68 5.24-2.04 8.63M147.801 34.485v34.92M121.775 34.485v34.92M102.546 204.724v13.97M102.546 222.379v.87M102.546 197.934v3.49M115.268 206.955v26.29M115.268 239.451v5.34M244.43 197.643v11.93M244.43 213.939v3.49M270.359 201.232v33.76M115.369 47.774h-13.6M94.486 47.774h3.4M241.516 47.774h-84.1M280.168 47.774h25.35" stroke="#071F4D"/><path fill-rule="evenodd" clip-rule="evenodd" d="m282.497 183.575-12.04-23.86h-27.29l11.36 23.86h27.97Z" fill="#00E4E5"/><path d="M234.427 134.88V69.6M234.427 140.412v7.66" stroke="#071F4D"/><path d="M220.831 228.684h16.99M240.934 228.684h2.43" stroke="#fff"/><path fill-rule="evenodd" clip-rule="evenodd" d="m223.842 187.462 21.46-.2-10.97-20.66-10.49 20.86Z" fill="#071F4D"/></g></svg>

After

Width:  |  Height:  |  Size: 4.5 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 5.0 KiB

View File

@ -0,0 +1,5 @@
<svg
viewBox="0 0 400 300"
fill="none"
xmlns="http://www.w3.org/2000/svg"
><mask id="a" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="47" y="38" width="307" height="224"><path d="M353.3 38H47.5v223.8h305.8V38Z" fill="#fff"/></mask><g mask="url(#a)"><path fill-rule="evenodd" clip-rule="evenodd" d="M299.2 200.6H61.6v5.1h240.3l-2.7-5.1Z" fill="#C7DEFF"/><path d="m308.9 185.8-6.5 20H183.7M332.3 127.6h10.6l-5 16.7-14.8-.1-7.2 21.1M328.8 127.4l13.6-39.6M307.6 166 337 84.7H180.6l-9.8 26.9h-10.5M296.6 196l4.3-11.8M157.2 149.2l6.4-17.7" stroke="#071F4D"/><path fill-rule="evenodd" clip-rule="evenodd" d="M324.8 93.1H188.5l-34.8 95.8h136.4l34.7-95.8ZM169.9 166.2l5-13.6-5 13.6Z" fill="#fff"/><path d="m169.9 166.2 5-13.6" stroke="#071F4D"/><path fill-rule="evenodd" clip-rule="evenodd" d="M324.8 93.1H188.5l-4 11.7h135.8l4.5-11.7Z" fill="#006EFF"/><path fill-rule="evenodd" clip-rule="evenodd" d="M102.6 159.5h38.3l2.7 36.6h-38.4c-10.1 0-20.9-8.2-20.9-18.3 0-10.1 8.2-18.3 18.3-18.3Z" fill="#DEEBFC"/><path fill-rule="evenodd" clip-rule="evenodd" d="M84.3 174.102c2.5 3.4 10 5 17.9 2.8 16.6-6.5 23.8-3.9 23.8-3.9s.5-3.4 1.3-5c-5.8-3-15.4.3-26.1 3.1-10.7 2.8-15.8-2.5-15.8-2.5-.4 0-1.1 2.8-1.1 5.5Z" fill="#fff"/><path d="M96.5 194.2c-7.2-3.3-12.2-10.5-12.2-19m0 0c0-11.5 9.3-20.8 20.8-20.8h29.4" stroke="#071F4D"/><path fill-rule="evenodd" clip-rule="evenodd" d="M140.3 195.1c-8.4-2.7-14.5-10.6-14.5-19.8l14.5 19.8Zm-14.5-19.8c0-11.5 9.3-20.8 20.8-20.8l-20.8 20.8Zm20.8-20.8c11.5 0 20.8 9.3 20.8 20.8l-20.8-20.8Zm20.8 20.8c0 8.4-5 15.6-12.1 18.9l12.1-18.9Z" fill="#fff"/><path d="M140.3 195.1c-8.4-2.7-14.5-10.6-14.5-19.8m0 0c0-11.5 9.3-20.8 20.8-20.8m0 0c11.5 0 20.8 9.3 20.8 20.8m0 0c0 8.4-5 15.6-12.1 18.9" stroke="#071F4D"/><path fill-rule="evenodd" clip-rule="evenodd" d="M161.5 177.2c0-7.7-6.3-14-14-14s-14 6.3-14 14c0 5.8 3.5 10.8 8.6 12.9.1 0 5.8 1.6 10.7 0 5.3-1.7 8.7-7.1 8.7-12.9Z" fill="#00E4E5"/><path d="M140.5 190.1c-5.8-2.4-9.9-8.2-9.9-14.9 0-8.9 7.2-16.1 16.1-16.1 8.9 0 16.1 7.2 16.1 16.1 0 6.8-4.2 12.5-10.1 14.9M88.4 170.604c2.9 1.3 7.7 2.6 13.6.3 14.7-5.7 22.3-4.3 24.6-3.5M84.5 174.599s5.9 6.5 19 1.7c9.2-3.4 15.3-3.9 18.8-3.8" stroke="#071F4D"/><path fill-rule="evenodd" clip-rule="evenodd" d="M340.6 112.3h-55.2l-2.7 6.2H338l2.6-6.2Z" fill="#071F4D"/><path fill-rule="evenodd" clip-rule="evenodd" d="M236.8 117.9c-16.13 0-29.2 13.07-29.2 29.2s13.07 29.2 29.2 29.2 29.2-13.07 29.2-29.2-13.07-29.2-29.2-29.2Z" fill="#00E4E5"/><path d="M265 123.3c13.1 13.1 13.1 34.4 0 47.6M306 205.9h19.2M61.7 205.9h32.9M181.2 196.2h115.2M47.5 205.9h10v-9.7h73.8" stroke="#071F4D"/><path fill-rule="evenodd" clip-rule="evenodd" d="M146.7 179.2c-2.49 0-4.5 2.01-4.5 4.5s2.01 4.5 4.5 4.5 4.5-2.01 4.5-4.5-2.01-4.5-4.5-4.5Z" fill="#071F4D"/><path fill-rule="evenodd" clip-rule="evenodd" d="M169.5 196.2c3.9 0 7.1 3.2 7.1 7.1 0 3.9-3.2 7.1-7.1 7.1H144c-2.1 0-3.9 1.7-3.9 3.9v1c0 2.1 1.7 3.9 3.9 3.9h48c5.1 0 9.2 4.1 9.2 9.2s-4.1 9.3-9.2 9.2h-33.8c-2.3 0-4.1 1.8-4.1 4.1s1.8 4.1 4.1 4.1h4.2c4.4 0 8 3.6 8 8s-3.6 8-8 8H111c-3.7 0-6.8-3-6.8-6.8 0-3.7 3-6.8 6.8-6.8h.3c2.3 0 4.1-1.8 4.1-4.1s-1.8-4.1-4.1-4.1H79c-4.5 0-8.1-3.6-8.1-8.1s3.6-8.1 8.1-8.1h37.7c2.1 0 3.9-1.7 3.9-3.9 0-2.1-1.7-3.9-3.9-3.9h-7.9c-4.4 0-7.9-3.5-7.9-7.9s3.5-7.9 7.9-7.9h30.4c2.2 0 3.9-1.8 3.9-3.9V187c0-1.9 1.6-3.5 3.5-3.5s3.5 1.6 3.5 3.5v5.3c0 2.2 1.8 3.9 3.9 3.9h15.5Z" fill="#006EFF"/><path d="m227.8 138.5 18.7 18.7M227.8 157.2l18.7-18.7" stroke="#fff" stroke-width="6"/><path fill-rule="evenodd" clip-rule="evenodd" d="M194.8 96.9c-.99 0-1.8.81-1.8 1.8s.81 1.8 1.8 1.8 1.8-.81 1.8-1.8-.81-1.8-1.8-1.8ZM202.9 96.9c-.99 0-1.8.81-1.8 1.8s.81 1.8 1.8 1.8 1.8-.81 1.8-1.8-.81-1.8-1.8-1.8Z" fill="#fff"/><path d="m291.7 184.3-1.6 4.6h-121M298.1 166.7l22.5-61.9" stroke="#071F4D"/><path fill-rule="evenodd" clip-rule="evenodd" d="m193 134.1 2.2-5.1h-19.4l-2.3 5.1H193ZM313.2 123.5l2.2-5.1h-24.5l-2.3 5.1h24.6Z" fill="#DEEBFC"/><path d="m164.5 159.2 19.8-54.6" stroke="#071F4D"/><path fill-rule="evenodd" clip-rule="evenodd" d="M199.6 119.8h-53.2l-4.4 9.3h53.2l4.4-9.3Z" fill="#00E4E5"/><path d="M151.3 129.1H142l4.4-9.3h16.9" stroke="#071F4D"/><path fill-rule="evenodd" clip-rule="evenodd" d="M353.3 169.4h-67.4l-4.8 12.2h67.3l4.9-12.2Z" fill="#006EFF"/><path d="M332.4 169.4h20.9l-4.9 12.2h-39.7M242.7 235.5v-4.8c0-3.8 3.1-7 7-7h20.2c3.8 0 7 3.1 7 7" stroke="#071F4D"/><path d="M261.1 235.5v-4.8c0-3.8 3.1-7 7-7h13.7c3.8 0 7 3.1 7 7v4.8M242.6 230.7h13.7M235.2 237.7h63.3M224 237.7h6.7" stroke="#071F4D"/><path fill-rule="evenodd" clip-rule="evenodd" d="M324.1 141.3H335l3.3-10.7h-10.2l-4 10.7Z" fill="#C7DEFF"/><path fill-rule="evenodd" clip-rule="evenodd" d="M288.3 230.4c0-3.6-2.9-6.5-6.5-6.5h-14.2c-3.6 0-6.5 2.9-6.5 6.5v5.3h27.2v-5.3Z" fill="#071F4D"/><path d="M80.4 228.5H83M87.7 228.5h19.2M146.3 195.8v2c0 3.6-2.9 6.6-6.6 6.6H138M133.4 204.3h1.5M154 249.9h9.4" stroke="#DEEBFC"/><path d="m299.4 141.9 5.1-13.9" stroke="#071F4D"/></g></svg>

After

Width:  |  Height:  |  Size: 4.8 KiB

View File

@ -0,0 +1 @@
.overview-cards[data-v-38548ddb]{display:grid;grid-template-columns:repeat(4,1fr);gap:16px;margin-bottom:24px}.overview-cards .card-item[data-v-38548ddb]{background:#f8f9fa;border-radius:8px;padding:16px;border:1px solid #ebeef5}.overview-cards .card-item .card-label[data-v-38548ddb]{font-size:13px;color:#909399;margin-bottom:8px}.overview-cards .card-item .card-value[data-v-38548ddb]{font-size:24px;font-weight:600;color:#303133;margin-bottom:8px}.overview-cards .card-item .card-value.text-primary[data-v-38548ddb]{color:var(--el-color-primary)}.overview-cards .card-item .card-value.text-success[data-v-38548ddb]{color:var(--el-color-success)}.overview-cards .card-item .card-value.text-warning[data-v-38548ddb]{color:var(--el-color-warning)}.overview-cards .card-item .card-value.text-danger[data-v-38548ddb]{color:var(--el-color-danger)}.overview-cards .card-item .card-value.text-info[data-v-38548ddb]{color:var(--el-color-info)}.overview-cards .card-item .card-sub[data-v-38548ddb]{font-size:12px;color:#606266}.level-badge[data-v-38548ddb]{padding:2px 6px;border-radius:4px;font-size:12px;font-weight:600}

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
import{_ as i}from"./ActivityRankingDrawer.vue_vue_type_script_setup_true_lang-DgB00tZC.js";import"./index-BoIUJTA2.js";/* empty css *//* empty css *//* empty css *//* empty css *//* empty css *//* empty css *//* empty css *//* empty css *//* empty css *//* empty css *//* empty css */import"./el-tooltip-l0sNRNKZ.js";/* empty css *//* empty css *//* empty css *//* empty css */import"./adminActivities-Dgt25iR5.js";import"./index-DqTthkO7.js";import"./index-BjuMygln.js";import"./index-Cp4NEpJ7.js";import"./index-BMeOzN3u.js";import"./index-COyGylbk.js";import"./index-Bq8lawOo.js";import"./_initCloneObject-DRmC-q3t.js";import"./isArrayLikeObject-CFQi-X2M.js";import"./raf-DsHSIRfX.js";import"./_baseIteratee-CtIat01j.js";import"./castArray-nM8ho4U3.js";import"./debounce-DQl5eUwG.js";import"./index-D8nVJoNy.js";import"./index-CXORCV4U.js";import"./index-DvejFoOw.js";import"./index-C1haaLtB.js";import"./index-D2gD5Tn5.js";import"./index-ZsMdSUVI.js";import"./token-DWNpOE8r.js";import"./index-B18-crhn.js";import"./use-dialog-FwJ-QdmW.js";export{i as default};

View File

@ -0,0 +1 @@
var e=(e,a,t)=>new Promise((l,o)=>{var s=e=>{try{i(t.next(e))}catch(a){o(a)}},r=e=>{try{i(t.throw(e))}catch(a){o(a)}},i=e=>e.done?l(e.value):Promise.resolve(e.value).then(s,r);i((t=t.apply(e,a)).next())});import{d as a,r as t,h as l,e as o,w as s,f as r,N as i,g as n,j as u,v as m,b2 as p,T as d}from"./index-BoIUJTA2.js";/* empty css *//* empty css *//* empty css *//* empty css *//* empty css *//* empty css *//* empty css *//* empty css *//* empty css *//* empty css *//* empty css */import"./el-tooltip-l0sNRNKZ.js";/* empty css *//* empty css *//* empty css *//* empty css */import{o as v}from"./adminActivities-Dgt25iR5.js";import{a as c,E as f}from"./index-DqTthkO7.js";import{E as j,a as g}from"./index-BjuMygln.js";import{E as x}from"./index-DvejFoOw.js";import{E as h}from"./index-C1haaLtB.js";import{E as y}from"./index-B18-crhn.js";const _={class:"mb-4 flex items-center justify-between"},b={class:"flex items-center"},w={class:"font-medium"},V={class:"text-xs text-g-400"},z={class:"font-mono"},E={class:"mt-4 flex justify-end"},U=a({__name:"ActivityRankingDrawer",setup(a,{expose:U}){const k=t(!1),C=t(!1),P=t(0),A=t("amount"),D=t(1),S=t(20),T=t(0),W=t([]),B=()=>e(this,null,function*(){D.value=1,yield F()}),F=()=>e(this,null,function*(){if(P.value){C.value=!0;try{const e=yield v(P.value,{sort_by:A.value,page:D.value,page_size:S.value});W.value=e.list||[],T.value=e.total||0}catch(e){d.error("获取活动排行榜失败")}finally{C.value=!1}}});return U({open:a=>e(this,null,function*(){P.value=a,A.value="amount",D.value=1,k.value=!0,yield F()})}),(e,a)=>{const t=f,d=c,v=g,U=x,P=j,G=h,I=y,M=p;return o(),l(I,{modelValue:k.value,"onUpdate:modelValue":a[3]||(a[3]=e=>k.value=e),title:"活动消费/订单排行榜",size:"70%","destroy-on-close":!0},{default:s(()=>[r("div",_,[n(d,{modelValue:A.value,"onUpdate:modelValue":a[0]||(a[0]=e=>A.value=e),size:"small",onChange:B},{default:s(()=>[n(t,{label:"amount"},{default:s(()=>[...a[4]||(a[4]=[u("消费总额排名",-1)])]),_:1}),n(t,{label:"orders"},{default:s(()=>[...a[5]||(a[5]=[u("订单数排名",-1)])]),_:1})]),_:1},8,["modelValue"]),a[6]||(a[6]=r("div",{class:"text-sm text-g-500"},"仅统计已支付订单GMV = 实付 + 优惠)",-1))]),i((o(),l(P,{data:W.value,border:"",stripe:""},{default:s(()=>[n(v,{prop:"rank",label:"排名",width:"80",align:"center"}),n(v,{label:"用户","min-width":"220"},{default:s(({row:e})=>[r("div",b,[n(U,{size:30,src:e.avatar,class:"mr-3"},null,8,["src"]),r("div",null,[r("div",w,m(e.nickname||"未设置昵称"),1),r("div",V,"ID: "+m(e.user_id),1)])])]),_:1}),n(v,{label:"消费总额(元)",width:"170",align:"right"},{default:s(({row:e})=>[r("span",z,"¥"+m(((e.total_amount||0)/100).toFixed(2)),1)]),_:1}),n(v,{prop:"order_count",label:"订单数",width:"120",align:"center"})]),_:1},8,["data"])),[[M,C.value]]),r("div",E,[n(G,{"current-page":D.value,"onUpdate:currentPage":a[1]||(a[1]=e=>D.value=e),"page-size":S.value,"onUpdate:pageSize":a[2]||(a[2]=e=>S.value=e),total:T.value,layout:"prev, pager, next, jumper",onCurrentChange:F},null,8,["current-page","page-size","total"])])]),_:1},8,["modelValue"])}}});export{U as _};

View File

@ -0,0 +1 @@
import{d as a,C as s,u as t,H as e,b as m,e as r,f as l,g as c,N as n,v as d,h as x,E as i,w as o,j as p}from"./index-BoIUJTA2.js";/* empty css */import{_ as u}from"./index-DVdhsH_J.js";const g={class:"page-content !border-0 !bg-transparent min-h-screen flex-cc"},f={class:"flex-cc max-md:!block max-md:text-center"},b={class:"ml-15 w-75 max-md:mx-auto max-md:mt-10 max-md:w-full max-md:text-center"},h={class:"text-xl leading-7 text-g-600 max-md:text-lg"},v=a({__name:"ArtException",props:{data:{}},setup(a){const v=s(),{homePath:_}=t(),j=()=>{v.push(_.value)};return(s,t)=>{const v=u,_=i,w=e("ripple");return r(),m("div",g,[l("div",f,[c(v,{src:a.data.imgUrl,size:"100%",class:"!w-100"},null,8,["src"]),l("div",b,[l("p",h,d(a.data.desc),1),n((r(),x(_,{type:"primary",size:"large",onClick:j,class:"mt-5"},{default:o(()=>[p(d(a.data.btnText),1)]),_:1})),[[w]])])])])}}});export{v as _};

View File

@ -0,0 +1 @@
var e=Object.defineProperty,t=Object.defineProperties,s=Object.getOwnPropertyDescriptors,r=Object.getOwnPropertySymbols,a=Object.prototype.hasOwnProperty,o=Object.prototype.propertyIsEnumerable,p=(t,s,r)=>s in t?e(t,s,{enumerable:!0,configurable:!0,writable:!0,value:r}):t[s]=r;import{_ as l}from"./index.vue_vue_type_script_setup_true_lang-DUbflfBQ.js";import{d as n,b as c,e as m,g as i,f as d,q as u,v as x,s as b}from"./index-BoIUJTA2.js";const g={class:"title mt-8 text-3xl font-medium !text-g-900 max-md:mt-2.5 max-md:text-2xl"},f={class:"msg mt-5 text-base text-g-600"},_={class:"res mt-7.5 rounded bg-g-200/80 dark:bg-g-300/40 px-7.5 py-5.5 text-left max-md:px-7.5 max-md:py-2.5 [&_p]:flex [&_p]:items-center [&_p]:py-2 [&_p]:text-sm [&_p]:text-[#808695] [&_p_i]:mr-1.5"},y={class:"btn-group mt-12.5"},v=n((O=((e,t)=>{for(var s in t||(t={}))a.call(t,s)&&p(e,s,t[s]);if(r)for(var s of r(t))o.call(t,s)&&p(e,s,t[s]);return e})({},{name:"ArtResultPage"}),t(O,s({__name:"ArtResultPage",props:{type:{default:"success"},title:{default:""},message:{default:""},iconCode:{default:""}},setup:e=>(t,s)=>{const r=l;return m(),c("div",{class:u(["page-content box-border !px-20 py-3.5 text-center max-md:!px-5",e.type])},[i(r,{class:u(["icon size-22 p-2 mt-16 block rounded-full !text-white","success"===e.type?"bg-[#19BE6B]":"bg-[#ED4014]"]),icon:e.iconCode},null,8,["icon","class"]),d("h1",g,x(e.title),1),d("p",f,x(e.message),1),d("div",_,[b(t.$slots,"content")]),d("div",y,[b(t.$slots,"buttons")])],2)}}))));var O;export{v as _};

View File

@ -0,0 +1 @@
.unit[data-v-47e87be5]{margin-left:8px;color:#909399}.form-tip[data-v-47e87be5]{margin-top:4px;font-size:12px;color:#909399;line-height:1.4}

File diff suppressed because one or more lines are too long

Binary file not shown.

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
.effect-manager[data-v-31a74478]{padding:0}.toolbar[data-v-31a74478]{margin-bottom:16px;display:flex;gap:12px}.params-view[data-v-31a74478]{display:flex;flex-wrap:wrap;gap:4px}.params-view .el-tag[data-v-31a74478]{margin:2px}

View File

@ -0,0 +1 @@
var e=Object.defineProperty,r=Object.defineProperties,a=Object.getOwnPropertyDescriptors,t=Object.getOwnPropertySymbols,o=Object.prototype.hasOwnProperty,n=Object.prototype.propertyIsEnumerable,s=(r,a,t)=>a in r?e(r,a,{enumerable:!0,configurable:!0,writable:!0,value:t}):r[a]=t;import{d as l,a as f,r as c,o as i,b1 as b,N as p,b2 as u,p as m,e as d,b as v,f as y}from"./index-BoIUJTA2.js";const O={class:"box-border w-full h-full"},h=["src"],j=l((w=((e,r)=>{for(var a in r||(r={}))o.call(r,a)&&s(e,a,r[a]);if(t)for(var a of t(r))n.call(r,a)&&s(e,a,r[a]);return e})({},{name:"IframeView"}),r(w,a({__name:"Iframe",setup(e){const r=f(),a=c(!0),t=c(""),o=c(null);i(()=>{const e=b.getInstance().findByPath(r.path);(null==e?void 0:e.meta)&&(t.value=e.meta.link||"")});const n=()=>{a.value=!1};return(e,r)=>{const s=u;return p((d(),v("div",O,[y("iframe",{ref_key:"iframeRef",ref:o,src:m(t),frameborder:"0",class:"w-full h-full min-h-[calc(100vh-120px)] border-none",onLoad:n},null,40,h)])),[[s,m(a)]])}}}))));var w;export{j as default};

File diff suppressed because one or more lines are too long

Binary file not shown.

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Binary file not shown.

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
.json-editor[data-v-cf7dfd13]{position:relative}.json-editor .el-button[data-v-cf7dfd13]{position:absolute;right:10px;bottom:10px}

View File

@ -0,0 +1 @@
.user-assignment[data-v-dcfb44a3]{display:flex;flex-direction:column;gap:16px;max-height:70vh;overflow-y:auto}.search-card[data-v-dcfb44a3]{margin-bottom:0}.search-form[data-v-dcfb44a3]{display:flex;flex-wrap:wrap;gap:8px}.card-header[data-v-dcfb44a3]{display:flex;justify-content:space-between;align-items:center}.header-actions[data-v-dcfb44a3]{display:flex;align-items:center;gap:12px}.title-tags[data-v-dcfb44a3]{display:flex;flex-wrap:wrap;gap:4px}.title-icon[data-v-dcfb44a3]{margin-left:2px}.pagination-container[data-v-dcfb44a3]{margin-top:16px;display:flex;justify-content:center}.assignment-config-card[data-v-dcfb44a3]{background-color:#f5f7fa}.unit[data-v-dcfb44a3]{margin-left:8px;color:#909399}.dialog-footer[data-v-dcfb44a3]{display:flex;justify-content:flex-end;gap:12px}

File diff suppressed because one or more lines are too long

Binary file not shown.

View File

@ -0,0 +1 @@
import{cM as e,d5 as t,d6 as r,d7 as a,d8 as c,d9 as n,da as o,db as s,dc as b,dd as u,cI as i,cO as j,cT as f,de as y,cQ as d,df as l}from"./index-BoIUJTA2.js";import{c as A,k as p,g as v,e as g,d as w,a as m,b as x,i as O}from"./_initCloneObject-DRmC-q3t.js";var I=Object.getOwnPropertySymbols?function(e){for(var r=[];e;)a(r,t(e)),e=v(e);return r}:r;function S(e){return c(e,p,I)}var U=Object.prototype.hasOwnProperty;var h=/\w*$/;var F=n?n.prototype:void 0,M=F?F.valueOf:void 0;function E(e,t,r){var a,c,n,o=e.constructor;switch(t){case"[object ArrayBuffer]":return g(e);case"[object Boolean]":case"[object Date]":return new o(+e);case"[object DataView]":return function(e,t){var r=t?g(e.buffer):e.buffer;return new e.constructor(r,e.byteOffset,e.byteLength)}(e,r);case"[object Float32Array]":case"[object Float64Array]":case"[object Int8Array]":case"[object Int16Array]":case"[object Int32Array]":case"[object Uint8Array]":case"[object Uint8ClampedArray]":case"[object Uint16Array]":case"[object Uint32Array]":return w(e,r);case"[object Map]":case"[object Set]":return new o;case"[object Number]":case"[object String]":return new o(e);case"[object RegExp]":return(n=new(c=e).constructor(c.source,h.exec(c))).lastIndex=c.lastIndex,n;case"[object Symbol]":return a=e,M?Object(M.call(a)):{}}}var B=u&&u.isMap,D=B?b(B):function(e){return o(e)&&"[object Map]"==s(e)};var C=u&&u.isSet,k=C?b(C):function(e){return o(e)&&"[object Set]"==s(e)},N="[object Arguments]",P="[object Function]",R="[object Object]",V={};function G(r,a,c,n,o,b){var u,v=1&a,g=2&a,w=4&a;if(c&&(u=o?c(r,n,o,b):c(r)),void 0!==u)return u;if(!i(r))return r;var h=d(r);if(h){if(u=function(e){var t=e.length,r=new e.constructor(t);return t&&"string"==typeof e[0]&&U.call(e,"index")&&(r.index=e.index,r.input=e.input),r}(r),!v)return m(r,u)}else{var F=s(r),M=F==P||"[object GeneratorFunction]"==F;if(j(r))return x(r,v);if(F==R||F==N||M&&!o){if(u=g||M?{}:O(r),!v)return g?function(e,t){return A(e,I(e),t)}(r,function(e,t){return e&&A(t,p(t),e)}(u,r)):function(e,r){return A(e,t(e),r)}(r,function(t,r){return t&&A(r,e(r),t)}(u,r))}else{if(!V[F])return o?r:{};u=E(r,F,v)}}b||(b=new f);var B=b.get(r);if(B)return B;b.set(r,u),k(r)?r.forEach(function(e){u.add(G(e,a,c,e,r,b))}):D(r)&&r.forEach(function(e,t){u.set(t,G(e,a,c,t,r,b))});var C=h?void 0:(w?g?S:y:g?p:e)(r);return function(e,t){for(var r=-1,a=null==e?0:e.length;++r<a&&!1!==t(e[r],r,e););}(C||r,function(e,t){C&&(e=r[t=e]),l(u,t,G(e,a,c,t,r,b))}),u}V[N]=V["[object Array]"]=V["[object ArrayBuffer]"]=V["[object DataView]"]=V["[object Boolean]"]=V["[object Date]"]=V["[object Float32Array]"]=V["[object Float64Array]"]=V["[object Int8Array]"]=V["[object Int16Array]"]=V["[object Int32Array]"]=V["[object Map]"]=V["[object Number]"]=V[R]=V["[object RegExp]"]=V["[object Set]"]=V["[object String]"]=V["[object Symbol]"]=V["[object Uint8Array]"]=V["[object Uint8ClampedArray]"]=V["[object Uint16Array]"]=V["[object Uint32Array]"]=!0,V["[object Error]"]=V[P]=V["[object WeakMap]"]=!1;export{G as b,S as g};

View File

@ -0,0 +1 @@
import{cT as n,dF as r,cI as t,cM as u,dG as e,bi as i,c2 as o,dH as f,bg as a,dI as c,cQ as s}from"./index-BoIUJTA2.js";function v(n){return n==n&&!t(n)}function l(n,r){return function(t){return null!=t&&(t[n]===r&&(void 0!==r||n in Object(t)))}}function d(t){var e=function(n){for(var r=u(n),t=r.length;t--;){var e=r[t],i=n[e];r[t]=[e,i,v(i)]}return r}(t);return 1==e.length&&e[0][2]?l(e[0][0],e[0][1]):function(u){return u===t||function(t,u,e,i){var o=e.length,f=o;if(null==t)return!f;for(t=Object(t);o--;){var a=e[o];if(a[2]?a[1]!==t[a[0]]:!(a[0]in t))return!1}for(;++o<f;){var c=(a=e[o])[0],s=t[c],v=a[1];if(a[2]){if(void 0===s&&!(c in t))return!1}else{var l=new n;if(!r(v,s,3,i,l))return!1}}return!0}(u,0,e)}}function b(n){return e(n)?(r=i(n),function(n){return null==n?void 0:n[r]}):function(n){return function(r){return a(r,n)}}(n);var r}function g(n){return"function"==typeof n?n:null==n?c:"object"==typeof n?s(n)?(t=n[0],u=n[1],e(t)&&v(u)?l(i(t),u):function(n){var e=o(n,t);return void 0===e&&e===u?f(n,t):r(u,e,3)}):d(n):b(n);var t,u}export{g as b};

View File

@ -0,0 +1 @@
import{cI as r,cN as t,df as e,dg as n,dh as o,cJ as u,di as a,dj as c,dk as f}from"./index-BoIUJTA2.js";var s=Object.create,i=function(){function t(){}return function(e){if(!r(e))return{};if(s)return s(e);t.prototype=e;var n=new t;return t.prototype=void 0,n}}();function p(r,t){var e=-1,n=r.length;for(t||(t=Array(n));++e<n;)t[e]=r[e];return t}function v(r,n,o,u){var a=!o;o||(o={});for(var c=-1,f=n.length;++c<f;){var s=n[c],i=void 0;void 0===i&&(i=r[s]),a?t(o,s,i):e(o,s,i)}return o}var d=Object.prototype.hasOwnProperty;function l(t){if(!r(t))return function(r){var t=[];if(null!=r)for(var e in Object(r))t.push(e);return t}(t);var e=n(t),o=[];for(var u in t)("constructor"!=u||!e&&d.call(t,u))&&o.push(u);return o}function y(r){return u(r)?o(r,!0):l(r)}var b=a(Object.getPrototypeOf,Object),h="object"==typeof exports&&exports&&!exports.nodeType&&exports,j=h&&"object"==typeof module&&module&&!module.nodeType&&module,g=j&&j.exports===h?c.Buffer:void 0,O=g?g.allocUnsafe:void 0;function w(r,t){if(t)return r.slice();var e=r.length,n=O?O(e):new r.constructor(e);return r.copy(n),n}function x(r){var t=new r.constructor(r.byteLength);return new f(t).set(new f(r)),t}function m(r,t){var e=t?x(r.buffer):r.buffer;return new r.constructor(e,r.byteOffset,r.length)}function k(r){return"function"!=typeof r.constructor||n(r)?{}:i(b(r))}export{p as a,w as b,v as c,m as d,x as e,b as g,k as i,y as k};

View File

@ -0,0 +1 @@
const o=(o,t)=>{const c=o.__vccOpts||o;for(const[s,n]of t)c[s]=n;return c};export{o as _};

View File

@ -0,0 +1 @@
import{_ as e}from"./_plugin-vue_export-helper-BCo6x5W8.js";const r=e({},[["render",function(e,r){return null}]]);export{r as default};

View File

@ -0,0 +1 @@
var e=Object.defineProperty,t=Object.defineProperties,a=Object.getOwnPropertyDescriptors,s=Object.getOwnPropertySymbols,r=Object.prototype.hasOwnProperty,o=Object.prototype.propertyIsEnumerable,i=(t,a,s)=>a in t?e(t,a,{enumerable:!0,configurable:!0,writable:!0,value:s}):t[a]=s,l=(e,t)=>{for(var a in t||(t={}))r.call(t,a)&&i(e,a,t[a]);if(s)for(var a of s(t))o.call(t,a)&&i(e,a,t[a]);return e};import{d as n,c as d,N as c,b2 as u,b as p,e as m,m as h,L as y,r as f,k as x,g,X as b,f as v,I as w,J as A,v as L,T as S}from"./index-BoIUJTA2.js";import{u as k,a as j,g as O}from"./useChart-DmniNG26.js";import{a as P}from"./operations-Cr4YfoRu.js";import"./installCanvasRenderer-D-xUkWdX.js";const B=n((W=l({},{name:"ArtBarChart"}),D={__name:"index",props:{data:{default:()=>[0,0,0,0,0,0,0]},xAxisData:{default:()=>[]},barWidth:{default:"40%"},stack:{type:Boolean,default:!1},borderRadius:{default:4},height:{default:k().chartHeight},loading:{type:Boolean,default:!1},isEmpty:{type:Boolean,default:!1},colors:{default:()=>k().colors},showAxisLabel:{type:Boolean,default:!0},showAxisLine:{type:Boolean,default:!0},showSplitLine:{type:Boolean,default:!0},showTooltip:{type:Boolean,default:!0},showLegend:{type:Boolean,default:!1},legendPosition:{default:"bottom"}},setup(e){const t=e,a=d(()=>Array.isArray(t.data)&&t.data.length>0&&"object"==typeof t.data[0]&&"name"in t.data[0]),s=(e,a)=>e||(void 0!==a?t.colors[a%t.colors.length]:new O.LinearGradient(0,0,0,1,[{offset:0,color:y("--el-color-primary-light-4")},{offset:1,color:y("--el-color-primary")}])),r=e=>new O.LinearGradient(0,0,0,1,[{offset:0,color:e},{offset:1,color:e}]),o=e=>{const a=b();return l({name:e.name,data:e.data,type:"bar",stack:e.stack,itemStyle:(s=e.color,{borderRadius:t.borderRadius,color:"string"==typeof s?r(s):s}),barWidth:e.barWidth||t.barWidth},a);var s},{chartRef:i,getAxisLineStyle:n,getAxisLabelStyle:f,getAxisTickStyle:x,getSplitLineStyle:g,getAnimationConfig:b,getTooltipStyle:v,getLegendStyle:w,getGridWithLegend:A}=j({props:t,checkEmpty:()=>{if(Array.isArray(t.data)&&"number"==typeof t.data[0]){const e=t.data;return!e.length||e.every(e=>0===e)}if(Array.isArray(t.data)&&"object"==typeof t.data[0]){const e=t.data;return!e.length||e.every(e=>{var t;return!(null==(t=e.data)?void 0:t.length)||e.data.every(e=>0===e)})}return!0},watchSources:[()=>t.data,()=>t.xAxisData,()=>t.colors],generateOptions:()=>{const e={grid:A(t.showLegend&&a.value,t.legendPosition,{top:15,right:0,left:0}),tooltip:t.showTooltip?v():void 0,xAxis:{type:"category",data:t.xAxisData,axisTick:x(),axisLine:n(t.showAxisLine),axisLabel:f(t.showAxisLabel)},yAxis:{type:"value",axisLabel:f(t.showAxisLabel),axisLine:n(t.showAxisLine),splitLine:g(t.showSplitLine)}};if(t.showLegend&&a.value&&(e.legend=w(t.legendPosition)),a.value){const a=t.data;e.series=a.map((e,a)=>{const r=s(t.colors[a],a);return o({name:e.name,data:e.data,color:r,barWidth:e.barWidth,stack:t.stack?e.stack||"total":void 0})})}else{const a=t.data,r=s();e.series=[o({data:a,color:r})]}return e}});return(e,a)=>{const s=u;return c((m(),p("div",{ref_key:"chartRef",ref:i,style:h({height:t.height})},null,4)),[[s,t.loading]])}}},t(W,a(D))));var W,D;const R={class:"art-card h-105 p-4 box-border mb-5 max-sm:mb-4"},T={class:"flex-b mt-2"},_={class:"text-2xl text-g-900"},C={class:"text-xs text-g-500"},G=n({__name:"active-user",setup(e){const t=f([]),a=f([]),s=x([{name:"总用户量",num:"0"},{name:"总访问量",num:"0"},{name:"日访问量",num:"0"},{name:"周同比",num:"+0%"}]);return(()=>{return e=this,r=null,o=function*(){try{const e=yield P("30d");t.value=e.chart.map(e=>e.date.slice(5)),a.value=e.chart.map(e=>e.value),s[0].num=String(e.metrics.totalUsers),s[1].num=String(e.metrics.totalVisits),s[2].num=String(e.metrics.dailyVisits),s[3].num=e.metrics.weeklyGrowth}catch(e){S.error("加载用户概述失败")}},new Promise((t,a)=>{var s=e=>{try{l(o.next(e))}catch(t){a(t)}},i=e=>{try{l(o.throw(e))}catch(t){a(t)}},l=e=>e.done?t(e.value):Promise.resolve(e.value).then(s,i);l((o=o.apply(e,r)).next())});var e,r,o})(),(e,r)=>{const o=B;return m(),p("div",R,[g(o,{class:"box-border p-2",barWidth:"50%",height:"13.7rem",showAxisLine:!1,data:a.value,xAxisData:t.value},null,8,["data","xAxisData"]),r[0]||(r[0]=b('<div class="ml-1"><h3 class="mt-5 text-lg font-medium">用户概述</h3><p class="mt-1 text-sm">比上周 <span class="text-success font-medium">+23%</span></p><p class="mt-1 text-sm">我们为您创建了多个选项,可将它们组合在一起并定制为像素完美的页面</p></div>',1)),v("div",T,[(m(!0),p(w,null,A(s,(e,t)=>(m(),p("div",{class:"flex-1",key:t},[v("p",_,L(e.num),1),v("p",C,L(e.name),1)]))),128))])])}}});export{G as default};

View File

@ -0,0 +1 @@
var e=Object.defineProperty,r=Object.getOwnPropertySymbols,t=Object.prototype.hasOwnProperty,a=Object.prototype.propertyIsEnumerable,s=(r,t,a)=>t in r?e(r,t,{enumerable:!0,configurable:!0,writable:!0,value:a}):r[t]=a;import{c1 as o}from"./index-BoIUJTA2.js";function i(e){return i=this,n=null,c=function*(){const i=((e,o)=>{for(var i in o||(o={}))t.call(o,i)&&s(e,i,o[i]);if(r)for(var i of r(o))a.call(o,i)&&s(e,i,o[i]);return e})({page:1,page_size:20},e||{});try{const e=yield o.get({url:"admin/activities",params:i,showErrorMessage:!1});return{records:e.list.map(e=>({id:e.id,name:e.name,categoryName:e.category_name,status:e.status,priceDraw:e.price_draw,isBoss:e.is_boss,drawMode:"",playType:e.play_type||"",minParticipants:0,intervalMinutes:0,scheduledTime:""})),total:e.total,current:e.page,size:e.page_size}}catch(n){return{records:[],total:0,current:i.page,size:i.page_size}}},new Promise((e,r)=>{var t=e=>{try{s(c.next(e))}catch(t){r(t)}},a=e=>{try{s(c.throw(e))}catch(t){r(t)}},s=r=>r.done?e(r.value):Promise.resolve(r.value).then(t,a);s((c=c.apply(i,n)).next())});var i,n,c}export{i as f};

View File

@ -0,0 +1 @@
import{d as t,r as e,k as l,o as a,b as s,e as r,f as o,v as n,I as i,J as c,j as d,q as g,g as x,w as v,n as f}from"./index-BoIUJTA2.js";/* empty css */import{b as u,c as b}from"./operations-Cr4YfoRu.js";import{E as p}from"./index-ZsMdSUVI.js";const h={class:"art-card h-140 p-5 mb-5 max-sm:mb-4"},m={class:"h-[calc(100%-40px)]"},y={class:"grid grid-cols-4 gap-4 mb-6"},w={class:"text-center p-3 bg-blue-50 rounded-lg"},C={class:"text-2xl font-bold text-blue-600"},R={class:"text-center p-3 bg-green-50 rounded-lg"},S={class:"text-2xl font-bold text-green-600"},j={class:"text-center p-3 bg-yellow-50 rounded-lg"},k={class:"text-2xl font-bold text-yellow-600"},P={class:"text-center p-3 bg-purple-50 rounded-lg"},$={class:"text-2xl font-bold text-purple-600"},T={class:"h-60 mb-4"},_={class:"overflow-auto"},A={class:"w-full text-sm"},W={class:"py-2"},E={class:"flex items-center"},F={class:"py-2"},L={class:"py-2"},N={class:"py-2"},q={class:"py-2"},z=t({__name:"activity-lottery",setup(t){const z=e(),D=l({totalActivities:0,totalParticipants:0,totalDraws:0,winnerCount:0,overallWinRate:0,costControl:0}),G=l([]),I=e(!1),J=t=>t.winRate>2?"success":t.winRate>1?"warning":"info",M=t=>t.winRate>2?"高中奖率":t.winRate>1?"中等中奖率":"低中奖率",O=(t,e)=>({1:`rgba(251, 191, 36, ${e})`,2:`rgba(156, 163, 175, ${e})`,3:`rgba(251, 146, 60, ${e})`,4:`rgba(96, 165, 250, ${e})`,5:`rgba(52, 211, 153, ${e})`}[t]||`rgba(156, 163, 175, ${e})`),B=()=>{return t=this,e=null,l=function*(){I.value=!0;try{const[t,e]=yield Promise.all([u("7d"),b("7d")]);Object.assign(D,t),G.splice(0,G.length,...e),f(()=>{(()=>{if(!z.value||0===G.length)return;const t=z.value,e=t.getContext("2d");if(!e)return;e.clearRect(0,0,t.width,t.height);const l=40,a=t.width-80,s=t.height-80,r=Math.max(...G.map(t=>t.winnerCount)),o=a/G.length*.6,n=a/G.length*.4;G.forEach((t,a)=>{const i=l+a*(o+n)+n/2,c=t.winnerCount/r*s,d=l+s-c,g=e.createLinearGradient(i,d+c,i,d);g.addColorStop(0,O(t.level,.8)),g.addColorStop(1,O(t.level,1)),e.fillStyle=g,e.fillRect(i,d,o,c),e.fillStyle="#333",e.font="12px sans-serif",e.textAlign="center",e.fillText(t.winnerCount.toString(),i+o/2,d-5),e.fillText(t.levelName,i+o/2,l+s+20)}),e.strokeStyle="#e0e0e0",e.lineWidth=1,e.beginPath(),e.moveTo(l,l),e.lineTo(l,l+s),e.lineTo(l+a,l+s),e.stroke()})()})}catch(t){}finally{I.value=!1}},new Promise((a,s)=>{var r=t=>{try{n(l.next(t))}catch(e){s(e)}},o=t=>{try{n(l.throw(t))}catch(e){s(e)}},n=t=>t.done?a(t.value):Promise.resolve(t.value).then(r,o);n((l=l.apply(t,e)).next())});var t,e,l};return a(()=>{B()}),(t,e)=>{const l=p;return r(),s("div",h,[e[5]||(e[5]=o("div",{class:"art-card-header"},[o("div",{class:"title"},[o("h4",null,"活动抽奖效果分析"),o("p",null,"优化中奖概率,控制活动成本")])],-1)),o("div",m,[o("div",y,[o("div",w,[o("div",C,n(D.totalActivities),1),e[0]||(e[0]=o("div",{class:"text-sm text-g-500"},"活动总数",-1))]),o("div",R,[o("div",S,n((a=D.totalParticipants,a>=1e4?(a/1e4).toFixed(1)+"w":a>=1e3?(a/1e3).toFixed(1)+"k":a.toString())),1),e[1]||(e[1]=o("div",{class:"text-sm text-g-500"},"参与人数",-1))]),o("div",j,[o("div",k,n(D.overallWinRate)+"%",1),e[2]||(e[2]=o("div",{class:"text-sm text-g-500"},"整体中奖率",-1))]),o("div",P,[o("div",$,n(D.costControl)+"%",1),e[3]||(e[3]=o("div",{class:"text-sm text-g-500"},"成本控制",-1))])]),o("div",T,[o("canvas",{ref_key:"chartRef",ref:z,width:"400",height:"240"},null,512)]),o("div",_,[o("table",A,[e[4]||(e[4]=o("thead",null,[o("tr",{class:"border-b border-g-200"},[o("th",{class:"text-left py-2"},"奖级"),o("th",{class:"text-left py-2"},"中奖人数"),o("th",{class:"text-left py-2"},"中奖率"),o("th",{class:"text-left py-2"},"成本"),o("th",{class:"text-left py-2"},"状态")])],-1)),o("tbody",null,[(r(!0),s(i,null,c(G,t=>{return r(),s("tr",{key:t.level,class:"border-b border-g-100 hover:bg-g-50"},[o("td",W,[o("div",E,[o("span",{class:g(["w-6 h-6 rounded-full flex items-center justify-center text-white text-xs font-bold mr-2",(e=t.level,{1:"bg-gradient-to-r from-yellow-400 to-yellow-300",2:"bg-gradient-to-r from-gray-400 to-gray-300",3:"bg-gradient-to-r from-orange-400 to-orange-300",4:"bg-gradient-to-r from-blue-400 to-blue-300",5:"bg-gradient-to-r from-green-400 to-green-300"}[e]||"bg-gradient-to-r from-gray-400 to-gray-300")])},n(t.level),3),d(" "+n(t.levelName),1)])]),o("td",F,n(t.winnerCount)+"人",1),o("td",L,n(t.winRate)+"%",1),o("td",N,"¥"+n(t.cost.toLocaleString()),1),o("td",q,[x(l,{type:J(t),size:"small"},{default:v(()=>[d(n(M(t)),1)]),_:2},1032,["type"])])]);var e}),128))])])])])]);var a}}});export{z as default};

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
.profit-card[data-v-4afd189b]{padding:1.25rem;background:var(--default-box-color);border:1px solid var(--art-gray-200);border-radius:calc(var(--custom-radius) + 4px);transition:all .3s cubic-bezier(.4,0,.2,1)}.profit-card[data-v-4afd189b]:hover{transform:translateY(-4px);border-color:var(--el-color-primary);box-shadow:0 12px 24px -8px rgba(var(--el-color-primary-rgb),.15)}.stat-item[data-v-4afd189b]{padding:.75rem;background:var(--art-gray-100);border:1px solid var(--art-gray-200);border-radius:calc(var(--custom-radius))}[data-v-4afd189b] .el-table{--el-table-border-color: var(--art-gray-200);--el-table-header-bg-color: var(--art-gray-100)}[data-v-4afd189b] .el-dialog{border-radius:calc(var(--custom-radius) + 8px);overflow:hidden}[data-v-4afd189b] .el-dialog__header{margin-right:0;padding-bottom:20px;border-bottom:1px solid var(--art-gray-200)}.payment-details-cell[data-v-4afd189b]{display:flex;flex-direction:column}.payment-detail-item[data-v-4afd189b]{display:flex;align-items:center;font-size:11px;padding:2px 0}.payment-detail-item i[data-v-4afd189b]{font-size:12px}.detail-filter-row[data-v-4afd189b]{display:flex;flex-wrap:wrap;gap:12px;margin-bottom:16px}.filter-input[data-v-4afd189b]{width:220px}

File diff suppressed because one or more lines are too long

Binary file not shown.

View File

@ -0,0 +1 @@
var e=Object.defineProperty,a=Object.getOwnPropertySymbols,l=Object.prototype.hasOwnProperty,t=Object.prototype.propertyIsEnumerable,o=(a,l,t)=>l in a?e(a,l,{enumerable:!0,configurable:!0,writable:!0,value:t}):a[l]=t,s=(e,s)=>{for(var r in s||(s={}))l.call(s,r)&&o(e,r,s[r]);if(a)for(var r of a(s))t.call(s,r)&&o(e,r,s[r]);return e};import{d as r,r as i,A as u,H as d,h as p,e as m,w as n,g as c,p as f,K as b,P as v,b as _,I as j,J as y,N as h,E as V,j as x,ai as g,bb as w}from"./index-BoIUJTA2.js";/* empty css *//* empty css *//* empty css *//* empty css *//* empty css *//* empty css *//* empty css *//* empty css */import{e as E}from"./adminActivities-Dgt25iR5.js";import{A as O}from"./activityEnums-zI8yOqFS.js";import{a as P,E as k}from"./index-BcfO0-fK.js";import{E as C}from"./index-C_sVHlWz.js";import{E as I}from"./index-CXD7B41Z.js";import{E as S,a as A}from"./index-D2gD5Tn5.js";import{E as N}from"./index-js0HKKV6.js";import{E as U}from"./index-BaD29Izp.js";import{_ as J}from"./_plugin-vue_export-helper-BCo6x5W8.js";import"./castArray-nM8ho4U3.js";import"./_baseClone-Ct7RL6h5.js";import"./_initCloneObject-DRmC-q3t.js";import"./index-BMeOzN3u.js";import"./index-COyGylbk.js";import"./index-Bq8lawOo.js";import"./index-Cp4NEpJ7.js";import"./index-ZsMdSUVI.js";import"./token-DWNpOE8r.js";import"./debounce-DQl5eUwG.js";import"./_baseIteratee-CtIat01j.js";import"./index-CXORCV4U.js";const T=J(r({__name:"activity-search",props:{modelValue:{}},emits:["update:modelValue","search","reset"],setup(e,{emit:a}){const l=e,t=a,o=i([]),r=i(s({},l.modelValue));u(()=>l.modelValue,(e,a)=>{JSON.stringify(e)!==JSON.stringify(a)&&(r.value=s({},e))},{deep:!0});let J=null;u(r,e=>{J&&clearTimeout(J),J=setTimeout(()=>{t("update:modelValue",s({},e))},100)},{deep:!0});const T=e=>{return a=this,l=null,t=function*(){if(e&&0===o.value.length)try{const e=yield E();o.value=e.list||[]}catch(a){}},new Promise((e,o)=>{var s=e=>{try{i(t.next(e))}catch(a){o(a)}},r=e=>{try{i(t.throw(e))}catch(a){o(a)}},i=a=>a.done?e(a.value):Promise.resolve(a.value).then(s,r);i((t=t.apply(a,l)).next())});var a,l,t},H=()=>{t("search",r.value)},K=()=>{r.value={name:void 0,category_id:void 0,status:void 0,is_boss:void 0},t("reset")};return(a,l)=>{const t=d("ripple");return m(),p(f(U),{class:"search-card",shadow:"never"},{default:n(()=>[c(f(P),{ref:"formRef",model:e.modelValue,"label-width":"80px"},{default:n(()=>[c(f(C),{gutter:20},{default:n(()=>[c(f(I),{span:6},{default:n(()=>[c(f(k),{label:"活动名称",prop:"name"},{default:n(()=>[c(f(b),{modelValue:r.value.name,"onUpdate:modelValue":l[0]||(l[0]=e=>r.value.name=e),placeholder:"请输入活动名称",clearable:"",onKeyup:v(H,["enter"])},null,8,["modelValue"])]),_:1})]),_:1}),c(f(I),{span:6},{default:n(()=>[c(f(k),{label:"分类",prop:"category_id"},{default:n(()=>[c(f(S),{modelValue:r.value.category_id,"onUpdate:modelValue":l[1]||(l[1]=e=>r.value.category_id=e),placeholder:"请选择分类",clearable:"",onVisibleChange:T},{default:n(()=>[(m(!0),_(j,null,y(o.value,e=>(m(),p(f(A),{key:e.id,label:e.name,value:e.id},null,8,["label","value"]))),128))]),_:1},8,["modelValue"])]),_:1})]),_:1}),c(f(I),{span:6},{default:n(()=>[c(f(k),{label:"状态",prop:"status"},{default:n(()=>[c(f(S),{modelValue:r.value.status,"onUpdate:modelValue":l[2]||(l[2]=e=>r.value.status=e),placeholder:"请选择状态",clearable:""},{default:n(()=>[(m(!0),_(j,null,y(f(O),(e,a)=>(m(),p(f(A),{key:a,value:Number(a),label:e},null,8,["value","label"]))),128))]),_:1},8,["modelValue"])]),_:1})]),_:1}),c(f(I),{span:6},{default:n(()=>[c(f(k),{label:"Boss活动",prop:"is_boss"},{default:n(()=>[c(f(S),{modelValue:r.value.is_boss,"onUpdate:modelValue":l[3]||(l[3]=e=>r.value.is_boss=e),placeholder:"请选择",clearable:""},{default:n(()=>[c(f(A),{value:1,label:"是"}),c(f(A),{value:0,label:"否"})]),_:1},8,["modelValue"])]),_:1})]),_:1}),c(f(I),{span:4},{default:n(()=>[c(f(k),{"label-width":"0"},{default:n(()=>[c(f(N),null,{default:n(()=>[h((m(),p(f(V),{type:"primary",onClick:H},{default:n(()=>[c(f(g),{class:"mr-1"},{default:n(()=>[c(f(w))]),_:1}),l[4]||(l[4]=x(" 搜索 ",-1))]),_:1})),[[t]]),h((m(),p(f(V),{onClick:K},{default:n(()=>[...l[5]||(l[5]=[x("重置",-1)])]),_:1})),[[t]])]),_:1})]),_:1})]),_:1})]),_:1})]),_:1},8,["model"])]),_:1})}}}),[["__scopeId","data-v-29878c58"]]);export{T as default};

View File

@ -0,0 +1 @@
.search-card[data-v-29878c58]{margin-bottom:16px}[data-v-29878c58] .el-card__body{padding-bottom:0}

View File

@ -0,0 +1 @@
const n={instant:"即时开奖",scheduled:"定时开奖"},t={ichiban:"一番赏",default:"无限赏",matching:"对对碰"},a={1:"S赏",2:"A赏",3:"B赏",4:"C赏",5:"D赏",6:"E赏",7:"F赏",8:"G赏",9:"H赏",11:"Last赏"},s={physical:"实物奖品",virtual:"虚拟奖品",coupon:"优惠券",points:"积分"},c={1:"进行中",2:"已下线",3:"未开始",active:"进行中",ended:"已结束",upcoming:"未开始"};function i(t){return n[t]||t}function u(n){return a[n]||`等级${n}`}function e(n){return s[n]||n}function o(n){return c[n]||`状态${n}`}export{c as A,n as D,t as P,i as a,e as b,u as c,a as d,o as g};

View File

@ -0,0 +1 @@
import{_ as i}from"./add-coupon-dialog.vue_vue_type_script_setup_true_lang-G6pFWYH-.js";import"./index-BoIUJTA2.js";/* empty css *//* empty css *//* empty css *//* empty css *//* empty css *//* empty css */import"./coupons-tpfgWUoF.js";import"./index-BcfO0-fK.js";import"./castArray-nM8ho4U3.js";import"./_baseClone-Ct7RL6h5.js";import"./_initCloneObject-DRmC-q3t.js";import"./index-D2gD5Tn5.js";import"./index-BMeOzN3u.js";import"./index-COyGylbk.js";import"./index-Bq8lawOo.js";import"./index-Cp4NEpJ7.js";import"./index-ZsMdSUVI.js";import"./token-DWNpOE8r.js";import"./debounce-DQl5eUwG.js";import"./_baseIteratee-CtIat01j.js";import"./index-CXORCV4U.js";import"./index-CjpBlozU.js";import"./use-dialog-FwJ-QdmW.js";import"./refs-Cw5r5QN8.js";export{i as default};

View File

@ -0,0 +1 @@
var e=(e,a,l)=>new Promise((o,t)=>{var i=e=>{try{r(l.next(e))}catch(a){t(a)}},s=e=>{try{r(l.throw(e))}catch(a){t(a)}},r=e=>e.done?o(e.value):Promise.resolve(e.value).then(i,s);r((l=l.apply(e,a)).next())});import{d as a,r as l,k as o,A as t,o as i,h as s,e as r,w as d,g as u,p as n,b as p,I as m,J as c,E as v,O as f,j as y}from"./index-BoIUJTA2.js";/* empty css *//* empty css *//* empty css *//* empty css *//* empty css *//* empty css */import{c as b}from"./coupons-tpfgWUoF.js";import{a as h,E as g}from"./index-BcfO0-fK.js";import{E as j,a as _}from"./index-D2gD5Tn5.js";import{E as I}from"./index-CjpBlozU.js";const x=a({__name:"add-coupon-dialog",props:{visible:{type:Boolean}},emits:["update:visible","submit"],setup(a,{emit:x}){const k=a,w=x,V=l(),E=l(!1),A=l([]),C=o({couponId:null});t(()=>k.visible,e=>{});const P={couponId:[{required:!0,message:"请选择优惠券",trigger:"change"}]},U=()=>e(this,null,function*(){var e;try{yield null==(e=V.value)?void 0:e.validate(),E.value=!0,w("submit",{coupon_id:C.couponId})}catch(a){}finally{E.value=!1}}),$=()=>{w("update:visible",!1)},q=()=>{var e;C.couponId=null,null==(e=V.value)||e.clearValidate()};return i(()=>e(this,null,function*(){try{const e=yield b.getList({status:1,page:1,page_size:100});A.value=Array.isArray(e.list)?e.list.map(e=>({id:e.id,name:e.name})):[]}catch(e){A.value=[]}})),(e,l)=>(r(),s(n(I),{"model-value":a.visible,title:"发放优惠券",width:"400px","close-on-click-modal":!1,"onUpdate:modelValue":l[1]||(l[1]=e=>w("update:visible",e)),onClosed:q},{footer:d(()=>[u(n(v),{onClick:f($,["prevent"])},{default:d(()=>[...l[2]||(l[2]=[y("取消",-1)])]),_:1}),u(n(v),{type:"primary",loading:E.value,onClick:f(U,["prevent"])},{default:d(()=>[...l[3]||(l[3]=[y(" 确定 ",-1)])]),_:1},8,["loading"])]),default:d(()=>[u(n(h),{ref_key:"formRef",ref:V,model:C,rules:P,"label-width":"80px"},{default:d(()=>[u(n(g),{label:"优惠券",prop:"couponId"},{default:d(()=>[u(n(j),{modelValue:C.couponId,"onUpdate:modelValue":l[0]||(l[0]=e=>C.couponId=e),placeholder:"请选择优惠券",filterable:"",style:{width:"100%"}},{default:d(()=>[(r(!0),p(m,null,c(A.value,e=>(r(),s(n(_),{key:e.id,label:`${e.name}ID: ${e.id}`,value:e.id},null,8,["label","value"]))),128))]),_:1},8,["modelValue"])]),_:1})]),_:1},8,["model"])]),_:1},8,["model-value"]))}});export{x as _};

View File

@ -0,0 +1 @@
import{_ as i}from"./add-game-ticket-dialog.vue_vue_type_script_setup_true_lang-DNRKIxIT.js";import"./index-BoIUJTA2.js";/* empty css *//* empty css *//* empty css *//* empty css *//* empty css *//* empty css *//* empty css */import"./index-BcfO0-fK.js";import"./castArray-nM8ho4U3.js";import"./_baseClone-Ct7RL6h5.js";import"./_initCloneObject-DRmC-q3t.js";import"./index-D2gD5Tn5.js";import"./index-BMeOzN3u.js";import"./index-COyGylbk.js";import"./index-Bq8lawOo.js";import"./index-Cp4NEpJ7.js";import"./index-ZsMdSUVI.js";import"./token-DWNpOE8r.js";import"./debounce-DQl5eUwG.js";import"./_baseIteratee-CtIat01j.js";import"./index-CXORCV4U.js";import"./index-C_S0YbqD.js";import"./index-BnK4BbY2.js";import"./index-CjpBlozU.js";import"./use-dialog-FwJ-QdmW.js";import"./refs-Cw5r5QN8.js";export{i as default};

View File

@ -0,0 +1 @@
import{d as e,r as a,k as l,A as o,h as r,e as t,w as m,g as i,p as s,K as d,E as u,O as n,j as p}from"./index-BoIUJTA2.js";/* empty css *//* empty css *//* empty css *//* empty css *//* empty css *//* empty css *//* empty css */import{a as c,E as v}from"./index-BcfO0-fK.js";import{E as g,a as f}from"./index-D2gD5Tn5.js";import{E as _}from"./index-C_S0YbqD.js";import{E as b}from"./index-CjpBlozU.js";const h=e({__name:"add-game-ticket-dialog",props:{visible:{type:Boolean}},emits:["update:visible","submit"],setup(e,{emit:h}){const k=e,j=h,y=a(),w=a(!1),x=l({game_code:"minesweeper",amount:1,remark:""});o(()=>k.visible,e=>{e&&(x.game_code="minesweeper",x.amount=1,x.remark="")});const V={game_code:[{required:!0,message:"请选择游戏类型",trigger:"change"}],amount:[{required:!0,message:"请输入资格数量",trigger:"blur"}]},E=()=>{return e=this,a=null,l=function*(){var e;try{yield null==(e=y.value)?void 0:e.validate(),w.value=!0,j("submit",{game_code:x.game_code,amount:x.amount,remark:x.remark})}catch(a){}finally{w.value=!1}},new Promise((o,r)=>{var t=e=>{try{i(l.next(e))}catch(a){r(a)}},m=e=>{try{i(l.throw(e))}catch(a){r(a)}},i=e=>e.done?o(e.value):Promise.resolve(e.value).then(t,m);i((l=l.apply(e,a)).next())});var e,a,l},U=()=>{j("update:visible",!1)},C=()=>{var e;x.game_code="minesweeper",x.amount=1,x.remark="",null==(e=y.value)||e.clearValidate()};return(a,l)=>(t(),r(s(b),{"model-value":e.visible,title:"发放游戏资格",width:"400px","close-on-click-modal":!1,"onUpdate:modelValue":l[3]||(l[3]=e=>j("update:visible",e)),onClosed:C},{footer:m(()=>[i(s(u),{onClick:n(U,["prevent"])},{default:m(()=>[...l[4]||(l[4]=[p("取消",-1)])]),_:1}),i(s(u),{type:"primary",loading:w.value,onClick:n(E,["prevent"])},{default:m(()=>[...l[5]||(l[5]=[p("确定",-1)])]),_:1},8,["loading"])]),default:m(()=>[i(s(c),{ref_key:"formRef",ref:y,model:x,rules:V,"label-width":"100px"},{default:m(()=>[i(s(v),{label:"游戏类型",prop:"game_code"},{default:m(()=>[i(s(g),{modelValue:x.game_code,"onUpdate:modelValue":l[0]||(l[0]=e=>x.game_code=e),placeholder:"请选择游戏",style:{width:"100%"}},{default:m(()=>[i(s(f),{label:"扫雷游戏",value:"minesweeper"})]),_:1},8,["modelValue"])]),_:1}),i(s(v),{label:"资格数量",prop:"amount"},{default:m(()=>[i(s(_),{modelValue:x.amount,"onUpdate:modelValue":l[1]||(l[1]=e=>x.amount=e),placeholder:"请输入数量",min:1,max:100,step:1,style:{width:"100%"}},null,8,["modelValue"])]),_:1}),i(s(v),{label:"备注",prop:"remark"},{default:m(()=>[i(s(d),{modelValue:x.remark,"onUpdate:modelValue":l[2]||(l[2]=e=>x.remark=e),type:"textarea",placeholder:"请输入备注",rows:2},null,8,["modelValue"])]),_:1})]),_:1},8,["model"])]),_:1},8,["model-value"]))}});export{h as _};

View File

@ -0,0 +1 @@
import{_ as i}from"./add-item-card-dialog.vue_vue_type_script_setup_true_lang-C9E8CieY.js";import"./index-BoIUJTA2.js";/* empty css *//* empty css *//* empty css *//* empty css *//* empty css *//* empty css *//* empty css */import"./itemCards-WBDl8YV9.js";import"./index-BcfO0-fK.js";import"./castArray-nM8ho4U3.js";import"./_baseClone-Ct7RL6h5.js";import"./_initCloneObject-DRmC-q3t.js";import"./index-D2gD5Tn5.js";import"./index-BMeOzN3u.js";import"./index-COyGylbk.js";import"./index-Bq8lawOo.js";import"./index-Cp4NEpJ7.js";import"./index-ZsMdSUVI.js";import"./token-DWNpOE8r.js";import"./debounce-DQl5eUwG.js";import"./_baseIteratee-CtIat01j.js";import"./index-CXORCV4U.js";import"./index-C_S0YbqD.js";import"./index-BnK4BbY2.js";import"./index-CjpBlozU.js";import"./use-dialog-FwJ-QdmW.js";import"./refs-Cw5r5QN8.js";export{i as default};

View File

@ -0,0 +1 @@
var e=(e,a,l)=>new Promise((t,i)=>{var r=e=>{try{s(l.next(e))}catch(a){i(a)}},d=e=>{try{s(l.throw(e))}catch(a){i(a)}},s=e=>e.done?t(e.value):Promise.resolve(e.value).then(r,d);s((l=l.apply(e,a)).next())});import{d as a,r as l,k as t,A as i,o as r,h as d,e as s,w as o,g as u,p as n,b as m,I as p,J as c,E as v,O as y,j as f}from"./index-BoIUJTA2.js";/* empty css *//* empty css *//* empty css *//* empty css *//* empty css *//* empty css *//* empty css */import{i as b}from"./itemCards-WBDl8YV9.js";import{a as g,E as h}from"./index-BcfO0-fK.js";import{E as j,a as _}from"./index-D2gD5Tn5.js";import{E as x}from"./index-C_S0YbqD.js";import{E as q}from"./index-CjpBlozU.js";const I=a({__name:"add-item-card-dialog",props:{visible:{type:Boolean}},emits:["update:visible","submit"],setup(a,{emit:I}){const V=a,k=I,w=l(),E=l(!1),C=l([]),A=t({cardId:null,quantity:1});i(()=>V.visible,e=>{});const U={cardId:[{required:!0,message:"请选择道具卡",trigger:"change"}],quantity:[{required:!0,message:"请输入数量",trigger:"change"}]},P=()=>e(this,null,function*(){var e;try{yield null==(e=w.value)?void 0:e.validate(),E.value=!0,k("submit",{card_id:A.cardId,quantity:A.quantity})}catch(a){}finally{E.value=!1}}),$=()=>{k("update:visible",!1)},z=()=>{var e;A.cardId=null,A.quantity=1,null==(e=w.value)||e.clearValidate()};return r(()=>e(this,null,function*(){try{const e=yield b.getList({page:1,page_size:100});C.value=Array.isArray(e.list)?e.list.map(e=>({id:e.id,name:e.name})):[]}catch(e){C.value=[]}})),(e,l)=>(s(),d(n(q),{"model-value":a.visible,title:"分配道具卡",width:"420px","close-on-click-modal":!1,"onUpdate:modelValue":l[2]||(l[2]=e=>k("update:visible",e)),onClosed:z},{footer:o(()=>[u(n(v),{onClick:y($,["prevent"])},{default:o(()=>[...l[3]||(l[3]=[f("取消",-1)])]),_:1}),u(n(v),{type:"primary",loading:E.value,onClick:y(P,["prevent"])},{default:o(()=>[...l[4]||(l[4]=[f("确定",-1)])]),_:1},8,["loading"])]),default:o(()=>[u(n(g),{ref_key:"formRef",ref:w,model:A,rules:U,"label-width":"80px"},{default:o(()=>[u(n(h),{label:"道具卡",prop:"cardId"},{default:o(()=>[u(n(j),{modelValue:A.cardId,"onUpdate:modelValue":l[0]||(l[0]=e=>A.cardId=e),placeholder:"请选择道具卡",filterable:"",style:{width:"100%"}},{default:o(()=>[(s(!0),m(p,null,c(C.value,e=>(s(),d(n(_),{key:e.id,label:`${e.name}ID: ${e.id}`,value:e.id},null,8,["label","value"]))),128))]),_:1},8,["modelValue"])]),_:1}),u(n(h),{label:"数量",prop:"quantity"},{default:o(()=>[u(n(x),{modelValue:A.quantity,"onUpdate:modelValue":l[1]||(l[1]=e=>A.quantity=e),min:1,max:100},null,8,["modelValue"])]),_:1})]),_:1},8,["model"])]),_:1},8,["model-value"]))}});export{I as _};

View File

@ -0,0 +1 @@
import{_ as i}from"./add-points-dialog.vue_vue_type_script_setup_true_lang-C3778r95.js";import"./index-BoIUJTA2.js";/* empty css *//* empty css *//* empty css *//* empty css *//* empty css *//* empty css *//* empty css *//* empty css *//* empty css */import"./index-BcfO0-fK.js";import"./castArray-nM8ho4U3.js";import"./_baseClone-Ct7RL6h5.js";import"./_initCloneObject-DRmC-q3t.js";import"./index-DqTthkO7.js";import"./index-C_S0YbqD.js";import"./index-BnK4BbY2.js";import"./index-D2gD5Tn5.js";import"./index-BMeOzN3u.js";import"./index-COyGylbk.js";import"./index-Bq8lawOo.js";import"./index-Cp4NEpJ7.js";import"./index-ZsMdSUVI.js";import"./token-DWNpOE8r.js";import"./debounce-DQl5eUwG.js";import"./_baseIteratee-CtIat01j.js";import"./index-CXORCV4U.js";import"./index-CjpBlozU.js";import"./use-dialog-FwJ-QdmW.js";import"./refs-Cw5r5QN8.js";export{i as default};

View File

@ -0,0 +1 @@
import{d as e,r as a,k as l,A as d,h as t,e as o,w as i,g as r,p as s,j as n,f as u,b as m,i as p,I as v,K as c,E as b,O as f,v as _}from"./index-BoIUJTA2.js";/* empty css *//* empty css *//* empty css *//* empty css *//* empty css *//* empty css *//* empty css *//* empty css *//* empty css */import{a as k,E as y}from"./index-BcfO0-fK.js";import{a as g,E as h}from"./index-DqTthkO7.js";import{E as j}from"./index-C_S0YbqD.js";import{E as x,a as V}from"./index-D2gD5Tn5.js";import{E as w}from"./index-CjpBlozU.js";const E={class:"text-xs text-gray-400 mt-1"},U={key:0,class:"text-orange-500"},C=e({__name:"add-points-dialog",props:{visible:{type:Boolean}},emits:["update:visible","submit"],setup(e,{emit:C}){const M=e,q=C,I=a(),K=a(!1),P=a("add"),T=l({points:null,kind:"admin_add",remark:""}),A=e=>{const a=e;T.kind="add"===a?"admin_add":"admin_deduct"};d(()=>M.visible,e=>{});const B={points:[{required:!0,message:"请输入积分数量",trigger:"blur"}],kind:[{required:!0,message:"请选择积分类型",trigger:"change"}]},J=()=>{return e=this,a=null,l=function*(){var e;try{yield null==(e=I.value)?void 0:e.validate(),K.value=!0;const a="deduct"===P.value?-Math.abs(T.points||0):Math.abs(T.points||0);q("submit",{points:a,kind:T.kind,remark:T.remark})}catch(a){}finally{K.value=!1}},new Promise((d,t)=>{var o=e=>{try{r(l.next(e))}catch(a){t(a)}},i=e=>{try{r(l.throw(e))}catch(a){t(a)}},r=e=>e.done?d(e.value):Promise.resolve(e.value).then(o,i);r((l=l.apply(e,a)).next())});var e,a,l},N=()=>{q("update:visible",!1)},O=()=>{var e;T.points=null,T.kind="admin_add",T.remark="",P.value="add",null==(e=I.value)||e.clearValidate()};return(a,l)=>(o(),t(s(w),{"model-value":e.visible,title:"积分调整",width:"420px","close-on-click-modal":!1,"onUpdate:modelValue":l[4]||(l[4]=e=>q("update:visible",e)),onClosed:O},{footer:i(()=>[r(s(b),{onClick:f(N,["prevent"])},{default:i(()=>[...l[8]||(l[8]=[n("取消",-1)])]),_:1}),r(s(b),{type:"add"===P.value?"primary":"warning",loading:K.value,onClick:f(J,["prevent"])},{default:i(()=>[n(_("add"===P.value?"确认增加":"确认扣减"),1)]),_:1},8,["type","loading"])]),default:i(()=>[r(s(k),{ref_key:"formRef",ref:I,model:T,rules:B,"label-width":"100px"},{default:i(()=>[r(s(y),{label:"操作类型",prop:"actionType"},{default:i(()=>[r(s(g),{modelValue:P.value,"onUpdate:modelValue":l[0]||(l[0]=e=>P.value=e),onChange:A},{default:i(()=>[r(s(h),{label:"add"},{default:i(()=>[...l[5]||(l[5]=[n("增加积分",-1)])]),_:1}),r(s(h),{label:"deduct"},{default:i(()=>[...l[6]||(l[6]=[n("扣减积分",-1)])]),_:1})]),_:1},8,["modelValue"])]),_:1}),r(s(y),{label:"add"===P.value?"增加积分":"扣减积分",prop:"points"},{default:i(()=>[r(s(j),{modelValue:T.points,"onUpdate:modelValue":l[1]||(l[1]=e=>T.points=e),placeholder:"请输入金额",min:.01,precision:2,step:1,style:{width:"100%"}},null,8,["modelValue"]),u("div",E,[l[7]||(l[7]=n(" 1 积分 = 1 元。支持两位小数。 ",-1)),"deduct"===P.value?(o(),m("span",U,"(扣减不能超过用户当前余额)")):p("",!0)])]),_:1},8,["label"]),r(s(y),{label:"积分类型",prop:"kind"},{default:i(()=>[r(s(x),{modelValue:T.kind,"onUpdate:modelValue":l[2]||(l[2]=e=>T.kind=e),placeholder:"请选择积分类型",style:{width:"100%"}},{default:i(()=>["add"===P.value?(o(),m(v,{key:0},[r(s(V),{label:"管理员增加",value:"admin_add"}),r(s(V),{label:"活动奖励",value:"activity_reward"}),r(s(V),{label:"签到奖励",value:"sign_reward"}),r(s(V),{label:"消费返还",value:"consume_return"})],64)):(o(),m(v,{key:1},[r(s(V),{label:"管理员扣减",value:"admin_deduct"}),r(s(V),{label:"违规处罚",value:"violation_penalty"}),r(s(V),{label:"系统调整",value:"system_adjust"})],64))]),_:1},8,["modelValue"])]),_:1}),r(s(y),{label:"备注",prop:"remark"},{default:i(()=>[r(s(c),{modelValue:T.remark,"onUpdate:modelValue":l[3]||(l[3]=e=>T.remark=e),type:"textarea",placeholder:"请输入备注",rows:3},null,8,["modelValue"])]),_:1})]),_:1},8,["model"])]),_:1},8,["model-value"]))}});export{C as _};

View File

@ -0,0 +1 @@
import{c1 as i}from"./index-BoIUJTA2.js";function t(t){return i.post({url:"admin/activities",params:t})}function a(t){return i.get({url:"admin/activities",params:t})}function r(t,a){return i.put({url:`admin/activities/${t}`,params:a})}function s(t){return i.del({url:`admin/activities/${t}`})}function n(t){return i.get({url:`admin/activities/${t}`})}function e(t,a=1,r=20){return i.get({url:`admin/activities/${t}/issues`,params:{page:a,page_size:r}})}function u(t,a){return i.post({url:`admin/activities/${t}/issues`,params:a})}function c(t,a,r){return i.put({url:`admin/activities/${t}/issues/${a}`,params:r})}function m(t,a){return i.del({url:`admin/activities/${t}/issues/${a}`})}function d(t,a){return i.get({url:`admin/activities/${t}/issues/${a}/rewards`})}function o(t,a,r){return i.post({url:`admin/activities/${t}/issues/${a}/rewards`,params:{rewards:r}})}function $(t,a,r,s){return i.put({url:`admin/activities/${t}/issues/${a}/rewards/${r}`,params:s})}function l(t,a,r){return i.put({url:`admin/activities/${t}/issues/${a}/rewards/batch`,params:{rewards:r}})}function p(t,a,r){return i.del({url:`admin/activities/${t}/issues/${a}/rewards/${r}`})}function f(){return i.get({url:"admin/activity_categories"})}function v(t){return i.post({url:`admin/activities/${t}/copy`})}function g(t){return i.post({url:`admin/activities/${t}/commitment/generate`})}function w(t){return i.get({url:`admin/activities/${t}/commitment/summary`})}function h(t){return i.get({url:`admin/activities/${t}/credential`})}function y(t,a){return i.get({url:`admin/activities/${t}/rankings`,params:a})}function b(t){return i.get({url:`admin/matching/audit/${t}`})}export{n as a,w as b,u as c,m as d,f as e,r as f,b as g,t as h,s as i,v as j,g as k,e as l,h as m,o as n,y as o,$ as p,d as q,p as r,l as s,a as t,c as u};

View File

@ -0,0 +1 @@
import{_ as i}from"./assign-title-dialog.vue_vue_type_script_setup_true_lang-BqTGbynB.js";import"./index-BoIUJTA2.js";/* empty css *//* empty css *//* empty css *//* empty css *//* empty css *//* empty css *//* empty css */import"./titles-D1iSw7M5.js";import"./index-BcfO0-fK.js";import"./castArray-nM8ho4U3.js";import"./_baseClone-Ct7RL6h5.js";import"./_initCloneObject-DRmC-q3t.js";import"./index-D2gD5Tn5.js";import"./index-BMeOzN3u.js";import"./index-COyGylbk.js";import"./index-Bq8lawOo.js";import"./index-Cp4NEpJ7.js";import"./index-ZsMdSUVI.js";import"./token-DWNpOE8r.js";import"./debounce-DQl5eUwG.js";import"./_baseIteratee-CtIat01j.js";import"./index-CXORCV4U.js";import"./index-BneqRonp.js";import"./index-BnK4BbY2.js";import"./index-CjpBlozU.js";import"./use-dialog-FwJ-QdmW.js";import"./refs-Cw5r5QN8.js";export{i as default};

View File

@ -0,0 +1 @@
var e=(e,l,a)=>new Promise((t,i)=>{var r=e=>{try{o(a.next(e))}catch(l){i(l)}},s=e=>{try{o(a.throw(e))}catch(l){i(l)}},o=e=>e.done?t(e.value):Promise.resolve(e.value).then(r,s);o((a=a.apply(e,l)).next())});import{d as l,r as a,k as t,o as i,h as r,e as s,w as o,g as d,p as m,b as p,I as u,J as n,K as v,E as c,O as f,j as x}from"./index-BoIUJTA2.js";/* empty css *//* empty css *//* empty css *//* empty css *//* empty css *//* empty css *//* empty css */import{titlesApi as h}from"./titles-D1iSw7M5.js";import{a as y,E as b}from"./index-BcfO0-fK.js";import{E as g,a as k}from"./index-D2gD5Tn5.js";import{E as _}from"./index-BneqRonp.js";import{E as j}from"./index-CjpBlozU.js";const V=l({__name:"assign-title-dialog",props:{visible:{type:Boolean}},emits:["update:visible","submit"],setup(l,{emit:V}){const I=V,A=a(),w=a(!1),E=a([]),Y=t({titleId:null,expiresAt:"",remark:""}),U={titleId:[{required:!0,message:"请选择称号",trigger:"change"}]},C=()=>e(this,null,function*(){var e;try{yield null==(e=A.value)?void 0:e.validate(),w.value=!0;const l={title_id:Y.titleId};Y.expiresAt&&(l.expires_at=Y.expiresAt),Y.remark&&(l.remark=Y.remark),I("submit",l)}catch(l){}finally{w.value=!1}}),D=()=>{I("update:visible",!1)},H=()=>{var e;Y.titleId=null,Y.expiresAt="",Y.remark="",null==(e=A.value)||e.clearValidate()};return i(()=>e(this,null,function*(){try{const e=yield h.getList({page:1,page_size:100});E.value=Array.isArray(e.list)?e.list.map(e=>({id:e.id,name:e.name})):[]}catch(e){E.value=[]}})),(e,a)=>(s(),r(m(j),{"model-value":l.visible,title:"分配称号",width:"460px","close-on-click-modal":!1,"onUpdate:modelValue":a[3]||(a[3]=e=>I("update:visible",e)),onClosed:H},{footer:o(()=>[d(m(c),{onClick:f(D,["prevent"])},{default:o(()=>[...a[4]||(a[4]=[x("取消",-1)])]),_:1}),d(m(c),{type:"primary",loading:w.value,onClick:f(C,["prevent"])},{default:o(()=>[...a[5]||(a[5]=[x("确定",-1)])]),_:1},8,["loading"])]),default:o(()=>[d(m(y),{ref_key:"formRef",ref:A,model:Y,rules:U,"label-width":"90px"},{default:o(()=>[d(m(b),{label:"称号",prop:"titleId"},{default:o(()=>[d(m(g),{modelValue:Y.titleId,"onUpdate:modelValue":a[0]||(a[0]=e=>Y.titleId=e),placeholder:"请选择称号",filterable:"",style:{width:"100%"}},{default:o(()=>[(s(!0),p(u,null,n(E.value,e=>(s(),r(m(k),{key:e.id,label:`${e.name}ID: ${e.id}`,value:e.id},null,8,["label","value"]))),128))]),_:1},8,["modelValue"])]),_:1}),d(m(b),{label:"过期时间",prop:"expiresAt"},{default:o(()=>[d(m(_),{modelValue:Y.expiresAt,"onUpdate:modelValue":a[1]||(a[1]=e=>Y.expiresAt=e),type:"datetime","value-format":"YYYY-MM-DDTHH:mm:ssZ",placeholder:"可选,默认为永久",style:{width:"100%"}},null,8,["modelValue"])]),_:1}),d(m(b),{label:"备注",prop:"remark"},{default:o(()=>[d(m(v),{modelValue:Y.remark,"onUpdate:modelValue":a[2]||(a[2]=e=>Y.remark=e),placeholder:"可选备注",maxlength:"100"},null,8,["modelValue"])]),_:1})]),_:1},8,["model"])]),_:1},8,["model-value"]))}});export{V as _};

View File

@ -0,0 +1 @@
.el-timeline{--el-timeline-node-size-normal: 12px;--el-timeline-node-size-large: 14px;--el-timeline-node-color: var(--el-border-color-light)}.el-timeline{margin:0;font-size:var(--el-font-size-base);list-style:none}.el-timeline .el-timeline-item:last-child .el-timeline-item__tail{display:none}.el-timeline .el-timeline-item__center{display:flex;align-items:center}.el-timeline .el-timeline-item__center .el-timeline-item__wrapper{width:100%}.el-timeline .el-timeline-item__center .el-timeline-item__tail{top:0}.el-timeline .el-timeline-item__center:first-child .el-timeline-item__tail{height:calc(50% + 10px);top:calc(50% - 10px)}.el-timeline .el-timeline-item__center:last-child .el-timeline-item__tail{display:block;height:calc(50% - 10px)}.el-timeline-item{position:relative;padding-bottom:20px}.el-timeline-item__wrapper{position:relative;padding-left:28px;top:-3px}.el-timeline-item__tail{position:absolute;left:4px;height:100%;border-left:2px solid var(--el-timeline-node-color)}.el-timeline-item .el-timeline-item__icon{color:var(--el-color-white);font-size:var(--el-font-size-small)}.el-timeline-item__node{position:absolute;background-color:var(--el-timeline-node-color);border-color:var(--el-timeline-node-color);border-radius:50%;box-sizing:border-box;display:flex;justify-content:center;align-items:center}.el-timeline-item__node--normal{left:-1px;width:var(--el-timeline-node-size-normal);height:var(--el-timeline-node-size-normal)}.el-timeline-item__node--large{left:-2px;width:var(--el-timeline-node-size-large);height:var(--el-timeline-node-size-large)}.el-timeline-item__node.is-hollow{background:var(--el-color-white);border-style:solid;border-width:2px}.el-timeline-item__node--primary{background-color:var(--el-color-primary);border-color:var(--el-color-primary)}.el-timeline-item__node--success{background-color:var(--el-color-success);border-color:var(--el-color-success)}.el-timeline-item__node--warning{background-color:var(--el-color-warning);border-color:var(--el-color-warning)}.el-timeline-item__node--danger{background-color:var(--el-color-danger);border-color:var(--el-color-danger)}.el-timeline-item__node--info{background-color:var(--el-color-info);border-color:var(--el-color-info)}.el-timeline-item__dot{position:absolute;display:flex;justify-content:center;align-items:center}.el-timeline-item__content{color:var(--el-text-color-primary)}.el-timeline-item__timestamp{color:var(--el-text-color-secondary);line-height:1;font-size:var(--el-font-size-small)}.el-timeline-item__timestamp.is-top{margin-bottom:8px;padding-top:4px}.el-timeline-item__timestamp.is-bottom{margin-top:8px}.audit-log-drawer[data-v-de3e805f]{padding:10px}[data-v-de3e805f] .el-timeline-item__timestamp{font-size:14px;font-weight:700}

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
.el-avatar{--el-avatar-text-color: var(--el-color-white);--el-avatar-bg-color: var(--el-text-color-disabled);--el-avatar-text-size: 14px;--el-avatar-icon-size: 18px;--el-avatar-border-radius: var(--el-border-radius-base);--el-avatar-size-large: 56px;--el-avatar-size-small: 24px;--el-avatar-size: 40px;display:inline-flex;justify-content:center;align-items:center;box-sizing:border-box;text-align:center;overflow:hidden;outline:none;color:var(--el-avatar-text-color);background:var(--el-avatar-bg-color);width:var(--el-avatar-size);height:var(--el-avatar-size);font-size:var(--el-avatar-text-size)}.el-avatar>img{display:block;width:100%;height:100%}.el-avatar--circle{border-radius:50%}.el-avatar--square{border-radius:var(--el-avatar-border-radius)}.el-avatar--icon{font-size:var(--el-avatar-icon-size)}.el-avatar--small{--el-avatar-size: 24px}.el-avatar--large{--el-avatar-size: 56px}

View File

@ -0,0 +1 @@
const A="data:image/webp;base64,UklGRkoIAABXRUJQVlA4ID4IAADwLwCdASqgAKAAPyWCtlKuKSUnrhuaScAkiWMA0B+4f6f151+lwftt/hONGh/exC2WVatFHq//nzLfx3/34IDPWrgNJbUktqSaiIHUiLzd82/VPIGht6KwyKTAjwyvI9cQ9AfLBtxkKB42QLruqr9fQTdB9rZc/nhl5QAZ3G5K871sNQKwGnur5vjfpLeLGjmyTfLjwB3PV+pnrdhhAnFtHylhTu8SXlHquf8lUlWFGYw2tID45sQ/t99JPt583xnvfgKorj3xDOUcUfBZ9+0Lo/m8nyr2+x2ieOfnhjfli3Sok/ujjMm2pdWp0poEMPxOTyoPI0xphwaL00N70kIDJw+8B7XNFde/zPTFA2lvtnd2YX744Ka2rnTeFRVJutgL6yfzJAquSHw9kV1FfjPSi6YNK4ffWdjwozPao5GpRbulnWhWFrhbkLymgrI12w56eykXbNDJaWWyzz8C8d32YfEJSyAU4szWBSmY9UiYOlDUBZmCDQGUSmZUnhSuLDAzufVluctzgAD+8Hd6XJDNl4hrW6beD6BmAq+qoAcQJnm709ObeZDChKLtxt9yq8J6i5cyL0vLiQ9bKlUbkg5mKUhY2zrCXwZq1RBQtrnSYf+jeKo/KENeaaXg03o1tmOWwuppQFVj4iipRywoiJrjdtByWDP0lMVoSVjFpqgi4tdzZsPvb2B+IPOupdnOdh/t/6mZd4DuiFXRuo/FHmOvpG5UStJkCmOVdTabRiy0YsYf0klGhcOspkYvixoXEG1RGI/m9+Wo9exmSR7MIjicNAxGbH/5mxs0EKce1GIk0VMXFuS/Mh/nH2MNc/hnAYaLcqD3k5H0nZYshDJ/vtzZeAtPbxdDZA7R4/YZxpjNDjFxPxuA5pizB53QFzGy1HZkt2fZBtiw3X8hgDFm+ZPQJnsSfXUSNtXLAqH873sJZEKOwfpRCpFdSjNGzia9yH6JJKAZKxT9yNsbOF+k+5lEj7w+0Ka2vIar4HMrIC5YV+mzusOpxk+akcq83Jw5K/9bAlhL5QhFCOUgfzyo1FqWPIzH/t+5dOFI0EItlltKhyH0WuohnXv0BZ640iqcp+0v72Ikprq1zwvnjW24P5Q/U+ROmTOGwm1SVfKfjYnv4xjAa11TaNI9COI7HqRERepkvMiolKspS3D4bQ1umTmeEzGSN1st44yzSyPzAX3jMXO8FDV9ESGVdGnGVVMHywZHDqdyhPJDtrQlaHcUBfBEyeUdTbX9KR+N2cyh/+5Pnpv05pPcKL2LTcbaP39yAUDrgLrblesJPtaGAGxbxGxAdmCwORKF/ezQONQOxH2mh2S7FUlV0o3KrJYikOSxgDBKmMGOYOkzvIb6s4WdqGq4EbpXK6AYCTqSdwJpMVU5jzS+TENbWClTurCFXqeHPeoUqSZhKbvb/UL/Z2EtPpUihzRGQ5WT93r+zU72fwK6PZEDQa+hDyOyjdJXWU00wY2Eqg6qSA9tp+KW/hCkuoZ0DkZJEuo+2gFua7JbL9QS2cVw9H+CwzukzpXZ675aLtu0llJUPQw/dE2/EPKEOr82Ll3xZxjoj/oxJx5SkVgkgYKc1ZA9vDVdyozo3iHKpOCesVkvlxM5oqbfK9a4l05T8HFDMrLuM/9ICWJk8jE4XYZq6y9RN8vnLj6SDq1I6O6+Cn9WpNxZhS1+4lMs+PVlON6Nt7rVvIsj6guhbatOVP+jXahNVe+ZlynjNo1SucIqQ2ssRmn79xgxE+vjeGwEiEfheVYUE7SDSUk8YjmJnTbTg09NXXeweef0QnkZ7uus2fPsZhksXZnums2szrwnMogSMq9oX/mgMOupMqUEVO6bpcsbf1HZSRANh11/MnU9sxyFwYqBP+C1NDGwsOURvTplOYGRarOBA4QA3l/RGa67F76ppOMPABcGFXioFr6HcWygnB5T1yAHdN+qeMhdd/BG/QMow0X0+ejPg7FLJ5YraB0g4cgIvoMhlZlUhIM640prUPLGZZUqYIFzjKaVwq/3QmzThSbptQLm47JOfwbelJ0sxGGW8TE6ezZXK/6dDXQQ5eyaqDd5FgQI2oiX4pYPHVrWUOteQE3Iu0P4Fg0Z0Aj+2KtsdeZ23QpEVvk3GakbcfgdLJ/9NBXrzA1efjLk6LqzZ29RnH6qk7O6n5WYE+IEN+EiDeGCvWkx7s0WT4frjXAg9N4hHYnzzlHOyx7YTy1ZHpEmgMuv/Dhs7t/7uWl9MGOD0J9ZHpdAmHbyCUNfDMCV2/OiLPwTRxXyjuLrw5lhVp9TpndEjew8ZwZXEElxCKW7Ke3rGgVxXFsYidZz17+4VaL8pFcLDL50EAr3kYtzN397jBBAgCBdQyyKwPXLSj7UQZtrldsjEbFVu+QO3iuoiCRr2KPx3wkq89oYOC4l9aAWl2uqyqzcmlroPTlB2wK2yEl/Y1uTYFCx9SoEnbxk+5dK//Q03foD1ukTuTP47PxxPcaMYbmd6mmroit+Uy6NQfHF2Q8ovhwNO3wxOITht/Yzxxbyjt5DE/FhO7kZ2pzCbj11oYHFczFdGz0CA0wR2qIkkir1mnnr2zfdCo5pg2SiOmUt7CS9/8NetjvMS54u/0TzrYXBotAz4jr7n5a+14HQ1cMduWpP/KFJp2QI4eZ+EFC+P2mobdYF3YTpOw7JlNEO14jc620BkTR4aAdLUGVWdbCm2LoSgUfll26tfBCBuuIDkf1Z9ulw/IGbESub0WAb1B3jBFazYmBDyBhAQsqLINtohnP52fmN9mxjKC37ej9Knu/bhay/9bi7mDK/4PlhgAoAwpo/rgSzjFN/uAaMgAAA";export{A as _};

View File

@ -0,0 +1 @@
const a="data:image/webp;base64,UklGRnoFAABXRUJQVlA4IG4FAABQJACdASqgAKAAPrVUpU0nJKOipxaKQOAWiWcqvPAxUAkbDCvZbPuzj7mZq0NYSjrl2MI3fMiYX+UKAIEv06jA/5TBuv2S0lfAQp+IjE4WYF3IqwJy/5QHd74StrgS78UojyD39cswHSCWalGc52fhAmf2c8eEs8l2zCM+3fqmcXsrOOPaXK0q7GA1g4uYFCFFTiT7Qx3r7mzR/oqvlsNR2a8OQeMam0TJRzCWgtMVdKM8LGDIPxfjKv/h3bh8dOm3vwvQbo1lMBEX6Q37xvklj7NmGI35SpsCup0qtkTIRHQ4JG72EX+tK//+E/les0KA2cXqUC3rvBnw6RiwfMGMOJ8EpekgaXye3rFGf/AcovtyKMK7UjpZ32YQU37EtIWv819EbcPLFNMuUAD+89fBlMUTIKSoIcwc3lAm5wqLrczmaAfybnj1VmGqdd4iWEESGVUm1H+fSvBk/4a4YmVx3hIupBb8tAtG4y+2AzyOI0/BNeeoemQqqYPtsxm1NpANjiQdDInS2ZQp7V00hRudyqE0360aIE0vZM5eqwSeYvsLaC8rvWaIWB9XVpE21FkW/2eqpgCy7i96eF1aJi+LXXk+5asdyFXIuIIuqmOeYQwEJuWYP/PfbvYlH1aTytQx18SJ/8ARRFqKQN8z9ciZ/9fmo4fP6SNLpYctoi+uIsNVD7EFXy1wgN5JhL6FBl+C7UhcfbXfDlJnEfm+E/tGRGz/EjKjpavd6LY/BLa0AAmhSAjYLwv+FjmzYxqoXRqbxQsVYEWs0CJzb67qJEGCtVaDTYHZQPRTjUR0C4kHfFD9Uzb1BxS7ZEtvrNRzp9J7+jaxbY+a2dFFFhYd4LdsmlcCWuYqz10Jz6FUoujzWGr0ZflDi8MDJwLvbbT3L2oX+j1LEb46BhRj8SNYDLf0pRLeC/IkrhTuJgtBE5PQ95LWpngo7MN1sqBKI3ZlPUaJ0gwAWpYItxuKwuRaaxCfuZxooKsuPjTTPTIZC2KdeHq0gWeNaQPJsBa6V1v3wt02N+CW4lM9cWrJIIU8sNnR2UZCLKHkrsW9kOv0/ZhxGG5oBrl5QzTNbe6lV+KbePeM7VPmUuIWiv5iJqzbidtC8IKBwPLFihicVr68KNYwQFqA9go0hsZeFj12t0MG88PBZL4UpX8QsID/heHNT8mQ+tHdHdxtRY75Tkx4ovnd4ryHJ4McFrhm7CsNccch2ukj9m7MjwnkFz8BiI/YHvz2vKyPzNmm/0ywGYr+bHAJ27mbijRLr5xjJWwkdvv4GzOzWggTgzediVNXZUKT0x3M0aAuwfpeqK7OP6TFETKRo32S309kH5WrEShvzOompbuRQhIP6kq+eNdqLMzdo6PpYHj5m6q00q222jkLxWxXgavd/8UtWUyGf1MFzIdLPJgl+lr8Kua/iS1PJ93fj7NNcLWzkVI937nLbii3MKUkX+D/rf3mNwF8ukfgDasUOZePF2FQEubwrcwwmfkVeXwDOXUR65mCF7U/ro58MwhSvkFjyb9cm4RglimRYCtv42mBqVdlps15TaD5ut5shhruAhHZOZwiZN05nIo8+POjqMjMP6SCNZdNr4nZ5xMVDW+v6KjxkeaX0Fc+qukcMsPVs+x4FLmd5q3olnMO5o8BoC8GsgF7RBtC3aWj8n2pBNd87wIqyHaAh1IV5Sl7CWPvByorqhCE2f8aImUQ5EB5Ol3VHpxcGUc7bwj66sceIm8L2GjHluOvqVA8D2atZCq9IlPZAJX9bDgotmeX8+2ONEBBXf7J35Rky10Jbv4bQrFgJWDgaRGpgIoVuSV1wE1oaJNdxJTGEG6Vlncm6TLPggJaz5aB4ljh2ZhWgAAA";export{a};

File diff suppressed because one or more lines are too long

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More