From 0bc0cd632d4e1ea9b5e06729c6b8a96f0cd9f2ba Mon Sep 17 00:00:00 2001 From: 陶杰 <1378534974@qq.com> Date: 星期五, 06 十二月 2024 10:46:20 +0800 Subject: [PATCH] 小程序菜单 --- src/main/java/com/mzl/flower/service/system/AppMenuService.java | 173 +++++++++++++++++ src/main/java/com/mzl/flower/web/system/AppMenuController.java | 125 ++++++++++++ src/main/resources/mapper/system/AppMenuMapper.xml | 51 +++++ src/main/java/com/mzl/flower/dto/response/system/AppMenuDTO.java | 41 ++++ src/main/java/com/mzl/flower/constant/Constants.java | 33 +++ src/main/java/com/mzl/flower/dto/request/system/CreateAppMenuDTO.java | 35 +++ src/main/java/com/mzl/flower/dto/response/system/AppMenuTreeDTO.java | 44 ++++ src/main/java/com/mzl/flower/mapper/system/AppMenuMapper.java | 22 ++ src/main/java/com/mzl/flower/entity/system/AppMenu.java | 49 ++++ src/main/java/com/mzl/flower/dto/request/system/UpdateAppMenuDTO.java | 11 + 10 files changed, 584 insertions(+), 0 deletions(-) diff --git a/src/main/java/com/mzl/flower/constant/Constants.java b/src/main/java/com/mzl/flower/constant/Constants.java index 648ca14..71b4fb4 100644 --- a/src/main/java/com/mzl/flower/constant/Constants.java +++ b/src/main/java/com/mzl/flower/constant/Constants.java @@ -677,4 +677,37 @@ } } + public enum CUSTOM01 { + ZERO(0) + ,ONE(1) + ; + + CUSTOM01(Integer desc) { + this.desc = desc; + } + + private Integer desc; + + public Integer getDesc() { + return desc; + } + } + + public enum APP_MENU_TYPE { + SUPPLIER("supplier") + , PARTNER("partner") + ; + + APP_MENU_TYPE(String desc) { + this.desc = desc; + } + + private String desc; + + public String getDesc() { + return desc; + } + } + + } diff --git a/src/main/java/com/mzl/flower/dto/request/system/CreateAppMenuDTO.java b/src/main/java/com/mzl/flower/dto/request/system/CreateAppMenuDTO.java new file mode 100644 index 0000000..58a9821 --- /dev/null +++ b/src/main/java/com/mzl/flower/dto/request/system/CreateAppMenuDTO.java @@ -0,0 +1,35 @@ +package com.mzl.flower.dto.request.system; + +import com.baomidou.mybatisplus.annotation.TableField; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +@Data +public class CreateAppMenuDTO { + @ApiModelProperty(value = "父节点ID") + private String parentId; + + @ApiModelProperty(value = "菜单名称") + private String menuName; + + @ApiModelProperty(value = "菜单类型") + private String type; + + @ApiModelProperty(value = "菜单图标") + private String menuIcon; + + @ApiModelProperty(value = "前端地址") + private String menuHref; + + @ApiModelProperty(value = "排序") + private Integer seq; + + private String keepAlive; + + @ApiModelProperty(value = "权限唯一标识") + private String permissionUq; + + @ApiModelProperty(value = "子账号权限标志") + private Integer subaccountAccessFlag; + +} diff --git a/src/main/java/com/mzl/flower/dto/request/system/UpdateAppMenuDTO.java b/src/main/java/com/mzl/flower/dto/request/system/UpdateAppMenuDTO.java new file mode 100644 index 0000000..bfbcc14 --- /dev/null +++ b/src/main/java/com/mzl/flower/dto/request/system/UpdateAppMenuDTO.java @@ -0,0 +1,11 @@ +package com.mzl.flower.dto.request.system; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +@Data +public class UpdateAppMenuDTO extends CreateAppMenuDTO { + + @ApiModelProperty(value = "菜单ID") + private String id; +} diff --git a/src/main/java/com/mzl/flower/dto/response/system/AppMenuDTO.java b/src/main/java/com/mzl/flower/dto/response/system/AppMenuDTO.java new file mode 100644 index 0000000..a5843d3 --- /dev/null +++ b/src/main/java/com/mzl/flower/dto/response/system/AppMenuDTO.java @@ -0,0 +1,41 @@ +package com.mzl.flower.dto.response.system; + +import com.mzl.flower.base.AbstractTransDTO; +import com.mzl.flower.base.annotation.DictTrans; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +@Data +public class AppMenuDTO extends AbstractTransDTO { + private String id; + + @ApiModelProperty(value = "父节点") + private String parentId; + + @ApiModelProperty(value = "菜单名称") + private String menuName; + + @ApiModelProperty(value = "菜单类型") + @DictTrans(codeType = "MENU_TYPE", target = "typeStr") + private String type; + + @ApiModelProperty(value = "菜单类型名") + private String typeStr; + + @ApiModelProperty(value = "菜单图标") + private String menuIcon; + + @ApiModelProperty(value = "菜单前端地址") + private String menuHref; + + @ApiModelProperty(value = "菜单排序") + private Integer seq; + + private String keepAlive; + + @ApiModelProperty(value = "权限标识") + private String permissionUq; + + @ApiModelProperty(value = "子账号权限") + private Integer subaccountAccessFlag; +} diff --git a/src/main/java/com/mzl/flower/dto/response/system/AppMenuTreeDTO.java b/src/main/java/com/mzl/flower/dto/response/system/AppMenuTreeDTO.java new file mode 100644 index 0000000..38661f7 --- /dev/null +++ b/src/main/java/com/mzl/flower/dto/response/system/AppMenuTreeDTO.java @@ -0,0 +1,44 @@ +package com.mzl.flower.dto.response.system; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.mzl.flower.base.Node; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +@Data +public class AppMenuTreeDTO extends Node { + @ApiModelProperty(value = "菜单名称") + private String menuName; + + @ApiModelProperty(value = "菜单类型") + private String type; + + @ApiModelProperty(value = "菜单类型名") + private String typeStr; + + @ApiModelProperty(value = "菜单图标") + private String menuIcon; + + @ApiModelProperty(value = "菜单前端地址") + private String menuHref; + + @ApiModelProperty(value = "菜单排序") + private Integer seq; + + + + private String isVisible; + + private String keepAlive; + private String path; + + private String name; + private String label; + + @ApiModelProperty(value = "权限标识") + private String permissionUq; + + @ApiModelProperty(value = "子账号权限") + private Integer subaccountAccessFlag; + +} diff --git a/src/main/java/com/mzl/flower/entity/system/AppMenu.java b/src/main/java/com/mzl/flower/entity/system/AppMenu.java new file mode 100644 index 0000000..b3d4690 --- /dev/null +++ b/src/main/java/com/mzl/flower/entity/system/AppMenu.java @@ -0,0 +1,49 @@ +package com.mzl.flower.entity.system; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.mzl.flower.base.BaseEntity; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@TableName("t_app_menu") +@NoArgsConstructor +@AllArgsConstructor +public class AppMenu extends BaseEntity { + + @TableField("PARENT_ID") + private String parentId; + + @TableField("NAME") + private String menuName; + + @TableField("TYPE") + private String type; + + @TableField("ICON") + private String menuIcon; + + @TableField("HREF") + private String menuHref; + + @TableField("SEQ") + private Integer seq; + + @TableField("IS_VISIBLE") + private String isVisible; + + @TableField("STATUS") + private String status; + + @TableField("keepAlive") + private String keepAlive; + + @TableField("PERMISSION_UQ") + private String permissionUq; + + @TableField("SUBACCOUNT_ACCESS_FLAG") + private Integer subaccountAccessFlag; + +} diff --git a/src/main/java/com/mzl/flower/mapper/system/AppMenuMapper.java b/src/main/java/com/mzl/flower/mapper/system/AppMenuMapper.java new file mode 100644 index 0000000..528d713 --- /dev/null +++ b/src/main/java/com/mzl/flower/mapper/system/AppMenuMapper.java @@ -0,0 +1,22 @@ +package com.mzl.flower.mapper.system; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.mzl.flower.dto.response.system.AppMenuTreeDTO; +import com.mzl.flower.entity.system.AppMenu; +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Repository; + +import java.util.List; + +@Repository +public interface AppMenuMapper extends BaseMapper<AppMenu> { + List<AppMenuTreeDTO> selectListOrderBySeq(); + + List<String> findByUserId(@Param("userId") String userId); + + List<AppMenuTreeDTO> selectOperationList(@Param("roleIds")List<String> roleIds); + + List<String> findChildMenuIds(@Param("parentId") String parentId); + + void updateMenuSubaccountAccessFlag(@Param("menuIds") List<String> menuIds, @Param("subaccountAccessFlag") Integer subaccountAccessFlag); +} diff --git a/src/main/java/com/mzl/flower/service/system/AppMenuService.java b/src/main/java/com/mzl/flower/service/system/AppMenuService.java new file mode 100644 index 0000000..670978a --- /dev/null +++ b/src/main/java/com/mzl/flower/service/system/AppMenuService.java @@ -0,0 +1,173 @@ +package com.mzl.flower.service.system; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.mzl.flower.config.exception.ValidationException; +import com.mzl.flower.constant.Constants; +import com.mzl.flower.dto.request.system.CreateAppMenuDTO; +import com.mzl.flower.dto.request.system.UpdateAppMenuDTO; +import com.mzl.flower.dto.response.system.AppMenuDTO; +import com.mzl.flower.dto.response.system.AppMenuTreeDTO; +import com.mzl.flower.entity.system.AppMenu; +import com.mzl.flower.mapper.system.AppMenuMapper; +import com.mzl.flower.service.BaseService; +import com.mzl.flower.utils.TreeBuilderUtil; +import com.mzl.flower.utils.UUIDGenerator; +import org.springframework.beans.BeanUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.CollectionUtils; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@Service +@Transactional +public class AppMenuService extends BaseService { + @Autowired + private AppMenuMapper menuMapper; + + public AppMenu getMenu(String id) { + return menuMapper.selectById(id); + } + + public void addMenu(CreateAppMenuDTO dto) { + AppMenu menu = new AppMenu(); + // 查找菜单名称是否已经存在 + if (menuMapper.selectCount(new QueryWrapper<AppMenu>() + .lambda().eq(AppMenu::getMenuName, dto.getMenuName()) + .eq(AppMenu::getStatus, Constants.STATUS_ACTIVE) + ) > 0) { + throw new ValidationException("菜单名称已经存在"); + } + // 查找权限标识是否已经存在 + if (menuMapper.selectCount(new QueryWrapper<AppMenu>().lambda().eq(AppMenu::getPermissionUq, dto.getPermissionUq()).eq(AppMenu::getStatus, Constants.STATUS_ACTIVE)) > 0) { + throw new ValidationException("权限标识已经存在"); + } + + BeanUtils.copyProperties(dto, menu); + menu.setId(UUIDGenerator.getUUID()); + menu.setIsVisible(Constants.Y); + menu.setStatus(Constants.STATUS_ACTIVE); + menu.setSubaccountAccessFlag(Constants.CUSTOM01.ONE.getDesc()); + + menuMapper.insert(menu); + } + + public List<AppMenuTreeDTO> searchOperationMenu() { + List<AppMenuTreeDTO> treeList = menuMapper.selectListOrderBySeq(); + for (AppMenuTreeDTO appMenuTreeDTO : treeList) { + appMenuTreeDTO.setLabel(appMenuTreeDTO.getMenuName()); + appMenuTreeDTO.setPath(appMenuTreeDTO.getMenuHref()); + appMenuTreeDTO.setName(appMenuTreeDTO.getMenuName()); + } + treeList = (List<AppMenuTreeDTO>) TreeBuilderUtil.buildListToTree(treeList); + return treeList; + } + + public AppMenuDTO getMenuDetail(String id) { + AppMenu menu = getMenu(id); + + //返回对象 + AppMenuDTO menuDTO = new AppMenuDTO(); + if (menu != null) { + BeanUtils.copyProperties(menu, menuDTO); + } + return menuDTO; + } + + public void updateMenu(UpdateAppMenuDTO dto) { + AppMenu menu = getMenu(dto.getId()); + if(null==menu){ + throw new ValidationException("菜单不存在"); + } + if (menuMapper.selectCount(new QueryWrapper<AppMenu>().lambda().eq(AppMenu::getMenuName, dto.getMenuName()).eq(AppMenu::getStatus, Constants.STATUS_ACTIVE).ne(AppMenu::getId, menu.getId())) > 0) { + throw new ValidationException("菜单名称已经存在"); + } + // 查找权限标识是否已经存在 + if (menuMapper.selectCount(new QueryWrapper<AppMenu>().lambda().eq(AppMenu::getPermissionUq, dto.getPermissionUq()).eq(AppMenu::getStatus, Constants.STATUS_ACTIVE).ne(AppMenu::getId, menu.getId())) > 0) { + throw new ValidationException("权限标识已经存在"); + } + Integer subaccountAccessFlag = menu.getSubaccountAccessFlag(); + BeanUtils.copyProperties(dto, menu); + menu.setSubaccountAccessFlag(subaccountAccessFlag); + menuMapper.updateById(menu); + } + + public void deleteMenu(String id) { + AppMenu menu = getMenu(id); + menu.setStatus(Constants.STATUS_DELETED); + menuMapper.updateById(menu); + + List<AppMenu> menus = menuMapper.selectList(new QueryWrapper<AppMenu>().eq("PARENT_ID", id)); + if (menus != null && menus.size() > 0) { + for (AppMenu children : menus) { + deleteMenu(children.getId()); + } + } + } + + public void updateMenuShow(String id) { + // 更新当前菜单及所有子菜单都变为隐藏 + List<String> menuIds = new ArrayList<>(); + findAllChildMenuIds(id, menuIds); + menuMapper.updateMenuSubaccountAccessFlag(menuIds, Constants.CUSTOM01.ONE.getDesc()); + } + + public void updateMenuHidden(String id) { + // 递归查找所有子菜单 + List<String> menuIds = new ArrayList<>(); + findAllChildMenuIds(id, menuIds); + menuMapper.updateMenuSubaccountAccessFlag(menuIds, Constants.CUSTOM01.ZERO.getDesc()); + } + + + /** + * 递归查找当前菜单及所有子菜单的 ID + * + * @param menuId 当前菜单 ID + * @param menuIds 存储菜单 ID 的列表 + */ + private void findAllChildMenuIds(String menuId, List<String> menuIds) { + // 首先将当前菜单 ID 加入菜单列表 + menuIds.add(menuId); + + // 查询当前菜单的所有子菜单 + List<String> childMenuIds = menuMapper.findChildMenuIds(menuId); + + // 如果有子菜单,递归查找 + if (childMenuIds != null && !childMenuIds.isEmpty()) { + for (String childMenuId : childMenuIds) { + findAllChildMenuIds(childMenuId, menuIds); // 递归查找子菜单 + } + } + } + + // 获取供应商菜单信息 + public List<AppMenu> getPermissionMenu() { + + LambdaQueryWrapper<AppMenu> queryWrapper = new QueryWrapper<AppMenu>() + .lambda() + .eq(AppMenu::getStatus, Constants.STATUS_ACTIVE) + .eq(AppMenu::getSubaccountAccessFlag,Constants.CUSTOM01.ONE.getDesc()) +// .eq(AppMenu::getPermissionUq, Constants.APP_MENU_TYPE.SUPPLIER.getDesc()) + ; + List<AppMenu> list = menuMapper.selectList(queryWrapper); + + if (!CollectionUtils.isEmpty(list)) { + + List<AppMenu> allMenuList = menuMapper.selectList( + new QueryWrapper<AppMenu>().lambda().eq(AppMenu::getStatus, Constants.STATUS_ACTIVE)); + + return allMenuList; + } + + return null; + } + + + +} diff --git a/src/main/java/com/mzl/flower/web/system/AppMenuController.java b/src/main/java/com/mzl/flower/web/system/AppMenuController.java new file mode 100644 index 0000000..517c0d3 --- /dev/null +++ b/src/main/java/com/mzl/flower/web/system/AppMenuController.java @@ -0,0 +1,125 @@ +package com.mzl.flower.web.system; + +import com.mzl.flower.base.BaseController; +import com.mzl.flower.base.R; +import com.mzl.flower.base.ReturnDataDTO; +import com.mzl.flower.base.annotation.OperationLog; +import com.mzl.flower.config.exception.ValidationException; +import com.mzl.flower.dto.request.system.CreateAppMenuDTO; +import com.mzl.flower.dto.request.system.CreateMenuDTO; +import com.mzl.flower.dto.request.system.UpdateAppMenuDTO; +import com.mzl.flower.dto.request.system.UpdateMenuDTO; +import com.mzl.flower.dto.response.system.AppMenuDTO; +import com.mzl.flower.dto.response.system.AppMenuTreeDTO; +import com.mzl.flower.dto.response.system.MenuDTO; +import com.mzl.flower.dto.response.system.MenuTreeDTO; +import com.mzl.flower.entity.flower.FlowerCategory; +import com.mzl.flower.entity.log.OperationRecord; +import com.mzl.flower.entity.system.AppMenu; +import com.mzl.flower.entity.system.Menu; +import com.mzl.flower.service.system.AppMenuService; +import com.mzl.flower.service.system.MenuService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.ApiOperation; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +@RestController +@RequestMapping("/api/app/menu") +@Api(value = "小程序菜单管理", tags = "小程序菜单管理") +@Validated +public class AppMenuController extends BaseController { + @Autowired + private AppMenuService menuService; + + @GetMapping("/list") + @ApiOperation(value = "查询菜单列表") + public ResponseEntity<ReturnDataDTO<List<AppMenuTreeDTO>>> searchMenuList() { + return returnData(R.SUCCESS.getCode(), menuService.searchOperationMenu()); + } + + @PostMapping("/list/new") + @ApiOperation(value = "新增菜单") + public ResponseEntity<ReturnDataDTO> addTenantMenu(@RequestBody @Validated CreateAppMenuDTO dto) { + if (StringUtils.isNotBlank(dto.getParentId()) && !"-1".equals(dto.getParentId())) { + AppMenu menu = menuService.getMenu(dto.getParentId()); + if (menu == null) { + throw new ValidationException("父菜单不存在"); + } + } + menuService.addMenu(dto); + return returnData(R.SUCCESS.getCode(), null); + } + + @GetMapping("/list/view") + @ApiImplicitParams({ + @ApiImplicitParam(name = "id", value = "菜单ID", required = true, dataType = "String", paramType = "query") + }) + @ApiOperation(value = "查询菜单详情") + public ResponseEntity<ReturnDataDTO<AppMenuDTO>> getMenu(String id) { + return returnData(R.SUCCESS.getCode(), menuService.getMenuDetail(id)); + } + + @PostMapping("/list/edit") + @ApiOperation(value = "编辑菜单") + public ResponseEntity<ReturnDataDTO> updateTenantMenu(@RequestBody @Validated UpdateAppMenuDTO dto) { + if (StringUtils.isNotBlank(dto.getParentId()) && !"-1".equals(dto.getParentId())) { + AppMenu menu = menuService.getMenu(dto.getParentId()); + if (menu == null) { + throw new ValidationException("父菜单不存在"); + } + } + menuService.updateMenu(dto); + return returnData(R.SUCCESS.getCode(), null); + } + + @GetMapping("/list/delete") + @ApiImplicitParams({ + @ApiImplicitParam(name = "id", value = "菜单ID", required = true, dataType = "String", paramType = "query") + }) + @ApiOperation(value = "删除菜单") + public ResponseEntity<ReturnDataDTO> deleteTenantMenu(String id) { + menuService.deleteMenu(id); + return returnData(R.SUCCESS.getCode(), null); + } + + + @GetMapping("/tree/shown") + @ApiOperation(value = "子账号显示菜单") + @ApiImplicitParams({ + @ApiImplicitParam(name = "id", value = "菜单id", required = true, dataType = "String", paramType = "query") + }) + public ResponseEntity<ReturnDataDTO<?>> showMenu(String id){ + + menuService.updateMenuShow(id); + + return returnData(R.SUCCESS.getCode(), null ); + + } + + @GetMapping("/tree/hidden") + @ApiOperation(value = "子账号隐藏菜单") + @ApiImplicitParams({ + @ApiImplicitParam(name = "id", value = "菜单id", required = true, dataType = "String", paramType = "query") + }) + public ResponseEntity<ReturnDataDTO<?>> hideMenu(String id){ + menuService.updateMenuHidden(id); + return returnData(R.SUCCESS.getCode(), null); + } + + + @GetMapping("/permission/menu") + @ApiOperation(value = "子账号有权限的菜单") + + public ResponseEntity<ReturnDataDTO<?>> getPermissionMenu(){ + return returnData(R.SUCCESS.getCode(), menuService.getPermissionMenu()); + } + +} diff --git a/src/main/resources/mapper/system/AppMenuMapper.xml b/src/main/resources/mapper/system/AppMenuMapper.xml new file mode 100644 index 0000000..684b61c --- /dev/null +++ b/src/main/resources/mapper/system/AppMenuMapper.xml @@ -0,0 +1,51 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" > +<mapper namespace="com.mzl.flower.mapper.system.AppMenuMapper"> + <update id="updateMenuSubaccountAccessFlag"> + UPDATE t_app_menu + SET subaccount_access_flag = #{subaccountAccessFlag} + WHERE id IN + <foreach item="item" collection="menuIds" open="(" separator="," close=")"> + #{item} + </foreach> + + </update> + + <select id="selectListOrderBySeq" resultType="com.mzl.flower.dto.response.system.AppMenuTreeDTO"> + SELECT ID AS id, PARENT_ID AS parentId, NAME AS menuName, keepAlive, TYPE AS type + , ICON AS menuIcon, HREF AS menuHref, SEQ AS seq,permission_uq,subaccount_access_flag + FROM t_app_menu + WHERE STATUS != 'D' + AND IS_VISIBLE = 'Y' + ORDER BY SEQ + </select> + + <select id="findByUserId" resultType="java.lang.String"> + SELECT DISTINCT rm.MENU_ID + FROM t_role_menu rm + JOIN t_user_role ur ON ur.ROLE_ID = rm.ROLE_ID + WHERE ur.USER_ID = #{userId} + </select> + + <select id="selectOperationList" resultType="com.mzl.flower.dto.response.system.AppMenuTreeDTO"> + SELECT DISTINCT m.ID AS id, PARENT_ID AS parentId, NAME AS menuName, TYPE AS type + , ICON AS menuIcon, keepAlive, HREF AS menuHref, SEQ AS seq,permission_uq,subaccount_access_flag + FROM t_app_menu m + JOIN t_role_menu rm ON m.ID = rm.MENU_ID + JOIN t_role r ON rm.ROLE_ID = r.ID + WHERE m.STATUS != 'D' + AND m.IS_VISIBLE = 'Y' + AND rm.ROLE_ID IN + <foreach collection="roleIds" item="item" open="(" separator="," close=")"> + #{item} + </foreach> + ORDER BY m.SEQ + </select> + <select id="findChildMenuIds" resultType="java.lang.String"> + SELECT id + FROM t_app_menu + WHERE parent_id = #{parentId}; + + </select> + +</mapper> -- Gitblit v1.9.3