迁移 system 服务,admin 逻辑

This commit is contained in:
YunaiV
2020-05-01 11:04:16 +08:00
parent 2543d95d0e
commit 157b166435
48 changed files with 627 additions and 400 deletions

View File

@@ -3,6 +3,8 @@ package cn.iocoder.mall.system.biz.bo.admin;
import lombok.Data;
import lombok.experimental.Accessors;
import java.util.Date;
/**
* 管理员模块 - 账号信息 BO
*/
@@ -14,9 +16,25 @@ public class AdminBO {
* 管理员编号
*/
private Integer id;
/**
* 账号编号
*/
private Integer accountId;
/**
* 真实名字
*/
private String name;
/**
* 部门编号
*/
private Integer departmentId;
/**
* 在职状态
*/
private Integer status;
/**
* 创建时间
*/
private Date createTime;
}

View File

@@ -24,6 +24,10 @@ public class RoleBO {
* 角色编码
*/
private String code;
/**
* 角色类型
*/
private Integer type;
/**
* 添加时间
*/

View File

@@ -1,8 +1,11 @@
package cn.iocoder.mall.system.biz.convert.admin;
import cn.iocoder.common.framework.vo.PageResult;
import cn.iocoder.mall.system.biz.bo.admin.AdminBO;
import cn.iocoder.mall.system.biz.dataobject.admin.AdminDO;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.factory.Mappers;
@Mapper
@@ -12,4 +15,7 @@ public interface AdminConvert {
AdminBO convert(AdminDO bean);
@Mapping(source = "records", target = "list")
PageResult<AdminBO> convertPage(IPage<AdminDO> bean);
}

View File

@@ -3,6 +3,7 @@ package cn.iocoder.mall.system.biz.convert.oauth2;
import cn.iocoder.mall.system.biz.bo.ouath2.OAuth2AuthenticateBO;
import cn.iocoder.mall.system.biz.dataobject.oauth2.OAuth2AccessTokenDO;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.factory.Mappers;
@Mapper
@@ -10,6 +11,7 @@ public interface OAuth2Convert {
OAuth2Convert INSTANCE = Mappers.getMapper(OAuth2Convert.class);
@Mapping(source = "id", target = "accessToken")
OAuth2AuthenticateBO convert(OAuth2AccessTokenDO bean);
}

View File

@@ -1,8 +1,12 @@
package cn.iocoder.mall.system.biz.dao.admin;
import cn.iocoder.mall.mybatis.query.QueryWrapperX;
import cn.iocoder.mall.system.biz.dataobject.admin.AdminDO;
import cn.iocoder.mall.system.biz.dto.admin.AdminPageDTO;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.stereotype.Repository;
@Repository
@@ -14,4 +18,10 @@ public interface AdminMapper extends BaseMapper<AdminDO> {
);
}
default IPage<AdminDO> selectPage(AdminPageDTO adminPageDTO) {
return selectPage(new Page<>(adminPageDTO.getPageNo(), adminPageDTO.getPageSize()),
new QueryWrapperX<AdminDO>().likeIfPresent("name", adminPageDTO.getName())
.eqIfPresent("department_id", adminPageDTO.getDepartmentId()));
}
}

View File

@@ -3,26 +3,26 @@ package cn.iocoder.mall.system.biz.dao.authorization;
import cn.iocoder.mall.mybatis.query.QueryWrapperX;
import cn.iocoder.mall.system.biz.dataobject.authorization.RoleDO;
import cn.iocoder.mall.system.biz.dto.authorization.RolePageDTO;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.stereotype.Repository;
import java.util.Collection;
import java.util.List;
@Repository
public interface RoleMapper extends BaseMapper<RoleDO> {
default List<RoleDO> selectList() {
return selectList(new QueryWrapper<>());
}
default IPage<RoleDO> selectPage(RolePageDTO rolePageDTO) {
return selectPage(new Page<>(rolePageDTO.getPageNo(), rolePageDTO.getPageSize()),
new QueryWrapperX<RoleDO>().likeIfPresent("name", rolePageDTO.getName()));
}
default List<RoleDO> selectListByIds(Collection<Integer> ids) {
return selectList(new QueryWrapperX<RoleDO>().inIfPresent("id", ids));
}
default RoleDO selectByName(String name) {
return selectOne(new QueryWrapperX<RoleDO>().eqIfPresent("name", name));
}

View File

@@ -2,6 +2,7 @@ package cn.iocoder.mall.system.biz.dataobject.admin;
import cn.iocoder.mall.mybatis.dataobject.DeletableDO;
import cn.iocoder.mall.system.biz.dataobject.account.AccountDO;
import cn.iocoder.mall.system.biz.enums.admin.AdminStatusEnum;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.EqualsAndHashCode;
@@ -31,10 +32,16 @@ public class AdminDO extends DeletableDO {
*/
private String name;
/**
* 科室编号
* 部门编号
*
* 关联 {@link DepartmentDO#getId()}
*/
private Integer departmentId;
/**
* 在职状态
*
* 枚举 {@link AdminStatusEnum}
*/
private Integer status;
}

View File

@@ -0,0 +1,26 @@
package cn.iocoder.mall.system.biz.dto.admin;
import cn.iocoder.common.framework.vo.PageParam;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
* 管理员模块 - 管理员分页 DTO
*/
@Data
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = true)
public class AdminPageDTO extends PageParam {
/**
* 真实名字,模糊匹配
*/
private String name;
/**
* 部门编号
*/
private Integer departmentId;
}

View File

@@ -0,0 +1,19 @@
package cn.iocoder.mall.system.biz.dto.authorization;
import lombok.Data;
import lombok.experimental.Accessors;
import javax.validation.constraints.NotNull;
import java.util.Collection;
/**
* 授权模块 - 获得每个账号所拥有的角色 DTO
*/
@Data
@Accessors(chain = true)
public class AuthorizationGetRoleMapByAccountIdsDTO {
@NotNull(message = "账号编号数组不能为空")
private Collection<Integer> accountIds;
}

View File

@@ -14,6 +14,8 @@ public class ResourceGetListDTO {
/**
* 资源编号数组
*
* 如果传入空,则不进行资源编号的过滤
*/
private Collection<Integer> ids;

View File

@@ -0,0 +1,22 @@
package cn.iocoder.mall.system.biz.dto.authorization;
import lombok.Data;
import lombok.experimental.Accessors;
import java.util.Collection;
/**
* 角色模块 - 获得角色列表 DTO
*/
@Data
@Accessors(chain = true)
public class RoleGetListDTO {
/**
* 角色编号数组
*
* 如果传入空,则不进行角色编号的过滤
*/
private Collection<Integer> ids;
}

View File

@@ -3,16 +3,18 @@ package cn.iocoder.mall.system.biz.dto.oatuh2;
import lombok.Data;
import lombok.experimental.Accessors;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.NotEmpty;
// TODO 注释
/**
* 认证模块 - 访问令牌认证 DTO
*/
@Data
@Accessors(chain = true)
public class OAuth2AccessTokenAuthenticateDTO {
@NotNull(message = "访问令牌不能为空")
@NotEmpty(message = "访问令牌不能为空")
private String accessToken;
@NotNull(message = "IP 不能为空")
@NotEmpty(message = "IP 不能为空")
private String ip;
}

View File

@@ -0,0 +1,20 @@
package cn.iocoder.mall.system.biz.dto.oatuh2;
import lombok.Data;
import lombok.experimental.Accessors;
import javax.validation.constraints.NotEmpty;
/**
* 认证模块 - 访问令牌认证 DTO
*/
@Data
@Accessors(chain = true)
public class OAuth2RefreshTokenAuthenticateDTO {
@NotEmpty(message = "访问令牌不能为空")
private String refreshToken;
@NotEmpty(message = "IP 不能为空")
private String ip;
}

View File

@@ -3,12 +3,19 @@ package cn.iocoder.mall.system.biz.dto.oatuh2;
import lombok.Data;
import lombok.experimental.Accessors;
// TODO 注释
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
/**
* 认证模块 - 账号 + 密码认证 DTO
*/
@Data
@Accessors(chain = true)
public class OAuth2UsernameAuthenticateDTO {
@NotEmpty(message = "账号不能为空")
private String username;
@NotNull(message = "密码不能为空")
private String password;
}

View File

@@ -1,14 +1,30 @@
package cn.iocoder.mall.system.biz.service.admin;
import cn.iocoder.common.framework.vo.PageResult;
import cn.iocoder.mall.system.biz.bo.admin.AdminBO;
import cn.iocoder.mall.system.biz.dto.admin.AdminPageDTO;
/**
* 管理员 Service 接口
* 管理员模块 - Service 接口
*/
public interface AdminService {
/**
* 根据编号获得管理员信息
*
* @param id 编号
* @return 管理员
*/
AdminBO getAdmin(Integer id);
/**
* 获得账号编号获得管理员信息
*
* @param accountId 账号编号
* @return 管理员
*/
AdminBO getAdminByAccountId(Integer accountId);
PageResult<AdminBO> getAdminPage(AdminPageDTO pageDTO);
}

View File

@@ -1,9 +1,10 @@
package cn.iocoder.mall.system.biz.service.admin;
import cn.iocoder.common.framework.vo.PageResult;
import cn.iocoder.mall.system.biz.bo.admin.AdminBO;
import cn.iocoder.mall.system.biz.convert.admin.AdminConvert;
import cn.iocoder.mall.system.biz.dao.admin.AdminMapper;
import cn.iocoder.mall.system.biz.dataobject.admin.AdminDO;
import cn.iocoder.mall.system.biz.dto.admin.AdminPageDTO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@@ -15,14 +16,17 @@ public class AdminServiceImpl implements AdminService {
@Override
public AdminBO getAdmin(Integer id) {
AdminDO adminDO = adminMapper.selectById(id);
return AdminConvert.INSTANCE.convert(adminDO);
return AdminConvert.INSTANCE.convert(adminMapper.selectById(id));
}
@Override
public AdminBO getAdminByAccountId(Integer accountId) {
AdminDO adminDO = adminMapper.selectByAccountId(accountId);
return AdminConvert.INSTANCE.convert(adminDO);
return AdminConvert.INSTANCE.convert(adminMapper.selectByAccountId(accountId));
}
@Override
public PageResult<AdminBO> getAdminPage(AdminPageDTO pageDTO) {
return AdminConvert.INSTANCE.convertPage(adminMapper.selectPage(pageDTO));
}
}

View File

@@ -3,12 +3,11 @@ package cn.iocoder.mall.system.biz.service.authorization;
import cn.iocoder.common.framework.exception.ServiceException;
import cn.iocoder.mall.system.biz.bo.authorization.ResourceBO;
import cn.iocoder.mall.system.biz.bo.authorization.ResourceTreeNodeBO;
import cn.iocoder.mall.system.biz.dto.authorization.AuthorizationAssignRoleResourceDTO;
import cn.iocoder.mall.system.biz.dto.authorization.AuthorizationCheckPermissionsDTO;
import cn.iocoder.mall.system.biz.dto.authorization.AuthorizationGetResourcesByAccountIdDTO;
import cn.iocoder.mall.system.biz.dto.authorization.AuthorizationGetRoleResourcesDTO;
import cn.iocoder.mall.system.biz.bo.authorization.RoleBO;
import cn.iocoder.mall.system.biz.dto.authorization.*;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
@@ -33,6 +32,14 @@ public interface AuthorizationService {
*/
List<ResourceBO> getResourcesByAccountId(AuthorizationGetResourcesByAccountIdDTO getResourcesByAccountIdDTO);
/**
* 获得每个账号拥有的角色集合
*
* @param getRoleMapByAccountIdsDTO 查询条件 DTO
* @return <账号编号, <RoleBO>>
*/
Map<Integer, Set<RoleBO>> getRoleMapByAccountIds(AuthorizationGetRoleMapByAccountIdsDTO getRoleMapByAccountIdsDTO);
/**
* 获得指定账号的资源树
*

View File

@@ -5,6 +5,7 @@ import cn.iocoder.common.framework.util.ServiceExceptionUtil;
import cn.iocoder.mall.mybatis.enums.DeletedStatusEnum;
import cn.iocoder.mall.system.biz.bo.authorization.ResourceBO;
import cn.iocoder.mall.system.biz.bo.authorization.ResourceTreeNodeBO;
import cn.iocoder.mall.system.biz.bo.authorization.RoleBO;
import cn.iocoder.mall.system.biz.dao.authorization.AccountRoleMapper;
import cn.iocoder.mall.system.biz.dao.authorization.RoleResourceMapper;
import cn.iocoder.mall.system.biz.dataobject.authorization.AccountRoleDO;
@@ -94,6 +95,25 @@ public class AuthorizationServiceImpl implements AuthorizationService {
return resourceService.getResources(new ResourceGetListDTO().setIds(resourceIds).setType(getResourcesByAccountIdDTO.getType()));
}
@Override
public Map<Integer, Set<RoleBO>> getRoleMapByAccountIds(AuthorizationGetRoleMapByAccountIdsDTO getRoleMapByAccountIdsDTO) {
return null;
}
// @Override
// public Map<Integer, Set<RoleBO>> getRoleIdMapByAccountIds(AuthorizationGetRoleMapByAccountIdsDTO getRoleMapByAccountIdsDTO) {
// // 查询管理员拥有的角色关联数据
// List<AccountRoleDO> accountRoleDOs = accountRoleMapper.selectListByAccountIds(getRoleMapByAccountIdsDTO.getAccountIds());
// if (CollectionUtil.isEmpty(accountRoleDOs)) {
// return Collections.emptyMap();
// }
// // 构建结果
// Map<Integer, Set<Integer>> accountRoleMap = CollectionUtil.convertMultiMap2(accountRoleDOs,
// AccountRoleDO::getAccountId, AccountRoleDO::getRoleId);
// getRoleMapByAccountIdsDTO.getAccountIds().forEach(accountId -> accountRoleMap.putIfAbsent(accountId, Collections.emptySet()));
// return accountRoleMap;
// }
@Override
public List<ResourceTreeNodeBO> getResourceTreeByAccountId(AuthorizationGetResourcesByAccountIdDTO getResourcesByAccountIdDTO) {
// 查询管理员拥有的角色关联数据

View File

@@ -6,6 +6,7 @@ import cn.iocoder.mall.system.biz.dto.authorization.RoleAddDTO;
import cn.iocoder.mall.system.biz.dto.authorization.RoleDeleteDTO;
import cn.iocoder.mall.system.biz.dto.authorization.RolePageDTO;
import cn.iocoder.mall.system.biz.dto.authorization.RoleUpdateDTO;
import cn.iocoder.mall.system.biz.dto.authorization.RoleGetListDTO;
import java.util.Collection;
import java.util.List;
@@ -17,7 +18,7 @@ public interface RoleService {
RoleBO getRole(Integer id);
List<RoleBO> getRoleList(Collection<Integer> ids);
List<RoleBO> getRoleList(RoleGetListDTO getListDTO);
PageResult<RoleBO> getRolePage(RolePageDTO pageDTO);

View File

@@ -8,12 +8,10 @@ import cn.iocoder.mall.system.biz.bo.authorization.RoleBO;
import cn.iocoder.mall.system.biz.convert.authorization.RoleConvert;
import cn.iocoder.mall.system.biz.dao.authorization.RoleMapper;
import cn.iocoder.mall.system.biz.dataobject.authorization.RoleDO;
import cn.iocoder.mall.system.biz.dto.authorization.RoleAddDTO;
import cn.iocoder.mall.system.biz.dto.authorization.RoleDeleteDTO;
import cn.iocoder.mall.system.biz.dto.authorization.RolePageDTO;
import cn.iocoder.mall.system.biz.dto.authorization.RoleUpdateDTO;
import cn.iocoder.mall.system.biz.dto.authorization.*;
import cn.iocoder.mall.system.biz.enums.SystemErrorCodeEnum;
import cn.iocoder.mall.system.biz.enums.authorization.RoleCodeEnum;
import cn.iocoder.mall.system.biz.enums.authorization.RoleTypeEnum;
import cn.iocoder.mall.system.biz.event.authorization.ResourceDeleteEvent;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
@@ -39,8 +37,8 @@ public class RoleServiceImpl implements RoleService {
}
@Override
public List<RoleBO> getRoleList(Collection<Integer> ids) {
return RoleConvert.INSTANCE.convertList(roleMapper.selectBatchIds(ids));
public List<RoleBO> getRoleList(RoleGetListDTO getListDTO) {
return RoleConvert.INSTANCE.convertList(roleMapper.selectListByIds(getListDTO.getIds()));
}
@Override
@@ -62,9 +60,10 @@ public class RoleServiceImpl implements RoleService {
@Override
public Integer addRole(RoleAddDTO roleAddDTO) {
// 校验角色
checkRole(roleAddDTO.getName(), roleAddDTO.getCode(), null);
checkDuplicateRole(roleAddDTO.getName(), roleAddDTO.getCode(), null);
// 保存到数据库
RoleDO role = RoleConvert.INSTANCE.convert(roleAddDTO);
role.setType(RoleTypeEnum.CUSTOM.getType());
role.setCreateTime(new Date());
role.setDeleted(DeletedStatusEnum.DELETED_NO.getValue());
roleMapper.insert(role);
@@ -76,14 +75,19 @@ public class RoleServiceImpl implements RoleService {
@Override
public void updateRole(RoleUpdateDTO roleUpdateDTO) {
// 校验角色是否存在
if (roleMapper.selectById(roleUpdateDTO.getId()) == null) {
RoleDO roleDO = roleMapper.selectById(roleUpdateDTO.getId());
if (roleDO == null) {
throw ServiceExceptionUtil.exception(SystemErrorCodeEnum.ROLE_NOT_EXISTS);
}
// 校验角色
checkRole(roleUpdateDTO.getName(), roleUpdateDTO.getCode(), roleUpdateDTO.getId());
// 内置角色,不允许修改
if (RoleTypeEnum.SYSTEM.getType().equals(roleDO.getType())) {
throw ServiceExceptionUtil.exception(SystemErrorCodeEnum.ROLE_CAN_NOT_UPDATE_SYSTEM_TYPE_ROLE);
}
// 校验角色的唯一字段是否重复
checkDuplicateRole(roleUpdateDTO.getName(), roleUpdateDTO.getCode(), roleUpdateDTO.getId());
// 更新到数据库
RoleDO roleDO = RoleConvert.INSTANCE.convert(roleUpdateDTO);
roleMapper.updateById(roleDO);
RoleDO updateRole = RoleConvert.INSTANCE.convert(roleUpdateDTO);
roleMapper.updateById(updateRole);
// TODO 插入操作日志
}
@@ -91,9 +95,14 @@ public class RoleServiceImpl implements RoleService {
@Transactional
public void deleteRole(RoleDeleteDTO roleDeleteDTO) {
// 校验角色是否存在
if (roleMapper.selectById(roleDeleteDTO.getId()) == null) {
RoleDO roleDO = roleMapper.selectById(roleDeleteDTO.getId());
if (roleDO == null) {
throw ServiceExceptionUtil.exception(SystemErrorCodeEnum.ROLE_NOT_EXISTS);
}
// 内置角色,不允许删除
if (RoleTypeEnum.SYSTEM.getType().equals(roleDO.getType())) {
throw ServiceExceptionUtil.exception(SystemErrorCodeEnum.ROLE_CAN_NOT_DELETE_SYSTEM_TYPE_ROLE);
}
// 更新到数据库,标记删除
roleMapper.deleteById(roleDeleteDTO.getId());
// 发布角色删除事件,方便清理关联表
@@ -102,7 +111,7 @@ public class RoleServiceImpl implements RoleService {
}
/**
* 校验角色是否合法
* 校验角色的唯一字段是否重复
*
* 1. 是否存在相同名字的角色
* 2. 是否存在相同编码的角色
@@ -111,31 +120,20 @@ public class RoleServiceImpl implements RoleService {
* @param code 角色额编码
* @param id 角色编号
*/
private void checkRole(String name, String code, Integer id) {
// 1. 是否存在相同名字的角色
private void checkDuplicateRole(String name, String code, Integer id) {
// 1. 该 name 名字被其它角色所使用
RoleDO role = roleMapper.selectByName(name);
if (role != null) {
// 如果 id 为空,说明不用比较是否为相同 id 的资源
if (id == null) {
throw ServiceExceptionUtil.exception(SystemErrorCodeEnum.ROLE_NAME_DUPLICATE, name);
}
if (!role.getId().equals(id)) {
throw ServiceExceptionUtil.exception(SystemErrorCodeEnum.ROLE_NAME_DUPLICATE, name);
}
if (role != null && !role.getId().equals(id)) {
throw ServiceExceptionUtil.exception(SystemErrorCodeEnum.ROLE_NAME_DUPLICATE, name);
}
// 2. 是否存在相同编码的角色
if (!StringUtil.hasText(code)) {
return;
}
// 该 code 编码被其它角色所使用
role = roleMapper.selectByCode(code);
if (role != null) {
// 如果 id 为空,说明不用比较是否为相同 id 的资源
if (id == null) {
throw ServiceExceptionUtil.exception(SystemErrorCodeEnum.ROLE_CODE_DUPLICATE, name);
}
if (!role.getId().equals(id)) {
throw ServiceExceptionUtil.exception(SystemErrorCodeEnum.ROLE_CODE_DUPLICATE, name);
}
if (role != null && !role.getId().equals(id)) {
throw ServiceExceptionUtil.exception(SystemErrorCodeEnum.ROLE_CODE_DUPLICATE, name);
}
}

View File

@@ -3,6 +3,7 @@ package cn.iocoder.mall.system.biz.service.oauth2;
import cn.iocoder.mall.system.biz.bo.ouath2.OAuth2AuthenticateBO;
import cn.iocoder.mall.system.biz.dto.oatuh2.OAuth2AccessTokenAuthenticateDTO;
import cn.iocoder.mall.system.biz.dto.oatuh2.OAuth2MobileCodeAuthenticateDTO;
import cn.iocoder.mall.system.biz.dto.oatuh2.OAuth2RefreshTokenAuthenticateDTO;
import cn.iocoder.mall.system.biz.dto.oatuh2.OAuth2UsernameAuthenticateDTO;
/**
@@ -16,4 +17,6 @@ public interface OAuth2Service {
OAuth2AuthenticateBO authenticate(OAuth2AccessTokenAuthenticateDTO authenticateDTO);
OAuth2AuthenticateBO authenticate(OAuth2RefreshTokenAuthenticateDTO authenticateDTO);
}

View File

@@ -13,8 +13,8 @@ import cn.iocoder.mall.system.biz.dataobject.oauth2.OAuth2RefreshTokenDO;
import cn.iocoder.mall.system.biz.dto.account.AccountCreateDTO;
import cn.iocoder.mall.system.biz.dto.oatuh2.OAuth2AccessTokenAuthenticateDTO;
import cn.iocoder.mall.system.biz.dto.oatuh2.OAuth2MobileCodeAuthenticateDTO;
import cn.iocoder.mall.system.biz.dto.oatuh2.OAuth2RefreshTokenAuthenticateDTO;
import cn.iocoder.mall.system.biz.dto.oatuh2.OAuth2UsernameAuthenticateDTO;
import cn.iocoder.mall.system.biz.enums.SystemErrorCodeEnum;
import cn.iocoder.mall.system.biz.service.account.AccountService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
@@ -24,8 +24,7 @@ import org.springframework.transaction.annotation.Transactional;
import java.util.Date;
import java.util.UUID;
import static cn.iocoder.mall.system.biz.enums.SystemErrorCodeEnum.OAUTH2_ACCOUNT_NOT_FOUND;
import static cn.iocoder.mall.system.biz.enums.SystemErrorCodeEnum.OAUTH2_ACCOUNT_PASSWORD_ERROR;
import static cn.iocoder.mall.system.biz.enums.SystemErrorCodeEnum.*;
@Service
public class OAuth2ServiceImpl implements OAuth2Service {
@@ -101,18 +100,42 @@ public class OAuth2ServiceImpl implements OAuth2Service {
public OAuth2AuthenticateBO authenticate(OAuth2AccessTokenAuthenticateDTO authenticateDTO) {
OAuth2AccessTokenDO oauth2AccessTokenDO = oauth2AccessTokenMapper.selectById(authenticateDTO.getAccessToken());
if (oauth2AccessTokenDO == null) { // 不存在
throw ServiceExceptionUtil.exception(SystemErrorCodeEnum.OAUTH2_ACCESS_TOKEN_NOT_FOUND.getCode());
throw ServiceExceptionUtil.exception(OAUTH2_ACCESS_TOKEN_NOT_FOUND);
}
if (oauth2AccessTokenDO.getExpiresTime().getTime() < System.currentTimeMillis()) { // 已过期
throw ServiceExceptionUtil.exception(SystemErrorCodeEnum.OAUTH2_ACCESS_TOKEN_TOKEN_EXPIRED.getCode());
throw ServiceExceptionUtil.exception(OAUTH2_ACCESS_TOKEN_TOKEN_EXPIRED);
}
if (!oauth2AccessTokenDO.getValid()) { // 无效
throw ServiceExceptionUtil.exception(SystemErrorCodeEnum.OAUTH2_ACCESS_TOKEN_INVALID.getCode());
throw ServiceExceptionUtil.exception(OAUTH2_ACCESS_TOKEN_INVALID);
}
// 转换返回
return OAuth2Convert.INSTANCE.convert(oauth2AccessTokenDO);
}
@Override
@Transactional
public OAuth2AuthenticateBO authenticate(OAuth2RefreshTokenAuthenticateDTO authenticateDTO) {
OAuth2RefreshTokenDO refreshTokenDO = oauth2RefreshTokenMapper.selectById(authenticateDTO.getRefreshToken());
// 校验刷新令牌是否合法
if (refreshTokenDO == null) { // 不存在
throw ServiceExceptionUtil.exception(OAUTH2_REFRESH_TOKEN_NOT_FOUND);
}
if (refreshTokenDO.getExpiresTime().getTime() < System.currentTimeMillis()) { // 已过期
throw ServiceExceptionUtil.exception(OAUTH_REFRESH_TOKEN_EXPIRED);
}
if (!refreshTokenDO.getValid()) { // 无效
throw ServiceExceptionUtil.exception(OAUTH_REFRESH_TOKEN_INVALID);
}
// 标记 refreshToken 对应的 accessToken 都不合法
// 这块的实现,参考了 Spring Security OAuth2 的代码
oauth2AccessTokenMapper.updateToInvalidByRefreshToken(authenticateDTO.getRefreshToken());
// 创建访问令牌
OAuth2AccessTokenDO oauth2AccessTokenDO = createOAuth2AccessToken(refreshTokenDO.getAccountId(),
refreshTokenDO.getId());
// 转换返回
return OAuth2Convert.INSTANCE.convert(oauth2AccessTokenDO);
}
private OAuth2AccessTokenDO createOAuth2AccessToken(Integer accountId, String refreshToken) {
OAuth2AccessTokenDO accessToken = new OAuth2AccessTokenDO()
.setId(generateAccessToken())