master
cody 1 month ago
parent 0791369141
commit c37f930325

@ -16,6 +16,7 @@ use App\Models\CourseSign;
use App\Models\RelatedModel;
use App\Models\ScoreLog;
use App\Models\ThirdAppointmentLog;
use App\Models\Sms;
use App\Models\User;
use App\Repositories\DoorRepository;
use App\Repositories\YuanheRepository;
@ -163,7 +164,7 @@ class UserController extends CommonController
*/
public function updateUser()
{
$all = \request()->all();
$all = \request()->except(['id','mobile','openid']);
$model = User::find($this->getUserId());
if (isset($all['password'])) {
// 判断旧密码是否正确
@ -202,7 +203,8 @@ class UserController extends CommonController
->where('plate', $plate)
->where('plate_status', 1)
->first();
if ($has) continue;
if ($has)
continue;
// 车辆预约
dispatch((new SendAppointCar($appointment, $plate)));
}
@ -226,11 +228,15 @@ class UserController extends CommonController
public function getUserInfo()
{
$user = User::with('appointments')
->withCount(['appointments as pass_appointments' => function ($query) {
$query->whereIn('status', [0, 1]);
}])->with(['courseSigns' => function ($query) {
$query->whereHas('course')->with('course.typeDetail')->where('status', 1)->where('fee_status', 1);
}])->find($this->getUserId());
->withCount([
'appointments as pass_appointments' => function ($query) {
$query->whereIn('status', [0, 1]);
}
])->with([
'courseSigns' => function ($query) {
$query->whereHas('course')->with('course.typeDetail')->where('status', 1)->where('fee_status', 1);
}
])->find($this->getUserId());
$doorRepository = new DoorRepository();
$door_appointments = Appointment::where('user_id', $this->getUserId())
@ -324,6 +330,14 @@ class UserController extends CommonController
public function bindMobile()
{
$all = \request()->all();
$clientIp = request()->ip();
// 检查IP锁定状态
$lockCheck = Sms::checkIpLock($clientIp, 'bind_mobile');
if ($lockCheck['locked']) {
return $this->fail([ResponseCode::ERROR_BUSINESS, $lockCheck['message']]);
}
$messages = [
'mobile.required' => '手机号必填',
'mobile.numeric' => '手机号格式错误',
@ -338,15 +352,29 @@ class UserController extends CommonController
if ($validator->fails()) {
return $this->fail([StarterResponseCode::START_ERROR_PARAMETER, implode(',', $validator->errors()->all())]);
}
$key = 'sms_' . $all['mobile'];
$check = Cache::get($key);
if (empty($check)) return $this->fail([ResponseCode::ERROR_BUSINESS, '请先发送验证码']);
if ($check['code'] != $all['code']) return $this->fail([ResponseCode::ERROR_BUSINESS, '验证码错误']);
if (empty($check)) {
return $this->fail([ResponseCode::ERROR_BUSINESS, '请先发送验证码']);
}
if ($check['code'] != $all['code']) {
$errorResult = Sms::recordError($clientIp, 'bind_mobile');
return $this->fail([ResponseCode::ERROR_BUSINESS, $errorResult['message']]);
}
// 验证码正确,清除错误计数
Sms::clearError($clientIp, 'bind_mobile');
// 删除验证码缓存
Cache::forget($key);
// 判断手机号是否存在
$hasMobile = User::where('mobile', $all['mobile'])->where('id', '!=', $this->getUserId())->first();
if ($hasMobile) {
return $this->fail([ResponseCode::ERROR_BUSINESS, '手机号已存在']);
}
$model = User::find($this->getUserId());
if ($all['is_bind']) {
$model->mobile = $all['mobile'];
@ -373,6 +401,14 @@ class UserController extends CommonController
public function checkMobile()
{
$all = \request()->all();
$clientIp = request()->ip();
// 检查IP锁定状态
$lockCheck = Sms::checkIpLock($clientIp, 'check_mobile');
if ($lockCheck['locked']) {
return $this->fail([ResponseCode::ERROR_BUSINESS, $lockCheck['message']]);
}
$messages = [
'mobile.required' => '手机号必填',
'mobile.numeric' => '手机号格式错误',
@ -385,10 +421,24 @@ class UserController extends CommonController
if ($validator->fails()) {
return $this->fail([StarterResponseCode::START_ERROR_PARAMETER, implode(',', $validator->errors()->all())]);
}
$key = 'sms_' . $all['mobile'];
$check = Cache::get($key);
if (empty($check)) return $this->fail([ResponseCode::ERROR_BUSINESS, '请先发送验证码']);
if ($check['code'] != $all['code']) return $this->fail([ResponseCode::ERROR_BUSINESS, '验证码错误']);
if (empty($check)) {
return $this->fail([ResponseCode::ERROR_BUSINESS, '请先发送验证码']);
}
if ($check['code'] != $all['code']) {
$errorResult = Sms::recordError($clientIp, 'check_mobile');
return $this->fail([ResponseCode::ERROR_BUSINESS, $errorResult['message']]);
}
// 验证码正确,清除错误计数
Sms::clearError($clientIp, 'check_mobile');
// 删除验证码缓存
Cache::forget($key);
// 判断手机号是否存在
$hasMobile = User::where('mobile', $all['mobile'])->first();
if ($hasMobile) {
@ -443,7 +493,7 @@ class UserController extends CommonController
if (isset($check) && time() - $check['time'] <= 60) {
return $this->fail([ResponseCode::ERROR_BUSINESS, '请勿频繁发送']);
}
$code = rand(1000, 9999);
$code = rand(100000, 999999);
$smsSign = Config::getValueByKey('sms_sign');
$content = "{$smsSign}您的验证码是:{$code},验证码五分钟内有效,如非本人操作,请忽略。";
$result = ymSms($all['mobile'], $content);
@ -540,6 +590,14 @@ class UserController extends CommonController
public function mobileLogin()
{
$all = \request()->all();
$clientIp = request()->ip();
// 检查IP锁定状态
$lockCheck = Sms::checkIpLock($clientIp, 'mobile_login');
if ($lockCheck['locked']) {
return $this->fail([ResponseCode::ERROR_BUSINESS, $lockCheck['message']]);
}
$messages = [
'code.required' => 'code必填',
'mobile.required' => '手机号必填'
@ -551,10 +609,24 @@ class UserController extends CommonController
if ($validator->fails()) {
return $this->fail([ResponseCode::ERROR_PARAMETER, implode(',', $validator->errors()->all())]);
}
$key = 'sms_login_' . $all['mobile'];
$check = Cache::get($key);
if (empty($check)) return $this->fail([ResponseCode::ERROR_BUSINESS, '请先发送验证码']);
if ($check['code'] != $all['code']) return $this->fail([ResponseCode::ERROR_BUSINESS, '验证码错误']);
if (empty($check)) {
return $this->fail([ResponseCode::ERROR_BUSINESS, '请先发送验证码']);
}
if ($check['code'] != $all['code']) {
$errorResult = Sms::recordError($clientIp, 'mobile_login');
return $this->fail([ResponseCode::ERROR_BUSINESS, $errorResult['message']]);
}
// 验证码正确,清除错误计数
Sms::clearError($clientIp, 'mobile_login');
// 删除验证码缓存
Cache::forget($key);
$user = User::where('mobile', $all['mobile'])->first();
$token = $user->createToken("mobile-token")->plainTextToken;
return $this->success(compact('token'));
@ -620,7 +692,7 @@ class UserController extends CommonController
if (isset($check) && time() - $check['time'] <= 60) {
return $this->fail([ResponseCode::ERROR_BUSINESS, '请勿频繁发送']);
}
$code = rand(1000, 9999);
$code = rand(100000, 999999);
$smsSign = Config::getValueByKey('sms_sign');
$content = "{$smsSign}您的验证码是:{$code},验证码五分钟内有效,如非本人操作,请忽略。";
$result = ymSms($all['mobile'], $content);

@ -1,15 +1,76 @@
<?php
namespace App\Models;
use Illuminate\Support\Facades\Cache;
class Sms extends SoftDeletesModel
class Sms
{
protected $table = "sms";
/**
* 检查IP是否被锁定
*
* @param string $ip 客户端IP地址
* @param string $type 方法类型 (bind_mobile/check_mobile)
* @return array ['locked' => bool, 'message' => string]
*/
public static function checkIpLock($ip, $type = 'bind_mobile')
{
$ipLockKey = 'sms_ip_lock_' . $type . '_' . $ip;
if (Cache::has($ipLockKey)) {
$lockTime = Cache::get($ipLockKey);
$remainingTime = $lockTime - time();
if ($remainingTime > 0) {
$minutes = ceil($remainingTime / 60);
return [
'locked' => true,
'message' => "访问过于频繁,请{$minutes}分钟后再试"
];
}
}
public function belongs() {
return $this->morphTo();
return ['locked' => false, 'message' => ''];
}
}
/**
* 记录验证码错误
*
* @param string $ip 客户端IP地址
* @param string $type 方法类型 (bind_mobile/check_mobile)
* @return array ['locked' => bool, 'message' => string]
*/
public static function recordError($ip, $type = 'bind_mobile')
{
$errorKey = 'sms_error_count_' . $type . '_' . $ip;
$ipLockKey = 'sms_ip_lock_' . $type . '_' . $ip;
$errorCount = Cache::get($errorKey, 0) + 1;
Cache::put($errorKey, $errorCount, 3600); // 1小时过期
// 如果错误次数达到10次锁定IP
if ($errorCount >= 10) {
Cache::put($ipLockKey, time() + 3600, 3600); // 锁定1小时
Cache::forget($errorKey); // 清除错误计数
return [
'locked' => true,
'message' => '验证码错误次数过多请1小时后再试'
];
}
return ['locked' => false, 'message' => '验证码错误'];
}
/**
* 清除错误计数
*
* @param string $ip 客户端IP地址
* @param string $type 方法类型 (bind_mobile/check_mobile)
*/
public static function clearError($ip, $type = 'bind_mobile')
{
$errorKey = 'sms_error_count_' . $type . '_' . $ip;
Cache::forget($errorKey);
}
}

Loading…
Cancel
Save