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

- 增加 .gitattributes ,解决 github 识别项目错误问题
This commit is contained in:
YunaiV 2019-05-09 19:34:31 +08:00
parent 21dbd7b8cb
commit 58525e0940
31 changed files with 252 additions and 96 deletions

4
.gitattributes vendored Normal file
View File

@ -0,0 +1,4 @@
*.css linguist-language=java
*.less linguist-language=java
*.js linguist-language=java
*.html linguist-language=java

View File

@ -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
# 技术 # 技术

View File

@ -1,18 +0,0 @@
# 前端 Server
* admin 18083
*
# 后端 Server
# 基础服务
## MySQL
## Zookeeper
# 运维
* ssh 端口
* 工作目录 /work2/

View File

@ -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 芋艿应该还有其它的异常需要进行翻译
} }

View File

@ -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;
}
}

View File

@ -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;
} }
} }

View File

@ -0,0 +1 @@
dubboExceptionFilter=cn.iocoder.common.framework.dubbo.DubboExceptionFilter

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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}

View File

@ -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:

View File

@ -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:

View File

@ -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

View File

@ -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:

View File

@ -6,6 +6,8 @@ import lombok.experimental.Accessors;
/** /**
* 商品 SPU * 商品 SPU
*
* TODO 芋艿后面增加商品普通参数例如说正面材料背面材料屏幕尺寸
*/ */
@Data @Data
@Accessors(chain = true) @Accessors(chain = true)

View File

@ -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

View File

@ -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:

View File

@ -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}

View File

@ -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:

View File

@ -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("商品搜索")

View File

@ -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

View File

@ -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:

View File

@ -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)));
// 处理父子关系 // 处理父子关系

View File

@ -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 对外暴露,从而不配置安全认证。也就是说,内网环境可访问,外网环境不可访问。当然,这么做的前提是,认为内网安全。

View File

@ -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();
} }
} }

View File

@ -34,4 +34,7 @@ public class AdminDO extends DeletableDO {
*/ */
private Integer status; private Integer status;
// TODO 芋艿最后登陆时间最后登陆 IP
// TODO 芋艿登陆日志
} }

View File

@ -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}

View File

@ -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:

View File

@ -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();
} }
} }

View File

@ -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}

View File

@ -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: