list, ConsumeConcurrentlyContext consumeConcurrentlyContext) {
+ for(MessageExt mes:list){
+ String topic= mes.getTopic();
+ try {
+ String msgbody=new String(mes.getBody(),"UTF-8");
+ String tags=mes.getTags();
+ System.out.println("========》topic" + topic+"===>msgbody:"+msgbody+"===>tags:"+tags+"延时:"+(mes.getStoreTimestamp()-mes.getBornTimestamp()));
+ } catch (UnsupportedEncodingException e) {
+ e.printStackTrace();
+ }
+ }
+ return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
+ }
+ });
+ consumer.start();
+ }
+}
diff --git a/msb-mall/mall-commons/pom.xml b/msb-mall/mall-commons/pom.xml
new file mode 100644
index 000000000..a8d806e03
--- /dev/null
+++ b/msb-mall/mall-commons/pom.xml
@@ -0,0 +1,71 @@
+
+
+
+ msb-mall
+ com.msb.mall
+ 1.0-SNAPSHOT
+
+ 4.0.0
+
+ mall-commons
+
+
+ 8
+ 8
+
+
+
+
+ org.projectlombok
+ lombok
+ 1.18.24
+
+
+ com.baomidou
+ mybatis-plus
+ 3.4.3.4
+
+
+ org.apache.httpcomponents
+ httpcore
+ 4.4.14
+
+
+ javax.validation
+ validation-api
+ 1.1.0.Final
+
+
+ commons-lang
+ commons-lang
+ 2.6
+
+
+ com.baomidou
+ mybatis-plus-boot-starter
+ 3.3.1
+
+
+ mysql
+ mysql-connector-java
+ 8.0.28
+
+
+ com.alibaba.cloud
+ spring-cloud-starter-alibaba-seata
+
+
+
+
+
+ com.alibaba.cloud
+ spring-cloud-alibaba-dependencies
+ 2.2.8.RELEASE
+ pom
+ import
+
+
+
+
\ No newline at end of file
diff --git a/msb-mall/mall-commons/src/main/java/com/msb/mall/commons/exception/RRException.java b/msb-mall/mall-commons/src/main/java/com/msb/mall/commons/exception/RRException.java
new file mode 100644
index 000000000..275c6dde3
--- /dev/null
+++ b/msb-mall/mall-commons/src/main/java/com/msb/mall/commons/exception/RRException.java
@@ -0,0 +1,61 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package com.msb.mall.commons.exception;
+
+/**
+ * 自定义异常
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+public class RRException extends RuntimeException {
+ private static final long serialVersionUID = 1L;
+
+ private String msg;
+ private int code = 500;
+
+ public RRException(String msg) {
+ super(msg);
+ this.msg = msg;
+ }
+
+ public RRException(String msg, Throwable e) {
+ super(msg, e);
+ this.msg = msg;
+ }
+
+ public RRException(String msg, int code) {
+ super(msg);
+ this.msg = msg;
+ this.code = code;
+ }
+
+ public RRException(String msg, int code, Throwable e) {
+ super(msg, e);
+ this.msg = msg;
+ this.code = code;
+ }
+
+ public String getMsg() {
+ return msg;
+ }
+
+ public void setMsg(String msg) {
+ this.msg = msg;
+ }
+
+ public int getCode() {
+ return code;
+ }
+
+ public void setCode(int code) {
+ this.code = code;
+ }
+
+
+}
diff --git a/msb-mall/mall-commons/src/main/java/com/msb/mall/commons/exception/RRExceptionHandler.java b/msb-mall/mall-commons/src/main/java/com/msb/mall/commons/exception/RRExceptionHandler.java
new file mode 100644
index 000000000..7472c1d86
--- /dev/null
+++ b/msb-mall/mall-commons/src/main/java/com/msb/mall/commons/exception/RRExceptionHandler.java
@@ -0,0 +1,64 @@
+///**
+// * Copyright (c) 2016-2019 人人开源 All rights reserved.
+// *
+// * https://www.renren.io
+// *
+// * 版权所有,侵权必究!
+// */
+//
+//package com.msb.mall.commons.exception;
+//
+//import io.renren.common.utils.R;
+//import org.apache.shiro.authz.AuthorizationException;
+//import org.slf4j.Logger;
+//import org.slf4j.LoggerFactory;
+//import org.springframework.dao.DuplicateKeyException;
+//import org.springframework.web.bind.annotation.ExceptionHandler;
+//import org.springframework.web.bind.annotation.RestControllerAdvice;
+//import org.springframework.web.servlet.NoHandlerFoundException;
+//
+///**
+// * 异常处理器
+// *
+// * @author Mark sunlightcs@gmail.com
+// */
+//@RestControllerAdvice
+//public class RRExceptionHandler {
+// private Logger logger = LoggerFactory.getLogger(getClass());
+//
+// /**
+// * 处理自定义异常
+// */
+// @ExceptionHandler(RRException.class)
+// public R handleRRException(RRException e){
+// R r = new R();
+// r.put("code", e.getCode());
+// r.put("msg", e.getMessage());
+//
+// return r;
+// }
+//
+// @ExceptionHandler(NoHandlerFoundException.class)
+// public R handlerNoFoundException(Exception e) {
+// logger.error(e.getMessage(), e);
+// return R.error(404, "路径不存在,请检查路径是否正确");
+// }
+//
+// @ExceptionHandler(DuplicateKeyException.class)
+// public R handleDuplicateKeyException(DuplicateKeyException e){
+// logger.error(e.getMessage(), e);
+// return R.error("数据库中已存在该记录");
+// }
+//
+// @ExceptionHandler(AuthorizationException.class)
+// public R handleAuthorizationException(AuthorizationException e){
+// logger.error(e.getMessage(), e);
+// return R.error("没有权限,请联系管理员授权");
+// }
+//
+// @ExceptionHandler(Exception.class)
+// public R handleException(Exception e){
+// logger.error(e.getMessage(), e);
+// return R.error();
+// }
+//}
diff --git a/msb-mall/mall-commons/src/main/java/com/msb/mall/commons/util/Constant.java b/msb-mall/mall-commons/src/main/java/com/msb/mall/commons/util/Constant.java
new file mode 100644
index 000000000..64cc7f96e
--- /dev/null
+++ b/msb-mall/mall-commons/src/main/java/com/msb/mall/commons/util/Constant.java
@@ -0,0 +1,153 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package com.msb.mall.commons.util;
+
+
+import com.msb.mall.commons.validator.group.AliyunGroup;
+import com.msb.mall.commons.validator.group.QcloudGroup;
+import com.msb.mall.commons.validator.group.QiniuGroup;
+
+import java.util.Optional;
+import java.util.stream.Stream;
+
+/**
+ * 常量
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+public class Constant {
+ /**
+ * 超级管理员ID
+ */
+ public static final int SUPER_ADMIN = 1;
+ /**
+ * 当前页码
+ */
+ public static final String PAGE = "page";
+ /**
+ * 每页显示记录数
+ */
+ public static final String LIMIT = "limit";
+ /**
+ * 排序字段
+ */
+ public static final String ORDER_FIELD = "sidx";
+ /**
+ * 排序方式
+ */
+ public static final String ORDER = "order";
+ /**
+ * 升序
+ */
+ public static final String ASC = "asc";
+
+ /**
+ * 菜单类型
+ *
+ * @author chenshun
+ * @email sunlightcs@gmail.com
+ * @date 2016年11月15日 下午1:24:29
+ */
+ public enum MenuType {
+ /**
+ * 目录
+ */
+ CATALOG(0),
+ /**
+ * 菜单
+ */
+ MENU(1),
+ /**
+ * 按钮
+ */
+ BUTTON(2);
+
+ private int value;
+
+ MenuType(int value) {
+ this.value = value;
+ }
+
+ public int getValue() {
+ return value;
+ }
+ }
+
+ /**
+ * 定时任务状态
+ *
+ * @author chenshun
+ * @email sunlightcs@gmail.com
+ * @date 2016年12月3日 上午12:07:22
+ */
+ public enum ScheduleStatus {
+ /**
+ * 正常
+ */
+ NORMAL(0),
+ /**
+ * 暂停
+ */
+ PAUSE(1);
+
+ private int value;
+
+ ScheduleStatus(int value) {
+ this.value = value;
+ }
+
+ public int getValue() {
+ return value;
+ }
+ }
+
+ /**
+ * 云服务商
+ */
+ public enum CloudService {
+ /**
+ * 七牛云
+ */
+ QINIU(1, QiniuGroup.class),
+ /**
+ * 阿里云
+ */
+ ALIYUN(2, AliyunGroup.class),
+ /**
+ * 腾讯云
+ */
+ QCLOUD(3, QcloudGroup.class);
+
+ private int value;
+
+ private Class> validatorGroupClass;
+
+ CloudService(int value, Class> validatorGroupClass) {
+ this.value = value;
+ this.validatorGroupClass = validatorGroupClass;
+ }
+
+ public int getValue() {
+ return value;
+ }
+
+ public Class> getValidatorGroupClass() {
+ return this.validatorGroupClass;
+ }
+
+ public static CloudService getByValue(Integer value) {
+ Optional first = Stream.of(CloudService.values()).filter(cs -> value.equals(cs.value)).findFirst();
+ if (!first.isPresent()) {
+ throw new IllegalArgumentException("非法的枚举值:" + value);
+ }
+ return first.get();
+ }
+ }
+
+}
diff --git a/msb-mall/mall-commons/src/main/java/com/msb/mall/commons/util/PageUtils.java b/msb-mall/mall-commons/src/main/java/com/msb/mall/commons/util/PageUtils.java
new file mode 100644
index 000000000..bdb14b2a1
--- /dev/null
+++ b/msb-mall/mall-commons/src/main/java/com/msb/mall/commons/util/PageUtils.java
@@ -0,0 +1,110 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package com.msb.mall.commons.util;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * 分页工具类
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+public class PageUtils implements Serializable {
+ private static final long serialVersionUID = 1L;
+ /**
+ * 总记录数
+ */
+ private int totalCount;
+ /**
+ * 每页记录数
+ */
+ private int pageSize;
+ /**
+ * 总页数
+ */
+ private int totalPage;
+ /**
+ * 当前页数
+ */
+ private int currPage;
+ /**
+ * 列表数据
+ */
+ private List> list;
+
+ /**
+ * 分页
+ * @param list 列表数据
+ * @param totalCount 总记录数
+ * @param pageSize 每页记录数
+ * @param currPage 当前页数
+ */
+ public PageUtils(List> list, int totalCount, int pageSize, int currPage) {
+ this.list = list;
+ this.totalCount = totalCount;
+ this.pageSize = pageSize;
+ this.currPage = currPage;
+ this.totalPage = (int)Math.ceil((double)totalCount/pageSize);
+ }
+
+ /**
+ * 分页
+ */
+ public PageUtils(IPage> page) {
+ this.list = page.getRecords();
+ this.totalCount = (int)page.getTotal();
+ this.pageSize = (int)page.getSize();
+ this.currPage = (int)page.getCurrent();
+ this.totalPage = (int)page.getPages();
+ }
+
+ public int getTotalCount() {
+ return totalCount;
+ }
+
+ public void setTotalCount(int totalCount) {
+ this.totalCount = totalCount;
+ }
+
+ public int getPageSize() {
+ return pageSize;
+ }
+
+ public void setPageSize(int pageSize) {
+ this.pageSize = pageSize;
+ }
+
+ public int getTotalPage() {
+ return totalPage;
+ }
+
+ public void setTotalPage(int totalPage) {
+ this.totalPage = totalPage;
+ }
+
+ public int getCurrPage() {
+ return currPage;
+ }
+
+ public void setCurrPage(int currPage) {
+ this.currPage = currPage;
+ }
+
+ public List> getList() {
+ return list;
+ }
+
+ public void setList(List> list) {
+ this.list = list;
+ }
+
+}
diff --git a/msb-mall/mall-commons/src/main/java/com/msb/mall/commons/util/Query.java b/msb-mall/mall-commons/src/main/java/com/msb/mall/commons/util/Query.java
new file mode 100644
index 000000000..ab16b7c9f
--- /dev/null
+++ b/msb-mall/mall-commons/src/main/java/com/msb/mall/commons/util/Query.java
@@ -0,0 +1,77 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package com.msb.mall.commons.util;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.core.metadata.OrderItem;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.msb.mall.commons.xss.SQLFilter;
+import org.apache.commons.lang.StringUtils;
+
+import java.util.Map;
+
+/**
+ * 查询参数
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+public class Query {
+
+ public IPage getPage(Map params) {
+ return this.getPage(params, null, false);
+ }
+
+ public IPage getPage(Map params, String defaultOrderField, boolean isAsc) {
+ //分页参数
+ long curPage = 1;
+ long limit = 10;
+
+ if(params.get(Constant.PAGE) != null){
+ curPage = Long.parseLong((String)params.get(Constant.PAGE));
+ }
+ if(params.get(Constant.LIMIT) != null){
+ limit = Long.parseLong((String)params.get(Constant.LIMIT));
+ }
+
+ //分页对象
+ Page page = new Page<>(curPage, limit);
+
+ //分页参数
+ params.put(Constant.PAGE, page);
+
+ //排序字段
+ //防止SQL注入(因为sidx、order是通过拼接SQL实现排序的,会有SQL注入风险)
+ String orderField = SQLFilter.sqlInject((String)params.get(Constant.ORDER_FIELD));
+ String order = (String)params.get(Constant.ORDER);
+
+
+ //前端字段排序
+ if(StringUtils.isNotEmpty(orderField) && StringUtils.isNotEmpty(order)){
+ if(Constant.ASC.equalsIgnoreCase(order)) {
+ return page.addOrder(OrderItem.asc(orderField));
+ }else {
+ return page.addOrder(OrderItem.desc(orderField));
+ }
+ }
+
+ //没有排序字段,则不排序
+ if(StringUtils.isBlank(defaultOrderField)){
+ return page;
+ }
+
+ //默认排序
+ if(isAsc) {
+ page.addOrder(OrderItem.asc(defaultOrderField));
+ }else {
+ page.addOrder(OrderItem.desc(defaultOrderField));
+ }
+
+ return page;
+ }
+}
diff --git a/msb-mall/mall-commons/src/main/java/com/msb/mall/commons/util/R.java b/msb-mall/mall-commons/src/main/java/com/msb/mall/commons/util/R.java
new file mode 100644
index 000000000..186f52f59
--- /dev/null
+++ b/msb-mall/mall-commons/src/main/java/com/msb/mall/commons/util/R.java
@@ -0,0 +1,64 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package com.msb.mall.commons.util;
+
+import org.apache.http.HttpStatus;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * 返回数据
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+public class R extends HashMap {
+ private static final long serialVersionUID = 1L;
+
+ public R() {
+ put("code", 0);
+ put("msg", "success");
+ }
+
+ public static R error() {
+ return error(HttpStatus.SC_INTERNAL_SERVER_ERROR, "未知异常,请联系管理员");
+ }
+
+ public static R error(String msg) {
+ return error(HttpStatus.SC_INTERNAL_SERVER_ERROR, msg);
+ }
+
+ public static R error(int code, String msg) {
+ R r = new R();
+ r.put("code", code);
+ r.put("msg", msg);
+ return r;
+ }
+
+ public static R ok(String msg) {
+ R r = new R();
+ r.put("msg", msg);
+ return r;
+ }
+
+ public static R ok(Map map) {
+ R r = new R();
+ r.putAll(map);
+ return r;
+ }
+
+ public static R ok() {
+ return new R();
+ }
+
+ public R put(String key, Object value) {
+ super.put(key, value);
+ return this;
+ }
+}
diff --git a/msb-mall/mall-commons/src/main/java/com/msb/mall/commons/validator/Assert.java b/msb-mall/mall-commons/src/main/java/com/msb/mall/commons/validator/Assert.java
new file mode 100644
index 000000000..dbfad0c6f
--- /dev/null
+++ b/msb-mall/mall-commons/src/main/java/com/msb/mall/commons/validator/Assert.java
@@ -0,0 +1,32 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package com.msb.mall.commons.validator;
+
+import com.msb.mall.commons.exception.RRException;
+import org.apache.commons.lang.StringUtils;
+
+/**
+ * 数据校验
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+public abstract class Assert {
+
+ public static void isBlank(String str, String message) {
+ if (StringUtils.isBlank(str)) {
+ throw new RRException(message);
+ }
+ }
+
+ public static void isNull(Object object, String message) {
+ if (object == null) {
+ throw new RRException(message);
+ }
+ }
+}
diff --git a/msb-mall/mall-commons/src/main/java/com/msb/mall/commons/validator/ValidatorUtils.java b/msb-mall/mall-commons/src/main/java/com/msb/mall/commons/validator/ValidatorUtils.java
new file mode 100644
index 000000000..27bbe05e1
--- /dev/null
+++ b/msb-mall/mall-commons/src/main/java/com/msb/mall/commons/validator/ValidatorUtils.java
@@ -0,0 +1,56 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package com.msb.mall.commons.validator;
+
+
+
+import com.msb.mall.commons.exception.RRException;
+import com.msb.mall.commons.util.Constant;
+
+import javax.validation.ConstraintViolation;
+import javax.validation.Validation;
+import javax.validation.Validator;
+import java.util.Set;
+
+/**
+ * hibernate-validator校验工具类
+ *
+ * 参考文档:http://docs.jboss.org/hibernate/validator/5.4/reference/en-US/html_single/
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+public class ValidatorUtils {
+ private static Validator validator;
+
+ static {
+ validator = Validation.buildDefaultValidatorFactory().getValidator();
+ }
+
+ /**
+ * 校验对象
+ * @param object 待校验对象
+ * @param groups 待校验的组
+ * @throws RRException 校验不通过,则报RRException异常
+ */
+ public static void validateEntity(Object object, Class>... groups)
+ throws RRException {
+ Set> constraintViolations = validator.validate(object, groups);
+ if (!constraintViolations.isEmpty()) {
+ StringBuilder msg = new StringBuilder();
+ for (ConstraintViolation