_vali([ 'email.require' => '邮箱不能为空', 'password.require' => '密码不能为空', 'first_name.require' => '名字不能为空', 'last_name.require' => '姓氏不能为空', 'access_token.require' => 'access_token不能为空', 'refresh_token.require' => 'refresh_token不能为空', 'registration_time.require' => '注册时间不能为空' ]); // 检查邮箱是否已存在 if (Db::name('cursor_accounts')->where('email', $data['email'])->find()) { return json([ 'code' => 400, 'msg' => '该邮箱已存在' ]); } // 准备插入数据 $insertData = [ 'email' => $data['email'], 'password' => $data['password'], 'first_name' => $data['first_name'], 'last_name' => $data['last_name'], 'access_token' => $data['access_token'], 'refresh_token' => $data['refresh_token'], 'machine_id' => $data['machine_id'] ?? '', 'user_agent' => $data['user_agent'] ?? '', 'registration_time' => $data['registration_time'], 'created_at' => date('Y-m-d H:i:s'), 'is_used' => 0 ]; // 插入数据 $id = Db::name('cursor_accounts')->insertGetId($insertData); return json([ 'code' => 200, 'msg' => '添加成功', 'data' => ['id' => $id] ]); } catch (\Exception $e) { return json([ 'code' => 500, 'msg' => $e->getMessage() ]); } } /** * 获取未使用的账号 */ public function getUnused() { try { // 获取machine_id $machineId = input('machine_id', ''); if (empty($machineId)) { return json([ 'code' => 401, 'msg' => '设备ID不能为空' ]); } // 检查设备是否在冷却期 $cooldownKey = "device_cooldown_{$machineId}"; $isInCooldown = \think\facade\Cache::get($cooldownKey); if ($isInCooldown) { return json([ 'code' => 429, 'msg' => '请求过于频繁,请稍后再试', 'data' => [ 'cooldown_expires' => date('Y-m-d H:i:s', $isInCooldown) ] ]); } // 查询设备激活状态 $activations = Db::name('cursor_activation_codes') ->where('used_by', '=', $machineId) ->where('is_used', '=', 1) ->order('used_at desc') ->select() ->toArray(); if (empty($activations)) { return json([ 'code' => 401, 'msg' => '设备未激活' ]); } // 计算总天数和到期时间 $totalDays = array_sum(array_column($activations, 'days')); $firstActivationTime = strtotime($activations[count($activations)-1]['used_at']); $expireTime = $firstActivationTime + ($totalDays * 24 * 3600); // 检查是否过期 if (time() > $expireTime) { return json([ 'code' => 401, 'msg' => '设备授权已过期' ]); } // 检查缓存中是否有该设备最近使用的账号 $cacheKey = "device_account_{$machineId}"; $cachedAccount = \think\facade\Cache::get($cacheKey); if ($cachedAccount) { // 检查账号是否仍然可用 $account = Db::name('cursor_accounts') ->where('id', $cachedAccount['id']) ->find(); if ($account) { // 更新缓存时间 \think\facade\Cache::set($cacheKey, $account, 600); // 10分钟缓存 // 返回账号信息 return json([ 'code' => 200, 'msg' => '获取成功', 'data' => [ 'email' => $account['email'], 'password' => $account['password'], 'access_token' => $account['access_token'], 'refresh_token' => $account['refresh_token'], 'expire_time' => date('Y-m-d H:i:s', $expireTime), 'days_left' => ceil(($expireTime - time()) / 86400) ] ]); } } // 记录冷却期 $cooldownExpires = time() + 1800; // 30分钟冷却期 \think\facade\Cache::set($cooldownKey, $cooldownExpires, 1800); // 开启事务 Db::startTrans(); try { // 获取一个未使用的账号 $account = Db::name('cursor_accounts') ->where('is_used', 0) ->lock(true) ->find(); if (empty($account)) { Db::rollback(); return json([ 'code' => 404, 'msg' => '没有可用的账号' ]); } // 如果有旧账号,将其标记为未使用 if ($cachedAccount) { Db::name('cursor_accounts') ->where('id', $cachedAccount['id']) ->update([ 'is_used' => 0, 'used_at' => null, 'used_by' => '' ]); } // 更新新账号状态 Db::name('cursor_accounts') ->where('id', $account['id']) ->update([ 'is_used' => 1, 'used_at' => date('Y-m-d H:i:s'), 'used_by' => $machineId ]); Db::commit(); // 缓存新账号信息 \think\facade\Cache::set($cacheKey, $account, 600); // 10分钟缓存 // 返回账号信息 return json([ 'code' => 200, 'msg' => '获取成功', 'data' => [ 'email' => $account['email'], 'password' => $account['password'], 'access_token' => $account['access_token'], 'refresh_token' => $account['refresh_token'], 'expire_time' => date('Y-m-d H:i:s', $expireTime), 'days_left' => ceil(($expireTime - time()) / 86400) ] ]); } catch (\Exception $e) { Db::rollback(); throw $e; } } catch (\Exception $e) { return json([ 'code' => 500, 'msg' => $e->getMessage() ]); } } /** * 后台强制重置设备账号 * @auth true */ public function resetDeviceAccount() { try { $data = $this->_vali([ 'machine_id.require' => '设备ID不能为空' ]); $machineId = $data['machine_id']; // 清除设备的账号缓存 $cacheKey = "device_account_{$machineId}"; \think\facade\Cache::delete($cacheKey); // 清除冷却期 $cooldownKey = "device_cooldown_{$machineId}"; \think\facade\Cache::delete($cooldownKey); // 将该设备使用的账号标记为未使用 Db::name('cursor_accounts') ->where('used_by', $machineId) ->update([ 'is_used' => 0, 'used_at' => null, 'used_by' => '' ]); return json([ 'code' => 200, 'msg' => '重置成功' ]); } catch (\Exception $e) { return json([ 'code' => 500, 'msg' => $e->getMessage() ]); } } }