cloudroam
2024-12-09 96abc87da07408ef817d9086ea71ba4c287aa474
Merge branch 'master-v5' of http://47.96.225.205:8888/r/flowerbackend-v2 into master-v5
已修改1个文件
已添加10个文件
606 ■■■■■ 文件已修改
src/main/java/com/mzl/flower/constant/Constants.java 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/mzl/flower/dto/request/system/CreateAppMenuDTO.java 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/mzl/flower/dto/request/system/UpdateAppMenuDTO.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/mzl/flower/dto/response/system/AppMenuDTO.java 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/mzl/flower/dto/response/system/AppMenuSimpleDTO.java 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/mzl/flower/dto/response/system/AppMenuTreeDTO.java 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/mzl/flower/entity/system/AppMenu.java 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/mzl/flower/mapper/system/AppMenuMapper.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/mzl/flower/service/system/AppMenuService.java 173 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/mzl/flower/web/system/AppMenuController.java 123 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/system/AppMenuMapper.xml 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
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;
        }
    }
}
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;
}
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;
}
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;
}
src/main/java/com/mzl/flower/dto/response/system/AppMenuSimpleDTO.java
对比新文件
@@ -0,0 +1,24 @@
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.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class AppMenuSimpleDTO extends AbstractTransDTO {
    private String id;
    @ApiModelProperty(value = "菜单名称")
    private String menuName;
    @ApiModelProperty(value = "权限标识")
    private String permissionUq;
    @ApiModelProperty(value = "子账号权限")
    private Integer subaccountAccessFlag;
}
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;
}
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;
}
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);
}
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;
    }
}
src/main/java/com/mzl/flower/web/system/AppMenuController.java
对比新文件
@@ -0,0 +1,123 @@
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.*;
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 com.mzl.flower.utils.ConverterUtil;
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(), ConverterUtil.transList(menuService.getPermissionMenu(), AppMenuSimpleDTO.class));
    }
}
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>