parent
21dbd7b8cb
commit
58525e0940
|
@ -0,0 +1,4 @@
|
||||||
|
*.css linguist-language=java
|
||||||
|
*.less linguist-language=java
|
||||||
|
*.js linguist-language=java
|
||||||
|
*.html linguist-language=java
|
30
README.md
30
README.md
|
@ -33,9 +33,35 @@ TODO 暂时不提供管理后台的账号密码,等后面提供。
|
||||||
|
|
||||||
TODO 此处应有一个演示的装逼 GIF 图。
|
TODO 此处应有一个演示的装逼 GIF 图。
|
||||||
|
|
||||||
## TODO
|
## 其它演示
|
||||||
|
|
||||||
提供其他演示环境。例如说 skywalking、sentinel 等等。
|
下面,我们会提供目前用到的中间件的管理平台。
|
||||||
|
|
||||||
|
> 艿艿:考虑到大家可以看到更全的功能,所以一般提供 admin 账号。所以,大家素质使用哟。
|
||||||
|
|
||||||
|
** SkyWalking UI **
|
||||||
|
|
||||||
|
* 地址:http://skywalking-ui.shop.iocoder.cn:18099
|
||||||
|
* 管理员账号:admin / admin
|
||||||
|
|
||||||
|
** Dubbo Admin **
|
||||||
|
|
||||||
|
* 地址:http://dubbo-admin.shop.iocoder.cn:18099
|
||||||
|
* 管理员账号:无需登陆
|
||||||
|
|
||||||
|
** RocketMQ Console **
|
||||||
|
|
||||||
|
* 地址:http://rocketmq-console.shop.iocoder.cn:18099
|
||||||
|
* 管理员账号:admin / RPsa2GHjTNs8pxEU
|
||||||
|
|
||||||
|
** Sentinel Console **
|
||||||
|
|
||||||
|
TODO
|
||||||
|
|
||||||
|
** XXL-Job Console **
|
||||||
|
|
||||||
|
* 地址:http://job-console.shop.iocoder.cn:18099
|
||||||
|
* 管理员账号:admin / 233666
|
||||||
|
|
||||||
# 技术
|
# 技术
|
||||||
|
|
||||||
|
|
18
Server.md
18
Server.md
|
@ -1,18 +0,0 @@
|
||||||
# 前端 Server
|
|
||||||
|
|
||||||
* admin 18083
|
|
||||||
*
|
|
||||||
|
|
||||||
# 后端 Server
|
|
||||||
|
|
||||||
# 基础服务
|
|
||||||
|
|
||||||
## MySQL
|
|
||||||
|
|
||||||
## Zookeeper
|
|
||||||
|
|
||||||
# 运维
|
|
||||||
|
|
||||||
* ssh 端口
|
|
||||||
* 工作目录 /work2/
|
|
||||||
|
|
|
@ -54,4 +54,6 @@ public class GlobalExceptionHandler {
|
||||||
return CommonResult.error(SysErrorCodeEnum.SYS_ERROR.getCode(), SysErrorCodeEnum.SYS_ERROR.getMessage());
|
return CommonResult.error(SysErrorCodeEnum.SYS_ERROR.getCode(), SysErrorCodeEnum.SYS_ERROR.getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO 芋艿,应该还有其它的异常,需要进行翻译
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,105 @@
|
||||||
|
package cn.iocoder.common.framework.dubbo;
|
||||||
|
|
||||||
|
import cn.iocoder.common.framework.exception.ServiceException;
|
||||||
|
import org.apache.dubbo.common.Constants;
|
||||||
|
import org.apache.dubbo.common.extension.Activate;
|
||||||
|
import org.apache.dubbo.common.logger.Logger;
|
||||||
|
import org.apache.dubbo.common.logger.LoggerFactory;
|
||||||
|
import org.apache.dubbo.common.utils.ReflectUtils;
|
||||||
|
import org.apache.dubbo.common.utils.StringUtils;
|
||||||
|
import org.apache.dubbo.rpc.*;
|
||||||
|
import org.apache.dubbo.rpc.filter.ExceptionFilter;
|
||||||
|
import org.apache.dubbo.rpc.service.GenericService;
|
||||||
|
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 基于 {@link org.apache.dubbo.rpc.filter.ExceptionFilter} 实现
|
||||||
|
*
|
||||||
|
* 主要目的是,一些全局性的异常,能够返回。因为,Dubbo Consumer 能够保证,一定会引入全局性的异常。
|
||||||
|
*/
|
||||||
|
@Activate(group = Constants.PROVIDER)
|
||||||
|
public class DubboExceptionFilter implements Filter {
|
||||||
|
|
||||||
|
private final Logger logger;
|
||||||
|
|
||||||
|
public DubboExceptionFilter() {
|
||||||
|
this(LoggerFactory.getLogger(ExceptionFilter.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
public DubboExceptionFilter(Logger logger) {
|
||||||
|
this.logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
|
||||||
|
try {
|
||||||
|
return invoker.invoke(invocation);
|
||||||
|
} catch (RuntimeException e) {
|
||||||
|
logger.error("Got unchecked and undeclared exception which called by " + RpcContext.getContext().getRemoteHost()
|
||||||
|
+ ". service: " + invoker.getInterface().getName() + ", method: " + invocation.getMethodName()
|
||||||
|
+ ", exception: " + e.getClass().getName() + ": " + e.getMessage(), e);
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Result onResponse(Result result, Invoker<?> invoker, Invocation invocation) {
|
||||||
|
if (result.hasException() && GenericService.class != invoker.getInterface()) {
|
||||||
|
try {
|
||||||
|
Throwable exception = result.getException();
|
||||||
|
|
||||||
|
// directly throw if it's checked exception
|
||||||
|
if (!(exception instanceof RuntimeException) && (exception instanceof Exception)) {
|
||||||
|
return result;
|
||||||
|
} else if (exception instanceof ServiceException) { // add by 芋艿。如果是业务异常,继续抛出
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
// directly throw if the exception appears in the signature
|
||||||
|
try {
|
||||||
|
Method method = invoker.getInterface().getMethod(invocation.getMethodName(), invocation.getParameterTypes());
|
||||||
|
Class<?>[] exceptionClassses = method.getExceptionTypes();
|
||||||
|
for (Class<?> exceptionClass : exceptionClassses) {
|
||||||
|
if (exception.getClass().equals(exceptionClass)) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (NoSuchMethodException e) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// for the exception not found in method's signature, print ERROR message in server's log.
|
||||||
|
logger.error("Got unchecked and undeclared exception which called by " + RpcContext.getContext().getRemoteHost()
|
||||||
|
+ ". service: " + invoker.getInterface().getName() + ", method: " + invocation.getMethodName()
|
||||||
|
+ ", exception: " + exception.getClass().getName() + ": " + exception.getMessage(), exception);
|
||||||
|
|
||||||
|
// directly throw if exception class and interface class are in the same jar file.
|
||||||
|
String serviceFile = ReflectUtils.getCodeBase(invoker.getInterface());
|
||||||
|
String exceptionFile = ReflectUtils.getCodeBase(exception.getClass());
|
||||||
|
if (serviceFile == null || exceptionFile == null || serviceFile.equals(exceptionFile)) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
// directly throw if it's JDK exception
|
||||||
|
String className = exception.getClass().getName();
|
||||||
|
if (className.startsWith("java.") || className.startsWith("javax.")) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
// directly throw if it's dubbo exception
|
||||||
|
if (exception instanceof RpcException) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// otherwise, wrap with RuntimeException and throw back to the client
|
||||||
|
return new RpcResult(new RuntimeException(StringUtils.toString(exception)));
|
||||||
|
} catch (Throwable e) {
|
||||||
|
logger.warn("Fail to ExceptionFilter when called by " + RpcContext.getContext().getRemoteHost()
|
||||||
|
+ ". service: " + invoker.getInterface().getName() + ", method: " + invocation.getMethodName()
|
||||||
|
+ ", exception: " + e.getClass().getName() + ": " + e.getMessage(), e);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -27,7 +27,7 @@ package cn.iocoder.common.framework.exception;
|
||||||
* 不限制规则。
|
* 不限制规则。
|
||||||
* 一般建议,每个模块自增。
|
* 一般建议,每个模块自增。
|
||||||
*/
|
*/
|
||||||
public class ServiceException extends RuntimeException {
|
public final class ServiceException extends RuntimeException {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 错误码
|
* 错误码
|
||||||
|
@ -43,4 +43,4 @@ public class ServiceException extends RuntimeException {
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
dubboExceptionFilter=cn.iocoder.common.framework.dubbo.DubboExceptionFilter
|
|
@ -1,21 +0,0 @@
|
||||||
package cn.iocoder.mall.order.api.bo;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 商品分组 BO
|
|
||||||
*
|
|
||||||
* 主要目的是,多个商品,
|
|
||||||
*/
|
|
||||||
public class CartItemGroupBO {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* TODO 芋艿,活动
|
|
||||||
*/
|
|
||||||
private Object activity;
|
|
||||||
/**
|
|
||||||
* 商品数组
|
|
||||||
*/
|
|
||||||
private List<CartItemBO> items;
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,26 +0,0 @@
|
||||||
package cn.iocoder.mall.order.api.bo;
|
|
||||||
|
|
||||||
public class FeeMessageBO {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 总价
|
|
||||||
*/
|
|
||||||
private Integer originalTotal;
|
|
||||||
/**
|
|
||||||
* 优惠总价
|
|
||||||
*
|
|
||||||
* 注意,满多少元包邮,不算在优惠中。
|
|
||||||
*/
|
|
||||||
private Integer discountTotal;
|
|
||||||
/**
|
|
||||||
* 邮费
|
|
||||||
*/
|
|
||||||
private Integer postageTotal;
|
|
||||||
/**
|
|
||||||
* 最终价格
|
|
||||||
*
|
|
||||||
* 计算公式 = 总价 - 优惠总价 + 邮费
|
|
||||||
*/
|
|
||||||
private Integer presentTotal;
|
|
||||||
|
|
||||||
}
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
spring:
|
||||||
|
# datasource
|
||||||
|
datasource:
|
||||||
|
url: jdbc:mysql://192.168.88.14:3306/mall_order?useSSL=false&useUnicode=true&characterEncoding=UTF-8
|
||||||
|
driver-class-name: com.mysql.jdbc.Driver
|
||||||
|
username: root
|
||||||
|
password: ${MALL_MYSQL_PASSWORD}
|
|
@ -24,6 +24,7 @@ dubbo:
|
||||||
scan:
|
scan:
|
||||||
base-packages: cn.iocoder.mall.order.biz.service
|
base-packages: cn.iocoder.mall.order.biz.service
|
||||||
provider:
|
provider:
|
||||||
|
filter: -exception
|
||||||
CartService:
|
CartService:
|
||||||
version: 1.0.0
|
version: 1.0.0
|
||||||
consumer:
|
consumer:
|
||||||
|
|
|
@ -1,12 +0,0 @@
|
||||||
# xxl-job
|
|
||||||
xxl:
|
|
||||||
job:
|
|
||||||
admin:
|
|
||||||
addresses: http://127.0.0.1:18079/
|
|
||||||
executor:
|
|
||||||
appname: pay-job-executor
|
|
||||||
ip:
|
|
||||||
port: 0
|
|
||||||
logpath: /Users/yunai/logs/xxl-job/
|
|
||||||
logretentiondays: 1
|
|
||||||
accessToken:
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
spring:
|
||||||
|
# datasource
|
||||||
|
datasource:
|
||||||
|
url: jdbc:mysql://192.168.88.14:3306/mall_apy?useSSL=false&useUnicode=true&characterEncoding=UTF-8
|
||||||
|
driver-class-name: com.mysql.jdbc.Driver
|
||||||
|
username: root
|
||||||
|
password: ${MALL_MYSQL_PASSWORD}
|
||||||
|
|
||||||
|
# xxl-job
|
||||||
|
xxl:
|
||||||
|
job:
|
||||||
|
admin:
|
||||||
|
addresses: http://127.0.0.1:18079/
|
||||||
|
executor:
|
||||||
|
appname: pay-job-executor
|
||||||
|
ip:
|
||||||
|
port: 0
|
||||||
|
logpath: /Users/yunai/logs/xxl-job/
|
||||||
|
logretentiondays: 1
|
||||||
|
accessToken:
|
||||||
|
|
||||||
|
# rocketmq
|
||||||
|
rocketmq:
|
||||||
|
name-server: 192.168.88.14:9876
|
||||||
|
producer:
|
||||||
|
group: pay-producer-group
|
|
@ -24,6 +24,7 @@ dubbo:
|
||||||
scan:
|
scan:
|
||||||
base-packages: cn.iocoder.mall.pay.biz.service
|
base-packages: cn.iocoder.mall.pay.biz.service
|
||||||
provider:
|
provider:
|
||||||
|
filter: -exception
|
||||||
PayTransactionService:
|
PayTransactionService:
|
||||||
version: 1.0.0
|
version: 1.0.0
|
||||||
PayRefundService:
|
PayRefundService:
|
||||||
|
|
|
@ -6,6 +6,8 @@ import lombok.experimental.Accessors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 商品 SPU
|
* 商品 SPU
|
||||||
|
*
|
||||||
|
* TODO 芋艿,后面增加商品普通参数。例如说,正面材料,背面材料,屏幕尺寸。
|
||||||
*/
|
*/
|
||||||
@Data
|
@Data
|
||||||
@Accessors(chain = true)
|
@Accessors(chain = true)
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
spring:
|
||||||
|
# datasource
|
||||||
|
datasource:
|
||||||
|
url: jdbc:mysql://192.168.88.14:3306/mall_product?useSSL=false&useUnicode=true&characterEncoding=UTF-8
|
||||||
|
driver-class-name: com.mysql.jdbc.Driver
|
||||||
|
username: root
|
||||||
|
password: ${MALL_MYSQL_PASSWORD}
|
||||||
|
|
||||||
|
# rocketmq
|
||||||
|
rocketmq:
|
||||||
|
name-server: 192.168.88.14:9876
|
||||||
|
producer:
|
||||||
|
group: product-producer-group
|
|
@ -24,6 +24,7 @@ dubbo:
|
||||||
scan:
|
scan:
|
||||||
base-packages: cn.iocoder.mall.product.service
|
base-packages: cn.iocoder.mall.product.service
|
||||||
provider:
|
provider:
|
||||||
|
filter: -exception
|
||||||
ProductAttrService:
|
ProductAttrService:
|
||||||
version: 1.0.0
|
version: 1.0.0
|
||||||
ProductCategoryService:
|
ProductCategoryService:
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
spring:
|
||||||
|
# datasource
|
||||||
|
datasource:
|
||||||
|
url: jdbc:mysql://192.168.88.14:3306/mall_promotion?useSSL=false&useUnicode=true&characterEncoding=UTF-8
|
||||||
|
driver-class-name: com.mysql.jdbc.Driver
|
||||||
|
username: root
|
||||||
|
password: ${MALL_MYSQL_PASSWORD}
|
|
@ -27,6 +27,7 @@ dubbo:
|
||||||
ProductSpuService:
|
ProductSpuService:
|
||||||
version: 1.0.0
|
version: 1.0.0
|
||||||
provider:
|
provider:
|
||||||
|
filter: -exception
|
||||||
BannerService:
|
BannerService:
|
||||||
version: 1.0.0
|
version: 1.0.0
|
||||||
CouponService:
|
CouponService:
|
||||||
|
|
|
@ -19,6 +19,9 @@ import java.util.Collections;
|
||||||
|
|
||||||
import static cn.iocoder.common.framework.vo.CommonResult.success;
|
import static cn.iocoder.common.framework.vo.CommonResult.success;
|
||||||
|
|
||||||
|
// TODO 芋艿,搜索关键字的配置
|
||||||
|
// TODO 芋艿,搜索日志
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("users/product")
|
@RequestMapping("users/product")
|
||||||
@Api("商品搜索")
|
@Api("商品搜索")
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
# es
|
||||||
|
spring:
|
||||||
|
data:
|
||||||
|
elasticsearch:
|
||||||
|
cluster-name: elasticsearch
|
||||||
|
cluster-nodes: 192.168.88.14:9300
|
||||||
|
repositories:
|
||||||
|
enable: true
|
||||||
|
|
||||||
|
# rocketmq
|
||||||
|
rocketmq:
|
||||||
|
name-server: 192.168.88.14:9876
|
||||||
|
producer:
|
||||||
|
group: search-producer-group
|
|
@ -19,6 +19,7 @@ dubbo:
|
||||||
scan:
|
scan:
|
||||||
base-packages: cn.iocoder.mall.search.biz.service
|
base-packages: cn.iocoder.mall.search.biz.service
|
||||||
provider:
|
provider:
|
||||||
|
filter: -exception
|
||||||
ProductSearchService:
|
ProductSearchService:
|
||||||
version: 1.0.0
|
version: 1.0.0
|
||||||
consumer:
|
consumer:
|
||||||
|
|
|
@ -50,7 +50,6 @@ public class AdminController {
|
||||||
public CommonResult<List<AdminMenuTreeNodeVO>> menuResourceTree() {
|
public CommonResult<List<AdminMenuTreeNodeVO>> menuResourceTree() {
|
||||||
List<ResourceBO> resources = resourceService.getResourcesByTypeAndRoleIds(ResourceConstants.TYPE_MENU, AdminSecurityContextHolder.getContext().getRoleIds());
|
List<ResourceBO> resources = resourceService.getResourcesByTypeAndRoleIds(ResourceConstants.TYPE_MENU, AdminSecurityContextHolder.getContext().getRoleIds());
|
||||||
// 创建 AdminMenuTreeNodeVO Map
|
// 创建 AdminMenuTreeNodeVO Map
|
||||||
// Map<Integer, AdminMenuTreeNodeVO> treeNodeMap = resources.stream().collect(Collectors.toMap(ResourceBO::getId, ResourceConvert.INSTANCE::convert));
|
|
||||||
Map<Integer, AdminMenuTreeNodeVO> treeNodeMap = new LinkedHashMap<>(); // 使用 LinkedHashMap 的原因,是为了排序 。实际也可以用 Stream API ,就是太丑了。
|
Map<Integer, AdminMenuTreeNodeVO> treeNodeMap = new LinkedHashMap<>(); // 使用 LinkedHashMap 的原因,是为了排序 。实际也可以用 Stream API ,就是太丑了。
|
||||||
resources.stream().sorted(Comparator.comparing(ResourceBO::getSort)).forEach(resourceBO -> treeNodeMap.put(resourceBO.getId(), ResourceConvert.INSTANCE.convert(resourceBO)));
|
resources.stream().sorted(Comparator.comparing(ResourceBO::getSort)).forEach(resourceBO -> treeNodeMap.put(resourceBO.getId(), ResourceConvert.INSTANCE.convert(resourceBO)));
|
||||||
// 处理父子关系
|
// 处理父子关系
|
||||||
|
|
|
@ -2,7 +2,7 @@ spring:
|
||||||
boot:
|
boot:
|
||||||
admin:
|
admin:
|
||||||
client:
|
client:
|
||||||
enabled: true
|
enabled: false # 暂时不用了
|
||||||
url: http://127.0.0.1:18097
|
url: http://127.0.0.1:18097
|
||||||
|
|
||||||
|
|
||||||
|
@ -12,4 +12,4 @@ management:
|
||||||
exposure:
|
exposure:
|
||||||
include: "*"
|
include: "*"
|
||||||
server:
|
server:
|
||||||
port: 19083 # 配置独立端口。而该端口,不使用 nginx 对外暴露,从而不配置安全认证。也就是说,内网环境可访问,外网环境不可访问。当然,这么做的前提是,认为内网安全。
|
port: 19083 # 配置独立端口。而该端口,不使用 nginx 对外暴露,从而不配置安全认证。也就是说,内网环境可访问,外网环境不可访问。当然,这么做的前提是,认为内网安全。
|
||||||
|
|
|
@ -7,24 +7,24 @@ package cn.iocoder.mall.admin.sdk.context;
|
||||||
*/
|
*/
|
||||||
public class AdminSecurityContextHolder {
|
public class AdminSecurityContextHolder {
|
||||||
|
|
||||||
private static final ThreadLocal<AdminSecurityContext> securityContext = new ThreadLocal<AdminSecurityContext>();
|
private static final ThreadLocal<AdminSecurityContext> SECURITY_CONTEXT = new ThreadLocal<>();
|
||||||
|
|
||||||
public static void setContext(AdminSecurityContext context) {
|
public static void setContext(AdminSecurityContext context) {
|
||||||
securityContext.set(context);
|
SECURITY_CONTEXT.set(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static AdminSecurityContext getContext() {
|
public static AdminSecurityContext getContext() {
|
||||||
AdminSecurityContext ctx = securityContext.get();
|
AdminSecurityContext ctx = SECURITY_CONTEXT.get();
|
||||||
// 为空时,设置一个空的进去
|
// 为空时,设置一个空的进去
|
||||||
if (ctx == null) {
|
if (ctx == null) {
|
||||||
ctx = new AdminSecurityContext(null, null);
|
ctx = new AdminSecurityContext(null, null);
|
||||||
securityContext.set(ctx);
|
SECURITY_CONTEXT.set(ctx);
|
||||||
}
|
}
|
||||||
return ctx;
|
return ctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void clear() {
|
public static void clear() {
|
||||||
securityContext.remove();
|
SECURITY_CONTEXT.remove();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,4 +34,7 @@ public class AdminDO extends DeletableDO {
|
||||||
*/
|
*/
|
||||||
private Integer status;
|
private Integer status;
|
||||||
|
|
||||||
|
// TODO 芋艿,最后登陆时间、最后登陆 IP
|
||||||
|
// TODO 芋艿,登陆日志
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
spring:
|
||||||
|
# datasource
|
||||||
|
datasource:
|
||||||
|
url: jdbc:mysql://192.168.88.14:3306/mall_admin?useSSL=false&useUnicode=true&characterEncoding=UTF-8
|
||||||
|
driver-class-name: com.mysql.jdbc.Driver
|
||||||
|
username: root
|
||||||
|
password: ${MALL_MYSQL_PASSWORD}
|
|
@ -24,6 +24,7 @@ dubbo:
|
||||||
scan:
|
scan:
|
||||||
base-packages: cn.iocoder.mall.admin.service
|
base-packages: cn.iocoder.mall.admin.service
|
||||||
provider:
|
provider:
|
||||||
|
filter: -exception
|
||||||
AdminAccessLogService:
|
AdminAccessLogService:
|
||||||
version: 1.0.0
|
version: 1.0.0
|
||||||
AdminService:
|
AdminService:
|
||||||
|
|
|
@ -7,24 +7,24 @@ package cn.iocoder.mall.user.sdk.context;
|
||||||
*/
|
*/
|
||||||
public class UserSecurityContextHolder {
|
public class UserSecurityContextHolder {
|
||||||
|
|
||||||
private static final ThreadLocal<UserSecurityContext> securityContext = new ThreadLocal<UserSecurityContext>();
|
private static final ThreadLocal<UserSecurityContext> SECURITY_CONTEXT = new ThreadLocal<UserSecurityContext>();
|
||||||
|
|
||||||
public static void setContext(UserSecurityContext context) {
|
public static void setContext(UserSecurityContext context) {
|
||||||
securityContext.set(context);
|
SECURITY_CONTEXT.set(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static UserSecurityContext getContext() {
|
public static UserSecurityContext getContext() {
|
||||||
UserSecurityContext ctx = securityContext.get();
|
UserSecurityContext ctx = SECURITY_CONTEXT.get();
|
||||||
// 为空时,设置一个空的进去
|
// 为空时,设置一个空的进去
|
||||||
if (ctx == null) {
|
if (ctx == null) {
|
||||||
ctx = new UserSecurityContext(null);
|
ctx = new UserSecurityContext(null);
|
||||||
securityContext.set(ctx);
|
SECURITY_CONTEXT.set(ctx);
|
||||||
}
|
}
|
||||||
return ctx;
|
return ctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void clear() {
|
public static void clear() {
|
||||||
securityContext.remove();
|
SECURITY_CONTEXT.remove();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
spring:
|
||||||
|
# datasource
|
||||||
|
datasource:
|
||||||
|
url: jdbc:mysql://192.168.88.14:3306/mall_user?useSSL=false&useUnicode=true&characterEncoding=UTF-8
|
||||||
|
driver-class-name: com.mysql.jdbc.Driver
|
||||||
|
username: root
|
||||||
|
password: ${MALL_MYSQL_PASSWORD}
|
|
@ -24,6 +24,7 @@ dubbo:
|
||||||
scan:
|
scan:
|
||||||
base-packages: cn.iocoder.mall.user.biz.service
|
base-packages: cn.iocoder.mall.user.biz.service
|
||||||
provider:
|
provider:
|
||||||
|
filter: -exception
|
||||||
MobileCodeService:
|
MobileCodeService:
|
||||||
version: 1.0.0
|
version: 1.0.0
|
||||||
OAuth2Service:
|
OAuth2Service:
|
||||||
|
|
Loading…
Reference in New Issue