273 lines
8.9 KiB
PHP
273 lines
8.9 KiB
PHP
<?php
|
|
declare (strict_types = 1);
|
|
|
|
namespace app\admin\controller\api;
|
|
|
|
use think\admin\Controller;
|
|
use think\facade\Db;
|
|
|
|
/**
|
|
* Cursor账号管理接口
|
|
*/
|
|
class Account extends Controller
|
|
{
|
|
/**
|
|
* 添加账号
|
|
*/
|
|
public function add()
|
|
{
|
|
try {
|
|
$data = $this->_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()
|
|
]);
|
|
}
|
|
}
|
|
}
|