package com.xjrsoft.module.system.controller; import cn.dev33.satoken.stp.StpUtil; import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; import com.baomidou.mybatisplus.core.toolkit.StringPool; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.github.yulichang.toolkit.MPJWrappers; import com.jdcloud.sdk.utils.StringUtils; import com.xjrsoft.common.constant.GlobalConstant; import com.xjrsoft.common.enums.*; import com.xjrsoft.common.model.result.R; import com.xjrsoft.common.model.result.RT; import com.xjrsoft.common.utils.TreeUtil; import com.xjrsoft.common.utils.VoToColumnUtil; import com.xjrsoft.module.organization.service.IUserRoleRelationService; import com.xjrsoft.module.system.dto.*; import com.xjrsoft.module.system.entity.*; import com.xjrsoft.module.system.service.*; import com.xjrsoft.module.system.vo.*; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.AllArgsConstructor; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.bind.annotation.*; import javax.validation.Valid; import javax.validation.constraints.NotNull; import java.util.ArrayList; import java.util.List; /** *

* 用户 前端控制器 *

* * @author tzx * @since 2022-03-16 */ @RestController @RequestMapping(GlobalConstant.SYSTEM_MODULE_PREFIX + "/menu") @Api(value = GlobalConstant.SYSTEM_MODULE_PREFIX + "/menu", tags = "菜单模块") @AllArgsConstructor public class MenuController { private final IMenuService menuService; private final IMenuButtonService menuButtonService; private final IMenuColumnService menuColumnService; private final IMenuFormService menuFormService; private final IAuthorizeService authorizeService; private final IUserRoleRelationService userRoleRelationService; @GetMapping("/list") @ApiOperation(value = "获取所有菜单(不分页)") public R list() { List list = menuService.list(Wrappers.lambdaQuery(Menu.class) .select(Menu.class, x -> VoToColumnUtil.fieldsToColumns(MenuListVo.class).contains(x.getProperty()))); List menuListVos = BeanUtil.copyToList(list, MenuListVo.class); return R.ok(TreeUtil.build(menuListVos)); } @GetMapping("/tree") @ApiOperation(value = "获取所有菜单(树结构)") public R menuTree(@Valid MenuTreeDto dto) { List list = menuService.getAuthMenuList(dto); List voList = BeanUtil.copyToList(list, MenuTreeVo.class); List treeVoList = TreeUtil.build(voList); return R.ok(treeVoList); } @GetMapping("/quick") @ApiOperation(value = "用户快捷菜单") public RT> quick(@Valid MenuTreeDto dto) { List menus = menuService.getUserQuick(dto); List menuListVos = BeanUtil.copyToList(menus, MenuVo.class); return RT.ok(menuListVos); } @GetMapping("/role-serve") @ApiOperation(value = "查询角色菜单服务") public RT> roleMenuServe(RoleMenuServeListDto dto) { List list = menuService.getRoleMenuServe(dto); return RT.ok(list); } @GetMapping("/serve") @ApiOperation(value = "获取菜单服务") public RT> menuServe(@Valid MenuTreeDto dto) { List list = menuService.getAuthMenuServe(dto); return RT.ok(list); } @GetMapping("/all-tree") @ApiOperation(value = "获取所有菜单(树结构)") public R allMenuTree(@Valid MenuTreeDto dto) { if (StrUtil.isEmpty(dto.getSystemType())) { dto.setSystemType(SystemTypeEnum.SYSTEMPC.getCode()); } List list = menuService.selectJoinList(MenuTreeVo.class, MPJWrappers.lambdaJoin() .like(StrUtil.isNotEmpty(dto.getTitle()), Menu::getTitle, dto.getTitle()) .like(StrUtil.isNotEmpty(dto.getName()), Menu::getName, dto.getName()) .eq(Menu::getSystemType, dto.getSystemType()) .select(Menu::getId) .select(Menu.class, x -> VoToColumnUtil.fieldsToColumns(MenuTreeVo.class).contains(x.getProperty())) .selectAs(Subsystem::getName, MenuTreeVo::getSystemName) .eq(ObjectUtils.isNotEmpty(dto.getEnabledMark()), Menu::getEnabledMark, dto.getEnabledMark()) .leftJoin(Subsystem.class, Subsystem::getId, Menu::getSystemId) .orderByAsc(Menu::getSortCode)); List treeVoList = TreeUtil.build(list); return R.ok(treeVoList); } @GetMapping("/child-tree") @ApiOperation(value = "获取所有菜单(树结构,禁用父级)") public R menuChildTree(@Valid MenuTreeDto dto) { List list = menuService.getAuthMenuList(dto); List voList = BeanUtil.copyToList(list, MenuChildTreeVo.class); List treeVoList = TreeUtil.build(voList); voList.forEach(treeVo -> treeVo.setFullPath(true)); return R.ok(treeVoList); } @GetMapping("/simple-tree") @ApiOperation(value = "获取所有菜单(树结构)") public R menuAuthTree(@Valid MenuTreeDto dto) { List list = menuService.getAuthMenuList(dto); List voList = BeanUtil.copyToList(list, MenuSimpleTreeVo.class); List treeVoList = TreeUtil.build(voList); return R.ok(treeVoList); } @GetMapping(value = "/info") @ApiOperation(value = "根据id查询菜单信息") public R info(Long id) { Menu menu = menuService.getById(id); if (menu == null) { R.error("找不到此菜单!"); } return R.ok(BeanUtil.toBean(menu, MenuVo.class)); } @PostMapping @ApiOperation(value = "新增菜单") @Transactional(rollbackFor = Exception.class) public R add(@Valid @RequestBody AddMenuDto dto) { long count = menuService.count(Wrappers.query().lambda().eq(Menu::getCode, dto.getCode())); if (count > 0) { return R.error("菜单编码已经存在!"); } Menu menu = BeanUtil.toBean(dto, Menu.class); if (ObjectUtil.isEmpty(menu.getSystemId())) { menu.setSystemId(1L); } //判断是否为菜单 if (menu.getMenuType() == YesOrNoEnum.NO.getCode()) { //如果是菜单 需要判断 path 第一个字符 是否为 / 菜单必须要 / 开头 if (!menu.getPath().startsWith(StringPool.SLASH)) { menu.setPath(StringPool.SLASH + menu.getPath()); } } //判断是否为外链 if (menu.getOutLink() == YesOrNoEnum.YES.getCode()) { //如果是外链 所有组件地址 改为 IFrame menu.setComponent("IFrame"); } menu.setAllowDelete(YesOrNoEnum.YES.getCode()); menu.setAllowModify(YesOrNoEnum.YES.getCode()); boolean isSuccess = menuService.save(menu); //按钮保存 List menuButtons = BeanUtil.copyToList(dto.getButtonList(), MenuButton.class); menuButtons.forEach(menuButton -> menuButton.setMenuId(menu.getId())); //删除原按钮 menuButtonService.remove(Wrappers.query().lambda().eq(MenuButton::getMenuId, menu.getId())); menuButtonService.saveBatch(menuButtons); // 列表字段保存 List columnList = BeanUtil.copyToList(dto.getColumnList(), MenuColumn.class); columnList.forEach(menuColumn -> menuColumn.setMenuId(menu.getId())); menuColumnService.remove(Wrappers.query().lambda().eq(MenuColumn::getMenuId, menu.getId())); menuColumnService.saveBatch(columnList); // 表单字段保存 List formList = new ArrayList<>(); for (AddMenuFormDto addMenuFormDto : dto.getFormList()) { formList.add(BeanUtil.toBean(addMenuFormDto, MenuForm.class)); List children = addMenuFormDto.getChildren(); if (org.apache.commons.collections.CollectionUtils.isNotEmpty(children)) { formList.addAll(BeanUtil.copyToList(children, MenuForm.class)); } } formList.forEach(menuForm -> menuForm.setMenuId(menu.getId())); menuFormService.remove(Wrappers.query().lambda().eq(MenuForm::getMenuId, menu.getId())); menuFormService.saveBatch(formList); return R.ok(isSuccess); } @PutMapping @ApiOperation(value = "修改菜单") @Transactional(rollbackFor = Exception.class) public R edit(@Valid @RequestBody UpdateMenuDto dto) { long count = menuService.count(Wrappers.query().lambda() .ne(Menu::getId, dto.getId()).and(wrapper -> wrapper.eq(Menu::getCode, dto.getCode()) ) ); if (count > 0) { return R.error("菜单编码已经存在!"); } Menu menu = BeanUtil.toBean(dto, Menu.class); //判断是否为菜单 if (menu.getMenuType() == YesOrNoEnum.NO.getCode()) { //如果是菜单 需要判断 path 第一个字符 是否为 / 菜单必须要 / 开头 if (!menu.getPath().startsWith(StringPool.SLASH)) { menu.setPath(StringPool.SLASH + menu.getPath()); } } //判断是否为外链 if (menu.getOutLink() == YesOrNoEnum.YES.getCode()) { //如果是外链 所有组件地址 改为 IFrame menu.setComponent("IFrame"); } menuService.updateById(menu); List menuButtons = BeanUtil.copyToList(dto.getButtonList(), MenuButton.class); menuButtons.forEach(menuButton -> menuButton.setMenuId(menu.getId())); //删除原按钮 menuButtonService.remove(Wrappers.query().lambda().eq(MenuButton::getMenuId, menu.getId())); // 列表字段保存 List columnList = BeanUtil.copyToList(dto.getColumnList(), MenuColumn.class); columnList.forEach(menuColumn -> menuColumn.setMenuId(menu.getId())); menuColumnService.remove(Wrappers.query().lambda().eq(MenuColumn::getMenuId, menu.getId())); // 表单字段保存 List formList = new ArrayList<>(); for (UpdateMenuFormDto updateMenuFormDto : dto.getFormList()) { formList.add(BeanUtil.toBean(updateMenuFormDto, MenuForm.class)); List children = updateMenuFormDto.getChildren(); if (org.apache.commons.collections.CollectionUtils.isNotEmpty(children)) { formList.addAll(BeanUtil.copyToList(children, MenuForm.class)); } } formList.forEach(menuForm -> menuForm.setMenuId(menu.getId())); menuFormService.remove(Wrappers.query().lambda().eq(MenuForm::getMenuId, menu.getId())); if (CollectionUtils.isNotEmpty(menuButtons)) { menuButtonService.saveBatch(menuButtons); } if (CollectionUtils.isNotEmpty(columnList)) { menuColumnService.saveBatch(columnList); } if (CollectionUtils.isNotEmpty(formList)) { menuFormService.saveBatch(formList); } return R.ok(); } @GetMapping(value = "/button") @ApiOperation(value = "根据id查询按钮") public R button(@NotNull @Valid Long id) { List list = menuButtonService.list(Wrappers.query().lambda().eq(MenuButton::getMenuId, id)); return R.ok(list); } @DeleteMapping @ApiOperation(value = "批量删除菜单") public R delete(@Valid @RequestBody List ids) { return R.ok(menuService.removeByIds(ids)); } @GetMapping("/auth-tree") @ApiOperation(value = "获取功能授权页面的菜单树结构") public R fullAuthTree() { List roleIdList = StpUtil.getTokenSession().get(GlobalConstant.LOGIN_USER_ROLE_ID_KEY, new ArrayList<>()); LambdaQueryWrapper queryMenuWrapper = Wrappers.query().lambda().eq(Menu::getEnabledMark, EnabledMark.ENABLED.getCode()); LambdaQueryWrapper queryBtnWrapper = Wrappers.query().lambda(); LambdaQueryWrapper queryColWrapper = Wrappers.query().lambda(); LambdaQueryWrapper queryFormWrapper = Wrappers.query().lambda(); boolean isAdmin = roleIdList.contains(GlobalConstant.SUPER_ADMIN_ROLE_ID); // 不是管理员 if (!isAdmin) { List authorizeList = authorizeService.list(Wrappers.query().lambda() .select(Authorize::getObjectId, Authorize::getAuthorizeType) .in(Authorize::getAuthorizeType, AuthorizeType.MENU.getCode(), AuthorizeType.BUTTON.getCode(), AuthorizeType.COLUMN.getCode(), AuthorizeType.FORM.getCode()) .in(Authorize::getRoleId, roleIdList)); if (CollectionUtils.isEmpty(authorizeList)) { return R.ok(); } List authMenuIdList = new ArrayList<>(); List authMenuBtnIdList = new ArrayList<>(); List authMenuIdColList = new ArrayList<>(); List authMenuIdFormList = new ArrayList<>(); for (Authorize authorize : authorizeList) { Long id = authorize.getId(); switch (authorize.getAuthorizeType()) { case 1: authMenuIdList.add(id); break; case 2: authMenuBtnIdList.add(id); break; case 3: authMenuIdColList.add(id); break; case 4: authMenuIdFormList.add(id); break; default: break; } } queryMenuWrapper.in(Menu::getId, authMenuIdList); queryBtnWrapper.in(MenuButton::getId, authMenuBtnIdList); queryColWrapper.in(MenuColumn::getId, authMenuIdColList); queryFormWrapper.in(MenuForm::getId, authMenuIdFormList); } List menuList = menuService.list(queryMenuWrapper); List menuBtnList = menuButtonService.list(queryBtnWrapper); List menuColList = menuColumnService.list(queryColWrapper); List menuFormList = menuFormService.list(queryFormWrapper); List menuVoList = BeanUtil.copyToList(menuList, MenuListVo.class); AuthMenuVo resultVo = new AuthMenuVo(); //菜单 resultVo.setMenuList(TreeUtil.build(menuVoList)); //按钮 for (MenuButton menuBtn : menuBtnList) { resultVo.addButton(menuBtn.getMenuId(), BeanUtil.toBean(menuBtn, MenuButtonVo.class)); } //列表 for (MenuColumn menuColumn : menuColList) { resultVo.addColumn(menuColumn.getMenuId(), BeanUtil.toBean(menuColumn, MenuColumnVo.class)); } //表单 for (MenuForm menuForm : menuFormList) { resultVo.addForm(menuForm.getMenuId(), BeanUtil.toBean(menuForm, MenuFormVo.class)); } return R.ok(resultVo); } @GetMapping("/parent-tree") @ApiOperation(value = "获取菜单树结构, 不包含页面类型的菜单") public R menuTree() { List menuList = menuService.list(Wrappers.query().lambda() .eq(Menu::getMenuType, MenuType.MENU.getCode()) .eq(Menu::getEnabledMark, EnabledMark.ENABLED.getCode()) .select(Menu.class, x -> VoToColumnUtil.fieldsToColumns(MenuListVo.class).contains(x.getProperty())) .orderByAsc(Menu::getSortCode)); List voList = BeanUtil.copyToList(menuList, MenuListVo.class); List treeVoList = TreeUtil.build(voList); return R.ok(treeVoList); } @GetMapping("/validate-url") @ApiOperation(value = "验证菜单路由是否存在") public R validateUrl(@RequestParam String outputArea, String className) { String component = StringPool.SLASH + StringUtils.lowerCase(outputArea) + StringPool.SLASH + StringUtils.lowerCase(className) + StringPool.SLASH + "index"; long count = menuService.count(Wrappers.lambdaQuery(Menu.class).eq(Menu::getComponent, component)); return R.ok(count > 0); } @GetMapping("/validate-code") @ApiOperation(value = "验证菜单编码是否存在") public R validateCode(@RequestParam(required = false) Long id, @RequestParam String code) { long count = menuService.count(Wrappers.lambdaQuery(Menu.class).eq(Menu::getCode, code).ne(id != null, Menu::getId, id)); return R.ok(count > 0); } }