diff --git a/beike/Libraries/Notification.php b/beike/Libraries/Notification.php new file mode 100644 index 00000000..50545e18 --- /dev/null +++ b/beike/Libraries/Notification.php @@ -0,0 +1,28 @@ + + * @created 2022-07-07 10:52:57 + * @modified 2022-07-07 10:52:57 + */ + +namespace Beike\Libraries; + + +class Notification +{ + /** + * @param string $code + * @param string $message + * @param string $type email|telephone + * @return bool + */ + public static function verifyCode(string $code, string $message, string $type): bool + { + + return true; + } +} diff --git a/beike/Models/VerifyCode.php b/beike/Models/VerifyCode.php new file mode 100644 index 00000000..f73a8538 --- /dev/null +++ b/beike/Models/VerifyCode.php @@ -0,0 +1,25 @@ + + * @created 2022-07-07 15:22:18 + * @modified 2022-07-07 15:22:18 + */ + +namespace Beike\Models; + +use Illuminate\Database\Eloquent\Model; +use Illuminate\Database\Eloquent\Factories\HasFactory; +use Illuminate\Database\Eloquent\SoftDeletes; + +class VerifyCode extends Model +{ + use HasFactory; + use SoftDeletes; + + protected $fillable = ['account', 'code']; +} + diff --git a/beike/Repositories/CustomerRepo.php b/beike/Repositories/CustomerRepo.php index aa5451ed..87a198ab 100644 --- a/beike/Repositories/CustomerRepo.php +++ b/beike/Repositories/CustomerRepo.php @@ -28,16 +28,24 @@ class CustomerRepo } /** - * @param $id + * @param $customer * @param $data * @return bool|int */ - public static function update($id, $data) + public static function update($customer, $data) { + if (!$customer instanceof Customer) { + $customer = Customer::query()->findOrFail($customer); + } if (isset($data['password'])) { $data['password'] = Hash::make($data['password']); } - return Customer::query()->find($id)->update($data); + return $customer->update($data); + } + + public static function findByEmail($email) + { + return Customer::query()->where('email', $email)->first(); } /** diff --git a/beike/Repositories/VerifyCodeRepo.php b/beike/Repositories/VerifyCodeRepo.php new file mode 100644 index 00000000..a6124526 --- /dev/null +++ b/beike/Repositories/VerifyCodeRepo.php @@ -0,0 +1,55 @@ + + * @created 2022-07-07 15:22:05 + * @modified 2022-07-07 15:22:05 + */ + +namespace Beike\Repositories; + + +use Beike\Models\VerifyCode; + +class VerifyCodeRepo +{ + /** + * 创建一个记录 + * @param $data + * @return int + */ + public static function create($data) + { + $verifyCode = VerifyCode::query()->create($data); + return $verifyCode; + } + + /** + * @param $id + * @return \Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Eloquent\Builder[]|\Illuminate\Database\Eloquent\Collection|\Illuminate\Database\Eloquent\Model|null + */ + public static function find($id) + { + return VerifyCode::query()->find($id); + } + + public static function findByAccount($account) + { + return VerifyCode::query()->where('account', $account)->first(); + } + + /** + * @param $id + * @return void + */ + public static function delete($id) + { + $verifyCode = VerifyCode::query()->find($id); + if ($verifyCode) { + $verifyCode->delete(); + } + } +} diff --git a/beike/Shop/Http/Controllers/Account/ForgottenController.php b/beike/Shop/Http/Controllers/Account/ForgottenController.php new file mode 100644 index 00000000..b8b1ae2e --- /dev/null +++ b/beike/Shop/Http/Controllers/Account/ForgottenController.php @@ -0,0 +1,50 @@ + + * @created 2022-07-06 15:39:08 + * @modified 2022-07-06 15:39:08 + */ + +namespace Beike\Shop\Http\Controllers\Account; + +use Beike\Shop\Services\AccountService; +use Illuminate\Http\Request; + +class ForgottenController +{ + /** + * 找回密码页面 + * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View + */ + public function index() + { + return view('account/forgotten'); + } + + /** + * 接收email地址,生成验证码发送到邮件地址 + * @param Request $request + * @return array + */ + public function sendVerifyCode(Request $request) + { + AccountService::sendVerifyCodeForForgotten($request->get('email'), 'email'); + return json_success('验证码已发送,请查看并输入验证码'); + } + + /** + * 接收验证码和新密码、确认密码,验证验证码是否正确、密码和确认密码是否相等,然后修改密码 + * @param Request $request + * @return array + */ + public function changePassword(ForgottenRequest $request) + { + AccountService::verifyAndChangePassword($request->get('code'), $request->get('account'), $request->get('password')); + + return json_success('密码已修改'); + } +} diff --git a/beike/Shop/Http/Requests/ForgottenRequest.php b/beike/Shop/Http/Requests/ForgottenRequest.php new file mode 100644 index 00000000..a7970d74 --- /dev/null +++ b/beike/Shop/Http/Requests/ForgottenRequest.php @@ -0,0 +1,37 @@ + 'required|confirmed', + ]; + } + + public function attributes() + { + return [ + 'password' => '密码' + ]; + } +} diff --git a/beike/Shop/Routes/shop.php b/beike/Shop/Routes/shop.php index dec6d0ce..26433645 100644 --- a/beike/Shop/Routes/shop.php +++ b/beike/Shop/Routes/shop.php @@ -2,6 +2,7 @@ use Beike\Models\Customer; use Beike\Shop\Http\Controllers\Account\AddressController; +use Beike\Shop\Http\Controllers\Account\ForgottenController; use Beike\Shop\Http\Controllers\Account\OrderController; use Beike\Shop\Http\Controllers\ZoneController; use Illuminate\Support\Facades\Route; @@ -40,6 +41,9 @@ Route::prefix('/') Route::get('register', [RegisterController::class, 'index'])->name('register.index'); Route::post('register', [RegisterController::class, 'store'])->name('register.store'); Route::get('logout', [LogoutController::class, 'index'])->name('logout'); + Route::get('forgotten', [ForgottenController::class, 'index'])->name('forgotten.index'); + Route::post('forgotten/send_code', [ForgottenController::class, 'sendVerifyCode'])->name('forgotten.send_code'); + Route::post('forgotten/password', [ForgottenController::class, 'changePassword'])->name('forgotten.password'); Route::resource('countries.zones', ZoneController::class); Route::middleware('shop_auth:' . Customer::AUTH_GUARD) diff --git a/beike/Shop/Services/AccountService.php b/beike/Shop/Services/AccountService.php index e3893f82..2d2caa4d 100644 --- a/beike/Shop/Services/AccountService.php +++ b/beike/Shop/Services/AccountService.php @@ -12,9 +12,13 @@ namespace Beike\Shop\Services; +use Beike\Libraries\Notification; use Beike\Models\Customer; use Beike\Repositories\CustomerRepo; +use Beike\Repositories\VerifyCodeRepo; +use Illuminate\Support\Carbon; use Illuminate\Support\Facades\Hash; +use Illuminate\Support\Facades\Log; class AccountService { @@ -38,4 +42,54 @@ class AccountService return CustomerRepo::create($data); } + + /** + * 发送验证码通过$type方式,type为email或telephone + * @param $email + * @param $type + * @return void + */ + public static function sendVerifyCodeForForgotten($email, $type) { + $code = str_pad(mt_rand(10, 999999), 6, '0', STR_PAD_LEFT); + + VerifyCodeRepo::create([ + 'account' => $email, + 'code' => $code, + ]); + + Log::info("找回密码验证码:{$code}"); + + Notification::verifyCode($code, "您的验证码是%s,该验证码仅用于找回密码。", $type); + } + + /** + * 验证验证码是否正确,并修改密码为新密码 + * @param $code + * @param $account + * @param $password + * @param $type $account类型,email代表$account为邮箱地址,telephone代表$account为手机号码 + * @return void + */ + public static function verifyAndChangePassword($code, $account, $password, $type = 'email') + { + $verifyCode = VerifyCodeRepo::findByAccount($account); + if ($verifyCode->created_at->addMinutes(10) < Carbon::now()) { + $verifyCode->delete(); + throw new \Exception("您的验证码已过期(10分钟),请重新获取"); + } + + if ($verifyCode->code != $code) { + throw new \Exception("您的验证码错误"); + } + + if ($type == 'email') { + $customer = CustomerRepo::findByEmail($account); + } elseif ($type == 'telephone') { + throw new \Exception("暂不支持手机号码找回密码"); + } else { + throw new \Exception("找回密码类型错误"); + } + CustomerRepo::update($customer, ['password' => $password]); + + } } diff --git a/database/migrations/2022_07_07_032305_verify_code.php b/database/migrations/2022_07_07_032305_verify_code.php new file mode 100644 index 00000000..f31aa07c --- /dev/null +++ b/database/migrations/2022_07_07_032305_verify_code.php @@ -0,0 +1,34 @@ +id(); + $table->string('account', 256); + $table->string('code', 16); + $table->softDeletes(); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('verify_codes'); + } +} diff --git a/themes/default/account/account.blade.php b/themes/default/account/account.blade.php index dc07e456..61fc2300 100644 --- a/themes/default/account/account.blade.php +++ b/themes/default/account/account.blade.php @@ -13,7 +13,7 @@