From e3951a09d87374925a88a87a668146ff530a2e96 Mon Sep 17 00:00:00 2001 From: zhang zhuo Date: Wed, 25 Jun 2025 18:08:54 +0800 Subject: [PATCH] =?UTF-8?q?=E4=B8=AA=E4=BA=BA=E4=B8=AD=E5=BF=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/Controller/Admin/Base.php | 19 +++----- app/Controller/Admin/Login.php | 86 +++++++++++++++++++++++++++++++-- app/Controller/Admin/System.php | 24 ++++----- app/Model/Account.php | 29 ++++++----- app/Model/AccountLog.php | 41 ++++++++++------ app/Model/AccountPost.php | 6 +-- app/Model/AccountRole.php | 6 +-- app/Model/Dept.php | 12 ++++- app/Model/Menu.php | 8 +-- config/autoload/app.php | 8 +++ config/autoload/file.php | 17 +++++++ config/autoload/logger.php | 15 ++---- config/autoload/rate_limit.php | 27 +++++++++++ config/autoload/server.php | 5 +- 14 files changed, 223 insertions(+), 80 deletions(-) create mode 100644 config/autoload/app.php create mode 100644 config/autoload/file.php create mode 100644 config/autoload/rate_limit.php diff --git a/app/Controller/Admin/Base.php b/app/Controller/Admin/Base.php index 6d0083b..15d6c69 100644 --- a/app/Controller/Admin/Base.php +++ b/app/Controller/Admin/Base.php @@ -10,19 +10,14 @@ use Psr\Http\Message\ResponseInterface; abstract class Base extends AbstractController { - /** - * 账号ID - * @var int - * Author: cfn - */ - 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"); } /** diff --git a/app/Controller/Admin/Login.php b/app/Controller/Admin/Login.php index 9f000af..71ed947 100644 --- a/app/Controller/Admin/Login.php +++ b/app/Controller/Admin/Login.php @@ -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 + ] + ); + } } \ No newline at end of file diff --git a/app/Controller/Admin/System.php b/app/Controller/Admin/System.php index ea59e0a..b1e9e67 100644 --- a/app/Controller/Admin/System.php +++ b/app/Controller/Admin/System.php @@ -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("操作失败"); } diff --git a/app/Model/Account.php b/app/Model/Account.php index 109f5bc..1b74dbe 100644 --- a/app/Model/Account.php +++ b/app/Model/Account.php @@ -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']]; diff --git a/app/Model/AccountLog.php b/app/Model/AccountLog.php index 3d64049..d46788d 100644 --- a/app/Model/AccountLog.php +++ b/app/Model/AccountLog.php @@ -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']); + } } diff --git a/app/Model/AccountPost.php b/app/Model/AccountPost.php index 368b273..a3484b7 100644 --- a/app/Model/AccountPost.php +++ b/app/Model/AccountPost.php @@ -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(); } } diff --git a/app/Model/AccountRole.php b/app/Model/AccountRole.php index 4d34440..73c9bf6 100644 --- a/app/Model/AccountRole.php +++ b/app/Model/AccountRole.php @@ -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(); } } diff --git a/app/Model/Dept.php b/app/Model/Dept.php index 41f8abf..6617308 100644 --- a/app/Model/Dept.php +++ b/app/Model/Dept.php @@ -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); + } + } + } } diff --git a/app/Model/Menu.php b/app/Model/Menu.php index 14b5136..46cd73d 100644 --- a/app/Model/Menu.php +++ b/app/Model/Menu.php @@ -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(); diff --git a/config/autoload/app.php b/config/autoload/app.php new file mode 100644 index 0000000..4610b37 --- /dev/null +++ b/config/autoload/app.php @@ -0,0 +1,8 @@ + + */ +return [ + // 域名 + 'domain' => 'https://server.leapy.cn/' +]; \ No newline at end of file diff --git a/config/autoload/file.php b/config/autoload/file.php new file mode 100644 index 0000000..3d4a8d5 --- /dev/null +++ b/config/autoload/file.php @@ -0,0 +1,17 @@ + 'local', + 'storage' => [ + 'local' => [ + 'driver' => LocalAdapterFactory::class, + 'root' => BASE_PATH . '/runtime', + ], + ], +]; diff --git a/config/autoload/logger.php b/config/autoload/logger.php index ee4691f..11ec4af 100644 --- a/config/autoload/logger.php +++ b/config/autoload/logger.php @@ -1,21 +1,14 @@ [ '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' => [ diff --git a/config/autoload/rate_limit.php b/config/autoload/rate_limit.php new file mode 100644 index 0000000..78f8c57 --- /dev/null +++ b/config/autoload/rate_limit.php @@ -0,0 +1,27 @@ + 1, + 'consume' => 1, + 'capacity' => 2, + 'limitCallback' => [], + 'waitTimeout' => 1, + 'storage' => [ + 'class' => RedisStorage::class, + 'options' => [ + 'pool' => 'default', + 'expired_time' => 0, + ], + ], +]; diff --git a/config/autoload/server.php b/config/autoload/server.php index e82f196..4b348da 100644 --- a/config/autoload/server.php +++ b/config/autoload/server.php @@ -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' => [