个人中心

This commit is contained in:
zhang zhuo 2025-06-25 18:08:54 +08:00
parent e5c4dd50b4
commit e3951a09d8
14 changed files with 223 additions and 80 deletions

View File

@ -10,19 +10,14 @@ use Psr\Http\Message\ResponseInterface;
abstract class Base extends AbstractController
{
/**
* 账号ID
* @var int
* Author: cfn <cfn@leapy.cn>
*/
public int $account_id = 0;
public array $account = [];
public function __construct()
public function accountId(): int
{
$this->account_id = $this->request->getAttribute("account_id");
$this->account = $this->request->getAttribute("account");
return $this->request->getAttribute("account_id");
}
public function account()
{
return $this->request->getAttribute("account");
}
/**

View File

@ -8,15 +8,18 @@ namespace App\Controller\Admin;
use App\Annotation\Auth;
use App\Event\LogEvent;
use App\Model\Account;
use App\Model\AccountLog;
use App\Utils\Param;
use App\Utils\Str;
use App\Utils\Token;
use Hyperf\Context\ApplicationContext;
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;
#[Controller(prefix: "admin")]
class Login extends Base
@ -93,14 +96,14 @@ class Login extends Base
#[Auth(needAuth: false)]
public function info()
{
return $this->success(Account::getInfo($this->account_id));
return $this->success(Account::getInfo($this->accountId()));
}
#[GetMapping(path: "menu")]
#[Auth(needAuth: false)]
public function menu()
{
return $this->success(Account::getMenu($this->account));
return $this->success(Account::getMenu($this->account()));
}
#[GetMapping(path: "logout")]
@ -115,7 +118,7 @@ class Login extends Base
public function changePwd()
{
$param = $this->request->all();
$account_id = $this->request->getAttribute("account_id");
$account_id = $this->accountId();
$account = Account::getById($account_id, ['password', 'salt']);
// 验证原密码
if (md5($account['salt'] . $param['old_password']) != $account['password']) {
@ -130,4 +133,81 @@ class Login extends Base
]);
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
]
);
}
}

View File

@ -93,14 +93,14 @@ class System extends Base
public function deptList()
{
$dept_name = $this->request->input("dept_name", "");
return $this->success("菜单列表", dModel::list($this->account['belong_id'], $this->account['account_type'], $dept_name));
return $this->success("菜单列表", dModel::list($this->accountId(), $this->account()['account_type'], $dept_name));
}
#[GetMapping(path: "dept/option")]
#[Auth(needAuth: false)]
public function deptOption()
{
return $this->success("菜单列表", dModel::options($this->account['belong_id'], $this->account['account_type']));
return $this->success("菜单列表", dModel::options($this->account()['belong_id'], $this->account()['account_type']));
}
#[PostMapping(path: "dept/add")]
@ -110,8 +110,8 @@ class System extends Base
$request = $this->container->get(dRequest::class);
$request->scene('add')->validateResolved();
$data = Param::only(['dept_name' => '', 'pid' => 0, 'rank', 'status' => 1]);
$data['belong_id'] = $this->account['belong_id'];
$data['account_type'] = $this->account['account_type'];
$data['belong_id'] = $this->account()['belong_id'];
$data['account_type'] = $this->account()['account_type'];
$res = dModel::add($data);
return $res ? $this->success("操作成功") : $this->error("操作失败");
}
@ -143,7 +143,7 @@ class System extends Base
public function roleList()
{
$role_name = $this->request->input("role_name", "");
return $this->success("菜单列表", rModel::list($this->account['belong_id'], $this->account['account_type'], $role_name));
return $this->success("菜单列表", rModel::list($this->account()['belong_id'], $this->account()['account_type'], $role_name));
}
// 角色选择
@ -151,7 +151,7 @@ class System extends Base
#[Auth(needAuth: false)]
public function roleOption()
{
return $this->success("菜单列表", rModel::options($this->account['belong_id'], $this->account['account_type']));
return $this->success("菜单列表", rModel::options($this->account()['belong_id'], $this->account()['account_type']));
}
// 添加角色
@ -162,8 +162,8 @@ class System extends Base
$request = $this->container->get(rRequest::class);
$request->scene('add')->validateResolved();
$data = Param::only(['role_name' => '', 'menus' => [], 'status' => 1, 'rank', "checked_menus"]);
$data['belong_id'] = $this->account['belong_id'];
$data['account_type'] = $this->account['account_type'];
$data['belong_id'] = $this->account()['belong_id'];
$data['account_type'] = $this->account()['account_type'];
$res = rModel::add($data);
return $res ? $this->success("操作成功") : $this->error("操作失败");
}
@ -196,14 +196,14 @@ class System extends Base
public function postList()
{
$post_name = $this->request->input("post_name", "");
return $this->success("岗位列表", pModel::list($this->account['belong_id'], $this->account['account_type'], $post_name));
return $this->success("岗位列表", pModel::list($this->account()['belong_id'], $this->account()['account_type'], $post_name));
}
#[GetMapping(path: "post/option")]
#[Auth(needAuth: false)]
public function postOption()
{
return $this->success("岗位列表", pModel::options($this->account['belong_id'], $this->account['account_type']));
return $this->success("岗位列表", pModel::options($this->account()['belong_id'], $this->account()['account_type']));
}
#[PostMapping(path: "post/add")]
@ -213,8 +213,8 @@ class System extends Base
$request = $this->container->get(pRequest::class);
$request->scene('add')->validateResolved();
$data = Param::only(['post_name' => '', 'rank', 'status' => 1]);
$data['belong_id'] = $this->account['belong_id'];
$data['account_type'] = $this->account['account_type'];
$data['belong_id'] = $this->account()['belong_id'];
$data['account_type'] = $this->account()['account_type'];
$res = pModel::add($data);
return $res ? $this->success("操作成功") : $this->error("操作失败");
}

View File

@ -60,16 +60,23 @@ class Account extends Model
{
$info = self::with('roles')
->with('posts')
->with('dept')
->select(['account_id', 'username', 'nickname', 'avatar', 'bio', 'tags', 'sex', 'birthday', 'create_time'])
->select(['account_id', 'username', 'nickname', 'avatar', 'bio', 'tags', 'sex', 'birthday', 'create_time', 'dept_id'])
->find($account_id);
return $info->toArray();
if ($info) {
$info = $info->toArray();
// 获取所有上级
$dept = [];
Dept::getTop($info['dept_id'], $dept);
$info['dept'] = array_reverse(array_column($dept,"dept_name"));
}
return $info;
}
public static function getMenu(array $account)
{
// 总后台账号
$field = ['title', 'path', 'pid', 'name', 'menu_id', 'icon', 'hidden'];
$field = ['m.title', 'm.path', 'm.pid', 'm.name', 'm.menu_id', 'm.icon', 'm.hidden'];
// 获取角色
$roles = match ($account['account_type']) {
1 => ["ADMIN"],
@ -168,7 +175,7 @@ class Account extends Model
if ($data['password']) {
$data['salt'] = Str::randStr(6);
$data['password'] = md5($data['salt'] . $data['password']);
}else{
} else {
unset($data['password']);
unset($data['salt']);
}
@ -182,11 +189,7 @@ class Account extends Model
return false;
}
// 删除之前的
$res1 = AccountRole::where('account_id', $data['account_id'])->delete();
if (!$res1) {
Db::rollBack();
return false;
}
AccountRole::where('account_id', $data['account_id'])->delete();
$account_role = [];
foreach ($roles as $role_id) {
$account_role[] = ['role_id' => $role_id, 'account_id' => $data['account_id']];
@ -199,11 +202,7 @@ class Account extends Model
}
}
// 删除之前的
$res1 = AccountPost::where('account_id', $data['account_id'])->delete();
if (!$res1) {
Db::rollBack();
return false;
}
AccountPost::where('account_id', $data['account_id'])->delete();
$account_post = [];
foreach ($posts as $post_id) {
$account_post[] = ['post_id' => $post_id, 'account_id' => $data['account_id']];

View File

@ -9,20 +9,20 @@ use Hyperf\HttpMessage\Server\Response;
use Hyperf\HttpServer\Contract\RequestInterface;
/**
* @property int $log_id
* @property int $account_type
* @property int $belong_id
* @property int $account_id
* @property string $username
* @property string $title
* @property string $method
* @property string $flag
* @property int $code
* @property string $request
* @property string $response
* @property string $ip
* @property string $ua
* @property string $create_time
* @property int $log_id
* @property int $account_type
* @property int $belong_id
* @property int $account_id
* @property string $username
* @property string $title
* @property string $method
* @property string $flag
* @property int $code
* @property string $request
* @property string $response
* @property string $ip
* @property string $ua
* @property string $create_time
*/
class AccountLog extends Model
{
@ -74,8 +74,19 @@ class AccountLog extends Model
'title' => Menu::getTitleByCache(strtolower($request->getMethod()), $flag, $admin['account_type']),
'method' => strtolower($request->getMethod()),
'code' => $code,
'request' => json_encode($request->all(),JSON_UNESCAPED_UNICODE),
'request' => json_encode($request->all(), JSON_UNESCAPED_UNICODE),
'response' => $content
]);
}
public static function list(array $param)
{
return self::when(isset($param['account_id']) && $param['account_id'], function ($query) use ($param) {
$query->where('account_id', $param['account_id']);
})->when(isset($param['flag']) && $param['flag'], function ($query) use ($param) {
$query->where('flag', $param['flag']);
})->select(['log_id', 'username', 'title', 'method', 'flag', 'code', 'ip', 'ua', 'create_time'])
->orderByDesc("log_id")
->paginate((int)$param['limit']);
}
}

View File

@ -7,8 +7,8 @@ namespace App\Model;
use Hyperf\DbConnection\Db;
/**
* @property int $account_id
* @property int $post_id
* @property int $account_id
* @property int $post_id
*/
class AccountPost extends \Hyperf\Database\Model\Model
{
@ -32,6 +32,6 @@ class AccountPost extends \Hyperf\Database\Model\Model
return Db::table("account_post")
->leftJoin('post', 'post.post_id', '=', 'account_post.post_id')
->where('account_post.account_id', $account_id)
->select(["post.post_id","post.post_name"])->get()->toArray();
->select(["post.post_id", "post.post_name"])->get()->toArray();
}
}

View File

@ -7,8 +7,8 @@ namespace App\Model;
use Hyperf\DbConnection\Db;
/**
* @property int $account_id
* @property int $role_id
* @property int $account_id
* @property int $role_id
*/
class AccountRole extends \Hyperf\Database\Model\Model
{
@ -32,6 +32,6 @@ class AccountRole extends \Hyperf\Database\Model\Model
return Db::table("account_role")
->leftJoin('role', 'role.role_id', '=', 'account_role.role_id')
->where('account_role.account_id', $account_id)
->select(["role.role_id","role.role_name"])->get()->toArray();
->select(["role.role_id", "role.role_name"])->get()->toArray();
}
}

View File

@ -57,10 +57,20 @@ class Dept extends Model
{
return self::where('belong_id', $belong_id)
->where('account_type', $account_type)
->where("status",1)
->where("status", 1)
->orderByDesc("rank")
->select(["dept_id", "pid", "dept_name"])
->get()->toArray();
}
public static function getTop(int $dept_id, array &$depts)
{
$info = self::select(["dept_name", "pid", "dept_id"])->find($dept_id);
if (!empty($info)) {
$depts[] = $info;
if ($info['pid'] != 0) {
self::getTop($info['pid'], $depts);
}
}
}
}

View File

@ -139,9 +139,11 @@ class Menu extends Model
*/
public static function getMenu(int $account_type, array $field = ['*'])
{
return self::where("account_type", $account_type)
->where("type", 0)
->orderByDesc("rank")
return (new self())->setTable('m')
->from("menu as m")
->where("m.account_type", $account_type)
->where("m.type", 0)
->orderByDesc("m.rank")
->select($field)
->get()
->toArray();

8
config/autoload/app.php Normal file
View File

@ -0,0 +1,8 @@
<?php
/**
* Author: cfn <cfn@leapy.cn>
*/
return [
// 域名
'domain' => 'https://server.leapy.cn/'
];

17
config/autoload/file.php Normal file
View File

@ -0,0 +1,17 @@
<?php
declare(strict_types=1);
use Hyperf\Filesystem\Adapter\CosAdapterFactory;
use Hyperf\Filesystem\Adapter\LocalAdapterFactory;
return [
'default' => 'local',
'storage' => [
'local' => [
'driver' => LocalAdapterFactory::class,
'root' => BASE_PATH . '/runtime',
],
],
];

View File

@ -1,21 +1,14 @@
<?php
declare(strict_types=1);
/**
* This file is part of Hyperf.
*
* @link https://www.hyperf.io
* @document https://hyperf.wiki
* @contact group@hyperf.io
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
*/
return [
'default' => [
'handler' => [
'class' => Monolog\Handler\StreamHandler::class,
'class' => Monolog\Handler\RotatingFileHandler::class,
'constructor' => [
'stream' => BASE_PATH . '/runtime/logs/hyperf.log',
'level' => Monolog\Logger::DEBUG,
'filename' => BASE_PATH . '/runtime/logs/hyperf.log',
'level' => Monolog\Logger::WARNING,
],
],
'formatter' => [

View File

@ -0,0 +1,27 @@
<?php
declare(strict_types=1);
/**
* This file is part of Hyperf.
*
* @link https://www.hyperf.io
* @document https://hyperf.wiki
* @contact group@hyperf.io
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
*/
use Hyperf\RateLimit\Storage\RedisStorage;
return [
'create' => 1,
'consume' => 1,
'capacity' => 2,
'limitCallback' => [],
'waitTimeout' => 1,
'storage' => [
'class' => RedisStorage::class,
'options' => [
'pool' => 'default',
'expired_time' => 0,
],
],
];

View File

@ -41,8 +41,9 @@ return [
Constant::OPTION_MAX_REQUEST => 100000,
Constant::OPTION_SOCKET_BUFFER_SIZE => 2 * 1024 * 1024,
Constant::OPTION_BUFFER_OUTPUT_SIZE => 2 * 1024 * 1024,
// 将 public 替换为上传目录
'document_root' => BASE_PATH . '/public',
Constant::OPTION_PACKAGE_MAX_LENGTH => 50 * 1024 * 1024,
'document_root' => BASE_PATH . '/runtime',
'enable_static_handler' => true,
],
'callbacks' => [