diff --git a/README.md b/README.md index 4c950c431..20de435d7 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,10 @@ > 一起交流,Get 知识。 * 我们迫切希望更多的参与进来,可以加入「交流群」,一起骚聊。 - * [《Onemall 电商开源项目 —— 应用分层》](http://www.iocoder.cn/Onemall/Application-layer/?vip&onemall) + * [《Onemall 电商开源项目 —— 应用分层》](http://www.iocoder.cn/Onemall/Application-layer/?onemall) + * [《Onemall 电商开源项目 —— 搭建调试环境》](http://www.iocoder.cn/Onemall/build-debugger-environment/?onemall) + +* 前端项目地址: # 演示 @@ -95,7 +98,7 @@ ## 搭建环境 -[搭建调试环境](https://gitee.com/zhijiantianya/onemall/blob/master/docs/setup/quick-start.md) +[搭建调试环境](http://www.iocoder.cn/Onemall/build-debugger-environment/) ## 架构图 diff --git a/common/common-framework/src/main/java/cn/iocoder/common/framework/exception/enums/GlobalErrorCodeConstants.java b/common/common-framework/src/main/java/cn/iocoder/common/framework/exception/enums/GlobalErrorCodeConstants.java index da4df581c..9b72a9958 100644 --- a/common/common-framework/src/main/java/cn/iocoder/common/framework/exception/enums/GlobalErrorCodeConstants.java +++ b/common/common-framework/src/main/java/cn/iocoder/common/framework/exception/enums/GlobalErrorCodeConstants.java @@ -28,7 +28,6 @@ public interface GlobalErrorCodeConstants { ErrorCode UNKNOWN = new ErrorCode(999, "未知错误"); - static boolean isMatch(Integer code) { return code != null && code >= SUCCESS.getCode() && code <= UNKNOWN.getCode(); diff --git a/common/common-framework/src/main/java/cn/iocoder/common/framework/exception/util/ServiceExceptionUtil.java b/common/common-framework/src/main/java/cn/iocoder/common/framework/exception/util/ServiceExceptionUtil.java index 0a758db97..5f8cf5d4e 100644 --- a/common/common-framework/src/main/java/cn/iocoder/common/framework/exception/util/ServiceExceptionUtil.java +++ b/common/common-framework/src/main/java/cn/iocoder/common/framework/exception/util/ServiceExceptionUtil.java @@ -15,7 +15,7 @@ import java.util.concurrent.ConcurrentMap; * 目的在于,格式化异常信息提示。 * 考虑到 String.format 在参数不正确时会报错,因此使用 {} 作为占位符,并使用 {@link #doFormat(int, String, Object...)} 方法来格式化 * - * 因为 {@link #messages} 里面默认是没有异常信息提示的模板的,所以需要使用方自己初始化进去。目前想到的有几种方式: + * 因为 {@link #MESSAGES} 里面默认是没有异常信息提示的模板的,所以需要使用方自己初始化进去。目前想到的有几种方式: * * 1. 异常提示信息,写在枚举类中,例如说,cn.iocoder.oceans.user.api.constants.ErrorCodeEnum 类 + ServiceExceptionConfiguration * 2. 异常提示信息,写在 .properties 等等配置文件 @@ -29,29 +29,29 @@ public class ServiceExceptionUtil { /** * 错误码提示模板 */ - private static ConcurrentMap messages = new ConcurrentHashMap<>(); + private static final ConcurrentMap MESSAGES = new ConcurrentHashMap<>(); public static void putAll(Map messages) { - ServiceExceptionUtil.messages.putAll(messages); + ServiceExceptionUtil.MESSAGES.putAll(messages); } public static void put(Integer code, String message) { - ServiceExceptionUtil.messages.put(code, message); + ServiceExceptionUtil.MESSAGES.put(code, message); } public static void delete(Integer code, String message) { - ServiceExceptionUtil.messages.remove(code, message); + ServiceExceptionUtil.MESSAGES.remove(code, message); } // ========== 和 ServiceException 的集成 ========== public static ServiceException exception(ErrorCode errorCode) { - String messagePattern = messages.getOrDefault(errorCode.getCode(), errorCode.getMessage()); + String messagePattern = MESSAGES.getOrDefault(errorCode.getCode(), errorCode.getMessage()); return exception0(errorCode.getCode(), messagePattern); } public static ServiceException exception(ErrorCode errorCode, Object... params) { - String messagePattern = messages.getOrDefault(errorCode.getCode(), errorCode.getMessage()); + String messagePattern = MESSAGES.getOrDefault(errorCode.getCode(), errorCode.getMessage()); return exception0(errorCode.getCode(), messagePattern, params); } @@ -62,7 +62,7 @@ public class ServiceExceptionUtil { * @return 异常 */ public static ServiceException exception(Integer code) { - return exception0(code, messages.get(code)); + return exception0(code, MESSAGES.get(code)); } /** @@ -73,7 +73,7 @@ public class ServiceExceptionUtil { * @return 异常 */ public static ServiceException exception(Integer code, Object... params) { - return exception0(code, messages.get(code), params); + return exception0(code, MESSAGES.get(code), params); } public static ServiceException exception0(Integer code, String messagePattern, Object... params) { diff --git a/common/mall-spring-boot-starter-redis/src/main/java/cn/iocoder/mall/redis/core/RedisKeyDefine.java b/common/mall-spring-boot-starter-redis/src/main/java/cn/iocoder/mall/redis/core/RedisKeyDefine.java index 0ac7ece2d..868de21bf 100644 --- a/common/mall-spring-boot-starter-redis/src/main/java/cn/iocoder/mall/redis/core/RedisKeyDefine.java +++ b/common/mall-spring-boot-starter-redis/src/main/java/cn/iocoder/mall/redis/core/RedisKeyDefine.java @@ -37,7 +37,7 @@ public class RedisKeyDefine { * * 如果是使用分布式锁,设置为 {@link java.util.concurrent.locks.Lock} 类型 */ - private final Class valueType; + private final Class valueType; /** * 过期时间 * @@ -45,7 +45,7 @@ public class RedisKeyDefine { */ private final Duration timeout; - public RedisKeyDefine(String keyTemplate, KeyTypeEnum keyType, Class valueType, Duration timeout) { + public RedisKeyDefine(String keyTemplate, KeyTypeEnum keyType, Class valueType, Duration timeout) { this.keyTemplate = keyTemplate; this.keyType = keyType; this.valueType = valueType; @@ -60,7 +60,7 @@ public class RedisKeyDefine { return keyType; } - public Class getValueType() { + public Class getValueType() { return valueType; } diff --git a/management-web-app/src/main/java/cn/iocoder/mall/managementweb/controller/datadict/vo/DataDictSimpleVO.java b/management-web-app/src/main/java/cn/iocoder/mall/managementweb/controller/datadict/vo/DataDictSimpleVO.java index acdafbfcf..784b56acc 100644 --- a/management-web-app/src/main/java/cn/iocoder/mall/managementweb/controller/datadict/vo/DataDictSimpleVO.java +++ b/management-web-app/src/main/java/cn/iocoder/mall/managementweb/controller/datadict/vo/DataDictSimpleVO.java @@ -11,13 +11,10 @@ import javax.validation.constraints.NotEmpty; public class DataDictSimpleVO { @ApiModelProperty(value = "大类枚举值", required = true, example = "gender") - @NotEmpty(message = "大类枚举值不能为空") private String enumValue; @ApiModelProperty(value = "小类数值", required = true, example = "1") - @NotEmpty(message = "小类数值不能为空") private String value; @ApiModelProperty(value = "展示名", required = true, example = "男") - @NotEmpty(message = "展示名不能为空") private String displayName; } diff --git a/management-web-app/src/main/java/cn/iocoder/mall/managementweb/controller/user/vo/UserUpdateStatusReqVO.java b/management-web-app/src/main/java/cn/iocoder/mall/managementweb/controller/user/vo/UserUpdateStatusReqVO.java index 6f3569f03..d8b43b7ca 100644 --- a/management-web-app/src/main/java/cn/iocoder/mall/managementweb/controller/user/vo/UserUpdateStatusReqVO.java +++ b/management-web-app/src/main/java/cn/iocoder/mall/managementweb/controller/user/vo/UserUpdateStatusReqVO.java @@ -15,6 +15,7 @@ public class UserUpdateStatusReqVO { @ApiModelProperty(value = "用户编号", required = true) @NotNull(message = "用户编号不能为空") private Integer userId; + @ApiModelProperty(value = "状态", required = true, example = "1", notes = "见 CommonStatusEnum 枚举") @NotNull(message = "状态不能为空") @InEnum(value = CommonStatusEnum.class, message = "修改状态必须是 {value}") diff --git a/management-web-app/src/main/java/cn/iocoder/mall/managementweb/service/pay/transaction/PayTransactionService.java b/management-web-app/src/main/java/cn/iocoder/mall/managementweb/service/pay/transaction/PayTransactionService.java index 61cbb69ac..ca322453d 100644 --- a/management-web-app/src/main/java/cn/iocoder/mall/managementweb/service/pay/transaction/PayTransactionService.java +++ b/management-web-app/src/main/java/cn/iocoder/mall/managementweb/service/pay/transaction/PayTransactionService.java @@ -6,13 +6,18 @@ import cn.iocoder.mall.managementweb.controller.pay.vo.transaction.PayTransactio import cn.iocoder.mall.managementweb.controller.pay.vo.transaction.PayTransactionRespVO; import cn.iocoder.mall.managementweb.convert.pay.transaction.PayTransactionConvert; import cn.iocoder.mall.payservice.rpc.transaction.dto.PayTransactionRespDTO; +import com.google.common.collect.Lists; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import javax.annotation.Resource; +import java.util.List; +import java.util.stream.Stream; + @Service public class PayTransactionService { - @Autowired + @Resource private PayTransactionClient payTransactionClient; public PageResult pagePayTransaction(PayTransactionPageReqVO pageReqVO) { diff --git a/system-service-project/system-service-app/src/main/java/cn/iocoder/mall/systemservice/manager/permission/PermissionManager.java b/system-service-project/system-service-app/src/main/java/cn/iocoder/mall/systemservice/manager/permission/PermissionManager.java index ad40fac28..f3e623487 100644 --- a/system-service-project/system-service-app/src/main/java/cn/iocoder/mall/systemservice/manager/permission/PermissionManager.java +++ b/system-service-project/system-service-app/src/main/java/cn/iocoder/mall/systemservice/manager/permission/PermissionManager.java @@ -7,7 +7,7 @@ import cn.iocoder.mall.systemservice.rpc.permission.dto.PermissionAssignAdminRol import cn.iocoder.mall.systemservice.rpc.permission.dto.PermissionAssignRoleResourceDTO; import cn.iocoder.mall.systemservice.rpc.permission.dto.PermissionCheckDTO; import cn.iocoder.mall.systemservice.service.permission.PermissionService; -import cn.iocoder.mall.systemservice.service.permission.ResourceService; +import cn.iocoder.mall.systemservice.service.permission.ResourceServiceImpl; import cn.iocoder.mall.systemservice.service.permission.RoleService; import cn.iocoder.mall.systemservice.service.permission.bo.ResourceBO; import org.springframework.beans.factory.annotation.Autowired; @@ -31,7 +31,7 @@ public class PermissionManager { @Autowired private RoleService roleService; @Autowired - private ResourceService resourceService; + private ResourceServiceImpl resourceService; /** * 获得角色拥有的资源编号 diff --git a/system-service-project/system-service-app/src/main/java/cn/iocoder/mall/systemservice/manager/permission/ResourceManager.java b/system-service-project/system-service-app/src/main/java/cn/iocoder/mall/systemservice/manager/permission/ResourceManager.java index ed9dcc072..04e9f572e 100644 --- a/system-service-project/system-service-app/src/main/java/cn/iocoder/mall/systemservice/manager/permission/ResourceManager.java +++ b/system-service-project/system-service-app/src/main/java/cn/iocoder/mall/systemservice/manager/permission/ResourceManager.java @@ -4,7 +4,7 @@ import cn.iocoder.mall.systemservice.convert.permission.ResourceConvert; import cn.iocoder.mall.systemservice.rpc.permission.dto.ResourceCreateDTO; import cn.iocoder.mall.systemservice.rpc.permission.dto.ResourceUpdateDTO; import cn.iocoder.mall.systemservice.rpc.permission.vo.ResourceVO; -import cn.iocoder.mall.systemservice.service.permission.ResourceService; +import cn.iocoder.mall.systemservice.service.permission.ResourceServiceImpl; import cn.iocoder.mall.systemservice.service.permission.RoleService; import cn.iocoder.mall.systemservice.service.permission.bo.ResourceBO; import org.springframework.beans.factory.annotation.Autowired; @@ -20,7 +20,7 @@ import java.util.List; public class ResourceManager { @Autowired - private ResourceService resourceService; + private ResourceServiceImpl resourceService; @Autowired private RoleService roleService; diff --git a/system-service-project/system-service-app/src/main/java/cn/iocoder/mall/systemservice/service/permission/ResourceService.java b/system-service-project/system-service-app/src/main/java/cn/iocoder/mall/systemservice/service/permission/ResourceService.java index ce7998511..32c1d4f06 100644 --- a/system-service-project/system-service-app/src/main/java/cn/iocoder/mall/systemservice/service/permission/ResourceService.java +++ b/system-service-project/system-service-app/src/main/java/cn/iocoder/mall/systemservice/service/permission/ResourceService.java @@ -1,230 +1,7 @@ package cn.iocoder.mall.systemservice.service.permission; -import cn.iocoder.common.framework.util.CollectionUtils; -import cn.iocoder.common.framework.exception.util.ServiceExceptionUtil; -import cn.iocoder.mall.systemservice.convert.permission.ResourceConvert; -import cn.iocoder.mall.systemservice.dal.mysql.dataobject.permission.ResourceDO; -import cn.iocoder.mall.systemservice.dal.mysql.dataobject.permission.RoleResourceDO; -import cn.iocoder.mall.systemservice.dal.mysql.mapper.permission.ResourceMapper; -import cn.iocoder.mall.systemservice.dal.mysql.mapper.permission.RoleResourceMapper; -import cn.iocoder.mall.systemservice.enums.SystemErrorCodeConstants; -import cn.iocoder.mall.systemservice.enums.permission.ResourceIdEnum; -import cn.iocoder.mall.systemservice.enums.permission.ResourceTypeEnum; -import cn.iocoder.mall.systemservice.service.permission.bo.ResourceBO; -import cn.iocoder.mall.systemservice.service.permission.bo.ResourceCreateBO; -import cn.iocoder.mall.systemservice.service.permission.bo.ResourceUpdateBO; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; -import org.springframework.validation.annotation.Validated; - -import javax.validation.Valid; -import java.util.Collection; -import java.util.Collections; -import java.util.List; - -import static cn.iocoder.mall.systemservice.enums.SystemErrorCodeConstants.*; - /** -* 资源 Service -*/ -@Service -@Validated -public class ResourceService { - - @Autowired - private ResourceMapper resourceMapper; - @Autowired - private RoleResourceMapper roleResourceMapper; - - /** - * 创建资源 - * - * @param createBO 创建资源 BO - * @return 资源 - */ - public ResourceBO createResource(@Valid ResourceCreateBO createBO) { - // 校验父资源存在 - checkParentResource(createBO.getPid(), null); - // 校验资源(自己) - checkResource(createBO.getPid(), createBO.getName(), null); - // 插入数据库 - ResourceDO resourceDO = ResourceConvert.INSTANCE.convert(createBO); - initResourceProperty(resourceDO); - resourceMapper.insert(resourceDO); - // 返回 - return ResourceConvert.INSTANCE.convert(resourceDO); - } - - /** - * 更新资源 - * - * @param updateBO 更新资源 BO - */ - public void updateResource(@Valid ResourceUpdateBO updateBO) { - // 校验更新的资源是否存在 - if (resourceMapper.selectById(updateBO.getId()) == null) { - throw ServiceExceptionUtil.exception(RESOURCE_NOT_EXISTS); - } - // 校验父资源存在 - checkParentResource(updateBO.getPid(), updateBO.getId()); - // 校验资源(自己) - checkResource(updateBO.getPid(), updateBO.getName(), updateBO.getId()); - // 更新到数据库 - ResourceDO updateObject = ResourceConvert.INSTANCE.convert(updateBO); - initResourceProperty(updateObject); - resourceMapper.updateById(updateObject); - } - - /** - * 删除资源 - * - * @param resourceId 资源编号 - */ - public void deleteResource(Integer resourceId) { - // 校验更新的资源是否存在 - if (resourceMapper.selectById(resourceId) == null) { - throw ServiceExceptionUtil.exception(SystemErrorCodeConstants.RESOURCE_NOT_EXISTS); - } - // 校验是否还有子资源 - if (resourceMapper.selectCountByPid(resourceId) > 0) { - throw ServiceExceptionUtil.exception(SystemErrorCodeConstants.RESOURCE_EXISTS_CHILDREN); - } - // 校验删除的资源是否存在 - if (resourceMapper.selectById(resourceId) == null) { - throw ServiceExceptionUtil.exception(RESOURCE_NOT_EXISTS); - } - // 标记删除 - resourceMapper.deleteById(resourceId); - // 删除授予给角色的权限 - roleResourceMapper.deleteByResourceId(resourceId); - } - - /** - * 获得资源 - * - * @param resourceId 资源编号 - * @return 资源 - */ - public ResourceBO getResource(Integer resourceId) { - ResourceDO resourceDO = resourceMapper.selectById(resourceId); - return ResourceConvert.INSTANCE.convert(resourceDO); - } - - /** - * 获得资源列表 - * - * @param resourceIds 资源编号列表 - * @return 资源列表 - */ - public List listResources(List resourceIds) { - List resourceDOs = resourceMapper.selectBatchIds(resourceIds); - return ResourceConvert.INSTANCE.convertList(resourceDOs); - } - - /** - * 获得资源全列表 - * - * @return 资源全列表 - */ - public List listResources() { - List resourceDOs = resourceMapper.selectList(null); - return ResourceConvert.INSTANCE.convertList(resourceDOs); - } - - /** - * 获得指定类型的资源列表 - * - * @param type 资源类型,允许空 - * @return 资源列表 - */ - public List listResourcesByType(Integer type) { - List resourceDOs = resourceMapper.selectListByType(type); - return ResourceConvert.INSTANCE.convertList(resourceDOs); - } - - /** - * 获得角色拥有的资源列表 - * - * @param roleIds 角色编号 - * @param type 资源类型,允许空 - * @return 资源列表 - */ - public List listRoleResourcesByType(Collection roleIds, Integer type) { - List roleResourceDOs = roleResourceMapper.selectListByRoleIds(roleIds); - if (CollectionUtils.isEmpty(roleResourceDOs)) { - return Collections.emptyList(); - } - List resourceDOs = resourceMapper.selectListByIdsAndType( - CollectionUtils.convertSet(roleResourceDOs, RoleResourceDO::getResourceId), type); - return ResourceConvert.INSTANCE.convertList(resourceDOs); - } - - /** - * 校验父资源是否合法 - * - * 1. 不能设置自己为父资源 - * 2. 父资源不存在 - * 3. 父资源必须是 {@link ResourceTypeEnum#MENU} 菜单类型 - * - * @param pid 父资源编号 - * @param childId 当前资源编号 - */ - private void checkParentResource(Integer pid, Integer childId) { - if (pid == null || ResourceIdEnum.ROOT.getId().equals(pid)) { - return; - } - // 不能设置自己为父资源 - if (pid.equals(childId)) { - throw ServiceExceptionUtil.exception(RESOURCE_PARENT_ERROR); - } - ResourceDO resource = resourceMapper.selectById(pid); - // 父资源不存在 - if (resource == null) { - throw ServiceExceptionUtil.exception(RESOURCE_PARENT_NOT_EXISTS); - } - // 父资源必须是菜单类型 - if (!ResourceTypeEnum.MENU.getType().equals(resource.getType())) { - throw ServiceExceptionUtil.exception(RESOURCE_PARENT_NOT_MENU); - } - } - - /** - * 校验资源是否合法 - * - * 1. 校验相同父资源编号下,是否存在相同的资源名 - * - * @param name 资源名字 - * @param pid 父资源编号 - * @param id 资源编号 - */ - private void checkResource(Integer pid, String name, Integer id) { - ResourceDO resource = resourceMapper.selectByPidAndName(pid, name); - if (resource == null) { - return; - } - // 如果 id 为空,说明不用比较是否为相同 id 的资源 - if (id == null) { - throw ServiceExceptionUtil.exception(RESOURCE_NAME_DUPLICATE); - } - if (!resource.getId().equals(id)) { - throw ServiceExceptionUtil.exception(RESOURCE_NAME_DUPLICATE); - } - } - - /** - * 初始化资源的通用属性。 - * - * 例如说,只有菜单类型的资源,才设置 icon - * - * @param resource 资源 - */ - private void initResourceProperty(ResourceDO resource) { - // 资源为按钮类型时,无需 route、icon、view 属性,进行置空 - if (ResourceTypeEnum.BUTTON.getType().equals(resource.getType())) { - resource.setRoute(null); - resource.setIcon(null); - resource.setView(null); - } - } - + * 资源 Service 接口 + */ +public interface ResourceService { } diff --git a/system-service-project/system-service-app/src/main/java/cn/iocoder/mall/systemservice/service/permission/ResourceServiceImpl.java b/system-service-project/system-service-app/src/main/java/cn/iocoder/mall/systemservice/service/permission/ResourceServiceImpl.java new file mode 100644 index 000000000..d2408fe43 --- /dev/null +++ b/system-service-project/system-service-app/src/main/java/cn/iocoder/mall/systemservice/service/permission/ResourceServiceImpl.java @@ -0,0 +1,230 @@ +package cn.iocoder.mall.systemservice.service.permission; + +import cn.iocoder.common.framework.util.CollectionUtils; +import cn.iocoder.common.framework.exception.util.ServiceExceptionUtil; +import cn.iocoder.mall.systemservice.convert.permission.ResourceConvert; +import cn.iocoder.mall.systemservice.dal.mysql.dataobject.permission.ResourceDO; +import cn.iocoder.mall.systemservice.dal.mysql.dataobject.permission.RoleResourceDO; +import cn.iocoder.mall.systemservice.dal.mysql.mapper.permission.ResourceMapper; +import cn.iocoder.mall.systemservice.dal.mysql.mapper.permission.RoleResourceMapper; +import cn.iocoder.mall.systemservice.enums.SystemErrorCodeConstants; +import cn.iocoder.mall.systemservice.enums.permission.ResourceIdEnum; +import cn.iocoder.mall.systemservice.enums.permission.ResourceTypeEnum; +import cn.iocoder.mall.systemservice.service.permission.bo.ResourceBO; +import cn.iocoder.mall.systemservice.service.permission.bo.ResourceCreateBO; +import cn.iocoder.mall.systemservice.service.permission.bo.ResourceUpdateBO; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.validation.annotation.Validated; + +import javax.validation.Valid; +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +import static cn.iocoder.mall.systemservice.enums.SystemErrorCodeConstants.*; + +/** +* 资源 Service +*/ +@Service +@Validated +public class ResourceServiceImpl implements ResourceService { + + @Autowired + private ResourceMapper resourceMapper; + @Autowired + private RoleResourceMapper roleResourceMapper; + + /** + * 创建资源 + * + * @param createBO 创建资源 BO + * @return 资源 + */ + public ResourceBO createResource(@Valid ResourceCreateBO createBO) { + // 校验父资源存在 + checkParentResource(createBO.getPid(), null); + // 校验资源(自己) + checkResource(createBO.getPid(), createBO.getName(), null); + // 插入数据库 + ResourceDO resourceDO = ResourceConvert.INSTANCE.convert(createBO); + initResourceProperty(resourceDO); + resourceMapper.insert(resourceDO); + // 返回 + return ResourceConvert.INSTANCE.convert(resourceDO); + } + + /** + * 更新资源 + * + * @param updateBO 更新资源 BO + */ + public void updateResource(@Valid ResourceUpdateBO updateBO) { + // 校验更新的资源是否存在 + if (resourceMapper.selectById(updateBO.getId()) == null) { + throw ServiceExceptionUtil.exception(RESOURCE_NOT_EXISTS); + } + // 校验父资源存在 + checkParentResource(updateBO.getPid(), updateBO.getId()); + // 校验资源(自己) + checkResource(updateBO.getPid(), updateBO.getName(), updateBO.getId()); + // 更新到数据库 + ResourceDO updateObject = ResourceConvert.INSTANCE.convert(updateBO); + initResourceProperty(updateObject); + resourceMapper.updateById(updateObject); + } + + /** + * 删除资源 + * + * @param resourceId 资源编号 + */ + public void deleteResource(Integer resourceId) { + // 校验更新的资源是否存在 + if (resourceMapper.selectById(resourceId) == null) { + throw ServiceExceptionUtil.exception(SystemErrorCodeConstants.RESOURCE_NOT_EXISTS); + } + // 校验是否还有子资源 + if (resourceMapper.selectCountByPid(resourceId) > 0) { + throw ServiceExceptionUtil.exception(SystemErrorCodeConstants.RESOURCE_EXISTS_CHILDREN); + } + // 校验删除的资源是否存在 + if (resourceMapper.selectById(resourceId) == null) { + throw ServiceExceptionUtil.exception(RESOURCE_NOT_EXISTS); + } + // 标记删除 + resourceMapper.deleteById(resourceId); + // 删除授予给角色的权限 + roleResourceMapper.deleteByResourceId(resourceId); + } + + /** + * 获得资源 + * + * @param resourceId 资源编号 + * @return 资源 + */ + public ResourceBO getResource(Integer resourceId) { + ResourceDO resourceDO = resourceMapper.selectById(resourceId); + return ResourceConvert.INSTANCE.convert(resourceDO); + } + + /** + * 获得资源列表 + * + * @param resourceIds 资源编号列表 + * @return 资源列表 + */ + public List listResources(List resourceIds) { + List resourceDOs = resourceMapper.selectBatchIds(resourceIds); + return ResourceConvert.INSTANCE.convertList(resourceDOs); + } + + /** + * 获得资源全列表 + * + * @return 资源全列表 + */ + public List listResources() { + List resourceDOs = resourceMapper.selectList(null); + return ResourceConvert.INSTANCE.convertList(resourceDOs); + } + + /** + * 获得指定类型的资源列表 + * + * @param type 资源类型,允许空 + * @return 资源列表 + */ + public List listResourcesByType(Integer type) { + List resourceDOs = resourceMapper.selectListByType(type); + return ResourceConvert.INSTANCE.convertList(resourceDOs); + } + + /** + * 获得角色拥有的资源列表 + * + * @param roleIds 角色编号 + * @param type 资源类型,允许空 + * @return 资源列表 + */ + public List listRoleResourcesByType(Collection roleIds, Integer type) { + List roleResourceDOs = roleResourceMapper.selectListByRoleIds(roleIds); + if (CollectionUtils.isEmpty(roleResourceDOs)) { + return Collections.emptyList(); + } + List resourceDOs = resourceMapper.selectListByIdsAndType( + CollectionUtils.convertSet(roleResourceDOs, RoleResourceDO::getResourceId), type); + return ResourceConvert.INSTANCE.convertList(resourceDOs); + } + + /** + * 校验父资源是否合法 + * + * 1. 不能设置自己为父资源 + * 2. 父资源不存在 + * 3. 父资源必须是 {@link ResourceTypeEnum#MENU} 菜单类型 + * + * @param pid 父资源编号 + * @param childId 当前资源编号 + */ + private void checkParentResource(Integer pid, Integer childId) { + if (pid == null || ResourceIdEnum.ROOT.getId().equals(pid)) { + return; + } + // 不能设置自己为父资源 + if (pid.equals(childId)) { + throw ServiceExceptionUtil.exception(RESOURCE_PARENT_ERROR); + } + ResourceDO resource = resourceMapper.selectById(pid); + // 父资源不存在 + if (resource == null) { + throw ServiceExceptionUtil.exception(RESOURCE_PARENT_NOT_EXISTS); + } + // 父资源必须是菜单类型 + if (!ResourceTypeEnum.MENU.getType().equals(resource.getType())) { + throw ServiceExceptionUtil.exception(RESOURCE_PARENT_NOT_MENU); + } + } + + /** + * 校验资源是否合法 + * + * 1. 校验相同父资源编号下,是否存在相同的资源名 + * + * @param name 资源名字 + * @param pid 父资源编号 + * @param id 资源编号 + */ + private void checkResource(Integer pid, String name, Integer id) { + ResourceDO resource = resourceMapper.selectByPidAndName(pid, name); + if (resource == null) { + return; + } + // 如果 id 为空,说明不用比较是否为相同 id 的资源 + if (id == null) { + throw ServiceExceptionUtil.exception(RESOURCE_NAME_DUPLICATE); + } + if (!resource.getId().equals(id)) { + throw ServiceExceptionUtil.exception(RESOURCE_NAME_DUPLICATE); + } + } + + /** + * 初始化资源的通用属性。 + * + * 例如说,只有菜单类型的资源,才设置 icon + * + * @param resource 资源 + */ + private void initResourceProperty(ResourceDO resource) { + // 资源为按钮类型时,无需 route、icon、view 属性,进行置空 + if (ResourceTypeEnum.BUTTON.getType().equals(resource.getType())) { + resource.setRoute(null); + resource.setIcon(null); + resource.setView(null); + } + } + +}