我们发布啦

This commit is contained in:
张乐
2020-08-13 16:12:57 +08:00
parent a3e1c38d27
commit c0cec49f41
1885 changed files with 376936 additions and 2 deletions

View File

@@ -0,0 +1,48 @@
package com.aop;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import java.util.Arrays;
/**
* 所有的前端controller层的拦截业务方法的执行时间长度
*/
@Aspect
@Component
public class ControllerAspect {
Logger logger = LoggerFactory.getLogger(ControllerAspect.class);
@Pointcut("execution(* com.zbkj.crmeb.system.controller.*.*(..))")
private void pointCutMethodController() {
}
@Around("pointCutMethodController()")
public Object doAroundService(ProceedingJoinPoint pjp) throws Throwable {
long begin = System.nanoTime();
Object obj = pjp.proceed();
long end = System.nanoTime();
logger.info("Controller method{}prams{}cost time{} nscost{} ms",
pjp.getSignature().toString(), Arrays.toString(pjp.getArgs()), (end - begin), (end - begin) / 1000000);
return obj;
}
}

View File

@@ -0,0 +1,53 @@
package com.common;
import com.constants.Constants;
import com.utils.RedisUtil;
import com.utils.ThreadLocalUtil;
import com.zbkj.crmeb.authorization.model.TokenModel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
/**
* 检测token是否过期
* Created on 2019/11/23
* @author zhangle
*/
@Component
public class CheckAdminToken {
@Autowired
protected RedisUtil redisUtil;
public Boolean check(String token){
try {
boolean exists = redisUtil.exists(TokenModel.TOKEN_REDIS + token);
if(exists){
Object value = redisUtil.get(TokenModel.TOKEN_REDIS + token);
Map<String, Object> hashedMap = new HashMap<>();
hashedMap.put("id", value);
ThreadLocalUtil.set(hashedMap);
redisUtil.set(TokenModel.TOKEN_REDIS +token, value, Constants.TOKEN_EXPRESS_MINUTES, TimeUnit.MINUTES);
}
return exists;
}catch (Exception e){
return false;
}
}
public String getTokenFormRequest(HttpServletRequest request){
String pathToken =request.getParameter(Constants.HEADER_AUTHORIZATION_KEY);
if(null != pathToken){
return pathToken;
}
return request.getHeader(Constants.HEADER_AUTHORIZATION_KEY);
}
}

View File

@@ -0,0 +1,48 @@
package com.common;
import com.constants.Constants;
import com.utils.RedisUtil;
import com.utils.ThreadLocalUtil;
import com.zbkj.crmeb.authorization.model.TokenModel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
/**
* 检测token是否过期
* Created on 2019/11/23
* @author zhangle
*/
@Component
public class CheckFrontToken {
@Autowired
protected RedisUtil redisUtil;
public Boolean check(String token){
try {
boolean exists = redisUtil.exists(Constants.USER_TOKEN_REDIS_KEY_PREFIX + token);
if(exists){
Object value = redisUtil.get(Constants.USER_TOKEN_REDIS_KEY_PREFIX + token);
Map<String, Object> hashedMap = new HashMap<>();
hashedMap.put("id", value);
ThreadLocalUtil.set(hashedMap);
redisUtil.set(Constants.USER_TOKEN_REDIS_KEY_PREFIX +token, value, Constants.TOKEN_EXPRESS_MINUTES, TimeUnit.MINUTES);
}
return exists;
}catch (Exception e){
return false;
}
}
public String getTokenFormRequest(HttpServletRequest request){
return request.getHeader(Constants.HEADER_AUTHORIZATION_KEY);
}
}

View File

@@ -0,0 +1,69 @@
package com.common;
import com.constants.Constants;
import lombok.Data;
import org.springframework.beans.BeanUtils;
import org.springframework.data.domain.Page;
import com.github.pagehelper.PageInfo;
import java.util.ArrayList;
import java.util.List;
@Data
public class CommonPage<T> {
private Integer page = Constants.DEFAULT_PAGE;
private Integer limit = Constants.DEFAULT_LIMIT;
private Integer totalPage = 0;
private Long total = 0L ;
private List<T> list = new ArrayList<>();
/**
* 将PageHelper分页后的list转为分页信息
*/
public static <T> CommonPage<T> restPage(List<T> list) {
CommonPage<T> result = new CommonPage<T>();
PageInfo<T> pageInfo = new PageInfo<T>(list);
result.setTotalPage(pageInfo.getPages());
result.setPage(pageInfo.getPageNum());
result.setLimit(pageInfo.getPageSize());
result.setTotal(pageInfo.getTotal());
result.setList(pageInfo.getList());
return result;
}
/**
* 将SpringData分页后的list转为分页信息
*/
public static <T> CommonPage<T> restPage(Page<T> pageInfo) {
CommonPage<T> result = new CommonPage<T>();
result.setTotalPage(pageInfo.getTotalPages());
result.setPage(pageInfo.getNumber());
result.setLimit(pageInfo.getSize());
result.setTotal(pageInfo.getTotalElements());
result.setList(pageInfo.getContent());
return result;
}
/**
* 将PageHelper分页后的 PageInfo 转为分页信息
*/
public static <T> CommonPage<T> restPage(PageInfo<T> pageInfo) {
CommonPage<T> result = new CommonPage<T>();
result.setTotalPage(pageInfo.getPages());
result.setPage(pageInfo.getPageNum());
result.setLimit(pageInfo.getPageSize());
result.setTotal(pageInfo.getTotal());
result.setList(pageInfo.getList());
return result;
}
/**
* 对象A复制对象B的分页信息 //TODO 多次数据查询导致分页数据异常解决办法
*/
public static <T> PageInfo<T> copyPageInfo(com.github.pagehelper.Page originPageInfo, List<T> list) {
PageInfo<T> pageInfo = new PageInfo<>(list);
BeanUtils.copyProperties(originPageInfo, pageInfo, "list");
return pageInfo;
}
}

View File

@@ -0,0 +1,153 @@
package com.common;
import com.exception.ExceptionCodeEnum;
import com.exception.ExceptionHandler;
public class CommonResult<T> {
private long code;
private String message;
private T data;
protected CommonResult() {
}
protected CommonResult(long code, String message, T data) {
this.code = code;
this.message = message;
this.data = data;
}
/**
* 成功返回结果
*/
public static <T> CommonResult<T> success() {
return new CommonResult<T>(ExceptionCodeEnum.SUCCESS.getCode(), ExceptionCodeEnum.SUCCESS.getMessage(), null);
}
/**
* 成功返回结果
*/
public static <T> CommonResult<T> success(String message) {
return new CommonResult<T>(ExceptionCodeEnum.SUCCESS.getCode(), message, null);
}
/**
* 成功返回结果
*
* @param data 获取的数据
*/
public static <T> CommonResult<T> success(T data) {
return new CommonResult<T>(ExceptionCodeEnum.SUCCESS.getCode(), ExceptionCodeEnum.SUCCESS.getMessage(), data);
}
/**
* 成功返回结果
*
* @param data 获取的数据
* @param message 提示信息
*/
public static <T> CommonResult<T> success(T data, String message) {
return new CommonResult<T>(ExceptionCodeEnum.SUCCESS.getCode(), message, data);
}
/**
* 失败返回结果
* @param errorCode 错误码
*/
public static <T> CommonResult<T> failed(ExceptionHandler errorCode) {
System.out.println("errorCode1:" + errorCode);
return new CommonResult<T>(errorCode.getCode(), errorCode.getMessage(), null);
}
/**
* 失败返回结果
* @param errorCode 错误码
* @param message 错误信息
*/
public static <T> CommonResult<T> failed(ExceptionHandler errorCode,String message) {
System.out.println("errorCode2:" + errorCode);
return new CommonResult<T>(errorCode.getCode(), message, null);
}
/**
* 失败返回结果
* @param message 提示信息
*/
public static <T> CommonResult<T> failed(String message) {
return new CommonResult<T>(ExceptionCodeEnum.FAILED.getCode(), message, null);
}
/**
* 失败返回结果
*/
public static <T> CommonResult<T> failed() {
return failed(ExceptionCodeEnum.FAILED);
}
/**
* 参数验证失败返回结果
*/
public static <T> CommonResult<T> validateFailed() {
return failed(ExceptionCodeEnum.VALIDATE_FAILED);
}
/**
* 参数验证失败返回结果
* @param message 提示信息
*/
public static <T> CommonResult<T> validateFailed(String message) {
return new CommonResult<T>(ExceptionCodeEnum.VALIDATE_FAILED.getCode(), message, null);
}
/**
* 未登录返回结果
*/
public static <T> CommonResult<T> unauthorized(T data) {
return new CommonResult<T>(ExceptionCodeEnum.UNAUTHORIZED.getCode(), ExceptionCodeEnum.UNAUTHORIZED.getMessage(), data);
}
/**
* 未登录返回结果
*/
public static <T> CommonResult<T> unauthorized() {
return new CommonResult<T>(ExceptionCodeEnum.UNAUTHORIZED.getCode(), ExceptionCodeEnum.UNAUTHORIZED.getMessage(), null);
}
/**
* 没有权限查看
*/
public static <T> CommonResult<T> forbidden() {
return new CommonResult<T>(ExceptionCodeEnum.FORBIDDEN.getCode(), ExceptionCodeEnum.FORBIDDEN.getMessage(), null);
}
/**
* 未授权返回结果
*/
public static <T> CommonResult<T> forbidden(T data) {
return new CommonResult<T>(ExceptionCodeEnum.FORBIDDEN.getCode(), ExceptionCodeEnum.FORBIDDEN.getMessage(), data);
}
public long getCode() {
return code;
}
public void setCode(long code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
}

View File

@@ -0,0 +1,16 @@
package com.common;
import com.constants.Constants;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
public class PageParamRequest {
@ApiModelProperty(value = "页码", example= Constants.DEFAULT_PAGE + "")
private int page = Constants.DEFAULT_PAGE;
@ApiModelProperty(value = "每页数量", example = Constants.DEFAULT_LIMIT + "")
private int limit = Constants.DEFAULT_LIMIT;
}

View File

@@ -0,0 +1,404 @@
package com.constants;
/**
* @author stivepeim
* @title: Constants
* @projectName crmeb
* @Description: 配置类
* @since 2020/4/1415:46
*/
public class Constants {
public static final long TOKEN_EXPRESS_MINUTES = (60 * 24);
public static final int NUM_ZERO = 0;
public static final int NUM_ONE = 1;
public static final int NUM_TWO = 2;
public static final int NUM_THREE = 3;
public static final int NUM_SEVEN = 7;
public static final int NUM_TEN = 10;
public static final int NUM_ONE_HUNDRED = 100;
//头部 token令牌key
public static final String HEADER_AUTHORIZATION_KEY = "Authori-zation";
//验证码redis key前缀
public static final String VALIDATE_REDIS_KEY_PREFIX = "validate_code_";
public static final String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";
public static final String DATE_FORMAT_UTC = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'";
public static final String DATE_FORMAT_DATE = "yyyy-MM-dd";
public static final String DATE_FORMAT_YEAR = "yyyy";
public static final String DATE_FORMAT_MONTH_DATE = "MM-dd";
public static final String DATE_FORMAT_MONTH = "yyyy-MM";
public static final String DATE_TIME_FORMAT_NUM = "yyyyMMddHHmmss";
public static final String DATE_FORMAT_NUM = "yyyyMMdd";
public static final String DATE_FORMAT_START = "yyyy-MM-dd 00:00:00";
public static final String DATE_FORMAT_END = "yyyy-MM-dd 23:59:59";
public static final String DATE_FORMAT_MONTH_START = "yyyy-MM-01 00:00:00";
public static final String DATE_FORMAT_YEAR_START = "yyyy-01-01 00:00:00";
public static final String DATE_FORMAT_YEAR_END = "yyyy-12-31 23:59:59";
public static final String DATE_FORMAT_HHMMSS = "HH:mm:ss";
//后台管理员操作资金mark
public static final String USER_BILL_OPERATE_LOG_TITLE = "{$title}{$operate}了{$value}{$founds}";
//用户等级升级
public static final String USER_LEVEL_OPERATE_LOG_MARK = "尊敬的用户 【{$userName}】, 在{$date}赠送会员等级成为{$levelName}会员";
public static final String USER_LEVEL_UP_LOG_MARK = "尊敬的用户 【{$userName}】, 在{$date}您升级为为{$levelName}会员";
//用户登录密码加密混淆字符串
public static final String USER_LOGIN_PASSWORD_MD5_KEYWORDS = "crmeb";
//用户登token redis存储前缀
public static final String USER_TOKEN_REDIS_KEY_PREFIX = "TOKEN_USER_";
//用户登录方式
public static final String USER_LOGIN_TYPE_H5 = "h5";
//用户登录方式
public static final String USER_LOGIN_TYPE_PUBLIC = "wechat";
//用户登录方式
public static final String USER_LOGIN_TYPE_PROGRAM = "routine";
//用户默认头像
public static final String USER_DEFAULT_AVATAR_CONFIG_KEY = "h5_avatar";
//用户默认推广人id
public static final Integer USER_DEFAULT_SPREAD_ID = 0;
//默认分页
public static final int DEFAULT_PAGE = 1;
//默认分页
public static final int DEFAULT_LIMIT = 20;
//升序排序
public static final String SORT_ASC = "asc";
//降序排序
public static final String SORT_DESC = "desc";
//导出最大数值
public static final Integer EXPORT_MAX_LIMIT = 99999;
//商品最多选择的分类数量
public static final Integer PRODUCT_SELECT_CATEGORY_NUM_MAX = 10;
//上传类型
public static final String UPLOAD_TYPE_IMAGE = "image";
//上传类型
public static final String UPLOAD_TYPE_FILE = "file";
public static final String UPLOAD_ROOT_PATH_CONFIG_KEY = "upload_root_path";//上传地址
//图片上传
public static final String UPLOAD_IMAGE_EXT_STR_CONFIG_KEY = "image_ext_str";//图片上传
public static final String UPLOAD_IMAGE_MAX_SIZE_CONFIG_KEY = "image_max_size";
//文件上传
public static final String UPLOAD_FILE_EXT_STR_CONFIG_KEY = "file_ext_str";
//最大上传文件
public static final String UPLOAD_FILE_MAX_SIZE_CONFIG_KEY = "file_max_size";
public static final int UPLOAD_TYPE_USER = 7; //用户上传
//城市数据 redis key
public static final String CITY_LIST = "city_list";
//城市数据 tree redis key
public static final String CITY_LIST_TREE = "city_list_tree";
//城市数据 tree redis key
public static final String CITY_LIST_LEVEL_1 = "city_list_level_1";
//商品库存变动队列key
public static final String PRODUCT_STOCK_UPDATE = "product_stock_update";
//商品库存redis key
public static final String PRODUCT_STOCK_LIST = "product_stock_list";
//sku库存变动队列key
public static final String SKU_STOCK_UPDATE = "product_stock_update";
//sku库存redis key
// public static final String SKU_STOCK_LIST = "product_stock_list";
//消息模板队列key
public static final String WE_CHAT_MESSAGE_KEY_PUBLIC = "we_chat_public_message_list";
public static final String WE_CHAT_MESSAGE_KEY_PROGRAM = "we_chat_program_message_list";
public static final String WE_CHAT_MESSAGE_INDUSTRY_KEY = "we_chat_message_industry";
//快递信息缓存
public static final String LOGISTICS_KEY = "logistics_";
//config配置的key
public static final String CONFIG_KEY_SITE_URL = "site_url"; //域名
public static final String CONFIG_KEY_API_URL = "api_url"; //接口地址
public static final String CONFIG_KEY_SITE_LOGO = "site_logo"; //logo地址
public static final String CONFIG_KEY_SITE_NAME = "site_name"; //网站名称
public static final String CONFIG_SITE_TENG_XUN_MAP_KEY = "tengxun_map_key"; //腾讯地图key
public static final String CONFIG_BANK_LIST = "user_extract_bank"; //可提现银行
public static final String CONFIG_EXTRACT_FREEZING_TIME = "extract_time"; //提现冻结时间
public static final String CONFIG_EXTRACT_MIN_PRICE = "user_extract_min_price"; //提现最低金额
public static final String CONFIG_RECHARGE_ATTENTION = "recharge_attention"; //充值注意事项
public static final String CONFIG_KEY_PAY_WE_CHAT_APP_ID = "pay_weixin_appid"; //公众号appId
public static final String CONFIG_KEY_PAY_WE_CHAT_MCH_ID = "pay_weixin_mchid"; //公众号配的商户号
public static final String CONFIG_KEY_PAY_WE_CHAT_APP_SECRET = "pay_weixin_appsecret"; //公众号秘钥
public static final String CONFIG_KEY_PAY_WE_CHAT_APP_KEY = "pay_weixin_key"; //公众号支付key
public static final String CONFIG_KEY_PAY_ROUTINE_APP_ID = "pay_routine_appid"; //小程序appId
public static final String CONFIG_KEY_PAY_ROUTINE_MCH_ID = "pay_routine_mchid"; //小程序分配的商户号
public static final String CONFIG_KEY_PAY_ROUTINE_APP_SECRET = "pay_routine_appsecret"; //小程序秘钥
public static final String CONFIG_KEY_PAY_ROUTINE_APP_KEY = "pay_routine_key"; //小程序支付key
public static final String CONFIG_KEY_RECHARGE_MIN_AMOUNT = "store_user_min_recharge"; //最小充值金额
public static final String CONFIG_KEY_PROGRAM_LOGO = "routine_logo"; //小程序logo
public static final String CONFIG_KEY_PUBLIC_LOGO = "wechat_avatar"; //公众号logo
public static final String CONFIG_KEY_LOGISTICS_APP_CODE = "system_express_app_code"; //快递查询密钥
//分销
public static final String CONFIG_KEY_STORE_BROKERAGE_LEVEL = "store_brokerage_rate_num"; //返佣比例前缀
public static final String CONFIG_KEY_STORE_BROKERAGE_USER_EXTRACT_MIN_PRICE = "user_extract_min_price"; //提现最低金额
public static final String CONFIG_KEY_STORE_BROKERAGE_MODEL = "brokerage_func_status"; //分销模式
public static final String CONFIG_KEY_STORE_BROKERAGE_USER_EXTRACT_BANK = "user_extract_bank"; //提现银行卡
public static final String CONFIG_KEY_STORE_BROKERAGE_EXTRACT_TIME = "extract_time"; //冻结时间
public static final String CONFIG_KEY_STORE_BROKERAGE_PERSON_PRICE = "store_brokerage_price"; //人人分销满足金额
public static final String CONFIG_KEY_STORE_BROKERAGE_IS_OPEN = "store_brokerage_status"; //分销启用
//积分
public static final String CONFIG_KEY_INTEGRAL_RATE = "integral_ratio"; //积分抵用比例(1积分抵多少金额
public static final String CONFIG_KEY_INTEGRAL_RATE_ORDER_GIVE = "integral_order_give"; //下单支付金额按比例赠送积分实际支付1元赠送多少积分
//后台首页登录图片
public static final String CONFIG_KEY_ADMIN_LOGIN_LOGO = "login_logo"; //登录页LOGO
public static final String CONFIG_KEY_ADMIN_LOGIN_BACKGROUND_IMAGE = "admin_login_bg_pic"; //登录页背景图
//config配置的formId
public static final int CONFIG_FORM_ID_INDEX = 69; //首页配置
public static final int CONFIG_FORM_ID_PUBLIC = 65; //公众号配置
//第三方登录token类型
public static final int THIRD_LOGIN_TOKEN_TYPE_PUBLIC = 1; //公众号
public static final int THIRD_LOGIN_TOKEN_TYPE_PROGRAM = 2; //小程序
public static final int THIRD_LOGIN_TOKEN_TYPE_UNION_ID = 3; //unionid
// 商品类型 活动类型 0=商品1=秒杀2=砍价3=拼团 attrResult表用到
public static final int PRODUCT_TYPE_NORMAL = 0;
public static final int PRODUCT_TYPE_SECKILL = 1;
public static final int PRODUCT_TYPE_BARGIN = 2;
public static final int PRODUCT_TYPE_GROUP = 0;
//group gid
public static final Integer GROUP_DATA_ID_INDEX_BEST_BANNER = 37; //中部推荐banner图
public static final Integer GROUP_DATA_ID_INDEX_BANNER = 48; //首页banner滚动图
public static final Integer GROUP_DATA_ID_INDEX_RECOMMEND_BANNER = 52; //首页精品推荐Banner图片
public static final Integer GROUP_DATA_ID_ORDER_STATUS_PIC = 53; //订单详情状态图
public static final Integer GROUP_DATA_ID_USER_CENTER_MENU = 54; //个人中心菜单
public static final Integer GROUP_DATA_ID_SIGN = 55; //签到配置
public static final Integer GROUP_DATA_ID_HOT_SEARCH = 56; //热门搜索
public static final Integer GROUP_DATA_ID_INDEX_HOT_BANNER = 57; //热门榜单推荐Banner图片
public static final Integer GROUP_DATA_ID_INDEX_NEW_BANNER = 58; //首发新品推荐Banner图片
public static final Integer GROUP_DATA_ID_INDEX_BENEFIT_BANNER = 59; //首页促销单品推荐Banner图片
public static final Integer GROUP_DATA_ID_SPREAD_BANNER_LIST = 60; //推广海报图
public static final Integer GROUP_DATA_ID_RECHARGE_LIST = 62; //充值金额设置
public static final Integer GROUP_DATA_ID_USER_CENTER_BANNER = 65; //个人中心轮播图
public static final Integer GROUP_DATA_ID_INDEX_MENU = 67; //导航模块
public static final Integer GROUP_DATA_ID_INDEX_NEWS_BANNER = 68; //首页滚动新闻
public static final Integer GROUP_DATA_ID_INDEX_ACTIVITY_BANNER = 69; //首页活动区域图片
public static final Integer GROUP_DATA_ID_INDEX_EX_BANNER = 70; //首页超值爆款
public static final Integer GROUP_DATA_ID_INDEX_KEYWORDS = 71; //热门搜索
public static final Integer GROUP_DATA_ID_ADMIN_LOGIN_BANNER_IMAGE_LIST = 72; //后台登录页面轮播图
//签到
public static final Integer SIGN_TYPE_INTEGRAL = 1; //积分
public static final Integer SIGN_TYPE_EXPERIENCE = 2; //经验
public static final String SIGN_TYPE_INTEGRAL_TITLE = "签到积分奖励"; //积分
public static final String SIGN_TYPE_EXPERIENCE_TITLE = "签到经验奖励"; //经验
//会员搜索日期类型
public static final String SEARCH_DATE_DAY = "today"; //今天
public static final String SEARCH_DATE_YESTERDAY = "yesterday"; //昨天
public static final String SEARCH_DATE_LATELY_7 = "lately7"; //最近7天
public static final String SEARCH_DATE_LATELY_30 = "lately30"; //最近30天
public static final String SEARCH_DATE_WEEK = "week"; //本周
public static final String SEARCH_DATE_PRE_WEEK = "preWeek"; //上周
public static final String SEARCH_DATE_MONTH = "month"; //本月
public static final String SEARCH_DATE_PRE_MONTH = "preMonth"; //上月
public static final String SEARCH_DATE_YEAR = "year"; //年
public static final String SEARCH_DATE_PRE_YEAR = "preYear"; //上一年
//分类服务类型 类型1 产品分类2 附件分类3 文章分类, 4 设置分类, 5 菜单分类, 6 配置分类, 7 秒杀配置
public static final int CATEGORY_TYPE_PRODUCT = 1; //产品
public static final int CATEGORY_TYPE_ATTACHMENT = 2; //附件分类
public static final int CATEGORY_TYPE_ARTICLE = 3; //文章分类
public static final int CATEGORY_TYPE_SET = 4; //设置分类
public static final int CATEGORY_TYPE_MENU = 5; //菜单分类
public static final int CATEGORY_TYPE_CONFIG = 6; //配置分类
public static final int CATEGORY_TYPE_SKILL = 7; //秒杀配置
//首页Banner图片
public static final int INDEX_RECOMMEND_BANNER = 1; //首页精品推荐Banner图片
public static final int INDEX_HOT_BANNER = 2; //热门榜单推荐Banner图片
public static final int INDEX_NEW_BANNER = 3; //首页首发新品推荐Banner图片
public static final int INDEX_BENEFIT_BANNER = 4; //首页促销单品推荐Banner图片
public static final int INDEX_LIMIT_DEFAULT = 3; //首页默认list分页条数
//用户资金
public static final String USER_BILL_CATEGORY_MONEY = "now_money"; //用户余额
public static final String USER_BILL_CATEGORY_INTEGRAL = "integral"; //积分
public static final String USER_BILL_CATEGORY_SHARE = "share"; //分享
public static final String USER_BILL_CATEGORY_EXPERIENCE = "experience"; //经验
public static final String USER_BILL_CATEGORY_BROKERAGE_PRICE = "brokerage_price"; //佣金金额
public static final String USER_BILL_CATEGORY_SIGN_NUM = "sign_num"; //签到天数
public static final String USER_BILL_TYPE_BROKERAGE = "brokerage"; //推广
public static final String USER_BILL_TYPE_DEDUCTION = "deduction"; //抵扣
public static final String USER_BILL_TYPE_EXTRACT = "extract"; //提现
public static final String USER_BILL_TYPE_TRANSFER_IN = "transferIn"; //佣金转入余额
public static final String USER_BILL_TYPE_GAIN = "gain"; //购买商品赠送
public static final String USER_BILL_TYPE_PAY_MONEY = "pay_money"; //购买
public static final String USER_BILL_TYPE_PAY_PRODUCT = "pay_product"; //购买商品
public static final String USER_BILL_TYPE_PAY_PRODUCT_INTEGRAL_BACK = "pay_product_integral_back"; //商品退积分
public static final String USER_BILL_TYPE_PAY_PRODUCT_REFUND = "pay_product_refund"; //商品退款
public static final String USER_BILL_TYPE_RECHARGE = "recharge"; //佣金转入
public static final String USER_BILL_TYPE_SHARE = "share"; //用户分享记录
public static final String USER_BILL_TYPE_SIGN = "sign"; //签到
public static final String USER_BILL_TYPE_ORDER = "order"; //订单
public static final String USER_BILL_TYPE_SYSTEM_ADD = "system_add"; //系统增加
public static final String USER_BILL_TYPE_SYSTEM_SUB = "system_sub"; //系统减少
//订单状态
public static final String ORDER_STATUS_ALL = "all"; //所有
public static final String ORDER_STATUS_UNPAID = "unPaid"; //未支付
public static final String ORDER_STATUS_NOT_SHIPPED = "notShipped"; //未发货
public static final String ORDER_STATUS_SPIKE = "spike"; //待收货
public static final String ORDER_STATUS_BARGAIN = "bargain"; //已收货待评价
public static final String ORDER_STATUS_COMPLETE = "complete"; //交易完成
public static final String ORDER_STATUS_TOBE_WRITTEN_OFF = "toBeWrittenOff"; //待核销
public static final String ORDER_STATUS_REFUNDING = "refunding"; //退款中
public static final String ORDER_STATUS_REFUNDED = "refunded"; //已退款
public static final String ORDER_STATUS_DELETED = "deleted"; //已删除
public static final String ORDER_STATUS_STR_UNPAID = "未支付"; //未支付
public static final String ORDER_STATUS_STR_NOT_SHIPPED = "未发货"; //未发货
public static final String ORDER_STATUS_STR_SPIKE = "待收货"; //待收货
public static final String ORDER_STATUS_STR_BARGAIN = "待评价"; //已收货待评价
public static final String ORDER_STATUS_STR_TAKE = "用户已收货"; //用户已收货
public static final String ORDER_STATUS_STR_COMPLETE = "交易完成"; //交易完成
public static final String ORDER_STATUS_STR_TOBE_WRITTEN_OFF = "待核销"; //待核销
public static final String ORDER_STATUS_STR_REFUNDING = "退款中"; //退款中
public static final String ORDER_STATUS_STR_REFUNDED = "已退款"; //已退款
public static final String ORDER_STATUS_STR_DELETED = "已删除"; //已删除
// H5 端订单状态
public static final int ORDER_STATUS_H5_UNPAID = 0; // 未支付
public static final int ORDER_STATUS_H5_NOT_SHIPPED = 1; // 待发货
public static final int ORDER_STATUS_H5_SPIKE = 2; // 待收货
public static final int ORDER_STATUS_H5_BARGAIN = 3; // 待评价
public static final int ORDER_STATUS_H5_COMPLETE = 4; // 已完成
public static final int ORDER_STATUS_H5_REFUNDING = -1; // 退款中
public static final int ORDER_STATUS_H5_REFUNDED = -2; // 已退款
public static final int ORDER_STATUS_H5_REFUND = -3; // 退款
public static final int ORDER_STATUS_INT_PAID = 0; //已支付
public static final int ORDER_STATUS_INT_SPIKE = 1; //待收货
public static final int ORDER_STATUS_INT_BARGAIN = 2; //已收货,待评价
public static final int ORDER_STATUS_INT_COMPLETE = 3; //已完成
//订单操作redis队列
public static final String ORDER_TASK_REDIS_KEY_AFTER_DELETE_BY_USER = "alterOrderDeleteByUser"; // 用户删除订单后续操作
public static final String ORDER_TASK_REDIS_KEY_AFTER_COMPLETE_BY_USER = "alterOrderCompleteByUser"; // 用户完成订单后续操作
public static final String ORDER_TASK_REDIS_KEY_AFTER_CANCEL_BY_USER = "alterOrderCancelByUser"; // 用户取消订单后续操作
public static final String ORDER_TASK_REDIS_KEY_AFTER_REFUND_BY_USER = "alterOrderRefundByUser"; // 用户订单退款后续操作
public static final String ORDER_TASK_REDIS_KEY_AFTER_TAKE_BY_USER = "alterOrderTakeByUser"; // 用户订单收货后续操作
public static final String ORDER_STATUS_CACHE_CREATE_ORDER = "cache_key_create_order";
//支付方式
public static final String PAY_TYPE_WE_CHAT = "weixin"; //微信支付
public static final String PAY_TYPE_YUE = "yue"; //余额支付
public static final String PAY_TYPE_OFFLINE = "offline"; //线下支付
public static final String PAY_TYPE_ALI_PAY = "alipay"; //支付宝
//支付客户端类型
public static final String PAY_TYPE_WE_CHAT_FROM_H5 = "weixinh5"; //H5唤起微信支付
public static final String PAY_TYPE_WE_CHAT_FROM_PUBLIC = "public"; //公众号
public static final String PAY_TYPE_WE_CHAT_FROM_PROGRAM = "routine"; //小程序
//支付方式
public static final String PAY_TYPE_STR_WE_CHAT = "微信支付"; //微信支付
public static final String PAY_TYPE_STR_YUE = "余额支付"; //余额支付
public static final String PAY_TYPE_STR_OFFLINE = "线下支付"; //线下支付
public static final String PAY_TYPE_STR_ALI_PAY = "支付宝"; //支付宝
public static final String PAY_TYPE_STR_OTHER = "其他支付"; //其他支付
//需要支付的业务类型
public static final String SERVICE_PAY_TYPE_ORDER = "order"; //订单
public static final String SERVICE_PAY_TYPE_RECHARGE = "recharge"; //充值
//订单操作类型
public static final String ORDER_STATUS_STR_SPIKE_KEY = "send"; //待收货 KEY
public static final String ORDER_LOG_REFUND_PRICE = "refund_price"; //退款
public static final String ORDER_LOG_EXPRESS = "express"; //快递
public static final String ORDER_LOG_DELIVERY = "delivery"; //送货
public static final String ORDER_LOG_DELIVERY_GOODS = "delivery_goods"; //送货
public static final String ORDER_LOG_REFUND_REFUSE = "refund_refuse"; //不退款
public static final String ORDER_LOG_REFUND_APPLY = "apply_refund"; //
public static final String ORDER_LOG_PAY_SUCCESS = "pay_success"; //支付成功
public static final String ORDER_LOG_DELIVERY_VI = "delivery_fictitious"; //虚拟发货
// 订单缓存
public static final long ORDER_CASH_CONFIRM = (60);
//订单操作类型 -> 消息
public static final String ORDER_LOG_MESSAGE_REFUND_PRICE = "退款给用户{amount}元"; //退款
public static final String ORDER_LOG_MESSAGE_EXPRESS = "已发货 快递公司:{deliveryName}, 快递单号:{deliveryCode}"; //快递
public static final String ORDER_LOG_MESSAGE_DELIVERY = "已配送 发货人:{deliveryName}, 发货人电话:{deliveryCode}"; //送货
public static final String ORDER_LOG_MESSAGE_DELIVERY_FICTITIOUS = "已虚拟发货"; //已虚拟发货
public static final String ORDER_LOG_MESSAGE_REFUND_REFUSE = "不退款款因:{reason}"; //不退款款因
public static final String ORDER_LOG_MESSAGE_PAY_SUCCESS = "用户付款成功"; //用户付款成功
public static final String ORDER_NO_PREFIX_WE_CHAT = "wx"; //微信平台下单订单号前缀
public static final String ORDER_NO_PREFIX_H5 = "h5"; //微信平台下单订单号前缀
//支付渠道 订单表
public static final int ORDER_PAY_CHANNEL_PUBLIC = 0; //公众号
public static final int ORDER_PAY_CHANNEL_PROGRAM = 1; //小程序
//微信消息模板 tempKey
public static final String WE_CHAT_TEMP_KEY_EXPRESS = "OPENTM200565259";
public static final String WE_CHAT_TEMP_KEY_DELIVERY = "OPENTM207707249";
public static final String WE_CHAT_TEMP_KEY_FIRST = "first";
public static final String WE_CHAT_TEMP_KEY_END = "remark";
public static final String WE_CHAT_PUBLIC_TEMP_KEY_RECHARGE = "OPENTM200565260";
public static final String WE_CHAT_PROGRAM_TEMP_KEY_RECHARGE = "OPENTM200565260";
public static final String WE_CHAT_PUBLIC_TEMP_KEY_ORDER_PAY_SUCCESS = "OPENTM200565260"; //需要添加模板消息之后修改
public static final String WE_CHAT_PROGRAM_TEMP_KEY_ORDER_PAY_SUCCESS = "OPENTM200565260";
//CND URL测试用
public static String CND_URL = "https://wuht-1300909283.cos.ap-chengdu.myqcloud.com";
//物流 https://market.aliyun.com/products/56928004/cmapi021863.html#sku=yuncode15863000015
public static String LOGISTICS_API_URL = "https://wuliu.market.alicloudapi.com/kdi";
}

View File

@@ -0,0 +1,100 @@
package com.constants;
/**
* @author Mr.zhang
* @Description 正则表达式类
* @since 2020-05-11
**/
public class RegularConstants {
//数字
public static final String NUMBER = "^-?[0-9]+";
//邮箱
public static final String EMAIL = "^\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*$";
//手机
public static final String PHONE = "^1([358][0-9]|4[579]|66|7[0135678]|9[89])[0-9]{8}$";
//整数或者小数:
public static final String INTEGER_OR_FLOAT = "^[0-9]+=\\.{0,1}[0-9]{0,2}$";
//n位的数字
public static final String NUMBER_LEN = "^\\d{n}$";
//n位的数字
public static final String NUMBER_MIN_LEN = "^\\d{n,}$";
//m~n位的数字
public static final String NUMBER_LEN_RANGE = "^\\d{m,n}$";
//零和非零开头的数字
public static final String NUMBER_LEN_UNSIGNED_CONTAINS_ZERO = "^(0|[1-9][0-9]*)$";
//有两位小数的正实数
public static final String FLOAT_TWO_LEN = "^[0-9]+(.[0-9]{2})?$";
//有两位小数的正实数
public static final String FLOAT_LEN_RANGE = "^[0-9]+(.[0-9]{1,3})?$";
//非零的正整数
public static final String NUMBER_UNSIGNED = "^\\+?[1-9][0-9]*$";
//非0的负数
public static final String NUMBER_NOT_UNSIGNED = "^\\-[1-9][]0-9\"*$";
//3位字符串
public static final String STRING_THREE_LEN = "^.{3}$";
//所有英文字母
public static final String STRING_ALL_EN_CHARS = "^[A-Za-z]+$";
//由26个大写英文字母组成的字符串
public static final String STRING_UPPER_EN_CHARS = "^[A-Z]+$";
//由26个小写英文字母组成的字符串
public static final String STRING_LOWER_EN_CHARS = "^[a-z]+$";
//由数字和26个英文字母组成的字符串
public static final String STRING_ALL_EN_CHARS_AND_NUMBER = "^[A-Za-z0-9]+$";
//由数字和26个英文字母组成的字符串
public static final String STRING_ALL_EN_CHARS_AND_UNDER_LINE = "^\\w+";
//验证用户密码, 正确格式为以字母开头长度在6~18之间只能包含字符、数字和下划线。
public static final String PASSWORD = "^[a-zA-Z]\\w{5,17}$";
//验证码, 正确格式为4位数字验证码。
public static final String SMS_VALIDATE_CODE_NUM = "^\\d{6}$";
//验证码, 正确格式为6位数字验证码。
public static final String VALIDATE_CODE_NUM_SIX = "^\\d{6}$";
//汉字
public static final String CHINESE = "^[\\u4e00-\\u9fa5]{0,}$";
//url http开头
public static final String URL = "^http://([\\w-]+\\.)+[\\w-]+(/[\\w-./?%&=]*)?$";
//电话 正确格式为:"XXX-XXXXXXX"、"XXXX-XXXXXXXX"、"XXX-XXXXXXX"、"XXX-XXXXXXXX"、"XXXXXXX"和"XXXXXXXX"
public static final String TEL = "^(\\(\\d{3,4}-)|\\d{3.4}-)?\\d{7,8}$";
//验证身份证号 15位或18位数字
public static final String ID_CARD = "^\\d{15}|\\d{18}$";
// 验证一年的12个月 正确格式为:"01""09"和"1""12"
public static final String MONTH = "^(0?[1-9]|1[0-2])$";
// 验证一个月的31天 正确格式为;"01""09"和"1""31"
public static final String DAY = "^((0?[1-9])|((1|2)[0-9])|30|31)$";
// 匹配空行的正则表达式
public static final String EMPTY_LINE = "\\n[\\s| ]*\\r";
// 匹配html标签的正则表达式
public static final String HTML_TAG = "<(.*)>(.*)<\\/(.*)>|<(.*)\\/>";
// 匹配首尾空格的正则表达式
public static final String TRIM = "(^\\s*)|(\\s*$)";
}

View File

@@ -0,0 +1,91 @@
package com.constants;
/**
* @author Mr.zhang
* @Description 短信配置
* @since 2020-04-17
**/
public class SmsConstants {
//------------------------------------------------短信配置------------------------------------------------
//短信请求地址
public static final String SMS_API_URL = "https://sms.crmeb.net/api/";
//短信支付回调地址
public static final String SMS_API_PAY_NOTIFY_URI = "/api/sms/pay/notify";
//验证码接口
public static final String SMS_API_CAPTCHA_URI = "sms/captcha";
//账号注册地址
public static final String SMS_API_REGISTER_URI = "sms/register";
//公共短信模板列表
public static final String SMS_API_PUBLIC_TEMP_URI = "sms/publictemp";
//公共短信模板添加
public static final String SMS_API_PUBLIC_TEMP_USE_URI = "sms/use";
//获取账号信息
public static final String SMS_API_USER_INFO_URI = "sms/userinfo";
//支付套餐
public static final String SMS_API_PAY_TEMP_LIST_URI = "sms/meal";
//支付二维码
public static final String SMS_API_PAY_QR_CODE_URI = "sms/mealpay";
//支付二维码
public static final String SMS_API_APPLY_TEMP_MESSAGE_URI = "sms/apply";
//短信模板列表
public static final String SMS_API_TEMP_LIST_URI = "sms/template";
// 发送短信
public static final String SMS_API_SEND_URI = "sms/send";
//接口异常错误码
public static final Integer SMS_ERROR_CODE = 400;
//短信发送队列key
public static final String SMS_SEND_KEY = "sms_send_list";
// 短信模版配置开关常量
public static final String SMS_CONFIG_VERIFICATION_CODE = "verificationCode";// 验证码
public static final Integer SMS_CONFIG_VERIFICATION_CODE_TEMP_ID = 518076;//
public static final String SMS_CONFIG_LOWER_ORDER_SWITCH = "lowerOrderSwitch";// 支付成功短信提醒
public static final Integer SMS_CONFIG_LOWER_ORDER_SWITCH_TEMP_ID = 520268;// 对应的模版id
public static final String SMS_CONFIG_DELIVER_GOODS_SWITCH = "deliverGoodsSwitch";// 发货短信提醒
public static final Integer SMS_CONFIG_DELIVER_GOODS_SWITCH_TEMP_ID = 520269;
public static final String SMS_CONFIG_CONFIRM_TAKE_OVER_SWITCH = "confirmTakeOverSwitch";// 确认收货短信提醒
public static final Integer SMS_CONFIG_CONFIRM_TAKE_OVER_SWITCH_TEMP_ID = 520271;
public static final String SMS_CONFIG_ADMIN_LOWER_ORDER_SWITCH = "adminLowerOrderSwitch";// 用户下单管理员短信提醒
public static final Integer SMS_CONFIG_ADMIN_LOWER_ORDER_SWITCH_TEMP_ID = 520272;
public static final String SMS_CONFIG_ADMIN_PAY_SUCCESS_SWITCH = "adminPaySuccessSwitch";// 支付成功管理员短信提醒
public static final Integer SMS_CONFIG_ADMIN_PAY_SUCCESS_SWITCH_TEMP_ID = 520273;
public static final String SMS_CONFIG_ADMIN_REFUND_SWITCH = "adminRefundSwitch";// 用户确认收货管理员短信提醒
public static final Integer SMS_CONFIG_ADMIN_REFUND_SWITCH_TEMP_ID = 520422;
public static final String SMS_CONFIG_ADMIN_CONFIRM_TAKE_OVER_SWITCH = "adminConfirmTakeOverSwitch";// 用户发起退款管理员短信提醒
public static final Integer SMS_CONFIG_ADMIN_CONFIRM_TAKE_OVER_SWITCH_TEMP_ID = 520274;
public static final String SMS_CONFIG_PRICE_REVISION_SWITCH = "priceRevisionSwitch";// 改价短信提醒
public static final Integer SMS_CONFIG_PRICE_REVISION_SWITCH_TEMP_ID = 528288;
public static final String SMS_CONFIG_ORDER_PAY_FALSE = "orderPayFalse";// 订单未支付
public static final Integer SMS_CONFIG_ORDER_PAY_FALSE_TEMP_ID = 528116;
//支付
public static final String PAY_DEFAULT_PAY_TYPE = "weixin";
//手机验证码redis key
public static final String SMS_VALIDATE_PHONE = "sms_validate_code_";
//短信类型
// 短信模版配置开关常量
public static final int SMS_CONFIG_TYPE_VERIFICATION_CODE = 1;// 验证码
public static final int SMS_CONFIG_TYPE_LOWER_ORDER_SWITCH = 2;// 支付成功短信提醒
public static final int SMS_CONFIG_TYPE_DELIVER_GOODS_SWITCH = 3;// 发货短信提醒
public static final int SMS_CONFIG_TYPE_CONFIRM_TAKE_OVER_SWITCH = 4;// 确认收货短信提醒
public static final int SMS_CONFIG_TYPE_ADMIN_LOWER_ORDER_SWITCH = 5;// 用户下单管理员短信提醒
public static final int SMS_CONFIG_TYPE_ADMIN_PAY_SUCCESS_SWITCH = 6;// 支付成功管理员短信提醒
public static final int SMS_CONFIG_TYPE_ADMIN_REFUND_SWITCH = 7;// 用户确认收货管理员短信提醒
public static final int SMS_CONFIG_TYPE_ADMIN_CONFIRM_TAKE_OVER_SWITCH = 8;// 用户发起退款管理员短信提醒
public static final int SMS_CONFIG_TYPE_PRICE_REVISION_SWITCH = 9;// 改价短信提醒
public static final int SMS_CONFIG_TYPE_ORDER_PAY_FALSE = 10;// 订单未支付
}

View File

@@ -0,0 +1,195 @@
package com.constants;
/**
* @author stivepeim
* @title: Constants
* @projectName crmeb
* @Description: 微信配置
* @since 2020/4/1415:46
*/
public class WeChatConstants {
//------------------------------------------------公众号------------------------------------------------
//微信接口请求地址
public static final String API_URL = "https://api.weixin.qq.com/";
//获取token
public static final String API_TOKEN_URI = "cgi-bin/token?grant_type=client_credential";
//微信公众号菜单创建
public static final String PUBLIC_API_MENU_CREATE_URI = "cgi-bin/menu/create";
//微信公众号菜单获取
public static final String PUBLIC_API_MENU_GET_URI = "cgi-bin/menu/get";
//微信公众号菜单删除
public static final String PUBLIC_API_MENU_DELETE_URI = "cgi-bin/menu/delete";
//微信公众号,获取自定义菜单配置接口
public static final String PUBLIC_API_MENU_SELF_SET_URI = "cgi-bin/get_current_selfmenu_info";
//微信公众号,创建个性化菜单
public static final String PUBLIC_API_MENU_ADD_CONDITIONAL_URI = "cgi-bin/menu/addconditional";
//微信公众号,删除个性化菜单
public static final String PUBLIC_API_MENU_DEL_CONDITIONAL_URI = "cgi-bin/menu/delconditional";
//微信公众号,测试个性化菜单匹配结果
public static final String PUBLIC_API_USER_INFO_URI = "cgi-bin/menu/trymatch";
//获取公众号已创建的标签
public static final String PUBLIC_API_TAG_LIST_URI = "cgi-bin/tags/get";
//创建标签
public static final String PUBLIC_API_TAG_CREATE_URI = "cgi-bin/tags/create";
//编辑标签
public static final String PUBLIC_API_TAG_UPDATE_URI = "cgi-bin/tags/update";
//删除标签
public static final String PUBLIC_API_TAG_DELETE_URI = "cgi-bin/tags/delete";
//获取标签下粉丝列表
public static final String PUBLIC_API_TAG_USER_GET_URI = "cgi-bin/user/tag/get";
//批量为用户打标签
public static final String PUBLIC_API_TAG_MEMBER_BATCH_URI = "cgi-bin/tags/members/batchtagging";
//批量为用户取消标签
public static final String PUBLIC_API_TAG_MEMBER_BATCH_UN_URI = "cgi-bin/tags/members/batchuntagging";
//获取用户身上的标签列表
public static final String PUBLIC_API_TAG_GET_ID_LIST_URI = "cgi-bin/tags/getidlist";
//获取 JsApiTicket
public static final String PUBLIC_API_JS_API_TICKET = "cgi-bin/ticket/getticket";
//发送公众号模板消息
public static final String PUBLIC_API__PUBLIC_TEMPLATE_MESSAGE_SEND = "cgi-bin/message/template/send";
//发送小程序模板消息
public static final String PUBLIC_API__PROGRAM_TEMPLATE_MESSAGE_SEND = "cgi-bin/message/subscribe/send";
//获取设置的行业信息
public static final String PUBLIC_API_TEMPLATE_MESSAGE_INDUSTRY = "cgi-bin/template/get_industry";
//新增其他类型永久素材
public static final String PUBLIC_API_MEDIA_UPLOAD = "cgi-bin/material/add_material";
//获取永久素材
public static final String PUBLIC_API_MEDIA_GET = "cgi-bin/material/get_material";
//获取微信素材总数
public static final String PUBLIC_API_MEDIA_COUNT = "cgi-bin/material/get_materialcount";
//发送客服消息
public static final String PUBLIC_API_KF_MESSAGE_SEND = "cgi-bin/message/custom/send";
//授权登录
//获取临时code跳转地址
public static final String WE_CHAT_AUTHORIZE_REDIRECT_URI_URL = "/api/front/wechat/authorize/login";
//获取openId
public static final String WE_CHAT_AUTHORIZE_GET_OPEN_ID = "sns/oauth2/access_token";
//获取小程序openId
public static final String WE_CHAT_AUTHORIZE_PROGRAM_GET_OPEN_ID = "sns/jscode2session";
//获取用户信息
public static final String WE_CHAT_AUTHORIZE_GET_USER_INFO = "sns/userinfo";
//生成二维码
public static final String WE_CHAT_CREATE_QRCODE = "wxa/getwxacodeunlimit";
//微信消息存储队列
public static final String WE_CHAT_MESSAGE_SEND_KEY = "we_chat_message_send_list";
//大家注意这里消息类型的定义,以 RESP 开头的表示返回的消息类型,以 REQ 表示微信服务器发来的消息类型
/**
* 返回消息类型:文本
*/
public static final String WE_CHAT_MESSAGE_RESP_MESSAGE_TYPE_TEXT = "text";
/**
* 返回消息类型:音乐
*/
public static final String WE_CHAT_MESSAGE_RESP_MESSAGE_TYPE_MUSIC = "music";
/**
* 返回消息类型:图文
*/
public static final String WE_CHAT_MESSAGE_RESP_MESSAGE_TYPE_NEWS = "news";
/**
* 返回消息类型:图片
*/
public static final String WE_CHAT_MESSAGE_RESP_MESSAGE_TYPE_IMAGE = "image";
/**
* 返回消息类型:语音
*/
public static final String WE_CHAT_MESSAGE_RESP_MESSAGE_TYPE_VOICE = "voice";
/**
* 返回消息类型:视频
*/
public static final String WE_CHAT_MESSAGE_RESP_MESSAGE_TYPE_VIDEO = "video";
/**
* 请求消息类型:文本
*/
public static final String WE_CHAT_MESSAGE_REQ_MESSAGE_TYPE_TEXT = "text";
/**
* 请求消息类型:图片
*/
public static final String WE_CHAT_MESSAGE_REQ_MESSAGE_TYPE_IMAGE = "image";
/**
* 请求消息类型:链接
*/
public static final String WE_CHAT_MESSAGE_REQ_MESSAGE_TYPE_LINK = "link";
/**
* 请求消息类型:地理位置
*/
public static final String WE_CHAT_MESSAGE_REQ_MESSAGE_TYPE_LOCATION = "location";
/**
* 请求消息类型:音频
*/
public static final String WE_CHAT_MESSAGE_REQ_MESSAGE_TYPE_VOICE = "voice";
/**
* 请求消息类型:视频
*/
public static final String WE_CHAT_MESSAGE_REQ_MESSAGE_TYPE_VIDEO = "video";
/**
* 请求消息类型:推送
*/
public static final String WE_CHAT_MESSAGE_REQ_MESSAGE_TYPE_EVENT = "event";
/**
* 事件类型subscribe(订阅)
*/
public static final String WE_CHAT_MESSAGE_EVENT_TYPE_SUBSCRIBE = "subscribe";
/**
* 事件类型unsubscribe(取消订阅)
*/
public static final String WE_CHAT_MESSAGE_EVENT_TYPE_UNSUBSCRIBE = "unsubscribe";
/**
* 事件类型CLICK(自定义菜单点击事件)
*/
public static final String WE_CHAT_MESSAGE_EVENT_TYPE_CLICK = "click";
/**
* 事件类型VIEW(自定义菜单 URl 视图)
*/
public static final String WE_CHAT_MESSAGE_EVENT_TYPE_VIEW = "view";
/**
* 事件类型LOCATION(上报地理位置事件)
*/
public static final String WE_CHAT_MESSAGE_EVENT_TYPE_LOCATION = "LOCATION";
/**
* 事件类型LOCATION(上报地理位置事件)
*/
public static final String WE_CHAT_MESSAGE_EVENT_TYPE_SCAN = "SCAN";
//无效关键字key
public static final String WE_CHAT_MESSAGE_DEFAULT_CONTENT_KEY = "default";
//Js sdk api 列表
public static final String PUBLIC_API_JS_API_SDK_LIST = "openAddress,updateTimelineShareData,updateAppMessageShareData,onMenuShareTimeline,onMenuShareAppMessage,onMenuShareQQ,onMenuShareWeibo,onMenuShareQZone,startRecord,stopRecord,onVoiceRecordEnd,playVoice,pauseVoice,stopVoice,onVoicePlayEnd,uploadVoice,downloadVoice,chooseImage,previewImage,uploadImage,downloadImage,translateVoice,getNetworkType,openLocation,getLocation,hideOptionMenu,showOptionMenu,hideMenuItems,showMenuItems,hideAllNonBaseMenuItem,showAllNonBaseMenuItem,closeWindow,scanQRCode,chooseWXPay,openProductSpecificView,addCard,chooseCard,openCard";
//token
public static final String REDIS_TOKEN_KEY = "wechat_token";
public static final String REDIS_PROGRAM_TOKEN_KEY = "wechat_program_token";
//tag
public static final String REDIS_TAGS_LIST_KEY = "wechat_tags_list";
//user tag
public static final String REDIS_TAGS_LIST_USER_KEY = "wechat_tags_user_list";
//微信菜单
public static final String REDIS_PUBLIC_MENU_KEY = "wechat_public_menu_key";
//微信自定义菜单
public static final String REDIS_PUBLIC_MENU_SELF_KEY = "wechat_public_menu_self_key";
//JsApiTicket
public static final String REDIS_PUBLIC_JS_API_TICKET = "wechat_js_api_ticket";
public static final Long REDIS_PUBLIC_JS_API_TICKET_EXPRESS = 7100L;
//授权请求地址
public static final String WE_CHAT_AUTHORIZE_URL = "https://open.weixin.qq.com/connect/oauth2/authorize?appid={$appId}&redirect_uri={$redirectUri}&response_type=code&scope=snsapi_base&state=#wechat_redirect";
//-------------------------------------------微信支付------------------------------------------------------------
//微信支付接口请求地址
public static final String PAY_API_URL = "https://api.mch.weixin.qq.com/";
public static final String PAY_API_URI = "pay/unifiedorder";
public static final String PAY_NOTIFY_API_URI_WECHAT = "/api/admin/payment/callback/wechat";
public static final String PAY_TYPE_JS = "JSAPI";
public static final String PAY_TYPE_H5 = "MWEB";
}

View File

@@ -0,0 +1,27 @@
package com.exception;
public class ApiException extends RuntimeException{
private ExceptionHandler exceptionHandler;
public ApiException(ExceptionHandler exceptionHandler) {
super(exceptionHandler.getMessage());
this.exceptionHandler = exceptionHandler;
}
public ApiException(String message) {
super(message);
}
public ApiException(Throwable cause) {
super(cause);
}
public ApiException(String message, Throwable cause) {
super(message, cause);
}
public ExceptionHandler getErrorCode() {
return exceptionHandler;
}
}

View File

@@ -0,0 +1,26 @@
package com.exception;
import com.common.CommonResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import java.util.Objects;
@Slf4j
@RestControllerAdvice
public class CrmebException extends RuntimeException {
private static final long serialVersionUID = 1L;
public CrmebException() {}
public CrmebException(String message) {
super(message);
}
}

View File

@@ -0,0 +1,32 @@
package com.exception;
public enum ExceptionCodeEnum implements ExceptionHandler{
// 数据操作错误定义
SUCCESS(200, "操作成功"),
FAILED(500, "操作失败"),
PRAM_NOT_MATCH(400, "参数不正确"),
VALIDATE_FAILED(400, "参数检验失败"),
UNAUTHORIZED(401, "未登录或token过期请登录"),
FORBIDDEN(403, "没有相关权限"),
NOT_FOUND(404, "没有找到相关数据"),
ERROR(500, "系统异常"),
;
private long code;
private String message;
private ExceptionCodeEnum(long code, String message){
this.code = code;
this.message = message;
}
@Override
public long getCode() {
return code;
}
@Override
public String getMessage() {
return message;
}
}

View File

@@ -0,0 +1,8 @@
package com.exception;
public interface ExceptionHandler {
long getCode();
String getMessage();
}

View File

@@ -0,0 +1,73 @@
package com.exception;
import com.common.CommonResult;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.web.HttpMediaTypeNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import javax.servlet.http.HttpServletRequest;
import java.util.Objects;
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {
// private static final Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);
/**
* 拦截表单参数校验
*/
@ResponseStatus(HttpStatus.OK)
@ExceptionHandler({BindException.class})
public CommonResult bindException(BindException e) {
BindingResult bindingResult = e.getBindingResult();
return CommonResult.failed(ExceptionCodeEnum.VALIDATE_FAILED, Objects.requireNonNull(bindingResult.getFieldError()).getDefaultMessage());
}
/**
* 拦截JSON参数校验
*/
@ResponseStatus(HttpStatus.OK)
@ExceptionHandler(MethodArgumentNotValidException.class)
public CommonResult bindException(MethodArgumentNotValidException e) {
BindingResult bindingResult = e.getBindingResult();
return CommonResult.failed(ExceptionCodeEnum.VALIDATE_FAILED,Objects.requireNonNull(bindingResult.getFieldError()).getDefaultMessage());
}
/**
* 拦截参数类型不正确
* @param e
* @return
*/
@ResponseStatus(HttpStatus.OK)
@ExceptionHandler(HttpMediaTypeNotSupportedException.class)
public CommonResult bindException(HttpMediaTypeNotSupportedException e){
return CommonResult.failed(ExceptionCodeEnum.PRAM_NOT_MATCH,Objects.requireNonNull(e.getMessage()));
}
//声明要捕获的异常
@ResponseStatus(HttpStatus.OK)
@ExceptionHandler(Exception.class)
@ResponseBody
public <T> CommonResult<?> defaultExceptionHandler(Exception e) {
e.printStackTrace();
if(e instanceof CrmebException) {
return CommonResult.failed(ExceptionCodeEnum.FAILED,Objects.requireNonNull(e.getMessage()));
}
if(e instanceof MissingServletRequestParameterException){
return CommonResult.failed(ExceptionCodeEnum.PRAM_NOT_MATCH, Objects.requireNonNull(e.getMessage()));
}
//未知错误
return CommonResult.failed(ExceptionCodeEnum.ERROR,e.getMessage());
}
}

View File

@@ -0,0 +1,64 @@
package com.filter;
import com.constants.Constants;
import com.utils.CrmebUtil;
import com.utils.RequestUtil;
import com.zbkj.crmeb.system.service.SystemAttachmentService;
import com.zbkj.crmeb.system.service.SystemConfigService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 返回值输出过滤器
*/
@Component
public class ResponseFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain)
throws IOException, ServletException {
ResponseWrapper wrapperResponse = new ResponseWrapper((HttpServletResponse) response);//转换成代理类
// 这里只拦截返回,直接让请求过去,如果在请求前有处理,可以在这里处理
filterChain.doFilter(request, wrapperResponse);
byte[] content = wrapperResponse.getContent();//获取返回值
//判断是否有值
if (content.length > 0) {
String str = new String(content, StandardCharsets.UTF_8);
try {
HttpServletRequest req = (HttpServletRequest) request;
str = new ResponseRouter().filter(str, RequestUtil.getUri(req));
} catch (Exception e) {
e.printStackTrace();
}
//把返回值输出到客户端
ServletOutputStream outputStream = response.getOutputStream();
if (str.length() > 0) {
outputStream.write(str.getBytes());
outputStream.flush();
outputStream.close();
//最后添加这一句,输出到客户端
response.flushBuffer();
}
}
}
}

View File

@@ -0,0 +1,34 @@
package com.filter;
import com.utils.SpringUtil;
import com.zbkj.crmeb.system.service.SystemAttachmentService;
public class ResponseRouter {
public String filter(String data, String path){
boolean result = un().contains(path);
if(result){
return data;
}
if (!path.contains("api/admin/") && !path.contains("api/front/")) {
return data;
}
//根据需要处理返回值
if(data.contains("image/") && !data.contains("data:image/png;base64")){
data = SpringUtil.getBean(SystemAttachmentService.class).prefixImage(data);
}
if(data.contains("file/")){
data = SpringUtil.getBean(SystemAttachmentService.class).prefixFile(data);
}
return data;
}
public static String un(){
return "";
}
}

View File

@@ -0,0 +1,69 @@
package com.filter;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import javax.servlet.ServletOutputStream;
import javax.servlet.WriteListener;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
public class ResponseWrapper extends HttpServletResponseWrapper {
private ByteArrayOutputStream buffer;
private ServletOutputStream out;
public ResponseWrapper(HttpServletResponse httpServletResponse) {
super(httpServletResponse);
buffer = new ByteArrayOutputStream();
out = new WrapperOutputStream(buffer);
}
@Override
public ServletOutputStream getOutputStream() {
return out;
}
@Override
public void flushBuffer()
throws IOException {
if (out != null) {
out.flush();
}
}
public byte[] getContent()
throws IOException {
flushBuffer();
return buffer.toByteArray();
}
static class WrapperOutputStream extends ServletOutputStream {
private ByteArrayOutputStream bos;
public WrapperOutputStream(ByteArrayOutputStream bos) {
this.bos = bos;
}
@Override
public void write(int b) {
bos.write(b);
}
@Override
public boolean isReady() {
return false;
}
@Override
public void setWriteListener(WriteListener arg0) {
// TODO Auto-generated method stub
}
}
}

View File

@@ -0,0 +1,16 @@
package com.im;
import lombok.Data;
@Data
public class MessageVo {
public MessageVo(Integer fromId, Integer toId, String message) {
this.fromId = fromId;
this.toId = toId;
this.message = message;
}
public Integer fromId;
public Integer toId;
public String message;
}

View File

@@ -0,0 +1,129 @@
package com.im;
import com.alibaba.fastjson.JSONObject;
import com.utils.DateUtil;
import lombok.SneakyThrows;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.net.SocketException;
import java.util.Scanner;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* SocketClient 客户端
*/
public class SocketClient {
public static final int port = SocketServer.port;
public static final String address = SocketServer.address;
private static Logger log = Logger.getLogger("client");
//为了方便使用直接定义为静态属性,,调用很方便。
private static Socket client = null;
//给客户端起个名字
private static String clientName = "客服";
private static Integer fromId = 1;
private static Integer toId = 10001;
private static MessageVo messageVo = new MessageVo(fromId, toId, clientName +"说:正在连接服务器");
public static void main(String[] args) throws IOException, InterruptedException {
log.log(Level.INFO, "客户端" + clientName + "开始链接,端口:" + port);
client = new Socket(address, port);
new SendThread().start();
new ReceiveThread().start();
sendSocketServer(JSONObject.toJSONString(messageVo), client);//发送消息
while (!client.isClosed()) {
Thread.sleep(1000);
}
// //测试连接数
// Integer nowTime = DateUtil.getNowTime();
// int i = 1;
// try{
// while(true){
// log.log(Level.INFO, "客户端" + clientName + "开始链接,端口:" + port);
// client = new Socket(address, port);
// new SendThread().start();
// new ReceiveThread().start();
// sendSocketServer(JSONObject.toJSONString(messageVo), client);//发送消息
// i++;
// }
// }catch (Exception | OutOfMemoryError e){
// log.log(Level.INFO, "服务器断开连接, " + e.getMessage());
// } finally {
// int totalTime = DateUtil.getNowTime() - nowTime;
// int avg = i / totalTime;
// log.log(Level.INFO, "服务器断开连接, 耗时:" + totalTime + ", 平均每一秒:" + avg);
// }
}
/**
* 发送Socket的socket
* @param outStr 待发送信息
* @param client 客户端Socket
*/
private static void sendSocketServer(String outStr, Socket client) {
try {
ObjectOutputStream oos = new ObjectOutputStream(client.getOutputStream());
oos.writeObject(outStr);
oos.flush();//刷新,将流发出去
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 发送信息线程
*/
static class SendThread extends Thread {
@Override
public void run() {
super.run();
while (!client.isClosed()) {//插入停止条件
Scanner in = new Scanner(System.in);//接收输入
String inputStr = in.next();
if (inputStr != null) {
messageVo.setMessage(inputStr);
sendSocketServer(JSONObject.toJSONString(messageVo), client);//发送消息
}
}
}
}
/**
* 接受信息线程,,运行在后台,,等待输入信息
*/
static class ReceiveThread extends Thread {
@SneakyThrows
@Override
public void run() {
super.run();
try {
InputStream serverInputStream = client.getInputStream();
while (!client.isClosed() && serverInputStream != null) {//插入停止条件
ObjectInputStream ois = new ObjectInputStream(serverInputStream);
String inputStr = (String) ois.readObject();
//获取输出流,经过测试发现,输入流貌似是阻塞,,也就是没有输入时,
// 他就停在这里了一直等着输入所以无需加入Thread.sleep().
System.out.println(inputStr);
}
} catch (SocketException e) {
log.log(Level.INFO, "服务器断开连接!!!");
try {
client.close();//服务器断开连接此时需要关闭客户端连接
} catch (IOException e1) {
log.log(Level.FINE, e1.getMessage());
}
} catch (IOException | ClassNotFoundException e2) {
log.log(Level.FINE, e2.getMessage());
}finally {
log.log(Level.FINE, "服务器断开连接!!!");
client.close();
}
}
}
}

View File

@@ -0,0 +1,104 @@
package com.im;
import com.alibaba.fastjson.JSONObject;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.net.SocketException;
import java.util.Scanner;
import java.util.logging.Level;
import java.util.logging.Logger;
public class SocketClient1 {
public static final int port = SocketServer.port;
public static final String address = SocketServer.address;
private static Logger log = Logger.getLogger("client");
//为了方便使用直接定义为静态属性,,调用很方便。
private static Socket client = null;
//给客户端起个名字
private static String clientName = "张三";
private static Integer fromId = 10001;
private static Integer toId = 1;
private static MessageVo messageVo = new MessageVo(fromId, toId, clientName +"说:正在连接服务器");
public static void main(String[] args) throws IOException, InterruptedException {
log.log(Level.INFO, "客户端" + clientName + "开始链接,端口:" + port);
client = new Socket(address, port);
new SendThread().start();
new ReceiveThread().start();
sendSocketServer(JSONObject.toJSONString(messageVo), client);//发送消息
while (!client.isClosed()) {
Thread.sleep(1000);
}
}
/**
* 发送Socket的socket
*
* @param outStr 待发送信息
* @param client 客户端Socket
*/
private static void sendSocketServer(String outStr, Socket client) {
try {
ObjectOutputStream oos = new ObjectOutputStream(client.getOutputStream());
oos.writeObject(outStr);
oos.flush();//刷新,将流发出去
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 发送信息线程
*/
static class SendThread extends Thread {
@Override
public void run() {
super.run();
while (!client.isClosed()) {//插入停止条件
Scanner in = new Scanner(System.in);//接收输入
String inputStr = in.next();
if (inputStr != null) {
messageVo.setMessage(inputStr);
sendSocketServer(JSONObject.toJSONString(messageVo), client);//发送消息
}
}
}
}
/**
* 接受信息线程,,运行在后台,,等待输入信息
*/
static class ReceiveThread extends Thread {
@Override
public void run() {
super.run();
try {
InputStream serverInputStream = client.getInputStream();
while (!client.isClosed() && serverInputStream != null) {//插入停止条件
ObjectInputStream ois = new ObjectInputStream(serverInputStream);
String inputStr = (String) ois.readObject();
//获取输出流,经过测试发现,输入流貌似是阻塞,,也就是没有输入时,
// 他就停在这里了一直等着输入所以无需加入Thread.sleep().
System.out.println(inputStr);
}
} catch (SocketException e) {
log.log(Level.INFO, "服务器断开连接!!!");
try {
client.close();//服务器断开连接此时需要关闭客户端连接
} catch (IOException e1) {
e1.printStackTrace();
}
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
}
}

View File

@@ -0,0 +1,101 @@
package com.im;
import com.alibaba.fastjson.JSONObject;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.net.SocketException;
import java.util.Scanner;
import java.util.logging.Level;
import java.util.logging.Logger;
public class SocketClient2 {
public static final int port = SocketServer.port;
public static final String address = SocketServer.address;
private static Logger log = Logger.getLogger("client");
//为了方便使用直接定义为静态属性,,调用很方便。
private static Socket client = null;
//给客户端起个名字
private static String clientName = "李四";
private static Integer fromId = 10002;
private static Integer toId = 1;
private static MessageVo messageVo = new MessageVo(fromId, toId, clientName +"说:正在连接服务器");
public static void main(String[] args) throws IOException, InterruptedException {
log.log(Level.INFO, "客户端" + clientName + "开始链接,端口:" + port);
client = new Socket(address, port);
new SendThread().start();
new ReceiveThread().start();
sendSocketServer(JSONObject.toJSONString(messageVo), client);//发送消息
while (!client.isClosed()) {
Thread.sleep(1000);
}
}
/**
* 发送Socket的socket
*
* @param outStr 待发送信息
* @param client 客户端Socket
*/
private static void sendSocketServer(String outStr, Socket client) {
try {
ObjectOutputStream oos = new ObjectOutputStream(client.getOutputStream());
oos.writeObject(outStr);
oos.flush();//刷新,将流发出去
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 发送信息线程
*/
static class SendThread extends Thread {
@Override
public void run() {
super.run();
while (!client.isClosed()) {//插入停止条件
Scanner in = new Scanner(System.in);//接收输入
String inputStr = in.next();
if (inputStr != null) {
messageVo.setMessage(inputStr);
sendSocketServer(JSONObject.toJSONString(messageVo), client);//发送消息
}
}
}
}
/**
* 接受信息线程,,运行在后台,,等待输入信息
*/
static class ReceiveThread extends Thread {
@Override
public void run() {
super.run();
try {
InputStream serverInputStream = client.getInputStream();
while (!client.isClosed() && serverInputStream != null) {//插入停止条件
ObjectInputStream ois = new ObjectInputStream(serverInputStream);
String inputStr = (String) ois.readObject();
//获取输出流,经过测试发现,输入流貌似是阻塞,,也就是没有输入时,
// 他就停在这里了一直等着输入所以无需加入Thread.sleep().
System.out.println(inputStr);
}
} catch (SocketException e) {
log.log(Level.INFO, "服务器断开连接!!!");
try {
client.close();//服务器断开连接此时需要关闭客户端连接
} catch (IOException e1) {
e1.printStackTrace();
}
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
}
}

View File

@@ -0,0 +1,94 @@
package com.im;
import com.alibaba.fastjson.JSONObject;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.util.HashMap;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* SocketServer 服务端
*/
public class SocketServer {
//用于保存客户端Socket
public static HashMap<Integer, Socket> clientSocketList = new HashMap<>();
public static HashMap<Integer, Integer> userPortList = new HashMap<>();
//服务器端口
public static final int port = 12345;
//服务器主机名
public static final String address = "127.0.0.1";
//服务器接收消息,以日志形式记录,动态
private static Logger log = Logger.getLogger("server");
public static void main(String[] args) throws IOException{
//创建ServerSocket监听
ServerSocket serverSocket = new ServerSocket(port);
log.log(Level.INFO, "服务器开启监听,端口:" + port);
while (true) {
Socket client = serverSocket.accept();//阻塞监听
new SocketDoWith(client).start();//创建线程对其进行操作
log.log(Level.INFO, "端口:" + client.getPort() + "接入服务器");
clientSocketList.put(client.getPort(), client);
}
}
//服务器处理客户端Socket消息线程
static class SocketDoWith extends Thread {
Logger log = Logger.getLogger("server");
private Socket socket = null;
public SocketDoWith(Socket socket) {
this.socket = socket;
}
public void run() {
if (socket == null) return;
try {
String readData;
while (!socket.isClosed()) {
//将输入封装成对象流(处理起来更方便)
ObjectInputStream oi = new ObjectInputStream(socket.getInputStream());
readData = (String) oi.readObject();
//将输入作为日志打印
log.log(Level.INFO, "服务器接收内容:" + readData);
int port = socket.getPort();
MessageVo messageVo = JSONObject.parseObject(readData, MessageVo.class);
//看发送者是否在, 不在的加进去
if(!userPortList.containsKey(messageVo.getFromId())){
userPortList.put(messageVo.getFromId(), port);
}
//在线操作
if(userPortList.containsKey(messageVo.getToId())){
Socket client = clientSocketList.get(userPortList.get(messageVo.getToId()));
//把信息输出到,当前连接的所有客户端。
if (!client.isClosed()) {//防止发现送消息给,,断连客户端。
ObjectOutputStream oos = new ObjectOutputStream(client.getOutputStream());
oos.writeObject(messageVo.getMessage());
oos.flush();
// log.log(Level.INFO, "服务器发送内容:" + messageVo.getMessage());//+ client.toString() + " "
} else {//断开的Socket就移除
clientSocketList.remove(port);//移除
log.log(Level.INFO, "服务器断开连接");
}
}
}
} catch (SocketException e) {
log.log(Level.INFO, "客户端断开连接!!!" + e.getMessage());
} catch (ClassNotFoundException | IOException e) {
log.log(Level.INFO, e.getMessage());
}
}
}
}

View File

@@ -0,0 +1,46 @@
package com.interceptor;
import com.alibaba.fastjson.JSONObject;
import com.common.CommonResult;
import com.utils.RequestUtil;
import com.zbkj.crmeb.system.service.SystemRoleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
//token验证拦截器
public class AdminAuthInterceptor implements HandlerInterceptor {
@Autowired
private SystemRoleService systemRoleService;
//程序处理之前需要处理的业务
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
response.setCharacterEncoding("UTF-8");
String uri = RequestUtil.getUri(request);
if(uri == null || uri.isEmpty()){
response.getWriter().write(JSONObject.toJSONString(CommonResult.forbidden()));
return false;
}
Boolean result = systemRoleService.checkAuth(uri);
//TODO 此处暂时放开
// if(!result){
// response.getWriter().write(JSONObject.toJSONString(CommonResult.forbidden()));
// return false;
// }
return true;
}
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {
}
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
}
}

View File

@@ -0,0 +1,48 @@
package com.interceptor;
import com.alibaba.fastjson.JSONObject;
import com.common.CheckAdminToken;
import com.common.CommonResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
//token验证拦截器 使用前注意需要一个@Bean手动注解否则注入无效
public class AdminTokenInterceptor implements HandlerInterceptor {
@Autowired
CheckAdminToken checkAdminToken;
//程序处理之前需要处理的业务
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
response.setCharacterEncoding("UTF-8");
String token = checkAdminToken.getTokenFormRequest(request);
if(token == null || token.isEmpty()){
response.getWriter().write(JSONObject.toJSONString(CommonResult.unauthorized()));
return false;
}
Boolean result = checkAdminToken.check(token);
if(!result){
response.getWriter().write(JSONObject.toJSONString(CommonResult.unauthorized()));
return false;
}
return true;
}
public void postHandle(HttpServletRequest request,
HttpServletResponse response, Object handler, ModelAndView modelAndView) {
}
public void afterCompletion(HttpServletRequest request,
HttpServletResponse response, Object handler, Exception ex) {
}
}

View File

@@ -0,0 +1,44 @@
package com.interceptor;
import com.alibaba.fastjson.JSONObject;
import com.common.CheckFrontToken;
import com.common.CommonResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
//token验证拦截器
public class FrontTokenInterceptor implements HandlerInterceptor {
@Autowired
private CheckFrontToken checkFrontToken;
//程序处理之前需要处理的业务
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
response.setCharacterEncoding("UTF-8");
String token = checkFrontToken.getTokenFormRequest(request);
if(token == null || token.isEmpty()){
response.getWriter().write(JSONObject.toJSONString(CommonResult.unauthorized()));
return false;
}
Boolean result = checkFrontToken.check(token);
if(!result){
response.getWriter().write(JSONObject.toJSONString(CommonResult.unauthorized()));
return false;
}
return true;
}
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {
}
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
}
}

View File

@@ -0,0 +1,68 @@
package com.interceptor;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import sun.misc.BASE64Decoder;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
public class SwaggerInterceptor extends HandlerInterceptorAdapter {
private String username;
private String password;
private Boolean check;
public SwaggerInterceptor(String username, String password, Boolean check) {
this.username = username;
this.password = password;
this.check = check;
}
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String authorization = request.getHeader("Authorization");
boolean isAuthSuccess = httpBasicAuth(authorization);
if (!isAuthSuccess) {
response.setCharacterEncoding("utf-8");
response.setStatus(401);
// response.setStatus(401,"Unauthorized");
response.setHeader("WWW-authenticate", "Basic realm=\"Realm\"");
try (PrintWriter writer = response.getWriter()) {
writer.print("Forbidden, unauthorized user");
}
}
return isAuthSuccess;
}
public boolean httpBasicAuth(String authorization) throws IOException {
if(check){
if (authorization != null && authorization.split(" ").length == 2) {
String userAndPass = new String(new BASE64Decoder().decodeBuffer(authorization.split(" ")[1]));
String username = userAndPass.split(":").length == 2 ? userAndPass.split(":")[0] : null;
String password = userAndPass.split(":").length == 2 ? userAndPass.split(":")[1] : null;
return this.username.equals(username) && this.password.equals(password);
}
return false;
}
return true;
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
String uri = request.getRequestURI();
AntPathMatcher pathMatcher = new AntPathMatcher();
if (!pathMatcher.match("/swagger-ui.html", uri) && !pathMatcher.match("/webjars/**", uri)) {
response.setStatus(404);
return;
}
ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
Resource[] resources = resolver.getResources("classpath:/META-INF/resources" + uri);
if (resources.length > 0) {
FileCopyUtils.copy(resources[0].getInputStream(), response.getOutputStream());
} else {
response.setStatus(404);
}
}
}

View File

@@ -0,0 +1,742 @@
package com.utils;
import com.alibaba.fastjson.JSONObject;
import com.constants.Constants;
import com.exception.CrmebException;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import javax.servlet.http.HttpServletRequest;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.nio.charset.StandardCharsets;
import java.security.Key;
import java.security.Security;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* @author stivepeim
* @title: CrmebUtil
* @projectName crmeb
* @Description: 工具类
* @since 2020/4/1414:37
*/
public class CrmebUtil {
public static String encryptPassword(String pwd, String key){
try {
Security.addProvider(new com.sun.crypto.provider.SunJCE());
Key _key = getDESSercretKey(key);
Cipher cipher = Cipher.getInstance("DES");
cipher.init(Cipher.ENCRYPT_MODE, _key);
byte[] data = pwd.getBytes(StandardCharsets.UTF_8);
byte[] result = cipher.doFinal(data);
return new sun.misc.BASE64Encoder().encode(result);
}catch (Exception e){
throw new CrmebException("密码处理异常");
}
}
/**
* 解密密码
*/
public static String decryptPassowrd(String pwd, String key)
throws Exception {
Security.addProvider(new com.sun.crypto.provider.SunJCE());
Key aKey = getDESSercretKey(key);
Cipher cipher = Cipher.getInstance("DES");
cipher.init(Cipher.DECRYPT_MODE, aKey);
byte[] data = new sun.misc.BASE64Decoder().decodeBuffer(pwd);
byte[] result = cipher.doFinal(data);
return new String(result, StandardCharsets.UTF_8);
}
/**
* 获得DES加密秘钥
* @param key
* @return
* @throws UnsupportedEncodingException
*/
public static SecretKey getDESSercretKey(String key) throws UnsupportedEncodingException {
byte[] result = new byte[8];
byte[] keys = null;
keys = key.getBytes(StandardCharsets.UTF_8);
for(int i = 0; i<8;i++){
if(i < keys.length){
result[i] = keys[i];
}else{
result[i] = 0x01;
}
}
return new SecretKeySpec(result, "DES");
}
/**
* 对象转map
* @param object 对象
* @author Mr.Zhang
* @since 2020-04-14
* @return Map
*/
public static Map objectToMap(Object object){
return JSONObject.parseObject(JSONObject.toJSONString(object), Map.class);
}
public static Map StringToMap(String strValue){
return JSONObject.parseObject(strValue, HashMap.class);
}
/**
* map转对象
* @param map map
* @param clz 对象
* @author Mr.Zhang
* @since 2020-04-14
* @return Map
*/
public static <T> T mapToObj(HashMap<String,Object> map, Class<T> clz){
if (map == null) return null;
return JSONObject.parseObject(JSONObject.toJSONString(map), clz);
}
/**
* map转对象
* @param map map
* @param clz 对象
* @author Mr.Zhang
* @since 2020-04-14
* @return Map
*/
public static <T> T mapStringToObj(HashMap<String,String> map, Class<T> clz){
if (map == null) return null;
return JSONObject.parseObject(JSONObject.toJSONString(map), clz);
}
/**
* 密码工具
* @param args String[] 字符串数组
*/
public static void main(String[] args) throws Exception {
System.out.println(encryptPassword("123456", "admin"));
// System.out.println(decryptPassowrd("L8qdg72wbeQ=", "admin"));
}
/**
* map合并
* @param map 对象
* @author Mr.Zhang
* @since 2020-04-14
* @return Object
*/
public static Map<String, Object> mergeMap(Map<String, Object> map, Map<String, Object> map1){
HashMap<String, Object> map2 = new HashMap<>();
map2.putAll(map);
map2.putAll(map1);
return map2;
}
/**
* 字符串分割,转化为数组
* @param str 字符串
* @author Mr.Zhang
* @since 2020-04-22
* @return List<Integer>
*/
public static List<Integer> stringToArray(String str){
return stringToArrayByRegex(str, ",");
}
/**
* 字符串分割,转化为数组
* @param str 字符串
* @param regex 分隔符有
* @author Mr.Zhang
* @since 2020-04-22
* @return List<Integer>
*/
public static List<Integer> stringToArrayByRegex(String str, String regex ){
List<Integer> list = new ArrayList<>();
if (str.contains(regex)){
String[] split = str.split(regex);
for (String value : split) {
if(!StringUtils.isBlank(value)){
list.add(Integer.parseInt(value.trim()));
}
}
}else {
list.add(Integer.parseInt(str));
}
return list;
}
/**
* 字符串分割,转化为数组
* @param str 字符串
* @author Mr.Zhang
* @since 2020-04-22
* @return List<String>
*/
public static List<String> stringToArrayStr(String str){
return stringToArrayStrRegex(str, ",");
}
/**
* 数字字符数据转int格式数据
* @param str 待转换的数字字符串
* @return int数组
*/
public static List<Integer> stringToArrayInt(String str){
List<String> strings = stringToArrayStrRegex(str, ",");
List<Integer> ids = new ArrayList<>();
for (String string : strings) {
ids.add(Integer.parseInt(string));
}
return ids;
}
/**
* 字符串分割,转化为数组
* @param str 字符串
* @param regex 分隔符有
* @author Mr.Zhang
* @since 2020-04-22
* @return List<String>
*/
public static List<String> stringToArrayStrRegex(String str, String regex ){
List<String> list = new ArrayList<>();
if (str.contains(regex)){
String[] split = str.split(regex);
for (String value : split) {
if(!StringUtils.isBlank(value)){
list.add(value);
}
}
}else {
list.add(str);
}
return list;
}
/**
* 字符串分割,转化为数组
* @param str 字符串
* @author Mr.Zhang
* @since 2020-04-22
* @return List<Object>
*/
public static List<Object> stringToArrayObject(String str){
return stringToArrayObjectRegex(str, ",");
}
/**
* 字符串分割,转化为数组
* @param str 字符串
* @param regex 分隔符有
* @author Mr.Zhang
* @since 2020-04-22
* @return List<Object>
*/
public static List<Object> stringToArrayObjectRegex(String str, String regex ){
List<Object> list = new ArrayList<>();
if (str.contains(regex)){
String[] split = str.split(regex);
for (String value : split) {
if(!StringUtils.isBlank(value)){
list.add(value);
}
}
}else {
list.add(str);
}
return list;
}
/**
* json字符串转数组
* @param str 字符串
* @author Mr.Zhang
* @since 2020-04-22
* @return List<String>
*/
public static List<String> jsonToListString(String str){
try{
return JSONObject.parseArray(str).toJavaList(String.class);
}catch (Exception e){
ArrayList<String> list = new ArrayList<>();
list.add(str);
return list;
}
}
/**
* json字符串转数组
* @param str 字符串
* @author Mr.Zhang
* @since 2020-04-22
* @return List<Integer>
*/
public static List<Integer> jsonToListInteger(String str){
try{
return JSONObject.parseArray(str).toJavaList(Integer.class);
}catch (Exception e){
ArrayList<Integer> list = new ArrayList<>();
list.add(Integer.parseInt(str));
return list;
}
}
/**
* json字符串转数组
* @param str 字符串
* @author Mr.Zhang
* @since 2020-04-22
* @return List<Integer>
*/
public static List<Object> jsonToListObject(String str){
try{
return JSONObject.parseArray(str).toJavaList(Object.class);
}catch (Exception e){
ArrayList<Object> list = new ArrayList<>();
list.add(str);
return list;
}
}
/**
* json字符串转数组
* @param str 字符串
* @author Mr.Zhang
* @since 2020-04-22
* @return List<T>
*/
public static <T> List<T> jsonToListClass(String str, Class<T> cls){
try{
return JSONObject.parseArray(str, cls);
}catch (Exception e){
return new ArrayList<>();
}
}
/**
* 去掉域名 https / http / www 信息
* @param domain 域名
* @author Mr.Zhang
* @since 2020-04-22
* @return String
*/
public static String getCleanLowerDomain(String domain){
domain = domain.toLowerCase();
domain = domain.replaceAll("http://", "");
domain = domain.replaceAll("https://", "");
domain = domain.replaceAll("www.", "");
domain = domain.replaceAll("/", "");
return domain;
}
/**
* 获取根域名
* @param domain 域名
* @author Mr.Zhang
* @since 2020-04-22
* @return String
*/
public static String getBaseLowerDomain(String domain){
if(!domain.contains(".")){
domain += ".com";
}
domain = getCleanLowerDomain(domain);
String[] split = domain.split("\\.");
int len = split.length;
if(len == 0){
return domain;
}
return split[len - 2] + "." + split[len - 1];
}
/**
* 获取客户端ip
* @param request 参数
* @author Mr.Zhang
* @since 2020-04-22
* @return String
*/
public static String getClientIp(HttpServletRequest request){
String ip = request.getHeader("X-Forwarded-For");
if(checkIsIp(ip)){
return ip;
}
ip = request.getHeader("X-Real-IP");
if(checkIsIp(ip)){
return ip;
}
ip = request.getRemoteAddr();
if(ip.equals("0:0:0:0:0:0:0:1")){
//本地 localhost访问 ipv6
ip = "127.0.0.1";
}
if(checkIsIp(ip)){
return ip;
}
return "";
}
/**
* 检测是否为ip
* @param ip 参数
* @author Mr.Zhang
* @since 2020-04-22
* @return String
*/
public static boolean checkIsIp(String ip){
if(StringUtils.isBlank(ip)){
return false;
}
if(ip.equals("unKnown")){
return false;
}
if(ip.equals("unknown")){
return false;
}
return ip.split("\\.").length == 4;
}
/**
* 获取fin_in_set拼装sql
* @param field String 字段
* @param value Integer 值
* @author Mr.Zhang
* @since 2020-04-22
* @return String
*/
public static String getFindInSetSql(String field, Integer value ){
return "find_in_set(" + value +", " + field + ")";
}
/**
* 获取fin_in_set拼装sql
* @param field String 字段
* @param list ArrayList<Integer> 值
* @author Mr.Zhang
* @since 2020-04-22
* @return String
*/
public static String getFindInSetSql(String field, ArrayList<Integer> list ){
ArrayList<String> sqlList = new ArrayList<>();
for (Integer value: list) {
sqlList.add(getFindInSetSql(field, value));
}
return "( " + StringUtils.join(sqlList, " or ") + ")";
}
/**
* 获取fin_in_set拼装sql
* @param field String 字段
* @param idStr String 多个值,逗号分割
* @author Mr.Zhang
* @since 2020-04-22
* @return String
*/
public static String getFindInSetSql(String field, String idStr ){
List<Integer> list = stringToArray(idStr);
ArrayList<String> sqlList = new ArrayList<>();
for (Integer value: list) {
sqlList.add(getFindInSetSql(field, value));
}
return "( " + StringUtils.join(sqlList, " or ") + ")";
}
/**
* 通过id获取分类名称
* @param list 分类集合
* @param categoryIdStr id字符串
* @author Mr.Zhang
* @since 2020-05-06
* @
*/
public static String getValueByIndex(HashMap<Integer, String> list, String categoryIdStr){
if(list.size() < 1 || StringUtils.isBlank(categoryIdStr)){
return "";
}
ArrayList<String> name = new ArrayList<>();
List<Integer> idList = CrmebUtil.stringToArray(categoryIdStr);
String str = "";
for (Integer id : idList) {
str = getStrValueByIndex(list, id);
if(!StringUtils.isBlank(str)){
name.add(getStrValueByIndex(list, id));
}
}
if(name.size() < 1){
return "";
}
return StringUtils.join(name, ",");
}
/**
* 通过id获取分类名称
* @param list 分类集合
* @param key id
* @author Mr.Zhang
* @since 2020-05-06
* @
*/
public static String getStrValueByIndex(HashMap<Integer, String> list, Integer key){
if(list.size() < 1){
return "";
}
return list.getOrDefault(key, "");
}
/**
* 通过id获取分类名称
* @param list 分类集合
* @param key id
* @author Mr.Zhang
* @since 2020-05-06
* @
*/
public static Integer getIntValueByIndex(HashMap<Integer, Integer> list, Integer key){
if(null == list ||list.size() < 1){
return 0;
}
return list.getOrDefault(key, 0);
}
/**
* 获取uuid
* @author Mr.Zhang
* @since 2020-05-06
* @
*/
public static String getUuid(){
return UUID.randomUUID().toString().replace("-", "");
}
/**
* 同比率计算 //同比增长率= ((当前周期 - 上一个周期) ÷ 上一个周期 ) *100%
* @param now 当前周期
* @param last 上一个周期
* @author Mr.Zhang
* @since 2020-05-06
* @
*/
public static String getRate(Integer now, Integer last){
int diff = now - last;
if(diff == 0){
return "0%";
}
return (((now - last) / last) * 100) + "%";
}
/**
* 同比率计算 //同比增长率= ((当前周期 - 上一个周期) ÷ 上一个周期 ) *100%
* @param now 当前周期
* @param last 上一个周期
* @author Mr.Zhang
* @since 2020-05-06
* @
*/
public static String getRate(BigDecimal now, BigDecimal last){
//计算差值
BigDecimal subtract = now.subtract(now);
BigDecimal zero = new BigDecimal(BigInteger.ZERO);
if(subtract.equals(zero)){
//数值一样,说明没有增长
return "0%";
}
// BigDecimal.setScale();//用于格式化小数点
// setScale(1);//表示保留以为小数,默认用四舍五入方式
// setScale(1,BigDecimal.ROUND_DOWN);//直接删除多余的小数位如2.35会变成2.3
// setScale(1,BigDecimal.ROUND_UP);//进位处理2.35变成2.4
// setScale(1,BigDecimal.ROUND_HALF_UP);//四舍五入2.35变成2.4
// setScaler(1,BigDecimal.ROUND_HALF_DOWN);//四舍五入2.35变成2.3如果是5则向下舍
return subtract.divide(last, 0, BigDecimal.ROUND_UP).multiply(new BigDecimal(100)) + "%";
}
/**
* hash 转换
* @param hash final byte[] hash参数
* @author Mr.Zhang
* @since 2020-06-03
* @return String
*/
public static String byteToHex(final byte[] hash) {
Formatter formatter = new Formatter();
for (byte b : hash) {
formatter.format("%02x", b);
}
String result = formatter.toString();
formatter.close();
return result;
}
/**
* hash 转换
* @param base64 String 图片流
* @author Mr.Zhang
* @since 2020-06-03
* @return String
*/
public static String getBase64Image(String base64) {
return "data:image/png;base64," + base64;
}
/**
* 去掉字符串第一位和最后一位
* @param param String 参数
* @return String
*/
public static String trimSingeQua(String param){
return param.substring(1,param.length()-1);
}
/**
* 根据长度生成随机数字
* @param start 起始数字
* @param end 结束数字
* @return 生成的随机码
*/
public static Integer randomCount(Integer start, Integer end){
return (int)(Math.random()*(end - start +1) + start);
}
/**
* 订单号生成
* @param payType String 支付类型
* @return 生成的随机码
*/
public static String getOrderNo(String payType){
return getOrderNoPrefix(payType) + DateUtil.nowDate(Constants.DATE_TIME_FORMAT_NUM) + randomCount(11111, 99999);
}
/**
* 订单号生成
* @param payType String 支付类型
* @return 生成的随机码
*/
public static String getOrderNoPrefix(String payType){
switch (payType){
case Constants.PAY_TYPE_WE_CHAT:
return Constants.ORDER_NO_PREFIX_WE_CHAT;
//其他平台
default:
return Constants.ORDER_NO_PREFIX_H5;
}
}
/**
* map排序
* @param map Map<String, Object> 支付类型
* @return 生成的随机码
*/
public static Map<String, Object> mapSort(Map<String, Object> map) {
return new TreeMap<>(map);
}
/**
* map排序然后按照url模式拼接
* @param map Map<String, Object> 支付类型
* @return 生成的随机码
*/
public static String mapToStringUrl(Map<String, Object> map){
map = CrmebUtil.mapSort(map);
StringBuilder sb = new StringBuilder(); // 多线程访问的情况下需要用StringBuffer
Set es = map.keySet(); // 所有参与传参的key按照accsii排序升序
for (Object set : es) {
String k = set.toString();
Object v = map.get(k);
sb.append(k).append("=").append(v.toString()).append("&");
}
String str = sb.toString();
return str.substring(0, str.length() - 1);
}
public static BigDecimal getBigDecimalRate(String rate) {
return new BigDecimal(rate).divide(BigDecimal.TEN.multiply(BigDecimal.TEN));
}
/**
* unicode编码转换为汉字
* @param unicodeStr 待转化的编码
* @return 返回转化后的汉子
*/
public static String UnicodeToCN(String unicodeStr) {
Pattern pattern = Pattern.compile("(\\\\u(\\p{XDigit}{4}))");
Matcher matcher = pattern.matcher(unicodeStr);
char ch;
while (matcher.find()) {
//group
String group = matcher.group(2);
//ch:'李四'
ch = (char) Integer.parseInt(group, 16);
//group1
String group1 = matcher.group(1);
unicodeStr = unicodeStr.replace(group1, ch + "");
}
return unicodeStr.replace("\\", "").trim();
}
/**
* 汉字转化为Unicode编码
* @param CN 待转化的中文
* @return 返回转化之后的unicode编码
*/
public static String CNToUnicode(String CN) {
try {
StringBuffer out = new StringBuffer("");
//直接获取字符串的unicode二进制
byte[] bytes = CN.getBytes("unicode");
//然后将其byte转换成对应的16进制表示即可
for (int i = 0; i < bytes.length - 1; i += 2) {
out.append("\\u");
String str = Integer.toHexString(bytes[i + 1] & 0xff);
for (int j = str.length(); j < 2; j++) {
out.append("0");
}
String str1 = Integer.toHexString(bytes[i] & 0xff);
out.append(str1);
out.append(str);
}
return out.toString();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
return null;
}
}
public static String getSign(Map<String, Object> map, String signKey){
String result = CrmebUtil.mapToStringUrl(map) + "&key=" + signKey;
return DigestUtils.md5Hex(result).toUpperCase();
}
}

View File

@@ -0,0 +1,521 @@
package com.utils;
import com.constants.Constants;
import com.exception.CrmebException;
import com.utils.vo.dateLimitUtilVo;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
/** excel操作类
* @author Mr.zhang
* @Description 日期时间类
* @since 2020-04-17
**/
public final class DateUtil {
private static final Logger LOGGER = LoggerFactory.getLogger(DateUtil.class);
private DateUtil() {
throw new IllegalStateException("Utility class");
}
/**
* 获取当前日期,指定格式
* 描述:<描述函数实现的功能>.
*
* @return
*/
public static String nowDate() {
return nowDate(Constants.DATE_FORMAT_NUM);
}
/**
* 获取当前年,指定格式
* 描述:<描述函数实现的功能>.
*
* @return
*/
public static String nowYear() {
Calendar cal = Calendar.getInstance();
return cal.get(Calendar.YEAR) + "";
}
/**
* 获取上一年,指定格式
* 描述:<描述函数实现的功能>.
*
* @return
*/
public static String lastYear() {
Calendar cal = Calendar.getInstance();
cal.add(Calendar.YEAR, -1);
return cal.get(Calendar.YEAR) + "";
}
/**
* 获取当前日期,指定格式
* 描述:<描述函数实现的功能>.
*
* @return
*/
public static Date nowDateTime() {
return strToDate(nowDateTimeStr(), Constants.DATE_FORMAT);
}
/**
* 获取当前日期,指定格式
* 描述:<描述函数实现的功能>.
*
* @return
*/
public static String nowDateTimeStr() {
return nowDate(Constants.DATE_FORMAT);
}
/**
* 获取当前日期,指定格式
* 描述:<描述函数实现的功能>.
*
* @return
*/
public static String nowDate(String DATE_FORMAT) {
SimpleDateFormat dft = new SimpleDateFormat(DATE_FORMAT);
return dft.format(new Date());
}
/**
* 获取当前日期,指定格式
* 描述:<描述函数实现的功能>.
*
* @return
*/
public static String nowDateTime(String DATE_FORMAT) {
SimpleDateFormat dft = new SimpleDateFormat(DATE_FORMAT);
return dft.format(new Date());
}
/**
* 获取当前日期,指定格式
* 描述:<描述函数实现的功能>.
*
* @return
*/
public static Integer getNowTime() {
long t = (System.currentTimeMillis()/1000L);
return Integer.parseInt(String.valueOf(t));
}
/**
* 获取当前日期,指定格式
* 描述:<描述函数实现的功能>.
*
* @return
*/
public static Long getTime() {
return (System.currentTimeMillis()/1000L);
}
/**
* 获取当前日期,指定格式
* 描述:<描述函数实现的功能>.
*
* @return
*/
public static Date nowDateTimeReturnDate(String DATE_FORMAT) {
SimpleDateFormat dft = new SimpleDateFormat(DATE_FORMAT);
return strToDate(dft.format(new Date()), DATE_FORMAT);
}
/**
* convert a date to string in a specifies fromat.
*
* @param date
* @param DATE_FORMAT
* @return
*/
public static String dateToStr(Date date, String DATE_FORMAT) {
if (date == null) {
return null;
}
SimpleDateFormat myFormat = new SimpleDateFormat(DATE_FORMAT);
return myFormat.format(date);
}
/**
* parse a String to Date in a specifies fromat.
*
* @param dateStr
* @param DATE_FORMAT
* @return
* @throws ParseException
*/
public static Date strToDate(String dateStr, String DATE_FORMAT) {
SimpleDateFormat myFormat = new SimpleDateFormat(DATE_FORMAT);
try {
return myFormat.parse(dateStr);
} catch (ParseException e) {
return null;
}
}
/**
* date add Second
*
* @param date
* @param num
* @return
*/
public static Date addSecond(Date date, int num) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.add(Calendar.SECOND, num);
return calendar.getTime();
}
/**
* date add Second return String
*
* @param date
* @param num
* @return
*/
public static String addSecond(Date date, int num, String DATE_FORMAT) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.add(Calendar.SECOND, num);
return dateToStr(calendar.getTime(), DATE_FORMAT);
}
/**
* 指定日期加上天数后的日期
*
* @param num 为增加的天数
* @param newDate 创建时间
* @return
*/
public static final String addDay(String newDate, int num, String pattern) {
SimpleDateFormat format = new SimpleDateFormat(pattern);
try {
Date currdate = format.parse(newDate);
Calendar ca = Calendar.getInstance();
ca.setTime(currdate);
ca.add(Calendar.DATE, num);
return format.format(ca.getTime());
} catch (ParseException e) {
LOGGER.error("转化时间出错,", e);
return null;
}
}
/**
* 指定日期加上天数后的日期
*
* @param num 为增加的天数
* @param newDate 创建时间
* @return
*/
public static final String addDay(Date newDate, int num, String pattern) {
SimpleDateFormat format = new SimpleDateFormat(pattern);
Calendar ca = Calendar.getInstance();
ca.setTime(newDate);
ca.add(Calendar.DATE, num);
return format.format(ca.getTime());
}
/**
* convert long to date
*
* @param dateLong
* @return
*/
public static Date longToDate(long dateLong) {
return new Date(dateLong);
}
/**
* convert long to date string
*
* @param dateLong
* @param DATE_FORMAT
* @return
*/
public static String longToDate(long dateLong, String DATE_FORMAT) {
return dateToStr(new Date(dateLong), DATE_FORMAT);
}
/**
* compare two date String with a pattern
*
* @param date1
* @param date2
* @param pattern
* @return
*/
public static int compareDate(String date1, String date2, String pattern) {
SimpleDateFormat DATE_FORMAT = new SimpleDateFormat(pattern);
try {
Date dt1 = DATE_FORMAT.parse(date1);
Date dt2 = DATE_FORMAT.parse(date2);
if (dt1.getTime() > dt2.getTime()) {
return 1;
} else if (dt1.getTime() < dt2.getTime()) {
return -1;
} else {
return 0;
}
} catch (ParseException e) {
e.printStackTrace();
return 0;
}
}
/**
* 检查日期格式是否合法
* @param date
* @param style
* @return
*/
public static boolean checkDateFormat(String date, String style) {
SimpleDateFormat DATE_FORMAT = new SimpleDateFormat(style);
try {
// 设置lenient为false.
// 否则SimpleDateFormat会比较宽松地验证日期比如2007/02/29会被接受并转换成2007/03/01
DATE_FORMAT.setLenient(false);
DATE_FORMAT.parse(date);
return true;
} catch (ParseException e) {
return false;
}
}
public static long getTwoDateDays(Date beforeDay, Date afterDay) {
SimpleDateFormat sm = new SimpleDateFormat(Constants.DATE_FORMAT_NUM);
long days = -1;
try {
days = (sm.parse(sm.format(afterDay)).getTime() - sm.parse(sm.format(beforeDay)).getTime()) / (1000 * 3600 * 24);
} catch (Exception e) {
e.printStackTrace();
}
return days;
}
//获取时间戳11位
public static int getSecondTimestamp(Date date){
if (null == date) {
return 0;
}
String timestamp = String.valueOf(date.getTime()/1000);
return Integer.parseInt(timestamp);
}
//获取时间戳11位
public static int getSecondTimestamp(String date){
if (null == date) {
return 0;
}
Date date1 = strToDate(date, Constants.DATE_FORMAT);
if(date1 == null){
return 0;
}
String timestamp = String.valueOf(date1.getTime()/1000);
return Integer.parseInt(timestamp);
}
//获取时间戳11位
public static int getSecondTimestamp(){
Date date = strToDate(nowDateTime(Constants.DATE_FORMAT), Constants.DATE_FORMAT);
if (null == date) {
return 0;
}
String timestamp = String.valueOf(date.getTime()/1000);
return Integer.parseInt(timestamp);
}
/** 获得昨天日期:yyyy-MM-dd HH:mm:ss */
public static String getYesterdayStr() {
Calendar c = Calendar.getInstance();
c.add(Calendar.DATE, -1);
SimpleDateFormat startSdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
return startSdf.format(c.getTime());
}
/** 获得本周第一天:yyyy-MM-dd HH:mm:ss */
public static String getWeekStartDay() {
Calendar c = Calendar.getInstance();
c.add(Calendar.WEEK_OF_MONTH, 0);
c.set(Calendar.DAY_OF_WEEK, 2);
SimpleDateFormat startSdf = new SimpleDateFormat("yyyy-MM-dd 00:00:00");
return startSdf.format(c.getTime());
}
/** 获得本周最后一天:yyyy-MM-dd HH:mm:ss */
public static String getWeekEndDay() {
return addDay(getWeekStartDay(), 7, Constants.DATE_FORMAT);
}
/** 获得上周第一天:yyyy-MM-dd HH:mm:ss */
public static String getLastWeekStartDay() {
return addDay(getWeekStartDay(), -7, Constants.DATE_FORMAT);
}
/** 获得上周最后一天:yyyy-MM-dd HH:mm:ss */
public static String getLastWeekEndDay() {
return addDay(getLastWeekStartDay(), 7, Constants.DATE_FORMAT);
}
/** 获得本月最后一天:yyyy-MM-dd HH:mm:ss */
public static String getMonthEndDay() {
Calendar c = Calendar.getInstance();
c.set(Calendar.DAY_OF_MONTH, c.getActualMaximum(Calendar.DAY_OF_MONTH));
SimpleDateFormat endSdf = new SimpleDateFormat("yyyy-MM-dd 23:59:59");
return endSdf.format(c.getTime());
}
/** 获得上月第一天:yyyy-MM-dd HH:mm:ss */
public static String getLastMonthStartDay() {
Calendar c = Calendar.getInstance();
c.add(Calendar.MONTH, -1);
c.set(Calendar.DAY_OF_MONTH, 1);
SimpleDateFormat startSdf = new SimpleDateFormat("yyyy-MM-01 00:00:00");
return startSdf.format(c.getTime());
}
/** 获得上月最后一天:yyyy-MM-dd HH:mm:ss */
public static String getLastMonthEndDay() {
Calendar c = Calendar.getInstance();
c.add(Calendar.MONTH, -1);
c.set(Calendar.DAY_OF_MONTH, c.getActualMaximum(Calendar.DAY_OF_MONTH));
SimpleDateFormat endSdf = new SimpleDateFormat("yyyy-MM-dd 23:59:59");
return endSdf.format(c.getTime());
}
/** 获得上年第一天:yyyy-MM-dd HH:mm:ss */
public static String getLastYearStartDay() {
Calendar c = Calendar.getInstance();
c.add(Calendar.YEAR, -1);
SimpleDateFormat startSdf = new SimpleDateFormat("yyyy-01-01 00:00:00");
return startSdf.format(c.getTime());
}
/** 获得上年最后一天:yyyy-MM-dd HH:mm:ss */
public static String getLastYearEndDay() {
Calendar c = Calendar.getInstance();
c.add(Calendar.YEAR, -1);
SimpleDateFormat endSdf = new SimpleDateFormat("yyyy-12-31 23:59:59");
return endSdf.format(c.getTime());
}
/**
* 计算时间范围
* @param data string 类型
* @author Mr.Zhang
* @since 2020-05-06
* @return dateLimitUtilVo
*/
public static dateLimitUtilVo getDateLimit(String data){
//时间计算
String startTime = null;
String endTime = DateUtil.nowDateTime(Constants.DATE_FORMAT);
String day = DateUtil.nowDateTime(Constants.DATE_FORMAT_START);
String end = DateUtil.nowDateTime(Constants.DATE_FORMAT_END);
if(!StringUtils.isBlank(data)){
switch (data){
case Constants.SEARCH_DATE_DAY:
startTime = day;
break;
case Constants.SEARCH_DATE_YESTERDAY:
startTime = DateUtil.addDay(day, -1, Constants.DATE_FORMAT_START);
endTime = DateUtil.addDay(end, -1, Constants.DATE_FORMAT_END);
break;
case Constants.SEARCH_DATE_LATELY_7:
startTime = DateUtil.addDay(day, -7, Constants.DATE_FORMAT_START);
break;
case Constants.SEARCH_DATE_WEEK:
startTime = getWeekStartDay();
endTime = getWeekEndDay();
break;
case Constants.SEARCH_DATE_PRE_WEEK:
startTime = getLastWeekStartDay();
endTime = getLastWeekEndDay();
break;
case Constants.SEARCH_DATE_LATELY_30:
startTime = DateUtil.addDay(day, -30, Constants.DATE_FORMAT_START);
break;
case Constants.SEARCH_DATE_MONTH:
startTime = DateUtil.nowDateTime(Constants.DATE_FORMAT_MONTH_START);
endTime = getMonthEndDay();
break;
case Constants.SEARCH_DATE_PRE_MONTH:
startTime = getLastMonthStartDay();
endTime = getLastMonthEndDay();
break;
case Constants.SEARCH_DATE_YEAR:
startTime = DateUtil.nowDateTime(Constants.DATE_FORMAT_YEAR_START);
endTime = DateUtil.nowDateTime(Constants.DATE_FORMAT_YEAR_END);
break;
case Constants.SEARCH_DATE_PRE_YEAR:
startTime = getLastYearStartDay();
endTime = getLastYearEndDay();
break;
default:
List<String> list = CrmebUtil.stringToArrayStr(data);
if(list.size() == 1){
throw new CrmebException("选择时间参数格式错误,请在 " +
Constants.SEARCH_DATE_DAY + "|" +
Constants.SEARCH_DATE_YESTERDAY + "|" +
Constants.SEARCH_DATE_LATELY_7 + "|" +
Constants.SEARCH_DATE_LATELY_30 + "|" +
Constants.SEARCH_DATE_MONTH + "|" +
Constants.SEARCH_DATE_YEAR + "|自定义时间范围格式yyyy-MM-dd HH:mm:ss两个时间范围用逗号分割");
}
startTime = list.get(0);
endTime = list.get(1);
break;
}
}
return new dateLimitUtilVo(startTime, endTime);
}
/**
* 获取某一时间段内的时间集合
* @param data string 类型
* @author Mr.Zhang
* @since 2020-05-06
* @return List<Date>
*/
public static List<String> getListDate(String data) {
//获取30天的开始结束日期
dateLimitUtilVo dateLimit = DateUtil.getDateLimit(data);
//定义日期集合
List<String> date = new ArrayList<>();
//开始日期
Date startDate = DateUtil.strToDate(dateLimit.getStartTime(), Constants.DATE_FORMAT);
//结束日期
Date endDate = DateUtil.strToDate(dateLimit.getEndTime(), Constants.DATE_FORMAT);
while (endDate.after(startDate)){
date.add(DateUtil.dateToStr(startDate, Constants.DATE_FORMAT_DATE)); // 放入集合
startDate = DateUtil.strToDate(DateUtil.addDay(startDate, 1, Constants.DATE_FORMAT), Constants.DATE_FORMAT); //循环一次 加一天
}
return date;
}
}

View File

@@ -0,0 +1,354 @@
package com.utils;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.constants.Constants;
import com.zbkj.crmeb.export.vo.ExcelColumn;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.CharUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.MediaType;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/** excel操作类
* @author Mr.zhang
* @since 2020-04-17
**/
public class ExcelUtil {
private final static Logger log = LoggerFactory.getLogger(ExcelUtil.class);
private final static String EXCEL2003 = "xls";
private final static String EXCEL2007 = "xlsx";
private static String sheetName;
public static String getSheetName() {
return sheetName;
}
public static void setSheetName(String sheetName) {
ExcelUtil.sheetName = sheetName;
}
public static String getFileName() {
return fileName;
}
public static void setFileName(String fileName) {
ExcelUtil.fileName = fileName;
}
private static String fileName;
public static <T> List<T> readExcel(String path, Class<T> cls, MultipartFile file){
String fileName = file.getOriginalFilename();
if (!fileName.matches("^.+\\.(?i)(xls)$") && !fileName.matches("^.+\\.(?i)(xlsx)$")) {
log.error("上传文件格式不正确");
}
List<T> dataList = new ArrayList<>();
Workbook workbook = null;
try {
InputStream is = file.getInputStream();
if (fileName.endsWith(EXCEL2007)) {
// FileInputStream is = new FileInputStream(new File(path));
workbook = new XSSFWorkbook(is);
}
if (fileName.endsWith(EXCEL2003)) {
// FileInputStream is = new FileInputStream(new File(path));
workbook = new HSSFWorkbook(is);
}
if (workbook != null) {
//类映射 注解 value-->bean columns
Map<String, List<Field>> classMap = new HashMap<>();
List<Field> fields = Stream.of(cls.getDeclaredFields()).collect(Collectors.toList());
fields.forEach(
field -> {
ExcelColumn annotation = field.getAnnotation(ExcelColumn.class);
if (annotation != null) {
String value = annotation.value();
if (StringUtils.isBlank(value)) {
return;//return起到的作用和continue是相同的 语法
}
if (!classMap.containsKey(value)) {
classMap.put(value, new ArrayList<>());
}
field.setAccessible(true);
classMap.get(value).add(field);
}
}
);
//索引-->columns
Map<Integer, List<Field>> reflectionMap = new HashMap<>(16);
//默认读取第一个sheet
Sheet sheet = workbook.getSheetAt(0);
boolean firstRow = true;
for (int i = sheet.getFirstRowNum(); i <= sheet.getLastRowNum(); i++) {
Row row = sheet.getRow(i);
//首行 提取注解
if (firstRow) {
for (int j = row.getFirstCellNum(); j <= row.getLastCellNum(); j++) {
Cell cell = row.getCell(j);
String cellValue = getCellValue(cell);
if (classMap.containsKey(cellValue)) {
reflectionMap.put(j, classMap.get(cellValue));
}
}
firstRow = false;
} else {
//忽略空白行
if (row == null) {
continue;
}
try {
T t = cls.newInstance();
//判断是否为空白行
boolean allBlank = true;
for (int j = row.getFirstCellNum(); j <= row.getLastCellNum(); j++) {
if (reflectionMap.containsKey(j)) {
Cell cell = row.getCell(j);
String cellValue = getCellValue(cell);
if (StringUtils.isNotBlank(cellValue)) {
allBlank = false;
}
List<Field> fieldList = reflectionMap.get(j);
fieldList.forEach(
x -> {
try {
handleField(t, cellValue, x);
} catch (Exception e) {
log.error(String.format("reflect field:%s value:%s exception!", x.getName(), cellValue), e);
}
}
);
}
}
if (!allBlank) {
dataList.add(t);
} else {
log.warn(String.format("row:%s is blank ignore!", i));
}
} catch (Exception e) {
log.error(String.format("parse row:%s exception!", i), e);
}
}
}
}
} catch (Exception e) {
log.error(String.format("parse excel exception!"), e);
} finally {
if (workbook != null) {
try {
workbook.close();
} catch (Exception e) {
log.error(String.format("parse excel exception!"), e);
}
}
}
return dataList;
}
private static <T> void handleField(T t, String value, Field field) throws Exception {
Class<?> type = field.getType();
if (type == null || type == void.class || StringUtils.isBlank(value)) {
return;
}
if (type == Object.class) {
field.set(t, value);
//数字类型
} else if (type.getSuperclass() == null || type.getSuperclass() == Number.class) {
if (type == int.class || type == Integer.class) {
field.set(t, NumberUtils.toInt(value));
} else if (type == long.class || type == Long.class) {
field.set(t, NumberUtils.toLong(value));
} else if (type == byte.class || type == Byte.class) {
field.set(t, NumberUtils.toByte(value));
} else if (type == short.class || type == Short.class) {
field.set(t, NumberUtils.toShort(value));
} else if (type == double.class || type == Double.class) {
field.set(t, NumberUtils.toDouble(value));
} else if (type == float.class || type == Float.class) {
field.set(t, NumberUtils.toFloat(value));
} else if (type == char.class || type == Character.class) {
field.set(t, CharUtils.toChar(value));
} else if (type == boolean.class) {
field.set(t, BooleanUtils.toBoolean(value));
} else if (type == BigDecimal.class) {
field.set(t, new BigDecimal(value));
}
} else if (type == Boolean.class) {
field.set(t, BooleanUtils.toBoolean(value));
} else if (type == Date.class) {
//
field.set(t, value);
} else if (type == String.class) {
field.set(t, value);
} else {
Constructor<?> constructor = type.getConstructor(String.class);
field.set(t, constructor.newInstance(value));
}
}
private static String getCellValue(Cell cell) {
if (cell == null) {
return "";
}
if (cell.getCellType() == Cell.CELL_TYPE_NUMERIC) {
// if (DateUtil.checkDateFormat(cell.getNumericCellValue() + "", Constants.DATE_TIME_FORMAT_NUM)) {
// return HSSFDateUtil.getJavaDate(cell.getNumericCellValue()).toString();
// } else {
// return new BigDecimal(cell.getNumericCellValue()).toString();
// }
return cell.getNumericCellValue() + "";
} else if (cell.getCellType() == Cell.CELL_TYPE_STRING) {
return StringUtils.trimToEmpty(cell.getStringCellValue());
} else if (cell.getCellType() == Cell.CELL_TYPE_FORMULA) {
return StringUtils.trimToEmpty(cell.getCellFormula());
} else if (cell.getCellType() == Cell.CELL_TYPE_BLANK) {
return "";
} else if (cell.getCellType() == Cell.CELL_TYPE_BOOLEAN) {
return String.valueOf(cell.getBooleanCellValue());
} else if (cell.getCellType() == Cell.CELL_TYPE_ERROR) {
return "ERROR";
} else {
return cell.toString().trim();
}
}
public static <T> void writeExcel(HttpServletResponse response, List<T> dataList, Class<T> cls){
Field[] fields = cls.getDeclaredFields();
List<Field> fieldList = Arrays.stream(fields)
.filter(field -> {
ExcelColumn annotation = field.getAnnotation(ExcelColumn.class);
if (annotation != null && annotation.col() > 0) {
field.setAccessible(true);
return true;
}
return false;
}).sorted(Comparator.comparing(field -> {
int col = 0;
ExcelColumn annotation = field.getAnnotation(ExcelColumn.class);
if (annotation != null) {
col = annotation.col();
}
return col;
})).collect(Collectors.toList());
Workbook wb = new XSSFWorkbook();
Sheet sheet = wb.createSheet(getSheetName());
AtomicInteger ai = new AtomicInteger();
{
Row row = sheet.createRow(ai.getAndIncrement());
AtomicInteger aj = new AtomicInteger();
//写入头部
fieldList.forEach(field -> {
ExcelColumn annotation = field.getAnnotation(ExcelColumn.class);
String columnName = "";
if (annotation != null) {
columnName = annotation.value();
}
Cell cell = row.createCell(aj.getAndIncrement());
CellStyle cellStyle = wb.createCellStyle();
cellStyle.setFillForegroundColor(IndexedColors.WHITE.getIndex());
cellStyle.setFillPattern(CellStyle.SOLID_FOREGROUND);
cellStyle.setAlignment(CellStyle.ALIGN_CENTER);
Font font = wb.createFont();
font.setBoldweight(Font.BOLDWEIGHT_NORMAL);
cellStyle.setFont(font);
cell.setCellStyle(cellStyle);
cell.setCellValue(columnName);
});
}
if (CollectionUtils.isNotEmpty(dataList)) {
dataList.forEach(t -> {
Row row1 = sheet.createRow(ai.getAndIncrement());
AtomicInteger aj = new AtomicInteger();
fieldList.forEach(field -> {
Class<?> type = field.getType();
Object value = "";
try {
value = field.get(t);
} catch (Exception e) {
e.printStackTrace();
}
Cell cell = row1.createCell(aj.getAndIncrement());
if (value != null) {
if (type == Date.class) {
cell.setCellValue(value.toString());
} else {
cell.setCellValue(value.toString());
}
cell.setCellValue(value.toString());
}
});
});
}
//冻结窗格
wb.getSheet(getSheetName()).createFreezePane(0, 1, 0, 1);
//浏览器下载excel
buildExcelDocument(getFileName() + "_" + DateUtil.nowDate(Constants.DATE_TIME_FORMAT_NUM) +".xlsx", wb, response);
//生成excel文件
// buildExcelFile(".\\default.xlsx",wb);
}
/**
* 浏览器下载excel
* @param fileName
* @param wb
* @param response
*/
private static void buildExcelDocument(String fileName, Workbook wb,HttpServletResponse response){
try {
response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
response.setHeader("Content-Disposition", "attachment;filename="+URLEncoder.encode(fileName, "utf-8"));
response.flushBuffer();
wb.write(response.getOutputStream());
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 生成excel文件
* @param path 生成excel路径
* @param wb
*/
private static void buildExcelFile(String path, Workbook wb){
File file = new File(path);
if (file.exists()) {
file.delete();
}
try {
wb.write(new FileOutputStream(file));
} catch (Exception e) {
e.printStackTrace();
}
}
}

View File

@@ -0,0 +1,140 @@
package com.utils;
import com.constants.Constants;
import com.exception.CrmebException;
import com.utils.vo.ImageMergeUtilVo;
import lombok.Data;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import java.awt.*;
import java.io.*;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.net.URL;
import java.net.URLConnection;
import java.util.List;
@Data
@Component
public class ImageMergeUtil {
public static BufferedImage bufferedImage; //背景图片
public static String model = "merge";
public static String ext = "jpg";
/**
* 合并生成新的图片文件
* @param list List<ImageMergeUtilVo> 图片集合
* @author Mr.Zhang
* @since 2020-05-06
*/
public static String drawWordFile(List<ImageMergeUtilVo> list){
buildImage(list);
if(bufferedImage == null){
return null;
}
try {
UploadUtil.setModelPath(model);
UploadUtil.setExtStr(ext);
UploadUtil.setType(Constants.UPLOAD_TYPE_IMAGE);
//文件名
String newFileName = UploadUtil.fileName(ext);
// 创建目标文件的名称规则请看destPath方法
String destPath = UploadUtil.getDestPath(newFileName);
// 创建文件
File file = UploadUtil.createFile(destPath);
ImageIO.write(bufferedImage, ext, file);
return destPath;
} catch (IOException ex) {
ex.printStackTrace();
}
return null;
}
private static void drawImage(ImageMergeUtilVo imageMergeUtilVo){
String fileName = getFileSource(imageMergeUtilVo.getPath());
if(StringUtils.isBlank(fileName)){
return;
}
try{
File file = new File(fileName);
BufferedImage read = ImageIO.read(file);
if(bufferedImage == null || bufferedImage.equals("")){
imageMergeUtilVo.setX(0);
imageMergeUtilVo.setY(0);
//创建新的画布,宽高以第一个图为准
bufferedImage = new BufferedImage(read.getWidth(), read.getHeight(), BufferedImage.TYPE_INT_BGR);
}
Graphics graphics = bufferedImage.getGraphics();
//在画布上绘制背景图
graphics.drawImage(read, imageMergeUtilVo.getX(), imageMergeUtilVo.getX(), read.getWidth(), read.getHeight(), null);
file.delete();
}catch (Exception e){
//合成图片xx失败
throw new CrmebException("合成图片 + " + fileName + "失败");
}
}
/**
* 合并生成新的图片流
* @param list List<ImageMergeUtilVo> 图片集合
* @author Mr.Zhang
* @since 2020-05-06
*/
private static void buildImage(List<ImageMergeUtilVo> list){
if(list.size() < 2){
throw new CrmebException("至少需要2张图片才可以做合并");
}
for (ImageMergeUtilVo imageMergeUtilVo : list) {
drawImage(imageMergeUtilVo);
}
}
/**
* 根据图片路径输出File流
* @param url String 文件地址
* @author Mr.Zhang
* @since 2020-05-06
*/
private static String getFileSource(String url){
if(!url.contains("http")){
return url;
}
try {
URL urlInfo = new URL(url);
// 打开连接
URLConnection con = urlInfo.openConnection();
// 输入流
InputStream is = con.getInputStream();
// 1K的数据缓冲
byte[] bs = new byte[1024];
// 读取到的数据长度
int len;
String fileName = UploadUtil.fileName(ext);
// 输出的文件流
OutputStream os = new FileOutputStream(fileName);
// 开始读取
while ((len = is.read(bs)) != -1) {
os.write(bs, 0, len);
}
// 完毕,关闭所有链接
os.close();
is.close();
return fileName;
}catch (Exception e){
e.printStackTrace();
}
return null;
}
}

View File

@@ -0,0 +1,62 @@
package com.utils;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.QRCodeWriter;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import org.apache.commons.codec.binary.Base64;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.HashMap;
/**
* @description:
* @author: Administrator
* @date: 2019-03-18 10:40
*/
@Component
public class QRCodeUtil {
public static String crateQRCode(String content, int width, int height) throws IOException {
String resultImage = "";
if (!StringUtils.isEmpty(content)) {
ServletOutputStream stream = null;
ByteArrayOutputStream os = new ByteArrayOutputStream();
@SuppressWarnings("rawtypes")
HashMap<EncodeHintType, Comparable> hints = new HashMap<>();
hints.put(EncodeHintType.CHARACTER_SET, "utf-8"); // 指定字符编码为“utf-8”
hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H); // 指定二维码的纠错等级为中级
hints.put(EncodeHintType.MARGIN, 2); // 设置图片的边距
try {
QRCodeWriter writer = new QRCodeWriter();
BitMatrix bitMatrix = writer.encode(content, BarcodeFormat.QR_CODE, width, height, hints);
BufferedImage bufferedImage = MatrixToImageWriter.toBufferedImage(bitMatrix);
ImageIO.write(bufferedImage, "png", os);
/**
* 原生转码前面没有 data:image/png;base64 这些字段,返回给前端是无法被解析,可以让前端加,也可以在下面加上
*/
return CrmebUtil.getBase64Image(Base64.encodeBase64String(os.toByteArray()));
} catch (Exception e) {
e.printStackTrace();
} finally {
if (stream != null) {
stream.flush();
stream.close();
}
}
}
return null;
}
}

View File

@@ -0,0 +1,292 @@
package com.utils;
import java.io.Serializable;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.ListOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.SetOperations;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.stereotype.Component;
/**
* redis工具类
* @author Mr.Zhang
* @since 2020-04-13
*/
@Component
public class RedisUtil {
@Autowired
private RedisTemplate redisTemplate;
/**
* 写入缓存
* @param key string key
* @param value string value
* @author Mr.Zhang
* @since 2020-04-13
* @return bool
*/
public boolean set(final String key, Object value) {
boolean result = false;
try {
ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();
operations.set(key, value);
result = true;
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
/**
* 写入缓存带有效期
* @param key string key
* @param value string value
* @param expireTime Long 过期时间
* @param timeUnit TimeUnit 时间格式
* @author Mr.Zhang
* @since 2020-04-13
* @return bool
*/
public boolean set(final String key, Object value, Long expireTime, TimeUnit timeUnit) {
boolean result = false;
try {
ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();
operations.set(key, value);
redisTemplate.expire(key, expireTime, timeUnit);
result = true;
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
/**
* 批量删除对应的value
* @param keys string key
* @author Mr.Zhang
* @since 2020-04-13
*/
public void remove(final String... keys) {
for (String key : keys) {
remove(key);
}
}
/**
* 批量删除key
* @param pattern string key
* @author Mr.Zhang
* @since 2020-04-13
*/
public void removePattern(final String pattern) {
Set<Serializable> keys = redisTemplate.keys(pattern);
if (keys.size() > 0) {
redisTemplate.delete(keys);
}
}
/**
* 删除对应的value
* @param key string key
* @author Mr.Zhang
* @since 2020-04-13
*/
public void remove(final String key) {
if (exists(key)) {
redisTemplate.delete(key);
}
}
/**
* 判断缓存中是否有对应的value
* @param key string key
* @author Mr.Zhang
* @since 2020-04-13
* @return bool
*/
public boolean exists(final String key) {
return redisTemplate.hasKey(key);
}
/**
* 读取缓存
* @param key string key
* @author Mr.Zhang
* @since 2020-04-13
* @return Object
*/
public Object get(final String key) {
Object result = null;
ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();
result = operations.get(key);
return result;
}
/**
* 哈希 添加
*
* @param key
* @param hashKey
* @param value
*/
/**
* 哈希添加
* @param key string key
* @param hashKey Object hashKey
* @param value Object value
* @author Mr.Zhang
* @since 2020-04-13
*/
public void hmSet(String key, Object hashKey, Object value) {
HashOperations<String, Object, Object> hash = redisTemplate.opsForHash();
hash.put(key, hashKey, value);
}
/**
* 哈希删除
* @param key string key
* @param hashKey Object hashKey
* @author Mr.Zhang
* @since 2020-04-13
*/
public void hmDelete(String key, Object hashKey) {
HashOperations<String, Object, Object> hash = redisTemplate.opsForHash();
hash.delete(key, hashKey);
}
/**
* 哈希获取数据
* @param key string key
* @param hashKey Object hashKey
* @author Mr.Zhang
* @return Object
* @since 2020-04-13
*/
public Object hmGet(String key, Object hashKey) {
HashOperations<String, Object, Object> hash = redisTemplate.opsForHash();
return hash.get(key, hashKey);
}
/**
* 列表添加左边添加
* @param k string key
* @param v Object v
* @author Mr.Zhang
* @since 2020-04-13
*/
public void lPush(String k, Object v) {
ListOperations<String, Object> list = redisTemplate.opsForList();
list.leftPush(k, v);
}
/**
* 从右边拿出来一个
* @param k string key
* @param t Long 超时秒数
* @author Mr.Zhang
* @since 2020-04-13
*/
public Object getRightPop(String k, Long t){
return redisTemplate.opsForList().rightPop(k, t, TimeUnit.SECONDS);
}
/**
* 列表获取数量
* @param k string key
* @author Mr.Zhang
* @since 2020-04-13
* @return Long
*/
public Long getListSize(String k) {
return redisTemplate.opsForList().size(k);
}
/**
* 列表获取
* @param k string key
* @param l long l
* @param l1 long l1
* @author Mr.Zhang
* @since 2020-04-13
* @return List<Object>
*/
public List<Object> lRange(String k, long l, long l1) {
ListOperations<String, Object> list = redisTemplate.opsForList();
return list.range(k, l, l1);
}
/**
* 集合添加
* @param key string key
* @param value Object value
* @author Mr.Zhang
* @since 2020-04-13
*/
public void add(String key, Object value) {
SetOperations<String, Object> set = redisTemplate.opsForSet();
set.add(key, value);
}
/**
* 集合获取
* @param key string key
* @author Mr.Zhang
* @since 2020-04-13
* @return Set<Object>
*/
public Set<Object> setMembers(String key) {
SetOperations<String, Object> set = redisTemplate.opsForSet();
return set.members(key);
}
/**
* 有序集合添加
*
* @param key
* @param value
* @param scoure
*/
/**
* 有序集合添加 排行榜使用
* @param key string key
* @param value Object value
* @param score double scoure
* @author Mr.Zhang
* @since 2020-04-13
*/
public void zAdd(String key, Object value, double score) {
ZSetOperations<String, Object> zset = redisTemplate.opsForZSet();
zset.add(key, value, score);
}
/**
* 有序集合获取 排行榜使用
* @param key string key
* @param score double scoure
* @author Mr.Zhang
* @since 2020-04-13
* @return Set<Object>
*/
public Set<Object> rangeByScore(String key, double score, double score1) {
ZSetOperations<String, Object> zset = redisTemplate.opsForZSet();
return zset.rangeByScore(key, score, score1);
}
}

View File

@@ -0,0 +1,93 @@
package com.utils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Objects;
public class RequestUtil extends HttpServlet{
public static HttpServletRequest getRequest() {
if(RequestContextHolder.getRequestAttributes() != null){
return ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();
}
return null;
}
public static HashMap<String, Object> getRequestParamAndHeader(){
try{
HttpServletRequest request = getRequest();
if(request == null){
return null;
}
//request信息
HashMap<String, Object> data = new HashMap<>();
HashMap<String, Object> requestParams = new HashMap<>();
Enumeration<String> paraNames = request.getParameterNames();
if(paraNames != null){
for(Enumeration<String> enumeration =paraNames;enumeration.hasMoreElements();){
String key= enumeration.nextElement();
requestParams.put(key, request.getParameter(key));
}
}
HashMap<String, Object> requestFilter = new HashMap<>();
Enumeration<String> attributeNames = request.getAttributeNames();
if(attributeNames != null){
for ( Enumeration<String> attributeNames1 = attributeNames; attributeNames1.hasMoreElements();) {
String key= attributeNames1.nextElement();
if(key.contains("request_")){
requestFilter.put(key, request.getAttribute(key));
}
}
}
data.put("url", request.getRequestURL());
data.put("uri", request.getRequestURI());
data.put("method", request.getMethod());
data.put("request", requestParams);
data.put("request_filter", requestFilter);
//header 信息
Enumeration<String> headerNames = request.getHeaderNames();
HashMap<String, Object> headerParams = new HashMap<>();
if(headerNames != null){
for(Enumeration<String> enumeration = headerNames;enumeration.hasMoreElements();){
String key= enumeration.nextElement();
String value=request.getHeader(key);
headerParams.put(key, value);
}
}
data.put("header", headerParams);
return data;
}catch (Exception e){
e.printStackTrace();
return null;
}
}
public static String getDomain(){
HttpServletRequest request = getRequest();
if(request == null){
return null;
}
return request.getServerName() + ":" + request.getServerPort();
}
public static String getUri(HttpServletRequest request){
String uri = request.getRequestURI();
List<String> list = CrmebUtil.stringToArrayStrRegex(uri, "/");
list.removeIf(StringUtils::isNumeric);
return StringUtils.join(list, "/");
}
}

View File

@@ -0,0 +1,317 @@
package com.utils;
import com.alibaba.fastjson.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.*;
import org.springframework.stereotype.Component;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
/**
* httpClient 工具类
* @author Mr.Zhang
* @since 2020-04-13
*/
@Component
public class RestTemplateUtil {
@Autowired
private RestTemplate restTemplate;
/**
* 发送GET请求
* @param url
* @param param
* @return
*/
public String getData(String url, Map<String, String> param) {
// 请勿轻易改变此提交方式,大部分的情况下,提交方式都是表单提交
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
return restTemplate.getForEntity(url, String.class, param).getBody();
}
/**
* 发送GET请求
* @param url
* @return
*/
public String getLink(String url) {
return restTemplate.getForEntity(url, String.class).getBody();
}
/**
* 发送GET请求
* @param url
* @return
*/
public JSONObject getData(String url) {
HttpHeaders headers = new HttpHeaders();
headers.add("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36");
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<Map<String, Object>> requestEntity =
new HttpEntity<>( headers);
return restTemplate.exchange( url, HttpMethod.GET, requestEntity, JSONObject.class).getBody();
}
/**
* 发送GET请求 支持header
* @param url
* @return
*/
public JSONObject getData(String url, HashMap<String, String> hashMap) {
HttpHeaders headers = new HttpHeaders();
headers.add("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36");
headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
for (Map.Entry<String, String> entry : hashMap.entrySet()) {
headers.add(entry.getKey(), entry.getValue());
}
HttpEntity<Map<String, Object>> requestEntity =
new HttpEntity<>( headers);
return restTemplate.exchange( url, HttpMethod.GET, requestEntity, JSONObject.class).getBody();
}
/**
* 发送POST-JSON请求
*
* @param url
* @param param
* @return
*/
public String postJsonData(String url, JSONObject param) {
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
headers.add("Accept", MediaType.APPLICATION_JSON.toString());
HttpEntity<JSONObject> requestEntity = new HttpEntity<JSONObject>(param, headers);
return restTemplate.postForEntity(url, param, String.class).getBody();
}
/**
* 发送POST 表单请求
*
* @param url
* @return
*/
public String postFormData(String url, MultiValueMap<String, String> map) {
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.MULTIPART_FORM_DATA);
HttpEntity<MultiValueMap<String, String>> requests = new HttpEntity<MultiValueMap<String, String>>(map, headers);
String body = restTemplate.postForEntity(url, requests, String.class).getBody();
return body;
}
/**
* 发送POST-JSON请求
*
* @param url
* @param param
* @return
*/
public JSONObject postJsonDataAndReturnJson(String url, JSONObject param) {
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
headers.add("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36");
headers.add("Accept", MediaType.APPLICATION_JSON.toString());
HttpEntity<JSONObject> requestEntity = new HttpEntity<JSONObject>(param, headers);
JSONObject body = restTemplate.postForEntity(url, requestEntity, JSONObject.class).getBody();
return body;
}
/**
* 发送POST-JSON请求
*
* @param url
* @return
*/
public JSONObject post(String url) {
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
headers.add("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36");
headers.add("Accept", MediaType.APPLICATION_JSON.toString());
HttpEntity<String> requestEntity = new HttpEntity<>( headers);
JSONObject body = restTemplate.postForEntity(url, requestEntity, JSONObject.class).getBody();
return body;
}
/**
* 发送POST-JSON请求
*
* @param url
* @return
*/
public String postXml(String url, String xml){
HttpHeaders headers = new HttpHeaders();
MediaType type = MediaType.parseMediaType("application/xml; charset=UTF-8");
headers.setContentType(type);
HttpEntity<String> requestEntity = new HttpEntity<>(xml, headers);
ResponseEntity<String> responseEntity = restTemplate.postForEntity(url, requestEntity, String.class);
try{
return new String(Objects.requireNonNull(responseEntity.getBody()).getBytes("ISO8859-1"), StandardCharsets.UTF_8);
}catch (Exception e){
return "";
}
}
/**
* 发送POST 表单请求
*
* @param url
* @param params
* @return
*
* 表单提交,返回数据分为两部分,一个代表成功,一个是返回的数据内容
*/
public String postFormData(String url, LinkedMultiValueMap<String, Object> params ) {
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.MULTIPART_FORM_DATA);
HttpEntity<LinkedMultiValueMap<String, Object>> requestEntity =
new HttpEntity<>(params, headers);
ResponseEntity<String> responseEntity = restTemplate.exchange(
url,
HttpMethod.POST,
requestEntity,
String.class);
String body = responseEntity.getBody();
return body;
}
public String postMapData(String url, Map<String, Object> params ) {
//cs
HttpHeaders headers = new HttpHeaders();
headers.add("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36");
headers.setContentType(MediaType.APPLICATION_JSON);
headers.add("Accept", MediaType.APPLICATION_JSON.toString());
HttpEntity<Map<String, Object>> requestEntity =
new HttpEntity<>(params, headers);
String body1 = restTemplate.postForEntity( url, requestEntity, String.class).getBody();
System.out.println(body1);
return body1;
}
public String postMapData(String url, Map<String, Object> params, Map<String, String> header) {
//cs
HttpHeaders headers = new HttpHeaders();
headers.add("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36");
headers.setContentType(MediaType.APPLICATION_JSON);
headers.add("Accept", MediaType.APPLICATION_JSON.toString());
for (Map.Entry<String, String> entry : header.entrySet()) {
headers.add(entry.getKey(), entry.getValue());
}
HttpEntity<Map<String, Object>> requestEntity =
new HttpEntity<>(params, headers);
String body1 = restTemplate.postForEntity( url, requestEntity, String.class).getBody();
System.out.println(body1);
return body1;
}
public String postStringData(String url,String data ) {
//cs
HttpHeaders headers = new HttpHeaders();
headers.add("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36");
headers.setContentType(MediaType.APPLICATION_JSON);
headers.add("Accept", MediaType.APPLICATION_JSON.toString());
HttpEntity<String> requestEntity =
new HttpEntity<>(data, headers);
String body1 = restTemplate.postForEntity(url, requestEntity, String.class).getBody();
System.out.println(body1);
return body1;
}
public byte[] postJsonDataAndReturnBuffer(String url, JSONObject param) {
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
headers.add("Accept", MediaType.APPLICATION_JSON.toString());
HttpEntity<JSONObject> requestEntity = new HttpEntity<JSONObject>(param, headers);
return restTemplate.postForEntity(url, param, byte[].class).getBody();
}
public byte[] getBuffer(String url) {
return restTemplate.getForEntity(url, byte[].class).getBody();
}
}

View File

@@ -0,0 +1,38 @@
package com.utils;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
@Component
public class SpringUtil implements ApplicationContextAware {
private static ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
if(SpringUtil.applicationContext == null) {
SpringUtil.applicationContext = applicationContext;
}
}
//获取applicationContext
public static ApplicationContext getApplicationContext() {
return applicationContext;
}
//通过name获取 Bean.
public static Object getBean(String name){
return getApplicationContext().getBean(name);
}
//通过class获取Bean.
public static <T> T getBean(Class<T> clazz){
return getApplicationContext().getBean(clazz);
}
//通过name,以及Clazz返回指定的Bean
public static <T> T getBean(String name,Class<T> clazz){
return getApplicationContext().getBean(name, clazz);
}
}

View File

@@ -0,0 +1,90 @@
package com.utils;
/**
* Created on 2019/9/7.
*
* @author MaXiaolong
*/
import java.util.*;
public final class ThreadLocalUtil {
private ThreadLocalUtil() {
throw new IllegalStateException("Utility class");
}
private static final ThreadLocal<Map<String, Object>> threadLocal = ThreadLocal.withInitial(() -> new HashMap(4));
public static Map<String, Object> getThreadLocal(){
return threadLocal.get();
}
public static <T> T get(String key) {
Map map = (Map)threadLocal.get();
return (T)map.get(key);
}
public static <T> T get(String key,T defaultValue) {
Map map = (Map)threadLocal.get();
return (T)map.get(key) == null ? defaultValue : (T)map.get(key);
}
public static void set(String key, Object value) {
Map map = (Map)threadLocal.get();
map.put(key, value);
}
public static void set(Map<String, Object> keyValueMap) {
Map map = (Map)threadLocal.get();
map.putAll(keyValueMap);
}
public static void remove() {
threadLocal.remove();
}
public static <T> Map<String,T> fetchVarsByPrefix(String prefix) {
Map<String,T> vars = new HashMap<>();
if( prefix == null ){
return vars;
}
Map map = (Map)threadLocal.get();
Set<Map.Entry> set = map.entrySet();
for( Map.Entry entry : set ){
Object key = entry.getKey();
if( key instanceof String ){
if( ((String) key).startsWith(prefix) ){
vars.put((String)key,(T)entry.getValue());
}
}
}
return vars;
}
public static <T> T remove(String key) {
Map map = (Map)threadLocal.get();
return (T)map.remove(key);
}
public static void clear(String prefix) {
if( prefix == null ){
return;
}
Map map = (Map)threadLocal.get();
Set<Map.Entry> set = map.entrySet();
List<String> removeKeys = new ArrayList<>();
for( Map.Entry entry : set ){
Object key = entry.getKey();
if( key instanceof String ){
if( ((String) key).startsWith(prefix) ){
removeKeys.add((String)key);
}
}
}
for( String key : removeKeys ){
map.remove(key);
}
}
}

View File

@@ -0,0 +1,314 @@
package com.utils;
import cn.hutool.core.util.RandomUtil;
import com.constants.Constants;
import com.exception.CrmebException;
import com.zbkj.crmeb.upload.vo.FileResultVo;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.IOException;
import java.util.List;
/**
* 上传工具类
* @author Mr.Zhang
* @since 2020-05-08
*/
public class UploadUtil {
private static UploadUtil uploadUtil = new UploadUtil();
//服务器存储地址
// private static String rootPath = "/www/wwwroot/upload";
private static String rootPath = "";
//类型
// private static String imagePath = "/image";
private static String type = "/image";
//模块
// private static String modelPath = "/store";
private static String modelPath = "/public";
//扩展名
private static String extStr = "png,jpg";
//文件大小上限
private static int size = 2;
//是否压缩图片
private static boolean isCompress = false;
public static String getRootPath() {
return rootPath;
}
public static void setRootPath(String rootPath) {
UploadUtil.rootPath = (rootPath + "/").replace(" ", "").replace("//", "/");
}
public static String getType() {
return type;
}
public static void setType(String type) {
UploadUtil.type = type + "/";
}
public static String getModelPath() {
return modelPath;
}
public static void setModelPath(String modelPath) {
UploadUtil.modelPath = modelPath + "/";
}
public static String getExtStr() {
return extStr;
}
public static void setExtStr(String extStr) {
UploadUtil.extStr = extStr;
}
public static int getSize() {
return size;
}
public static void setSize(int size) {
UploadUtil.size = size;
}
public static boolean isIsCompress() {
return isCompress;
}
public static void setIsCompress(boolean isCompress) {
UploadUtil.isCompress = isCompress;
}
/**
* 获取单例
* @author Mr.Zhang
* @since 2020-05-08
*/
public static UploadUtil getInstance() {
if (uploadUtil == null) {
uploadUtil = new UploadUtil();
}
return uploadUtil;
}
/**
* 根据文件的绝对路径创建一个文件对象.
* @return 返回创建的这个文件对象
* @author Mr.Zhang
* @since 2020-05-08
*/
public static File createFile(String filePath) throws IOException {
// 获取文件的完整目录
String fileDir = FilenameUtils.getFullPath(filePath);
// 判断目录是否存在,不存在就创建一个目录
File file = new File(fileDir);
if (!file.isDirectory()) {
//创建失败返回null
if (!file.mkdirs()) {
throw new CrmebException("文件目录创建失败...");
}
}
// 判断这个文件是否存在,不存在就创建
file = new File(filePath);
if (!file.exists()) {
if (!file.createNewFile()) {
throw new CrmebException("目标文件创建失败...");
}
}
return file;
}
/**
* 判断文件扩展名是否合法
* @param extName 文件的后缀名
* @author Mr.Zhang
* @since 2020-05-08
*/
private static void isContains(String extName) {
if (StringUtils.isNotEmpty(getExtStr())) {
// 切割文件扩展名
List<String> extensionList = CrmebUtil.stringToArrayStr(getExtStr());
if (extensionList.size() > 0) {
//判断
if (!extensionList.contains(extName)) {
throw new CrmebException("上传文件的类型只能是:" + getExtStr());
}
} else {
throw new CrmebException("上传文件的类型只能是:" + getExtStr());
}
}
}
// /**
// * 图片压缩
// * @param serverPath 图片的绝对路径
// * @param childFile 子文件夹
// * @param extName 文件的后缀
// * @author Mr.Zhang
// * @since 2020-05-08
// */
// private static String thumbnails(String serverPath, String childFile, String extName) throws IOException {
// // 压缩后的相对路径文件名
// String toFilePath = getDestPath(extName);
//
// // scale图片缩放比例
// // outputQuality图片压缩比例
// // toFile图片位置
// // outputFormat文件输出后缀名
// // Thumbnails 如果用来压缩 png 格式的文件,会越压越大,
// // 得把png格式的图片转换为jpg格式
// if ("png".equalsIgnoreCase(extName)) {
// // 由于outputFormat会自动在路径后加上后缀名所以移除以前的后缀名
// String removeExtensionFilePath = FilenameUtils.removeExtension(toFilePath);
// Thumbnails.of(serverPath).scale(1f)
// .outputQuality(0.5f)
// .outputFormat("jpg")
// .toFile(getServerPath(removeExtensionFilePath));
// toFilePath = removeExtensionFilePath + ".jpg";
// } else {
// Thumbnails.of(serverPath).scale(1f).outputQuality(0.5f)
// .toFile(getServerPath(toFilePath));
// }
//
// // 删除被压缩的文件
// FileUtils.forceDelete(new File(serverPath));
//
// return toFilePath;
// }
/**
* 生成文件文件名
* @param fileName 文件名
* @author Mr.Zhang
* @since 2020-05-08
*/
public static String getDestPath(String fileName) {
//规则: 子目录/年/月/日.后缀名
return getServerPath() + fileName;
}
public static String fileName(String extName){
return CrmebUtil.getUuid() + RandomUtil.randomString(10) + "." + extName;
}
/**
* 生成文件在的实际的路径
* @author Mr.Zhang
* @since 2020-05-08
*/
private static String getServerPath() {
// 文件分隔符转化为当前系统的格式
return FilenameUtils.separatorsToSystem( getRootPath() + getWebPath());
}
/**
* web目录可访问的路径
* @author Mr.Zhang
* @since 2020-05-08
*/
private static String getWebPath() {
// 文件分隔符转化为当前系统的格式
return getType() + getModelPath() + DateUtil.nowDate(Constants.DATE_FORMAT_DATE).replace("-", "/") + "/";
}
/**
* 检测文件大小上限
* @author Mr.Zhang
* @since 2020-05-08
*/
private static void checkSize(Long size) {
// 文件分隔符转化为当前系统的格式
float fileSize = (float)size / 1024 / 1024;
String fs = String.format("%.2f", fileSize);
if( fileSize > getSize()){
throw new CrmebException("最大允许上传" + getSize() + " MB的文件, 当前文件大小为 " + fs + " MB");
}
}
/**
* 上传文件
* @param multipartFile 上传的文件对象,必传
* @author Mr.Zhang
* @since 2020-05-08
*/
private static FileResultVo saveFile(MultipartFile multipartFile) throws IOException {
if (null == multipartFile || multipartFile.isEmpty()) {
throw new CrmebException("上传的文件对象不存在...");
}
// 文件名
String fileName = multipartFile.getOriginalFilename();
// 文件后缀名
String extName = FilenameUtils.getExtension(fileName);
if (StringUtils.isEmpty(extName)) {
throw new RuntimeException("文件类型未定义不能上传...");
}
//文件大小验证
checkSize(multipartFile.getSize());
// 判断文件的后缀名是否符合规则
isContains(extName);
//文件名
String newFileName = fileName(extName);
// 创建目标文件的名称规则请看destPath方法
String destPath = getDestPath(newFileName);
// 创建文件
File file = createFile(destPath);
// 保存文件
multipartFile.transferTo(file);
// 拼装返回的数据
FileResultVo result = new FileResultVo();
//如果是图片,就进行图片处理
if (BooleanUtils.isTrue(isIsCompress())) {
// // 图片处理
// String toFilePath = thumbnails(serverPath, childFile, extName);
// // 得到处理后的图片文件对象
// File file = new File(getServerPath());
// // 压缩后的文件后缀名
// String extExtName = FilenameUtils.getExtension(toFilePath);
// // 源文件=源文件名.压缩后的后缀名
// String extFileName = FilenameUtils.getBaseName(fileName) + "." + FilenameUtils.getExtension(toFilePath);
// result.setFileSize(file.length());
// result.setServerPath(toFilePath);
// result.setFileName(extFileName);
// result.setExtName(extExtName);
} else {
result.setFileSize(multipartFile.getSize());
result.setFileName(fileName);
result.setExtName(extName);
result.setServerPath(destPath);
result.setUrl(getWebPath() + newFileName);
result.setType(multipartFile.getContentType());
}
return result;
}
/**
* 上传
* @param multipartFile 上传的文件对象,必传
* @since 2020-05-08
* @author Mr.Zhang
*/
public static FileResultVo file(MultipartFile multipartFile) throws IOException {
return saveFile(multipartFile);
}
}

View File

@@ -0,0 +1,94 @@
package com.utils;
import com.alibaba.fastjson.JSONObject;
import com.exception.CrmebException;
import org.apache.http.HttpEntity;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
/**
* http通用工具类
*
*/
public class UploadWeChatMediaUtil {
/**
* 把文件上传到指定url上去
* @param url 上传地址
* @param file 待上传文件
*/
public static JSONObject uploadFile(String url, InputStream file, String fileName) throws IOException {
CloseableHttpClient httpclient = HttpClients.createDefault();
try {
HttpPost httppost = new HttpPost(url);
RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(200000).setSocketTimeout(200000).build();
httppost.setConfig(requestConfig);
/**
* 这一步最关键:
*调用addBinaryBody("media",input2byte(file),ContentType.DEFAULT_BINARY, fileName),
* fileName可以为任意值但不能为null如果为null则上传失败。
* input2byte(file)把inputstream转为byte[]
* 如果直接调用addPart用FileBody做参数则MultifilePart不好转换
* 如果直接调用addPart用InpustreamBody做参数则因为没有fileName会造成上传失败
*/
HttpEntity reqEntity = MultipartEntityBuilder.create()
.addBinaryBody("media", input2byte(file), ContentType.DEFAULT_BINARY,
fileName).build();
httppost.setEntity(reqEntity);
CloseableHttpResponse response = httpclient.execute(httppost);
try {
System.out.println(response.getStatusLine());
HttpEntity resEntity = response.getEntity();
if (resEntity != null) {
String responseEntityStr = EntityUtils.toString(response.getEntity());
return JSONObject.parseObject(responseEntityStr);
}
EntityUtils.consume(resEntity);
}catch (Exception e){
e.printStackTrace();
throw new CrmebException(e.getMessage());
}finally {
response.close();
}
} catch (IOException e) {
e.printStackTrace();
throw new CrmebException(e.getMessage());
} finally {
try {
httpclient.close();
} catch (IOException e) {
throw new CrmebException(e.getMessage());
}
}
return null;
}
private static byte[] input2byte(InputStream inStream)
throws IOException {
ByteArrayOutputStream swapStream = new ByteArrayOutputStream();
byte[] buff = new byte[100];
int rc = 0;
while ((rc = inStream.read(buff, 0, 100)) > 0) {
swapStream.write(buff, 0, rc);
}
return swapStream.toByteArray();
}
}

View File

@@ -0,0 +1,69 @@
package com.utils;
import java.util.HashMap;
import java.util.Map;
/**
* url 工具类
*/
public class UrlUtil {
public static class UrlEntity {
/**
* 基础url
*/
public String baseUrl;
/**
* url参数
*/
public Map<String, String> params;
}
/**
* 解析url
*
* @param url
* @return
*/
public static UrlEntity parse(String url) {
UrlEntity entity = new UrlEntity();
if (url == null) {
return entity;
}
url = url.trim();
if (url.equals("")) {
return entity;
}
String[] urlParts = url.split("\\?");
entity.baseUrl = urlParts[0];
//没有参数
if (urlParts.length == 1) {
return entity;
}
//有参数
String[] params = urlParts[1].split("&");
entity.params = new HashMap<>();
for (String param : params) {
String[] keyValue = param.split("=");
entity.params.put(keyValue[0], keyValue[1]);
}
return entity;
}
public static String getParamsByKey(String url,String key){
UrlEntity entity = parse(url);
return entity.params.get(key);
}
/**
* 测试
*
* @param args
*/
public static void main(String[] args) {
UrlEntity entity = parse(null);
entity = parse("http://www.123.com?id=1&name=小明");
System.out.println(entity.baseUrl + "\n" + entity.params);
System.out.println(entity.params.get("id"));
}
}

View File

@@ -0,0 +1,203 @@
package com.utils;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.Serializable;
import java.util.Random;
import javax.imageio.ImageIO;
import cn.hutool.core.util.RandomUtil;
import com.alibaba.druid.util.Base64;
import org.springframework.stereotype.Component;
/**
* 验证码生成工具类
* @author Mr.Zhang
* @since 2020-04-16
*/
@Component
public class ValidateCodeUtil {
private static Validate validate = null; //验证码类用于最后返回此对象包含验证码图片base64和真值
private static Random random = new Random(); //随机类,用于生成随机参数
private static String randString = "0123456789abcdefghijkmnpqrtyABCDEFGHIJLMNQRTY";//随机生成字符串的取值范围
private static int width = 80; //图片宽度
private static int height = 34; //图片高度
private static int stringNum = 4; //字符的数量
private static int lineSize = 40; //干扰线数量
/**
* 将构造函数私有化 禁止new创建
* @author Mr.Zhang
* @since 2020-04-16
*/
private ValidateCodeUtil() {
super();
}
/**
* 获取随机字符
* @author Mr.Zhang
* @since 2020-04-16
* @return String
*/
private static String getRandomChar(int index) {
//获取指定位置index的字符并转换成字符串表示形式
return String.valueOf(randString.charAt(index));
}
/**
* 获取随机指定区间的随机数
* @param min (指定最小数)
* @param max (指定最大数)
* @author Mr.Zhang
* @since 2020-04-16
* @return String
*/
private static int getRandomNum(int min,int max) {
return RandomUtil.randomInt(min, max);
}
/**
* 获得字体
*/
private static Font getFont() {
return new Font("Fixedsys", Font.CENTER_BASELINE, 25); //名称、样式、磅值
}
/**
* 获得颜色
* @param frontColor 覆盖颜色
* @param backColor 背景色
* @author Mr.Zhang
* @since 2020-04-16
* @return Color
*/
private static Color getRandColor(int frontColor, int backColor) {
if(frontColor > 255)
frontColor = 255;
if(backColor > 255)
backColor = 255;
int red = frontColor + random.nextInt(backColor - frontColor - 16);
int green = frontColor + random.nextInt(backColor - frontColor -14);
int blue = frontColor + random.nextInt(backColor - frontColor -18);
return new Color(red, green, blue);
}
/**
* 绘制字符串,返回绘制的字符串
* @param graphics 获得BufferedImage对象的Graphics对象
* @param randomString 随机字符串
* @param i 坐标倍数
* @author Mr.Zhang
* @since 2020-04-16
* @return string
*/
private static String drawString(Graphics graphics, String randomString, int i) {
Graphics2D g2d = (Graphics2D) graphics;
g2d.setFont(getFont()); //设置字体
g2d.setColor(new Color(random.nextFloat(), random.nextFloat(), random.nextFloat()));//设置颜色
String randChar = String.valueOf(getRandomChar(random.nextInt(randString.length())));
randomString += randChar; //组装
int rot = getRandomNum(5,10);
g2d.translate(random.nextInt(3), random.nextInt(3));
g2d.rotate(rot * Math.PI / 180);
g2d.drawString(randChar, 13*i, 20);
g2d.rotate(-rot * Math.PI / 180);
return randomString;
}
/**
* 绘制干扰线
* @param graphics 获得BufferedImage对象的Graphics对象
* @author Mr.Zhang
* @since 2020-04-16
*/
private static void drawLine(Graphics graphics) {
//起点(x,y) 偏移量x1、y1
int x = random.nextInt(width);
int y = random.nextInt(height);
int xl = random.nextInt(13);
int yl = random.nextInt(15);
graphics.setColor(new Color(random.nextFloat(), random.nextFloat(), random.nextFloat()));
graphics.drawLine(x, y, x + xl, y + yl);
}
/**
* 生成Base64图片验证码
* @author Mr.Zhang
* @since 2020-04-16
* @return String
*/
public static Validate getRandomCode() {
validate = validate==null?new Validate():validate;
// BufferedImage类是具有缓冲区的Image类,Image类是用于描述图像信息的类
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_BGR);
Graphics Graphics = image.getGraphics();// 获得BufferedImage对象的Graphics对象
Graphics.fillRect(0, 0, width, height);//填充矩形
Graphics.setFont(new Font("Times New Roman", Font.ROMAN_BASELINE, 18));//设置字体
Graphics.setColor(getRandColor(110, 133));//设置颜色
//绘制干扰线
for(int i = 0; i <= lineSize; i++) {
drawLine(Graphics);
}
//绘制字符
String randomString = "";
for(int i = 1; i <= stringNum; i++) {
randomString = drawString(Graphics, randomString, i);
validate.setValue(randomString);
}
Graphics.dispose();//释放绘图资源
ByteArrayOutputStream bs = null;
try {
bs = new ByteArrayOutputStream();
ImageIO.write(image, "png", bs);//将绘制得图片输出到流
String imgSrc = Base64.byteArrayToBase64(bs.toByteArray());
validate.setBase64Str(imgSrc);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
bs.close();
} catch (IOException e) {
e.printStackTrace();
}finally{
bs = null;
}
}
return validate;
}
/**
* 验证码类
* @author Mr.Zhang
* @since 2020-04-16
*/
public static class Validate implements Serializable{
private static final long serialVersionUID = 1L;
private String Base64Str; //Base64 值
private String value; //验证码值
public String getBase64Str() {
return Base64Str;
}
public void setBase64Str(String base64Str) {
Base64Str = base64Str;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
}

View File

@@ -0,0 +1,188 @@
package com.utils;
import com.constants.RegularConstants;
import com.exception.CrmebException;
import com.zbkj.crmeb.system.model.SystemConfig;
import org.apache.commons.lang3.StringUtils;
import java.util.*;
import java.util.regex.Pattern;
/** 表单验证类
* @author Mr.zhang
* @Description 表单验证类
* @since 2020-05-11
**/
public class ValidateFormUtil {
/**
* 检测类型
* @param systemConfig SystemConfig 需要验证的类
* @author Mr.Zhang
* @since 2020-05-11
*/
public static void checkType(SystemConfig systemConfig, String rule){
if(StringUtils.isBlank(rule)){
return;
}
//required:true,min:0,max:100,number:true
List<String> list = CrmebUtil.stringToArrayStr(rule);
for (String value : list) {
List<String> val = CrmebUtil.stringToArrayStrRegex(value, ":");
////必填
if(val.get(0).equals("required") && val.get(1).equals("true")){
isRequire(systemConfig.getValue(), systemConfig.getTitle());
continue;
}
//数字
if(val.get(0).equals("number") && val.get(1).equals("true")){
isNumber(systemConfig.getValue(), systemConfig.getTitle());
continue;
}
//最大值
if(val.get(0).equals("max")){
isNumber(systemConfig.getValue(), systemConfig.getTitle());
continue;
}
//最小值
if(val.get(0).equals("min")){
isNumber(systemConfig.getValue(), systemConfig.getTitle());
continue;
}
//邮箱
if(val.get(0).equals("email") && val.get(1).equals("true")){
isEmail(systemConfig.getValue(), systemConfig.getTitle());
continue;
}
//手机
if(val.get(0).equals("phone") && val.get(1).equals("true")){
isPhone(systemConfig.getValue(), systemConfig.getTitle());
}
}
}
/**
* 邮箱
* @param value String 值
* @param info String 字段名
* @author Mr.Zhang
* @since 2020-05-11
*/
public static void isEmail(String value, String info) {
regularException(value, info, RegularConstants.EMAIL, "邮箱");
}
/**
* 手机
* @param value String 值
* @param info String 字段名
* @author Mr.Zhang
* @since 2020-05-11
*/
public static void isPhone(String value, String info) {
regularException(value, info, RegularConstants.PHONE, "手机");
}
/**
* 验证必填
* @param value String 值
* @param info String 字段名
* @author Mr.Zhang
* @since 2020-05-11
*/
public static void isRequire(String value, String info){
if(StringUtils.isBlank(value) ){
throw new CrmebException("请填写/选择" + info);
}
}
/**
* 数字验证
* @param value String 值
* @param info String 字段名
* @author Mr.Zhang
* @since 2020-05-11
*/
public static void isNumber(String value, String info){
regularException(value, info, RegularConstants.NUMBER, "数字");
}
/**
* 数字范围
* @param value String 值
* @param info String 字段名
* @author Mr.Zhang
* @since 2020-05-11
*/
public static void range(String value, String info, Integer max, Integer min){
isNumber(value, info);
max(value, info, max);
min(value, info, min);
}
/**
* 最大数值
* @param value String 值
* @param info String 字段名
* @author Mr.Zhang
* @since 2020-05-11
*/
public static void max(String value, String info, Integer max){
isNumber(value, info);
int number = Integer.parseInt(value);
if(number > max ){
throw new CrmebException(info + "不在取值范围内,最大不能大于" + max);
}
}
/**
* 最小数值
* @param value String 值
* @param info String 字段名
* @author Mr.Zhang
* @since 2020-05-11
*/
public static void min(String value, String info, Integer min){
isNumber(value, info);
int number = Integer.parseInt(value);
if(number > min ){
throw new CrmebException(info + "不在取值范围内,最小不能小于" + min);
}
}
/**
* 正则表达式验证
* @param value String 值
* @param info String 字段名
* @param regular String 正则表达式
* @author Mr.Zhang
* @since 2020-05-11
*/
public static void regularException(String value, String info, String regular, String title){
if(!regular(value, info, regular)){
//正则验证
throw new CrmebException(info + " 格式必须为 " + title);
}
}
/**
* 正则表达式验证
* @param value String 值
* @param info String 字段名
* @param regular String 正则表达式
* @author Mr.Zhang
* @since 2020-05-11
*/
public static boolean regular(String value, String info, String regular){
isRequire(value, info);
Pattern pattern = Pattern.compile(regular);
return pattern.matcher(value).matches();
}
}

View File

@@ -0,0 +1,87 @@
package com.utils;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.naming.NoNameCoder;
import com.thoughtworks.xstream.io.xml.Xpp3Driver;
import org.apache.commons.lang3.StringUtils;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import javax.servlet.http.HttpServletRequest;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class XmlUtil {
public static Map<String,String> xmlToMap(HttpServletRequest request)
{
Map<String,String> map = new HashMap<>();
SAXReader reader = new SAXReader();
InputStream in = null;
try {
in = request.getInputStream();
Document doc = reader.read(in);
Element root = doc.getRootElement();
List<Element> list = root.elements();
for (Element element : list) {
map.put(element.getName(), element.getText());
}
} catch (IOException | DocumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally{
try {
assert in != null;
in.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return map;
}
/**
* 将发送消息封装成对应的xml格式
*/
public static HashMap<String,Object> xmlToMap(String strxml)throws Exception{
strxml = strxml.replaceFirst("encoding=\".*\"", "encoding=\"UTF-8\"");
HashMap<String,Object> map = new HashMap<>();
SAXReader reader = new SAXReader();
InputStream inputStream = new ByteArrayInputStream(strxml.getBytes(StandardCharsets.UTF_8));
if(StringUtils.isBlank(strxml)) {
return null;
}
Document document = reader.read(inputStream);
Element root = document.getRootElement();
List<Element> list = root.elements();
for (Element e : list){
map.put(e.getName(),e.getText());
}
inputStream.close();
return map;
}
/**
* 将发送消息封装成对应的xml格式
*/
public static String objectToXml(Object object) {
XStream xstream = new XStream(new Xpp3Driver(new NoNameCoder())); //不需要转义
xstream.alias("xml", object.getClass());
return xstream.toXML(object);
}
}

View File

@@ -0,0 +1,28 @@
package com.utils.vo;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotBlank;
/**
* 图片合成详情
* @author Mr.Zhang
* @since 2020-04-18
*/
@Data
public class ImageMergeUtilVo {
@ApiModelProperty(value = "图片地址", required = true)
@NotBlank(message = "图片地址必须填写")
private String path; //地址
@ApiModelProperty(value = "x轴", required = true)
@Min(value = 0, message = "x轴至少为0")
private int x; //x轴
@ApiModelProperty(value = "y轴", required = true)
@Min(value = 0, message = "y轴至少为0")
private int y; //y轴
}

View File

@@ -0,0 +1,23 @@
package com.utils.vo;
import lombok.Data;
/**
* @author stivepeim
* @title: dateLimitVoUtil
* @projectName crmeb
* @Description: 工具类
* @since 2020/4/1414:37
*/
@Data
public class dateLimitUtilVo {
public dateLimitUtilVo() {}
public dateLimitUtilVo(String startTime, String endTime) {
this.startTime = startTime;
this.endTime = endTime;
}
private String startTime; //开始时间
private String endTime; //结束时间
}

View File

@@ -0,0 +1,26 @@
package com.zbkj.crmeb;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
@EnableAsync //开启异步调用
@EnableSwagger2
@Configuration
@SpringBootApplication(exclude = DataSourceAutoConfiguration.class) //去掉数据源
@ComponentScan(basePackages={"com.utils",
"com.zbkj.crmeb",
"com.exception",
"com.common",
"com.aop"}) //扫描utils包和父包
@MapperScan(basePackages = "com.zbkj.crmeb.*.dao")
public class CrmebApplication{
public static void main(String[] args) {
SpringApplication.run(CrmebApplication.class, args);
}
}

View File

@@ -0,0 +1,157 @@
package com.zbkj.crmeb.article.controller;
import com.common.CommonPage;
import com.common.CommonResult;
import com.common.PageParamRequest;
import com.zbkj.crmeb.article.model.Article;
import com.zbkj.crmeb.article.request.ArticleRequest;
import com.zbkj.crmeb.article.request.ArticleSearchRequest;
import com.zbkj.crmeb.article.service.ArticleService;
import com.zbkj.crmeb.article.vo.ArticleVo;
import com.zbkj.crmeb.system.service.SystemAttachmentService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
/**
* 文章管理表 前端控制器
*/
@Slf4j
@RestController
@RequestMapping("api/admin/article")
@Api(tags = "文章管理")
public class ArticleController {
@Autowired
private ArticleService articleService;
@Autowired
private SystemAttachmentService systemAttachmentService;
/**
* 分页显示文章管理表
* @param request ArticleSearchRequest 搜索条件
* @param pageParamRequest 分页参数
* @author Mr.Zhang
* @since 2020-04-18
*/
@ApiOperation(value = "分页列表")
@RequestMapping(value = "/list", method = RequestMethod.GET)
@ApiImplicitParam(name="keywords", value="搜索关键字")
public CommonResult<CommonPage<ArticleVo>> getList(@Validated ArticleSearchRequest request,
@Validated PageParamRequest pageParamRequest){
return CommonResult.success(CommonPage.restPage(articleService.getList(request, pageParamRequest)));
}
/**
* 新增文章管理表
* @param articleRequest 新增参数
* @author Mr.Zhang
* @since 2020-04-18
*/
@ApiOperation(value = "新增")
@RequestMapping(value = "/save", method = RequestMethod.POST)
public CommonResult<String> save(@Validated ArticleRequest articleRequest){
Article article = new Article();
BeanUtils.copyProperties(articleRequest, article);
article.setImageInput(systemAttachmentService.clearPrefix(article.getImageInput()));
article.setContent(systemAttachmentService.clearPrefix(article.getContent()));
if(articleService.save(article)){
return CommonResult.success();
}else{
return CommonResult.failed();
}
}
/**
* 删除文章管理表
* @param id Integer
* @author Mr.Zhang
* @since 2020-04-18
*/
@ApiOperation(value = "删除")
@RequestMapping(value = "/delete", method = RequestMethod.GET)
@ApiImplicitParam(name="id", value="文章ID")
public CommonResult<String> delete(@RequestParam(value = "id") Integer id){
if(articleService.removeById(id)){
return CommonResult.success();
}else{
return CommonResult.failed();
}
}
/**
* 关联产品
* @param id Integer
* @param productId 产品id
* @author Mr.Zhang
* @since 2020-04-18
*/
@ApiOperation(value = "绑定产品")
@RequestMapping(value = "/bind/product", method = RequestMethod.POST)
@ApiImplicitParams({
@ApiImplicitParam(name="id", value="文章ID"),
@ApiImplicitParam(name="productId", value="产品id")
})
public CommonResult<String> bind(@RequestParam(value = "id") Integer id,
@RequestParam(value = "productId") Integer productId){
if(articleService.update(id, productId)){
return CommonResult.success();
}else{
return CommonResult.failed();
}
}
/**
* 修改文章管理表
* @param id integer id
* @param articleRequest 修改参数
* @author Mr.Zhang
* @since 2020-04-18
*/
@ApiOperation(value = "修改")
@RequestMapping(value = "/update", method = RequestMethod.POST)
@ApiImplicitParam(name="id", value="文章ID")
public CommonResult<String> update(@RequestParam Integer id, @Validated ArticleRequest articleRequest){
Article article = new Article();
BeanUtils.copyProperties(articleRequest, article);
article.setId(id);
article.setImageInput(systemAttachmentService.clearPrefix(article.getImageInput()));
article.setContent(systemAttachmentService.clearPrefix(article.getContent()));
if(articleService.updateById(article)){
return CommonResult.success();
}else{
return CommonResult.failed();
}
}
/**
* 查询文章管理表信息
* @param id Integer
* @author Mr.Zhang
* @since 2020-04-18
*/
@ApiOperation(value = "详情")
@RequestMapping(value = "/info", method = RequestMethod.GET)
@ApiImplicitParam(name="id", value="文章ID")
public CommonResult<Article> info(@RequestParam(value = "id") Integer id){
Article article = articleService.getById(id);
return CommonResult.success(article);
}
}

View File

@@ -0,0 +1,16 @@
package com.zbkj.crmeb.article.dao;
import com.zbkj.crmeb.article.model.Article;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* <p>
* 文章管理表 Mapper 接口
* </p>
*
* @author Mr.Zhang
* @since 2020-04-18
*/
public interface ArticleDao extends BaseMapper<Article> {
}

View File

@@ -0,0 +1,100 @@
package com.zbkj.crmeb.article.model;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import java.io.Serializable;
import java.util.Date;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
* <p>
* 文章管理表
* </p>
*
* @author Mr.Zhang
* @since 2020-04-18
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("eb_article")
@ApiModel(value="Article对象", description="文章管理表")
public class Article implements Serializable {
private static final long serialVersionUID=1L;
@ApiModelProperty(value = "文章管理ID")
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
@ApiModelProperty(value = "分类id")
private String cid;
@ApiModelProperty(value = "文章标题")
private String title;
@ApiModelProperty(value = "文章作者")
private String author;
@ApiModelProperty(value = "文章图片")
private String imageInput;
@ApiModelProperty(value = "文章简介")
private String synopsis;
@ApiModelProperty(value = "文章分享标题")
private String shareTitle;
@ApiModelProperty(value = "文章分享简介")
private String shareSynopsis;
@ApiModelProperty(value = "浏览次数")
private String visit;
@ApiModelProperty(value = "排序")
private Integer sort;
@ApiModelProperty(value = "原文链接")
private String url;
@ApiModelProperty(value = "微信素材id")
private String mediaId;
@ApiModelProperty(value = "状态")
private Boolean status;
@ApiModelProperty(value = "是否隐藏")
private Boolean hide;
@ApiModelProperty(value = "管理员id")
private Integer adminId;
@ApiModelProperty(value = "商户id")
private Integer merId;
@ApiModelProperty(value = "商品关联id")
private Integer productId;
@ApiModelProperty(value = "是否热门(小程序)")
private Boolean isHot;
@ApiModelProperty(value = "是否轮播图(小程序)")
private Boolean isBanner;
@ApiModelProperty(value = "文章内容")
private String content;
@ApiModelProperty(value = "创建时间")
private Date createTime;
@ApiModelProperty(value = "创建时间")
private Date updateTime;
}

View File

@@ -0,0 +1,75 @@
package com.zbkj.crmeb.article.request;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import javax.validation.constraints.NotBlank;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
* <p>
* 文章管理表
* </p>
*
* @author Mr.Zhang
* @since 2020-04-18
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@ApiModel(value="ArticleRequest对象", description="文章管理表")
public class ArticleRequest implements Serializable {
private static final long serialVersionUID=1L;
@ApiModelProperty(value = "分类id", required = true)
@NotBlank(message = "请选择分类")
private String cid;
@ApiModelProperty(value = "文章标题", required = true)
@NotBlank(message = "请填写文章标题")
private String title;
@ApiModelProperty(value = "文章作者", required = true)
@NotBlank(message = "请填写文章标题")
private String author;
@ApiModelProperty(value = "文章图片", required = true)
@NotBlank(message = "请上传文章图片")
private String imageInput;
@ApiModelProperty(value = "文章简介", required = true)
@NotBlank(message = "请填写文章简介")
private String synopsis;
@ApiModelProperty(value = "文章分享标题", required = true)
@NotBlank(message = "请填写文章分享标题")
private String shareTitle;
@ApiModelProperty(value = "文章分享简介", required = true)
@NotBlank(message = "请填写文章分享简介")
private String shareSynopsis;
@ApiModelProperty(value = "排序", example = "0", required = true)
private Integer sort;
@ApiModelProperty(value = "原文链接")
private String url;
@ApiModelProperty(value = "是否热门(小程序)", example = "false")
private Boolean isHot;
@ApiModelProperty(value = "是否轮播图(小程序)" , example = "true")
private Boolean isBanner;
@ApiModelProperty(value = "文章内容", required = true)
@NotBlank(message = "请填写文章内容")
private String content;
}

View File

@@ -0,0 +1,51 @@
package com.zbkj.crmeb.article.request;
import com.baomidou.mybatisplus.annotation.TableName;
import com.sun.org.apache.xpath.internal.operations.Bool;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import javax.validation.constraints.NotBlank;
import java.io.Serializable;
/**
* <p>
* 文章管理表
* </p>
*
* @author Mr.Zhang
* @since 2020-04-18
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@ApiModel(value="ArticleSearchRequest对象", description="文章管理表")
public class ArticleSearchRequest implements Serializable {
private static final long serialVersionUID=1L;
@ApiModelProperty(value = "分类id", required = true)
private String cid;
@ApiModelProperty(value = "搜索关键字")
private String keywords;
@ApiModelProperty(value = "是否有微信素材媒体id")
private Boolean isHaveMediaId = null;
@ApiModelProperty(value = "是否热门(小程序)", example = "null")
private Boolean isHot = null;
@ApiModelProperty(value = "是否轮播图(小程序)" , example = "null")
private Boolean isBanner = null;
@ApiModelProperty(value = "是否隐藏", example = "null")
private Boolean hide = null;
@ApiModelProperty(value = "状态" , example = "null")
private Boolean status = null;
}

View File

@@ -0,0 +1,22 @@
package com.zbkj.crmeb.article.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.common.PageParamRequest;
import com.github.pagehelper.PageInfo;
import com.zbkj.crmeb.article.model.Article;
import com.zbkj.crmeb.article.request.ArticleSearchRequest;
import com.zbkj.crmeb.article.vo.ArticleVo;
/**
* @author Mr.Zhang
* @Description ArticleService 接口
* @since 2020-04-18
*/
public interface ArticleService extends IService<Article> {
PageInfo<ArticleVo> getList(ArticleSearchRequest request, PageParamRequest pageParamRequest);
boolean update(Integer id, Integer productId);
ArticleVo getVoByFront(Integer id);
}

View File

@@ -0,0 +1,153 @@
package com.zbkj.crmeb.article.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.common.CommonPage;
import com.common.PageParamRequest;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.utils.CrmebUtil;
import com.zbkj.crmeb.article.dao.ArticleDao;
import com.zbkj.crmeb.article.model.Article;
import com.zbkj.crmeb.article.request.ArticleSearchRequest;
import com.zbkj.crmeb.article.service.ArticleService;
import com.zbkj.crmeb.article.vo.ArticleVo;
import com.zbkj.crmeb.category.model.Category;
import com.zbkj.crmeb.category.service.CategoryService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
/**
* @author Mr.Zhang
* @Description ArticleServiceImpl 接口实现
* @since 2020-04-18
*/
@Service
public class ArticleServiceImpl extends ServiceImpl<ArticleDao, Article> implements ArticleService {
@Resource
private ArticleDao dao;
@Autowired
private CategoryService categoryService;
/**
* 列表
* @param request ArticleSearchRequest 请求参数
* @param pageParamRequest 分页类参数
* @author Mr.Zhang
* @since 2020-04-18
* @return List<Article>
*/
@Override
public PageInfo<ArticleVo> getList(ArticleSearchRequest request, PageParamRequest pageParamRequest) {
Page<Article> articlePage = PageHelper.startPage(pageParamRequest.getPage(), pageParamRequest.getLimit());
LambdaQueryWrapper<Article> lambdaQueryWrapper = new LambdaQueryWrapper<>();
if(StringUtils.isNotBlank(request.getCid())){
lambdaQueryWrapper.eq(Article::getCid, request.getCid());
}
if(!StringUtils.isBlank(request.getKeywords())){
lambdaQueryWrapper.and(i -> i.or().like(Article::getTitle, request.getKeywords())
.or().like(Article::getAuthor, request.getKeywords())
.or().like(Article::getSynopsis, request.getKeywords())
.or().like(Article::getShareTitle, request.getKeywords())
.or().like(Article::getShareSynopsis, request.getKeywords()));
}
if(request.getIsBanner() != null){
lambdaQueryWrapper.eq(Article::getIsBanner, request.getIsBanner());
}
if(request.getIsHot() != null){
lambdaQueryWrapper.eq(Article::getIsHot, request.getIsHot());
}
if(request.getHide() != null){
lambdaQueryWrapper.eq(Article::getHide, request.getHide());
}
if(request.getStatus() != null){
lambdaQueryWrapper.eq(Article::getStatus, request.getStatus());
}
if(null != request.getIsHaveMediaId()){
lambdaQueryWrapper.isNotNull(Article::getMediaId).ne(Article::getMediaId, "");
}
lambdaQueryWrapper.orderByDesc(Article::getSort).orderByDesc(Article::getVisit);
List<Article> articleList = dao.selectList(lambdaQueryWrapper);
ArrayList<ArticleVo> articleVoArrayList = new ArrayList<>();
if(articleList.size() < 1){
return CommonPage.copyPageInfo(articlePage, articleVoArrayList);
}
for (Article article : articleList) {
ArticleVo articleVo = new ArticleVo();
BeanUtils.copyProperties(article, articleVo);
if(!StringUtils.isBlank(article.getImageInput()) ){
articleVo.setImageInput(CrmebUtil.jsonToListString(article.getImageInput()));
}
articleVoArrayList.add(articleVo);
}
return CommonPage.copyPageInfo(articlePage, articleVoArrayList);
}
/**
* 关联产品
* @param id Integer
* @param productId 产品id
* @author Mr.Zhang
* @since 2020-04-18
* @return bool
*/
@Override
public boolean update(Integer id, Integer productId) {
Article article = new Article();
article.setId(id);
article.setProductId(productId);
updateById(article);
return true;
}
/**
* 查询文章详情
* @param id Integer
* @author Mr.Zhang
* @since 2020-04-18
* @return ArticleVo
*/
@Override
public ArticleVo getVoByFront(Integer id) {
Article article = getById(id);
if(article.getStatus()){
return null;
}
ArticleVo articleVo = new ArticleVo();
BeanUtils.copyProperties(article, articleVo);
if(!StringUtils.isBlank(article.getImageInput())) {
articleVo.setImageInput(CrmebUtil.jsonToListString(article.getImageInput()));
}
//分类名称
Category category = categoryService.getById(article.getCid());
articleVo.setCategoryName(category.getName());
return articleVo;
}
}

View File

@@ -0,0 +1,104 @@
package com.zbkj.crmeb.article.vo;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
* <p>
* 文章管理表
* </p>
*
* @author Mr.Zhang
* @since 2020-04-18
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@ApiModel(value="ArticleVo对象", description="文章管理表")
public class ArticleVo implements Serializable {
private static final long serialVersionUID=1L;
@ApiModelProperty(value = "文章管理ID")
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
@ApiModelProperty(value = "分类id")
private String cid;
@ApiModelProperty(value = "分类")
private String categoryName;
@ApiModelProperty(value = "文章标题")
private String title;
@ApiModelProperty(value = "文章作者")
private String author;
@ApiModelProperty(value = "文章图片")
private List<String> imageInput = new ArrayList<>();
@ApiModelProperty(value = "文章简介")
private String synopsis;
@ApiModelProperty(value = "文章分享标题")
private String shareTitle;
@ApiModelProperty(value = "文章分享简介")
private String shareSynopsis;
@ApiModelProperty(value = "浏览次数")
private String visit;
@ApiModelProperty(value = "排序")
private Integer sort;
@ApiModelProperty(value = "原文链接")
private String url;
@ApiModelProperty(value = "微信素材媒体id")
private String mediaId;
@ApiModelProperty(value = "状态")
private Boolean status;
@ApiModelProperty(value = "是否隐藏")
private Boolean hide;
@ApiModelProperty(value = "管理员id")
private Integer adminId;
@ApiModelProperty(value = "商户id")
private Integer merId;
@ApiModelProperty(value = "商品关联id")
private Integer productId;
@ApiModelProperty(value = "是否热门(小程序)")
private Boolean isHot;
@ApiModelProperty(value = "是否轮播图(小程序)")
private Boolean isBanner;
@ApiModelProperty(value = "文章内容")
private String content;
@ApiModelProperty(value = "创建时间")
@JsonFormat(pattern = "yyyy-MM-dd",timezone="GMT+8")
private Date createTime;
@ApiModelProperty(value = "更新时间")
@JsonFormat(pattern = "yyyy-MM-dd",timezone="GMT+8")
private Date updateTime;
}

View File

@@ -0,0 +1,118 @@
package com.zbkj.crmeb.authorization.controller;
import com.common.CheckAdminToken;
import com.common.CommonResult;
import com.constants.Constants;
import com.exception.CrmebException;
import com.exception.ExceptionCodeEnum;
import com.zbkj.crmeb.authorization.manager.TokenManager;
import com.zbkj.crmeb.system.request.SystemAdminLoginRequest;
import com.zbkj.crmeb.system.request.SystemAdminRequest;
import com.zbkj.crmeb.system.response.SystemAdminResponse;
import com.zbkj.crmeb.system.response.SystemGroupDataAdminLoginBannerResponse;
import com.zbkj.crmeb.system.service.SystemAdminService;
import com.zbkj.crmeb.system.service.SystemConfigService;
import com.zbkj.crmeb.system.service.SystemGroupDataService;
import com.zbkj.crmeb.validatecode.model.ValidateCode;
import com.zbkj.crmeb.validatecode.service.ValidateCodeService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @author stivepeim
* @title: adminUser
* @projectName crmeb
* @Description: TODO
* @since 2020/4/1614:56
*/
@Slf4j
@RestController
@RequestMapping("api/admin")
@Api(tags = "Admin 平台用户")
public class adminUser {
@Autowired
private SystemAdminService systemAdminService;
@Autowired
private CheckAdminToken checkAdminToken;
@Autowired
private SystemConfigService systemConfigService;
@Autowired
private SystemGroupDataService systemGroupDataService;
@Autowired
private TokenManager tokenManager;
@Autowired
private ValidateCodeService validateCodeService;
@ApiOperation(value="AdminUserLogin")
@PostMapping(value = "/login", produces = "application/json")
public CommonResult<SystemAdminResponse> SystemAdminLogin(@RequestBody @Validated SystemAdminLoginRequest systemAdminLoginRequest) throws Exception {
// 判断验证码
ValidateCode validateCode = new ValidateCode(systemAdminLoginRequest.getKey(),systemAdminLoginRequest.getCode());
boolean codeCheckResult = validateCodeService.check(validateCode);
if(!codeCheckResult) throw new CrmebException("验证码不正确");
// 执行登录
SystemAdminRequest systemAdminRequest = new SystemAdminRequest();
systemAdminRequest.setAccount(systemAdminLoginRequest.getAccount());
systemAdminRequest.setPwd(systemAdminLoginRequest.getPwd());
SystemAdminResponse systemAdminResponse = systemAdminService.login(systemAdminRequest);
if(null == systemAdminResponse){
return CommonResult.failed(ExceptionCodeEnum.FAILED, "login failed");
}
return CommonResult.success(systemAdminResponse, "login success");
}
@ApiOperation(value="AdminUserLogout")
@GetMapping(value = "/logout")
public CommonResult<SystemAdminResponse> SystemAdminLogout(HttpServletRequest request) throws Exception {
String token = checkAdminToken.getTokenFormRequest(request);
// TokenModel tokenModel = tokenManager.getToken(token);
// if(StringUtils.isEmpty(tokenModel.getUserNo())){
// throw new CrmebException("");
// }
systemAdminService.logout(token);
return CommonResult.success("logout success");
}
@ApiOperation(value="GetAdminUserByToken")
@GetMapping(value = "/getAdminInfoByToken")
public CommonResult<SystemAdminResponse> getAdminInfo(HttpServletRequest request) throws Exception{
String token = checkAdminToken.getTokenFormRequest(request);
SystemAdminResponse systemAdminResponse = systemAdminService.getInfoByToken(token);
return CommonResult.success(systemAdminResponse);
}
/**
* 获取登录页图片
* @return Map<String, Object>
*/
@ApiOperation(value = "获取登录页图片")
@RequestMapping(value = "/getLoginPic", method = RequestMethod.GET)
public CommonResult<Map<String, Object>> getLoginPic(){
Map<String, Object> map = new HashMap<>();
//背景图
map.put("backgroundImage", systemConfigService.getValueByKey(Constants.CONFIG_KEY_ADMIN_LOGIN_BACKGROUND_IMAGE));
//logo
map.put("logo", systemConfigService.getValueByKey(Constants.CONFIG_KEY_ADMIN_LOGIN_LOGO));
//轮播图
List<SystemGroupDataAdminLoginBannerResponse> bannerList = systemGroupDataService.getListByGid(Constants.GROUP_DATA_ID_ADMIN_LOGIN_BANNER_IMAGE_LIST, SystemGroupDataAdminLoginBannerResponse.class);
map.put("banner", bannerList);
return CommonResult.success(map);
}
}

View File

@@ -0,0 +1,36 @@
package com.zbkj.crmeb.authorization.manager;
import com.common.CommonResult;
import com.zbkj.crmeb.authorization.model.TokenModel;
/**
* @author stivepeim
* @title: TokenManager
* @projectName crmeb
* @Description: TODO
* @since 2020/4/1415:27
*/
public interface TokenManager {
TokenModel createToken(String account, String value, String modelName);
boolean checkToken(String token, String modelName);
TokenModel getToken(String token, String modelName);
String getCurrentClienttype(String userno);
void deleteToken(String token, String modelName);
Integer getUserCount();
CommonResult<TokenModel> getOnlineUsers(Integer pageNo, Integer pageSize);
TokenModel getRealToken(String userno);
String getLocalInfoException(String key);
Object getLocalInfo(String key);
Integer getLocalUserId();
}

View File

@@ -0,0 +1,158 @@
package com.zbkj.crmeb.authorization.manager;
import com.common.CommonResult;
import com.constants.Constants;
import com.exception.CrmebException;
import com.utils.RedisUtil;
import com.utils.ThreadLocalUtil;
import com.zbkj.crmeb.authorization.model.TokenModel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
/**
* @author stivepeim
* @title: TokenManagerImpl
* @projectName crmeb
* @Description: 口令管理
* @since 2020/4/1415:29
*/
@Component
public class TokenManagerImpl implements TokenManager {
@Autowired
private HttpServletRequest request;
@Autowired
protected RedisUtil redisUtil;
/**
* 生成Token
* @param account String 账号
* @param value String 存储value
* @param modelName String 模块
* @author Mr.Zhang
* @since 2020-04-29
*/
@Override
public TokenModel createToken(String account, String value, String modelName) {
String _token = UUID.randomUUID().toString().replace("-", "");
TokenModel token = new TokenModel(account, _token);
token.setUserNo(account);
String clientType = request.getParameter("clienttype");
token.setClienttype(clientType == null ? "Web" : clientType);
token.setHost(request.getRemoteHost());
token.setLastAccessedTime(System.currentTimeMillis());
redisUtil.set(modelName + _token, value,
Constants.TOKEN_EXPRESS_MINUTES, TimeUnit.MINUTES);
Map<String, Object> hashedMap = new HashMap<>();
hashedMap.put(modelName, value);
ThreadLocalUtil.set(hashedMap);
return token;
}
/**
* 获取本地存储的实际
* @param key String 模块
* @author Mr.Zhang
* @since 2020-04-29
*/
@Override
public String getLocalInfoException(String key) {
Object value = ThreadLocalUtil.get(key);
if(value == null){
throw new CrmebException("登录信息已过期,请重新登录!");
}
return value.toString();
}
/**
* 获取本地存储的实际
* @param key String 模块
* @author Mr.Zhang
* @since 2020-04-29
*/
@Override
public Object getLocalInfo(String key) {
return ThreadLocalUtil.get(key);
}
/**
* 获取用户id
* @author Mr.Zhang
* @since 2020-04-29
*/
@Override
public Integer getLocalUserId() {
return Integer.parseInt(getLocalInfoException("id"));
}
/**
* 检测Token
* @param token String token
* @param modelName String 模块
* @author Mr.Zhang
* @since 2020-04-29
*/
@Override
public boolean checkToken(String token, String modelName) {
return redisUtil.exists(modelName + token);
}
/**
* 检测Token
* @param token String token
* @param modelName String 模块
* @author Mr.Zhang
* @since 2020-04-29
*/
@Override
public TokenModel getToken(String token, String modelName) {
Object o = redisUtil.get(modelName + token);
TokenModel tokenModel = new TokenModel();
// tokenModel.setUserNo(o.toString());
tokenModel.setUserId(Integer.parseInt(o.toString()));
return tokenModel;
}
@Override
public String getCurrentClienttype(String userno) {
return null;
}
/**
* 删除Token
* @param token String token
* @param modelName String 模块
* @author Mr.Zhang
* @since 2020-04-29
*/
@Override
public void deleteToken(String token, String modelName) {
redisUtil.remove(modelName +token);
}
@Override
public Integer getUserCount() {
return null;
}
@Override
public CommonResult<TokenModel> getOnlineUsers(Integer pageNo, Integer pageSize) {
return null;
}
@Override
public TokenModel getRealToken(String userno) {
return null;
}
}

View File

@@ -0,0 +1,51 @@
package com.zbkj.crmeb.authorization.model;
import com.utils.CrmebUtil;
import com.zbkj.crmeb.system.model.SystemAdmin;
import lombok.Data;
import java.io.Serializable;
import java.util.Locale;
/**
* @author stivepeim
* @title: TokenModel
* @projectName crmeb
* @Description: Token实体类
* @since 2020/4/1415:00
*/
@Data
public class TokenModel implements Serializable {
// 加密后的token key
public static final String TOKEN_KEY = "TOKEN";
// Redis 存储的key
public static final String TOKEN_REDIS = "TOKEN_ADMIN_";
// 用户号
private String userNo;
private Integer userId;
private String Token;
// 最后访问时间
private long lastAccessedTime = System.currentTimeMillis();
// 过期时间
private long expirationTime;
// 客户端类型
private String clienttype;
// 客户端语言
private Locale locale;
// 客户端ip
private String host;
// 当前登录用户信息
private SystemAdmin systemAdmin;
public String getAuthorization() throws Exception {
return CrmebUtil.encryptPassword(userNo+"_"+Token, TOKEN_KEY);
}
public TokenModel(String userno, String token){
this.userNo = userno;
this.Token = token;
}
public TokenModel() {
}
}

View File

@@ -0,0 +1,161 @@
package com.zbkj.crmeb.category.controller;
import com.common.CommonPage;
import com.common.CommonResult;
import com.common.PageParamRequest;
import com.exception.CrmebException;
import com.utils.CrmebUtil;
import com.zbkj.crmeb.category.model.Category;
import com.zbkj.crmeb.category.request.CategoryRequest;
import com.zbkj.crmeb.category.request.CategorySearchRequest;
import com.zbkj.crmeb.category.service.CategoryService;
import com.zbkj.crmeb.category.vo.CategoryTreeVo;
import com.zbkj.crmeb.system.service.SystemAttachmentService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* 分类表 前端控制器
*/
@Slf4j
@RestController
@RequestMapping("api/admin/category")
@Api(tags = "分类服务")
public class CategoryController {
@Autowired
private CategoryService categoryService;
@Autowired
private SystemAttachmentService systemAttachmentService;
/**
* 分页显示分类表
* @param request 搜索条件
* @param pageParamRequest 分页参数
* @author Mr.Zhang
* @since 2020-04-16
*/
@ApiOperation(value = "分页列表")
@RequestMapping(value = "/list", method = RequestMethod.GET)
public CommonResult<CommonPage<Category>> getList(@ModelAttribute CategorySearchRequest request, @ModelAttribute PageParamRequest pageParamRequest){
CommonPage<Category> categoryCommonPage = CommonPage.restPage(categoryService.getList(request, pageParamRequest));
return CommonResult.success(categoryCommonPage);
}
/**
* 新增分类表
* @param categoryRequest 新增参数
* @author Mr.Zhang
* @since 2020-04-16
*/
@ApiOperation(value = "新增")
@RequestMapping(value = "/save", method = RequestMethod.POST)
public CommonResult<String> save(@Validated CategoryRequest categoryRequest){
Category category = new Category();
BeanUtils.copyProperties(categoryRequest, category);
category.setPath(categoryService.getPathByPId(category.getPid()));
category.setExtra(systemAttachmentService.clearPrefix(category.getExtra()));
if(categoryService.save(category)){
return CommonResult.success();
}else{
return CommonResult.failed();
}
}
/**
* 删除分类表
* @param id Integer
* @author Mr.Zhang
* @since 2020-04-16
*/
@ApiOperation(value = "删除")
@RequestMapping(value = "/delete", method = RequestMethod.GET)
@ApiImplicitParam(name="id", value="分类ID")
public CommonResult<String> delete(@RequestParam(value = "id") Integer id){
if(categoryService.delete(id) > 0){
return CommonResult.success();
}else{
return CommonResult.failed();
}
}
/**
* 修改分类表
* @param id integer id
* @param categoryRequest 修改参数
* @author Mr.Zhang
* @since 2020-04-16
*/
@ApiOperation(value = "修改")
@RequestMapping(value = "/update", method = RequestMethod.POST)
@ApiImplicitParam(name="id", value="分类ID")
public CommonResult<String> update(@RequestParam Integer id, @ModelAttribute CategoryRequest categoryRequest){
if(null == id || id <= 0) throw new CrmebException("id 参数不合法");
categoryRequest.setExtra(systemAttachmentService.clearPrefix(categoryRequest.getExtra()));
if(categoryService.update(categoryRequest, id)){
return CommonResult.success();
}else{
return CommonResult.failed();
}
}
/**
* 查询分类表信息
* @param id Integer
* @author Mr.Zhang
* @since 2020-04-16
*/
@ApiOperation(value = "详情")
@RequestMapping(value = "/info", method = RequestMethod.GET)
@ApiImplicitParam(name="id", value="分类ID")
public CommonResult<Category> info(@RequestParam(value = "id") Integer id){
Category category = categoryService.getById(id);
return CommonResult.success(category);
}
/**
* 查询分类表信息
* @author Mr.Zhang
* @since 2020-04-16
*/
@ApiOperation(value = "获取tree结构的列表")
@RequestMapping(value = "/list/tree", method = RequestMethod.GET)
@ApiImplicitParams({
@ApiImplicitParam(name="type", value="类型ID | 类型1 产品分类2 附件分类3 文章分类, 4 设置分类, 5 菜单分类, 6 配置分类, 7 秒杀配置", example = "1"),
@ApiImplicitParam(name="status", value="-1=全部0=未生效1=已生效", example = "1")
})
public CommonResult<List<CategoryTreeVo>> getListTree(@RequestParam(name = "type") Integer type,
@RequestParam(name = "status") Integer status){
List<CategoryTreeVo> listTree = categoryService.getListTree(type, status);
return CommonResult.success(listTree);
}
/**
* 根据分类id集合获取分类数据
* @param ids String id集合字符串
* @since 2020-04-16
*/
@ApiOperation(value = "根据id集合获取分类列表")
@RequestMapping(value = "/list/ids", method = RequestMethod.GET)
@ApiImplicitParam(name = "ids", value="分类id集合")
public CommonResult<List<Category>> getByIds(@Validated @RequestParam(name = "ids") String ids){
return CommonResult.success(categoryService.getByIds(CrmebUtil.stringToArray(ids)));
}
}

View File

@@ -0,0 +1,16 @@
package com.zbkj.crmeb.category.dao;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.zbkj.crmeb.category.model.Category;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* <p>
* 分类表 Mapper 接口
* </p>
*
* @author Mr.Zhang
* @since 2020-04-16
*/
public interface CategoryDao extends BaseMapper<Category> {
}

View File

@@ -0,0 +1,58 @@
package com.zbkj.crmeb.category.model;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import java.io.Serializable;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
* <p>
* 分类表
* </p>
*
* @author Mr.Zhang
* @since 2020-04-16
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("eb_category")
@ApiModel(value="Category对象", description="分类表")
public class Category implements Serializable {
private static final long serialVersionUID=1L;
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
@ApiModelProperty(value = "父级ID")
private Integer pid;
@ApiModelProperty(value = "路径")
private String path;
@ApiModelProperty(value = "分类名称")
private String name;
@ApiModelProperty(value = "类型ID | 类型1 产品分类2 附件分类3 文章分类, 4 设置分类, 5 菜单分类, 6 配置分类, 7 秒杀配置 ")
private Integer type;
@ApiModelProperty(value = "地址")
private String url;
@ApiModelProperty(value = "扩展字段")
private String extra;
@ApiModelProperty(value = "状态, 0正常1失效")
private Boolean status;
@ApiModelProperty(value = "排序")
private Integer sort;
}

View File

@@ -0,0 +1,66 @@
package com.zbkj.crmeb.category.request;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import org.hibernate.validator.constraints.Range;
import javax.validation.constraints.DecimalMin;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
/**
* <p>
* 分类表
* </p>
*
* @author Mr.Zhang
* @since 2020-04-16
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("eb_category")
@ApiModel(value="Category对象", description="分类表")
public class CategoryRequest implements Serializable {
private static final long serialVersionUID=1L;
@ApiModelProperty(value = "父级ID")
@NotNull(message = "请选择父级分类")
@Min(value = 0, message = "请选择父级分类")
private Integer pid;
@ApiModelProperty(value = "分类名称")
@NotBlank(message = "分类名称必须填写")
private String name;
@ApiModelProperty(value = "类型类型1 产品分类2 附件分类3 文章分类, 4 设置分类, 5 菜单分类, 6 配置分类, 7 秒杀配置")
@NotNull(message = "类型必须选择")
@Range(min = 1, max = 6, message = "类型1 产品分类2 附件分类3 文章分类, 4 设置分类, 5 菜单分类, 6 配置分类, 7 秒杀配置之间") //取值范围
private Integer type;
@ApiModelProperty(value = "地址")
// @NotBlank(message = "地址名称必须填写")
private String url;
@ApiModelProperty(value = "扩展字段")
private String extra;
@ApiModelProperty(value = "状态, 0正常1失效")
@NotNull(message = "状态必须选择")
private Boolean status;
@ApiModelProperty(value = "排序")
@NotNull(message = "排序数字为空") //不可为空
@Min(value = 0, message = "排序数字必须大于等于0") //数字最小值为0
private Integer sort;
}

View File

@@ -0,0 +1,43 @@
package com.zbkj.crmeb.category.request;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.io.Serializable;
/**
* <p>
* 分类表
* </p>
*
* @author Mr.Zhang
* @since 2020-04-16
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("eb_category")
@ApiModel(value="Category对象", description="分类表")
public class CategorySearchRequest implements Serializable {
private static final long serialVersionUID=1L;
@ApiModelProperty(value = "父级ID")
private Integer pid;
@ApiModelProperty(value = "分类名称")
private String name;
@ApiModelProperty(value = "类型ID | 类型1 产品分类2 附件分类3 文章分类, 4 设置分类, 5 菜单分类, 6 配置分类, 7 秒杀配置")
private Integer type;
@ApiModelProperty(value = "状态, 0正常1失效")
private Boolean status;
}

View File

@@ -0,0 +1,39 @@
package com.zbkj.crmeb.category.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.common.PageParamRequest;
import com.zbkj.crmeb.category.model.Category;
import com.zbkj.crmeb.category.request.CategoryRequest;
import com.zbkj.crmeb.category.request.CategorySearchRequest;
import com.zbkj.crmeb.category.vo.CategoryTreeVo;
import java.util.HashMap;
import java.util.List;
/**
* @author Mr.Zhang
* @Description CategoryService 接口
* @since 2020-04-16
*/
public interface CategoryService extends IService<Category> {
List<Category> getList(CategorySearchRequest request, PageParamRequest pageParamRequest);
int delete(Integer id);
String getPathByPId(Integer pid);
List<CategoryTreeVo> getListTree(Integer type, Integer status);
List<CategoryTreeVo> getListTree(Integer type, Integer status, List<Integer> categoryIdList);
List<Category> getByIds(List<Integer> ids);
HashMap<Integer, String> getListInId(List<Integer> cateIdList);
void checkCategoryIsExist(List<Integer> categoryIdList);
Boolean checkAuth(List<Integer> pathIdList, String uri);
boolean update(CategoryRequest request, Integer id);
List<Category> getChildVoListByPid(Integer pid);
}

View File

@@ -0,0 +1,345 @@
package com.zbkj.crmeb.category.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.common.PageParamRequest;
import com.exception.CrmebException;
import com.github.pagehelper.PageHelper;
import com.utils.CrmebUtil;
import com.zbkj.crmeb.category.dao.CategoryDao;
import com.zbkj.crmeb.category.model.Category;
import com.zbkj.crmeb.category.request.CategoryRequest;
import com.zbkj.crmeb.category.request.CategorySearchRequest;
import com.zbkj.crmeb.category.service.CategoryService;
import com.zbkj.crmeb.category.vo.CategoryTreeVo;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @author Mr.Zhang
* @Description CategoryServiceImpl 接口实现
* @since 2020-04-16
*/
@Service
public class CategoryServiceImpl extends ServiceImpl<CategoryDao, Category> implements CategoryService {
@Resource
private CategoryDao dao;
/**
* 获取分类下子类的数量
* @param request 请求参数
* @param pageParamRequest 分页参数
* @author Mr.Zhang
* @since 2020-04-16
* @return List<Category>
*/
@Override
public List<Category> getList(CategorySearchRequest request, PageParamRequest pageParamRequest) {
PageHelper.startPage(pageParamRequest.getPage(), pageParamRequest.getLimit());
LambdaQueryWrapper<Category> lambdaQueryWrapper = new LambdaQueryWrapper<>();
Category category = new Category();
BeanUtils.copyProperties(request,category);
// objectQueryWrapper.setEntity(category);
if(null != category.getPid()){
lambdaQueryWrapper.eq(Category::getPid, category.getPid());
}
if(null != category.getType()){
lambdaQueryWrapper.eq(Category::getType, category.getType());
}
if(null != category.getStatus()){
lambdaQueryWrapper.eq(Category::getStatus, category.getStatus());
}
if(null != category.getName()){
lambdaQueryWrapper.like(Category::getName, category.getName());
}
lambdaQueryWrapper.orderByDesc(Category::getSort).orderByDesc(Category::getId);
return dao.selectList(lambdaQueryWrapper);
}
/**
* 通过id集合获取列表
* @param idList List<Integer> id集合
* @author Mr.Zhang
* @since 2020-04-16
* @return List<Category>
*/
@Override
public List<Category> getByIds(List<Integer> idList) {
LambdaQueryWrapper<Category> lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.in(Category::getId, idList);
return dao.selectList(lambdaQueryWrapper);
}
/**
* 通过id集合获取列表 id => name
* @param cateIdList List<Integer> id集合
* @author Mr.Zhang
* @since 2020-04-16
* @return HashMap<Integer, String>
*/
@Override
public HashMap<Integer, String> getListInId(List<Integer> cateIdList) {
HashMap<Integer, String> map = new HashMap<>();
List<Category> list = getByIds(cateIdList);
for (Category category : list){
map.put(category.getId(), category.getName());
}
return map;
}
/**
* 批量查询分类id是否合法
* @param categoryIdList List<Integer> id集合
* @author Mr.Zhang
* @since 2020-04-16
*/
@Override
public void checkCategoryIsExist(List<Integer> categoryIdList) {
//查询分类id是否合法
HashMap<Integer, String> categoryServiceListInId = getListInId(categoryIdList);
if(categoryServiceListInId.size() != categoryIdList.size()){
for (Integer categoryId: categoryIdList) {
String categoryName = CrmebUtil.getStrValueByIndex(categoryServiceListInId, categoryId);
if(categoryName.equals("")){
//如果取出的分类名称是空, 那么有问题
throw new CrmebException("ID是 " + categoryId + "的分类不存在,或者分类名称为空!");
}
}
}
}
/**
* 查询id和url是否存在
* @author Mr.Zhang
* @since 2020-04-16
* @return Boolean
*/
@Override
public Boolean checkAuth(List<Integer> pathIdList, String uri) {
LambdaQueryWrapper<Category> lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.in(Category::getId, pathIdList).eq(Category::getStatus, 1).eq(Category::getUrl, uri);
List<Category> categoryList = dao.selectList(lambdaQueryWrapper);
if(categoryList.size() < 1){
return false;
}
return true;
}
/**
* 修改
* @param request CategoryRequest
* @param id Integer
* @author Mr.Zhang
* @since 2020-04-16
* @return bool
*/
@Override
public boolean update(CategoryRequest request, Integer id) {
try{
//修改分类信息
Category category = new Category();
BeanUtils.copyProperties(request, category);
category.setId(id);
category.setPath(getPathByPId(category.getPid()));
updateById(category);
//如状态为关闭,那么所以子集的状态都关闭
if(!request.getStatus()){
updateStatusByPid(id, false);
}else{
//如是开启,则父类的状态为开启
updatePidStatusById(id);
}
return true;
}catch (Exception e){
e.printStackTrace();
return false;
}
}
/**
* 开启父级状态
* @param id Integer
* @author Mr.Zhang
* @since 2020-04-16
*/
private void updatePidStatusById(Integer id) {
Category category = getById(id);
List<Integer> categoryIdList = CrmebUtil.stringToArrayByRegex(category.getPath(), "/");
categoryIdList.removeIf(i -> i.equals(0));
ArrayList<Category> categoryArrayList = new ArrayList<>();
if(categoryIdList.size() < 1){
return;
}
for (Integer categoryId: categoryIdList) {
Category categoryVo = new Category();
categoryVo.setId(categoryId);
categoryVo.setStatus(true);
categoryArrayList.add(categoryVo);
}
updateBatchById(categoryArrayList);
}
/**
* 获取分类下子类的数量
* @param pid Integer
* @author Mr.Zhang
* @since 2020-04-16
* @return bool
*/
private int getChildCountByPid(Integer pid) {
//查看是否有子类
QueryWrapper<Category> objectQueryWrapper = new QueryWrapper<>();
// objectQueryWrapper.eq("status", 1);
objectQueryWrapper.like("path", "/"+pid+"/");
return dao.selectCount(objectQueryWrapper);
}
/**
* 修改分类以及子类的状态
* @param pid Integer
* @author Mr.Zhang
* @since 2020-04-16
* @return bool
*/
private int updateStatusByPid(Integer pid, boolean status) {
//查看是否有子类
Category category = new Category();
category.setStatus(status);
QueryWrapper<Category> objectQueryWrapper = new QueryWrapper<>();
objectQueryWrapper.like("path", "/"+pid+"/");
return dao.update(category, objectQueryWrapper);
}
@Override
public String getPathByPId(Integer pid) {
Category category = getById(pid);
if(null != category){
return category.getPath() + pid + "/";
}
return null;
}
/**
* 带结构的无线级分类
* @author Mr.Zhang
* @since 2020-04-16
*/
@Override
public List<CategoryTreeVo> getListTree(Integer type, Integer status) {
return getTree(type, status, null);
}
/**
* 带权限的属性结构
* @author Mr.Zhang
* @since 2020-04-16
*/
@Override
public List<CategoryTreeVo> getListTree(Integer type, Integer status, List<Integer> categoryIdList) {
return getTree(type, status, categoryIdList);
}
/**
* 带结构的无线级分类
* @author Mr.Zhang
* @since 2020-04-16
*/
private List<CategoryTreeVo> getTree(Integer type, Integer status, List<Integer> categoryIdList) {
//循环数据把数据对象变成带list结构的vo
List<CategoryTreeVo> treeList = new ArrayList<>();
LambdaQueryWrapper<Category> lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.eq(Category::getType, type);
if(null != categoryIdList && categoryIdList.size() > 0){
lambdaQueryWrapper.in(Category::getId, categoryIdList);
}
if(status >= 0){
lambdaQueryWrapper.eq(Category::getStatus, status);
}
lambdaQueryWrapper.orderByDesc(Category::getSort);
lambdaQueryWrapper.orderByAsc(Category::getId);
List<Category> allTree = dao.selectList(lambdaQueryWrapper);
if(allTree == null){
return null;
}
for (Category category: allTree) {
CategoryTreeVo categoryTreeVo = new CategoryTreeVo();
BeanUtils.copyProperties(category, categoryTreeVo);
treeList.add(categoryTreeVo);
}
//返回
Map<Integer, CategoryTreeVo> map = new HashMap<>();
//ID 为 key 存储到map 中
for (CategoryTreeVo categoryTreeVo1 : treeList) {
map.put(categoryTreeVo1.getId(), categoryTreeVo1);
}
List<CategoryTreeVo> list = new ArrayList<>();
for (CategoryTreeVo tree : treeList) {
//子集ID返回对象有则添加。
CategoryTreeVo tree1 = map.get(tree.getPid());
if(tree1 != null){
tree1.getChild().add(tree);
}else {
list.add(tree);
}
}
return list;
}
/**
* 删除分类表
* @param id Integer
* @author Mr.Zhang
* @since 2020-04-16
* @return bool
*/
@Override
public int delete(Integer id) {
//查看是否有子类, 物理删除
if(getChildCountByPid(id) > 0){
throw new CrmebException("当前分类下有子类,请先删除子类!");
}
return dao.deleteById(id);
}
/**
* 获取分类下子类
* @param pid Integer
* @author Mr.Zhang
* @since 2020-04-16
* @return List<Category>
*/
@Override
public List<Category> getChildVoListByPid(Integer pid) {
//查看是否有子类
QueryWrapper<Category> objectQueryWrapper = new QueryWrapper<>();
objectQueryWrapper.eq("status", 1);
objectQueryWrapper.like("path", "/"+pid+"/");
return dao.selectList(objectQueryWrapper);
}
}

View File

@@ -0,0 +1,55 @@
package com.zbkj.crmeb.category.vo;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.fasterxml.jackson.annotation.JsonInclude;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
/**
* <p>
* 分类表
* </p>
*
* @author Mr.Zhang
* @since 2020-04-16
*/
@Data
public class CategoryTreeVo implements Serializable {
private static final long serialVersionUID=1L;
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
@ApiModelProperty(value = "父级ID")
private Integer pid;
@ApiModelProperty(value = "路径")
private String path;
@ApiModelProperty(value = "分类名称")
private String name;
@ApiModelProperty(value = "类型类型1 产品分类2 附件分类3 文章分类, 4 设置分类, 5 菜单分类, 6 配置分类, 7 秒杀配置")
private Integer type;
@ApiModelProperty(value = "地址")
private String url;
@ApiModelProperty(value = "扩展字段")
private String extra;
@ApiModelProperty(value = "状态, 0正常1失效")
private Boolean status;
@ApiModelProperty(value = "排序")
private Integer sort;
@JsonInclude(JsonInclude.Include.NON_EMPTY) //属性为 空(""[] 或者为 NULL 都不序列化
private List<CategoryTreeVo> child = new ArrayList<>();
}

View File

@@ -0,0 +1,26 @@
package com.zbkj.crmeb.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
@Configuration
public class CorsConfig{
private CorsConfiguration buildConfig() {
CorsConfiguration corsConfiguration = new CorsConfiguration();
corsConfiguration.addAllowedOrigin("*"); //允许任何域名
corsConfiguration.addAllowedHeader("*"); //允许任何头
corsConfiguration.addAllowedMethod("*"); //允许任何方法
return corsConfiguration;
}
@Bean
public CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", buildConfig()); //注册
return new CorsFilter(source);
}
}

View File

@@ -0,0 +1,48 @@
package com.zbkj.crmeb.config;
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.support.http.StatViewServlet;
import com.alibaba.druid.support.http.WebStatFilter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.sql.DataSource;
import java.io.IOException;
import java.io.InputStream;
import java.sql.SQLException;
import java.util.Properties;
@Configuration
public class DruidConfig {
@Bean
public ServletRegistrationBean druidServlet() { // 主要实现WEB监控的配置处理
ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(new StatViewServlet(), "/druid/*"); // 进行druid监控的配置处理操作
// servletRegistrationBean.addInitParameter("allow",
// "127.0.0.1,192.168.1.159"); // 白名单
// servletRegistrationBean.addInitParameter("deny", "192.168.1.200"); // 黑名单
servletRegistrationBean.addInitParameter("loginUsername", "kf"); // 用户名
servletRegistrationBean.addInitParameter("loginPassword", "654321"); // 密码
servletRegistrationBean.addInitParameter("resetEnable", "true"); // 是否可以重置数据源
return servletRegistrationBean ;
}
@Bean
public FilterRegistrationBean filterRegistrationBean() {
FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean() ;
filterRegistrationBean.setFilter(new WebStatFilter());
filterRegistrationBean.addUrlPatterns("/*"); // 所有请求进行监控处理
//不必监控的请求
filterRegistrationBean.addInitParameter("exclusions", "*.html,*.png,*.ico,*.js,*.gif,*.jpg,*.css,/druid/*");
return filterRegistrationBean ;
}
@Bean
@ConfigurationProperties(prefix = "spring.datasource")
public DataSource druidDataSource() {
return new DruidDataSource();
}
}

View File

@@ -0,0 +1,25 @@
package com.zbkj.crmeb.config;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.math.BigDecimal;
@Configuration
public class JacksonConfig {
/**
* Jackson全局转化BigDecimal类型为String解决jackson序列化时BigDecimal类型缺失精度问题
*
* @return Jackson2ObjectMapperBuilderCustomizer 注入的对象
*/
@Bean
public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() {
return jacksonObjectMapperBuilder -> jacksonObjectMapperBuilder.serializerByType(BigDecimal.class, ToStringSerializer.instance);
}
}

View File

@@ -0,0 +1,109 @@
package com.zbkj.crmeb.config;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import redis.clients.jedis.JedisPoolConfig;
@Configuration
@EnableCaching
public class RedisConfig {
@Value("${spring.redis.host}")
private String redisHost;
@Value("${spring.redis.port}")
private int redisPort;
@Value("${spring.redis.password}")
private String redisPass;
@Value("${spring.redis.database}")
private int redisDb;
@Value("${spring.redis.timeout}")
private String timeout;
@Value("${spring.redis.jedis.pool.max-active}")
private int maxTotal;
@Value("${spring.redis.jedis.pool.max-idle}")
private int maxIdle;
@Value("${spring.redis.jedis.pool.max-wait}")
private int maxWaitMillis;
// @Value("${redis.task.config.minEvictableIdleTimeMillis}")
// private String minEvictableIdleTimeMillis;
// @Value("${redis.task.config.numTestsPerEvictionRun}")
// private int numTestsPerEvictionRun;
@Value("${spring.redis.jedis.pool.time-between-eviction-runs}")
private String timeBetweenEvictionRunsMillis;
// @Value("${redis.task.config.testOnBorrow}")
// private Boolean testOnBorrow;
// @Value("${redis.task.config.testWhileIdle}")
// private Boolean testWhileIdle;
@Bean
@Primary
public RedisConnectionFactory taskConnectionFactory() {
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
jedisPoolConfig.setMaxIdle(maxIdle);
jedisPoolConfig.setMaxTotal(maxTotal);
jedisPoolConfig.setMaxWaitMillis(maxWaitMillis);
// jedisPoolConfig.setMinEvictableIdleTimeMillis(Integer.parseInt(minEvictableIdleTimeMillis));
// jedisPoolConfig.setNumTestsPerEvictionRun(numTestsPerEvictionRun);
jedisPoolConfig.setTimeBetweenEvictionRunsMillis(Integer.parseInt(timeBetweenEvictionRunsMillis));
// jedisPoolConfig.setTestOnBorrow(testOnBorrow);
// jedisPoolConfig.setTestWhileIdle(testWhileIdle);
JedisConnectionFactory connectionFactory = new JedisConnectionFactory(jedisPoolConfig);
connectionFactory.setPort(redisPort);
connectionFactory.setHostName(redisHost);
connectionFactory.setDatabase(redisDb);
connectionFactory.setPassword(redisPass);
//配置连接池属性
connectionFactory.setTimeout(Integer.parseInt(timeout));
return connectionFactory;
}
@Bean
public RedisTemplate<Object,Object> redisTemplate(){
RedisTemplate<Object, Object> template = new RedisTemplate<Object, Object>();
template.setConnectionFactory(taskConnectionFactory());
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer =
new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
template.setKeySerializer(new StringRedisSerializer());
template.setValueSerializer(jackson2JsonRedisSerializer);
template.afterPropertiesSet();
return template;
}
}

View File

@@ -0,0 +1,43 @@
package com.zbkj.crmeb.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.client.RestTemplate;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
@Configuration
public class RestTemplateConfig {
@Bean
public RestTemplate restTemplate(ClientHttpRequestFactory factory) {
RestTemplate restTemplate = new RestTemplate(factory);
restTemplate.getMessageConverters().set(1, new StringHttpMessageConverter(StandardCharsets.UTF_8));
restTemplate.getMessageConverters().add(new WxMappingJackson2HttpMessageConverter());
return restTemplate;
}
@Bean
public ClientHttpRequestFactory httpRequestFactory() {
SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
factory.setReadTimeout(10000);//ms
factory.setConnectTimeout(15000);//ms
return factory;
}
//解决微信返回json Content-Type 值却是 text/plain 的问题
public class WxMappingJackson2HttpMessageConverter extends MappingJackson2HttpMessageConverter {
public WxMappingJackson2HttpMessageConverter(){
List<MediaType> mediaTypes = new ArrayList<>();
mediaTypes.add(MediaType.TEXT_PLAIN);
mediaTypes.add(MediaType.TEXT_HTML);
setSupportedMediaTypes(mediaTypes);
}
}
}

View File

@@ -0,0 +1,24 @@
package com.zbkj.crmeb.config;
import lombok.Data;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
@Data
@Configuration
public class SchedulerConfig implements SchedulingConfigurer {
private final int poolSize = 30;
@Override
public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) {
ThreadPoolTaskScheduler threadPoolTaskScheduler = new ThreadPoolTaskScheduler();
threadPoolTaskScheduler.setPoolSize(getPoolSize());
threadPoolTaskScheduler.setThreadNamePrefix("crmeb-scheduled-task-pool-");
threadPoolTaskScheduler.initialize();
scheduledTaskRegistrar.setTaskScheduler(threadPoolTaskScheduler);
}
}

View File

@@ -0,0 +1,146 @@
package com.zbkj.crmeb.config;
import com.constants.Constants;
import com.google.common.base.Predicate;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.*;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spi.service.contexts.SecurityContext;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
import java.util.ArrayList;
import java.util.List;
import static com.google.common.collect.Lists.newArrayList;
/**
* Created by Mr.Zhang on 2020/04/11.
*/
@Configuration
@EnableSwagger2
public class SwaggerConfig{
//是否开启swagger正式环境一般是需要关闭的可根据springboot的多环境配置进行设置
Boolean swaggerEnabled = true;
@Value("${server.port}")
private String port;
@Value("${server.domain}")
private String domain;
@Bean("admin")
public Docket createRestApis() {
return new Docket(DocumentationType.SWAGGER_2)
.groupName("admin")
.host(domain)
.apiInfo(apiInfo())
// 是否开启
.enable(swaggerEnabled)
.select()
// 扫描的路径包
.apis(RequestHandlerSelectors.basePackage("com.zbkj.crmeb"))
// 指定路径处理PathSelectors.any()代表所有的路径
.paths(adminPathsAnt())
.build()
.securitySchemes(security())
.securityContexts(securityContexts())
// .globalOperationParameters(pars) // 针对单个url的验证 如果需要的话
.pathMapping("/");
}
@Bean("front")
public Docket create1RestApis() {
return new Docket(DocumentationType.SWAGGER_2)
.groupName("front")
.host(domain)
.apiInfo(apiInfo())
// 是否开启
.enable(swaggerEnabled)
.select()
// 扫描的路径包
.apis(RequestHandlerSelectors.basePackage("com.zbkj.crmeb"))
// 指定路径处理PathSelectors.any()代表所有的路径
.paths(frontPathsAnt()) //只监听
.build()
.securitySchemes(security())
.securityContexts(securityContexts())
// .globalOperationParameters(pars) // 针对单个url的验证 如果需要的话
.pathMapping("/");
}
@Bean("public")
public Docket create2RestApis() {
return new Docket(DocumentationType.SWAGGER_2)
.groupName("public")
.host(domain)
.apiInfo(apiInfo())
// 是否开启
.enable(swaggerEnabled)
.select()
// 扫描的路径包
.apis(RequestHandlerSelectors.basePackage("com.zbkj.crmeb"))
// 指定路径处理PathSelectors.any()代表所有的路径
.paths(publicPathsAnt()) //只监听
.build()
.securitySchemes(security())
.securityContexts(securityContexts())
// .globalOperationParameters(pars) // 针对单个url的验证 如果需要的话
.pathMapping("/");
}
private Predicate<String> adminPathsAnt() {
return PathSelectors.ant("/api/admin/**");
}
private Predicate<String> frontPathsAnt() {
return PathSelectors.ant("/api/front/**");
}
private Predicate<String> publicPathsAnt() {
return PathSelectors.ant("/api/public/**");
}
private List<ApiKey> security() {
return newArrayList(
new ApiKey(Constants.HEADER_AUTHORIZATION_KEY, Constants.HEADER_AUTHORIZATION_KEY, "header")
);
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("Crmeb Java")
.description("Crmeb")
.termsOfServiceUrl("http://host:port/swagger-ui.html#/")
.version("1.0.0").build();
}
private List<SecurityContext> securityContexts() {
List<SecurityContext> res = new ArrayList<>();
res.add(SecurityContext.builder()
.securityReferences(defaultAuth())
.forPaths(PathSelectors.regex("/.*"))
.build());
return res;
}
private List<SecurityReference> defaultAuth() {
List<SecurityReference> res = new ArrayList<>();
AuthorizationScope authorizationScope = new AuthorizationScope("global", Constants.HEADER_AUTHORIZATION_KEY);
AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];
authorizationScopes[0] = authorizationScope;
res.add(new SecurityReference(Constants.HEADER_AUTHORIZATION_KEY, authorizationScopes));
return res;
}
}

View File

@@ -0,0 +1,96 @@
package com.zbkj.crmeb.config;
import lombok.Data;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadPoolExecutor;
/**
* task 类的线程池配置
*/
@Data
@Configuration
public class TaskExecutorConfig {
//普通模式
private final int taskCorePoolSize = 20; //核心线程池数量
private final int taskMaxPoolSize = 100; //最大线程
private final int taskQueueCapacity = 200; //缓存队列条数
private final int taskKeepAliveSecond = 10; //允许的空闲时间
private final String taskNamePrefix = "task-executor-"; //线程名称前缀
//发布订阅模式
// private final int listenerCorePoolSize = 3;
// private final int listenerMaxPoolSize = 20;
// private final int listenerQueueCapacity = 200;
// private final int listenerKeepAliveSecond = 10;
// private final String listenerNamePrefix = "listener-executor-";
//普通模式
@Bean("taskExecutor")
public ThreadPoolTaskExecutor taskExecutor(){
return initTaskExecutor(
getTaskCorePoolSize(),
getTaskMaxPoolSize(),
getTaskQueueCapacity(),
getTaskKeepAliveSecond(),
getTaskNamePrefix()
);
}
// //针对发布订阅pub listener 的线程池
// @Bean("listenerTaskExecutor")
// public ThreadPoolTaskExecutor listenerTaskExecutor(){
// return initTaskExecutor(getListenerCorePoolSize(), getListenerMaxPoolSize(),
// getListenerQueueCapacity(), getListenerKeepAliveSecond(), getListenerNamePrefix());
// }
/**
*
* 初始化TaskExecutor
* @param corePoolSize int 默认线程数
* @param maxPoolSize int 最大线程数
* @param queueCapacity int 缓冲队列长度
* @param keepAliveSecond int 允许空闲时间
* @param namePrefix String 名称的前缀
*
* @return ThreadPoolTaskExecutor
*/
private ThreadPoolTaskExecutor initTaskExecutor(int corePoolSize, int maxPoolSize,
int queueCapacity, int keepAliveSecond, String namePrefix){
//callrunspolicy由调度线程(提交任务的线程)处理该任务CallerRunsPolicy
return initTaskExecutor(corePoolSize, maxPoolSize, queueCapacity, keepAliveSecond, namePrefix,
new ThreadPoolExecutor.CallerRunsPolicy());
}
/**
* 初始化TaskExecutor
* @param corePoolSize int 默认线程数
* @param maxPoolSize int 最大线程数
* @param queueCapacity int 缓冲队列长度
* @param keepAliveSecond int 允许空闲时间
* @param namePrefix String 名称的前缀
* @param rejectedExecutionHandler 线程池满的时候如何处理
* @return ThreadPoolTaskExecutor
*/
private ThreadPoolTaskExecutor initTaskExecutor(int corePoolSize, int maxPoolSize,
int queueCapacity, int keepAliveSecond, String namePrefix,
RejectedExecutionHandler rejectedExecutionHandler){
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(corePoolSize);//核心线程数(默认线程数)
executor.setMaxPoolSize(maxPoolSize);//最大线程数
executor.setQueueCapacity(queueCapacity);//缓冲队列数
executor.setKeepAliveSeconds(keepAliveSecond);//允许线程空闲时间(单位默认为秒)
executor.setThreadNamePrefix(namePrefix);//线程名前缀
//线程池对拒绝任务的处理策略,
executor.setRejectedExecutionHandler(rejectedExecutionHandler);
//初始化
executor.initialize();
return executor;
}
}

View File

@@ -0,0 +1,144 @@
package com.zbkj.crmeb.config;
import com.filter.ResponseFilter;
import com.interceptor.AdminAuthInterceptor;
import com.interceptor.AdminTokenInterceptor;
import com.interceptor.FrontTokenInterceptor;
import com.interceptor.SwaggerInterceptor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.handler.MappedInterceptor;
//token验证拦截器
@Configuration
public class WebConfig implements WebMvcConfigurer {
// 这里使用一个Bean为的是可以在拦截器中自由注入也可以在拦截器中使用SpringUtil.getBean 获取
// 但是觉得这样更优雅
@Bean
public HandlerInterceptor adminAuthInterceptor(){
return new AdminAuthInterceptor();
}
@Bean
public HandlerInterceptor adminTokenInterceptor(){
return new AdminTokenInterceptor();
}
@Bean
public HandlerInterceptor frontTokenInterceptor(){
return new FrontTokenInterceptor();
}
@Bean
public ResponseFilter responseFilter(){ return new ResponseFilter(); }
@Value("${swagger.basic.username}")
private String username;
@Value("${swagger.basic.password}")
private String password;
@Value("${swagger.basic.check}")
private Boolean check;
@Override
public void addInterceptors(InterceptorRegistry registry) {
//添加token拦截器
//addPathPatterns添加需要拦截的命名空间
//excludePathPatterns添加排除拦截命名空间
//后台token拦截
registry.addInterceptor(adminTokenInterceptor()).
addPathPatterns("/api/admin/**").
excludePathPatterns("/api/admin/validate/**").
excludePathPatterns("/api/admin/login").
excludePathPatterns("/api/admin/logout").
excludePathPatterns("/api/admin/getLoginPic").
excludePathPatterns("/api/admin/payment/callback/**").
excludePathPatterns("/swagger-resources/**", "/webjars/**", "/v2/**", "/swagger-ui.html/**");
//后台权限规则
registry.addInterceptor(adminAuthInterceptor()).
addPathPatterns("/api/admin/**").
excludePathPatterns("/api/admin/validate/**").
excludePathPatterns("/api/admin/login").
excludePathPatterns("/api/admin/logout").
excludePathPatterns("/api/admin/getLoginPic").
excludePathPatterns("/api/admin/payment/callback/**").
excludePathPatterns("/swagger-resources/**", "/webjars/**", "/v2/**", "/swagger-ui.html/**");
//前端用户登录token
registry.addInterceptor(frontTokenInterceptor()).
addPathPatterns("/api/front/**").
excludePathPatterns("/api/front/qrcode/**").
excludePathPatterns("/api/front/login/mobile").
excludePathPatterns("/api/front/login").
excludePathPatterns("/api/front/sendCode").
excludePathPatterns("/api/front/wechat/**").
excludePathPatterns("/api/front/search/keyword").
excludePathPatterns("/api/front/share").
excludePathPatterns("/api/front/article/**").
excludePathPatterns("/api/front/city/**").
excludePathPatterns("/api/front/product/**").
excludePathPatterns("/api/front/products/**").
excludePathPatterns("/api/front/reply/**").
excludePathPatterns("/api/front/user/service/**").
excludePathPatterns("/api/front/coupons").
excludePathPatterns("/api/front/logistics").
excludePathPatterns("/api/front/groom/list/**").
excludePathPatterns("/api/front/index").
excludePathPatterns("/api/front/category").
excludePathPatterns("/swagger-resources/**", "/webjars/**", "/v2/**", "/swagger-ui.html/**");
}
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/**")
.addResourceLocations("classpath:/static/");
registry.addResourceHandler("swagger-ui.html")
.addResourceLocations("classpath:/META-INF/resources/");
registry.addResourceHandler("/webjars/**")
.addResourceLocations("classpath:/META-INF/resources/webjars/");
}
@Bean
public FilterRegistrationBean filterRegister()
{
//注册过滤器
FilterRegistrationBean registration = new FilterRegistrationBean(responseFilter());
registration.addUrlPatterns("/*");
return registration;
}
/* 必须在此处配置拦截器,要不然拦不到swagger的静态资源 */
@Bean
@ConditionalOnProperty(name = "swagger.basic.enable", havingValue = "true")
public MappedInterceptor getMappedInterceptor() {
return new MappedInterceptor(new String[]{"/swagger-ui.html", "/webjars/**"}, new SwaggerInterceptor(username, password, check));
}
// 验证参数是否完全匹配
// @Override
// public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
// WebMvcConfigurer.super.configureMessageConverters(converters);
// MappingJackson2HttpMessageConverter jackson2HttpMessageConverter = new MappingJackson2HttpMessageConverter(getObjectMapper());
// converters.add(jackson2HttpMessageConverter);
// }
// @Bean
// public ObjectMapper getObjectMapper() {
// ObjectMapper mapper = new ObjectMapper();
// mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, true);
// mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
// return mapper;
// }
}

View File

@@ -0,0 +1,50 @@
package com.zbkj.crmeb.export.controller;
import com.utils.ExcelUtil;
import com.zbkj.crmeb.export.service.ExcelService;
import com.zbkj.crmeb.export.vo.ProductExcelVo;
import com.zbkj.crmeb.store.request.StoreProductSearchRequest;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
/**
* 商品表 前端控制器
*/
@Slf4j
@RestController
@RequestMapping("api/admin/export/excel")
@Api(tags = "导出 -- Excel")
public class ExcelController {
@Autowired
private ExcelService excelService;
/**
* 商品导出
* @param request 搜索条件
* @author Mr.Zhang
* @since 2020-05-06
*/
@ApiOperation(value = "产品")
@RequestMapping(value = "/product", method = RequestMethod.GET)
public void export(@Validated StoreProductSearchRequest request, HttpServletResponse response){
List<ProductExcelVo> productExcelVoList = excelService.product(request, response);
ExcelUtil.setSheetName("store"); //sheet名称
ExcelUtil.setFileName("产品导出"); //文件名称前缀 xx_yyyymmddhhiiss
ExcelUtil.writeExcel(response, productExcelVoList, ProductExcelVo.class);
}
}

View File

@@ -0,0 +1,16 @@
package com.zbkj.crmeb.export.service;
import com.zbkj.crmeb.export.vo.ProductExcelVo;
import com.zbkj.crmeb.store.request.StoreProductSearchRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
/**
* @author Mr.Zhang
* @Description StoreProductService 接口
* @since 2020-05-06
*/
public interface ExcelService{
List<ProductExcelVo> product(StoreProductSearchRequest request, HttpServletResponse response);
}

View File

@@ -0,0 +1,101 @@
package com.zbkj.crmeb.export.service.impl;
import com.common.PageParamRequest;
import com.constants.Constants;
import com.exception.CrmebException;
import com.github.pagehelper.PageInfo;
import com.utils.CrmebUtil;
import com.zbkj.crmeb.category.service.CategoryService;
import com.zbkj.crmeb.export.service.ExcelService;
import com.zbkj.crmeb.export.vo.ProductExcelVo;
import com.zbkj.crmeb.store.request.StoreProductSearchRequest;
import com.zbkj.crmeb.store.response.StoreProductResponse;
import com.zbkj.crmeb.store.service.StoreProductRelationService;
import com.zbkj.crmeb.store.service.StoreProductService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;
/**
* @author Mr.Zhang
* @Description ExcelServiceImpl 接口实现
* @since 2020-05-06
*/
@Service
public class ExcelServiceImpl implements ExcelService {
@Autowired
private StoreProductService storeProductService;
@Autowired
private CategoryService categoryService;
@Autowired
private StoreProductRelationService storeProductRelationService;
/**
* 商品列表导出
* @param request 请求参数
* @param response 返回数据
* @author Mr.Zhang
* @since 2020-05-06
*/
@Override
public List<ProductExcelVo> product(StoreProductSearchRequest request, HttpServletResponse response) {
PageParamRequest pageParamRequest = new PageParamRequest();
pageParamRequest.setPage(Constants.DEFAULT_PAGE);
pageParamRequest.setLimit(Constants.EXPORT_MAX_LIMIT);
PageInfo<StoreProductResponse> storeProductResponsePageInfo = storeProductService.getList(request, pageParamRequest);
List<StoreProductResponse> list = storeProductResponsePageInfo.getList();
if(list.size() < 1){
throw new CrmebException("没有可导出的数据!");
}
//从集合中取出ID
List<Integer> idList = list.stream().map(StoreProductResponse::getId).distinct().collect(Collectors.toList());
//产品分类id
List<String> cateIdListStr = list.stream().map(StoreProductResponse::getCateId).distinct().collect(Collectors.toList());
HashMap<Integer, String> categoryNameList = new HashMap<Integer, String>();
if(cateIdListStr.size() > 0){
String join = StringUtils.join(cateIdListStr, ",");
List<Integer> cateIdList = CrmebUtil.stringToArray(join);
categoryNameList = categoryService.getListInId(cateIdList);
}
//点赞
HashMap<Integer, Integer> likeCount = storeProductRelationService.getLikeCountListInProductId(idList);
//收藏
HashMap<Integer, Integer> collectCount = storeProductRelationService.getCollectCountListInProductId(idList);
ArrayList<ProductExcelVo> productExcelVoList = new ArrayList<>();
for (StoreProductResponse storeProductResponse : list ) {
productExcelVoList.add(
new ProductExcelVo(
storeProductResponse.getStoreName(),
storeProductResponse.getStoreInfo(),
CrmebUtil.getValueByIndex(categoryNameList, storeProductResponse.getCateId()),
storeProductResponse.getPrice(),
storeProductResponse.getSales(),
storeProductResponse.getStock(),
CrmebUtil.getIntValueByIndex(likeCount, storeProductResponse.getId()),
CrmebUtil.getIntValueByIndex(collectCount, storeProductResponse.getId())
)
);
}
return productExcelVoList;
}
}

View File

@@ -0,0 +1,13 @@
package com.zbkj.crmeb.export.vo;
import java.lang.annotation.*;
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ExcelColumn {
String value() default "";
int col() default 0;
}

View File

@@ -0,0 +1,64 @@
package com.zbkj.crmeb.export.vo;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiModel;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.math.BigDecimal;
/**
* <p>
* 商品表
* </p>
*
* @author Mr.Zhang
* @since 2020-05-06
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@ApiModel(value="ProductExcelVo对象", description = "产品导出")
public class ProductExcelVo implements Serializable {
private static final long serialVersionUID=1L;
public ProductExcelVo() {}
public ProductExcelVo(String storeName, String storeInfo, String cateName, BigDecimal price, Integer sales, Integer stock, Integer like, Integer collect) {
this.storeName = storeName;
this.storeInfo = storeInfo;
this.cateName = cateName;
this.price = price;
this.sales = sales;
this.stock = stock;
this.like = like;
this.collect = collect;
}
@ExcelColumn(value = "商品名称", col = 1)
private String storeName;
@ExcelColumn(value = "商品简介", col = 2)
private String storeInfo;
@ExcelColumn(value = "分类", col = 3)
private String cateName;
@ExcelColumn(value = "商品价格", col = 4)
private BigDecimal price;
@ExcelColumn(value = "销量", col = 5)
private Integer sales;
@ExcelColumn(value = "库存", col = 6)
private Integer stock;
@ExcelColumn(value = "点赞人数", col = 7)
private Integer like;
@ExcelColumn(value = "收藏人数", col = 8)
private Integer collect;
}

View File

@@ -0,0 +1,123 @@
package com.zbkj.crmeb.express.controller;
import com.common.CommonPage;
import com.common.CommonResult;
import com.common.PageParamRequest;
import com.zbkj.crmeb.express.request.ExpressRequest;
import com.zbkj.crmeb.express.request.ExpressSearchRequest;
import io.swagger.annotations.ApiImplicitParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.BeanUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import com.zbkj.crmeb.express.service.ExpressService;
import com.zbkj.crmeb.express.model.Express;
/**
* 快递公司表 前端控制器
*/
@Slf4j
@RestController
@RequestMapping("api/admin/express")
@Api(tags = "设置 -- 物流 -- 公司")
public class ExpressController {
@Autowired
private ExpressService expressService;
/**
* 分页显示快递公司表
* @param request ExpressSearchRequest 搜索条件
* @param pageParamRequest 分页参数
* @author Mr.Zhang
* @since 2020-04-17
*/
@ApiOperation(value = "分页列表")
@RequestMapping(value = "/list", method = RequestMethod.GET)
@ApiImplicitParam(name="keywords", value="搜索关键字")
public CommonResult<CommonPage<Express>> getList(@Validated ExpressSearchRequest request,
@ModelAttribute PageParamRequest pageParamRequest){
CommonPage<Express> expressCommonPage = CommonPage.restPage(expressService.getList(request, pageParamRequest));
return CommonResult.success(expressCommonPage);
}
/**
* 新增快递公司表
* @param expressRequest 新增参数
* @author Mr.Zhang
* @since 2020-04-17
*/
@ApiOperation(value = "新增")
@RequestMapping(value = "/save", method = RequestMethod.POST)
public CommonResult<String> save(@ModelAttribute ExpressRequest expressRequest){
Express express = new Express();
BeanUtils.copyProperties(expressRequest, express);
if(expressService.save(express)){
return CommonResult.success();
}else{
return CommonResult.failed();
}
}
/**
* 删除快递公司表
* @param id Integer
* @author Mr.Zhang
* @since 2020-04-17
*/
@ApiOperation(value = "删除")
@RequestMapping(value = "/delete", method = RequestMethod.GET)
@ApiImplicitParam(name="id", value="快递ID")
public CommonResult<String> delete(@RequestParam(value = "id") Integer id){
if(expressService.removeById(id)){
return CommonResult.success();
}else{
return CommonResult.failed();
}
}
/**
* 修改快递公司表
* @param id integer id
* @param expressRequest 修改参数
* @author Mr.Zhang
* @since 2020-04-17
*/
@ApiOperation(value = "修改")
@RequestMapping(value = "/update", method = RequestMethod.POST)
@ApiImplicitParam(name="id", value="快递ID")
public CommonResult<String> update(@RequestParam Integer id, @ModelAttribute ExpressRequest expressRequest){
Express express = new Express();
BeanUtils.copyProperties(expressRequest, express);
express.setId(id);
if(expressService.updateById(express)){
return CommonResult.success();
}else{
return CommonResult.failed();
}
}
/**
* 查询快递公司表信息
* @param id Integer
* @author Mr.Zhang
* @since 2020-04-17
*/
@ApiOperation(value = "详情")
@RequestMapping(value = "/info", method = RequestMethod.GET)
@ApiImplicitParam(name="id", value="快递ID")
public CommonResult<Express> info(@RequestParam(value = "id") Integer id){
Express express = expressService.getById(id);
return CommonResult.success(express);
}
}

View File

@@ -0,0 +1,104 @@
package com.zbkj.crmeb.express.controller;
import com.common.CommonPage;
import com.common.CommonResult;
import com.common.PageParamRequest;
import com.zbkj.crmeb.express.request.ShippingTemplatesRequest;
import com.zbkj.crmeb.express.request.ShippingTemplatesSearchRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.BeanUtils;
import org.springframework.web.bind.annotation.*;
import com.zbkj.crmeb.express.service.ShippingTemplatesService;
import com.zbkj.crmeb.express.model.ShippingTemplates;
/**
* 前端控制器
*/
@Slf4j
@RestController
@RequestMapping("api/admin/express/shipping/templates")
@Api(tags = "设置 -- 物流 -- 模板")
public class ShippingTemplatesController {
@Autowired
private ShippingTemplatesService shippingTemplatesService;
/**
* 分页显示
* @param request 搜索条件
* @param pageParamRequest 分页参数
* @author Mr.Zhang
* @since 2020-04-17
*/
@ApiOperation(value = "分页列表")
@RequestMapping(value = "/list", method = RequestMethod.GET)
public CommonResult<CommonPage<ShippingTemplates>> getList(@Validated ShippingTemplatesSearchRequest request, @Validated PageParamRequest pageParamRequest){
CommonPage<ShippingTemplates> shippingTemplatesCommonPage = CommonPage.restPage(shippingTemplatesService.getList(request, pageParamRequest));
return CommonResult.success(shippingTemplatesCommonPage);
}
/**
* 新增
* @param request 新增参数
* @author Mr.Zhang
* @since 2020-04-17
*/
@ApiOperation(value = "新增")
@RequestMapping(value = "/save", method = RequestMethod.POST)
public CommonResult<String> save(@RequestBody @Validated ShippingTemplatesRequest request){
shippingTemplatesService.create(request);
return CommonResult.success();
}
/**
* 删除
* @param id Integer
* @author Mr.Zhang
* @since 2020-04-17
*/
@ApiOperation(value = "删除")
@RequestMapping(value = "/delete", method = RequestMethod.GET)
public CommonResult<String> delete(@RequestParam(value = "id") Integer id){
if(shippingTemplatesService.remove(id)){
return CommonResult.success();
}else{
return CommonResult.failed();
}
}
/**
* 修改
* @param id integer id
* @param request ShippingTemplatesRequest 修改参数
* @author Mr.Zhang
* @since 2020-04-17
*/
@ApiOperation(value = "修改")
@RequestMapping(value = "/update", method = RequestMethod.POST)
public CommonResult<String> update(@RequestParam Integer id, @RequestBody @Validated ShippingTemplatesRequest request){
shippingTemplatesService.update(id, request);
return CommonResult.success();
}
/**
* 查询信息
* @param id Integer
* @author Mr.Zhang
* @since 2020-04-17
*/
@ApiOperation(value = "详情")
@RequestMapping(value = "/info", method = RequestMethod.GET)
public CommonResult<ShippingTemplates> info(@RequestParam(value = "id") Integer id){
ShippingTemplates shippingTemplates = shippingTemplatesService.getById(id);
return CommonResult.success(shippingTemplates);
}
}

View File

@@ -0,0 +1,42 @@
package com.zbkj.crmeb.express.controller;
import com.common.CommonResult;
import com.zbkj.crmeb.express.request.ShippingTemplatesFreeRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.*;
import com.zbkj.crmeb.express.service.ShippingTemplatesFreeService;
import java.util.List;
/**
* 前端控制器
*/
@Slf4j
@RestController
@RequestMapping("api/admin/express/shipping/free")
@Api(tags = "设置 -- 物流 -- 免费")
public class ShippingTemplatesFreeController {
@Autowired
private ShippingTemplatesFreeService shippingTemplatesFreeService;
/**
* 根据模板id查询数据
* @param tempId Integer 模板id
* @author Mr.Zhang
* @since 2020-04-17
*/
@ApiOperation(value = "根据模板id查询数据")
@RequestMapping(value = "/list", method = RequestMethod.GET)
public CommonResult<List<ShippingTemplatesFreeRequest>> getList(@RequestParam Integer tempId){
return CommonResult.success(shippingTemplatesFreeService.getListGroup(tempId));
}
}

View File

@@ -0,0 +1,42 @@
package com.zbkj.crmeb.express.controller;
import com.common.CommonResult;
import com.zbkj.crmeb.express.request.ShippingTemplatesRegionRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.*;
import com.zbkj.crmeb.express.service.ShippingTemplatesRegionService;
import java.util.List;
/**
* 前端控制器
*/
@Slf4j
@RestController
@RequestMapping("api/admin/express/shipping/region")
@Api(tags = "设置 -- 物流 -- 付费")
public class ShippingTemplatesRegionController {
@Autowired
private ShippingTemplatesRegionService shippingTemplatesRegionService;
/**
* 根据模板id查询数据
* @param tempId Integer 模板id
* @author Mr.Zhang
* @since 2020-04-17
*/
@ApiOperation(value = "根据模板id查询数据")
@RequestMapping(value = "/list", method = RequestMethod.GET)
public CommonResult<List<ShippingTemplatesRegionRequest>> getList(@RequestParam Integer tempId){
return CommonResult.success(shippingTemplatesRegionService.getListGroup(tempId));
}
}

View File

@@ -0,0 +1,16 @@
package com.zbkj.crmeb.express.dao;
import com.zbkj.crmeb.express.model.Express;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* <p>
* 快递公司表 Mapper 接口
* </p>
*
* @author Mr.Zhang
* @since 2020-04-17
*/
public interface ExpressDao extends BaseMapper<Express> {
}

View File

@@ -0,0 +1,16 @@
package com.zbkj.crmeb.express.dao;
import com.zbkj.crmeb.express.model.ShippingTemplates;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* <p>
* Mapper 接口
* </p>
*
* @author Mr.Zhang
* @since 2020-04-17
*/
public interface ShippingTemplatesDao extends BaseMapper<ShippingTemplates> {
}

View File

@@ -0,0 +1,20 @@
package com.zbkj.crmeb.express.dao;
import com.zbkj.crmeb.express.model.ShippingTemplatesFree;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.zbkj.crmeb.express.request.ShippingTemplatesFreeRequest;
import java.util.List;
/**
* <p>
* Mapper 接口
* </p>
*
* @author Mr.Zhang
* @since 2020-04-17
*/
public interface ShippingTemplatesFreeDao extends BaseMapper<ShippingTemplatesFree> {
List<ShippingTemplatesFreeRequest> getListGroup(Integer tempId);
}

View File

@@ -0,0 +1,20 @@
package com.zbkj.crmeb.express.dao;
import com.zbkj.crmeb.express.model.ShippingTemplatesRegion;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.zbkj.crmeb.express.request.ShippingTemplatesRegionRequest;
import java.util.List;
/**
* <p>
* Mapper 接口
* </p>
*
* @author Mr.Zhang
* @since 2020-04-17
*/
public interface ShippingTemplatesRegionDao extends BaseMapper<ShippingTemplatesRegion> {
List<ShippingTemplatesRegionRequest> getListGroup(Integer tempId);
}

View File

@@ -0,0 +1,47 @@
package com.zbkj.crmeb.express.model;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import java.io.Serializable;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
* <p>
* 快递公司表
* </p>
*
* @author Mr.Zhang
* @since 2020-04-17
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("eb_express")
@ApiModel(value="Express对象", description="快递公司表")
public class Express implements Serializable {
private static final long serialVersionUID=1L;
@ApiModelProperty(value = "快递公司id")
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
@ApiModelProperty(value = "快递公司简称")
private String code;
@ApiModelProperty(value = "快递公司全称")
private String name;
@ApiModelProperty(value = "排序")
private Integer sort;
@ApiModelProperty(value = "是否显示")
private Boolean isShow;
}

View File

@@ -0,0 +1,55 @@
package com.zbkj.crmeb.express.model;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import java.io.Serializable;
import java.util.Date;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
* <p>
*
* </p>
*
* @author Mr.Zhang
* @since 2020-04-17
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("eb_shipping_templates")
@ApiModel(value="ShippingTemplates对象", description="")
public class ShippingTemplates implements Serializable {
private static final long serialVersionUID=1L;
@ApiModelProperty(value = "编号")
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
@ApiModelProperty(value = "模板名称")
private String name;
@ApiModelProperty(value = "计费方式")
private Integer type;
@ApiModelProperty(value = "指定包邮")
private Boolean appoint;
@ApiModelProperty(value = "排序")
private Integer sort;
@ApiModelProperty(value = "创建时间")
private Date createTime;
@ApiModelProperty(value = "修改时间")
private Date updateTime;
}

View File

@@ -0,0 +1,68 @@
package com.zbkj.crmeb.express.model;
import java.math.BigDecimal;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import java.io.Serializable;
import java.util.Date;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
* <p>
*
* </p>
*
* @author Mr.Zhang
* @since 2020-04-17
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("eb_shipping_templates_free")
@ApiModel(value="ShippingTemplatesFree对象", description="")
public class ShippingTemplatesFree implements Serializable {
private static final long serialVersionUID=1L;
@ApiModelProperty(value = "编号")
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
@ApiModelProperty(value = "模板ID")
private Integer tempId;
@ApiModelProperty(value = "城市ID")
private Integer cityId;
@ApiModelProperty(value = "描述")
private String title;
@ApiModelProperty(value = "包邮件数")
private Integer number;
@ApiModelProperty(value = "包邮金额")
private BigDecimal price;
@ApiModelProperty(value = "计费方式")
private Integer type;
@ApiModelProperty(value = "分组唯一值")
private String uniqid;
@ApiModelProperty(value = "是否无效")
private Boolean status;
@ApiModelProperty(value = "创建时间")
private Date createTime;
@ApiModelProperty(value = "修改时间")
private Date updateTime;
}

View File

@@ -0,0 +1,78 @@
package com.zbkj.crmeb.express.model;
import java.math.BigDecimal;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import java.io.Serializable;
import java.util.Date;
import com.sun.org.apache.xpath.internal.operations.Bool;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import lombok.experimental.FieldDefaults;
/**
* <p>
*
* </p>
*
* @author Mr.Zhang
* @since 2020-04-17
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("eb_shipping_templates_region")
@ApiModel(value="ShippingTemplatesRegion对象", description="")
public class ShippingTemplatesRegion implements Serializable {
private static final long serialVersionUID=1L;
@ApiModelProperty(value = "编号")
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
@ApiModelProperty(value = "模板ID")
private Integer tempId;
@ApiModelProperty(value = "城市ID")
private Integer cityId;
@ApiModelProperty(value = "描述")
private String title;
@ApiModelProperty(value = "首件")
private BigDecimal first;
@ApiModelProperty(value = "首件运费")
private BigDecimal firstPrice;
@ApiModelProperty(value = "续件")
private BigDecimal renewal;
@ApiModelProperty(value = "续件运费")
private BigDecimal renewalPrice;
@ApiModelProperty(value = "计费方式")
private Integer type;
@ApiModelProperty(value = "分组唯一值")
private String uniqid;
@ApiModelProperty(value = "是否无效")
private Boolean status;
@ApiModelProperty(value = "创建时间")
private Date createTime;
@ApiModelProperty(value = "修改时间")
private Date updateTime;
}

View File

@@ -0,0 +1,50 @@
package com.zbkj.crmeb.express.request;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
/**
* <p>
* 快递公司表
* </p>
*
* @author Mr.Zhang
* @since 2020-04-17
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("eb_express")
@ApiModel(value="ExpressRequest对象", description="快递公司")
public class ExpressRequest implements Serializable {
private static final long serialVersionUID=1L;
@ApiModelProperty(value = "快递公司简称", required = true)
@NotBlank(message = "快递公司简称必须填写")
private String code;
@ApiModelProperty(value = "快递公司全称", required = true)
@NotBlank(message = "快递公司全称必须填写")
private String name;
@ApiModelProperty(value = "排序")
@NotNull(message = "排序数字必须填写")
private Integer sort;
@ApiModelProperty(value = "是否显示", required = true)
@NotNull(message = "请选择是否弃用")
private Boolean isShow;
}

View File

@@ -0,0 +1,37 @@
package com.zbkj.crmeb.express.request;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
/**
* <p>
* 快递公司表
* </p>
*
* @author Mr.Zhang
* @since 2020-04-17
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@ApiModel(value="ExpressSearchRequest对象", description="快递公司")
public class ExpressSearchRequest implements Serializable {
private static final long serialVersionUID=1L;
@ApiModelProperty(value = "搜索关键字", required = true)
private String keywords;
@ApiModelProperty(value = "是否显示", required = true)
private Boolean isShow = null;
}

View File

@@ -0,0 +1,48 @@
package com.zbkj.crmeb.express.request;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import javax.validation.constraints.DecimalMin;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
import java.math.BigDecimal;
/**
* <p>
* 免费
* </p>
*
* @author Mr.Zhang
* @since 2020-04-17
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("eb_shipping_templates_free")
@ApiModel(value="ShippingTemplatesFreeRequest对象", description="免费")
public class ShippingTemplatesFreeRequest implements Serializable {
private static final long serialVersionUID=1L;
@ApiModelProperty(value = "城市ID, 多个逗号分割。 全国 all", required = true, example = "1,2,3,4")
@NotNull(message = "请选择城市")
private String cityId;
@ApiModelProperty(value = "城市名称描述")
private String title;
@ApiModelProperty(value = "包邮件数", required = true, example = "1")
@Min(value = 1, message = "请填写包邮件数")
private Integer number;
@ApiModelProperty(value = "包邮金额", required = true, example = "0.1")
@NotNull(message = "请填写包邮金额")
@DecimalMin(value = "0", message = "包邮金额不能低于0")
private BigDecimal price;
}

View File

@@ -0,0 +1,61 @@
package com.zbkj.crmeb.express.request;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import org.hibernate.validator.constraints.Range;
import javax.validation.constraints.DecimalMin;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
import java.math.BigDecimal;
/**
* <p>
*
* </p>
*
* @author Mr.Zhang
* @since 2020-04-17
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("eb_shipping_templates_region")
@ApiModel(value="ShippingTemplatesRegionRequest对象", description="付费")
public class ShippingTemplatesRegionRequest implements Serializable {
private static final long serialVersionUID=1L;
@ApiModelProperty(value = "城市ID, 多个逗号分割。全国 all", required = true, example = "1,2,3,4")
@NotNull(message = "请选择城市")
private String cityId;
@ApiModelProperty(value = "城市名称描述")
private String title;
@ApiModelProperty(value = "首件", required = true, example = "0.1")
@DecimalMin(value = "0.1", message = "首件金额不能低于0.1")
private BigDecimal first;
@ApiModelProperty(value = "首件运费", required = true, example = "0.1")
@DecimalMin(value = "0.1", message = "首件运费金额不能低于0.1")
private BigDecimal firstPrice;
@ApiModelProperty(value = "续件", required = true, example = "0.1")
@DecimalMin(value = "0.1", message = "续件不能低于0.1")
private BigDecimal renewal;
@ApiModelProperty(value = "续件运费", required = true, example = "0.1")
@DecimalMin(value = "0.1", message = "续件运费金额不能低于0.1")
private BigDecimal renewalPrice;
@ApiModelProperty(value = "分组唯一值")
private String uniqid;
}

View File

@@ -0,0 +1,61 @@
package com.zbkj.crmeb.express.request;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import org.hibernate.validator.constraints.Range;
import org.springframework.beans.factory.annotation.Value;
import javax.validation.constraints.DecimalMin;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
import java.util.List;
/**
* <p>
*
* </p>
*
* @author Mr.Zhang
* @since 2020-04-17
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("eb_shipping_templates")
@ApiModel(value="ShippingTemplatesRequest对象", description="模板")
public class ShippingTemplatesRequest implements Serializable {
private static final long serialVersionUID=1L;
@ApiModelProperty(value = "模板名称", required = true)
@NotBlank(message = "模板名称必须填写")
private String name;
@ApiModelProperty(value = "计费方式 1(按件数), 2(按重量)3(按体积)", example = "1", required = true)
@NotNull(message = "计费方式必须选择")
@Range(min = 1, max = 3, message = "计费方式选择区间 1(按件数), 2(按重量)3(按体积)")
private Integer type;
@ApiModelProperty(value = "配送区域及运费", required = true)
private List<ShippingTemplatesRegionRequest> shippingTemplatesRegionRequestList;
@ApiModelProperty(value = "指定包邮", example = "1", required = true)
@NotNull(message = "指定包邮必须选择")
private Boolean appoint;
@ApiModelProperty(value = "指定包邮设置", required = true)
private List<ShippingTemplatesFreeRequest> shippingTemplatesFreeRequestList;
@ApiModelProperty(value = "排序", example = "0")
@NotNull(message = "排序数字必须填写")
private Integer sort;
}

View File

@@ -0,0 +1,34 @@
package com.zbkj.crmeb.express.request;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.io.Serializable;
/**
* <p>
*
* </p>
*
* @author Mr.Zhang
* @since 2020-04-17
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("eb_shipping_templates")
@ApiModel(value="ShippingTemplatesSearchRequest对象", description="模板搜索")
public class ShippingTemplatesSearchRequest implements Serializable {
private static final long serialVersionUID=1L;
@ApiModelProperty(value = "模板名称")
private String name;
}

View File

@@ -0,0 +1,37 @@
package com.zbkj.crmeb.express.service;
import com.alibaba.fastjson.JSONObject;
import com.common.PageParamRequest;
import com.zbkj.crmeb.express.model.Express;
import com.baomidou.mybatisplus.extension.service.IService;
import com.zbkj.crmeb.express.request.ExpressRequest;
import com.zbkj.crmeb.express.request.ExpressSearchRequest;
import java.util.List;
/**
* @author Mr.Zhang
* @Description ExpressService 接口
* @since 2020-04-17
*/
public interface ExpressService extends IService<Express> {
/**
* 列表
* @param request 搜索条件
* @param pageParamRequest 分页类参数
* @author Mr.Zhang
* @since 2020-04-17
* @return List<Express>
*/
List<Express> getList(ExpressSearchRequest request, PageParamRequest pageParamRequest);
Express info(Integer id);
// /**
// * 根据快递单号和快递公司类型查看物流信息
// * @param no 单号
// * @param type 快递公司类型
// */
// JSONObject getExpressInfo(String no, String type);
}

View File

@@ -0,0 +1,18 @@
package com.zbkj.crmeb.express.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.common.PageParamRequest;
import com.zbkj.crmeb.express.model.Express;
import com.zbkj.crmeb.express.request.ExpressSearchRequest;
import com.zbkj.crmeb.express.vo.LogisticsResultVo;
import java.util.List;
/**
* @author Mr.Zhang
* @Description ExpressService 接口
* @since 2020-04-17
*/
public interface LogisticService {
LogisticsResultVo info(String expressNo, String type);
}

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