chore: 批量代码优化与功能迭代更新

本次提交包含大量代码优化、功能新增与服务端配置更新:
1. 修复分析报告统计数据,调整CMake策略设置
2. 优化APP权限配置、编辑器与聊天界面组件
3. 更新依赖库版本与pubspec配置
4. 新增文件传输服务端、信令服务器相关配置与脚本
5. 完善用户注销功能与数据库迁移脚本
6. 优化多处动画效果、代码风格与日志输出
7. 新增多种调试与部署脚本,修复已知BUG
This commit is contained in:
Developer
2026-05-12 06:28:04 +08:00
parent 72f64f9ca9
commit 283950ea07
245 changed files with 50255 additions and 6160 deletions

View File

@@ -33,6 +33,9 @@ class UserSecurity extends Api
'sendEms' => ['max' => 30, 'window' => 300],
'tokenLogin' => ['max' => 80, 'window' => 300],
'receiptLogin' => ['max' => 50, 'window' => 300],
'requestDeletion' => ['max' => 5, 'window' => 3600],
'cancelDeletion' => ['max' => 10, 'window' => 3600],
'deletionStatus' => ['max' => 60, 'window' => 60],
];
private static $testMode = false;
@@ -149,7 +152,8 @@ class UserSecurity extends Api
if ($ret) {
$this->recordLoginDevice($this->auth->id);
$this->updateOnlineStatus($this->auth->id);
$data = ['userinfo' => $this->auth->getUserinfo()];
$token = $this->auth->getToken();
$data = ['userinfo' => $this->auth->getUserinfo(), 'token' => $token];
$this->success(__('Logged in successful'), $data);
} else {
$this->error($this->auth->getError());
@@ -329,7 +333,8 @@ class UserSecurity extends Api
$verification = $verification ? json_decode($verification, true) : [];
$verification['email'] = 1;
db('user')->where('id', $userId)->update(['verification' => json_encode($verification)]);
$data = ['userinfo' => $this->auth->getUserinfo()];
$token = $this->auth->getToken();
$data = ['userinfo' => $this->auth->getUserinfo(), 'token' => $token];
$this->success(__('Sign up successful'), $data);
} else {
$this->error($this->auth->getError());
@@ -738,6 +743,164 @@ class UserSecurity extends Api
$this->error('未知状态');
}
/**
* @name 申请账号注销
* @desc 用户提交注销申请,需回执验证(action=delete_account)3天审核期
* @lastUpdate v9.2.0 新增
*/
public function requestDeletion()
{
$this->checkRateLimit('requestDeletion');
$user = $this->auth->getUser();
$reason = $this->request->post('reason', '', 'trim');
$this->verifyReceipt('delete_account', strval($user->id));
if ($reason) {
$reason = $this->sanitizeString($reason, 500);
}
$existing = db('user_deletion')
->where('user_id', $user->id)
->where('status', 0)
->find();
if ($existing) {
$statusMap = [0 => '待审核', 1 => '已通过(已注销)', 2 => '已拒绝', 3 => '已自动注销'];
$remain = $existing['auto_delete_time'] - time();
$countdown = '';
if ($remain > 0) {
$days = floor($remain / 86400);
$hours = floor(($remain % 86400) / 3600);
$countdown = "{$days}{$hours}小时后自动注销";
} else {
$countdown = '即将自动注销';
}
$this->error('已存在待审核的注销申请', [
'id' => $existing['id'],
'status_text' => $statusMap[$existing['status']] ?? '未知',
'countdown' => $countdown,
]);
}
$threeDaysLater = time() + 3 * 24 * 3600;
$now = time();
$data = [
'user_id' => $user->id,
'username' => $user->username ?? $user->nickname ?? '',
'reason' => $reason ?: '用户主动申请注销',
'status' => 0,
'admin_id' => 0,
'admin_remark' => '',
'auto_delete_time' => $threeDaysLater,
'createtime' => $now,
'updatetime' => $now,
'deletetime' => null,
];
$result = db('user_deletion')->insertGetId($data);
if ($result) {
$remain = $threeDaysLater - time();
$days = floor($remain / 86400);
$hours = floor(($remain % 86400) / 3600);
$countdown = "{$days}{$hours}小时后自动注销";
$this->success('注销申请已提交', [
'id' => $result,
'user_id' => $user->id,
'status' => 0,
'status_text' => '待审核',
'auto_delete_time' => $threeDaysLater,
'auto_delete_time_text' => date('Y-m-d H:i:s', $threeDaysLater),
'countdown' => $countdown,
'createtime_text' => date('Y-m-d H:i:s', $now),
]);
} else {
$this->error('提交失败,请稍后再试');
}
}
/**
* @name 查询注销状态
* @desc 查询当前用户的注销申请状态
* @lastUpdate v9.2.0 新增
*/
public function deletionStatus()
{
$this->checkRateLimit('deletionStatus');
$user = $this->auth->getUser();
$record = db('user_deletion')
->where('user_id', $user->id)
->order('createtime desc')
->find();
if (!$record) {
$this->success('', ['has_pending' => false]);
}
$statusMap = [0 => '待审核', 1 => '已通过(已注销)', 2 => '已拒绝', 3 => '已自动注销'];
$record['status_text'] = $statusMap[$record['status']] ?? '未知';
$record['createtime_text'] = date('Y-m-d H:i:s', $record['createtime']);
$record['auto_delete_time_text'] = date('Y-m-d H:i:s', $record['auto_delete_time']);
$remain = $record['auto_delete_time'] - time();
if ($record['status'] == 0 && $remain > 0) {
$days = floor($remain / 86400);
$hours = floor(($remain % 86400) / 3600);
$record['countdown'] = "{$days}{$hours}小时后自动注销";
} elseif ($record['status'] == 0) {
$record['countdown'] = '已超时,待自动注销';
} else {
$record['countdown'] = '-';
}
$this->success('', [
'has_pending' => $record['status'] == 0,
'id' => $record['id'],
'status' => $record['status'],
'status_text' => $record['status_text'],
'reason' => $record['reason'],
'auto_delete_time_text' => $record['auto_delete_time_text'],
'countdown' => $record['countdown'],
'createtime_text' => $record['createtime_text'],
]);
}
/**
* @name 取消注销申请
* @desc 用户取消待审核的注销申请
* @lastUpdate v9.2.0 新增
*/
public function cancelDeletion()
{
$this->checkRateLimit('cancelDeletion');
$user = $this->auth->getUser();
$record = db('user_deletion')
->where('user_id', $user->id)
->where('status', 0)
->find();
if (!$record) {
$this->error('没有待审核的注销申请');
}
$result = db('user_deletion')
->where('id', $record['id'])
->update([
'status' => 2,
'admin_remark' => '用户主动取消',
'updatetime' => time(),
]);
if ($result) {
$this->success('注销申请已取消');
} else {
$this->error('取消失败,请稍后再试');
}
}
/**
* @name 取消二维码
* @desc 取消二维码登录
@@ -775,10 +938,12 @@ class UserSecurity extends Api
$ip = $this->request->ip();
$now = time();
$ipLocation = $this->queryIpLocation($ip);
if ($deviceId) {
$exists = db('user_device')->where('user_id', $userId)->where('device_id', $deviceId)->find();
if ($exists) {
db('user_device')->where('id', $exists['id'])->update([
$updateData = [
'device_name' => $deviceName ?: $exists['device_name'],
'device_model' => $deviceModel ?: $exists['device_model'],
'platform' => $platform ?: $exists['platform'],
@@ -788,12 +953,17 @@ class UserSecurity extends Api
'is_online' => 1,
'user_agent' => substr($userAgent, 0, 500),
'updatetime' => $now,
]);
];
if ($ipLocation) {
if (!empty($ipLocation['city'])) $updateData['ip_city'] = $ipLocation['city'];
if (!empty($ipLocation['fw'])) $updateData['ip_range'] = $ipLocation['fw'];
}
db('user_device')->where('id', $exists['id'])->update($updateData);
return;
}
}
db('user_device')->insert([
$insertData = [
'user_id' => $userId,
'device_name' => $deviceName,
'device_model' => $deviceModel,
@@ -806,7 +976,45 @@ class UserSecurity extends Api
'user_agent' => substr($userAgent, 0, 500),
'createtime' => $now,
'updatetime' => $now,
]);
];
if ($ipLocation) {
if (!empty($ipLocation['city'])) $insertData['ip_city'] = $ipLocation['city'];
if (!empty($ipLocation['fw'])) $insertData['ip_range'] = $ipLocation['fw'];
}
db('user_device')->insert($insertData);
}
/**
* @name 查询IP归属地
* @desc 使用纯真IP数据库查询IP归属地返回city和fw
* @lastUpdate v9.2.0 新增解决登录时ip_city为空问题
*/
private function queryIpLocation($ip)
{
if (!$ip || $ip === '127.0.0.1' || $ip === '0.0.0.0') {
return null;
}
try {
$ips = new \Net\Ips('./qqwry.dat');
$resolved = gethostbyname($ip);
if (!$resolved || $resolved === $ip) {
$resolved = $ip;
}
$fwq = $ips->Getlocation($resolved);
$city = strToUTF8($fwq['country'] . ' ' . $fwq['area']);
$fw = '';
$domain = preg_replace('/(\d+)\..*/', '\\1', $resolved);
if ('1' <= $domain && $domain <= '126') {
$fw = '1.0.0.1 - 126.155.255.254';
} elseif ('128' <= $domain && $domain <= '191') {
$fw = '128.0.0.1 - 191.255.255.254';
} elseif ('192' <= $domain && $domain <= '223') {
$fw = '192.0.0.1 - 223.255.255.254';
}
return ['city' => $city, 'fw' => $fw];
} catch (\Exception $e) {
return null;
}
}
/**