开始重构 system 模块的代码,先修改认证逻辑

This commit is contained in:
YunaiV 2020-04-17 19:25:24 +08:00
parent 233a441579
commit 4ffc2cb815
201 changed files with 1788 additions and 561 deletions

View File

@ -19,6 +19,7 @@ function basePathBuilder(proxys, basePath) {
}
export default function(NODE_ENV, basePath) {
NODE_ENV = 'prod';
let proxys = NODE_ENV === 'development' || NODE_ENV === 'undefined' ? proxyDev : proxyProd;
if (basePath) {
proxys = basePathBuilder(proxys, basePath);

View File

@ -26,6 +26,15 @@ public class ServiceExceptionUtil {
private static final Logger LOGGER = LoggerFactory.getLogger(ServiceExceptionUtil.class);
/**
* 错误枚举的接口
*/
public interface Enumerable {
int getCode();
}
/**
* 错误码提示模板
*/
@ -39,16 +48,31 @@ public class ServiceExceptionUtil {
ServiceExceptionUtil.messages.put(code, message);
}
// TODO 芋艿可能不是目前最优解目前暂时这样 枚举实现接口
public static <T> CommonResult<T> error(Enumerable enumerable) {
return error(enumerable.getCode());
}
public static <T> CommonResult<T> error(Enumerable enumerable, Object... params) {
return error(enumerable.getCode(), params);
}
public static <T> CommonResult<T> error(Integer code) {
return CommonResult.error(code, messages.get(code));
}
public static CommonResult error(Integer code, Object... params) {
public static <T> CommonResult<T> error(Integer code, Object... params) {
String message = doFormat(code, messages.get(code), params);
return CommonResult.error(code, message);
}
public static ServiceException exception(Enumerable enumerable) {
return exception(enumerable.getCode());
}
public static ServiceException exception(Enumerable enumerable, Object... params) {
return exception(enumerable.getCode(), params);
}
/**
* 创建指定编号的 ServiceException 的异常
*

View File

@ -2,9 +2,9 @@ package cn.iocoder.mall.spring.boot.web;
import cn.iocoder.common.framework.constant.MallConstants;
import cn.iocoder.common.framework.servlet.CorsFilter;
import cn.iocoder.mall.admin.sdk.interceptor.AdminDemoInterceptor;
import cn.iocoder.mall.system.sdk.interceptor.AdminDemoInterceptor;
import cn.iocoder.mall.spring.boot.web.interceptor.AccessLogInterceptor;
import cn.iocoder.mall.admin.sdk.interceptor.AdminSecurityInterceptor;
import cn.iocoder.mall.system.sdk.interceptor.AdminSecurityInterceptor;
import cn.iocoder.mall.spring.boot.web.handler.GlobalExceptionHandler;
import cn.iocoder.mall.spring.boot.web.handler.GlobalResponseBodyHandler;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;

View File

@ -6,9 +6,9 @@ import cn.iocoder.common.framework.util.ExceptionUtil;
import cn.iocoder.common.framework.util.HttpUtil;
import cn.iocoder.common.framework.util.MallUtil;
import cn.iocoder.common.framework.vo.CommonResult;
import cn.iocoder.mall.admin.api.SystemLogService;
import cn.iocoder.mall.admin.api.dto.systemlog.AccessLogAddDTO;
import cn.iocoder.mall.admin.api.dto.systemlog.ExceptionLogAddDTO;
import cn.iocoder.mall.system.api.SystemLogService;
import cn.iocoder.mall.system.api.dto.systemlog.AccessLogAddDTO;
import cn.iocoder.mall.system.api.dto.systemlog.ExceptionLogAddDTO;
import com.alibaba.fastjson.JSON;
import io.micrometer.core.instrument.Counter;
import io.micrometer.core.instrument.Metrics;

View File

@ -3,8 +3,8 @@ package cn.iocoder.mall.spring.boot.web.interceptor;
import cn.iocoder.common.framework.util.HttpUtil;
import cn.iocoder.common.framework.util.MallUtil;
import cn.iocoder.common.framework.vo.CommonResult;
import cn.iocoder.mall.admin.api.SystemLogService;
import cn.iocoder.mall.admin.api.dto.systemlog.AccessLogAddDTO;
import cn.iocoder.mall.system.api.SystemLogService;
import cn.iocoder.mall.system.api.dto.systemlog.AccessLogAddDTO;
import com.alibaba.fastjson.JSON;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.apache.dubbo.config.annotation.Reference;

View File

@ -12,7 +12,7 @@
"axios": "^0.18.0",
"moment": "^2.24.0",
"pingpp-js": "^2.2.13",
"vant": "^2.2.14",
"vant": "^1.3.1",
"vue": "^2.5.17",
"vue-router": "^3.0.1",
"vuex": "^3.1.0"

View File

@ -3,8 +3,8 @@ package cn.iocoder.mall.order.application.controller.users;
import cn.iocoder.common.framework.util.HttpUtil;
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.datadict.DataDictBO;
import cn.iocoder.mall.system.api.DataDictService;
import cn.iocoder.mall.system.api.bo.datadict.DataDictBO;
import cn.iocoder.mall.order.api.CartService;
import cn.iocoder.mall.order.api.OrderService;
import cn.iocoder.mall.order.api.bo.*;

View File

@ -2,8 +2,8 @@ package cn.iocoder.mall.order.application.controller.users;
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.datadict.DataDictBO;
import cn.iocoder.mall.system.api.DataDictService;
import cn.iocoder.mall.system.api.bo.datadict.DataDictBO;
import cn.iocoder.mall.order.api.OrderLogisticsService;
import cn.iocoder.mall.order.api.bo.OrderLogisticsInfoBO;
import cn.iocoder.mall.order.api.bo.OrderLogisticsInfoWithOrderBO;

View File

@ -1,8 +1,8 @@
package cn.iocoder.mall.order.application.controller.users;
import cn.iocoder.common.framework.vo.CommonResult;
import cn.iocoder.mall.admin.api.DataDictService;
import cn.iocoder.mall.admin.api.bo.datadict.DataDictBO;
import cn.iocoder.mall.system.api.DataDictService;
import cn.iocoder.mall.system.api.bo.datadict.DataDictBO;
import cn.iocoder.mall.order.api.OrderReturnService;
import cn.iocoder.mall.order.api.bo.OrderReturnInfoBO;
import cn.iocoder.mall.order.api.constant.DictKeyConstants;

View File

@ -3,8 +3,8 @@ package cn.iocoder.mall.order.biz.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.datadict.DataDictBO;
import cn.iocoder.mall.system.api.DataDictService;
import cn.iocoder.mall.system.api.bo.datadict.DataDictBO;
import cn.iocoder.mall.order.api.OrderLogisticsService;
import cn.iocoder.mall.order.api.OrderReturnService;
import cn.iocoder.mall.order.api.bo.OrderLastLogisticsInfoBO;

View File

@ -1,7 +1,7 @@
package cn.iocoder.mall.product.application.controller.admins;
import cn.iocoder.common.framework.vo.CommonResult;
import cn.iocoder.mall.admin.sdk.context.AdminSecurityContextHolder;
import cn.iocoder.mall.system.sdk.context.AdminSecurityContextHolder;
import cn.iocoder.mall.product.api.ProductAttrService;
import cn.iocoder.mall.product.api.bo.ProductAttrBO;
import cn.iocoder.mall.product.api.bo.ProductAttrPageBO;

View File

@ -1,7 +1,7 @@
package cn.iocoder.mall.product.application.controller.admins;
import cn.iocoder.common.framework.vo.CommonResult;
import cn.iocoder.mall.admin.sdk.context.AdminSecurityContextHolder;
import cn.iocoder.mall.system.sdk.context.AdminSecurityContextHolder;
import cn.iocoder.mall.product.api.ProductBrandService;
import cn.iocoder.mall.product.api.bo.ProductBrandBO;
import cn.iocoder.mall.product.api.bo.ProductBrangPageBO;

View File

@ -1,7 +1,7 @@
package cn.iocoder.mall.product.application.controller.admins;
import cn.iocoder.common.framework.vo.CommonResult;
import cn.iocoder.mall.admin.sdk.context.AdminSecurityContextHolder;
import cn.iocoder.mall.system.sdk.context.AdminSecurityContextHolder;
import cn.iocoder.mall.product.api.ProductCategoryService;
import cn.iocoder.mall.product.api.bo.ProductCategoryBO;
import cn.iocoder.mall.product.api.constant.ProductCategoryConstants;

View File

@ -1,7 +1,7 @@
package cn.iocoder.mall.product.application.controller.admins;
import cn.iocoder.common.framework.vo.CommonResult;
import cn.iocoder.mall.admin.sdk.context.AdminSecurityContextHolder;
import cn.iocoder.mall.system.sdk.context.AdminSecurityContextHolder;
import cn.iocoder.mall.product.api.ProductSpuService;
import cn.iocoder.mall.product.api.bo.ProductSpuBO;
import cn.iocoder.mall.product.api.bo.ProductSpuDetailBO;

View File

@ -1,7 +1,7 @@
package cn.iocoder.mall.promotion.application.controller.admins;
import cn.iocoder.common.framework.vo.CommonResult;
import cn.iocoder.mall.admin.sdk.context.AdminSecurityContextHolder;
import cn.iocoder.mall.system.sdk.context.AdminSecurityContextHolder;
import cn.iocoder.mall.promotion.api.BannerService;
import cn.iocoder.mall.promotion.api.bo.BannerPageBO;
import cn.iocoder.mall.promotion.api.dto.BannerAddDTO;

View File

@ -2,7 +2,7 @@ package cn.iocoder.mall.promotion.application.controller.admins;
import cn.iocoder.common.framework.util.DateUtil;
import cn.iocoder.common.framework.vo.CommonResult;
import cn.iocoder.mall.admin.sdk.context.AdminSecurityContextHolder;
import cn.iocoder.mall.system.sdk.context.AdminSecurityContextHolder;
import cn.iocoder.mall.promotion.api.CouponService;
import cn.iocoder.mall.promotion.api.bo.CouponTemplateBO;
import cn.iocoder.mall.promotion.api.bo.CouponTemplatePageBO;

View File

@ -1,7 +1,7 @@
package cn.iocoder.mall.promotion.application.controller.admins;
import cn.iocoder.common.framework.vo.CommonResult;
import cn.iocoder.mall.admin.sdk.context.AdminSecurityContextHolder;
import cn.iocoder.mall.system.sdk.context.AdminSecurityContextHolder;
import cn.iocoder.mall.product.api.ProductSpuService;
import cn.iocoder.mall.product.api.bo.ProductSpuBO;
import cn.iocoder.mall.promotion.api.ProductRecommendService;

View File

@ -14,10 +14,15 @@
<packaging>pom</packaging>
<modules>
<module>system-application</module>
<!-- <module>system-application</module>-->
<module>system-sdk</module>
<module>system-service-api</module>
<module>system-service-impl</module>
<module>system-rpc-api</module>
<module>system-rpc</module>
<module>system-rest</module>
<module>system-biz</module>
<module>system-application</module>
</modules>
<dependencyManagement>

View File

@ -15,93 +15,10 @@
<!-- Mall 相关 -->
<dependency>
<groupId>cn.iocoder.mall</groupId>
<artifactId>common-framework</artifactId>
<artifactId>system-rest</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>cn.iocoder.mall</groupId>
<artifactId>mall-spring-boot</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>cn.iocoder.mall</groupId>
<artifactId>system-service-impl</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>cn.iocoder.mall</groupId>
<artifactId>system-sdk</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!-- Web 相关 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
</dependency>
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>swagger-bootstrap-ui</artifactId>
</dependency>
<!-- 云服务相关 -->
<dependency>
<groupId>com.qiniu</groupId>
<artifactId>qiniu-java-sdk</artifactId>
</dependency>
<!-- 服务保障相关 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<!-- 监控相关 -->
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-starter-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
</dependency>
<!-- 测试相关 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<!-- 提供给 mapstruct 使用 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
</plugin>
<!-- 打包 -->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

View File

@ -1,36 +0,0 @@
package cn.iocoder.mall.admin.application.convert;
import cn.iocoder.common.framework.vo.PageResult;
import cn.iocoder.mall.admin.api.bo.admin.AdminBO;
import cn.iocoder.mall.admin.api.bo.systemlog.AccessLogBO;
import cn.iocoder.mall.admin.api.bo.systemlog.AccessLogPageBO;
import cn.iocoder.mall.admin.application.vo.log.AccessLogPageVo;
import cn.iocoder.mall.admin.application.vo.log.AccessLogVo;
import cn.iocoder.mall.admin.dataobject.AccessLogDO;
import cn.iocoder.mall.admin.dataobject.AdminDO;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.Mappings;
import org.mapstruct.factory.Mappers;
/**
* @author:ycjx
* @descriptio
* @create:2019-06-23 17:36
*/
@Mapper
public interface AccessLogConvert {
AccessLogConvert INSTANCE = Mappers.getMapper(AccessLogConvert.class);
@Mappings({})
AccessLogPageVo convert(AccessLogPageBO result);
@Mappings({})
AccessLogVo convert(AccessLogBO result);
}

View File

@ -0,0 +1,24 @@
package cn.iocoder.mall.system.application;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.config.ConfigFileApplicationListener;
@SpringBootApplication(scanBasePackages = {"cn.iocoder.mall.system"})
public class SystemApplication {
/**
* 设置需要读取的配置文件的名字
* 基于 {@link org.springframework.boot.context.config.ConfigFileApplicationListener#CONFIG_NAME_PROPERTY} 实现
*/
private static final String CONFIG_NAME_VALUE = "biz,rest,application";
public static void main(String[] args) {
// 设置环境变量
System.setProperty(ConfigFileApplicationListener.CONFIG_NAME_PROPERTY, CONFIG_NAME_VALUE);
// 启动 Spring Boot 应用
SpringApplication.run(SystemApplication.class, args);
}
}

View File

@ -1,34 +1,3 @@
spring:
application:
name: admin-application
# Spring Cloud 配置项
cloud:
# Spring Cloud Sentinel 配置项
sentinel:
transport:
dashboard: s1.iocoder.cn:12088 # Sentinel Dashboard 服务地址
eager: true # 项目启动时,直接连接到 Sentinel
# server
server:
port: 18083
servlet:
context-path: /admin-api/
admins:
security:
ignore_urls: /admin-api/admins/passport/login, /admin-api/admins/file/get_qiniu_token
# qiniu
qiniu:
access-key: YldfyUC7OewoWM63TPYTairqnq8GMJvNek9EGoID
secret-key: zZ7Q8wwZRyaklVvkyLmVydA4WygOBqtc_gTYzalS
bucket: onemall
swagger:
enable: true # 暂时不去掉
title: 管理员子系统
description: 管理员子系统
version: 1.0.0
base-package: cn.iocoder.mall.admin.application.controller

68
system/system-biz/pom.xml Normal file
View File

@ -0,0 +1,68 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>system</artifactId>
<groupId>cn.iocoder.mall</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>system-biz</artifactId>
<dependencies>
<!-- Mall 相关 -->
<dependency>
<groupId>cn.iocoder.mall</groupId>
<artifactId>common-framework</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!-- Spring 核心 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<!-- DB 相关 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
</dependency>
<!-- 工具类相关 -->
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId> <!-- use mapstruct-jdk8 for Java 8 or higher -->
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-jdk8</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,26 @@
package cn.iocoder.mall.system.biz.bo.account;
import lombok.Data;
import lombok.experimental.Accessors;
/**
* 账号信息 BO
*/
@Data
@Accessors(chain = true)
public class AccountBO {
/**
* 账号编号
*/
private Integer id;
/**
* 登陆账号
*/
private String username;
/**
* 登陆密码
*/
private String password;
}

View File

@ -0,0 +1,22 @@
package cn.iocoder.mall.system.biz.bo.account;
import lombok.Data;
import lombok.experimental.Accessors;
/**
* 账号模块 - 用户名登陆 BO
*/
@Data
@Accessors(chain = true)
public class AccountUsernameAuthorizeBO {
/**
* 用户名
*/
private String username;
/**
* 密码
*/
private String password;
}

View File

@ -0,0 +1,22 @@
package cn.iocoder.mall.system.biz.bo.admin;
import lombok.Data;
import lombok.experimental.Accessors;
/**
* 管理员模块 - 账号信息 BO
*/
@Data
@Accessors(chain = true)
public class AdminBO {
/**
* 管理员编号
*/
private Integer id;
/**
* 真实名字
*/
private String name;
}

View File

@ -0,0 +1,32 @@
package cn.iocoder.mall.system.biz.bo.ouath2;
import lombok.Data;
import lombok.experimental.Accessors;
import java.util.Date;
/**
* TODO 注释
*/
@Data
@Accessors(chain = true)
public class OAuth2AccessTokenBO {
/**
* 访问令牌
*/
private String id;
/**
* 刷新令牌
*/
private String refreshToken;
/**
* 账号编号
*/
private Integer accountId;
/**
* 过期时间
*/
private Date expiresTime;
}

View File

@ -0,0 +1 @@
package cn.iocoder.mall.system.biz.bo;

View File

@ -0,0 +1,28 @@
package cn.iocoder.mall.system.biz.config;
import com.baomidou.mybatisplus.core.injector.DefaultSqlInjector;
import com.baomidou.mybatisplus.core.injector.ISqlInjector;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.annotation.EnableTransactionManagement;
@Configuration
@MapperScan("cn.iocoder.mall.system.biz.dao") // 扫描对应的 Mapper 接口
@EnableTransactionManagement(proxyTargetClass = true) // 启动事务管理为什么使用 proxyTargetClass 参数参见 https://blog.csdn.net/huang_550/article/details/76492600
public class DatabaseConfiguration {
// 数据库连接池 Druid
@Bean
public ISqlInjector sqlInjector() {
return new DefaultSqlInjector(); // MyBatis Plus 逻辑删除
}
@Bean
public PaginationInterceptor paginationInterceptor() {
return new PaginationInterceptor(); // MyBatis Plus 分页插件
}
}

View File

@ -0,0 +1,19 @@
package cn.iocoder.mall.system.biz.config;
import cn.iocoder.common.framework.util.ServiceExceptionUtil;
import cn.iocoder.mall.system.biz.constant.SystemErrorCodeEnum;
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() {
for (SystemErrorCodeEnum item : SystemErrorCodeEnum.values()) {
ServiceExceptionUtil.put(item.getCode(), item.getMessage());
}
}
}

View File

@ -0,0 +1,91 @@
package cn.iocoder.mall.system.biz.constant;
import cn.iocoder.common.framework.util.ServiceExceptionUtil;
/**
* 错误码枚举类
*
* system 系统使用 1-002-000-000
*/
public enum SystemErrorCodeEnum implements ServiceExceptionUtil.Enumerable {
// ========== OAUTH2 模块 ==========
OAUTH2_UNKNOWN(1001001000, "未知错误"), // 预留
OAUTH2_ACCOUNT_NOT_FOUND(1001001001, "账号不存在"),
OAUTH2_ACCOUNT_PASSWORD_ERROR(1001001002, "密码不正确"),
//// OAUTH2_INVALID_GRANT_USERNAME_NOT_FOUND(1001001002, "账号不存在"), // 暂时没用到
//// OAUTH2_INVALID_GRANT(1001001010, ""), // 预留
// OAUTH2_INVALID_TOKEN_NOT_FOUND(1002001011, "访问令牌不存在"),
// OAUTH2_INVALID_TOKEN_EXPIRED(1002001012, "访问令牌已过期"),
// OAUTH2_INVALID_TOKEN_INVALID(1002001013, "访问令牌已失效"),
// OAUTH2_NOT_LOGIN(1002001015, "账号未登陆"),
// OAUTH2_INVALID_TOKEN_ERROR_USER_TYPE(1002001016, "访问令牌用户类型不正确"),
// OAUTH_INVALID_REFRESH_TOKEN_NOT_FOUND(1002001017, "刷新令牌不存在"),
// OAUTH_INVALID_REFRESH_TOKEN_EXPIRED(1002001018, "访问令牌已过期"),
// OAUTH_INVALID_REFRESH_TOKEN_INVALID(1002001019, "刷新令牌已失效"),
// ========== 管理员模块 1002002000 ==========
ADMIN_NOT_FOUND(1002002000, "管理员不存在"),
// 废弃 ADMIN_USERNAME_NOT_REGISTERED(1002002000, "账号不存在"),
// 废弃 ADMIN_PASSWORD_ERROR(1002002001, "密码不正确"),
// ADMIN_IS_DISABLE(1002002002, "账号被禁用"),
// ADMIN_USERNAME_EXISTS(1002002002, "账号已经存在"),
// ADMIN_STATUS_EQUALS(1002002003, "账号已经是该状态"),
// ADMIN_DELETE_ONLY_DISABLE(1002002004, "只有关闭的账号才可以删除"),
// ADMIN_ADMIN_STATUS_CAN_NOT_UPDATE(1002002005, "管理员的账号状态不允许变更"),
// ADMIN_ASSIGN_ROLE_NOT_EXISTS(1002002006, "分配员工角色时,有角色不存在"),
// ADMIN_INVALID_PERMISSION(1002002007, "没有该操作权限"),
// ADMIN_ADMIN_CAN_NOT_UPDATE(1002002008, "管理员的账号不允许变更"),
// ADMIN_DEMO_CAN_NOT_WRITE(1002002009, "演示账号暂不允许写操作。欢迎加入我们的交流群http://t.cn/EKEr5WE"),
// ========== 资源模块 1002003000 ==========
// RESOURCE_NAME_DUPLICATE(1002003000, "已经存在该名字的资源"),
// RESOURCE_PARENT_NOT_EXISTS(1002003001, "父资源不存在"),
// RESOURCE_PARENT_ERROR(1002003002, "不能设置自己为父资源"),
// RESOURCE_NOT_EXISTS(1002003003, "资源不存在"),
// RESOURCE_EXISTS_CHILDREN(1002003004, "存在子资源,无法删除"),
// RESOURCE_PARENT_NOT_MENU(1002003005, "父资源的类型必须是菜单"),
// ========== 角色模块 1002004000 ==========
// ROLE_NOT_EXISTS(1002004000, "角色不存在"),
// ROLE_ASSIGN_RESOURCE_NOT_EXISTS(1002004001, "分配角色资源时,有资源不存在"),
// ========== 数据字典模块 1002005000 ==========
// DATA_DICT_EXISTS(1002005000, "该数据字典已经存在"),
// DATA_DICT_NOT_EXISTS(1002005001, "该数据字典不存在"),
// ========== 短信模板 1002006000 ==========
// SMS_PLATFORM_FAIL(1002006000, "短信平台调用失败【具体错误会动态替换】"),
// SMS_SIGN_NOT_EXISTENT(1002006001, "短信签名不存在"),
// SMS_SIGN_IS_EXISTENT(1002006002, "短信签名已存在"),
// SMS_TEMPLATE_NOT_EXISTENT(1002006020, "短信签名不存在"),
// SMS_TEMPLATE_IS_EXISTENT(1002006021, "短信签名不存在"),
// SMS_NOT_SEND_CLIENT(1002006030, "短信没有发送的client"),
// ========== 部门模块 1002007000 ==========
// DEPT_SAME_LEVEL_NAME_EXITS(1002007001,"当前级别部门名字已存在"),
// DEPT_PARENT_NOT_EXITS(1002007002,"父级部门不存在"),
// DEPT_NOT_EXITS(1002007003, "当前部门不存在"),
// DEPT_EXITS_CHILDREN(1002007004, "当前部门存在子部门"),
// DEPT_PARENT_NOT_LEGAL(1002007005, "父级部门不合法"),
;
private final int code;
private final String message;
SystemErrorCodeEnum(int code, String message) {
this.code = code;
this.message = message;
}
@Override
public int getCode() {
return code;
}
public String getMessage() {
return message;
}
}

View File

@ -0,0 +1,15 @@
package cn.iocoder.mall.system.biz.convert;
import cn.iocoder.mall.system.biz.bo.account.AccountBO;
import cn.iocoder.mall.system.biz.dataobject.account.AccountDO;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
@Mapper
public interface AccountConvert {
AccountConvert INSTANCE = Mappers.getMapper(AccountConvert.class);
AccountBO convert(AccountDO accountDO);
}

View File

@ -0,0 +1,15 @@
package cn.iocoder.mall.system.biz.convert;
import cn.iocoder.mall.system.biz.bo.admin.AdminBO;
import cn.iocoder.mall.system.biz.dataobject.admin.AdminDO;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
@Mapper
public interface AdminConvert {
AdminConvert INSTANCE = Mappers.getMapper(AdminConvert.class);
AdminBO convert(AdminDO adminDO);
}

View File

@ -0,0 +1,15 @@
package cn.iocoder.mall.system.biz.convert;
import cn.iocoder.mall.system.biz.bo.ouath2.OAuth2AccessTokenBO;
import cn.iocoder.mall.system.biz.dataobject.oauth2.OAuth2AccessTokenDO;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
@Mapper
public interface OAuth2Convert {
OAuth2Convert INSTANCE = Mappers.getMapper(OAuth2Convert.class);
OAuth2AccessTokenBO convert(OAuth2AccessTokenDO accessTokenDO);
}

View File

@ -0,0 +1,17 @@
package cn.iocoder.mall.system.biz.dao.account;
import cn.iocoder.mall.system.biz.dataobject.account.AccountDO;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.springframework.stereotype.Repository;
@Repository
public interface AccountMapper extends BaseMapper<AccountDO> {
default AccountDO selectByUsername(String username) {
return selectOne(new QueryWrapper<AccountDO>()
.eq("username", username)
);
}
}

View File

@ -0,0 +1,10 @@
package cn.iocoder.mall.system.biz.dao.admin;
import cn.iocoder.mall.system.biz.dataobject.admin.AdminDO;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.springframework.stereotype.Repository;
@Repository
public interface AdminMapper extends BaseMapper<AdminDO> {
}

View File

@ -0,0 +1,24 @@
package cn.iocoder.mall.system.biz.dao.oauth2;
import cn.iocoder.mall.system.biz.dataobject.oauth2.OAuth2AccessTokenDO;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.springframework.stereotype.Repository;
@Repository
public interface OAuth2AccessTokenMapper extends BaseMapper<OAuth2AccessTokenDO> {
default int updateToInvalid(Integer accountId) {
QueryWrapper<OAuth2AccessTokenDO> query = new QueryWrapper<OAuth2AccessTokenDO>()
.eq("account_id", accountId)
.eq("valid", true);
return update(new OAuth2AccessTokenDO().setValid(false), query);
}
default int updateToInvalidByRefreshToken(String refreshToken) {
QueryWrapper<OAuth2AccessTokenDO> query = new QueryWrapper<OAuth2AccessTokenDO>()
.eq("refresh_token", refreshToken).eq("valid", true);
return update(new OAuth2AccessTokenDO().setValid(false), query);
}
}

View File

@ -0,0 +1,18 @@
package cn.iocoder.mall.system.biz.dao.oauth2;
import cn.iocoder.mall.system.biz.dataobject.oauth2.OAuth2RefreshTokenDO;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.springframework.stereotype.Repository;
@Repository
public interface OAuth2RefreshTokenMapper extends BaseMapper<OAuth2RefreshTokenDO> {
default int updateToInvalid(Integer accountId) {
QueryWrapper<OAuth2RefreshTokenDO> query = new QueryWrapper<OAuth2RefreshTokenDO>()
.eq("account_id", accountId)
.eq("valid", true);
return update(new OAuth2RefreshTokenDO().setValid(false), query);
}
}

View File

@ -0,0 +1,66 @@
package cn.iocoder.mall.system.biz.dataobject.account;
import cn.iocoder.common.framework.dataobject.DeletableDO;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.util.Date;
/**
* 账号实体
*/
@TableName(value = "account")
@Data
@EqualsAndHashCode(callSuper = true)
@Accessors(chain = true)
public class AccountDO extends DeletableDO {
/**
* 账号编号
*/
private Integer id;
/**
* 登陆账号
*/
private String username;
/**
* 手机号
*/
private String mobile;
/**
* 邮箱
*/
private String email;
/**
* 密码
*
* // TODO 芋艿 暂时明文
*/
private String password;
/**
* 账号状态
*
* {@link cn.iocoder.common.framework.constant.CommonStatusEnum}
*/
private Integer status;
/**
* 创建 IP
*/
private String createIp;
/**
* 最后登陆时间
*/
private Date lastLoginTime;
/**
* 最后登陆 IP
*/
private String lastLoginIp;
/**
* 登陆次数
*/
private Integer loginTimes;
}

View File

@ -0,0 +1,40 @@
package cn.iocoder.mall.system.biz.dataobject.admin;
import cn.iocoder.common.framework.dataobject.DeletableDO;
import cn.iocoder.mall.system.biz.dataobject.account.AccountDO;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
* 管理员实体
*/
@TableName(value = "admin")
@Data
@EqualsAndHashCode(callSuper = true)
@Accessors(chain = true)
public class AdminDO extends DeletableDO {
/**
* 管理员编号
*/
private Integer id;
/**
* 账号编号
*
* 关联 {@link AccountDO#getId()}
*/
private Integer accountId;
/**
* 真实名字
*/
private String name;
/**
* 科室编号
*
* 关联 {@link DepartmentDO#getId()}
*/
private Integer departmentId;
}

View File

@ -0,0 +1,35 @@
package cn.iocoder.mall.system.biz.dataobject.admin;
import cn.iocoder.common.framework.dataobject.DeletableDO;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
* 部门实体
*/
@TableName(value = "department")
@Data
@EqualsAndHashCode(callSuper = true)
@Accessors(chain = true)
public class DepartmentDO extends DeletableDO {
/**
* 部门编号
*/
private Integer id;
/**
* 部门名称
*/
private String name;
/**
* 排序值
*/
private Integer sort;
/**
* 父级部门编号
*/
private Integer pid;
}

View File

@ -0,0 +1,49 @@
package cn.iocoder.mall.system.biz.dataobject.oauth2;
import cn.iocoder.common.framework.dataobject.BaseDO;
import cn.iocoder.mall.system.biz.dataobject.account.AccountDO;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.util.Date;
/**
* OAuth2 访问令牌
*/
@TableName("oauth2_access_token")
@Data
@EqualsAndHashCode(callSuper = true)
@Accessors(chain = true)
public class OAuth2AccessTokenDO extends BaseDO {
/**
* 访问令牌
*/
@TableId(type = IdType.INPUT)
private String id;
/**
* 刷新令牌
*
* 关联 {@link OAuth2RefreshTokenDO#getId()}
*/
private String refreshToken;
/**
* 账号编号
*
* 关联 {@link AccountDO#getId()}
*/
private Integer accountId;
/**
* 过期时间
*/
private Date expiresTime;
/**
* 是否有效
*/
private Boolean valid;
}

View File

@ -0,0 +1,45 @@
package cn.iocoder.mall.system.biz.dataobject.oauth2;
import cn.iocoder.common.framework.dataobject.BaseDO;
import cn.iocoder.mall.system.biz.dataobject.account.AccountDO;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.util.Date;
/**
* OAuth2 刷新令牌
*
* idx_uid
*/
@TableName("oauth2_refresh_token")
@Data
@EqualsAndHashCode(callSuper = true)
@Accessors(chain = true)
public class OAuth2RefreshTokenDO extends BaseDO {
/**
* 刷新令牌
*/
@TableId(type = IdType.INPUT)
private String id;
/**
* 账号编号
*
* 关联 {@link AccountDO#getId()}
*/
private Integer accountId;
/**
* 是否有效
*/
private Boolean valid;
/**
* 过期时间
*/
private Date expiresTime;
}

View File

@ -0,0 +1,38 @@
package cn.iocoder.mall.system.biz.dataobject.user;
import cn.iocoder.common.framework.dataobject.DeletableDO;
import cn.iocoder.mall.system.biz.dataobject.account.AccountDO;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
* 用户实体
*/
@TableName(value = "user")
@Data
@EqualsAndHashCode(callSuper = true)
@Accessors(chain = true)
public class UserDO extends DeletableDO {
/**
* 用户编号
*/
private Integer id;
/**
* 账号编号
*
* 关联 {@link AccountDO#getId()}
*/
private Integer accountId;
/**
* 昵称
*/
private String nickname;
/**
* 头像
*/
private String avatar;
}

View File

@ -0,0 +1,14 @@
package cn.iocoder.mall.system.biz.dto.oatuh2;
import lombok.Data;
import lombok.experimental.Accessors;
// TODO 注释
@Data
@Accessors(chain = true)
public class OAuth2UsernameAuthenticateDTO {
private String username;
private String password;
}

View File

@ -0,0 +1 @@
package cn.iocoder.mall.system.biz.dto;

View File

@ -0,0 +1,14 @@
package cn.iocoder.mall.system.biz.service.account;
import cn.iocoder.mall.system.biz.bo.account.AccountBO;
/**
* 账号 Service 接口
*/
public interface AccountService {
AccountBO getByUsername(String username);
boolean matchPassword(String rawPassword, String encodedPassword);
}

View File

@ -0,0 +1,30 @@
package cn.iocoder.mall.system.biz.service.account.impl;
import cn.iocoder.mall.system.biz.bo.account.AccountBO;
import cn.iocoder.mall.system.biz.convert.AccountConvert;
import cn.iocoder.mall.system.biz.dao.account.AccountMapper;
import cn.iocoder.mall.system.biz.dataobject.account.AccountDO;
import cn.iocoder.mall.system.biz.service.account.AccountService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Objects;
@Service
public class AccountServiceImpl implements AccountService {
@Autowired
private AccountMapper accountMapper;
@Override
public AccountBO getByUsername(String username) {
AccountDO accountDO = accountMapper.selectByUsername(username);
return AccountConvert.INSTANCE.convert(accountDO);
}
@Override
public boolean matchPassword(String rawPassword, String encodedPassword) {
return Objects.equals(rawPassword, encodedPassword);
}
}

View File

@ -0,0 +1,9 @@
package cn.iocoder.mall.system.biz.service.admin;
import cn.iocoder.mall.system.biz.bo.admin.AdminBO;
public interface AdminService {
AdminBO get(Integer id);
}

View File

@ -0,0 +1,23 @@
package cn.iocoder.mall.system.biz.service.admin.impl;
import cn.iocoder.mall.system.biz.bo.admin.AdminBO;
import cn.iocoder.mall.system.biz.convert.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.service.admin.AdminService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class AdminServiceImpl implements AdminService {
@Autowired
private AdminMapper adminMapper;
@Override
public AdminBO get(Integer id) {
AdminDO adminDO = adminMapper.selectById(id);
return AdminConvert.INSTANCE.convert(adminDO);
}
}

View File

@ -0,0 +1,13 @@
package cn.iocoder.mall.system.biz.service.oauth2;
import cn.iocoder.mall.system.biz.bo.ouath2.OAuth2AccessTokenBO;
import cn.iocoder.mall.system.biz.dto.oatuh2.OAuth2UsernameAuthenticateDTO;
/**
* OAuth2 Service 接口
*/
public interface OAuth2Service {
OAuth2AccessTokenBO authenticate(OAuth2UsernameAuthenticateDTO usernameAuthenticateDTO);
}

View File

@ -0,0 +1,95 @@
package cn.iocoder.mall.system.biz.service.oauth2.impl;
import cn.iocoder.common.framework.util.ServiceExceptionUtil;
import cn.iocoder.mall.system.biz.bo.account.AccountBO;
import cn.iocoder.mall.system.biz.bo.ouath2.OAuth2AccessTokenBO;
import cn.iocoder.mall.system.biz.convert.OAuth2Convert;
import cn.iocoder.mall.system.biz.dao.oauth2.OAuth2AccessTokenMapper;
import cn.iocoder.mall.system.biz.dao.oauth2.OAuth2RefreshTokenMapper;
import cn.iocoder.mall.system.biz.dataobject.oauth2.OAuth2AccessTokenDO;
import cn.iocoder.mall.system.biz.dataobject.oauth2.OAuth2RefreshTokenDO;
import cn.iocoder.mall.system.biz.dto.oatuh2.OAuth2UsernameAuthenticateDTO;
import cn.iocoder.mall.system.biz.service.account.AccountService;
import cn.iocoder.mall.system.biz.service.oauth2.OAuth2Service;
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.UUID;
import static cn.iocoder.mall.system.biz.constant.SystemErrorCodeEnum.OAUTH2_ACCOUNT_NOT_FOUND;
import static cn.iocoder.mall.system.biz.constant.SystemErrorCodeEnum.OAUTH2_ACCOUNT_PASSWORD_ERROR;
@Service
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 AccountService accountService;
@Autowired
private OAuth2AccessTokenMapper oauth2AccessTokenMapper;
@Autowired
private OAuth2RefreshTokenMapper oauth2RefreshTokenMapper;
@Override
@Transactional
public OAuth2AccessTokenBO authenticate(OAuth2UsernameAuthenticateDTO usernameAuthenticateDTO) {
// 获得账号
AccountBO accountBO = accountService.getByUsername(usernameAuthenticateDTO.getUsername());
if (accountBO == null) {
throw ServiceExceptionUtil.exception(OAUTH2_ACCOUNT_NOT_FOUND);
}
// 校验密码
if (!accountService.matchPassword(usernameAuthenticateDTO.getPassword(), accountBO.getPassword())) {
throw ServiceExceptionUtil.exception(OAUTH2_ACCOUNT_PASSWORD_ERROR);
}
// 创建刷新令牌 + 访问令牌
OAuth2RefreshTokenDO oauth2RefreshTokenDO = createOAuth2RefreshToken(accountBO.getId());
OAuth2AccessTokenDO oauth2AccessTokenDO = createOAuth2AccessToken(accountBO.getId(), oauth2RefreshTokenDO.getId());
// 返回访问令牌
return OAuth2Convert.INSTANCE.convert(oauth2AccessTokenDO);
}
private OAuth2AccessTokenDO createOAuth2AccessToken(Integer accountId, String refreshToken) {
OAuth2AccessTokenDO accessToken = new OAuth2AccessTokenDO()
.setId(generateAccessToken())
.setAccountId(accountId)
.setRefreshToken(refreshToken)
.setExpiresTime(new Date(System.currentTimeMillis() + accessTokenExpireTimeMillis))
.setValid(true);
oauth2AccessTokenMapper.insert(accessToken);
return accessToken;
}
private OAuth2RefreshTokenDO createOAuth2RefreshToken(Integer accountId) {
OAuth2RefreshTokenDO refreshToken = new OAuth2RefreshTokenDO()
.setId(generateRefreshToken())
.setAccountId(accountId)
.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("-", "");
}
}

View File

@ -0,0 +1,4 @@
##################### 业务模块 #####################
## OAuth2CodeService
modules.oauth2-code-service.access-token-expire-time-millis = 2880000
modules.oauth2-code-service.refresh-token-expire-time-millis = 43200000

View File

@ -0,0 +1,20 @@
spring:
# 数据源配置项
datasource:
url: jdbc:mysql://s1.iocoder.cn:3306/mall_system?useSSL=false&useUnicode=true&characterEncoding=UTF-8
driver-class-name: com.mysql.jdbc.Driver
username: root
password: ${MALL_MYSQL_PASSWORD}
# MyBatis Plus 配置项
mybatis-plus:
configuration:
map-underscore-to-camel-case: true # 虽然默认为 true ,但是还是显示去指定下。
global-config:
db-config:
id-type: auto
logic-delete-value: 1 # 逻辑已删除值(默认为 1)
logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)
mapper-locations: classpath*:mapper/*.xml
type-aliases-package: cn.iocoder.mall.system.biz.dataobject

View File

@ -0,0 +1,41 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>system</artifactId>
<groupId>cn.iocoder.mall</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>system-rest</artifactId>
<description>提供 system 服务的 Rest 接口的实现,提供对外调用</description>
<dependencies>
<!-- Mall 相关 -->
<dependency>
<groupId>cn.iocoder.mall</groupId>
<artifactId>system-biz</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!-- Web 相关 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- TODO 实现自己的 starter -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
</dependency>
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>swagger-bootstrap-ui</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,50 @@
package cn.iocoder.mall.system.rest.controller.admin;
import cn.iocoder.common.framework.constant.MallConstants;
import cn.iocoder.common.framework.util.ServiceExceptionUtil;
import cn.iocoder.common.framework.vo.CommonResult;
import cn.iocoder.mall.system.biz.bo.admin.AdminBO;
import cn.iocoder.mall.system.biz.bo.ouath2.OAuth2AccessTokenBO;
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.AdminsAuthorizeUsernameLoginResponse;
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.constant.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("用户名认证")
public CommonResult<AdminsAuthorizeUsernameLoginResponse> usernameAuthenticate(AdminsOAuth2UsernameAuthenticateRequest request) {
// 执行认证
OAuth2UsernameAuthenticateDTO usernameAuthenticateDTO = AdminsOAuth2Convert.INSTANCE.convert(request);
OAuth2AccessTokenBO accessTokenBO = oauth2Service.authenticate(usernameAuthenticateDTO);
// 获得 Admin 信息
AdminBO adminBO = adminService.get(accessTokenBO.getAccountId());
if (adminBO == null) {
throw ServiceExceptionUtil.exception(ADMIN_NOT_FOUND);
}
// 转换返回
return CommonResult.success(
AdminsOAuth2Convert.INSTANCE.convert(adminBO, accessTokenBO)
);
}
}

View File

@ -0,0 +1,15 @@
package cn.iocoder.mall.system.rest.convert.admin;
import cn.iocoder.mall.system.biz.bo.account.AccountUsernameAuthorizeBO;
import cn.iocoder.mall.system.rest.request.oauth2.AdminsOAuth2UsernameAuthenticateRequest;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
@Mapper
public interface AdminsAdminConvert {
AdminsAdminConvert INSTANCE = Mappers.getMapper(AdminsAdminConvert.class);
AccountUsernameAuthorizeBO convert(AdminsOAuth2UsernameAuthenticateRequest request);
}

View File

@ -0,0 +1,29 @@
package cn.iocoder.mall.system.rest.convert.oauth2;
import cn.iocoder.mall.system.biz.bo.admin.AdminBO;
import cn.iocoder.mall.system.biz.bo.ouath2.OAuth2AccessTokenBO;
import cn.iocoder.mall.system.biz.dto.oatuh2.OAuth2UsernameAuthenticateDTO;
import cn.iocoder.mall.system.rest.request.oauth2.AdminsOAuth2UsernameAuthenticateRequest;
import cn.iocoder.mall.system.rest.response.AdminsAuthorizeUsernameLoginResponse;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.Mappings;
import org.mapstruct.factory.Mappers;
@Mapper
public interface AdminsOAuth2Convert {
AdminsOAuth2Convert INSTANCE = Mappers.getMapper(AdminsOAuth2Convert.class);
OAuth2UsernameAuthenticateDTO convert(AdminsOAuth2UsernameAuthenticateRequest request);
@Mappings(value = {
@Mapping(source = "adminBO.id", target = "id"),
@Mapping(source = "adminBO.name", target = "name"),
@Mapping(source = "accessTokenBO.id", target = "token.accessToken"),
@Mapping(source = "accessTokenBO.refreshToken", target = "token.refreshToken"),
@Mapping(source = "accessTokenBO.expiresTime", target = "token.expiresTime"),
})
AdminsAuthorizeUsernameLoginResponse convert(AdminBO adminBO, OAuth2AccessTokenBO accessTokenBO);
}

View File

@ -0,0 +1,28 @@
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 AdminsOAuth2UsernameAuthenticateRequest {
@ApiModelProperty(value = "用户名", required = true, example = "yudaoyuanma")
@NotEmpty(message = "登陆账号不能为空")
@Length(min = 5, max = 16, message = "账号长度为 5-16 位")
@Pattern(regexp = "^[A-Za-z0-9]+$", message = "账号格式为数字以及字母")
private String username;
@ApiModelProperty(value = "用户名", required = true, example = "buzhidao")
@NotEmpty(message = "密码不能为空")
@Length(min = 4, max = 16, message = "密码长度为 4-16 位")
private String password;
}

View File

@ -0,0 +1 @@
package cn.iocoder.mall.system.rest.request;

View File

@ -0,0 +1,40 @@
package cn.iocoder.mall.system.rest.response;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.experimental.Accessors;
import java.util.Date;
@ApiModel("管理员 - 认证 - 用户名登陆响应")
@Data
@Accessors(chain = true)
public class AdminsAuthorizeUsernameLoginResponse {
@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;
}
@ApiModelProperty(value = "管理员编号", required = true, example = "1")
private Integer id;
@ApiModelProperty(value = "真实名字", required = true, example = "小王")
private String name;
/**
* TODO 晚点测试下 swagger 的表现
*/
private Token token;
}

View File

@ -0,0 +1,5 @@
# 服务器的配置项
server:
port: 18083
servlet:
context-path: /system-api/

View File

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>system</artifactId>
<groupId>cn.iocoder.mall</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>system-rpc-api</artifactId>
</project>

View File

@ -0,0 +1,4 @@
/**
* 提供 system 服务的 RPC 接口的定义提供内部调用
*/
package cn.iocoder.mall.system.rpc;

15
system/system-rpc/pom.xml Normal file
View File

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>system</artifactId>
<groupId>cn.iocoder.mall</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>system-rpc</artifactId>
</project>

View File

@ -0,0 +1,4 @@
/**
* 提供 system 服务的 RPC 接口的实现提供内部调用
*/
package cn.iocoder.mall.system.rpc;

View File

@ -1,6 +0,0 @@
/**
* 提供 SDK 给其它服务使用如下功能
*
* 1. 通过 {@link cn.iocoder.mall.admin.sdk.interceptor.AdminSecurityInterceptor} 拦截器实现需要登陆 URL 的鉴权
*/
package cn.iocoder.mall.admin.sdk;

View File

@ -1,4 +1,4 @@
package cn.iocoder.mall.admin.sdk.annotation;
package cn.iocoder.mall.system.sdk.annotation;
import java.lang.annotation.*;

View File

@ -1,4 +1,4 @@
package cn.iocoder.mall.admin.sdk.constant;
package cn.iocoder.mall.system.sdk.constant;
/**
* 逻辑类型枚举

View File

@ -1,4 +1,4 @@
package cn.iocoder.mall.admin.sdk.context;
package cn.iocoder.mall.system.sdk.context;
import lombok.Data;
import lombok.experimental.Accessors;

View File

@ -1,4 +1,4 @@
package cn.iocoder.mall.admin.sdk.context;
package cn.iocoder.mall.system.sdk.context;
/**
* {@link AdminSecurityContext} Holder

View File

@ -1,9 +1,9 @@
package cn.iocoder.mall.admin.sdk.interceptor;
package cn.iocoder.mall.system.sdk.interceptor;
import cn.iocoder.common.framework.util.ServiceExceptionUtil;
import cn.iocoder.mall.admin.api.constant.AdminConstants;
import cn.iocoder.mall.admin.api.constant.AdminErrorCodeEnum;
import cn.iocoder.mall.admin.sdk.context.AdminSecurityContextHolder;
import cn.iocoder.mall.system.api.constant.AdminConstants;
import cn.iocoder.mall.system.api.constant.AdminErrorCodeEnum;
import cn.iocoder.mall.system.sdk.context.AdminSecurityContextHolder;
import org.springframework.http.HttpMethod;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

View File

@ -1,19 +1,19 @@
package cn.iocoder.mall.admin.sdk.interceptor;
package cn.iocoder.mall.system.sdk.interceptor;
import cn.iocoder.common.framework.constant.UserTypeEnum;
import cn.iocoder.common.framework.exception.ServiceException;
import cn.iocoder.common.framework.util.HttpUtil;
import cn.iocoder.common.framework.util.MallUtil;
import cn.iocoder.common.framework.util.StringUtil;
import cn.iocoder.mall.admin.api.AdminService;
import cn.iocoder.mall.admin.api.OAuth2Service;
import cn.iocoder.mall.admin.api.bo.admin.AdminAuthorizationBO;
import cn.iocoder.mall.admin.api.bo.oauth2.OAuth2AuthenticationBO;
import cn.iocoder.mall.admin.api.constant.AdminErrorCodeEnum;
import cn.iocoder.mall.admin.api.dto.oauth2.OAuth2GetTokenDTO;
import cn.iocoder.mall.admin.sdk.annotation.RequiresPermissions;
import cn.iocoder.mall.admin.sdk.context.AdminSecurityContext;
import cn.iocoder.mall.admin.sdk.context.AdminSecurityContextHolder;
import cn.iocoder.mall.system.api.AdminService;
import cn.iocoder.mall.system.api.OAuth2Service;
import cn.iocoder.mall.system.api.bo.admin.AdminAuthorizationBO;
import cn.iocoder.mall.system.api.bo.oauth2.OAuth2AuthenticationBO;
import cn.iocoder.mall.system.api.constant.AdminErrorCodeEnum;
import cn.iocoder.mall.system.api.dto.oauth2.OAuth2GetTokenDTO;
import cn.iocoder.mall.system.sdk.annotation.RequiresPermissions;
import cn.iocoder.mall.system.sdk.context.AdminSecurityContext;
import cn.iocoder.mall.system.sdk.context.AdminSecurityContextHolder;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

View File

@ -0,0 +1,6 @@
/**
* 提供 SDK 给其它服务使用如下功能
*
* 1. 通过 {@link cn.iocoder.mall.system.sdk.interceptor.AdminSecurityInterceptor} 拦截器实现需要登陆 URL 的鉴权
*/
package cn.iocoder.mall.system.sdk;

View File

@ -1,11 +1,12 @@
package cn.iocoder.mall.admin.api;
package cn.iocoder.mall.system.api;
import cn.iocoder.common.framework.vo.PageResult;
import cn.iocoder.mall.admin.api.bo.admin.AdminAuthenticationBO;
import cn.iocoder.mall.admin.api.bo.admin.AdminAuthorizationBO;
import cn.iocoder.mall.admin.api.bo.admin.AdminBO;
import cn.iocoder.mall.admin.api.bo.role.RoleBO;
import cn.iocoder.mall.system.api.bo.admin.AdminAuthenticationBO;
import cn.iocoder.mall.system.api.bo.admin.AdminAuthorizationBO;
import cn.iocoder.mall.system.api.bo.admin.AdminBO;
import cn.iocoder.mall.system.api.bo.role.RoleBO;
import cn.iocoder.mall.admin.api.dto.admin.*;
import cn.iocoder.mall.system.api.dto.admin.*;
import java.util.Collection;
import java.util.List;

View File

@ -1,9 +1,9 @@
package cn.iocoder.mall.admin.api;
package cn.iocoder.mall.system.api;
import cn.iocoder.common.framework.vo.CommonResult;
import cn.iocoder.mall.admin.api.bo.datadict.DataDictBO;
import cn.iocoder.mall.admin.api.dto.datadict.DataDictAddDTO;
import cn.iocoder.mall.admin.api.dto.datadict.DataDictUpdateDTO;
import cn.iocoder.mall.system.api.bo.datadict.DataDictBO;
import cn.iocoder.mall.system.api.dto.datadict.DataDictAddDTO;
import cn.iocoder.mall.system.api.dto.datadict.DataDictUpdateDTO;
import java.util.Collection;
import java.util.List;

View File

@ -1,10 +1,10 @@
package cn.iocoder.mall.admin.api;
package cn.iocoder.mall.system.api;
import cn.iocoder.common.framework.vo.PageResult;
import cn.iocoder.mall.admin.api.bo.deptment.DeptmentBO;
import cn.iocoder.mall.admin.api.dto.depetment.DeptmentAddDTO;
import cn.iocoder.mall.admin.api.dto.depetment.DeptmentPageDTO;
import cn.iocoder.mall.admin.api.dto.depetment.DeptmentUpdateDTO;
import cn.iocoder.mall.system.api.bo.deptment.DeptmentBO;
import cn.iocoder.mall.system.api.dto.depetment.DeptmentAddDTO;
import cn.iocoder.mall.system.api.dto.depetment.DeptmentPageDTO;
import cn.iocoder.mall.system.api.dto.depetment.DeptmentUpdateDTO;
import java.util.List;

View File

@ -1,11 +1,11 @@
package cn.iocoder.mall.admin.api;
package cn.iocoder.mall.system.api;
import cn.iocoder.mall.admin.api.bo.oauth2.OAuth2AccessTokenBO;
import cn.iocoder.mall.admin.api.bo.oauth2.OAuth2AuthenticationBO;
import cn.iocoder.mall.admin.api.dto.oauth2.OAuth2CreateTokenDTO;
import cn.iocoder.mall.admin.api.dto.oauth2.OAuth2GetTokenDTO;
import cn.iocoder.mall.admin.api.dto.oauth2.OAuth2RefreshTokenDTO;
import cn.iocoder.mall.admin.api.dto.oauth2.OAuth2RemoveTokenByUserDTO;
import cn.iocoder.mall.system.api.bo.oauth2.OAuth2AccessTokenBO;
import cn.iocoder.mall.system.api.bo.oauth2.OAuth2AuthenticationBO;
import cn.iocoder.mall.system.api.dto.oauth2.OAuth2CreateTokenDTO;
import cn.iocoder.mall.system.api.dto.oauth2.OAuth2GetTokenDTO;
import cn.iocoder.mall.system.api.dto.oauth2.OAuth2RefreshTokenDTO;
import cn.iocoder.mall.system.api.dto.oauth2.OAuth2RemoveTokenByUserDTO;
/**
* Oauth2 服务接口

View File

@ -1,8 +1,8 @@
package cn.iocoder.mall.admin.api;
package cn.iocoder.mall.system.api;
import cn.iocoder.mall.admin.api.bo.resource.ResourceBO;
import cn.iocoder.mall.admin.api.dto.resource.ResourceAddDTO;
import cn.iocoder.mall.admin.api.dto.resource.ResourceUpdateDTO;
import cn.iocoder.mall.system.api.bo.resource.ResourceBO;
import cn.iocoder.mall.system.api.dto.resource.ResourceAddDTO;
import cn.iocoder.mall.system.api.dto.resource.ResourceUpdateDTO;
import org.springframework.lang.Nullable;
import java.util.List;

View File

@ -1,11 +1,11 @@
package cn.iocoder.mall.admin.api;
package cn.iocoder.mall.system.api;
import cn.iocoder.common.framework.vo.PageResult;
import cn.iocoder.mall.admin.api.bo.role.RoleBO;
import cn.iocoder.mall.admin.api.dto.role.RoleAddDTO;
import cn.iocoder.mall.admin.api.dto.role.RoleAssignResourceDTO;
import cn.iocoder.mall.admin.api.dto.role.RolePageDTO;
import cn.iocoder.mall.admin.api.dto.role.RoleUpdateDTO;
import cn.iocoder.mall.system.api.bo.role.RoleBO;
import cn.iocoder.mall.system.api.dto.role.RoleAddDTO;
import cn.iocoder.mall.system.api.dto.role.RoleAssignResourceDTO;
import cn.iocoder.mall.system.api.dto.role.RolePageDTO;
import cn.iocoder.mall.system.api.dto.role.RoleUpdateDTO;
import java.util.Collection;
import java.util.List;

View File

@ -1,11 +1,11 @@
package cn.iocoder.mall.admin.api;
package cn.iocoder.mall.system.api;
import cn.iocoder.mall.admin.api.bo.sms.SmsSignBO;
import cn.iocoder.mall.admin.api.bo.sms.PageSmsSignBO;
import cn.iocoder.mall.admin.api.bo.sms.SmsTemplateBO;
import cn.iocoder.mall.admin.api.bo.sms.PageSmsTemplateBO;
import cn.iocoder.mall.admin.api.dto.sms.PageQuerySmsSignDTO;
import cn.iocoder.mall.admin.api.dto.sms.PageQuerySmsTemplateDTO;
import cn.iocoder.mall.system.api.bo.sms.SmsSignBO;
import cn.iocoder.mall.system.api.bo.sms.PageSmsSignBO;
import cn.iocoder.mall.system.api.bo.sms.SmsTemplateBO;
import cn.iocoder.mall.system.api.bo.sms.PageSmsTemplateBO;
import cn.iocoder.mall.system.api.dto.sms.PageQuerySmsSignDTO;
import cn.iocoder.mall.system.api.dto.sms.PageQuerySmsTemplateDTO;
import java.util.List;
import java.util.Map;

View File

@ -1,10 +1,9 @@
package cn.iocoder.mall.admin.api;
package cn.iocoder.mall.system.api;
import cn.iocoder.common.framework.vo.PageResult;
import cn.iocoder.mall.admin.api.bo.systemlog.AccessLogPageBO;
import cn.iocoder.mall.admin.api.dto.systemlog.AccessLogAddDTO;
import cn.iocoder.mall.admin.api.dto.systemlog.AccessLogPageDTO;
import cn.iocoder.mall.admin.api.dto.systemlog.ExceptionLogAddDTO;
import cn.iocoder.mall.system.api.bo.systemlog.AccessLogPageBO;
import cn.iocoder.mall.system.api.dto.systemlog.AccessLogAddDTO;
import cn.iocoder.mall.system.api.dto.systemlog.AccessLogPageDTO;
import cn.iocoder.mall.system.api.dto.systemlog.ExceptionLogAddDTO;
/**
* 系统日志 Service 接口

View File

@ -1,6 +1,6 @@
package cn.iocoder.mall.admin.api.bo.admin;
package cn.iocoder.mall.system.api.bo.admin;
import cn.iocoder.mall.admin.api.bo.oauth2.OAuth2AccessTokenBO;
import cn.iocoder.mall.system.api.bo.oauth2.OAuth2AccessTokenBO;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

View File

@ -1,4 +1,4 @@
package cn.iocoder.mall.admin.api.bo.admin;
package cn.iocoder.mall.system.api.bo.admin;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;

View File

@ -1,4 +1,4 @@
package cn.iocoder.mall.admin.api.bo.admin;
package cn.iocoder.mall.system.api.bo.admin;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;

View File

@ -1,4 +1,4 @@
package cn.iocoder.mall.admin.api.bo.admin;
package cn.iocoder.mall.system.api.bo.admin;
import lombok.Data;
import lombok.experimental.Accessors;

View File

@ -1,4 +1,4 @@
package cn.iocoder.mall.admin.api.bo.datadict;
package cn.iocoder.mall.system.api.bo.datadict;
import lombok.Data;
import lombok.experimental.Accessors;

View File

@ -1,4 +1,4 @@
package cn.iocoder.mall.admin.api.bo.deptment;
package cn.iocoder.mall.system.api.bo.deptment;
import io.swagger.annotations.ApiModel;
import lombok.Data;

View File

@ -1,4 +1,4 @@
package cn.iocoder.mall.admin.api.bo.oauth2;
package cn.iocoder.mall.system.api.bo.oauth2;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;

View File

@ -1,4 +1,4 @@
package cn.iocoder.mall.admin.api.bo.oauth2;
package cn.iocoder.mall.system.api.bo.oauth2;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;

View File

@ -1,4 +1,4 @@
package cn.iocoder.mall.admin.api.bo.resource;
package cn.iocoder.mall.system.api.bo.resource;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;

View File

@ -1,4 +1,4 @@
package cn.iocoder.mall.admin.api.bo.role;
package cn.iocoder.mall.system.api.bo.role;
import lombok.Data;
import lombok.experimental.Accessors;

View File

@ -1,4 +1,4 @@
package cn.iocoder.mall.admin.api.bo.sms;
package cn.iocoder.mall.system.api.bo.sms;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;

View File

@ -1,4 +1,4 @@
package cn.iocoder.mall.admin.api.bo.sms;
package cn.iocoder.mall.system.api.bo.sms;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;

View File

@ -1,4 +1,4 @@
package cn.iocoder.mall.admin.api.bo.sms;
package cn.iocoder.mall.system.api.bo.sms;
import lombok.Data;
import lombok.experimental.Accessors;

View File

@ -1,4 +1,4 @@
package cn.iocoder.mall.admin.api.bo.sms;
package cn.iocoder.mall.system.api.bo.sms;
import lombok.Data;
import lombok.experimental.Accessors;

View File

@ -1,4 +1,4 @@
package cn.iocoder.mall.admin.api.bo.systemlog;
package cn.iocoder.mall.system.api.bo.systemlog;
import lombok.Data;
import lombok.experimental.Accessors;

View File

@ -1,4 +1,4 @@
package cn.iocoder.mall.admin.api.bo.systemlog;
package cn.iocoder.mall.system.api.bo.systemlog;
import lombok.Data;
import lombok.experimental.Accessors;

View File

@ -1,4 +1,4 @@
package cn.iocoder.mall.admin.api.constant;
package cn.iocoder.mall.system.api.constant;
public class AdminConstants {

View File

@ -1,4 +1,4 @@
package cn.iocoder.mall.admin.api.constant;
package cn.iocoder.mall.system.api.constant;
/**
* 错误码枚举类

Some files were not shown because too many files have changed in this diff Show More