Files
dafuweng-saiadmin6.x/server/app/api/controller/UserController.php

216 lines
7.8 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
declare(strict_types=1);
namespace app\api\controller;
use support\Request;
use support\Response;
use app\api\cache\UserCache;
use app\api\logic\UserLogic;
use app\api\util\ReturnCode;
use app\dice\model\play_record\DicePlayRecord;
use app\dice\model\player_wallet_record\DicePlayerWalletRecord;
use plugin\saiadmin\basic\OpenController;
/**
* API 用户登录等
* 登录接口 /api/user/Login 无需 token其余接口需在请求头携带 tokenbase64(username.-.time)),由 TokenMiddleware 鉴权并注入 request->player_id / request->player
*/
class UserController extends OpenController
{
/**
* 登录JSON body
* POST /api/user/Login
* body: { "username": "+60123456789", "password": "123456", "lang": "chs", "coin": 2000.00, "time": 1772692089 }
* 根据 username 查找或创建 DicePlayer按 coin 增减平台币,会话写 Redis返回带 token 的连接地址
*/
public function Login(Request $request): Response
{
$body = $request->rawBody();
if ($body === '' || $body === null) {
return $this->fail('请提交 JSON body', ReturnCode::PARAMS_ERROR);
}
$data = json_decode($body, true);
if (!is_array($data)) {
return $this->fail('JSON 格式错误', ReturnCode::PARAMS_ERROR);
}
$username = trim((string) ($data['username'] ?? ''));
$password = trim((string) ($data['password'] ?? ''));
$lang = trim((string) ($data['lang'] ?? 'chs'));
$coin = isset($data['coin']) ? (float) $data['coin'] : 0.0;
$time = isset($data['time']) ? (string) $data['time'] : (string) time();
if ($username === '' || $password === '') {
return $this->fail('username、password 不能为空', ReturnCode::PARAMS_ERROR);
}
try {
$logic = new UserLogic();
$result = $logic->loginByUsername($username, $password, $lang, $coin, $time);
return $this->success([
'url' => $result['url'],
'token' => $result['token'],
'lang' => $result['lang'],
'user_id' => $result['user_id'],
'user' => $result['user'],
]);
} catch (\plugin\saiadmin\exception\ApiException $e) {
return $this->fail($e->getMessage(), ReturnCode::PARAMS_ERROR);
}
}
/**
* 退出登录
* POST /api/user/logout
* header: tokenJWT清除该 username 的 Redis 会话
*/
public function logout(Request $request): Response
{
$token = $request->header('token');
if ($token === null || $token === '') {
$auth = $request->header('authorization');
if ($auth && stripos($auth, 'Bearer ') === 0) {
$token = trim(substr($auth, 7));
}
}
$token = $token !== null ? trim((string) $token) : '';
if ($token === '') {
return $this->fail('请携带 token', ReturnCode::UNAUTHORIZED);
}
$username = UserLogic::getUsernameFromJwtPayload($token);
if ($username === null || $username === '') {
return $this->fail('token 无效', ReturnCode::TOKEN_INVALID);
}
UserCache::deleteSessionByUsername($username);
return $this->success('已退出登录');
}
/**
* 获取当前用户信息
* GET /api/user/info
* header: token由 TokenMiddleware 校验并注入 request->player_id
*/
public function info(Request $request): Response
{
$userId = (int) ($request->player_id ?? 0);
$user = UserLogic::getCachedUser($userId);
if (empty($user)) {
return $this->fail('用户不存在', ReturnCode::NOT_FOUND);
}
$fields = ['id', 'username', 'phone', 'uid', 'name', 'coin', 'total_ticket_count'];
$info = [];
foreach ($fields as $field) {
if (array_key_exists($field, $user)) {
$info[$field] = $user[$field];
}
}
return $this->success($info);
}
/**
* 获取钱包余额(优先读缓存)
* GET /api/user/balance
* header: token由 TokenMiddleware 注入 request->player_id
*/
public function balance(Request $request): Response
{
$userId = (int) ($request->player_id ?? 0);
$user = UserLogic::getCachedUser($userId);
if (empty($user)) {
return $this->fail('用户不存在', ReturnCode::NOT_FOUND);
}
$coin = $user['coin'] ?? 0;
if (is_string($coin) && is_numeric($coin)) {
$coin = str_contains($coin, '.') ? (float) $coin : (int) $coin;
}
return $this->success([
'coin' => $coin,
'phone' => $user['phone'] ?? '',
'username' => $user['username'] ?? '',
]);
}
/**
* 玩家钱包流水
* GET /api/user/walletRecord
* header: token由 TokenMiddleware 注入 request->player_id
* 参数: page 页码默认1, limit 每页条数默认10, create_time_min/create_time_max 创建时间范围(可选)
*/
public function walletRecord(Request $request): Response
{
$userId = (int) ($request->player_id ?? 0);
$page = (int) $request->post('page', 1);
$limit = (int) $request->post('limit', 10);
if ($page < 1) {
$page = 1;
}
if ($limit < 1) {
$limit = 10;
}
$query = DicePlayerWalletRecord::where('player_id', $userId)->order('id', 'desc');
$createTimeMin = $request->post('create_time_min', '');
$createTimeMax = $request->post('create_time_max', '');
if ($createTimeMin !== '' && $createTimeMin !== null) {
$query->where('create_time', '>=', $createTimeMin);
}
if ($createTimeMax !== '' && $createTimeMax !== null) {
$query->where('create_time', '<=', $createTimeMax);
}
$total = $query->count();
$list = $query->page($page, $limit)->select()->toArray();
$totalPage = $limit > 0 ? (int) ceil($total / $limit) : 0;
return $this->success([
'list' => $list,
'total_count' => $total,
'total_page' => $totalPage,
'current_page' => $page,
'limit' => $limit,
]);
}
/**
* 游玩记录
* GET /api/user/playGameRecord
* header: token由 TokenMiddleware 注入 request->player_id
* 参数: page 页码默认1, limit 每页条数默认10, create_time_min/create_time_max 创建时间范围(可选)
*/
public function playGameRecord(Request $request): Response
{
$userId = (int) ($request->player_id ?? 0);
$page = (int) $request->post('page', 1);
$limit = (int) $request->post('limit', 10);
if ($page < 1) {
$page = 1;
}
if ($limit < 1) {
$limit = 10;
}
$query = DicePlayRecord::where('player_id', $userId)->order('id', 'desc');
$createTimeMin = $request->post('create_time_min', '');
$createTimeMax = $request->post('create_time_max', '');
if ($createTimeMin !== '' && $createTimeMin !== null) {
$query->where('create_time', '>=', $createTimeMin);
}
if ($createTimeMax !== '' && $createTimeMax !== null) {
$query->where('create_time', '<=', $createTimeMax);
}
$total = $query->count();
$list = $query->page($page, $limit)->select()->toArray();
$totalPage = $limit > 0 ? (int) ceil($total / $limit) : 0;
return $this->success([
'list' => $list,
'total_count' => $total,
'total_page' => $totalPage,
'current_page' => $page,
'limit' => $limit,
]);
}
}