From befa4d898d8db17aaedd3184918d9b57604f60cb Mon Sep 17 00:00:00 2001 From: zhang zhuo Date: Mon, 23 Jun 2025 13:37:09 +0800 Subject: [PATCH] =?UTF-8?q?=E8=8F=9C=E5=8D=95=E7=AE=A1=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/Controller/Admin/Login.php | 28 +++++++ app/Controller/Admin/System.php | 126 ++++++++++++++++++++++++++++++++ app/Model/Account.php | 10 ++- app/Model/Menu.php | 54 ++++++++------ app/Model/Model.php | 11 +++ app/Request/Menu.php | 47 ++++++++++++ app/Utils/Crud.php | 25 +++++++ app/Utils/Str.php | 17 +++++ 8 files changed, 294 insertions(+), 24 deletions(-) create mode 100644 app/Controller/Admin/System.php create mode 100644 app/Request/Menu.php create mode 100644 app/Utils/Crud.php diff --git a/app/Controller/Admin/Login.php b/app/Controller/Admin/Login.php index fd1cbd4..9f000af 100644 --- a/app/Controller/Admin/Login.php +++ b/app/Controller/Admin/Login.php @@ -102,4 +102,32 @@ class Login extends Base { return $this->success(Account::getMenu($this->account)); } + + #[GetMapping(path: "logout")] + #[Auth(needAuth: false)] + public function logout() + { + return $this->success("登出成功"); + } + + #[PostMapping(path: "change/pwd")] + #[Auth(needAuth: false)] + public function changePwd() + { + $param = $this->request->all(); + $account_id = $this->request->getAttribute("account_id"); + $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("修改失败"); + } } \ No newline at end of file diff --git a/app/Controller/Admin/System.php b/app/Controller/Admin/System.php new file mode 100644 index 0000000..a020a75 --- /dev/null +++ b/app/Controller/Admin/System.php @@ -0,0 +1,126 @@ + + */ + +namespace App\Controller\Admin; + +use App\Annotation\Auth; +use App\Model\Menu as mModel; +use App\Utils\Param; +use Hyperf\HttpServer\Annotation\Controller; +use Hyperf\HttpServer\Annotation\DeleteMapping; +use Hyperf\HttpServer\Annotation\GetMapping; +use Hyperf\HttpServer\Annotation\PostMapping; +use Hyperf\HttpServer\Annotation\PutMapping; +use App\Request\Menu as mRequest; + +#[Controller(prefix: "admin")] +class System extends Base +{ + #[GetMapping(path: "menu/list")] + #[Auth(needAuth: false, auth: "menu:list")] + public function menuList() + { + return $this->success("菜单列表", mModel::getMenus(1)); + } + + #[GetMapping(path: "menu/option")] + #[Auth(needAuth: false, auth: "menu:option")] + public function menuOption() + { + // 菜单类型 + return $this->success("菜单列表", mModel::getMenus(1)); + } + + #[PostMapping(path: "menu/add")] + #[Auth(needAuth: false, auth: "menu:add")] + public function menuAdd() + { + $data = Param::only(['pid' => 0, 'title' => '', 'account_type' => 1, 'type' => 0, 'method', 'flag', 'name', + 'path', 'icon', 'rank', 'hidden', 'remark' + ], $this->request->post()); + $request = $this->container->get(mRequest::class); + $request->scene('add')->validateResolved(); + $id = mModel::add($data); + return $id ? $this->success("操作成功", ['menu_id' => $id]) : $this->error("操作失败"); + } + + #[PutMapping(path: "menu/edit")] + #[Auth(needAuth: false, auth: "menu:edit")] + public function menuEdit() + { + $data = Param::only(['pid' => 0, 'title' => '', 'account_type' => 1, 'type' => 0, 'method', 'flag', 'name', + 'path', 'icon', 'rank', 'hidden', 'remark', 'menu_id' => 0 + ], $this->request->post()); + $request = $this->container->get(mRequest::class); + $request->scene('edit')->validateResolved(); + $res = mModel::edit($data); + return $res ? $this->success("操作成功") : $this->error("操作失败"); + } + + #[DeleteMapping(path: "menu/del")] + #[Auth(needAuth: false, auth: "menu:del")] + public function menuDel() + { + $menu_id = $this->request->input("menu_id", ""); + if (!$menu_id) return $this->error("请选择要删除的菜单"); + $res = mModel::del($menu_id); + return $res ? $this->success("操作成功") : $this->error("操作失败"); + } + + #[GetMapping(path: "dept/index")] + #[Auth(auth: "dept:index")] + public function deptIndex(): ResponseInterface + { + // 获取当前账号归属 + $account = $this->request->getAttribute("account"); + $dept_name = $this->request->input("dept_name", ""); + return $this->success("菜单列表", Dept::depts($account['belong_id'], $account['account_type'], $dept_name)); + } + + #[GetMapping(path: "dept/option")] + #[Auth(needAuth: false)] + public function deptOption(): ResponseInterface + { + // 获取当前账号归属 + $account = $this->request->getAttribute("account"); + return $this->success("菜单列表", Dept::options($account['belong_id'], $account['account_type'])); + } + + #[PostMapping(path: "dept/add")] + #[Auth(auth: "dept:add")] + public function deptAdd() + { + $request = $this->container->get(DeptRequest::class); + $request->scene('add')->validateResolved(); + $data = Com::only(['dept_name' => '', 'parent_id' => 0, 'rank', 'remark', 'status' => 1], $this->request->post()); + $account = $this->request->getAttribute("account"); + $data['belong_id'] = $account['belong_id']; + $data['belong'] = $account['account_type']; + $res = dModel::add($data); + return $res ? $this->success("操作成功") : $this->error("操作失败"); + } + + #[PutMapping(path: "dept/edit")] + #[Auth(auth: "dept:edit")] + public function deptEdit() + { + $request = $this->container->get(DeptRequest::class); + $request->scene('edit')->validateResolved(); + $data = Com::only(['dept_id' => '', 'dept_name' => '', 'parent_id' => 0, 'rank', 'remark', 'status' => 1], $this->request->post()); + $res = dModel::edit($data); + return $res ? $this->success("操作成功") : $this->error("操作失败"); + } + + #[DeleteMapping(path: "dept/del")] + #[Auth(auth: "dept:del")] + public function deptDel() + { + $dept_id = $this->request->input("dept_id", ""); + if (!$dept_id) return $this->error("请选择要删除的菜单"); + $res = dModel::del($dept_id); + return $res ? $this->success("操作成功") : $this->error("操作失败"); + } + +} \ No newline at end of file diff --git a/app/Model/Account.php b/app/Model/Account.php index 256b813..1116ea2 100644 --- a/app/Model/Account.php +++ b/app/Model/Account.php @@ -63,10 +63,18 @@ class Account extends Model return $info->toArray(); } + public static function getById(int $account_id, array $field = ['*']): array + { + $info = self::where("account_id", $account_id) + ->select($field) + ->first(); + return $info->toArray(); + } + public static function getMenu(array $account) { // 总后台账号 - $field = ['m.title', 'm.path', 'm.parent_id', 'm.name', 'm.menu_id', 'm.icon', 'm.hidden']; + $field = ['title', 'path', 'pid', 'name', 'menu_id', 'icon', 'hidden']; // 获取角色 $roles = match ($account['account_type']) { 1 => ["ADMIN"], diff --git a/app/Model/Menu.php b/app/Model/Menu.php index cf75ace..2b48a9d 100644 --- a/app/Model/Menu.php +++ b/app/Model/Menu.php @@ -32,6 +32,8 @@ class Menu extends Model */ protected ?string $table = 'menu'; + protected string $primaryKey = "menu_id"; + /** * The attributes that are mass assignable. */ @@ -82,28 +84,27 @@ class Menu extends Model * Author: cfn * @param $method * @param $flag - * @param $belong + * @param $account_type * @return string */ - public static function getTitleByCache($method, $flag, $belong) + public static function getTitleByCache($method, $flag, $account_type) { // 先从缓存取数据,缓存中没则从数据库中取数据 $container = ApplicationContext::getContainer(); $redis = $container->get(\Hyperf\Redis\Redis::class); - $menus = $redis->get("AUTH:" . $belong); + $menus = $redis->get("AUTH:" . $account_type); if (!empty($menus) && isset($menus[$method . ":" . $flag])) { // 存在则从缓存中读取 return $menus[$method . ":" . $flag]; } else { - $title = self::where('del_flag', 0) - ->where('type', 2) + $title = self::where('type', 2) ->where('method', $method) ->where('flag', $flag) - ->where('belong', $belong) + ->where('account_type', $account_type) ->value("title"); if ($title) { // 代表缓存数据已过期需更新 - self::setCache($belong); + self::setCache($account_type); return $title; } return "未知操作"; @@ -112,14 +113,13 @@ class Menu extends Model /** * Author: cfn - * @param $belong + * @param $account_type * @return bool|\Redis */ - private static function setCache($belong) + private static function setCache($account_type) { - $arr = self::where('del_flag', 0) - ->where('type', 2) - ->where('belong', $belong) + $arr = self::where('type', 2) + ->where('account_type', $account_type) ->select(["title", "concat(method,':',flag) as flag"]); // 数组形式转换 $newArr = []; @@ -128,7 +128,7 @@ class Menu extends Model } $container = ApplicationContext::getContainer(); $redis = $container->get(\Hyperf\Redis\Redis::class); - return $redis->set("AUTH:" . $belong, json_encode($newArr), 72 * 60 * 60); + return $redis->set("AUTH:" . $account_type, json_encode($newArr), 72 * 60 * 60); } /** @@ -139,10 +139,9 @@ class Menu extends Model */ public static function getMenu(int $account_type, array $field = ['*']) { - return self::from("menu as m") - ->where("m.belong", $account_type) - ->where("m.type", 0) - ->orderByDesc("m.rank") + return self::where("account_type", $account_type) + ->where("type", 0) + ->orderByDesc("rank") ->select($field) ->get() ->toArray(); @@ -155,11 +154,10 @@ class Menu extends Model */ public static function getButton(int $account_type) { - return self::from("menu as m") - ->where("m.belong", $account_type) - ->where("m.type", 1) - ->orderByDesc("m.rank") - ->pluck('m.flag') + return self::where("account_type", $account_type) + ->where("type", 1) + ->orderByDesc("rank") + ->pluck('flag') ->toArray(); } @@ -178,7 +176,7 @@ class Menu extends Model ->where("ar.account_id", $account_id) ->where("m.account_type", $account_type) ->where("m.type", 0) - ->orderByDesc("rank") + ->orderByDesc("m.rank") ->select($field) ->get() ->toArray(); @@ -201,4 +199,14 @@ class Menu extends Model ->pluck('m.flag') ->toArray(); } + + public static function getMenus(int $account_type) + { + return self::where('account_type', $account_type) + ->orderByDesc("rank") + ->select(["menu_id", "title", "flag", "pid", "type", "method", "name", "path", "icon", "rank", "hidden", "account_type"]) + ->groupBy(["menu_id"]) + ->get() + ->toArray(); + } } diff --git a/app/Model/Model.php b/app/Model/Model.php index eb1327b..5958844 100644 --- a/app/Model/Model.php +++ b/app/Model/Model.php @@ -12,10 +12,21 @@ declare(strict_types=1); namespace App\Model; +use App\Utils\Crud; use Hyperf\Database\Model\SoftDeletes; use Hyperf\DbConnection\Model\Model as BaseModel; abstract class Model extends BaseModel { + public const CREATED_AT = 'create_time'; + + /** + * The name of the "updated at" column. + * + * @var null|string + */ + public const UPDATED_AT = 'update_time'; + use SoftDeletes; + use Crud; } diff --git a/app/Request/Menu.php b/app/Request/Menu.php new file mode 100644 index 0000000..4a93bc5 --- /dev/null +++ b/app/Request/Menu.php @@ -0,0 +1,47 @@ + + */ + +namespace App\Request; + +use Hyperf\Validation\Request\FormRequest; + +class Menu extends FormRequest +{ + protected array $scenes = [ + 'add' => ['pid', 'title', 'type'], + 'edit' => ['pid', 'title', 'type','menu_id'], + ]; + + /** + * Determine if the user is authorized to make this request. + */ + public function authorize(): bool + { + return true; + } + + /** + * Get the validation rules that apply to the request. + */ + public function rules(): array + { + return [ + 'menu_id' => 'required', + 'pid' => 'required', + 'title' => 'required', + 'type' => 'required' + ]; + } + + public function messages(): array + { + return [ + 'menu_id.required' => '菜单ID必填!', + 'pid.required' => '上级ID必选!', + 'title.required' => '菜单名称必填!', + 'type.required' => '菜单类型必填!' + ]; + } +} \ No newline at end of file diff --git a/app/Utils/Crud.php b/app/Utils/Crud.php new file mode 100644 index 0000000..33ee721 --- /dev/null +++ b/app/Utils/Crud.php @@ -0,0 +1,25 @@ + + */ + +namespace App\Utils; + +trait Crud +{ + public static function add(array $data) + { + $data['create_time'] = date("Y-m-d H:i:s"); + return self::insertGetId($data); + } + + public static function edit(array $data) + { + return self::where("menu_id", $data['menu_id'])->update($data); + } + + public static function del(string $ids): int + { + return self::destroy(explode(",", $ids)); + } +} \ No newline at end of file diff --git a/app/Utils/Str.php b/app/Utils/Str.php index 14a1bfc..0c590ce 100644 --- a/app/Utils/Str.php +++ b/app/Utils/Str.php @@ -23,4 +23,21 @@ class Str return $prefix . $uuid; } + /** + * 获取随机字符串 + * @param int $num + * @param string $prefix + * @return string + */ + static function randStr(int $num, string $prefix = ""): string + { + $str = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"; + $_str = ""; + while ($num > 0) { + $_str .= substr($str, rand(0, strlen($str) - 1), 1); + $num--; + } + return $prefix . $_str; + } + } \ No newline at end of file