Files
buildadmin-webman/app/api/controller/Account.php
2026-03-09 17:35:53 +08:00

259 lines
9.0 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
namespace app\api\controller;
use ba\Date;
use Throwable;
use ba\Captcha;
use ba\Random;
use app\common\model\User;
use think\facade\Validate;
use app\common\facade\Token;
use app\common\model\UserScoreLog;
use app\common\model\UserMoneyLog;
use app\common\controller\Frontend;
use app\api\validate\Account as AccountValidate;
class Account extends Frontend
{
protected array $noNeedLogin = ['retrievePassword'];
protected array $noNeedPermission = ['verification', 'changeBind'];
public function initialize(): void
{
parent::initialize();
}
public function overview(): void
{
$sevenDays = Date::unixTime('day', -6);
$score = $money = $days = [];
for ($i = 0; $i < 7; $i++) {
$days[$i] = date("Y-m-d", $sevenDays + ($i * 86400));
$tempToday0 = strtotime($days[$i]);
$tempToday24 = strtotime('+1 day', $tempToday0) - 1;
$score[$i] = UserScoreLog::where('user_id', $this->auth->id)
->where('create_time', 'BETWEEN', $tempToday0 . ',' . $tempToday24)
->sum('score');
$userMoneyTemp = UserMoneyLog::where('user_id', $this->auth->id)
->where('create_time', 'BETWEEN', $tempToday0 . ',' . $tempToday24)
->sum('money');
$money[$i] = bcdiv($userMoneyTemp, 100, 2);
}
$this->success('', [
'days' => $days,
'score' => $score,
'money' => $money,
]);
}
/**
* 会员资料
* @throws Throwable
*/
public function profile(): void
{
if ($this->request->isPost()) {
$model = $this->auth->getUser();
$data = $this->request->only(['avatar', 'username', 'nickname', 'gender', 'birthday', 'motto']);
$data['id'] = $this->auth->id;
if (!isset($data['birthday'])) {
$data['birthday'] = null;
}
try {
$validate = new AccountValidate();
$validate->scene('edit')->check($data);
} catch (Throwable $e) {
$this->error($e->getMessage());
}
$model->startTrans();
try {
$model->save($data);
$model->commit();
} catch (Throwable $e) {
$model->rollback();
$this->error($e->getMessage());
}
$this->success(__('Data updated successfully~'));
}
$this->success('', [
'accountVerificationType' => get_account_verification_type()
]);
}
/**
* 通过手机号或邮箱验证账户
* 此处检查的验证码是通过 api/Ems或api/Sms发送的
* 验证成功后,向前端返回一个 email-pass Token或着 mobile-pass Token
* 在 changBind 方法中,通过 pass Token来确定用户已经通过了账户验证用户未绑定邮箱/手机时通过账户密码验证)
* @throws Throwable
*/
public function verification(): void
{
$captcha = new Captcha();
$params = $this->request->only(['type', 'captcha']);
if ($captcha->check($params['captcha'], ($params['type'] == 'email' ? $this->auth->email : $this->auth->mobile) . "user_{$params['type']}_verify")) {
$uuid = Random::uuid();
Token::set($uuid, $params['type'] . '-pass', $this->auth->id, 600);
$this->success('', [
'type' => $params['type'],
'accountVerificationToken' => $uuid,
]);
}
$this->error(__('Please enter the correct verification code'));
}
/**
* 修改绑定信息(手机号、邮箱)
* 通过 pass Token来确定用户已经通过了账户验证也就是以上的 verification 方法,同时用户未绑定邮箱/手机时通过账户密码验证
* @throws Throwable
*/
public function changeBind(): void
{
$captcha = new Captcha();
$params = $this->request->only(['type', 'captcha', 'email', 'mobile', 'accountVerificationToken', 'password']);
$user = $this->auth->getUser();
if ($user[$params['type']]) {
if (!Token::check($params['accountVerificationToken'], $params['type'] . '-pass', $user->id)) {
$this->error(__('You need to verify your account before modifying the binding information'));
}
} elseif (!isset($params['password']) || !verify_password($params['password'], $user->password, ['salt' => $user->salt])) {
$this->error(__('Password error'));
}
// 检查验证码
if ($captcha->check($params['captcha'], $params[$params['type']] . "user_change_{$params['type']}")) {
if ($params['type'] == 'email') {
$validate = Validate::rule(['email' => 'require|email|unique:user'])->message([
'email.require' => 'email format error',
'email.email' => 'email format error',
'email.unique' => 'email is occupied',
]);
if (!$validate->check(['email' => $params['email']])) {
$this->error(__($validate->getError()));
}
$user->email = $params['email'];
} elseif ($params['type'] == 'mobile') {
$validate = Validate::rule(['mobile' => 'require|mobile|unique:user'])->message([
'mobile.require' => 'mobile format error',
'mobile.mobile' => 'mobile format error',
'mobile.unique' => 'mobile is occupied',
]);
if (!$validate->check(['mobile' => $params['mobile']])) {
$this->error(__($validate->getError()));
}
$user->mobile = $params['mobile'];
}
Token::delete($params['accountVerificationToken']);
$user->save();
$this->success();
}
$this->error(__('Please enter the correct verification code'));
}
public function changePassword(): void
{
if ($this->request->isPost()) {
$model = $this->auth->getUser();
$params = $this->request->only(['oldPassword', 'newPassword']);
if (!verify_password($params['oldPassword'], $model->password, ['salt' => $model->salt])) {
$this->error(__('Old password error'));
}
$model->startTrans();
try {
$validate = new AccountValidate();
$validate->scene('changePassword')->check(['password' => $params['newPassword']]);
$model->resetPassword($this->auth->id, $params['newPassword']);
$model->commit();
} catch (Throwable $e) {
$model->rollback();
$this->error($e->getMessage());
}
$this->auth->logout();
$this->success(__('Password has been changed, please login again~'));
}
}
/**
* 积分日志
* @throws Throwable
*/
public function integral(): void
{
$limit = $this->request->request('limit');
$integralModel = new UserScoreLog();
$res = $integralModel->where('user_id', $this->auth->id)
->order('create_time desc')
->paginate($limit);
$this->success('', [
'list' => $res->items(),
'total' => $res->total(),
]);
}
/**
* 余额日志
* @throws Throwable
*/
public function balance(): void
{
$limit = $this->request->request('limit');
$moneyModel = new UserMoneyLog();
$res = $moneyModel->where('user_id', $this->auth->id)
->order('create_time desc')
->paginate($limit);
$this->success('', [
'list' => $res->items(),
'total' => $res->total(),
]);
}
/**
* 找回密码
* @throws Throwable
*/
public function retrievePassword(): void
{
$params = $this->request->only(['type', 'account', 'captcha', 'password']);
try {
$validate = new AccountValidate();
$validate->scene('retrievePassword')->check($params);
} catch (Throwable $e) {
$this->error($e->getMessage());
}
if ($params['type'] == 'email') {
$user = User::where('email', $params['account'])->find();
} else {
$user = User::where('mobile', $params['account'])->find();
}
if (!$user) {
$this->error(__('Account does not exist~'));
}
$captchaObj = new Captcha();
if (!$captchaObj->check($params['captcha'], $params['account'] . 'user_retrieve_pwd')) {
$this->error(__('Please enter the correct verification code'));
}
if ($user->resetPassword($user->id, $params['password'])) {
$this->success(__('Password has been changed~'));
} else {
$this->error(__('Failed to modify password, please try again later~'));
}
}
}