This commit is contained in:
2026-03-05 16:50:52 +08:00
parent 39955a17a8
commit aef404548d
4 changed files with 106 additions and 59 deletions

View File

@@ -18,13 +18,13 @@ REDIS_DB = 0
# API 鉴权与用户(可选,不填则用默认值) # API 鉴权与用户(可选,不填则用默认值)
# authToken 签名密钥(必填,与客户端约定,用于 signature 校验) # authToken 签名密钥(必填,与客户端约定,用于 signature 校验)
API_AUTH_TOKEN_SECRET = xF75oK91TQj13s0UmNIr1NBWMWGfflNO API_AUTH_TOKEN_SECRET = xF75oK91TQj13s0UmNIr1NBWMWGfflNO
# authToken 时间戳允许误差秒数,防重放,默认 300 # authToken 时间戳允许误差秒数,防重放,默认 300
API_AUTH_TOKEN_TIME_TOLERANCE = 300 API_AUTH_TOKEN_TIME_TOLERANCE = 300
API_AUTH_TOKEN_EXP = 86400 API_AUTH_TOKEN_EXP = 86400
# API_USER_TOKEN_EXP = 604800 # API_USER_TOKEN_EXP = 604800
API_USER_CACHE_EXPIRE = 86400 API_USER_CACHE_EXPIRE = 86400
API_USER_ENCRYPT_KEY = Wj818SK8dhKBKNOY3PUTmZfhQDMCXEZi API_USER_ENCRYPT_KEY = Wj818SK8dhKBKNOY3PUTmZfhQDMCXEZi
# 验证码配置,支持cache|session # 验证码配置,支持cache|session
CAPTCHA_MODE = cache CAPTCHA_MODE = cache

View File

@@ -27,7 +27,8 @@ class GameLogic
/** /**
* 购买抽奖券 * 购买抽奖券
* @param int $playerId 玩家ID即 user_id * 先更新 Redis 玩家信息(后续游玩从 Redis 读),再用事务更新数据库;事务失败则回滚 Redis
* @param int $playerId 玩家ID
* @param int $count 购买档位1 / 5 / 10 * @param int $count 购买档位1 / 5 / 10
* @return array 更新后的 coin, total_ticket_count, paid_ticket_count, free_ticket_count * @return array 更新后的 coin, total_ticket_count, paid_ticket_count, free_ticket_count
*/ */
@@ -55,59 +56,70 @@ class GameLogic
$totalBefore = (int) ($player->total_ticket_count ?? 0); $totalBefore = (int) ($player->total_ticket_count ?? 0);
$paidBefore = (int) ($player->paid_ticket_count ?? 0); $paidBefore = (int) ($player->paid_ticket_count ?? 0);
$freeBefore = (int) ($player->free_ticket_count ?? 0); $freeBefore = (int) ($player->free_ticket_count ?? 0);
$totalAfter = $totalBefore + $addTotal;
$paidAfter = $paidBefore + $addPaid;
$freeAfter = $freeBefore + $addFree;
Db::transaction(function () use ( $oldUserArr = $player->hidden(['password'])->toArray();
$player, $updatedUserArr = $oldUserArr;
$playerId, $updatedUserArr['coin'] = $coinAfter;
$cost, $updatedUserArr['total_ticket_count'] = $totalAfter;
$coinBefore, $updatedUserArr['paid_ticket_count'] = $paidAfter;
$coinAfter, $updatedUserArr['free_ticket_count'] = $freeAfter;
$addTotal,
$addPaid,
$addFree,
$totalBefore,
$paidBefore,
$freeBefore
) {
$player->coin = $coinAfter;
$player->total_ticket_count = $totalBefore + $addTotal;
$player->paid_ticket_count = $paidBefore + $addPaid;
$player->free_ticket_count = $freeBefore + $addFree;
$player->save();
// 钱包流水记录 UserCache::setUser($playerId, $updatedUserArr);
DicePlayerWalletRecord::create([
'player_id' => $playerId,
'coin' => -$cost,
'type' => self::WALLET_TYPE_BUY_DRAW,
'wallet_before' => $coinBefore,
'wallet_after' => $coinAfter,
'total_ticket_count' => $addTotal,
'paid_ticket_count' => $addPaid,
'free_ticket_count' => $addFree,
'remark' => "购买抽奖券{$addTotal}次(付费{$addPaid}次+赠送{$addFree}次)",
]);
// 抽奖券获取记录 try {
DicePlayerTicketRecord::create([ Db::transaction(function () use (
'player_id' => $playerId, $player,
'use_coins' => $cost, $playerId,
'total_ticket_count' => $addTotal, $cost,
'paid_ticket_count' => $addPaid, $coinBefore,
'free_ticket_count' => $addFree, $coinAfter,
'remark' => "购买抽奖券{$addTotal}次(付费{$addPaid}次+赠送{$addFree}次)", $addTotal,
]); $addPaid,
}); $addFree,
$totalAfter,
$paidAfter,
$freeAfter
) {
$player->coin = $coinAfter;
$player->total_ticket_count = $totalAfter;
$player->paid_ticket_count = $paidAfter;
$player->free_ticket_count = $freeAfter;
$player->save();
$updated = DicePlayer::find($playerId); DicePlayerWalletRecord::create([
$userArr = $updated->hidden(['password'])->toArray(); 'player_id' => $playerId,
UserCache::setUser($playerId, $userArr); 'coin' => -$cost,
'type' => self::WALLET_TYPE_BUY_DRAW,
'wallet_before' => $coinBefore,
'wallet_after' => $coinAfter,
'total_ticket_count' => $addTotal,
'paid_ticket_count' => $addPaid,
'free_ticket_count' => $addFree,
'remark' => "购买抽奖券{$addTotal}次(付费{$addPaid}次+赠送{$addFree}次)",
]);
DicePlayerTicketRecord::create([
'player_id' => $playerId,
'use_coins' => $cost,
'total_ticket_count' => $addTotal,
'paid_ticket_count' => $addPaid,
'free_ticket_count' => $addFree,
'remark' => "购买抽奖券{$addTotal}次(付费{$addPaid}次+赠送{$addFree}次)",
]);
});
} catch (\Throwable $e) {
UserCache::setUser($playerId, $oldUserArr);
throw $e;
}
return [ return [
'coin' => (float) $updated->coin, 'coin' => (float) $coinAfter,
'total_ticket_count' => (int) $updated->total_ticket_count, 'total_ticket_count' => (int) $totalAfter,
'paid_ticket_count' => (int) $updated->paid_ticket_count, 'paid_ticket_count' => (int) $paidAfter,
'free_ticket_count' => (int) $updated->free_ticket_count, 'free_ticket_count' => (int) $freeAfter,
]; ];
} }
} }

View File

@@ -49,6 +49,11 @@ class DicePlayer extends BaseModel
*/ */
protected $table = 'dice_player'; protected $table = 'dice_player';
/** 创建时间字段dice_player 表为 created_at */
protected $createTime = 'created_at';
/** 更新时间字段dice_player 表为 updated_at */
protected $updateTime = 'updated_at';
/** /**
* 新增前:生成唯一 uid昵称 name 默认使用 uid * 新增前:生成唯一 uid昵称 name 默认使用 uid
* 用 try-catch 避免表尚未含 uid 时 getAttr/getData 抛 InvalidArgumentException * 用 try-catch 避免表尚未含 uid 时 getAttr/getData 抛 InvalidArgumentException

View File

@@ -35,6 +35,12 @@ class BaseModel extends Model implements ModelInterface
*/ */
protected $updateTime = 'update_time'; protected $updateTime = 'update_time';
/**
* 自动写入时间戳(创建时写 create_time更新时写 update_time
* @var bool
*/
protected $autoWriteTimestamp = true;
/** /**
* 隐藏字段 * 隐藏字段
* @var array * @var array
@@ -94,24 +100,48 @@ class BaseModel extends Model implements ModelInterface
} }
/** /**
* 新增前事件 * 新增前事件:自动写入 create_time有后台登录信息时写入 created_by
* @param Model $model * @param Model $model
* @return void * @return void
*/ */
public static function onBeforeInsert($model): void public static function onBeforeInsert($model): void
{ {
$info = getCurrentInfo(); $createTime = $model->createTime ?? 'create_time';
$info && $model->setAttr('created_by', $info['id']); if ($createTime && !$model->getData($createTime)) {
$model->set($createTime, date('Y-m-d H:i:s'));
}
if (function_exists('getCurrentInfo')) {
$info = getCurrentInfo();
if (!empty($info['id'])) {
try {
$model->setAttr('created_by', $info['id']);
} catch (\Throwable $e) {
}
}
}
} }
/** /**
* 写入前事件 * 写入前事件:更新时自动写入 update_time有后台登录信息时写入 updated_by
* @param Model $model * @param Model $model
* @return void * @return void
*/ */
public static function onBeforeWrite($model): void public static function onBeforeWrite($model): void
{ {
$info = getCurrentInfo(); if ($model->isUpdate()) {
$info && $model->setAttr('updated_by', $info['id']); $updateTime = $model->updateTime ?? 'update_time';
if ($updateTime) {
$model->set($updateTime, date('Y-m-d H:i:s'));
}
}
if (function_exists('getCurrentInfo')) {
$info = getCurrentInfo();
if (!empty($info['id'])) {
try {
$model->setAttr('updated_by', $info['id']);
} catch (\Throwable $e) {
}
}
}
} }
} }