package com.imed.costaccount.service.impl; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.date.DateUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.imed.costaccount.common.constants.Constant; import com.imed.costaccount.common.exception.CostException; import com.imed.costaccount.common.util.PageUtils; import com.imed.costaccount.mapper.MenuMapper; import com.imed.costaccount.model.Menu; import com.imed.costaccount.model.User; import com.imed.costaccount.model.dto.MenuEditDTO; import com.imed.costaccount.model.dto.MenuSaveDTO; import com.imed.costaccount.model.vo.MenuVO; import com.imed.costaccount.service.MenuService; import com.imed.costaccount.service.UserService; import com.imed.costaccount.utils.BeanUtil; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; import java.util.ArrayList; import java.util.List; import java.util.Objects; import java.util.stream.Collectors; @Slf4j @Service("menuService") public class MenuServiceImpl extends ServiceImpl implements MenuService { private final UserService userService; public MenuServiceImpl(UserService userService) { this.userService = userService; } /** * 保存菜单 * * @param menuSaveDTO {@link MenuSaveDTO} * @param user {@linkplain User} */ @Override @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class) public void saveMenu(MenuSaveDTO menuSaveDTO, User user) { // 校验 this.check(menuSaveDTO.getType(), menuSaveDTO.getParentId()); Menu menu = BeanUtil.convertObj(menuSaveDTO, Menu.class); menu.setHospId(user.getHospId()) .setModifyTime(System.currentTimeMillis()) .setModifyUserId(user.getId()); this.save(menu); } /** * 分页查询菜单列表 * * @param page 页码 * @param pageSize 每页数据大小 * @param user 当前登录用户 * @return 菜单伪列表 */ @Override public PageUtils selectList(Integer page, Integer pageSize, User user) { List list = this.list( new LambdaQueryWrapper().eq(Menu::getHospId, user.getHospId()).orderByAsc(Menu::getOrderNum) ); List menuVOS = list.stream().map(i -> { MenuVO menuVO = BeanUtil.convertObj(i, MenuVO.class); menuVO.setModifyTime(DateUtil.formatDateTime(DateUtil.date(i.getModifyTime()))); menuVO.setModifyUserName(userService.getUsernameByIdAndHospId(user.getId(), user.getHospId())); return menuVO; }).collect(Collectors.toList()); List roots = menuVOS.stream().filter(i -> i.getParentId() == 0).collect(Collectors.toList()); List treeVOs = new ArrayList<>(); for (MenuVO i : roots) { List menus = this.getMenuTree(i, menuVOS); treeVOs.addAll(menus); } return new PageUtils(treeVOs, 0, 0, 0); } /** * 编辑某个菜单 * * @param menuDTO {@link MenuEditDTO} * @param user {@link User} */ @Override @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Throwable.class) public void updateMenu(MenuEditDTO menuDTO, User user) { this.check(menuDTO.getType(), menuDTO.getParentId()); Menu byId = this.getById(menuDTO.getId()); if (Objects.isNull(byId)) { throw new CostException(500, "选择的菜单已被移除"); } BeanUtil.convertObj(menuDTO, byId); log.info("byId:{}", byId); this.updateById(byId); } /** * 递归遍历 * * @param menuVO * @param menuVOS * @return */ private List getMenuTree(MenuVO menuVO, List menuVOS) { List list = new ArrayList<>(); list.add(menuVO); for (MenuVO vo : menuVOS) { if (vo.getParentId().equals(menuVO.getMenuId())) { List children = menuVO.getChildren(); if (CollUtil.isEmpty(children)) { children = new ArrayList<>(); } children.add(vo); menuVO.setChildren(children); this.getMenuTree(vo, menuVOS); } } return list; } /** * 校验相关 菜单格式 * * @param parentId 父级id * @param type 菜单类型 */ private void check(Integer type, Long parentId) { //上级菜单类型 int parentType = Constant.MenuType.CATALOG.getValue(); if (parentId != 0L) { Menu parentMenu = this.getById(parentId); parentType = parentMenu.getType(); } // 如果当前是 目录、菜单 if (type == Constant.MenuType.CATALOG.getValue() || type == Constant.MenuType.MENU.getValue()) { if (parentType != Constant.MenuType.CATALOG.getValue()) { throw new CostException("上级菜单只能为目录类型"); } return; } // 如果当前是按钮 if (type == Constant.MenuType.BUTTON.getValue()) { if (parentType != Constant.MenuType.MENU.getValue()) { throw new CostException("上级菜单只能为菜单类型"); } } } }