Browse Source

08 03 01 fix some code

hr 4 years ago
parent
commit
2515e82b6b
30 changed files with 1171 additions and 0 deletions
  1. 127 0
      src/main/java/com/imed/costaccount/common/constants/Constant.java
  2. 16 0
      src/main/java/com/imed/costaccount/mapper/MenuMapper.java
  3. 16 0
      src/main/java/com/imed/costaccount/mapper/RoleMapper.java
  4. 16 0
      src/main/java/com/imed/costaccount/mapper/RoleMenuMapper.java
  5. 16 0
      src/main/java/com/imed/costaccount/mapper/UserRoleMapper.java
  6. 79 0
      src/main/java/com/imed/costaccount/model/Menu.java
  7. 55 0
      src/main/java/com/imed/costaccount/model/Role.java
  8. 47 0
      src/main/java/com/imed/costaccount/model/RoleMenu.java
  9. 47 0
      src/main/java/com/imed/costaccount/model/UserRole.java
  10. 33 0
      src/main/java/com/imed/costaccount/model/dto/MenuSaveDTO.java
  11. 19 0
      src/main/java/com/imed/costaccount/model/dto/RoleEditDTO.java
  12. 23 0
      src/main/java/com/imed/costaccount/model/dto/RoleSaveDTO.java
  13. 41 0
      src/main/java/com/imed/costaccount/model/vo/MenuVO.java
  14. 27 0
      src/main/java/com/imed/costaccount/model/vo/RoleVO.java
  15. 36 0
      src/main/java/com/imed/costaccount/service/MenuService.java
  16. 19 0
      src/main/java/com/imed/costaccount/service/RoleMenuService.java
  17. 44 0
      src/main/java/com/imed/costaccount/service/RoleService.java
  18. 19 0
      src/main/java/com/imed/costaccount/service/UserRoleService.java
  19. 8 0
      src/main/java/com/imed/costaccount/service/UserService.java
  20. 126 0
      src/main/java/com/imed/costaccount/service/impl/MenuServiceImpl.java
  21. 14 0
      src/main/java/com/imed/costaccount/service/impl/RoleMenuServiceImpl.java
  22. 107 0
      src/main/java/com/imed/costaccount/service/impl/RoleServiceImpl.java
  23. 14 0
      src/main/java/com/imed/costaccount/service/impl/UserRoleServiceImpl.java
  24. 22 0
      src/main/java/com/imed/costaccount/service/impl/UserServiceImpl.java
  25. 69 0
      src/main/java/com/imed/costaccount/web/MenuController.java
  26. 61 0
      src/main/java/com/imed/costaccount/web/RoleController.java
  27. 23 0
      src/main/resources/mapper/MenuMapper.xml
  28. 17 0
      src/main/resources/mapper/RoleMapper.xml
  29. 15 0
      src/main/resources/mapper/RoleMenuMapper.xml
  30. 15 0
      src/main/resources/mapper/UserRoleMapper.xml

+ 127 - 0
src/main/java/com/imed/costaccount/common/constants/Constant.java

@@ -0,0 +1,127 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package com.imed.costaccount.common.constants;
+
+/**
+ * 常量
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+public class Constant {
+	/** 超级管理员ID */
+	public static final int SUPER_ADMIN = 1;
+    /**
+     * 当前页码
+     */
+    public static final String PAGE = "page";
+    /**
+     * 每页显示记录数
+     */
+    public static final String LIMIT = "limit";
+    /**
+     * 排序字段
+     */
+    public static final String ORDER_FIELD = "sidx";
+    /**
+     * 排序方式
+     */
+    public static final String ORDER = "order";
+    /**
+     *  升序
+     */
+    public static final String ASC = "asc";
+	/**
+	 * 菜单类型
+	 * 
+	 * @author chenshun
+	 * @email sunlightcs@gmail.com
+	 * @date 2016年11月15日 下午1:24:29
+	 */
+    public enum MenuType {
+        /**
+         * 目录
+         */
+    	CATALOG(0),
+        /**
+         * 菜单
+         */
+        MENU(1),
+        /**
+         * 按钮
+         */
+        BUTTON(2);
+
+        private int value;
+
+        MenuType(int value) {
+            this.value = value;
+        }
+
+        public int getValue() {
+            return value;
+        }
+    }
+    
+    /**
+     * 定时任务状态
+     * 
+     * @author chenshun
+     * @email sunlightcs@gmail.com
+     * @date 2016年12月3日 上午12:07:22
+     */
+    public enum ScheduleStatus {
+        /**
+         * 正常
+         */
+    	NORMAL(0),
+        /**
+         * 暂停
+         */
+    	PAUSE(1);
+
+        private int value;
+
+        ScheduleStatus(int value) {
+            this.value = value;
+        }
+        
+        public int getValue() {
+            return value;
+        }
+    }
+
+    /**
+     * 云服务商
+     */
+    public enum CloudService {
+        /**
+         * 七牛云
+         */
+        QINIU(1),
+        /**
+         * 阿里云
+         */
+        ALIYUN(2),
+        /**
+         * 腾讯云
+         */
+        QCLOUD(3);
+
+        private int value;
+
+        CloudService(int value) {
+            this.value = value;
+        }
+
+        public int getValue() {
+            return value;
+        }
+    }
+
+}

+ 16 - 0
src/main/java/com/imed/costaccount/mapper/MenuMapper.java

@@ -0,0 +1,16 @@
+package com.imed.costaccount.mapper;
+
+import com.imed.costaccount.model.Menu;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * 菜单管理
+ * 
+ * @author huangrui
+ * @date 2021-08-03 08:56:22
+ */
+@Mapper
+public interface MenuMapper extends BaseMapper<Menu> {
+	
+}

+ 16 - 0
src/main/java/com/imed/costaccount/mapper/RoleMapper.java

@@ -0,0 +1,16 @@
+package com.imed.costaccount.mapper;
+
+import com.imed.costaccount.model.Role;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * 角色
+ * 
+ * @author huangrui
+ * @date 2021-08-03 08:56:22
+ */
+@Mapper
+public interface RoleMapper extends BaseMapper<Role> {
+	
+}

+ 16 - 0
src/main/java/com/imed/costaccount/mapper/RoleMenuMapper.java

@@ -0,0 +1,16 @@
+package com.imed.costaccount.mapper;
+
+import com.imed.costaccount.model.RoleMenu;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * 角色与菜单对应关系
+ * 
+ * @author huangrui
+ * @date 2021-08-03 08:56:22
+ */
+@Mapper
+public interface RoleMenuMapper extends BaseMapper<RoleMenu> {
+	
+}

+ 16 - 0
src/main/java/com/imed/costaccount/mapper/UserRoleMapper.java

@@ -0,0 +1,16 @@
+package com.imed.costaccount.mapper;
+
+import com.imed.costaccount.model.UserRole;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * 用户与角色对应关系
+ * 
+ * @author huangrui
+ * @date 2021-08-03 08:56:22
+ */
+@Mapper
+public interface UserRoleMapper extends BaseMapper<UserRole> {
+	
+}

+ 79 - 0
src/main/java/com/imed/costaccount/model/Menu.java

@@ -0,0 +1,79 @@
+package com.imed.costaccount.model;
+
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+
+import java.io.Serializable;
+import java.util.Date;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.experimental.Accessors;
+
+/**
+ * 菜单管理
+ * 
+ * @author huangrui
+ * @email 
+ * @date 2021-08-03 08:56:22
+ */
+@Data
+@Accessors(chain = true)
+@AllArgsConstructor
+@NoArgsConstructor
+@TableName("sys_menu")
+public class Menu implements Serializable {
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * 
+	 */
+	@TableId
+	private Long menuId;
+	/**
+	 * 父菜单ID,一级菜单为0
+	 */
+	private Long parentId;
+	/**
+	 * 菜单名称
+	 */
+	private String name;
+	/**
+	 * 菜单URL
+	 */
+	private String path;
+	/**
+	 * 外部系统url
+	 */
+	private String url;
+	/**
+	 * 授权(多个用逗号分隔,如:user:list,user:create)
+	 */
+	private String perms;
+	/**
+	 * 归属医院id
+	 */
+	private Long hospId;
+	/**
+	 * 类型   0:目录   1:菜单   2:按钮
+	 */
+	private Integer type;
+	/**
+	 * 菜单图标
+	 */
+	private String icon;
+	/**
+	 * 排序
+	 */
+	private Integer orderNum;
+	/**
+	 * 修改人id
+	 */
+	private Long modifyUserId;
+	/**
+	 * 修改时间
+	 */
+	private Long modifyTime;
+
+}

+ 55 - 0
src/main/java/com/imed/costaccount/model/Role.java

@@ -0,0 +1,55 @@
+package com.imed.costaccount.model;
+
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+
+import java.io.Serializable;
+import java.util.Date;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.experimental.Accessors;
+
+/**
+ * 角色
+ * 
+ * @author huangrui
+ * @email 
+ * @date 2021-08-03 08:56:22
+ */
+@Data
+@Accessors(chain = true)
+@AllArgsConstructor
+@NoArgsConstructor
+@TableName("sys_role")
+public class Role implements Serializable {
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * 
+	 */
+	@TableId
+	private Long roleId;
+	/**
+	 * 角色名称
+	 */
+	private String roleName;
+	/**
+	 * 备注
+	 */
+	private String remark;
+	/**
+	 * 归属医院id
+	 */
+	private Long hospId;
+	/**
+	 * 创建者ID
+	 */
+	private Long createUserId;
+	/**
+	 * 创建时间
+	 */
+	private Long createTime;
+
+}

+ 47 - 0
src/main/java/com/imed/costaccount/model/RoleMenu.java

@@ -0,0 +1,47 @@
+package com.imed.costaccount.model;
+
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+
+import java.io.Serializable;
+import java.util.Date;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.experimental.Accessors;
+
+/**
+ * 角色与菜单对应关系
+ * 
+ * @author huangrui
+ * @email 
+ * @date 2021-08-03 08:56:22
+ */
+@Data
+@Accessors(chain = true)
+@AllArgsConstructor
+@NoArgsConstructor
+@TableName("sys_role_menu")
+public class RoleMenu implements Serializable {
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * 
+	 */
+	@TableId
+	private Long id;
+	/**
+	 * 角色ID
+	 */
+	private Long roleId;
+	/**
+	 * 菜单ID
+	 */
+	private Long menuId;
+	/**
+	 * 归属医院id
+	 */
+	private Long hospId;
+
+}

+ 47 - 0
src/main/java/com/imed/costaccount/model/UserRole.java

@@ -0,0 +1,47 @@
+package com.imed.costaccount.model;
+
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+
+import java.io.Serializable;
+import java.util.Date;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.experimental.Accessors;
+
+/**
+ * 用户与角色对应关系
+ * 
+ * @author huangrui
+ * @email 
+ * @date 2021-08-03 08:56:22
+ */
+@Data
+@Accessors(chain = true)
+@AllArgsConstructor
+@NoArgsConstructor
+@TableName("sys_user_role")
+public class UserRole implements Serializable {
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * 
+	 */
+	@TableId
+	private Long id;
+	/**
+	 * 用户ID
+	 */
+	private Long userId;
+	/**
+	 * 角色ID
+	 */
+	private Long roleId;
+	/**
+	 * 归属医院id
+	 */
+	private Long hospId;
+
+}

+ 33 - 0
src/main/java/com/imed/costaccount/model/dto/MenuSaveDTO.java

@@ -0,0 +1,33 @@
+package com.imed.costaccount.model.dto;
+
+import io.swagger.annotations.ApiModel;
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+
+@Data
+@ApiModel("菜单保存")
+public class MenuSaveDTO {
+
+    @NotNull(message = "父级id不能为空")
+    private Long parentId;
+
+    @NotBlank(message = "菜单名称不能为空")
+    private String name;
+
+    @NotBlank(message = "菜单路径不能为空")
+    private String path;
+
+    private String url;
+
+    private String perms;
+
+    @NotNull(message = "菜单类型不能为空")
+    private Integer type;
+
+    @NotBlank(message = "菜单图标不能为空")
+    private String icon;
+
+    private Integer orderNum;
+}

+ 19 - 0
src/main/java/com/imed/costaccount/model/dto/RoleEditDTO.java

@@ -0,0 +1,19 @@
+package com.imed.costaccount.model.dto;
+
+
+import io.swagger.annotations.ApiModel;
+import lombok.Data;
+
+import javax.validation.constraints.NotNull;
+
+@Data
+@ApiModel("角色编辑")
+public class RoleEditDTO {
+
+    @NotNull(message = "角色id不能为空")
+    private Long roleId;
+
+    private String roleName;
+
+    private String remark;
+}

+ 23 - 0
src/main/java/com/imed/costaccount/model/dto/RoleSaveDTO.java

@@ -0,0 +1,23 @@
+package com.imed.costaccount.model.dto;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import javax.validation.constraints.NotBlank;
+
+@ApiModel("保存角色")
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class RoleSaveDTO {
+
+    @NotBlank(message = "角色名称不能为空")
+    @ApiModelProperty(name = "roleName",value = "角色名称")
+    private String roleName;
+
+    @ApiModelProperty(name = "remark",value = "描述")
+    private String remark;
+}

+ 41 - 0
src/main/java/com/imed/costaccount/model/vo/MenuVO.java

@@ -0,0 +1,41 @@
+package com.imed.costaccount.model.vo;
+
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import io.swagger.annotations.ApiModel;
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+@ApiModel
+public class MenuVO {
+
+    private Long menuId;
+
+    @JsonIgnore
+    private Long parentId;
+
+    private String name;
+
+    private String path;
+
+    private String url;
+
+    private String perms;
+
+    private Integer type;
+
+    private String icon;
+
+    private Integer orderNum;
+
+    private String modifyUserName;
+
+    private String modifyTime;
+
+    @JsonInclude(JsonInclude.Include.NON_NULL)
+    private List<MenuVO> children;
+
+}

+ 27 - 0
src/main/java/com/imed/costaccount/model/vo/RoleVO.java

@@ -0,0 +1,27 @@
+package com.imed.costaccount.model.vo;
+
+import io.swagger.annotations.ApiModel;
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+@ApiModel("角色视图对象")
+public class RoleVO {
+
+    private Long roleId;
+
+    private String roleName;
+
+    private String hospName;
+
+    private String modifyUserName;
+
+    private String modifyTime;
+
+    private String remark;
+
+    private List<CommonVO> users;
+
+    private List<CommonVO> menus;
+}

+ 36 - 0
src/main/java/com/imed/costaccount/service/MenuService.java

@@ -0,0 +1,36 @@
+package com.imed.costaccount.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.imed.costaccount.common.util.PageUtils;
+import com.imed.costaccount.model.User;
+import com.imed.costaccount.model.dto.MenuSaveDTO;
+import com.imed.costaccount.model.Menu;
+
+import java.util.Map;
+
+/**
+ * 菜单管理
+ *
+ * @author huangrui
+ * @email 
+ * @date 2021-08-03 08:56:22
+ */
+public interface MenuService extends IService<Menu> {
+
+    /**
+     * 保存菜单
+     * @param menuSaveDTO {@link MenuSaveDTO}
+     * @param user {@linkplain User}
+     */
+    void saveMenu(MenuSaveDTO menuSaveDTO, User user);
+
+    /**
+     * 分页查询菜单列表
+     * @param page 页码
+     * @param pageSize 每页数据大小
+     * @param user 当前登录用户
+     * @return 菜单分页列表
+     */
+    PageUtils selectList(Integer page, Integer pageSize, User user);
+}
+

+ 19 - 0
src/main/java/com/imed/costaccount/service/RoleMenuService.java

@@ -0,0 +1,19 @@
+package com.imed.costaccount.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.imed.costaccount.utils.PageUtils;
+import com.imed.costaccount.model.RoleMenu;
+
+import java.util.Map;
+
+/**
+ * 角色与菜单对应关系
+ *
+ * @author huangrui
+ * @email 
+ * @date 2021-08-03 08:56:22
+ */
+public interface RoleMenuService extends IService<RoleMenu> {
+
+}
+

+ 44 - 0
src/main/java/com/imed/costaccount/service/RoleService.java

@@ -0,0 +1,44 @@
+package com.imed.costaccount.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.imed.costaccount.common.util.PageUtils;
+import com.imed.costaccount.model.User;
+import com.imed.costaccount.model.dto.RoleEditDTO;
+import com.imed.costaccount.model.dto.RoleSaveDTO;
+import com.imed.costaccount.model.Role;
+
+/**
+ * 角色
+ *
+ * @author huangrui
+ * @email 
+ * @date 2021-08-03 08:56:22
+ */
+public interface RoleService extends IService<Role> {
+
+    /**
+     * 保存角色
+     * @param roleSaveDTO {@link RoleSaveDTO}
+     * @param user
+     */
+    void saveRole(RoleSaveDTO roleSaveDTO, User user);
+
+    /**
+     * 查询角色列表并分页
+     * @param page 页码
+     * @param pageSize 每页展示数据条数
+     * @param keyword 模糊匹配关键字
+     * @param user 当前登录用户
+     * @return {@link PageUtils} 分页对象
+     */
+    PageUtils selectList(Integer page, Integer pageSize, String keyword, User user);
+
+    /**
+     * 编辑某个角色
+     * @param roleEditDTO {@link RoleEditDTO}
+     * @param userId 当前登录人id
+     */
+    void updateRole(RoleEditDTO roleEditDTO, Long userId);
+
+}
+

+ 19 - 0
src/main/java/com/imed/costaccount/service/UserRoleService.java

@@ -0,0 +1,19 @@
+package com.imed.costaccount.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.imed.costaccount.utils.PageUtils;
+import com.imed.costaccount.model.UserRole;
+
+import java.util.Map;
+
+/**
+ * 用户与角色对应关系
+ *
+ * @author huangrui
+ * @email 
+ * @date 2021-08-03 08:56:22
+ */
+public interface UserRoleService extends IService<UserRole> {
+
+}
+

+ 8 - 0
src/main/java/com/imed/costaccount/service/UserService.java

@@ -68,5 +68,13 @@ public interface UserService extends IService<User> {
      * @param user
      */
     void logout(User user);
+
+    /**
+     * 通过用户id和医院id获取用户的名称,如果不存在,返回""
+     * @param createUserId id
+     * @param hospId 医院id
+     * @return 用户名称,如果不存在返回空字符串
+     */
+    String getUsernameByIdAndHospId(Long createUserId, Long hospId);
 }
 

+ 126 - 0
src/main/java/com/imed/costaccount/service/impl/MenuServiceImpl.java

@@ -0,0 +1,126 @@
+package com.imed.costaccount.service.impl;
+
+import cn.hutool.core.collection.CollUtil;
+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.MenuSaveDTO;
+import com.imed.costaccount.model.vo.MenuVO;
+import com.imed.costaccount.service.MenuService;
+import com.imed.costaccount.utils.BeanUtil;
+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.stream.Collectors;
+
+
+@Service("menuService")
+public class MenuServiceImpl extends ServiceImpl<MenuMapper, Menu> implements MenuService {
+
+
+    /**
+     * 保存菜单
+     *
+     * @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);
+
+        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<Menu> list = this.list(
+                new LambdaQueryWrapper<Menu>().eq(Menu::getHospId, user.getHospId()).orderByAsc(Menu::getOrderNum)
+        );
+        List<MenuVO> menuVOS = BeanUtil.convertList(list, MenuVO.class);
+        List<MenuVO> roots = menuVOS.stream().filter(i -> i.getParentId() == 0).collect(Collectors.toList());
+        List<MenuVO> treeVOs = new ArrayList<>();
+        for (MenuVO i : roots) {
+            List<MenuVO> menus = this.getMenuTree(i, menuVOS);
+            treeVOs.addAll(menus);
+
+        }
+        return new PageUtils(list,0,0,0);
+    }
+
+    /**
+     * 递归遍历
+     * @param menuVO
+     * @param menuVOS
+     * @return
+     */
+    private List<MenuVO> getMenuTree(MenuVO menuVO, List<MenuVO> menuVOS) {
+        List<MenuVO> list = new ArrayList<>();
+        list.add(menuVO);
+        List<MenuVO> children = menuVO.getChildren();
+        if (CollUtil.isEmpty(children)) {
+            children = new ArrayList<>();
+        }
+        for (MenuVO j : menuVOS) {
+            if (j.getParentId().equals(menuVO.getMenuId())) {
+                children.add(j);
+            }
+            menuVO.setChildren(children);
+            this.getMenuTree(j, menuVOS);
+        }
+        return list;
+    }
+
+    /**
+     * 校验相关 菜单格式
+     * @param menuSaveDTO
+     */
+    private void check(MenuSaveDTO menuSaveDTO) {
+        //上级菜单类型
+        int parentType = Constant.MenuType.CATALOG.getValue();
+        if (menuSaveDTO.getParentId() != 0) {
+            Menu parentMenu = this.getById(menuSaveDTO.getParentId());
+            parentType = parentMenu.getType();
+        }
+
+        // 如果当前是 目录、菜单
+        if (menuSaveDTO.getType() == Constant.MenuType.CATALOG.getValue() ||
+                menuSaveDTO.getType() == Constant.MenuType.MENU.getValue()) {
+            if (parentType != Constant.MenuType.CATALOG.getValue()) {
+                throw new CostException("上级菜单只能为目录类型");
+            }
+            return;
+        }
+
+        // 如果当前是按钮
+        if (menuSaveDTO.getType() == Constant.MenuType.BUTTON.getValue()) {
+            if (parentType != Constant.MenuType.MENU.getValue()) {
+                throw new CostException("上级菜单只能为菜单类型");
+            }
+            return;
+        }
+    }
+}

+ 14 - 0
src/main/java/com/imed/costaccount/service/impl/RoleMenuServiceImpl.java

@@ -0,0 +1,14 @@
+package com.imed.costaccount.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.imed.costaccount.mapper.RoleMenuMapper;
+import com.imed.costaccount.model.RoleMenu;
+import com.imed.costaccount.service.RoleMenuService;
+import org.springframework.stereotype.Service;
+
+
+@Service("roleMenuService")
+public class RoleMenuServiceImpl extends ServiceImpl<RoleMenuMapper, RoleMenu> implements RoleMenuService {
+
+
+}

+ 107 - 0
src/main/java/com/imed/costaccount/service/impl/RoleServiceImpl.java

@@ -0,0 +1,107 @@
+package com.imed.costaccount.service.impl;
+
+import cn.hutool.core.date.DateUtil;
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.imed.costaccount.common.exception.CostException;
+import com.imed.costaccount.common.util.PageUtils;
+import com.imed.costaccount.mapper.RoleMapper;
+import com.imed.costaccount.model.Role;
+import com.imed.costaccount.model.User;
+import com.imed.costaccount.model.dto.RoleEditDTO;
+import com.imed.costaccount.model.dto.RoleSaveDTO;
+import com.imed.costaccount.model.vo.RoleVO;
+import com.imed.costaccount.service.RoleService;
+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.List;
+import java.util.Objects;
+import java.util.stream.Collectors;
+
+@Slf4j
+@Service("roleService")
+public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements RoleService {
+
+
+    private final UserService userService;
+
+    public RoleServiceImpl(UserService userService) {
+        this.userService = userService;
+    }
+
+    /**
+     * 保存角色
+     *
+     * @param roleSaveDTO {@link RoleSaveDTO}
+     * @param user
+     */
+    @Override
+    @Transactional(propagation = Propagation.REQUIRED,rollbackFor = Exception.class)
+    public void saveRole(RoleSaveDTO roleSaveDTO, User user) {
+        Role role = BeanUtil.convertObj(roleSaveDTO, Role.class);
+        role.setCreateUserId(user.getId())
+                .setHospId(user.getHospId())
+                .setCreateTime(System.currentTimeMillis());
+        this.save(role);
+    }
+
+    /**
+     * 查询角色列表并分页
+     *
+     * @param page     页码
+     * @param pageSize 每页展示数据条数
+     * @param keyword  模糊匹配关键字
+     * @param user     当前登录用户
+     * @return {@link PageUtils} 分页对象
+     */
+    @Override
+    public PageUtils selectList(Integer page, Integer pageSize, String keyword, User user) {
+        Page<Role> rolePage = new Page<>(page, pageSize);
+        Page<Role> pages = this.page(rolePage,
+                new LambdaQueryWrapper<Role>().eq(Role::getHospId, user.getHospId())
+                        .and( StrUtil.isNotBlank(keyword), i -> i.eq( Role::getRoleName, keyword)
+                                .or()
+                                .eq(Role::getRemark, keyword))
+
+        );
+        List<Role> records = pages.getRecords();
+        List<RoleVO> list = records.stream().map(i -> {
+            RoleVO roleVO = BeanUtil.convertObj(i, RoleVO.class);
+            roleVO.setModifyUserName(userService.getUsernameByIdAndHospId(i.getCreateUserId(), user.getHospId()));
+            roleVO.setModifyTime(DateUtil.formatDateTime(DateUtil.date(i.getCreateTime())));
+            // todo 相关user 菜单等绑定信息
+            return roleVO;
+        }).collect(Collectors.toList());
+
+        return new PageUtils(list, (int) pages.getTotal(),pageSize,page);
+    }
+
+
+    /**
+     * 编辑某个角色
+     *
+     * @param roleEditDTO {@link RoleEditDTO}
+     * @param userId 当前登录人id
+     */
+    @Override
+    @Transactional(propagation = Propagation.REQUIRED,rollbackFor = Exception.class)
+    public void updateRole(RoleEditDTO roleEditDTO, Long userId) {
+        Role byId = this.getById(roleEditDTO.getRoleId());
+        if (Objects.isNull(byId)) {
+            throw new CostException(500, "选择的角色已被移除");
+        }
+        BeanUtil.convertObj(roleEditDTO, byId);
+        byId.setCreateTime(System.currentTimeMillis());
+        byId.setCreateUserId(userId);
+
+        log.info("byId:{}",byId);
+        this.updateById(byId);
+    }
+}

+ 14 - 0
src/main/java/com/imed/costaccount/service/impl/UserRoleServiceImpl.java

@@ -0,0 +1,14 @@
+package com.imed.costaccount.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.imed.costaccount.mapper.UserRoleMapper;
+import com.imed.costaccount.model.UserRole;
+import com.imed.costaccount.service.UserRoleService;
+import org.springframework.stereotype.Service;
+
+
+@Service("userRoleService")
+public class UserRoleServiceImpl extends ServiceImpl<UserRoleMapper, UserRole> implements UserRoleService {
+
+
+}

+ 22 - 0
src/main/java/com/imed/costaccount/service/impl/UserServiceImpl.java

@@ -278,4 +278,26 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
     public void logout(User user) {
         redisUtil.del(user.getId() + "");
     }
+
+    /**
+     * 通过用户id和医院id获取用户的名称,
+     *
+     * @param createUserId id
+     * @param hospId       医院id
+     * @return 如果不存在,返回"" (使用redis 缓存避免过多的查询)
+     */
+    @Override
+    public String getUsernameByIdAndHospId(Long createUserId, Long hospId) {
+        User one = this.getOne(
+                new LambdaQueryWrapper<User>()
+                        .select(User::getName)
+                        .eq(User::getId, createUserId)
+                        .eq(User::getHospId, hospId)
+                        .last("limit 1")
+        );
+        if (Objects.isNull(one)) {
+            return "";
+        }
+        return one.getName();
+    }
 }

+ 69 - 0
src/main/java/com/imed/costaccount/web/MenuController.java

@@ -0,0 +1,69 @@
+package com.imed.costaccount.web;
+
+import com.imed.costaccount.common.util.PageUtils;
+import com.imed.costaccount.common.util.Result;
+import com.imed.costaccount.model.Menu;
+import com.imed.costaccount.model.dto.MenuSaveDTO;
+import com.imed.costaccount.service.MenuService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import javax.validation.Valid;
+import java.util.Arrays;
+
+
+/**
+ * 菜单管理
+ *
+ * @author huangrui
+ * @date 2021-08-03 08:56:22
+ */
+@Api(tags = "菜单管理")
+@RestController
+@RequestMapping("/costAccount/menu/")
+public class MenuController extends AbstractController {
+
+    private final MenuService menuService;
+
+    public MenuController(MenuService menuService) {
+        this.menuService = menuService;
+    }
+
+
+    @ApiOperation("保存菜单")
+    @PostMapping("/save")
+    public Result save(@RequestBody @Valid MenuSaveDTO menuSaveDTO) {
+        menuService.saveMenu(menuSaveDTO, getUser());
+        return Result.ok();
+    }
+
+    /**
+     * 分页查询列表
+     */
+    @ApiOperation("菜单列表")
+    @GetMapping("/list")
+    public Result list(@RequestParam(defaultValue = "1", value = "current") Integer page,
+                       @RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize) {
+        PageUtils pageUtils = menuService.selectList(page, pageSize, getUser());
+        return Result.ok();
+    }
+
+    @ApiOperation("编辑某个菜单")
+    @PostMapping("/edit")
+    public Result update(@RequestBody @Valid Menu menu) {
+        menuService.updateById(menu);
+        return Result.ok();
+    }
+
+    /**
+     * 删除
+     */
+    @RequestMapping("/delete")
+    public Result delete(@RequestBody Long[] menuIds) {
+        menuService.removeByIds(Arrays.asList(menuIds));
+        return Result.ok();
+    }
+
+}

+ 61 - 0
src/main/java/com/imed/costaccount/web/RoleController.java

@@ -0,0 +1,61 @@
+package com.imed.costaccount.web;
+
+import com.imed.costaccount.common.util.PageUtils;
+import com.imed.costaccount.common.util.Result;
+import com.imed.costaccount.model.Role;
+import com.imed.costaccount.model.dto.RoleEditDTO;
+import com.imed.costaccount.model.dto.RoleSaveDTO;
+import com.imed.costaccount.service.RoleService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import javax.validation.Valid;
+import java.util.Arrays;
+
+
+@Api(tags="角色管理相关")
+@RestController
+@RequestMapping("/costAccount/role/")
+public class RoleController extends AbstractController{
+
+    private final RoleService roleService;
+
+    public RoleController(RoleService roleService) {
+        this.roleService = roleService;
+    }
+
+
+    @ApiOperation("新增一个角色")
+    @PostMapping("/save")
+    public Result save(@RequestBody @Valid RoleSaveDTO roleSaveDTO){
+        roleService.saveRole(roleSaveDTO,getUser());
+        return Result.ok();
+    }
+
+
+    @ApiOperation("查询角色列表")
+    @GetMapping("/list")
+    public Result list(@RequestParam(defaultValue = "1", value = "current") Integer page,
+                       @RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize,
+                       @RequestParam(value = "keyword",required = false) String keyword){
+        PageUtils pageUtils = roleService.selectList(page, pageSize, keyword, getUser());
+        return Result.ok(pageUtils);
+    }
+
+    @ApiOperation("编辑某个角色")
+    @PostMapping("/edit")
+    public Result update(@RequestBody @Valid RoleEditDTO roleEditDTO){
+		roleService.updateRole(roleEditDTO,getUserId());
+        return Result.ok();
+    }
+
+    @ApiOperation("删除")
+    @PostMapping("/delete")
+    public Result delete(@RequestBody Long[] roleIds){
+		roleService.removeByIds(Arrays.asList(roleIds));
+        return Result.ok();
+    }
+
+}

+ 23 - 0
src/main/resources/mapper/MenuMapper.xml

@@ -0,0 +1,23 @@
+<?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.imed.costaccount.mapper.MenuMapper">
+
+	<!-- 可根据自己的需求,是否要使用 -->
+    <resultMap type="com.imed.costaccount.model.Menu" id="menuMap">
+        <result property="menuId" column="menu_id"/>
+        <result property="parentId" column="parent_id"/>
+        <result property="name" column="name"/>
+        <result property="path" column="path"/>
+        <result property="url" column="url"/>
+        <result property="perms" column="perms"/>
+        <result property="hospId" column="hosp_id"/>
+        <result property="type" column="type"/>
+        <result property="icon" column="icon"/>
+        <result property="orderNum" column="order_num"/>
+        <result property="modifyUserId" column="modify_user_id"/>
+        <result property="modifyTime" column="modify_time"/>
+    </resultMap>
+
+
+</mapper>

+ 17 - 0
src/main/resources/mapper/RoleMapper.xml

@@ -0,0 +1,17 @@
+<?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.imed.costaccount.mapper.RoleMapper">
+
+	<!-- 可根据自己的需求,是否要使用 -->
+    <resultMap type="com.imed.costaccount.model.Role" id="roleMap">
+        <result property="roleId" column="role_id"/>
+        <result property="roleName" column="role_name"/>
+        <result property="remark" column="remark"/>
+        <result property="hospId" column="hosp_id"/>
+        <result property="createUserId" column="create_user_id"/>
+        <result property="createTime" column="create_time"/>
+    </resultMap>
+
+
+</mapper>

+ 15 - 0
src/main/resources/mapper/RoleMenuMapper.xml

@@ -0,0 +1,15 @@
+<?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.imed.costaccount.mapper.RoleMenuMapper">
+
+	<!-- 可根据自己的需求,是否要使用 -->
+    <resultMap type="com.imed.costaccount.model.RoleMenu" id="roleMenuMap">
+        <result property="id" column="id"/>
+        <result property="roleId" column="role_id"/>
+        <result property="menuId" column="menu_id"/>
+        <result property="hospId" column="hosp_id"/>
+    </resultMap>
+
+
+</mapper>

+ 15 - 0
src/main/resources/mapper/UserRoleMapper.xml

@@ -0,0 +1,15 @@
+<?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.imed.costaccount.mapper.UserRoleMapper">
+
+	<!-- 可根据自己的需求,是否要使用 -->
+    <resultMap type="com.imed.costaccount.model.UserRole" id="userRoleMap">
+        <result property="id" column="id"/>
+        <result property="userId" column="user_id"/>
+        <result property="roleId" column="role_id"/>
+        <result property="hospId" column="hosp_id"/>
+    </resultMap>
+
+
+</mapper>