| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355 |
- <?php
- namespace App\Service;
- use App\Model\Employee;
- use App\Model\RoleMenu;
- use App\Model\RoleMenuButton;
- use App\Model\SysMenu;
- use App\Model\SysMenuButton;
- use Illuminate\Support\Facades\DB;
- class SysMenuService extends Service
- {
- public function edit($data){
- list($status,$msg) = $this->menuRule($data,false);
- if(! $status) return [$status, $msg];
- $del_button_id = $msg;
- DB::beginTransaction();
- try{
- $model = SysMenu::where('id',$data['id'])->first();
- $model->title = $data['title'];
- $model->icon = $data['icon'] ?? '';
- $model->uri = $data['uri'];
- $model->parent_id = $data['parent_id'];
- $model->sort = $data['sort'] ?? 0;
- $model->save();
- $time = time();
- //按钮
- $this->saveDetail($model->id, time(), $data);
- if(! empty($del_button_id)){
- SysMenuButton::where('del_time',0)
- ->whereIn('id',$del_button_id)
- ->update(['del_time' => $time]);
- RoleMenuButton::where('del_time',0)
- ->whereIn('button_id', $del_button_id)
- ->update(['del_time' => $time]);
- }
- DB::commit();
- }catch (\Exception $exception){
- DB::rollBack();
- return [false,$exception->getMessage()];
- }
- return [true,''];
- }
- public function add($data,$user){
- list($status,$msg) = $this->menuRule($data);
- if(! $status) return [$status,$msg];
- DB::beginTransaction();
- try{
- $model = new SysMenu();
- $sort = $model->where('parent_id',$data['parent_id'])->max('sort');
- $model->title = $data['title'];
- $model->icon = $data['icon'] ?? '';
- $model->uri = $data['uri'];
- $model->parent_id = $data['parent_id'];
- $model->sort = $sort ? $sort + 1 : 1;
- $model->crt_id = $user['id'];
- $model->save();
- //按钮
- $this->saveDetail($model->id, time(), $data);
- DB::commit();
- }catch (\Exception $exception){
- DB::rollBack();
- return [false,$exception->getMessage()];
- }
- return [true,''];
- }
- private function saveDetail($id, $time, $data){
- if (! empty($data['button'])) {
- $toUpdate = [];
- $toInsert = [];
- foreach ($data['button'] as $key => $value) {
- $row = [
- 'menu_id' => $id,
- 'title' => $value['title'],
- 'sort' => $key,
- 'func' => $value['func'],
- ];
- if (!empty($value['id'])) {
- $row['id'] = $value['id'];
- $toUpdate[] = $row;
- } else {
- $row['crt_time'] = $time;
- $toInsert[] = $row;
- }
- }
- // 1. 批量插入
- if (! empty($toInsert)) SysMenuButton::insert($toInsert);
- // 2. 批量更新
- if(! empty($toUpdate)){
- foreach ($toUpdate as $updateRow) {
- $id = $updateRow['id'];
- unset($updateRow['id']);
- SysMenuButton::where('id', $id)->update($updateRow);
- }
- }
- }
- }
- public function del($data){
- if($this->isEmpty($data,'id')) return [false,'菜单ID不能为空'];
- DB::beginTransaction();
- try {
- $time = time();
- SysMenu::where('id',$data['id'])->update([
- 'del_time' => $time
- ]);
- SysMenuButton::where('del_time',0)->where('menu_id',$data['id'])->update([
- 'del_time' => $time
- ]);
- RoleMenu::where('del_time',0)->where('menu_id',$data['id'])->update([
- 'del_time' => $time
- ]);
- RoleMenuButton::where('del_time',0)->where('menu_id',$data['id'])->update([
- 'del_time' => $time
- ]);
- DB::commit();
- }catch (\Exception $exception){
- DB::rollBack();
- return [false,$exception->getMessage()];
- }
- return [true,''];
- }
- public function menuList($data, $user){
- $return = [];
- $type = $data['type'] ?? "";
- $tree_type = $data['tree_type'] ?? SysMenu::tree_type_zero;
- $sysList = SysMenu::where('del_time',0)
- ->where('type', SysMenu::type_zero)
- ->where('tree_type', $tree_type)
- ->select('title','icon','uri','parent_id','sort','id','is_authority', 'state')
- ->orderBy('sort','desc')
- ->get()
- ->toArray();
- $button = SysMenuButton::where('del_time',0)
- ->select('id','title','sort','func','menu_id')
- ->get()->toArray();
- if(empty($type)){
- $return = $this->fillMenuButton($button,$sysList, $user);
- }elseif($type == "all"){
- $return_one = $this->fillMenuButton($button, $sysList, $user);
- $return_two = $this->returnTwo($sysList, $user);
- $return_three = $this->fillMenuButton($button, $sysList, $user,2);
- $return = [
- 'one' => $return_one,
- 'two' => $return_two,
- 'three' => $return_three,
- ];
- }
- return [true, $return];
- }
- public function menuRule($data, $is_check = true){
- if($this->isEmpty($data,'title')) return [false,'名称不能为空!'];
- if($this->isEmpty($data,'parent_id')) return [false,'父级不存在!'];
- //菜单
- if($is_check){
- $bool = SysMenu::where('title',$data['title'])
- ->where('del_time',0)
- ->exists();
- }else{
- if($this->isEmpty($data,'id')) return [false,'ID不能为空!'];
- $bool = SysMenu::where('title',$data['title'])
- ->where('id','<>',$data['id'])
- ->where('del_time',0)
- ->exists();
- $menu_button = SysMenuButton::where('del_time',0)
- ->where('menu_id',$data['id'])
- ->pluck('id')->all();
- }
- if($bool) return [false,'菜单名称已经存在'];
- //按钮
- if(! empty($data['button'])){
- $title = array_column($data['button'],'title');
- $title = array_map(function($val) {
- return $val !== null ? $val : "";
- }, $title);
- $title_count = array_count_values($title);
- foreach ($title as $value){
- if(empty($value)) return [false,'按钮名称不能为空!'];
- if($title_count[$value] > 1) return [false,'按钮名称不能重复'];
- }
- }
- $del = [];
- if(! empty($menu_button)){
- $submit = array_column($data['button'],'id');
- foreach ($menu_button as $value){
- if(! in_array($value, $submit)) $del[] = $value;
- }
- }
- return [true, $del];
- }
- public function menuMove($data){
- if($this->isEmpty($data,'id')) return [false,'ID不能为空!'];
- if($this->isEmpty($data,'move')) return [false,'移动不能能为空!'];
- //移动项
- $model = new SysMenu();
- $res = $model->where('id', $data['id'])->first();
- if($data['move'] == 1 || $data['move'] == -1){
- //替项目
- $moveModel = $model->where('del_time',0)->where('parent_id',$res->parent_id);
- //下移-1 上移1
- $data['move'] == 1 ? $moveModel->orderby('sort','desc')->where('sort','<', $res['sort']) : $moveModel->orderby('sort','asc')->where('sort','>', $res['sort']);
- $moveRes = $moveModel->first();
- if(! $moveRes) return [false, '移动失败'];
- $weightOne = $res->sort;
- $weightTwo = $moveRes->sort;
- $res->sort = $weightTwo;
- $res->save();
- $moveRes->sort = $weightOne;
- $moveRes->save();
- }elseif($data['move'] == 'top' || $data['move'] == 'bottom'){
- if($data['move'] == 'top'){
- $sort = $model->where('del_time',0)->where('parent_id',$res->parent_id)->max('sort');
- if($sort == $res->sort) return [false,'已经置顶,移动失败!'];
- $res->sort = $sort + 1;
- }elseif($data['move'] == 'bottom'){
- $sort = $model->where('del_time',0)->where('parent_id',$res->parent_id)->min('sort');
- if($sort == $res->sort) return [false,'已经置底部,移动失败!'];
- $res->sort = $sort - 1;
- }
- $res->save();
- }else{
- return [false, '异常参数'];
- }
- return [true,''];
- }
- public function fillMenuButton($button, $menu, $user, $type = 1)
- {
- // 1. 预处理所有按钮池(合并配置中的特殊按钮)
- $allButtons = collect($button)->concat(config('specialButton') ?? [])->groupBy('menu_id');
- // 2. 获取权限基础数据(如果是超管,这两个值为空,逻辑依然兼容)
- $isSuper = ($user['is_admin'] == Employee::IS_ADMIN_TWO);
- $roleButtons = $isSuper ? [] : (new EmployeeService())->fillRoleButton($user['role_ids'] ?? []);
- $allowedMenuIds = $isSuper ? [] : $this->getMenuIDByRoleInList($user);
- $result = [];
- foreach ($menu as $m) {
- $menuId = $m['id'];
- // 权限过滤:非超管且不在权限内,跳过
- if (!$isSuper && !in_array($menuId, $allowedMenuIds)) continue;
- // 计算当前菜单拥有的按钮
- if ($isSuper) {
- $btns = $allButtons->get($menuId) ?? [];
- } else {
- // 取交集:只返回该角色拥有的按钮数据
- $myBtnIds = $roleButtons[$menuId] ?? [];
- $btnPool = collect($allButtons->get($menuId))->keyBy('id');
- $btns = collect($myBtnIds)->map(fn($id) => $btnPool->get($id))->filter()->values();
- }
- // 3. 根据 type 返回不同的数据结构
- if ($type == 1) {
- // 完整模式:保留原菜单所有字段
- $m['button'] = $btns;
- $result[] = $m;
- } else {
- // 精简模式:只给前端路由用的字段
- $result[] = [
- 'id' => $menuId,
- 'uri' => $m['uri'] ?? '',
- 'button' => $btns,
- ];
- }
- }
- return $result;
- }
- private function returnTwo($sysList, $user){
- //人员所拥有的菜单
- $menu = $this->getMenuIDByRoleInList($user);
- foreach ($sysList as $key => $value){
- if($value['state'] <= 0) unset($sysList[$key]);
- if($user['is_admin'] != Employee::IS_ADMIN_TWO && ! in_array($value['id'], $menu)) unset($sysList[$key]);
- }
- $list = array_values($sysList);
- $return = $this->makeTree(0,$list);
- return $this->set_sort_circle($return);;
- }
- //通过角色获取菜单ID
- public function getMenuIDByRoleInList($user){
- $role_id = $user['role_ids'] ?? [];
- if(empty($role_id)) return [];
- return RoleMenu::whereIn('role_id', $role_id)
- ->where('del_time',0)
- ->pluck('menu_id')
- ->all();
- }
- public function getMenuDataByRoleInList($user){
- $role_id = $user['role_ids'] ?? [];
- if(empty($role_id)) return [];
- return RoleMenu::whereIn('role_id',$role_id)
- ->where('del_time',0)
- ->select('menu_id','type')
- ->get()->toArray();
- }
- public function getMap($menu_id){
- $menu_id = array_filter((array)$menu_id);
- if (empty($menu_id)) return [];
- return SysMenu::whereIn('id', $menu_id)
- ->pluck('title', 'id')
- ->toArray();
- }
- }
|