| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177 |
- <?php
- namespace app\api\library;
- use think\Db;
- /**
- * 玩家常用设备管理
- * 维护玩家最近登录的3个常用设备,用于设备切换验证判断
- */
- class MemberDevice
- {
- // 最大常用设备数量
- const MAX_RECENT_DEVICES = 3;
- /**
- * 添加/更新常用设备
- * 登录时调用,将设备记录存储到 recent_devices 字段
- *
- * @param int $memberId 玩家ID
- * @param int $gameId 游戏ID
- * @param string $imei 设备IMEI
- * @param int $deviceType 设备类型:1=PC,2=安卓,3=苹果
- * @param bool $forceReplace 列表已满时是否强制替换最旧设备(验证通过后传true)
- * @param bool $onlyUpdateExisting 是否仅更新已存在的设备(登录时传true,不添加新设备)
- * @return bool
- */
- public function addDevice($memberId, $gameId, $imei, $deviceType = 0, $forceReplace = false, $onlyUpdateExisting = false)
- {
- if (empty($memberId) || empty($gameId) || empty($imei)) {
- return false;
- }
- // 查询当前常用设备列表
- $subInfo = Db::name('nw_subaccount')
- ->where('member_id', $memberId)
- ->where('game_id', $gameId)
- ->field('id, recent_devices')
- ->find();
- if (empty($subInfo)) {
- return false;
- }
- // 解析现有设备列表
- $recentDevices = [];
- if (!empty($subInfo['recent_devices'])) {
- $recentDevices = json_decode($subInfo['recent_devices'], true);
- if (!is_array($recentDevices)) {
- $recentDevices = [];
- }
- }
- // 检查设备是否已存在
- $existsIndex = $this->findDeviceIndex($recentDevices, $imei);
- $now = time();
- if ($existsIndex !== false) {
- // 设备已存在,更新最后登录时间
- $recentDevices[$existsIndex]['last_login'] = $now;
- } else {
- // 设备不存在
- // 仅更新模式:不添加新设备
- if ($onlyUpdateExisting) {
- return false;
- }
- // 判断是否需要添加
- if (count($recentDevices) >= self::MAX_RECENT_DEVICES) {
- // 列表已满,且未强制替换,不处理
- if (!$forceReplace) {
- return false;
- }
- // 强制替换:移除最旧的设备
- $oldestIndex = $this->findOldestDeviceIndex($recentDevices);
- if ($oldestIndex !== false) {
- unset($recentDevices[$oldestIndex]);
- $recentDevices = array_values($recentDevices);
- }
- }
- // 添加新设备
- $recentDevices[] = [
- 'imei' => $imei,
- 'device_type' => (int)$deviceType,
- 'last_login' => $now,
- ];
- }
- // 更新数据库
- $result = Db::name('nw_subaccount')
- ->where('id', $subInfo['id'])
- ->update([
- 'recent_devices' => json_encode($recentDevices),
- 'update_time' => $now,
- ]);
- return $result !== false;
- }
- /**
- * 判断是否为最近登录的设备
- *
- * @param int $memberId 玩家ID
- * @param int $gameId 游戏ID
- * @param string $imei 设备IMEI
- * @return bool true=是常用设备,false=不是常用设备
- */
- public function isRecentDevice($memberId, $gameId, $imei)
- {
- if (empty($memberId) || empty($gameId) || empty($imei)) {
- return false;
- }
- // 查询当前常用设备列表
- $subInfo = Db::name('nw_subaccount')
- ->where('member_id', $memberId)
- ->where('game_id', $gameId)
- ->field('recent_devices')
- ->find();
- if (empty($subInfo) || empty($subInfo['recent_devices'])) {
- return false;
- }
- // 解析设备列表
- $recentDevices = json_decode($subInfo['recent_devices'], true);
- if (!is_array($recentDevices) || empty($recentDevices)) {
- return false;
- }
- // 查找设备
- return $this->findDeviceIndex($recentDevices, $imei) !== false;
- }
- /**
- * 查找设备在列表中的索引
- *
- * @param array $devices 设备列表
- * @param string $imei 设备IMEI
- * @return int|false 找到返回索引,未找到返回false
- */
- private function findDeviceIndex($devices, $imei)
- {
- foreach ($devices as $index => $device) {
- if (isset($device['imei']) && $device['imei'] === $imei) {
- return $index;
- }
- }
- return false;
- }
- /**
- * 查找最旧设备的索引
- *
- * @param array $devices 设备列表
- * @return int|false
- */
- private function findOldestDeviceIndex($devices)
- {
- if (empty($devices)) {
- return false;
- }
- $oldestIndex = 0;
- $oldestTime = PHP_INT_MAX;
- foreach ($devices as $index => $device) {
- if (isset($device['last_login']) && $device['last_login'] < $oldestTime) {
- $oldestTime = $device['last_login'];
- $oldestIndex = $index;
- }
- }
- return $oldestIndex;
- }
- }
|