提交 58525e09 authored 作者: YunaiV's avatar YunaiV

- 后端:修改配置文件,指向服务器

- 增加 .gitattributes ,解决 github 识别项目错误问题
上级 21dbd7b8
*.css linguist-language=java
*.less linguist-language=java
*.js linguist-language=java
*.html linguist-language=java
......@@ -33,9 +33,35 @@ TODO 暂时不提供管理后台的账号密码,等后面提供。
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
# 技术
......
# 前端 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());
}
// TODO 芋艿,应该还有其它的异常,需要进行翻译
}
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;
}
}
\ No newline at end of file
}
dubboExceptionFilter=cn.iocoder.common.framework.dubbo.DubboExceptionFilter
package cn.iocoder.mall.order.api.bo;
import java.util.List;
/**
* 商品分组 BO
*
* 主要目的是,多个商品,
*/
public class CartItemGroupBO {
/**
* TODO 芋艿,活动
*/
private Object activity;
/**
* 商品数组
*/
private List<CartItemBO> items;
}
package cn.iocoder.mall.order.api.bo;
public class FeeMessageBO {
/**
* 总价
*/
private Integer originalTotal;
/**
* 优惠总价
*
* 注意,满多少元包邮,不算在优惠中。
*/
private Integer discountTotal;
/**
* 邮费
*/
private Integer postageTotal;
/**
* 最终价格
*
* 计算公式 = 总价 - 优惠总价 + 邮费
*/
private Integer presentTotal;
}
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:
base-packages: cn.iocoder.mall.order.biz.service
provider:
filter: -exception
CartService:
version: 1.0.0
consumer:
......
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:
......@@ -10,3 +18,9 @@ xxl:
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:
base-packages: cn.iocoder.mall.pay.biz.service
provider:
filter: -exception
PayTransactionService:
version: 1.0.0
PayRefundService:
......
......@@ -6,6 +6,8 @@ import lombok.experimental.Accessors;
/**
* 商品 SPU
*
* TODO 芋艿,后面增加商品普通参数。例如说,正面材料,背面材料,屏幕尺寸。
*/
@Data
@Accessors(chain = true)
......
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:
base-packages: cn.iocoder.mall.product.service
provider:
filter: -exception
ProductAttrService:
version: 1.0.0
ProductCategoryService:
......
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:
version: 1.0.0
provider:
filter: -exception
BannerService:
version: 1.0.0
CouponService:
......
......@@ -19,6 +19,9 @@ import java.util.Collections;
import static cn.iocoder.common.framework.vo.CommonResult.success;
// TODO 芋艿,搜索关键字的配置
// TODO 芋艿,搜索日志
@RestController
@RequestMapping("users/product")
@Api("商品搜索")
......
# 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:
base-packages: cn.iocoder.mall.search.biz.service
provider:
filter: -exception
ProductSearchService:
version: 1.0.0
consumer:
......
......@@ -50,7 +50,6 @@ public class AdminController {
public CommonResult<List<AdminMenuTreeNodeVO>> menuResourceTree() {
List<ResourceBO> resources = resourceService.getResourcesByTypeAndRoleIds(ResourceConstants.TYPE_MENU, AdminSecurityContextHolder.getContext().getRoleIds());
// 创建 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 ,就是太丑了。
resources.stream().sorted(Comparator.comparing(ResourceBO::getSort)).forEach(resourceBO -> treeNodeMap.put(resourceBO.getId(), ResourceConvert.INSTANCE.convert(resourceBO)));
// 处理父子关系
......
......@@ -2,7 +2,7 @@ spring:
boot:
admin:
client:
enabled: true
enabled: false # 暂时不用了
url: http://127.0.0.1:18097
......@@ -12,4 +12,4 @@ management:
exposure:
include: "*"
server:
port: 19083 # 配置独立端口。而该端口,不使用 nginx 对外暴露,从而不配置安全认证。也就是说,内网环境可访问,外网环境不可访问。当然,这么做的前提是,认为内网安全。
\ No newline at end of file
port: 19083 # 配置独立端口。而该端口,不使用 nginx 对外暴露,从而不配置安全认证。也就是说,内网环境可访问,外网环境不可访问。当然,这么做的前提是,认为内网安全。
......@@ -7,24 +7,24 @@ package cn.iocoder.mall.admin.sdk.context;
*/
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) {
securityContext.set(context);
SECURITY_CONTEXT.set(context);
}
public static AdminSecurityContext getContext() {
AdminSecurityContext ctx = securityContext.get();
AdminSecurityContext ctx = SECURITY_CONTEXT.get();
// 为空时,设置一个空的进去
if (ctx == null) {
ctx = new AdminSecurityContext(null, null);
securityContext.set(ctx);
SECURITY_CONTEXT.set(ctx);
}
return ctx;
}
public static void clear() {
securityContext.remove();
SECURITY_CONTEXT.remove();
}
}
\ No newline at end of file
}
......@@ -34,4 +34,7 @@ public class AdminDO extends DeletableDO {
*/
private Integer status;
// TODO 芋艿,最后登陆时间、最后登陆 IP
// TODO 芋艿,登陆日志
}
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:
base-packages: cn.iocoder.mall.admin.service
provider:
filter: -exception
AdminAccessLogService:
version: 1.0.0
AdminService:
......
......@@ -7,24 +7,24 @@ package cn.iocoder.mall.user.sdk.context;
*/
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) {
securityContext.set(context);
SECURITY_CONTEXT.set(context);
}
public static UserSecurityContext getContext() {
UserSecurityContext ctx = securityContext.get();
UserSecurityContext ctx = SECURITY_CONTEXT.get();
// 为空时,设置一个空的进去
if (ctx == null) {
ctx = new UserSecurityContext(null);
securityContext.set(ctx);
SECURITY_CONTEXT.set(ctx);
}
return ctx;
}
public static void clear() {
securityContext.remove();
SECURITY_CONTEXT.remove();
}
}
\ No newline at end of file
}
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:
base-packages: cn.iocoder.mall.user.biz.service
provider:
filter: -exception
MobileCodeService:
version: 1.0.0
OAuth2Service:
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论