- admin 模块重命名 system 模块
This commit is contained in:
@@ -0,0 +1,14 @@
|
||||
package cn.iocoder.mall.admin.config;
|
||||
|
||||
import org.mybatis.spring.annotation.MapperScan;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.transaction.annotation.EnableTransactionManagement;
|
||||
|
||||
@Configuration
|
||||
@MapperScan("cn.iocoder.mall.admin.dao") // 扫描对应的 Mapper 接口
|
||||
@EnableTransactionManagement(proxyTargetClass = true) // 启动事务管理。为什么使用 proxyTargetClass 参数,参见 https://blog.csdn.net/huang_550/article/details/76492600
|
||||
public class DatabaseConfiguration {
|
||||
|
||||
// 数据源,使用 HikariCP
|
||||
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package cn.iocoder.mall.admin.config;
|
||||
|
||||
import cn.iocoder.common.framework.util.ServiceExceptionUtil;
|
||||
import cn.iocoder.mall.admin.api.constant.AdminErrorCodeEnum;
|
||||
import org.springframework.boot.context.event.ApplicationReadyEvent;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.event.EventListener;
|
||||
|
||||
@Configuration
|
||||
public class ServiceExceptionConfiguration {
|
||||
|
||||
@EventListener(ApplicationReadyEvent.class) // 可参考 https://www.cnblogs.com/ssslinppp/p/7607509.html
|
||||
public void initMessages() {
|
||||
// 从 service_exception_message.properties 加载错误码的方案
|
||||
// Properties properties;
|
||||
// try {
|
||||
// properties = PropertiesLoaderUtils.loadAllProperties("classpath:service_exception_message.properties");
|
||||
// } catch (IOException e) {
|
||||
// throw new RuntimeException(e);
|
||||
// }
|
||||
for (AdminErrorCodeEnum item : AdminErrorCodeEnum.values()) {
|
||||
ServiceExceptionUtil.put(item.getCode(), item.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package cn.iocoder.mall.admin.convert;
|
||||
|
||||
import cn.iocoder.mall.admin.api.dto.AdminAccessLogAddDTO;
|
||||
import cn.iocoder.mall.admin.dataobject.AdminAccessLogDO;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.Mappings;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
@Mapper
|
||||
public interface AdminAccessLogConvert {
|
||||
|
||||
AdminAccessLogConvert INSTANCE = Mappers.getMapper(AdminAccessLogConvert.class);
|
||||
|
||||
@Mappings({})
|
||||
AdminAccessLogDO convert(AdminAccessLogAddDTO adminAccessLogAddDTO);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package cn.iocoder.mall.admin.convert;
|
||||
|
||||
import cn.iocoder.mall.admin.api.bo.AdminBO;
|
||||
import cn.iocoder.mall.admin.api.dto.AdminAddDTO;
|
||||
import cn.iocoder.mall.admin.api.dto.AdminUpdateDTO;
|
||||
import cn.iocoder.mall.admin.dataobject.AdminDO;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.Mappings;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Mapper
|
||||
public interface AdminConvert {
|
||||
|
||||
AdminConvert INSTANCE = Mappers.getMapper(AdminConvert.class);
|
||||
|
||||
@Mappings({})
|
||||
AdminBO convert(AdminDO adminDO);
|
||||
|
||||
@Mappings({})
|
||||
AdminDO convert(AdminAddDTO adminAddDTO);
|
||||
|
||||
@Mappings({})
|
||||
AdminDO convert(AdminUpdateDTO adminUpdateDTO);
|
||||
|
||||
@Mappings({})
|
||||
List<AdminBO> convert(List<AdminDO> adminBOs);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package cn.iocoder.mall.admin.convert;
|
||||
|
||||
import cn.iocoder.mall.admin.api.bo.DataDictBO;
|
||||
import cn.iocoder.mall.admin.api.dto.DataDictAddDTO;
|
||||
import cn.iocoder.mall.admin.api.dto.DataDictUpdateDTO;
|
||||
import cn.iocoder.mall.admin.dataobject.DataDictDO;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Mapper
|
||||
public interface DataDictConvert {
|
||||
|
||||
DataDictConvert INSTANCE = Mappers.getMapper(DataDictConvert.class);
|
||||
|
||||
DataDictDO convert(DataDictAddDTO dataDictAddDTO);
|
||||
|
||||
DataDictDO convert(DataDictUpdateDTO dataDictUpdateDTO);
|
||||
|
||||
DataDictBO convert(DataDictDO dataDictDO);
|
||||
|
||||
List<DataDictBO> convert(List<DataDictDO> dataDictDOs);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package cn.iocoder.mall.admin.convert;
|
||||
|
||||
import cn.iocoder.mall.admin.api.bo.OAuth2AccessTokenBO;
|
||||
import cn.iocoder.mall.admin.api.bo.OAuth2AuthenticationBO;
|
||||
import cn.iocoder.mall.admin.dataobject.AdminRoleDO;
|
||||
import cn.iocoder.mall.admin.dataobject.OAuth2AccessTokenDO;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.Mapping;
|
||||
import org.mapstruct.Mappings;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Mapper
|
||||
public interface OAuth2Convert {
|
||||
|
||||
OAuth2Convert INSTANCE = Mappers.getMapper(OAuth2Convert.class);
|
||||
|
||||
@Mappings({
|
||||
@Mapping(source = "id", target = "accessToken")
|
||||
})
|
||||
OAuth2AccessTokenBO convertToAccessToken(OAuth2AccessTokenDO oauth2AccessTokenDO);
|
||||
|
||||
default OAuth2AccessTokenBO convertToAccessTokenWithExpiresIn(OAuth2AccessTokenDO oauth2AccessTokenDO) {
|
||||
return this.convertToAccessToken(oauth2AccessTokenDO)
|
||||
.setExpiresIn(Math.max((int) ((oauth2AccessTokenDO.getExpiresTime().getTime() - System.currentTimeMillis()) / 1000), 0));
|
||||
}
|
||||
|
||||
@Mappings({})
|
||||
OAuth2AuthenticationBO convertToAuthentication(OAuth2AccessTokenDO oauth2AccessTokenDO);
|
||||
|
||||
default OAuth2AuthenticationBO convertToAuthentication(OAuth2AccessTokenDO oauth2AccessTokenDO, List<AdminRoleDO> adminRoleDOs) {
|
||||
return convertToAuthentication(oauth2AccessTokenDO)
|
||||
.setRoleIds(adminRoleDOs.stream().map(AdminRoleDO::getRoleId).collect(Collectors.toSet()));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package cn.iocoder.mall.admin.convert;
|
||||
|
||||
import cn.iocoder.mall.admin.api.bo.ResourceBO;
|
||||
import cn.iocoder.mall.admin.api.dto.ResourceAddDTO;
|
||||
import cn.iocoder.mall.admin.api.dto.ResourceUpdateDTO;
|
||||
import cn.iocoder.mall.admin.dataobject.ResourceDO;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.Mappings;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Mapper
|
||||
public interface ResourceConvert {
|
||||
|
||||
ResourceConvert INSTANCE = Mappers.getMapper(ResourceConvert.class);
|
||||
|
||||
@Mappings({})
|
||||
ResourceBO convert(ResourceDO resourceDO);
|
||||
|
||||
@Mappings({})
|
||||
List<ResourceBO> convert(List<ResourceDO> resourceDOs);
|
||||
|
||||
@Mappings({})
|
||||
ResourceDO convert(ResourceAddDTO resourceAddDTO);
|
||||
|
||||
@Mappings({})
|
||||
ResourceDO convert(ResourceUpdateDTO resourceUpdateDTO);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package cn.iocoder.mall.admin.convert;
|
||||
|
||||
import cn.iocoder.mall.admin.api.bo.RoleBO;
|
||||
import cn.iocoder.mall.admin.api.dto.RoleAddDTO;
|
||||
import cn.iocoder.mall.admin.api.dto.RoleUpdateDTO;
|
||||
import cn.iocoder.mall.admin.dataobject.RoleDO;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.Mappings;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Mapper
|
||||
public interface RoleConvert {
|
||||
|
||||
RoleConvert INSTANCE = Mappers.getMapper(RoleConvert.class);
|
||||
|
||||
@Mappings({})
|
||||
RoleDO convert(RoleAddDTO roleAddDTO);
|
||||
|
||||
@Mappings({})
|
||||
RoleDO convert(RoleUpdateDTO roleUpdateDTO);
|
||||
|
||||
@Mappings({})
|
||||
RoleBO convert(RoleDO roleDO);
|
||||
|
||||
@Mappings({})
|
||||
List<RoleBO> convert(List<RoleDO> roleDOs);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package cn.iocoder.mall.admin.dao;
|
||||
|
||||
import cn.iocoder.mall.admin.dataobject.AdminAccessLogDO;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
@Repository
|
||||
public interface AdminAccessLogMapper {
|
||||
|
||||
void insert(AdminAccessLogDO entity);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package cn.iocoder.mall.admin.dao;
|
||||
|
||||
import cn.iocoder.mall.admin.dataobject.AdminDO;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Repository
|
||||
public interface AdminMapper {
|
||||
|
||||
AdminDO selectById(@Param("id") Integer id);
|
||||
|
||||
AdminDO selectByUsername(@Param("username") String username);
|
||||
|
||||
List<AdminDO> selectListByNicknameLike(@Param("nickname") String nickname,
|
||||
@Param("offset") Integer offset,
|
||||
@Param("limit") Integer limit);
|
||||
|
||||
Integer selectCountByNicknameLike(@Param("nickname") String nickname);
|
||||
|
||||
void insert(AdminDO admin);
|
||||
|
||||
int update(AdminDO admin);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package cn.iocoder.mall.admin.dao;
|
||||
|
||||
import cn.iocoder.mall.admin.dataobject.AdminRoleDO;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Repository
|
||||
public interface AdminRoleMapper {
|
||||
|
||||
List<AdminRoleDO> selectByAdminId(@Param("adminId") Integer adminId);
|
||||
|
||||
int updateToDeletedByAdminId(@Param("adminId") Integer adminId);
|
||||
|
||||
int updateToDeletedByRoleId(@Param("roleId") Integer roleId);
|
||||
|
||||
void insertList(@Param("adminRoleDOs") List<AdminRoleDO> adminRoleDOs);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package cn.iocoder.mall.admin.dao;
|
||||
|
||||
import cn.iocoder.mall.admin.dataobject.DataDictDO;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
@Repository
|
||||
public interface DataDictMapper {
|
||||
|
||||
DataDictDO selectById(@Param("id") Integer id);
|
||||
|
||||
DataDictDO selectByEnumValueAndValue(
|
||||
@Param("enumValue") String enumValue,
|
||||
@Param("value") String value
|
||||
);
|
||||
|
||||
List<DataDictDO> selectByEnumValueAndValues(
|
||||
@Param("enumValue") String enumValue,
|
||||
@Param("values") Collection<String> values
|
||||
);
|
||||
|
||||
List<DataDictDO> selectByEnumValue(
|
||||
@Param("enumValue") String enumValue
|
||||
);
|
||||
|
||||
List<DataDictDO> selectList();
|
||||
|
||||
void insert(DataDictDO dataDict);
|
||||
|
||||
int update(DataDictDO dataDict);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package cn.iocoder.mall.admin.dao;
|
||||
|
||||
import cn.iocoder.mall.admin.dataobject.OAuth2AccessTokenDO;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
@Repository
|
||||
public interface OAuth2AccessTokenMapper {
|
||||
|
||||
void insert(OAuth2AccessTokenDO entity);
|
||||
|
||||
OAuth2AccessTokenDO selectByTokenId(@Param("id") String id);
|
||||
|
||||
int updateToInvalidByAdminId(@Param("adminId") Integer adminId);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package cn.iocoder.mall.admin.dao;
|
||||
|
||||
import cn.iocoder.mall.admin.dataobject.OAuth2RefreshTokenDO;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
@Repository
|
||||
public interface OAuth2RefreshTokenMapper {
|
||||
|
||||
void insert(OAuth2RefreshTokenDO entity);
|
||||
|
||||
int updateToInvalidByAdminId(@Param("adminId") Integer adminId);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package cn.iocoder.mall.admin.dao;
|
||||
|
||||
import cn.iocoder.mall.admin.dataobject.ResourceDO;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
@Repository
|
||||
public interface ResourceMapper {
|
||||
|
||||
ResourceDO selectByTypeAndHandler(@Param("type") Integer type,
|
||||
@Param("handler") String handler);
|
||||
|
||||
List<ResourceDO> selectListByTypeAndRoleIds(@Param("type") Integer type,
|
||||
@Param("roleIds") Set<Integer> roleIds);
|
||||
|
||||
List<ResourceDO> selectListByType(@Param("type") Integer type);
|
||||
|
||||
ResourceDO selectByName(@Param("name") String name);
|
||||
|
||||
ResourceDO selectById(@Param("id") Integer id);
|
||||
|
||||
List<ResourceDO> selectListByIds(@Param("ids") Set<Integer> ids);
|
||||
|
||||
void insert(ResourceDO resource);
|
||||
|
||||
int update(ResourceDO resource);
|
||||
|
||||
int selectCountByPid(@Param("pid") Integer pid);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package cn.iocoder.mall.admin.dao;
|
||||
|
||||
import cn.iocoder.mall.admin.dataobject.RoleDO;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
@Repository
|
||||
public interface RoleMapper {
|
||||
|
||||
void insert(RoleDO roleDO);
|
||||
|
||||
int update(RoleDO roleDO);
|
||||
|
||||
RoleDO selectById(@Param("id") Integer id);
|
||||
|
||||
List<RoleDO> selectListByNameLike(@Param("name") String name,
|
||||
@Param("offset") Integer offset,
|
||||
@Param("limit") Integer limit);
|
||||
|
||||
Integer selectCountByNameLike(@Param("name") String name);
|
||||
|
||||
List<RoleDO> selectListByIds(@Param("ids") Set<Integer> ids);
|
||||
|
||||
List<RoleDO> selectList();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package cn.iocoder.mall.admin.dao;
|
||||
|
||||
import cn.iocoder.mall.admin.dataobject.RoleResourceDO;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Repository
|
||||
public interface RoleResourceMapper {
|
||||
|
||||
int insertList(@Param("roleResources") List<RoleResourceDO> resourceDOs);
|
||||
|
||||
List<RoleResourceDO> selectByResourceHandler(@Param("resourceHandler") String resourceHandler);
|
||||
|
||||
List<RoleResourceDO> selectByResourceId(@Param("resourceId") Integer resourceId);
|
||||
|
||||
int updateToDeletedByResourceId(@Param("resourceId") Integer resourceId);
|
||||
|
||||
int updateToDeletedByRoleId(@Param("roleId") Integer roleId);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
package cn.iocoder.mall.admin.dataobject;
|
||||
|
||||
import cn.iocoder.common.framework.dataobject.DeletableDO;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 管理员访问日志 DO
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class AdminAccessLogDO extends DeletableDO {
|
||||
|
||||
/**
|
||||
* 编号
|
||||
*/
|
||||
private Integer id;
|
||||
/**
|
||||
* 管理员编号.
|
||||
*
|
||||
* 当管理员为空时,该值为0
|
||||
*/
|
||||
private Integer adminId;
|
||||
/**
|
||||
* 访问地址
|
||||
*/
|
||||
private String uri;
|
||||
/**
|
||||
* 参数
|
||||
*/
|
||||
private String queryString;
|
||||
/**
|
||||
* http 方法
|
||||
*/
|
||||
private String method;
|
||||
/**
|
||||
* userAgent
|
||||
*/
|
||||
private String userAgent;
|
||||
/**
|
||||
* ip
|
||||
*/
|
||||
private String ip;
|
||||
/**
|
||||
* 请求时间
|
||||
*/
|
||||
private Date startTime;
|
||||
/**
|
||||
* 响应时长 -- 毫秒级
|
||||
*/
|
||||
private Integer responseTime;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package cn.iocoder.mall.admin.dataobject;
|
||||
|
||||
import cn.iocoder.common.framework.dataobject.DeletableDO;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/**
|
||||
* 管理员实体
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class AdminDO extends DeletableDO {
|
||||
|
||||
/**
|
||||
* 管理员编号
|
||||
*/
|
||||
private Integer id;
|
||||
/**
|
||||
* 登陆账号
|
||||
*/
|
||||
private String username;
|
||||
/**
|
||||
* 昵称
|
||||
*/
|
||||
private String nickname;
|
||||
/**
|
||||
* 密码
|
||||
*
|
||||
* TODO 芋艿 暂时最简单的 MD5
|
||||
*/
|
||||
private String password;
|
||||
/**
|
||||
* 账号状态
|
||||
*/
|
||||
private Integer status;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package cn.iocoder.mall.admin.dataobject;
|
||||
|
||||
import cn.iocoder.common.framework.dataobject.DeletableDO;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/**
|
||||
* {@link AdminDO} 和 {@link RoleDO} 的关联表
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class AdminRoleDO extends DeletableDO {
|
||||
|
||||
/**
|
||||
* 编号
|
||||
*/
|
||||
private Integer id;
|
||||
/**
|
||||
* 管理员编号(外键:{@link AdminDO}
|
||||
*/
|
||||
private Integer adminId;
|
||||
/**
|
||||
* 角色编号(外键:{@link RoleDO}
|
||||
*/
|
||||
private Integer roleId;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package cn.iocoder.mall.admin.dataobject;
|
||||
|
||||
import cn.iocoder.common.framework.dataobject.DeletableDO;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/**
|
||||
* 数据字典
|
||||
*
|
||||
* 使用 {@link #enumValue} 作为聚合。例如说:
|
||||
*
|
||||
* enumValue :gender 性别
|
||||
* value:1 男
|
||||
* value:2 女
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class DataDictDO extends DeletableDO {
|
||||
|
||||
/**
|
||||
* 编号
|
||||
*/
|
||||
private Integer id;
|
||||
/**
|
||||
* 大类枚举值
|
||||
*/
|
||||
private String enumValue;
|
||||
/**
|
||||
* 小类数值
|
||||
*/
|
||||
private String value;
|
||||
/**
|
||||
* 展示名
|
||||
*/
|
||||
private String displayName;
|
||||
/**
|
||||
* 排序值
|
||||
*/
|
||||
private Integer sort;
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
private String memo;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
package cn.iocoder.mall.admin.dataobject;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* OAUTH2 AccessToken
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class OAuth2AccessTokenDO {
|
||||
|
||||
/**
|
||||
* 访问令牌
|
||||
*/
|
||||
private String id;
|
||||
/**
|
||||
* 刷新令牌
|
||||
*/
|
||||
private String refreshToken;
|
||||
/**
|
||||
* 管理员比那好
|
||||
*/
|
||||
private Integer adminId;
|
||||
/**
|
||||
* 过期时间
|
||||
*/
|
||||
private Date expiresTime;
|
||||
/**
|
||||
* 是否有效
|
||||
*/
|
||||
private Boolean valid;
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
private Date createTime;
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public OAuth2AccessTokenDO setId(String id) {
|
||||
this.id = id;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getRefreshToken() {
|
||||
return refreshToken;
|
||||
}
|
||||
|
||||
public OAuth2AccessTokenDO setRefreshToken(String refreshToken) {
|
||||
this.refreshToken = refreshToken;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Integer getAdminId() {
|
||||
return adminId;
|
||||
}
|
||||
|
||||
public OAuth2AccessTokenDO setAdminId(Integer adminId) {
|
||||
this.adminId = adminId;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Date getExpiresTime() {
|
||||
return expiresTime;
|
||||
}
|
||||
|
||||
public OAuth2AccessTokenDO setExpiresTime(Date expiresTime) {
|
||||
this.expiresTime = expiresTime;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Boolean getValid() {
|
||||
return valid;
|
||||
}
|
||||
|
||||
public OAuth2AccessTokenDO setValid(Boolean valid) {
|
||||
this.valid = valid;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Date getCreateTime() {
|
||||
return createTime;
|
||||
}
|
||||
|
||||
public OAuth2AccessTokenDO setCreateTime(Date createTime) {
|
||||
this.createTime = createTime;
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package cn.iocoder.mall.admin.dataobject;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 刷新令牌
|
||||
*
|
||||
* idx_uid
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class OAuth2RefreshTokenDO {
|
||||
|
||||
/**
|
||||
* 刷新令牌
|
||||
*/
|
||||
private String id;
|
||||
/**
|
||||
* 用户编号
|
||||
*/
|
||||
private Integer adminId;
|
||||
/**
|
||||
* 是否有效
|
||||
*/
|
||||
private Boolean valid;
|
||||
/**
|
||||
* 过期时间
|
||||
*/
|
||||
private Date expiresTime;
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
private Date createTime;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
package cn.iocoder.mall.admin.dataobject;
|
||||
|
||||
import cn.iocoder.common.framework.dataobject.DeletableDO;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 资源实体
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class ResourceDO extends DeletableDO {
|
||||
|
||||
/**
|
||||
* 资源类型 - 菜单
|
||||
*/
|
||||
@Deprecated
|
||||
public static final Integer TYPE_MENU = 1;
|
||||
/**
|
||||
* 资源类型 - 操作
|
||||
*
|
||||
* 例如,按钮。
|
||||
*/
|
||||
@Deprecated
|
||||
public static final Integer TYPE_OPERATION = 2;
|
||||
|
||||
/**
|
||||
* 资源编号
|
||||
*/
|
||||
private Integer id;
|
||||
/**
|
||||
* 资源名字(标识)
|
||||
*/
|
||||
private String name;
|
||||
/**
|
||||
* 资源类型
|
||||
*/
|
||||
private Integer type;
|
||||
/**
|
||||
* 排序
|
||||
*/
|
||||
private Integer sort;
|
||||
/**
|
||||
* 展示名
|
||||
*/
|
||||
private String displayName;
|
||||
/**
|
||||
* 添加时间
|
||||
*/
|
||||
private Date createTime;
|
||||
/**
|
||||
* 父级资源编号(外键:{@link ResourceDO#id})
|
||||
*/
|
||||
private Integer pid;
|
||||
/**
|
||||
* 操作
|
||||
*
|
||||
* 当资源类型为【菜单】时,handler 配置为界面 URL ,或者前端组件名
|
||||
* 当资源类型为【URL】时,handler 配置为后端 URL 。举个例子,如果有一个「创建管理员」的表单,那么前端界面上的按钮可以根据这个 url 判断是否展示,后端接收到该 url 的请求时会判断是否有权限。
|
||||
*/
|
||||
private String handler;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package cn.iocoder.mall.admin.dataobject;
|
||||
|
||||
import cn.iocoder.common.framework.dataobject.DeletableDO;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/**
|
||||
* 角色实体
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class RoleDO extends DeletableDO {
|
||||
|
||||
/**
|
||||
* 角色编号
|
||||
*/
|
||||
private Integer id;
|
||||
/**
|
||||
* 角色名
|
||||
*/
|
||||
private String name;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package cn.iocoder.mall.admin.dataobject;
|
||||
|
||||
import cn.iocoder.common.framework.dataobject.DeletableDO;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/**
|
||||
* {@link RoleDO} 和 {@link ResourceDO} 的关联表
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class RoleResourceDO extends DeletableDO {
|
||||
|
||||
/**
|
||||
* 编号
|
||||
*/
|
||||
private Integer id;
|
||||
/**
|
||||
* 角色编号(外键:{@link RoleDO}
|
||||
*/
|
||||
private Integer roleId;
|
||||
/**
|
||||
* 资源编号(外键:{@link ResourceDO}
|
||||
*/
|
||||
private Integer resourceId;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
package cn.iocoder.mall.admin.service;
|
||||
|
||||
import cn.iocoder.common.framework.util.StringUtil;
|
||||
import cn.iocoder.common.framework.vo.CommonResult;
|
||||
import cn.iocoder.mall.admin.api.AdminAccessLogService;
|
||||
import cn.iocoder.mall.admin.api.dto.AdminAccessLogAddDTO;
|
||||
import cn.iocoder.mall.admin.convert.AdminAccessLogConvert;
|
||||
import cn.iocoder.mall.admin.dao.AdminAccessLogMapper;
|
||||
import cn.iocoder.mall.admin.dataobject.AdminAccessLogDO;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
@Service
|
||||
@org.apache.dubbo.config.annotation.Service(validation = "true")
|
||||
public class AdminAccessLogServiceImpl implements AdminAccessLogService {
|
||||
|
||||
/**
|
||||
* 请求参数最大长度。
|
||||
*/
|
||||
private static final Integer QUERY_STRING_MAX_LENGTH = 4096;
|
||||
/**
|
||||
* 请求地址最大长度。
|
||||
*/
|
||||
private static final Integer URI_MAX_LENGTH = 4096;
|
||||
/**
|
||||
* User-Agent 最大长度。
|
||||
*/
|
||||
private static final Integer USER_AGENT_MAX_LENGTH = 1024;
|
||||
|
||||
@Autowired
|
||||
private AdminAccessLogMapper adminAccessLogMapper;
|
||||
|
||||
@Override
|
||||
public CommonResult<Boolean> addAdminAccessLog(AdminAccessLogAddDTO adminAccessLogAddDTO) {
|
||||
// 创建 AdminAccessLogDO
|
||||
AdminAccessLogDO accessLog = AdminAccessLogConvert.INSTANCE.convert(adminAccessLogAddDTO);
|
||||
accessLog.setCreateTime(new Date());
|
||||
// 截取最大长度
|
||||
if (accessLog.getUri().length() > URI_MAX_LENGTH) {
|
||||
accessLog.setUri(StringUtil.substring(accessLog.getUri(), URI_MAX_LENGTH));
|
||||
}
|
||||
if (accessLog.getQueryString().length() > QUERY_STRING_MAX_LENGTH) {
|
||||
accessLog.setQueryString(StringUtil.substring(accessLog.getQueryString(), QUERY_STRING_MAX_LENGTH));
|
||||
}
|
||||
if (accessLog.getUserAgent().length() > USER_AGENT_MAX_LENGTH) {
|
||||
accessLog.setUserAgent(StringUtil.substring(accessLog.getUserAgent(), USER_AGENT_MAX_LENGTH));
|
||||
}
|
||||
// 插入
|
||||
adminAccessLogMapper.insert(accessLog);
|
||||
// 返回成功
|
||||
return CommonResult.success(true);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,203 @@
|
||||
package cn.iocoder.mall.admin.service;
|
||||
|
||||
import cn.iocoder.common.framework.constant.CommonStatusEnum;
|
||||
import cn.iocoder.common.framework.constant.DeletedStatusEnum;
|
||||
import cn.iocoder.common.framework.util.ServiceExceptionUtil;
|
||||
import cn.iocoder.common.framework.vo.CommonResult;
|
||||
import cn.iocoder.mall.admin.api.AdminService;
|
||||
import cn.iocoder.mall.admin.api.bo.AdminBO;
|
||||
import cn.iocoder.mall.admin.api.bo.AdminPageBO;
|
||||
import cn.iocoder.mall.admin.api.constant.AdminConstants;
|
||||
import cn.iocoder.mall.admin.api.constant.AdminErrorCodeEnum;
|
||||
import cn.iocoder.mall.admin.api.dto.AdminAddDTO;
|
||||
import cn.iocoder.mall.admin.api.dto.AdminPageDTO;
|
||||
import cn.iocoder.mall.admin.api.dto.AdminUpdateDTO;
|
||||
import cn.iocoder.mall.admin.convert.AdminConvert;
|
||||
import cn.iocoder.mall.admin.dao.AdminMapper;
|
||||
import cn.iocoder.mall.admin.dao.AdminRoleMapper;
|
||||
import cn.iocoder.mall.admin.dataobject.AdminDO;
|
||||
import cn.iocoder.mall.admin.dataobject.AdminRoleDO;
|
||||
import cn.iocoder.mall.admin.dataobject.RoleDO;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.DigestUtils;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
@org.apache.dubbo.config.annotation.Service(validation = "true")
|
||||
public class AdminServiceImpl implements AdminService {
|
||||
|
||||
@Autowired
|
||||
private AdminMapper adminMapper;
|
||||
@Autowired
|
||||
private AdminRoleMapper adminRoleMapper;
|
||||
|
||||
@Autowired
|
||||
private OAuth2ServiceImpl oAuth2Service;
|
||||
@Autowired
|
||||
private RoleServiceImpl roleService;
|
||||
|
||||
public CommonResult<AdminDO> validAdmin(String username, String password) {
|
||||
AdminDO admin = adminMapper.selectByUsername(username);
|
||||
// 账号不存在
|
||||
if (admin == null) {
|
||||
return ServiceExceptionUtil.error(AdminErrorCodeEnum.ADMIN_USERNAME_NOT_REGISTERED.getCode());
|
||||
}
|
||||
// 密码不正确
|
||||
if (encodePassword(password).equals(admin.getPassword())) {
|
||||
return ServiceExceptionUtil.error(AdminErrorCodeEnum.ADMIN_PASSWORD_ERROR.getCode());
|
||||
}
|
||||
// 账号被禁用
|
||||
if (CommonStatusEnum.DISABLE.getValue().equals(admin.getStatus())) {
|
||||
return ServiceExceptionUtil.error(AdminErrorCodeEnum.ADMIN_IS_DISABLE.getCode());
|
||||
}
|
||||
// 校验成功,返回管理员。并且,去掉一些非关键字段,考虑安全性。
|
||||
admin.setPassword(null);
|
||||
admin.setStatus(null);
|
||||
return CommonResult.success(admin);
|
||||
}
|
||||
|
||||
public List<AdminRoleDO> getAdminRoles(Integer adminId) {
|
||||
return adminRoleMapper.selectByAdminId(adminId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommonResult<AdminPageBO> getAdminPage(AdminPageDTO adminPageDTO) {
|
||||
AdminPageBO adminPage = new AdminPageBO();
|
||||
// 查询分页数据
|
||||
int offset = (adminPageDTO.getPageNo() - 1) * adminPageDTO.getPageSize();
|
||||
adminPage.setList(AdminConvert.INSTANCE.convert(adminMapper.selectListByNicknameLike(adminPageDTO.getNickname(),
|
||||
offset, adminPageDTO.getPageSize())));
|
||||
// 查询分页总数
|
||||
adminPage.setTotal(adminMapper.selectCountByNicknameLike(adminPageDTO.getNickname()));
|
||||
return CommonResult.success(adminPage);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommonResult<AdminBO> addAdmin(Integer adminId, AdminAddDTO adminAddDTO) {
|
||||
// 校验账号唯一
|
||||
if (adminMapper.selectByUsername(adminAddDTO.getUsername()) != null) {
|
||||
return ServiceExceptionUtil.error(AdminErrorCodeEnum.ADMIN_USERNAME_EXISTS.getCode());
|
||||
}
|
||||
// 保存到数据库
|
||||
AdminDO admin = AdminConvert.INSTANCE.convert(adminAddDTO)
|
||||
.setPassword(encodePassword(adminAddDTO.getPassword())) // 加密密码
|
||||
.setStatus(CommonStatusEnum.ENABLE.getValue());
|
||||
admin.setCreateTime(new Date());
|
||||
admin.setDeleted(DeletedStatusEnum.DELETED_NO.getValue());
|
||||
adminMapper.insert(admin);
|
||||
// TODO 插入操作日志
|
||||
// 返回成功
|
||||
return CommonResult.success(AdminConvert.INSTANCE.convert(admin));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommonResult<Boolean> updateAdmin(Integer adminId, AdminUpdateDTO adminUpdateDTO) {
|
||||
// 校验账号存在
|
||||
if (adminMapper.selectById(adminUpdateDTO.getId()) == null) {
|
||||
return ServiceExceptionUtil.error(AdminErrorCodeEnum.ADMIN_USERNAME_NOT_REGISTERED.getCode());
|
||||
}
|
||||
// 校验账号唯一
|
||||
AdminDO usernameAdmin = adminMapper.selectByUsername(adminUpdateDTO.getUsername());
|
||||
if (usernameAdmin != null && !usernameAdmin.getId().equals(adminUpdateDTO.getId())) {
|
||||
return ServiceExceptionUtil.error(AdminErrorCodeEnum.ADMIN_USERNAME_EXISTS.getCode());
|
||||
}
|
||||
// 更新到数据库
|
||||
AdminDO updateAdmin = AdminConvert.INSTANCE.convert(adminUpdateDTO);
|
||||
adminMapper.update(updateAdmin);
|
||||
// TODO 插入操作日志
|
||||
// 返回成功
|
||||
return CommonResult.success(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public CommonResult<Boolean> updateAdminStatus(Integer adminId, Integer updateAdminId, Integer status) {
|
||||
// 校验账号存在
|
||||
AdminDO admin = adminMapper.selectById(updateAdminId);
|
||||
if (admin == null) {
|
||||
return ServiceExceptionUtil.error(AdminErrorCodeEnum.ADMIN_USERNAME_NOT_REGISTERED.getCode());
|
||||
}
|
||||
if (AdminConstants.USERNAME_ADMIN.equals(admin.getUsername())) {
|
||||
return ServiceExceptionUtil.error(AdminErrorCodeEnum.ADMIN_ADMIN_STATUS_CAN_NOT_UPDATE.getCode());
|
||||
}
|
||||
// 如果状态相同,则返回错误
|
||||
if (status.equals(admin.getStatus())) {
|
||||
return ServiceExceptionUtil.error(AdminErrorCodeEnum.ADMIN_STATUS_EQUALS.getCode());
|
||||
}
|
||||
// 更新管理员状态
|
||||
AdminDO updateAdmin = new AdminDO().setId(updateAdminId).setStatus(status);
|
||||
adminMapper.update(updateAdmin);
|
||||
// 如果是关闭管理员,则标记 token 失效。否则,管理员还可以继续蹦跶
|
||||
if (CommonStatusEnum.DISABLE.getValue().equals(status)) {
|
||||
oAuth2Service.removeToken(updateAdminId);
|
||||
}
|
||||
// TODO 插入操作日志
|
||||
// 返回成功
|
||||
return CommonResult.success(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public CommonResult<Boolean> deleteAdmin(Integer adminId, Integer updateAdminId) {
|
||||
// 校验账号存在
|
||||
AdminDO admin = adminMapper.selectById(updateAdminId);
|
||||
if (admin == null) {
|
||||
return ServiceExceptionUtil.error(AdminErrorCodeEnum.ADMIN_USERNAME_NOT_REGISTERED.getCode());
|
||||
}
|
||||
// 只有禁用的账号才可以删除
|
||||
if (CommonStatusEnum.ENABLE.getValue().equals(admin.getStatus())) {
|
||||
return ServiceExceptionUtil.error(AdminErrorCodeEnum.ADMIN_DELETE_ONLY_DISABLE.getCode());
|
||||
}
|
||||
// 标记删除 AdminDO
|
||||
AdminDO updateAdmin = new AdminDO().setId(updateAdminId);
|
||||
updateAdmin.setDeleted(DeletedStatusEnum.DELETED_YES.getValue());
|
||||
adminMapper.update(updateAdmin);
|
||||
// 标记删除 AdminRole
|
||||
adminRoleMapper.updateToDeletedByAdminId(updateAdminId);
|
||||
// TODO 插入操作日志
|
||||
// 返回成功
|
||||
return CommonResult.success(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public CommonResult<Boolean> assignRole(Integer adminId, Integer updateAdminId, Set<Integer> roleIds) {
|
||||
// 校验账号存在
|
||||
AdminDO admin = adminMapper.selectById(updateAdminId);
|
||||
if (admin == null) {
|
||||
return ServiceExceptionUtil.error(AdminErrorCodeEnum.ADMIN_USERNAME_NOT_REGISTERED.getCode());
|
||||
}
|
||||
// 校验是否有不存在的角色
|
||||
List<RoleDO> roles = roleService.getRoles(roleIds);
|
||||
if (roles.size() != roleIds.size()) {
|
||||
return ServiceExceptionUtil.error(AdminErrorCodeEnum.ROLE_ASSIGN_RESOURCE_NOT_EXISTS.getCode());
|
||||
}
|
||||
// TODO 芋艿,这里先简单实现。即方式是,删除老的分配的角色关系,然后添加新的分配的角色关系
|
||||
// 标记管理员角色源关系都为删除
|
||||
adminRoleMapper.updateToDeletedByAdminId(updateAdminId);
|
||||
// 创建 RoleResourceDO 数组,并插入到数据库
|
||||
if (!roleIds.isEmpty()) {
|
||||
List<AdminRoleDO> adminRoleDOs = roleIds.stream().map(roleId -> {
|
||||
AdminRoleDO roleResource = new AdminRoleDO().setAdminId(updateAdminId).setRoleId(roleId);
|
||||
roleResource.setCreateTime(new Date());
|
||||
roleResource.setDeleted(DeletedStatusEnum.DELETED_NO.getValue());
|
||||
return roleResource;
|
||||
}).collect(Collectors.toList());
|
||||
adminRoleMapper.insertList(adminRoleDOs);
|
||||
}
|
||||
// TODO 插入操作日志
|
||||
// 返回成功
|
||||
return CommonResult.success(true);
|
||||
}
|
||||
|
||||
private String encodePassword(String password) {
|
||||
return DigestUtils.md5DigestAsHex(password.getBytes());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
package cn.iocoder.mall.admin.service;
|
||||
|
||||
import cn.iocoder.common.framework.constant.DeletedStatusEnum;
|
||||
import cn.iocoder.common.framework.util.ServiceExceptionUtil;
|
||||
import cn.iocoder.common.framework.vo.CommonResult;
|
||||
import cn.iocoder.mall.admin.api.DataDictService;
|
||||
import cn.iocoder.mall.admin.api.bo.DataDictBO;
|
||||
import cn.iocoder.mall.admin.api.constant.AdminErrorCodeEnum;
|
||||
import cn.iocoder.mall.admin.api.dto.DataDictAddDTO;
|
||||
import cn.iocoder.mall.admin.api.dto.DataDictUpdateDTO;
|
||||
import cn.iocoder.mall.admin.convert.DataDictConvert;
|
||||
import cn.iocoder.mall.admin.dao.DataDictMapper;
|
||||
import cn.iocoder.mall.admin.dataobject.DataDictDO;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 数据字典 Service
|
||||
*/
|
||||
@Service
|
||||
@org.apache.dubbo.config.annotation.Service(validation = "true")
|
||||
public class DataDictServiceImpl implements DataDictService {
|
||||
|
||||
@Autowired
|
||||
private DataDictMapper dataDictMapper;
|
||||
|
||||
@Override
|
||||
public CommonResult<List<DataDictBO>> selectDataDictList() {
|
||||
List<DataDictDO> dataDicts = dataDictMapper.selectList();
|
||||
return CommonResult.success(DataDictConvert.INSTANCE.convert(dataDicts));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommonResult<DataDictBO> addDataDict(Integer adminId, DataDictAddDTO dataDictAddDTO) {
|
||||
// 校验数据字典重复
|
||||
if (dataDictMapper.selectByEnumValueAndValue(dataDictAddDTO.getEnumValue(), dataDictAddDTO.getValue()) != null) {
|
||||
return ServiceExceptionUtil.error(AdminErrorCodeEnum.DATA_DICT_EXISTS.getCode());
|
||||
}
|
||||
// 保存到数据库
|
||||
DataDictDO dataDict = DataDictConvert.INSTANCE.convert(dataDictAddDTO);
|
||||
dataDict.setCreateTime(new Date());
|
||||
dataDict.setDeleted(DeletedStatusEnum.DELETED_NO.getValue());
|
||||
dataDictMapper.insert(dataDict);
|
||||
// TODO 插入操作日志
|
||||
// 返回成功
|
||||
return CommonResult.success(DataDictConvert.INSTANCE.convert(dataDict));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommonResult<Boolean> updateDataDict(Integer adminId, DataDictUpdateDTO dataDictUpdateDTO) {
|
||||
// 校验数据字典不存在
|
||||
DataDictDO existsDataDict = dataDictMapper.selectById(dataDictUpdateDTO.getId());
|
||||
if (existsDataDict == null) {
|
||||
return ServiceExceptionUtil.error(AdminErrorCodeEnum.DATA_DICT_NOT_EXISTS.getCode());
|
||||
}
|
||||
// 校验数据字典重复
|
||||
DataDictDO duplicateDataDict = dataDictMapper.selectByEnumValueAndValue(existsDataDict.getEnumValue(), dataDictUpdateDTO.getValue());
|
||||
if (duplicateDataDict != null && !duplicateDataDict.getId().equals(dataDictUpdateDTO.getId())) {
|
||||
return ServiceExceptionUtil.error(AdminErrorCodeEnum.DATA_DICT_EXISTS.getCode());
|
||||
}
|
||||
// 更新到数据库
|
||||
DataDictDO updateDataDict = DataDictConvert.INSTANCE.convert(dataDictUpdateDTO);
|
||||
dataDictMapper.update(updateDataDict);
|
||||
// TODO 插入操作日志
|
||||
// 返回成功
|
||||
return CommonResult.success(true);
|
||||
}
|
||||
|
||||
// 一般情况下,不要删除数据字典。
|
||||
// 因为,业务数据正在使用该数据字典,删除后,可能有不可预知的问题。
|
||||
@Override
|
||||
public CommonResult<Boolean> deleteDataDict(Integer adminId, Integer dataDictId) {
|
||||
// 校验数据字典不存在
|
||||
DataDictDO existsDataDict = dataDictMapper.selectById(dataDictId);
|
||||
if (existsDataDict == null) {
|
||||
return ServiceExceptionUtil.error(AdminErrorCodeEnum.DATA_DICT_NOT_EXISTS.getCode());
|
||||
}
|
||||
// 更新到数据库
|
||||
DataDictDO updateDataDict = new DataDictDO().setId(dataDictId);
|
||||
updateDataDict.setDeleted(DeletedStatusEnum.DELETED_YES.getValue());
|
||||
dataDictMapper.update(updateDataDict);
|
||||
// TODO 插入操作日志
|
||||
// 返回成功
|
||||
return CommonResult.success(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommonResult<DataDictBO> getDataDict(String dictKey, Object dictValue) {
|
||||
DataDictDO dataDictDO = dataDictMapper.selectByEnumValueAndValue(dictKey, String.valueOf(dictValue));
|
||||
DataDictBO dataDictBO = DataDictConvert.INSTANCE.convert(dataDictDO);
|
||||
return CommonResult.success(dataDictBO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommonResult<List<DataDictBO>> getDataDict(String dictKey) {
|
||||
List<DataDictDO> dataDictDOList = dataDictMapper.selectByEnumValue(dictKey);
|
||||
List<DataDictBO> dataDictBOList = DataDictConvert.INSTANCE.convert(dataDictDOList);
|
||||
return CommonResult.success(dataDictBOList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommonResult<List<DataDictBO>> getDataDictList(String dictKey, Collection<?> dictValueList) {
|
||||
Set<String> convertDictValueList = dictValueList.stream().map(o -> String.valueOf(o)).collect(Collectors.toSet());
|
||||
List<DataDictDO> dataDictDOList = dataDictMapper.selectByEnumValueAndValues(dictKey, convertDictValueList);
|
||||
List<DataDictBO> dataDictBOList = DataDictConvert.INSTANCE.convert(dataDictDOList);
|
||||
return CommonResult.success(dataDictBOList);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,145 @@
|
||||
package cn.iocoder.mall.admin.service;
|
||||
|
||||
import cn.iocoder.common.framework.util.ServiceExceptionUtil;
|
||||
import cn.iocoder.common.framework.vo.CommonResult;
|
||||
import cn.iocoder.mall.admin.api.OAuth2Service;
|
||||
import cn.iocoder.mall.admin.api.bo.OAuth2AccessTokenBO;
|
||||
import cn.iocoder.mall.admin.api.bo.OAuth2AuthenticationBO;
|
||||
import cn.iocoder.mall.admin.api.constant.AdminErrorCodeEnum;
|
||||
import cn.iocoder.mall.admin.convert.OAuth2Convert;
|
||||
import cn.iocoder.mall.admin.dao.OAuth2AccessTokenMapper;
|
||||
import cn.iocoder.mall.admin.dao.OAuth2RefreshTokenMapper;
|
||||
import cn.iocoder.mall.admin.dataobject.*;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
@Service
|
||||
@org.apache.dubbo.config.annotation.Service(validation = "true")
|
||||
public class OAuth2ServiceImpl implements OAuth2Service {
|
||||
|
||||
/**
|
||||
* 访问令牌过期时间,单位:毫秒
|
||||
*/
|
||||
@Value("${modules.oauth2-code-service.access-token-expire-time-millis}")
|
||||
private int accessTokenExpireTimeMillis;
|
||||
/**
|
||||
* 刷新令牌过期时间,单位:毫秒
|
||||
*/
|
||||
@Value("${modules.oauth2-code-service.refresh-token-expire-time-millis}")
|
||||
private int refreshTokenExpireTimeMillis;
|
||||
|
||||
@Autowired
|
||||
private AdminServiceImpl adminService;
|
||||
@Autowired
|
||||
private OAuth2AccessTokenMapper oauth2AccessTokenMapper;
|
||||
@Autowired
|
||||
private OAuth2RefreshTokenMapper oauth2RefreshTokenMapper;
|
||||
@Autowired
|
||||
private RoleServiceImpl roleService;
|
||||
@Autowired
|
||||
private ResourceServiceImpl resourceService;
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public CommonResult<OAuth2AccessTokenBO> getAccessToken(String username, String password) {
|
||||
CommonResult<AdminDO> adminResult = adminService.validAdmin(username, password);
|
||||
// 校验失败,返回错误结果
|
||||
if (adminResult.isError()) {
|
||||
return CommonResult.error(adminResult);
|
||||
}
|
||||
AdminDO admin = adminResult.getData();
|
||||
// 创建刷新令牌
|
||||
OAuth2RefreshTokenDO oauth2RefreshTokenDO = createOAuth2RefreshToken(admin.getId());
|
||||
// 创建访问令牌
|
||||
OAuth2AccessTokenDO oauth2AccessTokenDO = createOAuth2AccessToken(admin.getId(), oauth2RefreshTokenDO.getId());
|
||||
// 转换返回
|
||||
return CommonResult.success(OAuth2Convert.INSTANCE.convertToAccessTokenWithExpiresIn(oauth2AccessTokenDO));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommonResult<OAuth2AuthenticationBO> checkToken(String accessToken) {
|
||||
OAuth2AccessTokenDO accessTokenDO = oauth2AccessTokenMapper.selectByTokenId(accessToken);
|
||||
if (accessTokenDO == null) { // 不存在
|
||||
return ServiceExceptionUtil.error(AdminErrorCodeEnum.OAUTH_INVALID_TOKEN_NOT_FOUND.getCode());
|
||||
}
|
||||
if (accessTokenDO.getExpiresTime().getTime() < System.currentTimeMillis()) { // 已过期
|
||||
return ServiceExceptionUtil.error(AdminErrorCodeEnum.OAUTH_INVALID_TOKEN_EXPIRED.getCode());
|
||||
}
|
||||
if (!accessTokenDO.getValid()) { // 无效
|
||||
return ServiceExceptionUtil.error(AdminErrorCodeEnum.OAUTH_INVALID_TOKEN_INVALID.getCode());
|
||||
}
|
||||
// 获得管理员拥有的角色
|
||||
List<AdminRoleDO> adminRoleDOs = adminService.getAdminRoles(accessTokenDO.getAdminId());
|
||||
return CommonResult.success(OAuth2Convert.INSTANCE.convertToAuthentication(accessTokenDO, adminRoleDOs));
|
||||
}
|
||||
|
||||
/**
|
||||
* 移除管理员对应的 Token
|
||||
*
|
||||
* @param adminId 管理员编号
|
||||
*/
|
||||
@Transactional
|
||||
public void removeToken(Integer adminId) {
|
||||
// 设置 access token 失效
|
||||
oauth2AccessTokenMapper.updateToInvalidByAdminId(adminId);
|
||||
// 设置 refresh token 失效
|
||||
oauth2RefreshTokenMapper.updateToInvalidByAdminId(adminId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommonResult<Boolean> checkPermission(Integer adminId, Set<Integer> roleIds, String url) {
|
||||
// 如果未配置该资源,说明无需权限控制。
|
||||
ResourceDO resource = resourceService.getResourceByTypeAndHandler(ResourceDO.TYPE_OPERATION, url);
|
||||
if (resource == null) {
|
||||
return CommonResult.success(true);
|
||||
}
|
||||
// 资源存在,结果无角色,说明没有权限。
|
||||
if (roleIds == null || roleIds.isEmpty()) {
|
||||
return ServiceExceptionUtil.error(AdminErrorCodeEnum.OAUTH_INVALID_PERMISSION.getCode());
|
||||
}
|
||||
// 校验是否有资源对应的角色,即 RBAC 。
|
||||
List<RoleResourceDO> roleResourceDOs = roleService.getRoleByResourceId(resource.getId());
|
||||
for (RoleResourceDO roleResourceDO : roleResourceDOs) {
|
||||
if (roleIds.contains(roleResourceDO.getRoleId())) {
|
||||
return CommonResult.success(true);
|
||||
}
|
||||
}
|
||||
// 没有权限,返回错误
|
||||
return ServiceExceptionUtil.error(AdminErrorCodeEnum.OAUTH_INVALID_PERMISSION.getCode());
|
||||
}
|
||||
|
||||
private OAuth2AccessTokenDO createOAuth2AccessToken(Integer adminId, String refreshToken) {
|
||||
OAuth2AccessTokenDO accessToken = new OAuth2AccessTokenDO().setId(generateAccessToken())
|
||||
.setRefreshToken(refreshToken)
|
||||
.setAdminId(adminId)
|
||||
.setExpiresTime(new Date(System.currentTimeMillis() + accessTokenExpireTimeMillis))
|
||||
.setValid(true);
|
||||
oauth2AccessTokenMapper.insert(accessToken);
|
||||
return accessToken;
|
||||
}
|
||||
|
||||
private OAuth2RefreshTokenDO createOAuth2RefreshToken(Integer adminId) {
|
||||
OAuth2RefreshTokenDO refreshToken = new OAuth2RefreshTokenDO().setId(generateRefreshToken())
|
||||
.setAdminId(adminId)
|
||||
.setExpiresTime(new Date(System.currentTimeMillis() + refreshTokenExpireTimeMillis))
|
||||
.setValid(true);
|
||||
oauth2RefreshTokenMapper.insert(refreshToken);
|
||||
return refreshToken;
|
||||
}
|
||||
|
||||
private String generateAccessToken() {
|
||||
return UUID.randomUUID().toString().replaceAll("-", "");
|
||||
}
|
||||
|
||||
private String generateRefreshToken() {
|
||||
return UUID.randomUUID().toString().replaceAll("-", "");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,159 @@
|
||||
package cn.iocoder.mall.admin.service;
|
||||
|
||||
import cn.iocoder.common.framework.constant.DeletedStatusEnum;
|
||||
import cn.iocoder.common.framework.constant.SysErrorCodeEnum;
|
||||
import cn.iocoder.common.framework.util.ServiceExceptionUtil;
|
||||
import cn.iocoder.common.framework.vo.CommonResult;
|
||||
import cn.iocoder.mall.admin.api.ResourceService;
|
||||
import cn.iocoder.mall.admin.api.bo.ResourceBO;
|
||||
import cn.iocoder.mall.admin.api.constant.AdminErrorCodeEnum;
|
||||
import cn.iocoder.mall.admin.api.constant.ResourceConstants;
|
||||
import cn.iocoder.mall.admin.api.dto.ResourceAddDTO;
|
||||
import cn.iocoder.mall.admin.api.dto.ResourceUpdateDTO;
|
||||
import cn.iocoder.mall.admin.convert.ResourceConvert;
|
||||
import cn.iocoder.mall.admin.dao.ResourceMapper;
|
||||
import cn.iocoder.mall.admin.dao.RoleResourceMapper;
|
||||
import cn.iocoder.mall.admin.dataobject.ResourceDO;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
@Service
|
||||
@org.apache.dubbo.config.annotation.Service(validation = "true")
|
||||
public class ResourceServiceImpl implements ResourceService {
|
||||
|
||||
@Autowired
|
||||
private ResourceMapper resourceMapper;
|
||||
@Autowired
|
||||
private RoleResourceMapper roleResourceMapper;
|
||||
|
||||
public ResourceDO getResourceByTypeAndHandler(Integer type, String handler) {
|
||||
return resourceMapper.selectByTypeAndHandler(type, handler);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ResourceBO> getResourcesByTypeAndRoleIds(Integer type, Set<Integer> roleIds) {
|
||||
if (roleIds == null || roleIds.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return ResourceConvert.INSTANCE.convert(resourceMapper.selectListByTypeAndRoleIds(type, roleIds));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ResourceBO> getResourcesByType(Integer type) {
|
||||
return ResourceConvert.INSTANCE.convert(resourceMapper.selectListByType (type));
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("Duplicates")
|
||||
public CommonResult<ResourceBO> addResource(Integer adminId, ResourceAddDTO resourceAddDTO) {
|
||||
// 补充未在 Validation 中校验的参数校验
|
||||
if (!isValidResourceType(resourceAddDTO.getType())) {
|
||||
return CommonResult.error(SysErrorCodeEnum.VALIDATION_REQUEST_PARAM_ERROR.getCode(), "资源类型必须是菜单或 Url"); // TODO 有点搓
|
||||
}
|
||||
// 校验资源唯一性
|
||||
if (resourceMapper.selectByName(resourceAddDTO.getName()) != null) {
|
||||
return ServiceExceptionUtil.error(AdminErrorCodeEnum.RESOURCE_NAME_DUPLICATE.getCode());
|
||||
}
|
||||
// 校验父资源存在
|
||||
if (resourceAddDTO.getPid() == null) {
|
||||
resourceAddDTO.setPid(ResourceConstants.PID_ROOT);
|
||||
}
|
||||
if (checkParentExists(resourceAddDTO.getPid())) {
|
||||
return ServiceExceptionUtil.error(AdminErrorCodeEnum.RESOURCE_PARENT_NOT_EXISTS.getCode());
|
||||
}
|
||||
// 存储到数据库
|
||||
ResourceDO resource = ResourceConvert.INSTANCE.convert(resourceAddDTO);
|
||||
if (ResourceConstants.PID_ROOT.equals(resourceAddDTO.getPid())) { // 根节点,必须没有操作
|
||||
resource.setHandler(null);
|
||||
} else if (!resource.getHandler().startsWith("/")) {
|
||||
resource.setHandler("/" + resource.getHandler());
|
||||
}
|
||||
resource.setCreateTime(new Date());
|
||||
resource.setDeleted(DeletedStatusEnum.DELETED_NO.getValue());
|
||||
resourceMapper.insert(resource);
|
||||
// TODO 操作日志
|
||||
// 返回成功
|
||||
return CommonResult.success(ResourceConvert.INSTANCE.convert(resource));
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("Duplicates")
|
||||
public CommonResult<Boolean> updateResource(Integer adminId, ResourceUpdateDTO resourceUpdateDTO) {
|
||||
// 校验更新的资源是否存在
|
||||
if (resourceMapper.selectById(resourceUpdateDTO.getId()) == null) {
|
||||
return ServiceExceptionUtil.error(AdminErrorCodeEnum.RESOURCE_NOT_EXISTS.getCode());
|
||||
}
|
||||
// 校验资源唯一性
|
||||
ResourceDO existNameResource = resourceMapper.selectByName(resourceUpdateDTO.getName());
|
||||
if (existNameResource != null && !existNameResource.getId().equals(resourceUpdateDTO.getId())) {
|
||||
return ServiceExceptionUtil.error(AdminErrorCodeEnum.RESOURCE_NAME_DUPLICATE.getCode());
|
||||
}
|
||||
// 不能设置自己为父资源
|
||||
if (resourceUpdateDTO.getId().equals(resourceUpdateDTO.getPid())) {
|
||||
return ServiceExceptionUtil.error(AdminErrorCodeEnum.RESOURCE_PARENT_ERROR.getCode());
|
||||
}
|
||||
// 校验父资源存在
|
||||
if (resourceUpdateDTO.getPid() == null) {
|
||||
resourceUpdateDTO.setPid(ResourceConstants.PID_ROOT);
|
||||
}
|
||||
if (checkParentExists(resourceUpdateDTO.getPid())) {
|
||||
return ServiceExceptionUtil.error(AdminErrorCodeEnum.RESOURCE_PARENT_NOT_EXISTS.getCode());
|
||||
}
|
||||
// 更新到数据库
|
||||
ResourceDO resource = ResourceConvert.INSTANCE.convert(resourceUpdateDTO);
|
||||
if (ResourceConstants.PID_ROOT.equals(resourceUpdateDTO.getPid())) { // 根节点,必须没有操作
|
||||
resource.setHandler(null);
|
||||
}
|
||||
resourceMapper.update(resource);
|
||||
// TODO 操作日志
|
||||
// 返回成功
|
||||
return CommonResult.success(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public CommonResult<Boolean> deleteResource(Integer adminId, Integer resourceId) {
|
||||
// 校验更新的资源是否存在
|
||||
if (resourceMapper.selectById(resourceId) == null) {
|
||||
return ServiceExceptionUtil.error(AdminErrorCodeEnum.RESOURCE_NOT_EXISTS.getCode());
|
||||
}
|
||||
// 校验是否还有子资源
|
||||
if (resourceMapper.selectCountByPid(resourceId) > 0) {
|
||||
return ServiceExceptionUtil.error(AdminErrorCodeEnum.RESOURCE_EXISTS_CHILDREN.getCode());
|
||||
}
|
||||
// 更新到数据库
|
||||
ResourceDO resource = new ResourceDO().setId(resourceId);
|
||||
resource.setDeleted(DeletedStatusEnum.DELETED_YES.getValue());
|
||||
resourceMapper.update(resource);
|
||||
// 删除资源关联表
|
||||
roleResourceMapper.updateToDeletedByResourceId(resourceId);
|
||||
// 返回成功
|
||||
return CommonResult.success(true);
|
||||
}
|
||||
|
||||
public List<ResourceDO> getResources(Set<Integer> resourceIds) {
|
||||
if (resourceIds == null || resourceIds.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return resourceMapper.selectListByIds(resourceIds);
|
||||
}
|
||||
|
||||
private boolean isValidResourceType(Integer type) {
|
||||
return ResourceConstants.TYPE_MENU.equals(type)
|
||||
|| ResourceConstants.TYPE_URL.equals(type);
|
||||
}
|
||||
|
||||
private boolean checkParentExists(Integer pid) {
|
||||
if (!ResourceConstants.PID_ROOT.equals(pid)) {
|
||||
return resourceMapper.selectById(pid) == null;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,163 @@
|
||||
package cn.iocoder.mall.admin.service;
|
||||
|
||||
import cn.iocoder.common.framework.constant.DeletedStatusEnum;
|
||||
import cn.iocoder.common.framework.util.CollectionUtil;
|
||||
import cn.iocoder.common.framework.util.ServiceExceptionUtil;
|
||||
import cn.iocoder.common.framework.vo.CommonResult;
|
||||
import cn.iocoder.mall.admin.api.RoleService;
|
||||
import cn.iocoder.mall.admin.api.bo.RoleBO;
|
||||
import cn.iocoder.mall.admin.api.bo.RolePageBO;
|
||||
import cn.iocoder.mall.admin.api.constant.AdminErrorCodeEnum;
|
||||
import cn.iocoder.mall.admin.api.dto.RoleAddDTO;
|
||||
import cn.iocoder.mall.admin.api.dto.RolePageDTO;
|
||||
import cn.iocoder.mall.admin.api.dto.RoleUpdateDTO;
|
||||
import cn.iocoder.mall.admin.convert.RoleConvert;
|
||||
import cn.iocoder.mall.admin.dao.AdminRoleMapper;
|
||||
import cn.iocoder.mall.admin.dao.RoleMapper;
|
||||
import cn.iocoder.mall.admin.dao.RoleResourceMapper;
|
||||
import cn.iocoder.mall.admin.dataobject.AdminRoleDO;
|
||||
import cn.iocoder.mall.admin.dataobject.ResourceDO;
|
||||
import cn.iocoder.mall.admin.dataobject.RoleDO;
|
||||
import cn.iocoder.mall.admin.dataobject.RoleResourceDO;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
@org.apache.dubbo.config.annotation.Service(validation = "true")
|
||||
public class RoleServiceImpl implements RoleService {
|
||||
|
||||
@Autowired
|
||||
private RoleResourceMapper roleResourceMapper;
|
||||
@Autowired
|
||||
private AdminRoleMapper adminRoleMapper;
|
||||
@Autowired
|
||||
private RoleMapper roleMapper;
|
||||
|
||||
@Autowired
|
||||
private ResourceServiceImpl resourceService;
|
||||
|
||||
public List<RoleResourceDO> getRoleByResourceHandler(String resourceHandler) {
|
||||
return roleResourceMapper.selectByResourceHandler(resourceHandler);
|
||||
}
|
||||
|
||||
public List<RoleResourceDO> getRoleByResourceId(Integer resourceId) {
|
||||
return roleResourceMapper.selectByResourceId(resourceId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommonResult<RolePageBO> getRolePage(RolePageDTO rolePageDTO) {
|
||||
RolePageBO rolePage = new RolePageBO();
|
||||
// 查询分页数据
|
||||
int offset = rolePageDTO.getPageNo() * rolePageDTO.getPageSize();
|
||||
rolePage.setRoles(RoleConvert.INSTANCE.convert(roleMapper.selectListByNameLike(rolePageDTO.getName(),
|
||||
offset, rolePageDTO.getPageSize())));
|
||||
// 查询分页总数
|
||||
rolePage.setCount(roleMapper.selectCountByNameLike(rolePageDTO.getName()));
|
||||
return CommonResult.success(rolePage);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommonResult<Set<Integer>> getRoleList(Integer adminId) {
|
||||
List<AdminRoleDO> adminRoleDOs = adminRoleMapper.selectByAdminId(adminId);
|
||||
return CommonResult.success(adminRoleDOs.stream().map(AdminRoleDO::getRoleId).collect(Collectors.toSet()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommonResult<List<RoleBO>> getRoleList() {
|
||||
List<RoleDO> roleList = roleMapper.selectList();
|
||||
return CommonResult.success(RoleConvert.INSTANCE.convert(roleList));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommonResult<RoleBO> addRole(Integer adminId, RoleAddDTO roleAddDTO) {
|
||||
// TODO 芋艿,角色名是否要唯一呢?貌似一般系统都是允许的。
|
||||
// 保存到数据库
|
||||
RoleDO role = RoleConvert.INSTANCE.convert(roleAddDTO);
|
||||
role.setCreateTime(new Date());
|
||||
role.setDeleted(DeletedStatusEnum.DELETED_NO.getValue());
|
||||
roleMapper.insert(role);
|
||||
// TODO 插入操作日志
|
||||
// 返回成功
|
||||
return CommonResult.success(RoleConvert.INSTANCE.convert(role));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommonResult<Boolean> updateRole(Integer adminId, RoleUpdateDTO roleUpdateDTO) {
|
||||
// TODO 芋艿,角色名是否要唯一呢?貌似一般系统都是允许的。
|
||||
// 校验角色是否存在
|
||||
if (roleMapper.selectById(roleUpdateDTO.getId()) == null) {
|
||||
return ServiceExceptionUtil.error(AdminErrorCodeEnum.RESOURCE_NOT_EXISTS.getCode());
|
||||
}
|
||||
// 更新到数据库
|
||||
RoleDO roleDO = RoleConvert.INSTANCE.convert(roleUpdateDTO);
|
||||
roleMapper.update(roleDO);
|
||||
// TODO 插入操作日志
|
||||
// 返回成功
|
||||
return CommonResult.success(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public CommonResult<Boolean> deleteRole(Integer adminId, Integer roleId) {
|
||||
// 校验角色是否存在
|
||||
if (roleMapper.selectById(roleId) == null) {
|
||||
return ServiceExceptionUtil.error(AdminErrorCodeEnum.RESOURCE_NOT_EXISTS.getCode());
|
||||
}
|
||||
// 更新到数据库,标记删除
|
||||
RoleDO roleDO = new RoleDO().setId(roleId);
|
||||
roleDO.setDeleted(DeletedStatusEnum.DELETED_YES.getValue());
|
||||
roleMapper.update(roleDO);
|
||||
// 标记删除 RoleResource
|
||||
roleResourceMapper.updateToDeletedByRoleId(roleId);
|
||||
// 标记删除 AdminRole
|
||||
adminRoleMapper.updateToDeletedByRoleId(roleId);
|
||||
// TODO 插入操作日志
|
||||
// 返回成功
|
||||
return CommonResult.success(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public CommonResult<Boolean> assignResource(Integer adminId, Integer roleId, Set<Integer> resourceIds) {
|
||||
// 校验角色是否存在
|
||||
if (roleMapper.selectById(roleId) == null) {
|
||||
return ServiceExceptionUtil.error(AdminErrorCodeEnum.RESOURCE_NOT_EXISTS.getCode());
|
||||
}
|
||||
// 校验是否有不存在的资源
|
||||
List<ResourceDO> resources = resourceService.getResources(resourceIds);
|
||||
if (resources.size() != resourceIds.size()) {
|
||||
return ServiceExceptionUtil.error(AdminErrorCodeEnum.ROLE_ASSIGN_RESOURCE_NOT_EXISTS.getCode());
|
||||
}
|
||||
// TODO 芋艿,这里先简单实现。即方式是,删除老的分配的资源关系,然后添加新的分配的资源关系
|
||||
// 标记角色原资源关系都为删除
|
||||
roleResourceMapper.updateToDeletedByRoleId(roleId);
|
||||
// 创建 RoleResourceDO 数组,并插入到数据库
|
||||
if (!resourceIds.isEmpty()) {
|
||||
List<RoleResourceDO> roleResources = resourceIds.stream().map(resourceId -> {
|
||||
RoleResourceDO roleResource = new RoleResourceDO().setRoleId(roleId).setResourceId(resourceId);
|
||||
roleResource.setCreateTime(new Date());
|
||||
roleResource.setDeleted(DeletedStatusEnum.DELETED_NO.getValue());
|
||||
return roleResource;
|
||||
}).collect(Collectors.toList());
|
||||
roleResourceMapper.insertList(roleResources);
|
||||
}
|
||||
// TODO 插入操作日志
|
||||
// 返回成功
|
||||
return CommonResult.success(true);
|
||||
}
|
||||
|
||||
public List<RoleDO> getRoles(Set<Integer> roleIds) {
|
||||
if (CollectionUtil.isEmpty(roleIds)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return roleMapper.selectListByIds(roleIds);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user