diff --git a/management-web-app/pom.xml b/management-web-app/pom.xml new file mode 100644 index 000000000..f45ef6288 --- /dev/null +++ b/management-web-app/pom.xml @@ -0,0 +1,88 @@ + + + + onemall + cn.iocoder.mall + 1.0-SNAPSHOT + + 4.0.0 + + management-web-app + 管理后台,提供管理员管理的所有功能 + + + + + + cn.iocoder.mall + mall-dependencies + 1.0-SNAPSHOT + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + com.alibaba.cloud + spring-cloud-starter-dubbo + + + + + cn.iocoder.mall + user-service-api + 1.0-SNAPSHOT + + + + cn.iocoder.mall + system-service-api + 1.0-SNAPSHOT + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + + + + + org.projectlombok + lombok + + + + org.mapstruct + mapstruct + + + org.mapstruct + mapstruct-jdk8 + + + + + + + + + + + + + + + + diff --git a/management-web-app/src/main/java/cn/iocoder/mall/managementweb/ManagementWebApplication.java b/management-web-app/src/main/java/cn/iocoder/mall/managementweb/ManagementWebApplication.java new file mode 100644 index 000000000..121979533 --- /dev/null +++ b/management-web-app/src/main/java/cn/iocoder/mall/managementweb/ManagementWebApplication.java @@ -0,0 +1,13 @@ +package cn.iocoder.mall.managementweb; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class ManagementWebApplication { + + public static void main(String[] args) { + SpringApplication.run(ManagementWebApplication.class, args); + } + +} diff --git a/management-web-app/src/main/java/cn/iocoder/mall/managementweb/controller/passport/AdminPassportController.java b/management-web-app/src/main/java/cn/iocoder/mall/managementweb/controller/passport/AdminPassportController.java new file mode 100644 index 000000000..89ed6e92a --- /dev/null +++ b/management-web-app/src/main/java/cn/iocoder/mall/managementweb/controller/passport/AdminPassportController.java @@ -0,0 +1,35 @@ +package cn.iocoder.mall.managementweb.controller.passport; + +import cn.iocoder.common.framework.util.HttpUtil; +import cn.iocoder.common.framework.vo.CommonResult; +import cn.iocoder.mall.managementweb.controller.passport.dto.AdminPassportLoginDTO; +import cn.iocoder.mall.managementweb.controller.passport.vo.AdminPassportVO; +import cn.iocoder.mall.managementweb.manager.admin.AdminPassportManager; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.servlet.http.HttpServletRequest; + +import static cn.iocoder.common.framework.vo.CommonResult.success; + +@Api(tags = "管理员 Passport API") +@RestController +@RequestMapping("/passport") +public class AdminPassportController { + + @Autowired + private AdminPassportManager adminPassportManager; + + @PostMapping("/login") + @ApiOperation("账号密码登陆") +// @RequiresNone TODO 晚点加上 + public CommonResult login(AdminPassportLoginDTO loginDTO, + HttpServletRequest request) { + return success(adminPassportManager.login(loginDTO, HttpUtil.getIp(request))); + } + +} diff --git a/system/system-rest/src/main/java/cn/iocoder/mall/system/rest/request/oauth2/AdminsOAuth2UsernameAuthenticateRequest.java b/management-web-app/src/main/java/cn/iocoder/mall/managementweb/controller/passport/dto/AdminPassportLoginDTO.java similarity index 75% rename from system/system-rest/src/main/java/cn/iocoder/mall/system/rest/request/oauth2/AdminsOAuth2UsernameAuthenticateRequest.java rename to management-web-app/src/main/java/cn/iocoder/mall/managementweb/controller/passport/dto/AdminPassportLoginDTO.java index 2388568f3..fd5c301da 100644 --- a/system/system-rest/src/main/java/cn/iocoder/mall/system/rest/request/oauth2/AdminsOAuth2UsernameAuthenticateRequest.java +++ b/management-web-app/src/main/java/cn/iocoder/mall/managementweb/controller/passport/dto/AdminPassportLoginDTO.java @@ -1,4 +1,4 @@ -package cn.iocoder.mall.system.rest.request.oauth2; +package cn.iocoder.mall.managementweb.controller.passport.dto; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; @@ -8,11 +8,12 @@ import org.hibernate.validator.constraints.Length; import javax.validation.constraints.NotEmpty; import javax.validation.constraints.Pattern; +import java.io.Serializable; -@ApiModel("管理员 - OAuth2 模块 - 用户名认证请求") +@ApiModel("管理登录 DTO") @Data @Accessors(chain = true) -public class AdminsOAuth2UsernameAuthenticateRequest { +public class AdminPassportLoginDTO implements Serializable { @ApiModelProperty(value = "用户名", required = true, example = "yudaoyuanma") @NotEmpty(message = "登陆账号不能为空") @@ -20,7 +21,7 @@ public class AdminsOAuth2UsernameAuthenticateRequest { @Pattern(regexp = "^[A-Za-z0-9]+$", message = "账号格式为数字以及字母") private String username; - @ApiModelProperty(value = "用户名", required = true, example = "buzhidao") + @ApiModelProperty(value = "密码", required = true, example = "buzhidao") @NotEmpty(message = "密码不能为空") @Length(min = 4, max = 16, message = "密码长度为 4-16 位") private String password; diff --git a/management-web-app/src/main/java/cn/iocoder/mall/managementweb/controller/passport/vo/AdminPassportVO.java b/management-web-app/src/main/java/cn/iocoder/mall/managementweb/controller/passport/vo/AdminPassportVO.java new file mode 100644 index 000000000..854e1744e --- /dev/null +++ b/management-web-app/src/main/java/cn/iocoder/mall/managementweb/controller/passport/vo/AdminPassportVO.java @@ -0,0 +1,50 @@ +package cn.iocoder.mall.managementweb.controller.passport.vo; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.experimental.Accessors; + +import java.util.Date; + +@ApiModel("管理员通信证信息 VO") +@Data +@Accessors(chain = true) +public class AdminPassportVO { + + @ApiModel("认证信息") + @Data + @Accessors(chain = true) + public static class Authentication { + + @ApiModelProperty(value = "访问令牌", required = true, example = "001e8f49b20e47f7b3a2de774497cd50") + private String accessToken; + @ApiModelProperty(value = "刷新令牌", required = true, example = "001e8f49b20e47f7b3a2de774497cd50") + private String refreshToken; + @ApiModelProperty(value = "过期时间", required = true) + private Date expiresTime; + + } + + @ApiModel("管理员信息") + @Data + @Accessors(chain = true) + public static class Admin { + + @ApiModelProperty(value = "用户编号", required = true, example = "1") + private Integer id; + @ApiModelProperty(value = "真实姓名", required = true, example = "小王") + private String name; + + } + + /** + * 管理员信息 + */ + private Admin admin; + /** + * 认证信息 + */ + private Authentication authorization; + +} diff --git a/management-web-app/src/main/java/cn/iocoder/mall/managementweb/convert/passport/AdminPassportConvert.java b/management-web-app/src/main/java/cn/iocoder/mall/managementweb/convert/passport/AdminPassportConvert.java new file mode 100644 index 000000000..ef04b1b39 --- /dev/null +++ b/management-web-app/src/main/java/cn/iocoder/mall/managementweb/convert/passport/AdminPassportConvert.java @@ -0,0 +1,24 @@ +package cn.iocoder.mall.managementweb.convert.passport; + +import cn.iocoder.mall.managementweb.controller.passport.dto.AdminPassportLoginDTO; +import cn.iocoder.mall.managementweb.controller.passport.vo.AdminPassportVO; +import cn.iocoder.mall.systemservice.rpc.admin.dto.AdminVerifyPasswordDTO; +import cn.iocoder.mall.systemservice.rpc.admin.vo.AdminVO; +import cn.iocoder.mall.systemservice.rpc.oauth.vo.OAuth2AccessTokenVO; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +@Mapper +public interface AdminPassportConvert { + + AdminPassportConvert INSTANCE = Mappers.getMapper(AdminPassportConvert.class); + + AdminVerifyPasswordDTO convert(AdminPassportLoginDTO loginDTO); + + default AdminPassportVO convert(AdminVO adminVO, OAuth2AccessTokenVO accessTokenVO) { + return new AdminPassportVO().setAdmin(convert(adminVO)).setAuthorization(convert(accessTokenVO)); + } + AdminPassportVO.Admin convert(AdminVO adminVO); + AdminPassportVO.Authentication convert(OAuth2AccessTokenVO accessTokenVO); + +} diff --git a/management-web-app/src/main/java/cn/iocoder/mall/managementweb/manager/admin/AdminPassportManager.java b/management-web-app/src/main/java/cn/iocoder/mall/managementweb/manager/admin/AdminPassportManager.java new file mode 100644 index 000000000..35df88de6 --- /dev/null +++ b/management-web-app/src/main/java/cn/iocoder/mall/managementweb/manager/admin/AdminPassportManager.java @@ -0,0 +1,37 @@ +package cn.iocoder.mall.managementweb.manager.admin; + +import cn.iocoder.common.framework.enums.UserTypeEnum; +import cn.iocoder.common.framework.vo.CommonResult; +import cn.iocoder.mall.managementweb.controller.passport.dto.AdminPassportLoginDTO; +import cn.iocoder.mall.managementweb.controller.passport.vo.AdminPassportVO; +import cn.iocoder.mall.managementweb.convert.passport.AdminPassportConvert; +import cn.iocoder.mall.systemservice.rpc.admin.AdminRpc; +import cn.iocoder.mall.systemservice.rpc.admin.vo.AdminVO; +import cn.iocoder.mall.systemservice.rpc.oauth.OAuth2Rpc; +import cn.iocoder.mall.systemservice.rpc.oauth.dto.OAuth2CreateAccessTokenDTO; +import cn.iocoder.mall.systemservice.rpc.oauth.vo.OAuth2AccessTokenVO; +import org.apache.dubbo.config.annotation.Reference; +import org.springframework.stereotype.Service; + +@Service +public class AdminPassportManager { + + @Reference(version = "${dubbo.consumer.AdminRpc.version}", validation = "false") + private AdminRpc adminRpc; + @Reference(version = "${dubbo.consumer.OAuth2Rpc.version}", validation = "false") + private OAuth2Rpc oauth2Rpc; + + public AdminPassportVO login(AdminPassportLoginDTO loginDTO, String ip) { + // 校验管理员密码 + CommonResult verifyPasswordResult = adminRpc.verifyPassword(AdminPassportConvert.INSTANCE.convert(loginDTO).setIp(ip)); + verifyPasswordResult.checkError(); + // 创建访问令牌 + CommonResult createAccessTokenResult = oauth2Rpc.createAccessToken( + new OAuth2CreateAccessTokenDTO().setUserId(verifyPasswordResult.getData().getId()) + .setUserType(UserTypeEnum.ADMIN.getValue()).setCreateIp(ip)); + createAccessTokenResult.checkError(); + // 返回 + return AdminPassportConvert.INSTANCE.convert(verifyPasswordResult.getData(), createAccessTokenResult.getData()); + } + +} diff --git a/management-web-app/src/main/resources/application-dev.yml b/management-web-app/src/main/resources/application-dev.yml new file mode 100644 index 000000000..4cfe1567c --- /dev/null +++ b/management-web-app/src/main/resources/application-dev.yml @@ -0,0 +1,14 @@ +spring: + # Spring Cloud 配置项 + cloud: + nacos: + # Spring Cloud Nacos Discovery 配置项 + discovery: + server-addr: 400-infra.server.iocoder.cn:8848 # Nacos 服务器地址 + namespace: dev # Nacos 命名空间 + +# Dubbo 配置项 +dubbo: + # Dubbo 注册中心 + registry: + address: spring-cloud://400-infra.server.iocoder.cn:8848 # 指定 Dubbo 服务注册中心的地址 diff --git a/management-web-app/src/main/resources/application-local.yml b/management-web-app/src/main/resources/application-local.yml new file mode 100644 index 000000000..2e9e99973 --- /dev/null +++ b/management-web-app/src/main/resources/application-local.yml @@ -0,0 +1,14 @@ +spring: + # Spring Cloud 配置项 + cloud: + nacos: + # Spring Cloud Nacos Discovery 配置项 + discovery: + server-addr: 400-infra.server.iocoder.cn:8848 # Nacos 服务器地址 + namespace: local # Nacos 命名空间 + +# Dubbo 配置项 +dubbo: + # Dubbo 注册中心 + registry: + address: spring-cloud://400-infra.server.iocoder.cn:8848 # 指定 Dubbo 服务注册中心的地址 diff --git a/management-web-app/src/main/resources/application.yml b/management-web-app/src/main/resources/application.yml new file mode 100644 index 000000000..48d8f39e3 --- /dev/null +++ b/management-web-app/src/main/resources/application.yml @@ -0,0 +1,30 @@ +# 服务器的配置项 +server: + port: 18083 + servlet: + context-path: /management-api/ + +spring: + # Application 的配置项 + application: + name: management-web + # Profile 的配置项 + profiles: + active: local + +# Dubbo 配置项 +dubbo: + # Spring Cloud Alibaba Dubbo 专属配置 + cloud: + subscribed-services: 'user-service, system-service' # 设置订阅的应用列表,默认为 * 订阅所有应用 + # Dubbo 服务消费者的配置 + consumer: + timeout: 10000 + UserSmsCodeRpc: + version: 1.0.0 + UserRpc: + version: 1.0.0 + OAuth2Rpc: + version: 1.0.0 + AdminRpc: + version: 1.0.0 diff --git a/pom.xml b/pom.xml index 0928ad1a2..d434b6539 100644 --- a/pom.xml +++ b/pom.xml @@ -29,6 +29,8 @@ user-service-project user-web-app system-service-project + management-web-app + shop-web-app pom diff --git a/shop-web-app/pom.xml b/shop-web-app/pom.xml new file mode 100644 index 000000000..0ee3de356 --- /dev/null +++ b/shop-web-app/pom.xml @@ -0,0 +1,15 @@ + + + + onemall + cn.iocoder.mall + 1.0-SNAPSHOT + + 4.0.0 + + shop-web-app + 商城,用于用户购物 + + diff --git a/system-service-project/system-service-api/src/main/java/cn/iocoder/mall/systemservice/enums/SystemErrorCodeEnum.java b/system-service-project/system-service-api/src/main/java/cn/iocoder/mall/systemservice/enums/SystemErrorCodeEnum.java index 76fd3f68b..884e6721f 100644 --- a/system-service-project/system-service-api/src/main/java/cn/iocoder/mall/systemservice/enums/SystemErrorCodeEnum.java +++ b/system-service-project/system-service-api/src/main/java/cn/iocoder/mall/systemservice/enums/SystemErrorCodeEnum.java @@ -25,9 +25,8 @@ public enum SystemErrorCodeEnum implements ServiceExceptionUtil.Enumerable verifyPassword(AdminVerifyPasswordDTO verifyPasswordDTO); + +} diff --git a/system-service-project/system-service-api/src/main/java/cn/iocoder/mall/systemservice/rpc/admin/dto/AdminVerifyPasswordDTO.java b/system-service-project/system-service-api/src/main/java/cn/iocoder/mall/systemservice/rpc/admin/dto/AdminVerifyPasswordDTO.java new file mode 100644 index 000000000..22ffd2904 --- /dev/null +++ b/system-service-project/system-service-api/src/main/java/cn/iocoder/mall/systemservice/rpc/admin/dto/AdminVerifyPasswordDTO.java @@ -0,0 +1,36 @@ +package cn.iocoder.mall.systemservice.rpc.admin.dto; + +import lombok.Data; +import lombok.experimental.Accessors; +import org.hibernate.validator.constraints.Length; + +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.Pattern; + +/** + * 管理员校验密码 DTO + */ +@Data +@Accessors(chain = true) +public class AdminVerifyPasswordDTO { + + /** + * 用户名 + */ + @NotEmpty(message = "登陆账号不能为空") + @Length(min = 5, max = 16, message = "账号长度为 5-16 位") + @Pattern(regexp = "^[A-Za-z0-9]+$", message = "账号格式为数字以及字母") + private String username; + /** + * 密码 + */ + @NotEmpty(message = "密码不能为空") + @Length(min = 4, max = 16, message = "密码长度为 4-16 位") + private String password; + /** + * IP + */ + @NotEmpty(message = "IP 不能为空") + private String ip; + +} diff --git a/system-service-project/system-service-api/src/main/java/cn/iocoder/mall/systemservice/rpc/admin/vo/AdminVO.java b/system-service-project/system-service-api/src/main/java/cn/iocoder/mall/systemservice/rpc/admin/vo/AdminVO.java new file mode 100644 index 000000000..66e67317b --- /dev/null +++ b/system-service-project/system-service-api/src/main/java/cn/iocoder/mall/systemservice/rpc/admin/vo/AdminVO.java @@ -0,0 +1,38 @@ +package cn.iocoder.mall.systemservice.rpc.admin.vo; + +import cn.iocoder.mall.systemservice.enums.admin.AdminStatusEnum; +import lombok.Data; +import lombok.experimental.Accessors; + +/** + * 管理员 DO + */ +@Data +@Accessors(chain = true) +public class AdminVO { + + /** + * 管理员编号 + */ + private Integer id; + /** + * 真实名字 + */ + private String name; + /** + * 部门编号 + */ + private Integer departmentId; + /** + * 在职状态 + * + * 枚举 {@link AdminStatusEnum} + */ + private Integer status; + + /** + * 登陆账号 + */ + private String username; + +} diff --git a/system-service-project/system-service-app/src/main/java/cn/iocoder/mall/systemservice/convert/admin/AdminConvert.java b/system-service-project/system-service-app/src/main/java/cn/iocoder/mall/systemservice/convert/admin/AdminConvert.java new file mode 100644 index 000000000..db880169f --- /dev/null +++ b/system-service-project/system-service-app/src/main/java/cn/iocoder/mall/systemservice/convert/admin/AdminConvert.java @@ -0,0 +1,24 @@ +package cn.iocoder.mall.systemservice.convert.admin; + +import cn.iocoder.common.framework.vo.PageResult; +import cn.iocoder.mall.systemservice.dal.mysql.dataobject.admin.AdminDO; +import cn.iocoder.mall.systemservice.rpc.admin.vo.AdminVO; +import cn.iocoder.mall.systemservice.service.admin.bo.AdminBO; +import com.baomidou.mybatisplus.core.metadata.IPage; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.factory.Mappers; + +@Mapper +public interface AdminConvert { + + AdminConvert INSTANCE = Mappers.getMapper(AdminConvert.class); + + AdminBO convert(AdminDO bean); + + @Mapping(source = "records", target = "list") + PageResult convertPage(IPage bean); + + AdminVO convert(AdminBO adminBO); + +} diff --git a/system-service-project/system-service-app/src/main/java/cn/iocoder/mall/systemservice/convert/package-info.java b/system-service-project/system-service-app/src/main/java/cn/iocoder/mall/systemservice/convert/package-info.java deleted file mode 100644 index c57c3b722..000000000 --- a/system-service-project/system-service-app/src/main/java/cn/iocoder/mall/systemservice/convert/package-info.java +++ /dev/null @@ -1 +0,0 @@ -package cn.iocoder.mall.systemservice.convert; diff --git a/system-service-project/system-service-app/src/main/java/cn/iocoder/mall/systemservice/manager/admin/AdminManager.java b/system-service-project/system-service-app/src/main/java/cn/iocoder/mall/systemservice/manager/admin/AdminManager.java new file mode 100644 index 000000000..025b5c495 --- /dev/null +++ b/system-service-project/system-service-app/src/main/java/cn/iocoder/mall/systemservice/manager/admin/AdminManager.java @@ -0,0 +1,23 @@ +package cn.iocoder.mall.systemservice.manager.admin; + +import cn.iocoder.mall.systemservice.convert.admin.AdminConvert; +import cn.iocoder.mall.systemservice.rpc.admin.dto.AdminVerifyPasswordDTO; +import cn.iocoder.mall.systemservice.rpc.admin.vo.AdminVO; +import cn.iocoder.mall.systemservice.service.admin.AdminService; +import cn.iocoder.mall.systemservice.service.admin.bo.AdminBO; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class AdminManager { + + @Autowired + private AdminService adminService; + + public AdminVO verifyPassword(AdminVerifyPasswordDTO verifyPasswordDTO) { + AdminBO adminBO = adminService.verifyPassword(verifyPasswordDTO.getUsername(), + verifyPasswordDTO.getPassword(), verifyPasswordDTO.getIp()); + return AdminConvert.INSTANCE.convert(adminBO); + } + +} diff --git a/system-service-project/system-service-app/src/main/java/cn/iocoder/mall/systemservice/manager/package-info.java b/system-service-project/system-service-app/src/main/java/cn/iocoder/mall/systemservice/manager/package-info.java deleted file mode 100644 index 4e0936108..000000000 --- a/system-service-project/system-service-app/src/main/java/cn/iocoder/mall/systemservice/manager/package-info.java +++ /dev/null @@ -1 +0,0 @@ -package cn.iocoder.mall.systemservice.manager; diff --git a/system-service-project/system-service-app/src/main/java/cn/iocoder/mall/systemservice/rpc/admin/AdminRpcImpl.java b/system-service-project/system-service-app/src/main/java/cn/iocoder/mall/systemservice/rpc/admin/AdminRpcImpl.java new file mode 100644 index 000000000..3360d8417 --- /dev/null +++ b/system-service-project/system-service-app/src/main/java/cn/iocoder/mall/systemservice/rpc/admin/AdminRpcImpl.java @@ -0,0 +1,23 @@ +package cn.iocoder.mall.systemservice.rpc.admin; + +import cn.iocoder.common.framework.vo.CommonResult; +import cn.iocoder.mall.systemservice.manager.admin.AdminManager; +import cn.iocoder.mall.systemservice.rpc.admin.dto.AdminVerifyPasswordDTO; +import cn.iocoder.mall.systemservice.rpc.admin.vo.AdminVO; +import org.apache.dubbo.config.annotation.Service; +import org.springframework.beans.factory.annotation.Autowired; + +import static cn.iocoder.common.framework.vo.CommonResult.success; + +@Service(version = "${dubbo.provider.AdminRpc.version}", validation = "false") +public class AdminRpcImpl implements AdminRpc { + + @Autowired + private AdminManager adminManager; + + @Override + public CommonResult verifyPassword(AdminVerifyPasswordDTO verifyPasswordDTO) { + return success(adminManager.verifyPassword(verifyPasswordDTO)); + } + +} diff --git a/system-service-project/system-service-app/src/main/java/cn/iocoder/mall/systemservice/rpc/package-info.java b/system-service-project/system-service-app/src/main/java/cn/iocoder/mall/systemservice/rpc/package-info.java deleted file mode 100644 index e75b646bd..000000000 --- a/system-service-project/system-service-app/src/main/java/cn/iocoder/mall/systemservice/rpc/package-info.java +++ /dev/null @@ -1 +0,0 @@ -package cn.iocoder.mall.systemservice.rpc; diff --git a/system-service-project/system-service-app/src/main/java/cn/iocoder/mall/systemservice/service/admin/AdminService.java b/system-service-project/system-service-app/src/main/java/cn/iocoder/mall/systemservice/service/admin/AdminService.java new file mode 100644 index 000000000..0a7791a41 --- /dev/null +++ b/system-service-project/system-service-app/src/main/java/cn/iocoder/mall/systemservice/service/admin/AdminService.java @@ -0,0 +1,39 @@ +package cn.iocoder.mall.systemservice.service.admin; + +import cn.iocoder.common.framework.util.DigestUtils; +import cn.iocoder.common.framework.util.ServiceExceptionUtil; +import cn.iocoder.mall.systemservice.convert.admin.AdminConvert; +import cn.iocoder.mall.systemservice.dal.mysql.dataobject.admin.AdminDO; +import cn.iocoder.mall.systemservice.dal.mysql.mapper.admin.AdminMapper; +import cn.iocoder.mall.systemservice.enums.SystemErrorCodeEnum; +import cn.iocoder.mall.systemservice.enums.admin.AdminStatusEnum; +import cn.iocoder.mall.systemservice.service.admin.bo.AdminBO; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class AdminService { + + @Autowired + private AdminMapper adminMapper; + + public AdminBO verifyPassword(String username, String password, String ip) { + AdminDO adminDO = adminMapper.selectByUsername(username); + if (adminDO == null) { + throw ServiceExceptionUtil.exception(SystemErrorCodeEnum.ADMIN_NOT_FOUND); + } + // 校验密码是否正确 + String encodedPassword = DigestUtils.bcrypt(password, adminDO.getPasswordSalt()); + if (encodedPassword.equals(adminDO.getPassword())) { + // TODO 需要补充密码错误上限 + throw ServiceExceptionUtil.exception(SystemErrorCodeEnum.ADMIN_PASSWORD_ERROR); + } + // 账号被禁用 + if (!AdminStatusEnum.ACTIVE.getStatus().equals(adminDO.getStatus())) { + throw ServiceExceptionUtil.exception(SystemErrorCodeEnum.ADMIN_IS_DISABLE); + } + // 返回 + return AdminConvert.INSTANCE.convert(adminDO); + } + +} diff --git a/system-service-project/system-service-app/src/main/java/cn/iocoder/mall/systemservice/service/admin/bo/AdminBO.java b/system-service-project/system-service-app/src/main/java/cn/iocoder/mall/systemservice/service/admin/bo/AdminBO.java new file mode 100644 index 000000000..34e798b63 --- /dev/null +++ b/system-service-project/system-service-app/src/main/java/cn/iocoder/mall/systemservice/service/admin/bo/AdminBO.java @@ -0,0 +1,41 @@ +package cn.iocoder.mall.systemservice.service.admin.bo; + +import cn.iocoder.mall.systemservice.dal.mysql.dataobject.admin.DepartmentDO; +import cn.iocoder.mall.systemservice.enums.admin.AdminStatusEnum; +import lombok.Data; +import lombok.experimental.Accessors; + +/** + * 管理员信息 BO + */ +@Data +@Accessors(chain = true) +public class AdminBO { + + /** + * 管理员编号 + */ + private Integer id; + /** + * 真实名字 + */ + private String name; + /** + * 部门编号 + * + * 关联 {@link DepartmentDO#getId()} + */ + private Integer departmentId; + /** + * 在职状态 + * + * 枚举 {@link AdminStatusEnum} + */ + private Integer status; + + /** + * 登陆账号 + */ + private String username; + +} diff --git a/system-service-project/system-service-app/src/main/java/cn/iocoder/mall/systemservice/service/package-info.java b/system-service-project/system-service-app/src/main/java/cn/iocoder/mall/systemservice/service/package-info.java deleted file mode 100644 index 960445f36..000000000 --- a/system-service-project/system-service-app/src/main/java/cn/iocoder/mall/systemservice/service/package-info.java +++ /dev/null @@ -1 +0,0 @@ -package cn.iocoder.mall.systemservice.service; diff --git a/system-service-project/system-service-app/src/main/resources/application.yaml b/system-service-project/system-service-app/src/main/resources/application.yaml index d3840c46d..349b7252d 100644 --- a/system-service-project/system-service-app/src/main/resources/application.yaml +++ b/system-service-project/system-service-app/src/main/resources/application.yaml @@ -35,3 +35,5 @@ dubbo: filter: -exception OAuth2Rpc: version: 1.0.0 + AdminRpc: + version: 1.0.0 diff --git a/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/service/admin/AdminServiceImpl.java b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/service/admin/AdminServiceImpl.java index a6c02e803..8416ae3f2 100644 --- a/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/service/admin/AdminServiceImpl.java +++ b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/service/admin/AdminServiceImpl.java @@ -11,19 +11,6 @@ import org.springframework.stereotype.Service; @Service public class AdminServiceImpl implements AdminService { - @Autowired - private AdminMapper adminMapper; - - @Override - public AdminBO getAdmin(Integer id) { - return AdminConvert.INSTANCE.convert(adminMapper.selectById(id)); - } - - @Override - public AdminBO getAdminByAccountId(Integer accountId) { - return AdminConvert.INSTANCE.convert(adminMapper.selectByAccountId(accountId)); - } - @Override public PageResult getAdminPage(AdminPageDTO pageDTO) { return AdminConvert.INSTANCE.convertPage(adminMapper.selectPage(pageDTO)); diff --git a/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/service/user/UserService.java b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/service/user/UserService.java index 2bc3173f7..bd74169ad 100644 --- a/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/service/user/UserService.java +++ b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/service/user/UserService.java @@ -1,13 +1,12 @@ package cn.iocoder.mall.system.biz.service.user; import cn.iocoder.common.framework.vo.PageResult; -import cn.iocoder.mall.system.biz.bo.user.UserAuthenticateBO; import cn.iocoder.mall.system.biz.bo.user.UserBO; -import cn.iocoder.mall.system.biz.dto.oatuh2.OAuth2MobileCodeAuthenticateDTO; import cn.iocoder.mall.system.biz.dto.user.UserPageDTO; import cn.iocoder.mall.system.biz.dto.user.UserUpdateDTO; import cn.iocoder.mall.system.biz.dto.user.UserUpdateStatusDTO; import org.springframework.validation.annotation.Validated; + import javax.validation.Valid; /** @@ -16,10 +15,6 @@ import javax.validation.Valid; @Validated public interface UserService { - UserAuthenticateBO authenticate(OAuth2MobileCodeAuthenticateDTO authenticateDTO); - - UserBO getUserByAccountId(Integer accountId); - /** * 根据条件分页获取用户列表 * @param userPageDTO diff --git a/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/service/user/UserServiceImpl.java b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/service/user/UserServiceImpl.java index a5c816924..f3c327117 100644 --- a/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/service/user/UserServiceImpl.java +++ b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/service/user/UserServiceImpl.java @@ -27,30 +27,6 @@ public class UserServiceImpl implements UserService { @Autowired private UserMapper userMapper; - @Autowired - private OAuth2Service oAuth2Service; - - @Override - @Transactional - public UserAuthenticateBO authenticate(OAuth2MobileCodeAuthenticateDTO authenticateDTO) { - // 执行认证 - OAuth2AuthenticateBO accessTokenBO = oAuth2Service.authenticate(authenticateDTO); - // 获得用户 - UserDO userDO = userMapper.selectById(accessTokenBO.getAccountId()); - if (userDO == null) { - userDO = this.creatUser(accessTokenBO.getAccountId()); - } - UserBO userBO = UserConvert.INSTANCE.convert(userDO); - // 拼装返回 - return UserConvert.INSTANCE.convert(userBO, accessTokenBO); - } - - @Override - public UserBO getUserByAccountId(Integer accountId) { - UserDO userDO = userMapper.selectById(accountId); - return UserConvert.INSTANCE.convert(userDO); - } - /** * 根据条件分页获取用户列表 * @param userPageDTO @@ -109,12 +85,4 @@ public class UserServiceImpl implements UserService { return true; } - private UserDO creatUser(Integer accountId) { - UserDO user = new UserDO(); - user.setAccountId(accountId); - user.setDeleted(DeletedStatusEnum.DELETED_NO.getValue()); - userMapper.insert(user); - return user; - } - } diff --git a/system/system-rest/src/main/java/cn/iocoder/mall/system/rest/controller/oauth2/AdminsOAuth2Controller.java b/system/system-rest/src/main/java/cn/iocoder/mall/system/rest/controller/oauth2/AdminsOAuth2Controller.java deleted file mode 100644 index c8421fccc..000000000 --- a/system/system-rest/src/main/java/cn/iocoder/mall/system/rest/controller/oauth2/AdminsOAuth2Controller.java +++ /dev/null @@ -1,52 +0,0 @@ -package cn.iocoder.mall.system.rest.controller.oauth2; - -import cn.iocoder.common.framework.enums.MallConstants; -import cn.iocoder.common.framework.util.ServiceExceptionUtil; -import cn.iocoder.common.framework.vo.CommonResult; -import cn.iocoder.mall.security.core.annotation.RequiresNone; -import cn.iocoder.mall.system.biz.bo.admin.AdminBO; -import cn.iocoder.mall.system.biz.bo.ouath2.OAuth2AuthenticateBO; -import cn.iocoder.mall.system.biz.dto.oatuh2.OAuth2UsernameAuthenticateDTO; -import cn.iocoder.mall.system.biz.service.admin.AdminService; -import cn.iocoder.mall.system.biz.service.oauth2.OAuth2Service; -import cn.iocoder.mall.system.rest.convert.oauth2.AdminsOAuth2Convert; -import cn.iocoder.mall.system.rest.request.oauth2.AdminsOAuth2UsernameAuthenticateRequest; -import cn.iocoder.mall.system.rest.response.oauth2.AdminsOAuth2AuthenticateResponse; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -import static cn.iocoder.mall.system.biz.enums.SystemErrorCodeEnum.*; - -@RestController -@RequestMapping(MallConstants.ROOT_PATH_ADMIN + "/oauth2") -@Api(tags = "管理员 - OAuth2 API") -public class AdminsOAuth2Controller { - - @Autowired - private OAuth2Service oauth2Service; - @Autowired - private AdminService adminService; - - @PostMapping("/username-authenticate") - @ApiOperation("用户名认证(登陆)") - @RequiresNone - public CommonResult usernameAuthenticate(AdminsOAuth2UsernameAuthenticateRequest request) { - // 执行认证 - OAuth2UsernameAuthenticateDTO authenticateDTO = AdminsOAuth2Convert.INSTANCE.convert(request); - OAuth2AuthenticateBO accessTokenBO = oauth2Service.authenticate(authenticateDTO); - // 获得 Admin 信息 - AdminBO adminBO = adminService.getAdmin(accessTokenBO.getAccountId()); - if (adminBO == null) { - throw ServiceExceptionUtil.exception(ADMIN_NOT_FOUND); - } - // 转换返回 - return CommonResult.success( - AdminsOAuth2Convert.INSTANCE.convert(adminBO, accessTokenBO) - ); - } - -} diff --git a/system/system-rest/src/main/java/cn/iocoder/mall/system/rest/controller/oauth2/UsersOAuth2Controller.java b/system/system-rest/src/main/java/cn/iocoder/mall/system/rest/controller/oauth2/UsersOAuth2Controller.java deleted file mode 100644 index 2677bf67e..000000000 --- a/system/system-rest/src/main/java/cn/iocoder/mall/system/rest/controller/oauth2/UsersOAuth2Controller.java +++ /dev/null @@ -1,26 +0,0 @@ -package cn.iocoder.mall.system.rest.controller.oauth2; - -import cn.iocoder.common.framework.enums.MallConstants; -import cn.iocoder.mall.system.biz.service.oauth2.OAuth2MobileCodeService; -import cn.iocoder.mall.system.biz.service.oauth2.OAuth2Service; -import cn.iocoder.mall.system.biz.service.user.UserService; -import io.swagger.annotations.Api; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -@RestController -@RequestMapping(MallConstants.ROOT_PATH_USER + "/oauth2") -@Api(tags = "用户 - OAuth2 API") -public class UsersOAuth2Controller { - - @Autowired - private OAuth2Service oauth2Service; - @Autowired - private UserService userService; - @Autowired - private OAuth2MobileCodeService oauth2MobileCodeService; - - - -} diff --git a/system/system-rest/src/main/java/cn/iocoder/mall/system/rest/request/oauth2/UsersOAuth2MobileCodeAuthenticateRequest.java b/system/system-rest/src/main/java/cn/iocoder/mall/system/rest/request/oauth2/UsersOAuth2MobileCodeAuthenticateRequest.java deleted file mode 100644 index 0cb2cae7d..000000000 --- a/system/system-rest/src/main/java/cn/iocoder/mall/system/rest/request/oauth2/UsersOAuth2MobileCodeAuthenticateRequest.java +++ /dev/null @@ -1,29 +0,0 @@ -package cn.iocoder.mall.system.rest.request.oauth2; - -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; -import lombok.Data; -import lombok.experimental.Accessors; -import org.hibernate.validator.constraints.Length; - -import javax.validation.constraints.NotEmpty; -import javax.validation.constraints.Pattern; - -@ApiModel("用户 - OAuth2 模块 - 手机验证码认证请求") -@Data -@Accessors(chain = true) -public class UsersOAuth2MobileCodeAuthenticateRequest { - - @ApiModelProperty(value = "手机号", required = true, example = "15601691300") - @NotEmpty(message = "手机号不能为空") - @Length(min = 11, max = 11, message = "账号长度为 11 位") - @Pattern(regexp = "^[0-9]+$", message = "手机号必须都是数字") - private String mobile; - - @ApiModelProperty(value = "手机验证码", required = true, example = "1024") - @NotEmpty(message = "手机验证码不能为空") - @Length(min = 4, max = 6, message = "手机验证码长度为 4-6 位") - @Pattern(regexp = "^[0-9]+$", message = "手机验证码必须都是数字") - private String code; - -} diff --git a/system/system-rest/src/main/java/cn/iocoder/mall/system/rest/response/oauth2/AdminsOAuth2AuthenticateResponse.java b/system/system-rest/src/main/java/cn/iocoder/mall/system/rest/response/oauth2/AdminsOAuth2AuthenticateResponse.java deleted file mode 100644 index 3310902c6..000000000 --- a/system/system-rest/src/main/java/cn/iocoder/mall/system/rest/response/oauth2/AdminsOAuth2AuthenticateResponse.java +++ /dev/null @@ -1,51 +0,0 @@ -package cn.iocoder.mall.system.rest.response.oauth2; - -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; -import lombok.Data; -import lombok.experimental.Accessors; - -import java.util.Date; - -@ApiModel("管理员 - OAuth2 模块 - 认证响应") -@Data -@Accessors(chain = true) -public class AdminsOAuth2AuthenticateResponse { - - @ApiModel("管理员") - @Data - public static class Admin { - - @ApiModelProperty(value = "管理员编号", required = true, example = "1") - private Integer id; - - @ApiModelProperty(value = "真实名字", required = true, example = "小王") - private String name; - - } - - @ApiModel("访问令牌") - @Data - public static class Token { - - @ApiModelProperty(value = "access token", required = true, example = "001e8f49b20e47f7b3a2de774497cd50") - private String accessToken; - - @ApiModelProperty(value = "refresh token", required = true, example = "001e8f49b20e47f7b3a2de774497cd50") - private String refreshToken; - - @ApiModelProperty(value = "过期时间", required = true) - private Date expiresTime; - - } - - /** - * 管理员 - */ - private Admin admin; - /** - * 访问令牌 - */ - private Token token; - -} diff --git a/user-web-app/src/main/java/cn/iocoder/mall/userweb/controller/passport/UserPassportController.java b/user-web-app/src/main/java/cn/iocoder/mall/userweb/controller/passport/UserPassportController.java index cf27edc8b..253ace630 100644 --- a/user-web-app/src/main/java/cn/iocoder/mall/userweb/controller/passport/UserPassportController.java +++ b/user-web-app/src/main/java/cn/iocoder/mall/userweb/controller/passport/UserPassportController.java @@ -6,6 +6,7 @@ import cn.iocoder.mall.userweb.controller.passport.dto.UserPassportLoginBySmsDTO import cn.iocoder.mall.userweb.controller.passport.dto.UserPassportSendSmsCodeDTO; import cn.iocoder.mall.userweb.controller.passport.vo.UserPassportVO; import cn.iocoder.mall.userweb.manager.passport.UserPassportManager; +import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.PostMapping; @@ -16,6 +17,7 @@ import javax.servlet.http.HttpServletRequest; import static cn.iocoder.common.framework.vo.CommonResult.success; +@Api(tags = "用户 Passport API") @RestController @RequestMapping("/passport") public class UserPassportController { diff --git a/user-web-app/src/main/java/cn/iocoder/mall/userweb/controller/passport/dto/UserPassportLoginBySmsDTO.java b/user-web-app/src/main/java/cn/iocoder/mall/userweb/controller/passport/dto/UserPassportLoginBySmsDTO.java index ddb4e6d93..5f4171146 100644 --- a/user-web-app/src/main/java/cn/iocoder/mall/userweb/controller/passport/dto/UserPassportLoginBySmsDTO.java +++ b/user-web-app/src/main/java/cn/iocoder/mall/userweb/controller/passport/dto/UserPassportLoginBySmsDTO.java @@ -5,8 +5,10 @@ import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import lombok.experimental.Accessors; +import org.hibernate.validator.constraints.Length; -import javax.validation.constraints.NotNull; +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.Pattern; import java.io.Serializable; @ApiModel("用户短信验证码登陆 DTO") @@ -14,11 +16,15 @@ import java.io.Serializable; @Accessors(chain = true) public class UserPassportLoginBySmsDTO implements Serializable { - @ApiModelProperty(value = "手机号", example = "15601691234") + @ApiModelProperty(value = "手机号", required = true, example = "15601691300") + @NotEmpty(message = "手机号不能为空") @Mobile private String mobile; - @ApiModelProperty(value = "验证码", example = "1234") - @NotNull(message = "验证码不能为空") + + @ApiModelProperty(value = "手机验证码", required = true, example = "1024") + @NotEmpty(message = "手机验证码不能为空") + @Length(min = 4, max = 6, message = "手机验证码长度为 4-6 位") + @Pattern(regexp = "^[0-9]+$", message = "手机验证码必须都是数字") private String code; } diff --git a/user-web-app/src/main/java/cn/iocoder/mall/userweb/controller/passport/vo/UserPassportVO.java b/user-web-app/src/main/java/cn/iocoder/mall/userweb/controller/passport/vo/UserPassportVO.java index 74771609c..81b11650d 100644 --- a/user-web-app/src/main/java/cn/iocoder/mall/userweb/controller/passport/vo/UserPassportVO.java +++ b/user-web-app/src/main/java/cn/iocoder/mall/userweb/controller/passport/vo/UserPassportVO.java @@ -1,57 +1,41 @@ package cn.iocoder.mall.userweb.controller.passport.vo; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; import lombok.Data; import lombok.experimental.Accessors; import java.util.Date; -/** - * 用户通信证信息 - */ +@ApiModel("用户通信证信息 VO") @Data @Accessors(chain = true) public class UserPassportVO { - /** - * 认证信息 - */ + @ApiModel("认证信息") @Data @Accessors(chain = true) public static class Authentication { - /** - * 访问令牌 - */ + @ApiModelProperty(value = "访问令牌", required = true, example = "001e8f49b20e47f7b3a2de774497cd50") private String accessToken; - /** - * 刷新令牌 - */ + @ApiModelProperty(value = "刷新令牌", required = true, example = "001e8f49b20e47f7b3a2de774497cd50") private String refreshToken; - /** - * 过期时间 - */ + @ApiModelProperty(value = "过期时间", required = true) private Date expiresTime; } - /** - * 用户信息 - */ + @ApiModel("用户信息") @Data @Accessors(chain = true) public static class User { - /** - * 用户编号 - */ + @ApiModelProperty(value = "用户编号", required = true, example = "1") private Integer id; - /** - * 昵称 - */ + @ApiModelProperty(value = "用户昵称", required = true, example = "小王") private String nickname; - /** - * 头像 - */ + @ApiModelProperty(value = "用户头像", required = true, example = "http://www.iocoder.cn/image") private String avatar; } diff --git a/user-web-app/src/main/java/cn/iocoder/mall/userweb/controller/user/UserController.java b/user-web-app/src/main/java/cn/iocoder/mall/userweb/controller/user/UserController.java index b3bfea735..f3714e2c6 100644 --- a/user-web-app/src/main/java/cn/iocoder/mall/userweb/controller/user/UserController.java +++ b/user-web-app/src/main/java/cn/iocoder/mall/userweb/controller/user/UserController.java @@ -1,4 +1,7 @@ package cn.iocoder.mall.userweb.controller.user; +import io.swagger.annotations.Api; + +@Api(tags = "用户信息 API") public class UserController { }