!6 4.1.0功能合并

Merge pull request !6 from chopper711/Bulbasaur
This commit is contained in:
chopper711 2021-06-21 14:15:41 +08:00 committed by Gitee
commit 4bd4ba7e08
357 changed files with 6868 additions and 3279 deletions

View File

@ -37,11 +37,11 @@ public class AdminApplication {
successHandler.setDefaultTargetUrl(this.adminServer.path("/"));
http.authorizeRequests().antMatchers("/instances**").permitAll();
http.authorizeRequests(
(authorizeRequests) -> authorizeRequests.antMatchers(this.adminServer.path("/assets/**")).permitAll() // 授予公众对所有静态资产和登录页面的访问权限
(authorizeRequests) -> authorizeRequests.antMatchers(this.adminServer.path("/assets/**")).permitAll() //授予公众对所有静态资产和登录页面的访问权限
.antMatchers(this.adminServer.path("/login")).permitAll().anyRequest().authenticated() //其他所有请求都必须经过验证
).formLogin(
(formLogin) -> formLogin.loginPage(this.adminServer.path("/login")).successHandler(successHandler).and() // 配置登录和注销
).logout((logout) -> logout.logoutUrl(this.adminServer.path("/logout"))).httpBasic(Customizer.withDefaults()) // 启用HTTP基本支持这是Spring Boot Admin Client注册所必需的
(formLogin) -> formLogin.loginPage(this.adminServer.path("/login")).successHandler(successHandler).and() //配置登录和注销
).logout((logout) -> logout.logoutUrl(this.adminServer.path("/logout"))).httpBasic(Customizer.withDefaults()) //启用HTTP基本支持这是Spring Boot Admin Client注册所必需的
.csrf().disable()
.rememberMe((rememberMe) -> rememberMe.key(UUID.randomUUID().toString()).tokenValiditySeconds(1209600));
}

View File

@ -82,9 +82,6 @@ public class GoodsBuyerController {
@NotNull(message = "SKU ID不能为空") @PathVariable("skuId") String skuId) {
Map<String, Object> map = goodsSkuService.getGoodsSkuDetail(goodsId, skuId);
return ResultUtil.data(map);
}

View File

@ -1,8 +1,13 @@
package cn.lili.controller.other;
import cn.lili.common.enums.ResultUtil;
import cn.lili.common.utils.PageUtil;
import cn.lili.common.vo.PageVO;
import cn.lili.common.vo.ResultMessage;
import cn.lili.modules.system.entity.dos.AppVersion;
import cn.lili.modules.system.service.AppVersionService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
@ -33,4 +38,13 @@ public class AppVersionBuyerController {
public ResultMessage<Object> getAppVersion(@PathVariable String appType) {
return ResultUtil.data(appVersionService.getAppVersion(appType));
}
@ApiOperation(value = "获取版本号列表")
@ApiImplicitParam(name = "appType", value = "app类型", required = true, paramType = "path")
@GetMapping("/appVersion/{appType}")
public ResultMessage<IPage<AppVersion>> appVersion(@PathVariable String appType, PageVO pageVO) {
IPage<AppVersion> page = appVersionService.page(PageUtil.initPage(pageVO), new LambdaQueryWrapper<AppVersion>().eq(AppVersion::getType, appType));
return ResultUtil.data(page);
}
}

View File

@ -0,0 +1,48 @@
package cn.lili.controller.other.broadcast;
import cn.lili.common.enums.ResultUtil;
import cn.lili.common.vo.PageVO;
import cn.lili.common.vo.ResultMessage;
import cn.lili.modules.broadcast.entity.dos.Studio;
import cn.lili.modules.broadcast.service.StudioService;
import com.baomidou.mybatisplus.core.metadata.IPage;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* 买家端,直播间接口
*
* @author Bulbasaur
* @date: 2021/5/20 12:03 下午
*/
@RestController
@Api(tags = "买家端,直播间接口")
@RequestMapping("/buyer/broadcast/studio")
public class StudioController {
@Autowired
private StudioService studioService;
@ApiOperation(value = "获取店铺直播间列表")
@ApiImplicitParams({
@ApiImplicitParam(name = "recommend", value = "是否推荐", paramType = "query", dataType = "int"),
@ApiImplicitParam(name = "status", value = "直播间状态", paramType = "query", dataType = "String")
})
@GetMapping
public ResultMessage<IPage<Studio>> page(PageVO pageVO, Integer recommend, String status) {
return ResultUtil.data(studioService.studioList(pageVO, recommend, status));
}
@ApiOperation(value = "获取店铺直播间回放地址")
@GetMapping("/getLiveInfo/{roomId}")
public ResultMessage<Object> getLiveInfo(Integer roomId) {
return ResultUtil.data(studioService.getLiveInfo(roomId));
}
}

View File

@ -17,6 +17,7 @@ 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.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@ -30,6 +31,7 @@ import java.io.IOException;
* @author Chopper
* @date 2020-11-25 19:29
*/
@Slf4j
@RestController
@Api(tags = "买家端,web联合登录")
@RequestMapping("/buyer/connect")
@ -93,7 +95,7 @@ public class ConnectBuyerWebController {
try {
return ResultUtil.data(connectService.appLoginCallback(authUser, uuid));
} catch (Exception e) {
e.printStackTrace();
log.error("unionID登录错误",e);
}
return null;
}

View File

@ -12,6 +12,7 @@ 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.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
@ -25,6 +26,7 @@ import javax.servlet.http.HttpServletResponse;
* @author Chopper
* @date 2020-12-18 16:59
*/
@Slf4j
@RestController
@Api(tags = "买家端,收银台接口")
@RequestMapping("/buyer/cashier")
@ -63,7 +65,7 @@ public class CashierController {
try {
return cashierSupport.payment(paymentMethodEnum, paymentClientEnum, request, response, payParam);
} catch (Exception e) {
e.printStackTrace();
log.error("收银台支付错误",e);
}
return null;

View File

@ -17,29 +17,29 @@ import java.util.List;
/**
* 买家端,限时抢购接口
* 买家端,秒杀活动接口
*
* @author paulG
* @date 2020/11/17 2:30 下午
*/
@Api(tags = "买家端,限时抢购接口")
@Api(tags = "买家端,秒杀活动接口")
@RestController
@RequestMapping("/buyer/promotion/seckill")
public class SeckillBuyerController {
/**
* 限时抢购
* 秒杀活动
*/
@Autowired
private SeckillApplyService seckillApplyService;
@ApiOperation(value = "获取当天限时抢购信息")
@ApiOperation(value = "获取当天秒杀活动信息")
@GetMapping
public ResultMessage<List<SeckillTimelineVO>> getSeckillTime() {
return ResultUtil.data(seckillApplyService.getSeckillTimeline());
}
@ApiOperation(value = "获取某个时刻的限时抢购商品信息")
@ApiOperation(value = "获取某个时刻的秒杀活动商品信息")
@GetMapping("/{timeline}")
public ResultMessage<List<SeckillGoodsVO>> getSeckillGoods(@PathVariable Integer timeline) {
return ResultUtil.data(seckillApplyService.getSeckillGoods(timeline));

View File

@ -50,8 +50,17 @@ public class CartController {
public ResultMessage<Object> add(@NotNull(message = "产品id不能为空") String skuId,
@NotNull(message = "购买数量不能为空") @Min(value = 1, message = "加入购物车数量必须大于0") Integer num,
String cartType) {
cartService.add(skuId, num, cartType);
return ResultUtil.success();
try {
//读取选中的列表
cartService.add(skuId, num, cartType);
return ResultUtil.success();
} catch (ServiceException se) {
log.info(se.getMsg(), se);
return ResultUtil.error(se.getResultCode().code(), se.getResultCode().message());
} catch (Exception e) {
log.error(ResultCode.CART_ERROR.message(), e);
throw new ServiceException(ResultCode.CART_ERROR);
}
}
@ -148,10 +157,11 @@ public class CartController {
@GetMapping("/checked")
public ResultMessage<TradeDTO> cartChecked(@NotNull(message = "读取选中列表") String way) {
try {
// 读取选中的列表
//读取选中的列表
return ResultUtil.data(this.cartService.getCheckedTradeDTO(CartTypeEnum.valueOf(way)));
} catch (ServiceException e) {
throw e;
} catch (ServiceException se) {
log.error(se.getMsg(), se);
return ResultUtil.error(se.getResultCode().code(), se.getResultCode().message());
} catch (Exception e) {
log.error(ResultCode.CART_ERROR.message(), e);
throw new ServiceException(ResultCode.CART_ERROR);
@ -193,6 +203,9 @@ public class CartController {
try {
cartService.shippingMethod(selleId, shippingMethod, way);
return ResultUtil.success();
} catch (ServiceException se) {
log.error(se.getMsg(), se);
return ResultUtil.error(se.getResultCode().code(), se.getResultCode().message());
} catch (Exception e) {
log.error(ResultCode.CART_ERROR.message(), e);
throw new ServiceException(ResultCode.CART_ERROR);
@ -226,10 +239,11 @@ public class CartController {
@PostMapping(value = "/create/trade", consumes = "application/json", produces = "application/json")
public ResultMessage<Object> crateTrade(@RequestBody TradeParams tradeParams) {
try {
// 读取选中的列表
//读取选中的列表
return ResultUtil.data(this.cartService.createTrade(tradeParams));
} catch (ServiceException e) {
throw e;
} catch (ServiceException se) {
log.error(se.getMsg(), se);
return ResultUtil.error(se.getResultCode().code(), se.getResultCode().message());
} catch (Exception e) {
log.error(ResultCode.ORDER_ERROR.message(), e);
throw new ServiceException(ResultCode.ORDER_ERROR);

View File

@ -67,7 +67,7 @@ public class BuyerAuthenticationFilter extends BasicAuthenticationFilter {
//从header中获取jwt
String jwt = request.getHeader(SecurityEnum.HEADER_TOKEN.getValue());
try {
// 如果没有token 则return
//如果没有token 则return
if (StrUtil.isBlank(jwt)) {
chain.doFilter(request, response);
return;
@ -99,7 +99,7 @@ public class BuyerAuthenticationFilter extends BasicAuthenticationFilter {
String json = claims.get(SecurityEnum.USER_CONTEXT.getValue()).toString();
AuthUser authUser = new Gson().fromJson(json, AuthUser.class);
// 校验redis中是否有权限
//校验redis中是否有权限
if (cache.hasKey(CachePrefix.ACCESS_TOKEN.getPrefix(UserEnums.MEMBER) + jwt)) {
//构造返回信息
List<GrantedAuthority> auths = new ArrayList<>();

View File

@ -48,35 +48,35 @@ public class BuyerSecurityConfig extends WebSecurityConfigurerAdapter {
ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry registry = http
.authorizeRequests();
// 配置的url 不需要授权
//配置的url 不需要授权
for (String url : ignoredUrlsProperties.getUrls()) {
registry.antMatchers(url).permitAll();
}
registry
.and()
// 禁止网页iframe
//禁止网页iframe
.headers().frameOptions().disable()
.and()
.logout()
.permitAll()
.and()
.authorizeRequests()
// 任何请求
//任何请求
.anyRequest()
// 需要身份认证
//需要身份认证
.authenticated()
.and()
// 允许跨域
//允许跨域
.cors().configurationSource((CorsConfigurationSource) SpringContextUtil.getBean("corsConfigurationSource")).and()
// 关闭跨站请求防护
//关闭跨站请求防护
.csrf().disable()
// 前后端分离采用JWT 不需要session
//前后端分离采用JWT 不需要session
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
// 自定义权限拒绝处理类
//自定义权限拒绝处理类
.exceptionHandling().accessDeniedHandler(accessDeniedHandler)
.and()
// 添加JWT认证过滤器
//添加JWT认证过滤器
.addFilter(new BuyerAuthenticationFilter(authenticationManager(), cache));
}

View File

@ -4,9 +4,6 @@ server:
servlet:
context-path: /
# 正式部署时候,解开此处配置,防止文件夹被清除导致的文件上传失败问题
# multipart:
# location: /Users/lifenlong/Desktop/ceshi
tomcat:
uri-encoding: UTF-8
threads:
@ -153,6 +150,7 @@ ignored:
- /buyer/memberEvaluation/**/goodsEvaluation
- /buyer/memberEvaluation/**/evaluationNumber
- /buyer/appVersion/**
- /buyer/broadcast/studio/**
- /druid/**
- /swagger-ui.html
- /doc.html
@ -262,7 +260,8 @@ lili:
# account:
# username: elastic
# password: LiLiShopES
logstash:
server: 192.168.0.116:4560
rocketmq:
promotion-topic: lili_promotion_topic
promotion-group: lili_promotion_group

View File

@ -0,0 +1,40 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration>
<configuration>
<include resource="org/springframework/boot/logging/logback/defaults.xml"/>
<include resource="org/springframework/boot/logging/logback/console-appender.xml"/>
<!--应用名称-->
<property name="APP_NAME" value="buyer-api"/>
<!--日志文件保存路径-->
<property name="LOG_FILE_PATH" value="lili-logs"/>
<contextName>${APP_NAME}</contextName>
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${LOG_FILE_PATH}/${APP_NAME}-%d{yyyy-MM-dd}.log</fileNamePattern>
<maxHistory>30</maxHistory>
</rollingPolicy>
<encoder>
<pattern>${FILE_LOG_PATTERN}</pattern>
</encoder>
</appender>
<!--输出到elk的LOGSTASH-->
<appender name="LOGSTASH" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
<destination>127.0.0.1:4560</destination>
<encoder charset="UTF-8" class="net.logstash.logback.encoder.LogstashEncoder">
<providers>
<timestamp>
<timeZone>UTC</timeZone>
</timestamp>
</providers>
<!--自定义字段 区分项目-->
<customFields>{"appName":"${APP_NAME}"}</customFields>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="CONSOLE"/>
<appender-ref ref="FILE"/>
<appender-ref ref="LOGSTASH"/>
</root>
</configuration>

View File

@ -50,9 +50,9 @@ class CartTest {
@Test
void createTrade() {
// TradeDTO allTradeDTO = cartService.getAllTradeDTO();
// Assert.assertNotNull(allTradeDTO);
// System.out.println(JsonUtil.objectToJson(allTradeDTO));
// TradeDTO allTradeDTO = cartService.getAllTradeDTO();
// Assert.assertNotNull(allTradeDTO);
// System.out.println(JsonUtil.objectToJson(allTradeDTO));
cartService.createTrade(new TradeParams());
}

View File

@ -5,6 +5,7 @@ import cn.lili.modules.file.plugin.FileManagerPlugin;
import cn.lili.modules.goods.entity.dos.Brand;
import cn.lili.modules.goods.service.BrandService;
import com.xkcoding.http.util.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
@ -19,6 +20,7 @@ import java.util.List;
* @author paulG
* @since 2020/11/14
**/
@Slf4j
@RunWith(SpringRunner.class)
@SpringBootTest
class FileTest {
@ -40,10 +42,10 @@ class FileTest {
}
URL url = new URL(brand.getLogo());
InputStream inputStream = url.openStream();
// 上传至第三方云服务或服务器
//上传至第三方云服务或服务器
brand.setLogo(fileManagerPlugin.inputStreamUpload(inputStream, brand.getId() + ".png"));
} catch (IOException e) {
e.printStackTrace();
log.error("上传你文件出错",e);
}
}
brandService.updateBatchById(categoryList);

View File

@ -2,9 +2,6 @@ server:
servlet:
context-path: /
# 正式部署时候,解开此处配置,防止文件夹被清除导致的文件上传失败问题
# multipart:
# location: /Users/lifenlong/Desktop/ceshi
tomcat:
uri-encoding: UTF-8
threads:

View File

@ -8,6 +8,7 @@ import cn.lili.common.verification.service.VerificationService;
import cn.lili.common.vo.ResultMessage;
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.web.bind.annotation.*;
@ -17,8 +18,9 @@ import org.springframework.web.bind.annotation.*;
* @author Chopper
* @date 2020/11/26 15:41
*/
@RequestMapping("/common/slider")
@Slf4j
@RestController
@RequestMapping("/common/slider")
@Api(tags = "滑块验证码接口")
public class SliderImageController {
@ -35,7 +37,7 @@ public class SliderImageController {
} catch (ServiceException e) {
throw e;
} catch (Exception e) {
e.printStackTrace();
log.error("获取校验接口错误",e);
return null;
}
}

View File

@ -73,7 +73,7 @@ public class UploadController {
}
if (StringUtils.isNotBlank(base64)) {
// base64上传
//base64上传
file = Base64DecodeMultipartFile.base64Convert(base64);
}
String result = "";
@ -81,9 +81,9 @@ public class UploadController {
File newFile = new File();
try {
InputStream inputStream = file.getInputStream();
// 上传至第三方云服务或服务器
//上传至第三方云服务或服务器
result = fileManagerPlugin.inputStreamUpload(inputStream, fileKey);
// 保存数据信息至数据库
//保存数据信息至数据库
newFile.setName(file.getOriginalFilename());
newFile.setFileSize(file.getSize());
newFile.setFileType(file.getContentType());

View File

@ -48,18 +48,18 @@ public class CommonSecurityConfig extends WebSecurityConfigurerAdapter {
.authorizeRequests();
registry
.and()
// 禁止网页iframe
//禁止网页iframe
.headers().frameOptions().disable()
.and()
.authorizeRequests()
// 任何请求
//任何请求
.anyRequest()
// 需要身份认证
//需要身份认证
.permitAll()
.and()
// 允许跨域
//允许跨域
.cors().configurationSource(corsConfigurationSource).and()
// 关闭跨站请求防护
//关闭跨站请求防护
.csrf().disable();
}

View File

@ -4,9 +4,6 @@ server:
servlet:
context-path: /
# 正式部署时候,解开此处配置,防止文件夹被清除导致的文件上传失败问题
# multipart:
# location: /Users/lifenlong/Desktop/ceshi
tomcat:
uri-encoding: UTF-8
threads:

View File

@ -0,0 +1,41 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration>
<configuration>
<include resource="org/springframework/boot/logging/logback/defaults.xml"/>
<include resource="org/springframework/boot/logging/logback/console-appender.xml"/>
<!--应用名称-->
<property name="APP_NAME" value="common-api"/>
<!--日志文件保存路径-->
<property name="LOG_FILE_PATH" value="lili-logs"/>
<contextName>${APP_NAME}</contextName>
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${LOG_FILE_PATH}/${APP_NAME}-%d{yyyy-MM-dd}.log</fileNamePattern>
<maxHistory>30</maxHistory>
</rollingPolicy>
<encoder>
<pattern>${FILE_LOG_PATTERN}</pattern>
</encoder>
</appender>
<!--输出到elk的LOGSTASH-->
<appender name="LOGSTASH" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
<!-- 配置elk日志收集 配饰的是 LOGSTASH 的地址-->
<destination>127.0.0.1:4560</destination>
<encoder charset="UTF-8" class="net.logstash.logback.encoder.LogstashEncoder">
<providers>
<timestamp>
<timeZone>UTC</timeZone>
</timestamp>
</providers>
<!--自定义字段 区分项目-->
<customFields>{"appName":"${APP_NAME}"}</customFields>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="CONSOLE"/>
<appender-ref ref="FILE"/>
<appender-ref ref="LOGSTASH"/>
</root>
</configuration>

View File

@ -2,9 +2,6 @@ server:
servlet:
context-path: /
# 正式部署时候,解开此处配置,防止文件夹被清除导致的文件上传失败问题
# multipart:
# location: /Users/lifenlong/Desktop/ceshi
tomcat:
uri-encoding: UTF-8
threads:
@ -80,7 +77,7 @@ spring:
default-datasource:
type: com.alibaba.druid.pool.DruidDataSource
driverClassName: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://192.168.0.116:3306/lilishop?useUnicode=true&characterEncoding=utf-8&useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai
url: jdbc:mysql://192.168.0.116:3306/Bulbasaur?useUnicode=true&characterEncoding=utf-8&useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai
username: root
password: lilishop
maxActive: 20
@ -150,6 +147,7 @@ ignored:
- /buyer/memberEvaluation/**/goodsEvaluation
- /buyer/memberEvaluation/**/evaluationNumber
- /buyer/appVersion/**
- /buyer/broadcast/studio/**
- /store/login/**
- /manager/user/login
- /manager/user/refresh/**
@ -252,7 +250,7 @@ lili:
# jwt 细节设定
jwt-setting:
# token过期时间分钟
tokenExpireTime: 60
tokenExpireTime: 30
# 使用Spring @Cacheable注解失效时间
cache:
@ -276,6 +274,8 @@ lili:
# username: elastic
# password: LiLiShopES
logstash:
server: 192.168.0.116:4560
rocketmq:
promotion-topic: lili_promotion_topic
promotion-group: lili_promotion_group

View File

@ -15,6 +15,8 @@ import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
/**
* 分销订单入库
*
@ -28,7 +30,7 @@ public class DistributionOrderExecute implements OrderStatusChangeEvent, EveryDa
@Autowired
private DistributionOrderService distributionOrderService;
//分销订单持久层
@Autowired
@Resource
private DistributionOrderMapper distributionOrderMapper;

View File

@ -0,0 +1,92 @@
package cn.lili.event.impl;
import cn.lili.common.utils.CurrencyUtil;
import cn.lili.event.GoodsCommentCompleteEvent;
import cn.lili.event.MemberRegisterEvent;
import cn.lili.event.OrderStatusChangeEvent;
import cn.lili.modules.member.entity.dos.Member;
import cn.lili.modules.member.entity.dos.MemberEvaluation;
import cn.lili.modules.member.service.MemberService;
import cn.lili.modules.order.order.entity.dos.Order;
import cn.lili.modules.order.order.entity.dto.OrderMessage;
import cn.lili.modules.order.order.entity.enums.OrderStatusEnum;
import cn.lili.modules.order.order.service.OrderService;
import cn.lili.modules.system.entity.dos.Setting;
import cn.lili.modules.system.entity.dto.ExperienceSetting;
import cn.lili.modules.system.entity.enums.SettingEnum;
import cn.lili.modules.system.service.SettingService;
import com.google.gson.Gson;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* 会员经验值
*
* @author Bulbasaur
* @date: 2021/5/16 11:16 下午
*/
@Service
public class MemberExperienceExecute implements MemberRegisterEvent, GoodsCommentCompleteEvent, OrderStatusChangeEvent {
//配置
@Autowired
private SettingService settingService;
//会员
@Autowired
private MemberService memberService;
//订单
@Autowired
private OrderService orderService;
/**
* 会员注册赠送经验值
* @param member 会员
*/
@Override
public void memberRegister(Member member) {
//获取经验值设置
ExperienceSetting experienceSetting = getExperienceSetting();
//赠送会员经验值
memberService.updateMemberExperience(Long.valueOf(experienceSetting.getRegister().longValue()), true, member.getId(), "会员注册,赠送经验值" + experienceSetting.getRegister());
}
/**
* 商品评价赠送经验值
* @param memberEvaluation 会员评价
*/
@Override
public void goodsComment(MemberEvaluation memberEvaluation) {
//获取经验值设置
ExperienceSetting experienceSetting = getExperienceSetting();
//赠送会员经验值
memberService.updateMemberExperience(Long.valueOf(experienceSetting.getComment().longValue()), true, memberEvaluation.getMemberId(), "会员评价,赠送经验值" + experienceSetting.getComment());
}
/**
* 完成订单赠送经验值
* @param orderMessage 订单消息
*/
@Override
public void orderChange(OrderMessage orderMessage) {
if(orderMessage.getNewStatus().equals(OrderStatusEnum.COMPLETED)){
//获取经验值设置
ExperienceSetting experienceSetting = getExperienceSetting();
//获取订单信息
Order order = orderService.getBySn(orderMessage.getOrderSn());
//计算赠送经验值数量
Double point= CurrencyUtil.mul(experienceSetting.getMoney(),order.getFlowPrice(),0);
//赠送会员经验值
memberService.updateMemberExperience(point.longValue(), true, order.getMemberId(), "会员下单,赠送经验值" + point + "");
}
}
/**
* 获取经验值设置
* @return 经验值设置
*/
private ExperienceSetting getExperienceSetting(){
Setting setting = settingService.get(SettingEnum.EXPERIENCE_SETTING.name());
return new Gson().fromJson(setting.getSettingValue(), ExperienceSetting.class);
}
}

View File

@ -1,30 +1,37 @@
package cn.lili.event.impl;
import cn.lili.common.utils.CurrencyUtil;
import cn.lili.event.AfterSaleStatusChangeEvent;
import cn.lili.event.GoodsCommentCompleteEvent;
import cn.lili.event.MemberRegisterEvent;
import cn.lili.event.OrderStatusChangeEvent;
import cn.lili.modules.member.entity.dos.Member;
import cn.lili.modules.member.entity.dos.MemberEvaluation;
import cn.lili.modules.member.service.MemberService;
import cn.lili.modules.member.service.MemberWalletService;
import cn.lili.modules.order.order.entity.dos.AfterSale;
import cn.lili.modules.order.order.entity.dos.Order;
import cn.lili.modules.order.order.entity.dto.OrderMessage;
import cn.lili.modules.order.order.entity.enums.OrderPromotionTypeEnum;
import cn.lili.modules.order.order.entity.enums.OrderStatusEnum;
import cn.lili.modules.order.order.service.OrderService;
import cn.lili.modules.order.trade.entity.enums.AfterSaleStatusEnum;
import cn.lili.modules.system.entity.dos.Setting;
import cn.lili.modules.system.entity.dto.PointSetting;
import cn.lili.modules.system.entity.enums.SettingEnum;
import cn.lili.modules.system.service.SettingService;
import com.google.gson.Gson;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* 会员积分
*
* @author Chopper
* @author Bulbasaur
* @date 2020-07-03 11:20
*/
@Service
public class MemberPointExecute implements MemberRegisterEvent, GoodsCommentCompleteEvent {
public class MemberPointExecute implements MemberRegisterEvent, GoodsCommentCompleteEvent, OrderStatusChangeEvent, AfterSaleStatusChangeEvent {
//配置
@Autowired
@ -32,22 +39,80 @@ public class MemberPointExecute implements MemberRegisterEvent, GoodsCommentComp
//会员
@Autowired
private MemberService memberService;
//订单
@Autowired
private OrderService orderService;
/**
* 会员注册赠送积分
* @param member 会员
*/
@Override
public void memberRegister(Member member) {
//获取签到积分赠送设置
Setting setting = settingService.get(SettingEnum.POINT_SETTING.name());
PointSetting pointSetting = new Gson().fromJson(setting.getSettingValue(), PointSetting.class);
//获取积分设置
PointSetting pointSetting=getPointSetting();
//赠送会员积分
memberService.updateMemberPoint(Long.valueOf(pointSetting.getRegister().longValue()), 1, member.getId(), "会员注册,赠送积分" + pointSetting.getRegister() + "");
memberService.updateMemberPoint(Long.valueOf(pointSetting.getRegister().longValue()), true, member.getId(), "会员注册,赠送积分" + pointSetting.getRegister() + "");
}
/**
* 会员评价赠送积分
* @param memberEvaluation 会员评价
*/
@Override
public void goodsComment(MemberEvaluation memberEvaluation) {
//获取签到积分赠送设置
Setting setting = settingService.get(SettingEnum.POINT_SETTING.name());
PointSetting pointSetting = new Gson().fromJson(setting.getSettingValue(), PointSetting.class);
//获取积分设置
PointSetting pointSetting=getPointSetting();
//赠送会员积分
memberService.updateMemberPoint(Long.valueOf(pointSetting.getComment().longValue()), 1, memberEvaluation.getMemberId(), "会员评价,赠送积分" + pointSetting.getComment() + "");
memberService.updateMemberPoint(Long.valueOf(pointSetting.getComment().longValue()), true, memberEvaluation.getMemberId(), "会员评价,赠送积分" + pointSetting.getComment() + "");
}
/**
* 非积分订单订单完成后赠送积分
* @param orderMessage 订单消息
*/
@Override
public void orderChange(OrderMessage orderMessage) {
if(orderMessage.getNewStatus().equals(OrderStatusEnum.COMPLETED)){
//根据订单编号获取订单数据,如果为积分订单则跳回
Order order = orderService.getBySn(orderMessage.getOrderSn());
if(order.getOrderPromotionType().equals(OrderPromotionTypeEnum.POINT.name())){
return;
}
//获取积分设置
PointSetting pointSetting=getPointSetting();
//计算赠送积分数量
Double point=CurrencyUtil.mul(pointSetting.getMoney(),order.getFlowPrice(),0);
//赠送会员积分
memberService.updateMemberPoint(point.longValue(), true, order.getMemberId(), "会员下单,赠送积分" + point + "");
}
}
/**
* 提交售后后扣除积分
* @param afterSale 售后
*/
@Override
public void afterSaleStatusChange(AfterSale afterSale) {
if (afterSale.getServiceStatus().equals(AfterSaleStatusEnum.COMPLETE.name())) {
//获取积分设置
PointSetting pointSetting=getPointSetting();
//计算扣除积分数量
Double point=CurrencyUtil.mul(pointSetting.getMoney(), afterSale.getActualRefundPrice(),0);
//扣除会员积分
memberService.updateMemberPoint(point.longValue(), false, afterSale.getMemberId(), "会员退款,扣除积分" + point + "");
}
}
/**
* 获取积分设置
* @return 积分设置
*/
private PointSetting getPointSetting(){
Setting setting = settingService.get(SettingEnum.POINT_SETTING.name());
return new Gson().fromJson(setting.getSettingValue(), PointSetting.class);
}
}

View File

@ -11,12 +11,11 @@ import cn.lili.modules.message.service.NoticeMessageService;
import cn.lili.modules.order.cart.entity.dto.TradeDTO;
import cn.lili.modules.order.order.entity.dos.AfterSale;
import cn.lili.modules.order.order.entity.dto.OrderMessage;
import cn.lili.modules.order.order.entity.enums.OrderTypeEnum;
import cn.lili.modules.order.order.entity.enums.OrderPromotionTypeEnum;
import cn.lili.modules.order.order.entity.vo.OrderDetailVO;
import cn.lili.modules.order.order.service.OrderService;
import cn.lili.modules.order.trade.entity.enums.AfterSaleStatusEnum;
import cn.lili.modules.order.trade.entity.enums.AfterSaleTypeEnum;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@ -83,7 +82,7 @@ public class NoticeMessageExecute implements TradeEvent, OrderStatusChangeEvent,
break;
//如果是拼团订单发送拼团成功消息
case UNDELIVERED:
if(orderDetailVO.getOrder().getOrderType().equals(OrderTypeEnum.PINTUAN.name())){
if(orderDetailVO.getOrder().getOrderPromotionType().equals(OrderPromotionTypeEnum.PINTUAN.name())){
//拼团成功消息
noticeMessageDTO.setNoticeMessageNodeEnum(NoticeMessageNodeEnum.PINTUAN_SUCCESS);
}

View File

@ -10,8 +10,6 @@ import cn.lili.modules.order.order.service.OrderService;
import cn.lili.modules.payment.entity.RefundLog;
import cn.lili.modules.payment.kit.Payment;
import cn.lili.modules.payment.kit.enums.PaymentMethodEnum;
import cn.lili.modules.payment.service.PaymentService;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@ -24,9 +22,6 @@ import org.springframework.stereotype.Service;
@Service
public class PaymentExecute implements OrderStatusChangeEvent {
//支付日志
@Autowired
private PaymentService paymentService;
//订单
@Autowired
private OrderService orderService;

View File

@ -0,0 +1,41 @@
package cn.lili.event.impl;
import cn.lili.event.MemberRegisterEvent;
import cn.lili.modules.member.entity.dos.Member;
import cn.lili.modules.promotion.entity.dos.CouponActivity;
import cn.lili.modules.promotion.entity.enums.CouponActivityTypeEnum;
import cn.lili.modules.promotion.entity.enums.PromotionStatusEnum;
import cn.lili.modules.promotion.service.CouponActivityService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.List;
/**
* 注册赠券活动
*
* @author Bulbasaur
* @date: 2021/5/24 10:48 上午
*/
@Component
public class RegisteredCouponActivityExecute implements MemberRegisterEvent {
@Autowired
private CouponActivityService couponActivityService;
/**
* 获取进行中的注册赠券的优惠券活动
* 发送注册赠券
*
* @param member 会员
*/
@Override
public void memberRegister(Member member) {
List<CouponActivity> couponActivities = couponActivityService.list(new LambdaQueryWrapper<CouponActivity>()
.eq(CouponActivity::getCouponActivityType, CouponActivityTypeEnum.REGISTERED.name())
.eq(CouponActivity::getPromotionStatus, PromotionStatusEnum.START.name()));
couponActivityService.registered(couponActivities, member);
}
}

View File

@ -161,7 +161,7 @@ public class StockUpdateExecute implements OrderStatusChangeEvent {
//促销库存key 集合
List<String> promotionKey = new ArrayList<>();
// 循环订单
//循环订单
for (OrderItem orderItem : order.getOrderItems()) {
skuKeys.add(GoodsSkuService.getStockCacheKey(orderItem.getSkuId()));
GoodsSku goodsSku = new GoodsSku();
@ -221,7 +221,7 @@ public class StockUpdateExecute implements OrderStatusChangeEvent {
List<GoodsSku> goodsSkus = new ArrayList<>();
//sku库存key 集合
List<String> skuKeys = new ArrayList<>();
// 循环订单
//循环订单
for (OrderItem orderItem : order.getOrderItems()) {
skuKeys.add(GoodsSkuService.getStockCacheKey(orderItem.getSkuId()));
GoodsSku goodsSku = new GoodsSku();

View File

@ -0,0 +1,62 @@
package cn.lili.event.impl;
import cn.hutool.core.util.RandomUtil;
import cn.lili.common.utils.CommonUtil;
import cn.lili.event.OrderStatusChangeEvent;
import cn.lili.modules.order.order.entity.dos.Order;
import cn.lili.modules.order.order.entity.dto.OrderMessage;
import cn.lili.modules.order.order.entity.enums.OrderStatusEnum;
import cn.lili.modules.order.order.service.OrderService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* 虚拟商品
*
* @author Bulbasaur
* @date: 2021/5/29 9:17 上午
*/
@Component
public class VerificationOrderExecute implements OrderStatusChangeEvent {
@Autowired
private OrderService orderService;
@Override
public void orderChange(OrderMessage orderMessage) {
//订单状态为待核验添加订单添加核验码
if (orderMessage.getNewStatus().equals(OrderStatusEnum.TAKE)) {
//获取订单信息
Order order = orderService.getBySn(orderMessage.getOrderSn());
//获取随机数判定是否存在
String code = getCode(order.getStoreId());
//设置订单验证码
orderService.update(new LambdaUpdateWrapper<Order>()
.set(Order::getVerificationCode, code)
.eq(Order::getSn, orderMessage.getOrderSn()));
}
}
/**
* 获取随机数
* 判断当前店铺下是否使用验证码如果已使用则重新获取
*
* @param storeId 店铺ID
* @return
*/
private String getCode(String storeId) {
//获取八位验证码
String code = Long.toString(RandomUtil.randomLong(10000000, 99999999));
LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper<Order>()
.eq(Order::getVerificationCode, code)
.eq(Order::getStoreId, storeId);
if (orderService.getOne(lambdaQueryWrapper) == null) {
return code;
} else {
return this.getCode(storeId);
}
}
}

View File

@ -112,7 +112,7 @@ public class GoodsMessageListener implements RocketMQListener<MessageExt> {
for (GoodsCompleteMessage goodsCompleteMessage : goodsCompleteMessageList) {
Goods goods = goodsService.getById(goodsCompleteMessage.getGoodsId());
if (goods != null) {
// 更新商品购买数量
//更新商品购买数量
if (goods.getBuyCount() == null) {
goods.setBuyCount(0);
}
@ -126,7 +126,7 @@ public class GoodsMessageListener implements RocketMQListener<MessageExt> {
}
GoodsSku goodsSku = goodsSkuService.getById(goodsCompleteMessage.getSkuId());
if (goodsSku != null) {
// 更新商品购买数量
//更新商品购买数量
if (goodsSku.getBuyCount() == null) {
goodsSku.setBuyCount(0);
}

View File

@ -44,6 +44,7 @@ public class OrderMessageListener implements RocketMQListener<MessageExt> {
case ORDER_CREATE:
String key = new String(messageExt.getBody());
TradeDTO tradeDTO = (TradeDTO) cache.get(key);
boolean result = true;
for (TradeEvent event : tradeEvent) {
try {
event.orderCreate(tradeDTO);
@ -52,8 +53,14 @@ public class OrderMessageListener implements RocketMQListener<MessageExt> {
tradeDTO.getSn(),
event.getClass().getName(),
e);
result = false;
}
}
//如所有步骤顺利完成
if (Boolean.TRUE.equals(result)) {
//清除记录信息的trade cache key
cache.remove(key);
}
break;
//订单状态变更
case STATUS_CHANGE:

View File

@ -44,7 +44,6 @@ public class BillExecute implements EveryDayExecute {
//获取当前时间
DateTime endTime =DateUtil.date();
//批量商家结算
for (StoreSettlementDay storeSettlementDay : storeList) {

View File

@ -0,0 +1,25 @@
package cn.lili.timetask.handler.impl.broadcast;
import cn.lili.modules.broadcast.service.CommodityService;
import cn.lili.timetask.handler.EveryHourExecute;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* 小程序直播状态获取
*
* @author Bulbasaur
* @date: 2021/5/20 2:52 下午
*/
@Component
public class BroadcastExecute implements EveryHourExecute {
@Autowired
private CommodityService commodityService;
@Override
public void execute() {
//同步直播商品状态
commodityService.getGoodsWareHouse();
}
}

View File

@ -0,0 +1,80 @@
package cn.lili.timetask.handler.impl.coupon;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.lili.modules.promotion.entity.dos.CouponActivity;
import cn.lili.modules.promotion.entity.enums.CouponActivityTypeEnum;
import cn.lili.modules.promotion.entity.enums.PromotionStatusEnum;
import cn.lili.modules.promotion.service.CouponActivityService;
import cn.lili.timetask.handler.EveryMinuteExecute;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.List;
/**
* 优惠券活动状态监测
*
* @author Bulbasaur
* @date: 2021/5/24 10:08 上午
*/
@Component
public class CouponActivityExecute implements EveryMinuteExecute {
@Autowired
private CouponActivityService couponActivityService;
@Override
public void execute() {
//精确发券活动
specify();
//注册赠券的活动
registered();
}
/**
* 监测精确发券活动
* 达到活动时间发送优惠券
*/
private void specify(){
DateTime dateTime=DateUtil.date();
List<CouponActivity> couponActivities=couponActivityService.list(new LambdaQueryWrapper<CouponActivity>()
.eq(CouponActivity::getCouponActivityType, CouponActivityTypeEnum.SPECIFY.name())
.le(CouponActivity::getStartTime, dateTime)
.eq(CouponActivity::getPromotionStatus,PromotionStatusEnum.NEW.name()));
//如果有符合要求的优惠券活动发送优惠券
if(couponActivities.size()>0){
for (CouponActivity couponActivity:couponActivities) {
couponActivityService.specify(couponActivity.getId());
//修改精准发券优惠券活动状态
couponActivityService.update(new LambdaUpdateWrapper<CouponActivity>()
.eq(CouponActivity::getId,couponActivity.getId())
.set(CouponActivity::getPromotionStatus,PromotionStatusEnum.END.name()));
}
}
}
/**
* 注册赠券活动状态监测
*/
private void registered(){
//开启注册赠券优惠券活动
LambdaUpdateWrapper<CouponActivity> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
lambdaUpdateWrapper.eq(CouponActivity::getCouponActivityType, CouponActivityTypeEnum.REGISTERED.name())
.eq(CouponActivity::getPromotionStatus, PromotionStatusEnum.NEW.name())
.le(CouponActivity::getStartTime, DateUtil.date())
.set(CouponActivity::getPromotionStatus,PromotionStatusEnum.START.name());
couponActivityService.update(lambdaUpdateWrapper);
//关闭注册赠券优惠券活动
LambdaUpdateWrapper<CouponActivity> endWrapper = new LambdaUpdateWrapper<>();
endWrapper.eq(CouponActivity::getCouponActivityType, CouponActivityTypeEnum.REGISTERED.name())
.eq(CouponActivity::getPromotionStatus, PromotionStatusEnum.START.name())
.le(CouponActivity::getEndTime, DateUtil.date())
.set(CouponActivity::getPromotionStatus,PromotionStatusEnum.END.name());
couponActivityService.update(endWrapper);
}
}

View File

@ -0,0 +1,38 @@
package cn.lili.timetask.handler.impl.coupon;
import cn.hutool.core.date.DateUtil;
import cn.lili.modules.promotion.entity.dos.MemberCoupon;
import cn.lili.modules.promotion.entity.enums.MemberCouponStatusEnum;
import cn.lili.modules.promotion.service.MemberCouponService;
import cn.lili.timetask.handler.EveryDayExecute;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* 优惠券状态监测
*
* @author Bulbasaur
* @date: 2021/5/24 10:08 上午
*/
@Component
public class CouponExecute implements EveryDayExecute {
@Autowired
private MemberCouponService memberCouponService;
/**
* 检测优惠券的使用时间超期未使用则失效
* 此方法用于领取*天后失效优惠券使用
*/
@Override
public void execute() {
LambdaUpdateWrapper<MemberCoupon> updateWrapper = new LambdaUpdateWrapper<MemberCoupon>()
.eq(MemberCoupon::getMemberCouponStatus, MemberCouponStatusEnum.NEW.name())
.le(MemberCoupon::getEndTime, DateUtil.date())
.set(MemberCoupon::getMemberCouponStatus, MemberCouponStatusEnum.EXPIRE.name());
this.memberCouponService.update(updateWrapper);
}
}

View File

@ -39,7 +39,6 @@ public class GoodsExecute implements EveryDayExecute {
new QueryWrapper<MemberEvaluation>()
.between("create_time", DateUtil.yesterday(), new DateTime()));
System.out.println("评论数量" + list.size());
for (Map<String, Object> map : list) {
goodsMapper.addGoodsCommentNum(Integer.parseInt(map.get("num").toString()), map.get("goods_id").toString());
}

View File

@ -43,11 +43,11 @@ public class CancelOrderTaskExecute implements EveryMinuteExecute {
Setting setting = settingService.get(SettingEnum.ORDER_SETTING.name());
OrderSetting orderSetting = JSONUtil.toBean(setting.getSettingValue(), OrderSetting.class);
if (orderSetting != null && orderSetting.getAutoCancel() != null) {
// 订单自动取消时间 = 当前时间 - 自动取消时间分钟数
//订单自动取消时间 = 当前时间 - 自动取消时间分钟数
DateTime cancelTime = DateUtil.offsetMinute(DateUtil.date(), -orderSetting.getAutoCancel());
LambdaQueryWrapper<Order> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(Order::getOrderStatus, OrderStatusEnum.UNPAID.name());
// 订单创建时间 <= 订单自动取消时间
//订单创建时间 <= 订单自动取消时间
queryWrapper.le(Order::getCreateTime, cancelTime);
List<Order> list = orderService.list(queryWrapper);
List<String> cancelSnList = list.stream().map(Order::getSn).collect(Collectors.toList());

View File

@ -73,11 +73,11 @@ public class OrderEveryDayTaskExecute implements EveryDayExecute {
* @param orderSetting 订单设置
*/
private void completedOrder(OrderSetting orderSetting) {
// 订单自动收货时间 = 当前时间 - 自动收货时间天数
//订单自动收货时间 = 当前时间 - 自动收货时间天数
DateTime receiveTime = DateUtil.offsetDay(DateUtil.date(), -orderSetting.getAutoEvaluation());
LambdaQueryWrapper<Order> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(Order::getOrderStatus, OrderStatusEnum.DELIVERED.name());
// 订单发货时间 >= 订单自动收货时间
//订单发货时间 >= 订单自动收货时间
queryWrapper.ge(Order::getLogisticsTime, receiveTime);
List<Order> list = orderService.list(queryWrapper);
List<String> receiveSnList = list.stream().map(Order::getSn).collect(Collectors.toList());
@ -98,9 +98,9 @@ public class OrderEveryDayTaskExecute implements EveryDayExecute {
* @param orderSetting 订单设置
*/
private void memberEvaluation(OrderSetting orderSetting) {
// 订单自动收货时间 = 当前时间 - 自动收货时间天数
//订单自动收货时间 = 当前时间 - 自动收货时间天数
DateTime receiveTime = DateUtil.offsetDay(DateUtil.date(), -orderSetting.getAutoReceive());
// 订单完成时间 <= 订单自动好评时间
//订单完成时间 <= 订单自动好评时间
List<OrderItem> orderItems = orderItemService.waitEvaluate(receiveTime);
for (OrderItem orderItem : orderItems) {

View File

@ -3,15 +3,21 @@ package cn.lili.timetask.handler.impl.promotion;
import cn.lili.modules.order.cart.entity.vo.FullDiscountVO;
import cn.lili.modules.promotion.entity.dos.MemberCoupon;
import cn.lili.modules.promotion.entity.dos.PromotionGoods;
import cn.lili.modules.promotion.entity.dos.Seckill;
import cn.lili.modules.promotion.entity.enums.MemberCouponStatusEnum;
import cn.lili.modules.promotion.entity.enums.PromotionStatusEnum;
import cn.lili.modules.promotion.entity.vos.CouponVO;
import cn.lili.modules.promotion.entity.vos.PintuanVO;
import cn.lili.modules.promotion.service.*;
import cn.lili.modules.search.service.EsGoodsIndexService;
import cn.lili.modules.system.entity.dos.Setting;
import cn.lili.modules.system.entity.dto.SeckillSetting;
import cn.lili.modules.system.entity.enums.SettingEnum;
import cn.lili.modules.system.service.SettingService;
import cn.lili.timetask.handler.EveryDayExecute;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.google.gson.Gson;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
@ -55,6 +61,13 @@ public class PromotionEverydayExecute implements EveryDayExecute {
@Autowired
private PromotionGoodsService promotionGoodsService;
//系统设置
@Autowired
private SettingService settingService;
//秒杀活动
@Autowired
private SeckillService seckillService;
/**
* 将已过期的促销活动置为结束
@ -69,13 +82,34 @@ public class PromotionEverydayExecute implements EveryDayExecute {
//结束条件 活动结束时间大于当前时间
query.addCriteria(Criteria.where("endTime").lt(new Date()));
//结束满减活动
endFullDiscount(query);
//关闭拼团活动
endPintuan(query);
//结束优惠券
endCoupon(query);
//定时创建活动
addSeckill();
}
/**
* 结束优惠券活动
*
* @param query
*/
private void endCoupon(Query query) {
try {
//关闭满减活动
List<FullDiscountVO> fullDiscountVOS = mongoTemplate.find(query, FullDiscountVO.class);
if (!fullDiscountVOS.isEmpty()) {
//关闭优惠券活动
List<CouponVO> couponVOS = mongoTemplate.find(query, CouponVO.class);
if (!couponVOS.isEmpty()) {
List<String> ids = new ArrayList<>();
//循环活动 关闭活动
for (FullDiscountVO vo : fullDiscountVOS) {
// //关闭的优惠券活动
for (CouponVO vo : couponVOS) {
vo.setPromotionStatus(PromotionStatusEnum.END.name());
if (vo.getPromotionGoodsList() != null && !vo.getPromotionGoodsList().isEmpty()) {
for (PromotionGoods promotionGoods : vo.getPromotionGoodsList()) {
@ -86,11 +120,23 @@ public class PromotionEverydayExecute implements EveryDayExecute {
mongoTemplate.save(vo);
ids.add(vo.getId());
}
fullDiscountService.update(this.getUpdatePromotionWrapper(ids));
couponService.update(this.getUpdatePromotionWrapper(ids));
LambdaUpdateWrapper<MemberCoupon> memberCouponLambdaUpdateWrapper = new LambdaUpdateWrapper<MemberCoupon>().in(MemberCoupon::getCouponId, ids).set(MemberCoupon::getMemberCouponStatus, MemberCouponStatusEnum.EXPIRE.name());
memberCouponService.update(memberCouponLambdaUpdateWrapper);
//将活动商品对照表进行结束处理
promotionGoodsService.update(this.getUpdatePromotionGoodsWrapper(ids));
}
} catch (Exception e) {
log.error("满减活动关闭错误", e);
log.error("优惠券活动关闭错误", e);
}
}
/**
* 结束拼团活动
*
* @param query
*/
private void endPintuan(Query query) {
try {
//关闭拼团活动
List<PintuanVO> pintuanVOS = mongoTemplate.find(query, PintuanVO.class);
@ -115,14 +161,21 @@ public class PromotionEverydayExecute implements EveryDayExecute {
} catch (Exception e) {
log.error("拼团活动关闭错误", e);
}
}
/**
* 结束满减活动
*
* @param query
*/
private void endFullDiscount(Query query) {
try {
//关闭优惠券活动
List<CouponVO> couponVOS = mongoTemplate.find(query, CouponVO.class);
if (!couponVOS.isEmpty()) {
//关闭满减活动
List<FullDiscountVO> fullDiscountVOS = mongoTemplate.find(query, FullDiscountVO.class);
if (!fullDiscountVOS.isEmpty()) {
List<String> ids = new ArrayList<>();
// // 关闭的优惠券活动
for (CouponVO vo : couponVOS) {
//循环活动 关闭活动
for (FullDiscountVO vo : fullDiscountVOS) {
vo.setPromotionStatus(PromotionStatusEnum.END.name());
if (vo.getPromotionGoodsList() != null && !vo.getPromotionGoodsList().isEmpty()) {
for (PromotionGoods promotionGoods : vo.getPromotionGoodsList()) {
@ -133,24 +186,30 @@ public class PromotionEverydayExecute implements EveryDayExecute {
mongoTemplate.save(vo);
ids.add(vo.getId());
}
couponService.update(this.getUpdatePromotionWrapper(ids));
LambdaUpdateWrapper<MemberCoupon> memberCouponLambdaUpdateWrapper = new LambdaUpdateWrapper<MemberCoupon>().in(MemberCoupon::getCouponId, ids).set(MemberCoupon::getMemberCouponStatus, MemberCouponStatusEnum.EXPIRE.name());
memberCouponService.update(memberCouponLambdaUpdateWrapper);
//将活动商品对照表进行结束处理
promotionGoodsService.update(this.getUpdatePromotionGoodsWrapper(ids));
fullDiscountService.update(this.getUpdatePromotionWrapper(ids));
}
} catch (Exception e) {
log.error("优惠券活动关闭错误", e);
log.error("满减活动关闭错误", e);
}
}
/**
* 添加秒杀活动
* 从系统设置中获取秒杀活动的配置
* 添加30天后的秒杀活动
*/
private void addSeckill() {
Setting setting = settingService.get(SettingEnum.SECKILL_SETTING.name());
SeckillSetting seckillSetting = new Gson().fromJson(setting.getSettingValue(), SeckillSetting.class);
Seckill seckill = new Seckill(30, seckillSetting.getHours(), seckillSetting.getSeckillRule());
seckillService.saveSeckill(seckill);
}
/**
* 获取促销修改查询条件 修改活动状态
*
* @param ids
* @return
* @param ids 促销活动ID
* @return 促销活动商品查询Wrapper
*/
private UpdateWrapper getUpdatePromotionWrapper(List<String> ids) {
UpdateWrapper updateWrapper = new UpdateWrapper<>();
@ -162,8 +221,8 @@ public class PromotionEverydayExecute implements EveryDayExecute {
/**
* 获取商品的促销修改查询条件 修改商品状态
*
* @param ids
* @return
* @param ids 促销活动ID
* @return 促销活动商品修改Wrapper
*/
private UpdateWrapper getUpdatePromotionGoodsWrapper(List<String> ids) {
UpdateWrapper updateWrapper = new UpdateWrapper<>();

View File

@ -186,7 +186,6 @@ class PageViewStatistics {
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
this.date = calendar.getTime();
System.out.println(DateUtil.toString(date,DateUtil.STANDARD_FORMAT));
}
}

View File

@ -31,23 +31,23 @@ public abstract class AbstractDelayQueueListen {
private void startDelayQueueMachine() {
log.info("延时队列机器{}开始运作", setDelayQueueName());
// 监听redis队列
//监听redis队列
while (true) {
try {
// 获取当前时间的时间戳
//获取当前时间的时间戳
long now = System.currentTimeMillis() / 1000;
// 获取当前时间前需要执行的任务列表
//获取当前时间前需要执行的任务列表
Set<DefaultTypedTuple> tuples = cache.zRangeByScore(setDelayQueueName(), 0, now);
// 如果任务不为空
//如果任务不为空
if (!CollectionUtils.isEmpty(tuples)) {
log.info("执行任务:{}", JSONUtil.toJsonStr(tuples));
for (DefaultTypedTuple tuple : tuples) {
String jobId = (String) tuple.getValue();
// 移除缓存如果移除成功则表示当前线程处理了延时任务则执行延时任务
//移除缓存如果移除成功则表示当前线程处理了延时任务则执行延时任务
Long num = cache.zRemove(setDelayQueueName(), jobId);
// 如果移除成功, 则执行
//如果移除成功, 则执行
if (num > 0) {
ThreadPoolUtil.execute(() -> invoke(jobId));
}
@ -57,7 +57,7 @@ public abstract class AbstractDelayQueueListen {
} catch (Exception e) {
log.error("处理延时任务发生异常,异常原因为{}", e.getMessage(), e);
} finally {
// 间隔一秒钟搞一次
//间隔一秒钟搞一次
try {
TimeUnit.SECONDS.sleep(5L);
} catch (InterruptedException e) {

View File

@ -0,0 +1,36 @@
package cn.lili.trigger.executor;
import cn.hutool.json.JSONUtil;
import cn.lili.common.delayqueue.BroadcastMessage;
import cn.lili.common.trigger.model.TimeExecuteConstant;
import cn.lili.modules.broadcast.service.StudioService;
import cn.lili.trigger.TimeTriggerExecutor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* 直播间事件触发
*
* @author Bulbasaur
* @date: 2021/6/1 5:02 下午
*/
@Slf4j
@Component(TimeExecuteConstant.BROADCAST_EXECUTOR)
public class BroadcastTimeTriggerExecutor implements TimeTriggerExecutor {
@Autowired
private StudioService studioService;
@Override
public void execute(Object object) {
//直播间订单消息
BroadcastMessage broadcastMessage = JSONUtil.toBean(JSONUtil.parseObj(object), BroadcastMessage.class);
if (broadcastMessage != null && broadcastMessage.getStudioId() != null) {
log.info("直播间消费:{}", broadcastMessage);
//修改直播间状态
studioService.updateStudioStatus(broadcastMessage);
}
}
}

View File

@ -42,19 +42,19 @@ public class PromotionTimeTriggerExecutor implements TimeTriggerExecutor {
@Override
public void execute(Object object) {
PromotionMessage promotionMessage = JSONUtil.toBean(JSONUtil.parseObj(object), PromotionMessage.class);
// 促销延时信息
//促销延时信息
if (promotionMessage != null && promotionMessage.getPromotionId() != null) {
log.info("促销活动信息消费:{}", promotionMessage);
// 如果为促销活动开始则需要发布促销活动结束的定时任务
//如果为促销活动开始则需要发布促销活动结束的定时任务
if (PromotionStatusEnum.START.name().equals(promotionMessage.getPromotionStatus())) {
if (!promotionService.updatePromotionStatus(promotionMessage)) {
log.error("开始促销活动失败: {}", promotionMessage);
return;
}
// 促销活动开始后设置促销活动结束的定时任务
//促销活动开始后设置促销活动结束的定时任务
promotionMessage.setPromotionStatus(PromotionStatusEnum.END.name());
String uniqueKey = "{TIME_TRIGGER_" + promotionMessage.getPromotionType() + "}_" + promotionMessage.getPromotionId();
// 结束时间延时一分钟
//结束时间延时一分钟
long closeTime = promotionMessage.getEndTime().getTime() + 60000;
TimeTriggerMsg timeTriggerMsg = new TimeTriggerMsg(TimeExecuteConstant.PROMOTION_EXECUTOR, closeTime, promotionMessage, uniqueKey, rocketmqCustomProperties.getPromotionTopic());
//添加延时任务
@ -69,7 +69,7 @@ public class PromotionTimeTriggerExecutor implements TimeTriggerExecutor {
PintuanOrderMessage pintuanOrderMessage = JSONUtil.toBean(JSONUtil.parseObj(object), PintuanOrderMessage.class);
if (pintuanOrderMessage != null && pintuanOrderMessage.getPintuanId() != null) {
log.info("拼团订单信息消费:{}", pintuanOrderMessage);
// 拼团订单自动处理
//拼团订单自动处理
orderService.agglomeratePintuanOrder(pintuanOrderMessage.getPintuanId(), pintuanOrderMessage.getOrderSn());
}
}

View File

@ -29,6 +29,6 @@ public class PromotionDelayQueueListen extends AbstractDelayQueueListen {
@Override
public String setDelayQueueName() {
return DelayQueueEnums.PROMOTION_QUEUE.name();
return DelayQueueEnums.PROMOTION.name();
}
}

View File

@ -4,9 +4,6 @@ server:
servlet:
context-path: /
# 正式部署时候,解开此处配置,防止文件夹被清除导致的文件上传失败问题
# multipart:
# location: /Users/lifenlong/Desktop/ceshi
tomcat:
uri-encoding: UTF-8
threads:
@ -49,7 +46,7 @@ spring:
open-in-view: false
# Redis
redis:
host: 127.0.0.1
host: 192.168.0.116
port: 6379
password: lilishop
lettuce:
@ -80,7 +77,7 @@ spring:
default-datasource:
type: com.alibaba.druid.pool.DruidDataSource
driverClassName: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/lilishop?useUnicode=true&characterEncoding=utf-8&useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai
url: jdbc:mysql://127.0.0.1:3306/Bulbasaur?useUnicode=true&characterEncoding=utf-8&useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai
username: root
password: lilishop
maxActive: 20
@ -282,6 +279,8 @@ lili:
notice-send-group: lili_send_notice_group
after-sale-topic: lili_after_sale_topic
after-sale-group: lili_after_sale_group
broadcast-topic: lili_broadcast_topic
broadcast-group: lili_broadcast_group
rocketmq:
name-server: 127.0.0.1:9876
producer:

View File

@ -0,0 +1,41 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration>
<configuration>
<include resource="org/springframework/boot/logging/logback/defaults.xml"/>
<include resource="org/springframework/boot/logging/logback/console-appender.xml"/>
<!--应用名称-->
<property name="APP_NAME" value="consumer"/>
<!--日志文件保存路径-->
<property name="LOG_FILE_PATH" value="lili-logs"/>
<contextName>${APP_NAME}</contextName>
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${LOG_FILE_PATH}/${APP_NAME}-%d{yyyy-MM-dd}.log</fileNamePattern>
<maxHistory>30</maxHistory>
</rollingPolicy>
<encoder>
<pattern>${FILE_LOG_PATTERN}</pattern>
</encoder>
</appender>
<!--输出到elk的LOGSTASH-->
<appender name="LOGSTASH" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
<!-- 配置elk日志收集 配饰的是 LOGSTASH 的地址-->
<destination>192.168.0.116:4560</destination>
<encoder charset="UTF-8" class="net.logstash.logback.encoder.LogstashEncoder">
<providers>
<timestamp>
<timeZone>UTC</timeZone>
</timestamp>
</providers>
<!--自定义字段 区分项目-->
<customFields>{"appName":"${APP_NAME}"}</customFields>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="CONSOLE"/>
<appender-ref ref="FILE"/>
<appender-ref ref="LOGSTASH"/>
</root>
</configuration>

View File

@ -45,47 +45,16 @@
<de.codecentric>2.3.1</de.codecentric>
<userAgentUtils>1.21</userAgentUtils>
<interceptor-api>1.2</interceptor-api>
<poi-version>4.1.2</poi-version>
<poi-ooxml-version>4.1.2</poi-ooxml-version>
<logstash-logback-encoder>6.6</logstash-logback-encoder>
<zxing>3.4.1</zxing>
<slf4j-api>1.7.28</slf4j-api>
<xk-time>2.2.0</xk-time>
<commons-text>1.4</commons-text>
</properties>
<dependencies>
<dependency>
<groupId>javax.interceptor</groupId>
<artifactId>javax.interceptor-api</artifactId>
<version>${interceptor-api}</version>
</dependency>
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-starter-client</artifactId>
<version>${de.codecentric}</version>
</dependency>
<!-- 开源多维码生成工具 -->
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>core</artifactId>
<version>3.4.1</version>
</dependency>
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>javase</artifactId>
<version>3.4.1</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.28</version>
</dependency>
<!-- 开源多维码生成工具 -->
<dependency>
<groupId>com.github.xkzhangsan</groupId>
<artifactId>xk-time</artifactId>
<version>2.2.0</version>
</dependency>
<!-- <dependency>-->
<!-- <groupId>org.springframework.boot</groupId>-->
<!-- <artifactId>spring-boot-starter-thymeleaf</artifactId>-->
<!-- </dependency>-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
@ -356,23 +325,11 @@
<artifactId>simple-http</artifactId>
<version>${simple-http-version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.antlr/antlr4-runtime -->
<dependency>
<groupId>org.antlr</groupId>
<artifactId>antlr4-runtime</artifactId>
<version>${antlr4-runtime-version}</version>
</dependency>
<!-- http client -->
<!-- <dependency>-->
<!-- <groupId>org.apache.httpcomponents</groupId>-->
<!-- <artifactId>httpclient</artifactId>-->
<!-- <version>${httpclient-version}</version>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>com.squareup.okhttp3</groupId>-->
<!-- <artifactId>okhttp</artifactId>-->
<!-- <version>${okhttp-version}</version>-->
<!-- </dependency>-->
<dependency>
<groupId>com.alipay.sdk</groupId>
<artifactId>alipay-sdk-java</artifactId>
@ -385,8 +342,54 @@
<artifactId>UserAgentUtils</artifactId>
<version>${userAgentUtils}</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>${poi-version}</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>${poi-ooxml-version}</version>
</dependency>
<!--集成logstash-->
<dependency>
<groupId>net.logstash.logback</groupId>
<artifactId>logstash-logback-encoder</artifactId>
<version>${logstash-logback-encoder}</version>
</dependency>
<dependency>
<groupId>javax.interceptor</groupId>
<artifactId>javax.interceptor-api</artifactId>
<version>${interceptor-api}</version>
</dependency>
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-starter-client</artifactId>
<version>${de.codecentric}</version>
</dependency>
<!-- 开源多维码生成工具 -->
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>core</artifactId>
<version>${zxing}</version>
</dependency>
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>javase</artifactId>
<version>${zxing}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j-api}</version>
</dependency>
<!-- 开源多维码生成工具 -->
<dependency>
<groupId>com.github.xkzhangsan</groupId>
<artifactId>xk-time</artifactId>
<version>${xk-time}</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-text</artifactId>

View File

@ -20,12 +20,12 @@ public class MybatisPlusConfig {
return new PaginationInterceptor();
//阻断解析器测试环境使用
// PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
// PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
//
// List<ISqlParser> sqlParserList = new ArrayList<>();
// // 攻击 SQL 阻断解析器加入解析链
// sqlParserList.add(new BlockAttackSqlParser());
// paginationInterceptor.setSqlParserList(sqlParserList);
// return paginationInterceptor;
// List<ISqlParser> sqlParserList = new ArrayList<>();
// //攻击 SQL 阻断解析器加入解析链
// sqlParserList.add(new BlockAttackSqlParser());
// paginationInterceptor.setSqlParserList(sqlParserList);
// return paginationInterceptor;
}
}

View File

@ -1,6 +1,7 @@
package cn.lili.common.aop.limiter;
import cn.lili.common.aop.limiter.annotation.LimitPoint;
import cn.lili.common.exception.ServiceException;
import com.google.common.collect.ImmutableList;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
@ -21,6 +22,7 @@ import java.lang.reflect.Method;
/**
* 流量拦截
*
* @author Chopper
*/
@Aspect
@ -42,7 +44,7 @@ public class LimitInterceptor {
}
@Around("execution(public * *(..)) && @annotation(cn.lili.common.aop.limiter.annotation.LimitPoint)")
public Object interceptor(ProceedingJoinPoint pjp) {
public Object interceptor(ProceedingJoinPoint pjp) throws Throwable {
MethodSignature signature = (MethodSignature) pjp.getSignature();
Method method = signature.getMethod();
LimitPoint limitPointAnnotation = method.getAnnotation(LimitPoint.class);
@ -65,22 +67,26 @@ public class LimitInterceptor {
try {
Number count = redisTemplate.execute(limitScript, keys, limitCount, limitPeriod);
log.info("Access try count is {} for name={} and key = {}", count, name, key);
if (count != null && count.intValue() <= limitCount) {
//如果缓存里没有值或者他的值小于限制频率
if (count.intValue() <= limitCount) {
return pjp.proceed();
} else {
throw new RuntimeException("访问过于频繁,请稍后再试");
}
} catch (Throwable e) {
if (e instanceof RuntimeException) {
throw new RuntimeException(e.getLocalizedMessage());
throw new ServiceException("访问过于频繁,请稍后再试");
}
}
//如果从redis中执行都值判定为空则这里跳过
catch (NullPointerException e) {
return pjp.proceed();
} catch (Exception e) {
throw new RuntimeException("服务器异常,请稍后再试");
}
}
//默认unknown常量值
private static final String UNKNOWN = "unknown";
//获取ip
public String getIpAddress() {
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
String ip = request.getHeader("x-forwarded-for");

View File

@ -102,7 +102,7 @@ public class SystemLogAspect {
//请求参数
systemLogVO.setMapToParams(logParams);
//响应参数 此处数据太大了所以先注释掉
// systemLogVO.setResponseBody(JSONUtil.toJsonStr(rvt));
// systemLogVO.setResponseBody(JSONUtil.toJsonStr(rvt));
//请求IP
systemLogVO.setIp(IpUtils.getIpAddress(request));
//IP地址

View File

@ -219,7 +219,7 @@ public enum CachePrefix {
STORE_ID_FULL_DISCOUNT,
/**
* 限时抢购活动缓存key前缀
* 秒杀活动活动缓存key前缀
*/
STORE_ID_SECKILL,

View File

@ -1,6 +1,7 @@
package cn.lili.common.cache.impl;
import cn.lili.common.cache.Cache;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.*;
@ -18,6 +19,7 @@ import java.util.function.Consumer;
*
* @author Chopepr
*/
@Slf4j
@Component
public class RedisCache implements Cache {
@ -158,7 +160,7 @@ public class RedisCache implements Cache {
return null;
} catch (IOException e) {
e.printStackTrace();
log.error("scan错误",e);
throw new RuntimeException(e);
}
});
@ -168,7 +170,7 @@ public class RedisCache implements Cache {
@Override
public Long cumulative(Object key, Object value) {
HyperLogLogOperations<Object, Object> operations = redisTemplate.opsForHyperLogLog();
// add 方法对应 PFADD 命令
//add 方法对应 PFADD 命令
return operations.add(key, value);
}
@ -177,7 +179,7 @@ public class RedisCache implements Cache {
public Long counter(Object key) {
HyperLogLogOperations<Object, Object> operations = redisTemplate.opsForHyperLogLog();
// add 方法对应 PFADD 命令
//add 方法对应 PFADD 命令
return operations.size(key);
}
@ -196,7 +198,7 @@ public class RedisCache implements Cache {
@Override
public Long mergeCounter(Object... key) {
HyperLogLogOperations<Object, Object> operations = redisTemplate.opsForHyperLogLog();
// 计数器合并累加
//计数器合并累加
return operations.union(key[0], key);
}
@ -221,7 +223,7 @@ public class RedisCache implements Cache {
*/
@Override
public void incrementScore(String sortedSetName, String keyword) {
// x 的含义请见本方法的注释
//x 的含义请见本方法的注释
double x = 1.0;
this.redisTemplate.opsForZSet().incrementScore(sortedSetName, keyword, x);
}

View File

@ -44,7 +44,7 @@ public abstract class BaseElasticsearchService {
static {
RequestOptions.Builder builder = RequestOptions.DEFAULT.toBuilder();
// 默认缓冲限制为100MB此处修改为30MB
//默认缓冲限制为100MB此处修改为30MB
builder.setHttpAsyncResponseConsumerFactory(new HttpAsyncResponseConsumerFactory.HeapBufferedResponseConsumerFactory(30 * 1024 * 1024));
COMMON_OPTIONS = builder.build();
}
@ -88,7 +88,7 @@ public abstract class BaseElasticsearchService {
protected void createIndexRequest(String index) {
try {
CreateIndexRequest request = new CreateIndexRequest(index);
// Settings for this index
//Settings for this index
request.settings(Settings.builder().put("index.number_of_shards", elasticsearchProperties.getIndex().getNumberOfShards()).put("index.number_of_replicas", elasticsearchProperties.getIndex().getNumberOfReplicas()));
//创建索引
@ -98,7 +98,7 @@ public abstract class BaseElasticsearchService {
log.info(" Indicates whether the requisite number of shard copies were started for each shard in the index before timing out :{}", createIndexResponse.isShardsAcknowledged());
return;
} catch (Exception e) {
e.printStackTrace();
log.error("创建索引错误",e);
throw new ElasticsearchException("创建索引 {" + index + "} 失败:" + e.getMessage());
}
}
@ -308,13 +308,13 @@ public abstract class BaseElasticsearchService {
PutMappingRequest request = new PutMappingRequest(index)
.source(source, XContentType.JSON);
// AcknowledgedResponse putMappingResponse = client.indices().putMapping(request,
// RequestOptions.DEFAULT);
// AcknowledgedResponse putMappingResponse = client.indices().putMapping(request,
// RequestOptions.DEFAULT);
//
// boolean acknowledged = putMappingResponse.isAcknowledged();
// if (acknowledged) {
// log.error("Succeed to put mapping");
// }
// boolean acknowledged = putMappingResponse.isAcknowledged();
// if (acknowledged) {
// log.error("Succeed to put mapping");
// }
CountDownLatch latch = new CountDownLatch(1);
AtomicReference response = new AtomicReference<AcknowledgedResponse>();
client.indices().putMappingAsync(
@ -420,7 +420,7 @@ public abstract class BaseElasticsearchService {
try {
searchResponse = client.search(searchRequest, COMMON_OPTIONS);
} catch (IOException e) {
e.printStackTrace();
log.error("es 搜索错误",e);
}
return searchResponse;
}

View File

@ -97,7 +97,8 @@ public enum ResultCode {
USER_RECEIPT_NOT_EXIST(20014, "会员发票信息不存在"),
USER_EDIT_ERROR(20015, "用户修改失败"),
USER_OLD_PASSWORD_ERROR(20016, "旧密码不正确"),
USER_COLLECTION_EXIST(2001, "无法重复收藏"),
USER_COLLECTION_EXIST(20017, "无法重复收藏"),
USER_GRADE_IS_DEFAULT(20018, "会员等级为默认会员等级"),
DELETE_EXIST(2001, "无法重复收藏"),
/**
@ -124,61 +125,97 @@ public enum ResultCode {
* 购物车
*/
CART_ERROR(30001, "读取结算页的购物车异常"),
CART_PINTUAN_NOT_EXIST_ERROR(30002, "拼团活动不存在错误"),
CART_PINTUAN_LIMIT_ERROR(30003, "购买数量超过拼团活动限制数量"),
SHIPPING_NOT_APPLY(30005, "购物商品不支持当前收货地址配送"),
/**
* 订单
*/
ORDER_ERROR(31001, "创建订单异常,请稍后重试"),
ORDER_NOT_EXIST(31002, "订单不存在"),
ORDER_DELIVERED_ERROR(31003, "订单状态错误,无法进行确认收货"),
ORDER_UPDATE_PRICE_ERROR(31004, "已支付的订单不能修改金额"),
ORDER_LOGISTICS_ERROR(31005, "物流错误"),
ORDER_DELIVER_ERROR(31006, "物流错误"),
ORDER_NOT_USER(31007, "非当前会员的订单"),
ORDER_TAKE_ERROR(31008, "当前订单无法核销"),
MEMBER_ADDRESS_NOT_EXIST(31009, "订单无收货地址,请先配置收货地址"),
ORDER_DELIVER_NUM_ERROR(31010, "没有待发货的订单"),
/**
* 支付
*/
PAY_UN_WANTED(32000, "当前订单不需要付款,返回订单列表等待系统订单出库即可"),
PAY_SUCCESS(32001, "支付成功"),
PAY_INCONSISTENT_ERROR(32002, "付款金额和应付金额不一致"),
PAY_DOUBLE_ERROR(32003, "订单已支付,不能再次进行支付"),
PAY_CASHIER_ERROR(32004, "收银台信息获取错误"),
PAY_ERROR(32005, "支付业务异常,请稍后重试"),
PAY_BAN(32006, "当前订单不需要付款,请返回订单列表重新操作"),
PAY_PARTIAL_ERROR(32007, "该订单已部分支付,请前往订单中心进行支付"),
PAY_NOT_SUPPORT(32008, "支付暂不支持"),
PAY_CLIENT_TYPE_ERROR(32009, "错误的客户端"),
PAY_POINT_ENOUGH(32010, "积分不足,不能兑换"),
PAY_NOT_EXIST_ORDER(32011, "支付订单不存在"),
/**
* 售后
*/
AFTER_SALES_NOT_PAY_ERROR(33001, "当前订单未支付,不能申请售后"),
AFTER_SALES_CANCEL_ERROR(33002, "当前售后单无法取消"),
AFTER_SALES_BAN(33003, "订单状态不允许申请售后,请联系平台或商家"),
AFTER_SALES_DOUBLE_ERROR(33004, "售后已审核,无法重复操作"),
AFTER_SALES_LOGISTICS_ERROR(33005, "物流公司错误,请重新选择"),
AFTER_STATUS_ERROR(33006, "售后状态错误,请刷新页面"),
/**
* 投诉
*/
COMPLAINT_ORDER_ITEM_EMPTY_ERROR(33100, "订单不存在"),
COMPLAINT_SKU_EMPTY_ERROR(33101, "商品已下架,如需投诉请联系平台客服"),
COMPLAINT_ERROR(33102, "投诉异常,请稍后重试"),
/**
* 余额
*/
WALLET_NOT_EXIT_ERROR(34000, "钱包不存在,请联系管理员"),
WALLET_INSUFFICIENT(34001, "余额不足以支付订单,请充值!"),
WALLET_WITHDRAWAL_INSUFFICIENT(34002, "可提现金额不足!"),
WALLET_ERROR_INSUFFICIENT(34003, "零钱提现失败!"),
WALLET_REMARK_ERROR(34004, "请填写审核备注!"),
WALLET_APPLY_ERROR(34005, "提现申请异常!"),
/**
@ -195,52 +232,74 @@ public enum ResultCode {
* 优惠券
*/
COUPON_EDIT_STATUS_SUCCESS(41001, "修改状态成功!"),
COUPON_CANCELLATION_SUCCESS(41002, "会员优惠券作废成功"),
COUPON_EXPIRED(41003, "优惠券已使用/已过期,不能使用"),
COUPON_EDIT_STATUS_ERROR(41004, "优惠券修改状态失败!"),
/**
* 拼团
*/
PINTUAN_MANUAL_OPEN_SUCCESS(42001, "手动开启拼团活动成功"),
PINTUAN_MANUAL_CLOSE_SUCCESS(42002, "手动关闭拼团活动成功"),
PINTUAN_ADD_SUCCESS(42003, "添加拼团活动成功"),
PINTUAN_EDIT_SUCCESS(42004, "修改拼团活动成功"),
PINTUAN_DELETE_SUCCESS(42005, "删除拼团活动成功"),
PINTUAN_MANUAL_OPEN_ERROR(42006, "手动开启拼团活动失败"),
PINTUAN_MANUAL_CLOSE_ERROR(42007, "手动关闭拼团活动失败"),
PINTUAN_ADD_ERROR(42008, "添加拼团活动失败"),
PINTUAN_EDIT_ERROR(42009, "修改拼团活动失败"),
PINTUAN_DELETE_ERROR(42010, "删除拼团活动失败"),
/**
* 满额活动
*/
FULL_DISCOUNT_EDIT_SUCCESS(43001, "修改满优惠活动成功"),
FULL_DISCOUNT_EDIT_DELETE(43002, "删除满优惠活动成功"),
/**
* 店铺
*/
STORE_NOT_EXIST(50001, "此店铺不存在"),
STORE_NAME_EXIST_ERROR(50002, "店铺名称已存在!"),
STORE_APPLY_DOUBLE_ERROR(50003, "已有店铺,无需重复申请!"),
/**
* 结算单
*/
BILL_CHECK_ERROR(51001, "只有已出账结算单可以核对"),
BILL_COMPLETE_ERROR(51002, "只有已审核结算单可以支付"),
/**
* 文章
*/
ARTICLE_CATEGORY_NAME_EXIST(60001, "文章分类名称已存在"),
ARTICLE_CATEGORY_PARENT_NOT_EXIST(60002, "文章分类父分类不存在"),
ARTICLE_CATEGORY_BEYOND_TWO(60003, "最多为二级分类,操作失败"),
ARTICLE_CATEGORY_DELETE_ERROR(60004, "该文章分类下存在子分类,不能删除"),
ARTICLE_CATEGORY_HAS_ARTICLE(60005, "该文章分类下存在文章,不能删除"),
ARTICLE_CATEGORY_NO_DELETION(60007, "默认文章分类不能进行删除"),
ARTICLE_NO_DELETION(60008, "默认文章不能进行删除"),
@ -248,8 +307,11 @@ public enum ResultCode {
* 页面
*/
PAGE_NOT_EXIST(61001, "页面不存在"),
PAGE_OPEN_DELETE_ERROR(61002, "当前页面为开启状态,无法删除"),
PAGE_DELETE_ERROR(61003, "当前页面为唯一页面,无法删除"),
PAGE_RELEASE_ERROR(61004, "页面已发布,无需重复提交"),
/**
@ -266,39 +328,49 @@ public enum ResultCode {
* 站内信
*/
NOTICE_NOT_EXIST(80101, "当前消息模板不存在"),
NOTICE_ERROR(80102, "修改站内信异常,请稍后重试"),
/**
* OSS
*/
OSS_NOT_EXIST(80201, "OSS未配置"),
OSS_EXCEPTION(80202, "文件上传失败,请稍后重试"),
/**
* 验证码
*/
VERIFICATION_SEND_SUCCESS(80301, "短信验证码,发送成功"),
VERIFICATION_ERROR(80302, "验证失败"),
VERIFICATION_SMS_ERROR(80303, "短信验证码错误,请重新校验"),
VERIFICATION_SMS_EXPIRED_ERROR(80304, "验证码已失效,请重新校验"),
/**
* 配置错误
*/
ALIPAY_NOT_SETTING(80401, "支付宝支付未配置"),
ALIPAY_EXCEPTION(80402, "支付宝支付错误,请稍后重试"),
ALIPAY_PARAMS_EXCEPTION(80403, "支付宝参数异常"),
/**
* 微信相关异常
*/
WECHAT_CONNECT_NOT_SETTING(80500, "微信联合登陆信息未配置"),
WECHAT_PAYMENT_NOT_SETTING(80501, "微信支付信息未配置"),
WECHAT_QRCODE_ERROR(80502, "微信二维码生成异常"),
WECHAT_MP_MESSAGE_ERROR(80503, "微信小程序小消息订阅异常"),
APP_VERSION_EXIST(80600, "APP版本已存在")
;
APP_VERSION_EXIST(80600, "APP版本已存在");
private final Integer code;
private final String message;

View File

@ -67,24 +67,24 @@ public class GlobalControllerExceptionHandler {
return ResultUtil.error(ResultCode.ERROR);
}
// /**
// * 通用的接口映射异常处理方
// */
// @Override
// protected ResponseEntity<Object> handleExceptionInternal(Exception ex, Object body, HttpHeaders headers, HttpStatus status, WebRequest request) {
// if (ex instanceof MethodArgumentNotValidException) {
// MethodArgumentNotValidException exception = (MethodArgumentNotValidException) ex;
// return new ResponseEntity<>(new ResultUtil<>().setErrorMsg(exception.getBindingResult().getAllErrors().get(0).getDefaultMessage()), status);
// }
// if (ex instanceof MethodArgumentTypeMismatchException) {
// MethodArgumentTypeMismatchException exception = (MethodArgumentTypeMismatchException) ex;
// logger.error("参数转换失败,方法:" + exception.getParameter().getMethod().getName() + ",参数:" + exception.getName()
// + ",信息:" + exception.getLocalizedMessage());
// return new ResponseEntity<>(new ResultUtil<>().setErrorMsg("参数转换失败"), status);
// }
// ex.printStackTrace();
// return new ResponseEntity<>(new ResultUtil<>().setErrorMsg("未知异常,请联系管理员"), status);
// }
// /**
// * 通用的接口映射异常处理方
// */
// @Override
// protected ResponseEntity<Object> handleExceptionInternal(Exception ex, Object body, HttpHeaders headers, HttpStatus status, WebRequest request) {
// if (ex instanceof MethodArgumentNotValidException) {
// MethodArgumentNotValidException exception = (MethodArgumentNotValidException) ex;
// return new ResponseEntity<>(new ResultUtil<>().setErrorMsg(exception.getBindingResult().getAllErrors().get(0).getDefaultMessage()), status);
// }
// if (ex instanceof MethodArgumentTypeMismatchException) {
// MethodArgumentTypeMismatchException exception = (MethodArgumentTypeMismatchException) ex;
// logger.error("参数转换失败,方法:" + exception.getParameter().getMethod().getName() + ",参数:" + exception.getName()
// + ",信息:" + exception.getLocalizedMessage());
// return new ResponseEntity<>(new ResultUtil<>().setErrorMsg("参数转换失败"), status);
// }
// ex.printStackTrace();
// return new ResponseEntity<>(new ResultUtil<>().setErrorMsg("未知异常,请联系管理员"), status);
// }
/**
* bean校验未通过异常

View File

@ -80,7 +80,7 @@ public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper {
* @return
*/
private String cleanXSS2(String value) {
// 移除特殊标签
//移除特殊标签
value = value.replaceAll("<", "&lt;").replaceAll(">", "&gt;");
value = value.replaceAll("\\(", "&#40;").replaceAll("\\)", "&#41;");
value = value.replaceAll("'", "&#39;");
@ -93,40 +93,40 @@ public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper {
private String cleanXSS(String value) {
if (value != null) {
//推荐使用ESAPI库来避免脚本攻击,value = ESAPI.encoder().canonicalize(value);
// // 避免空字符串
// value = value.replaceAll(" ", "");
// 避免script 标签
// //避免空字符串
// value = value.replaceAll(" ", "");
//避免script 标签
Pattern scriptPattern = Pattern.compile("<script>(.*?)</script>", Pattern.CASE_INSENSITIVE);
value = scriptPattern.matcher(value).replaceAll("");
// 避免src形式的表达式
//避免src形式的表达式
scriptPattern = Pattern.compile("src[\r\n]*=[\r\n]*\\\'(.*?)\\\'",
Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
value = scriptPattern.matcher(value).replaceAll("");
scriptPattern = Pattern.compile("src[\r\n]*=[\r\n]*\\\"(.*?)\\\"",
Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
value = scriptPattern.matcher(value).replaceAll("");
// 删除单个的 </script> 标签
//删除单个的 </script> 标签
scriptPattern = Pattern.compile("</script>", Pattern.CASE_INSENSITIVE);
value = scriptPattern.matcher(value).replaceAll("");
// 删除单个的<script ...> 标签
//删除单个的<script ...> 标签
scriptPattern = Pattern.compile("<script(.*?)>",
Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
value = scriptPattern.matcher(value).replaceAll("");
// 避免 eval(...) 形式表达式
//避免 eval(...) 形式表达式
scriptPattern = Pattern.compile("eval\\((.*?)\\)",
Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
value = scriptPattern.matcher(value).replaceAll("");
// 避免 e­xpression(...) 表达式
//避免 e­xpression(...) 表达式
scriptPattern = Pattern.compile("e­xpression\\((.*?)\\)",
Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
value = scriptPattern.matcher(value).replaceAll("");
// 避免 javascript: 表达式
//避免 javascript: 表达式
scriptPattern = Pattern.compile("javascript:", Pattern.CASE_INSENSITIVE);
value = scriptPattern.matcher(value).replaceAll("");
// 避免 vbscript:表达式
//避免 vbscript:表达式
scriptPattern = Pattern.compile("vbscript:", Pattern.CASE_INSENSITIVE);
value = scriptPattern.matcher(value).replaceAll("");
// 避免 onload= 表达式
//避免 onload= 表达式
scriptPattern = Pattern.compile("onload(.*?)=",
Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
value = scriptPattern.matcher(value).replaceAll("");

View File

@ -73,7 +73,7 @@ public class SmsUtilAliImplService implements SmsUtil, AliSmsUtil {
//准备发送短信参数
Map<String, String> params = new HashMap<>();
// 验证码内容
//验证码内容
params.put("code", code);
//模版 默认为登录验证
@ -119,7 +119,6 @@ public class SmsUtilAliImplService implements SmsUtil, AliSmsUtil {
default:
return;
}
//如果是测试模式 默认验证码 6个1
if (systemSetting.getIsTestModel()) {
code = "111111";
@ -156,7 +155,7 @@ public class SmsUtilAliImplService implements SmsUtil, AliSmsUtil {
try {
SendSmsResponse response = client.sendSms(sendSmsRequest);
} catch (Exception e) {
e.printStackTrace();
log.error("发送短信错误",e);
}
}
@ -183,7 +182,7 @@ public class SmsUtilAliImplService implements SmsUtil, AliSmsUtil {
signNameList.add(sign.subList((i * 100), endPoint));
}
// //发送短信
// //发送短信
for (int i = 0; i < mobileList.size(); i++) {
SendBatchSmsRequest sendBatchSmsRequest = new SendBatchSmsRequest()
.setPhoneNumberJson(JSONUtil.toJsonStr(mobileList.get(i)))
@ -192,7 +191,7 @@ public class SmsUtilAliImplService implements SmsUtil, AliSmsUtil {
try {
client.sendBatchSms(sendBatchSmsRequest);
} catch (Exception e) {
e.printStackTrace();
log.error("批量发送短信错误",e);
}
}
@ -203,8 +202,6 @@ public class SmsUtilAliImplService implements SmsUtil, AliSmsUtil {
public void addSmsSign(SmsSign smsSign) throws Exception {
//设置参数添加短信签名
com.aliyun.dysmsapi20170525.Client client = this.createClient();
System.out.println(smsSign.getBusinessLicense().substring(smsSign.getBusinessLicense().lastIndexOf(".") + 1));
System.out.println(smsSign.getLicense().substring(smsSign.getLicense().lastIndexOf(".")));
//营业执照
AddSmsSignRequest.AddSmsSignRequestSignFileList signFileList0 = new AddSmsSignRequest.AddSmsSignRequestSignFileList()
.setFileContents(Base64Utils.encode(smsSign.getBusinessLicense()))
@ -359,15 +356,15 @@ public class SmsUtilAliImplService implements SmsUtil, AliSmsUtil {
SmsSetting smsSetting = new Gson().fromJson(setting.getSettingValue(), SmsSetting.class);
Config config = new Config();
// 您的AccessKey ID
//您的AccessKey ID
config.accessKeyId = smsSetting.getAccessKeyId();
// 您的AccessKey Secret
//您的AccessKey Secret
config.accessKeySecret = smsSetting.getAccessSecret();
// 访问的域名
//访问的域名
config.endpoint = "dysmsapi.aliyuncs.com";
return new com.aliyun.dysmsapi20170525.Client(config);
} catch (Exception e) {
e.printStackTrace();
log.error("短信初始化错误",e);
}
return null;
}

View File

@ -121,15 +121,15 @@ public class TokenUtil {
* @return
*/
private String createToken(String username, Object claim, Long expirationTime) {
// JWT 生成
//JWT 生成
return Jwts.builder()
// jwt 私有声明
//jwt 私有声明
.claim(SecurityEnum.USER_CONTEXT.getValue(), new Gson().toJson(claim))
// JWT的主体
//JWT的主体
.setSubject(username)
// 失效时间 当前时间+过期分钟
//失效时间 当前时间+过期分钟
.setExpiration(new Date(System.currentTimeMillis() + expirationTime * 60 * 1000))
// 签名算法和密钥
//签名算法和密钥
.signWith(SecretKeyUtil.generalKey())
.compact();
}

View File

@ -43,7 +43,7 @@ public class ManagerTokenGenerate extends AbstractTokenGenerate {
@Override
public Token createToken(String username, Boolean longTerm) {
// 生成token
//生成token
AdminUser adminUser = adminUserService.findByUsername(username);
AuthUser user = new AuthUser(adminUser.getUsername(), adminUser.getId(), UserEnums.MANAGER, adminUser.getNickName(), adminUser.getIsSuper());

View File

@ -54,7 +54,7 @@ public class MemberTokenGenerate extends AbstractTokenGenerate {
memberService.updateById(member);
AuthUser authUser = new AuthUser(member.getUsername(), member.getId(),member.getNickName(), UserEnums.MEMBER);
// 登陆成功生成token
//登陆成功生成token
return tokenUtil.createToken(username, authUser, longTerm, UserEnums.MEMBER);
}

View File

@ -33,7 +33,7 @@ public class StoreTokenGenerate extends AbstractTokenGenerate {
@Override
public Token createToken(String username, Boolean longTerm) {
// 生成token
//生成token
Member member = memberService.findByUsername(username);
if (!member.getHaveStore()) {
throw new ServiceException("该会员未开通店铺");

View File

@ -2,8 +2,6 @@ package cn.lili.common.trigger.delay.queue;
import cn.lili.common.trigger.delay.AbstractDelayQueueMachineFactory;
import cn.lili.common.trigger.enums.DelayQueueEnums;
import cn.lili.common.trigger.interfaces.TimeTrigger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
@ -18,11 +16,9 @@ import org.springframework.stereotype.Component;
@Component
public class PromotionDelayQueue extends AbstractDelayQueueMachineFactory {
@Autowired
private TimeTrigger timeTrigger;
@Override
public String setDelayQueueName() {
return DelayQueueEnums.PROMOTION_QUEUE.name();
return DelayQueueEnums.PROMOTION.name();
}
}

View File

@ -7,9 +7,9 @@ public enum DelayQueueEnums {
/**
* 促销任务队列
* 促销活动
*/
PROMOTION_QUEUE("促销任务队列");
PROMOTION("促销活动");
private String description;

View File

@ -6,7 +6,7 @@ package cn.lili.common.trigger.enums;
* @author paulG
* @since 2021/5/7
*/
public enum PromotionDelayTypeEnums {
public enum DelayTypeEnums {
/**
* 促销活动
@ -15,11 +15,16 @@ public enum PromotionDelayTypeEnums {
/**
* 拼团订单
*/
PINTUAN_ORDER("拼团订单");
PINTUAN_ORDER("拼团订单"),
/**
* 直播
*/
BROADCAST("直播");
private String description;
PromotionDelayTypeEnums(String description) {
DelayTypeEnums(String description) {
this.description = description;
}

View File

@ -0,0 +1,34 @@
package cn.lili.common.delayqueue;
import cn.hutool.core.date.DateTime;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Date;
/**
* 直播消息实体
*
* @author Bulbasaur
* @date: 2021/6/1 4:48 下午
*/
@Data
@NoArgsConstructor
public class BroadcastMessage {
/**
* 直播间ID
*/
private String studioId;
/**
* 状态
*/
private String status;
public BroadcastMessage(String studioId, String status) {
this.studioId = studioId;
this.status = status;
}
}

View File

@ -13,4 +13,9 @@ public abstract class TimeExecuteConstant {
*/
public static final String PROMOTION_EXECUTOR = "promotionTimeTriggerExecutor";
/**
* 直播间延迟加载执行器
*/
public static final String BROADCAST_EXECUTOR = "broadcastTimeTriggerExecutor";
}

View File

@ -1,6 +1,6 @@
package cn.lili.common.trigger.util;
import cn.lili.common.trigger.enums.PromotionDelayTypeEnums;
import cn.lili.common.trigger.enums.DelayTypeEnums;
/**
* 延时任务工具类
@ -22,7 +22,7 @@ public class DelayQueueTools {
* @param id id
* @return 唯一键
*/
public static String wrapperUniqueKey(PromotionDelayTypeEnums type, String id) {
public static String wrapperUniqueKey(DelayTypeEnums type, String id) {
return "{TIME_TRIGGER_" + type.name() + "}_" + id;
}

View File

@ -1,5 +1,6 @@
package cn.lili.common.utils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.multipart.MultipartFile;
import java.util.Base64;
@ -12,6 +13,7 @@ import java.io.*;
*
* @author Chopper
*/
@Slf4j
public class Base64DecodeMultipartFile implements MultipartFile {
private final byte[] imgContent;
@ -64,7 +66,7 @@ public class Base64DecodeMultipartFile implements MultipartFile {
stream = new FileOutputStream(dest);
stream.write(imgContent);
} catch (IOException e) {
e.printStackTrace();
log.error("transferTo错误",e);
}finally {
stream.close();
}
@ -92,14 +94,14 @@ public class Base64DecodeMultipartFile implements MultipartFile {
byte[] bytes = Base64.getDecoder().decode(base64);
stream = new ByteArrayInputStream(bytes);
} catch (Exception e) {
e.printStackTrace();
log.error("base64ToInputStream错误",e);
}
return stream;
}
public static String inputStreamToStream(InputStream in) {
byte[] data = null;
// 读取图片字节数组
//读取图片字节数组
try {
ByteArrayOutputStream swapStream = new ByteArrayOutputStream();
byte[] buff = new byte[100];
@ -109,13 +111,13 @@ public class Base64DecodeMultipartFile implements MultipartFile {
}
data = swapStream.toByteArray();
} catch (IOException e) {
e.printStackTrace();
log.error("转码错误",e);
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
log.error("inputStreamToStream错误",e);
}
}
}

View File

@ -14,9 +14,9 @@ import java.util.regex.Pattern;
public class CheckMobileUtil {
// \b 是单词边界(连着的两个(字母字符 非字母字符) 之间的逻辑上的间隔),
// 字符串在编译时会被转码一次,所以是 "\\b"
// \B 是单词内部逻辑间隔(连着的两个字母字符之间的逻辑上的间隔)
//\b 是单词边界(连着的两个(字母字符 非字母字符) 之间的逻辑上的间隔),
//字符串在编译时会被转码一次,所以是 "\\b"
//\B 是单词内部逻辑间隔(连着的两个字母字符之间的逻辑上的间隔)
static String phoneReg = "\\b(ip(hone|od)|android|opera m(ob|in)i"
+ "|windows (phone|ce)|blackberry"
+ "|s(ymbian|eries60|amsung)|p(laybook|alm|rofile/midp"
@ -41,7 +41,7 @@ public class CheckMobileUtil {
if (null == userAgent) {
userAgent = "";
}
// 匹配
//匹配
Matcher matcherPhone = phonePat.matcher(userAgent);
Matcher matcherTable = tablePat.matcher(userAgent);
if (matcherPhone.find() || matcherTable.find()) {

View File

@ -1,5 +1,7 @@
package cn.lili.common.utils;
import lombok.extern.slf4j.Slf4j;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@ -11,24 +13,9 @@ import javax.servlet.http.HttpServletResponse;
* @version v1.0
* 2020-12-14 09:32
*/
@Slf4j
public class CookieUtil {
/**
* 新增cookie
*
* @param key key值
* @param value 对应值
* @param response 响应
*/
public static void addCookie(String key, String value, HttpServletResponse response) {
try {
Cookie c = new Cookie(key, value);
c.setPath("/");
response.addCookie(c);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 新增cookie
@ -45,7 +32,7 @@ public class CookieUtil {
c.setPath("/");
response.addCookie(c);
} catch (Exception e) {
e.printStackTrace();
log.error("新增cookie错误",e);
}
}
@ -61,7 +48,7 @@ public class CookieUtil {
c.setMaxAge(0);
response.addCookie(c);
} catch (Exception e) {
e.printStackTrace();
log.error("删除cookie错误",e);
}
}
@ -83,7 +70,7 @@ public class CookieUtil {
}
}
} catch (Exception e) {
e.printStackTrace();
log.error("获取cookie错误",e);
}
return null;
}

View File

@ -56,6 +56,24 @@ public final class CurrencyUtil {
return b1.multiply(b2).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
}
/**
* 提供精确的乘法运算
*
* @param v1 被乘数
* @param v2 乘数
* @param scale 表示表示需要精确到小数点以后几位
* @return 两个参数的积
*/
public static Double mul(double v1, double v2, int scale) {
if (scale < 0) {
throw new IllegalArgumentException(
"The scale must be a positive integer or zero");
}
BigDecimal b1 = new BigDecimal(Double.toString(v1));
BigDecimal b2 = new BigDecimal(Double.toString(v2));
return b1.multiply(b2).setScale(scale, BigDecimal.ROUND_HALF_UP).doubleValue();
}
/**
* 提供相对精确的除法运算当发生除不尽的情况时 精确到小数点以后10位以后的数字四舍五入
*

View File

@ -148,18 +148,18 @@ public class DateUtil {
* @return
*/
public static Long[] getLastMonth() {
// 取得系统当前时间
//取得系统当前时间
Calendar cal = Calendar.getInstance();
int year = cal.get(Calendar.YEAR);
int month = cal.get(Calendar.MONTH) + 1;
// 取得系统当前时间所在月第一天时间对象
//取得系统当前时间所在月第一天时间对象
cal.set(Calendar.DAY_OF_MONTH, 1);
// 日期减一,取得上月最后一天时间对象
//日期减一,取得上月最后一天时间对象
cal.add(Calendar.DAY_OF_MONTH, -1);
// 输出上月最后一天日期
//输出上月最后一天日期
int day = cal.get(Calendar.DAY_OF_MONTH);
String months = "";
@ -355,7 +355,7 @@ public class DateUtil {
*/
public static Integer getDelayTime(Long startTime) {
int time = Math.toIntExact((startTime - System.currentTimeMillis()) / 1000);
// 如果时间为负数则改为一秒后执行
//如果时间为负数则改为一秒后执行
if (time <= 0) {
time = 1;
}

View File

@ -43,14 +43,14 @@ public class HibernateProxyTypeAdapter extends TypeAdapter<HibernateProxy> {
out.nullValue();
return;
}
// Retrieve the original (not proxy) class
//Retrieve the original (not proxy) class
Class<?> baseType = Hibernate.getClass(value);
// Get the TypeAdapter of the original class, to delegate the serialization
//Get the TypeAdapter of the original class, to delegate the serialization
TypeAdapter delegate = context.getAdapter(TypeToken.get(baseType));
// Get a filled instance of the original class
//Get a filled instance of the original class
Object unproxiedValue = ((HibernateProxy) value).getHibernateLazyInitializer()
.getImplementation();
// Serialize the value
//Serialize the value
delegate.write(out, unproxiedValue);
}
}

View File

@ -1,9 +1,12 @@
package cn.lili.common.utils;
import org.apache.http.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpEntityEnclosingRequest;
import org.apache.http.HttpHost;
import org.apache.http.HttpRequest;
import org.apache.http.NoHttpResponseException;
import org.apache.http.client.HttpRequestRetryHandler;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
@ -21,7 +24,6 @@ import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import javax.net.ssl.SSLException;
@ -30,31 +32,30 @@ import java.io.IOException;
import java.io.InterruptedIOException;
import java.net.URI;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@Slf4j
public class HttpClientUtils {
// org.apache.http.impl.client.CloseableHttpClient
//org.apache.http.impl.client.CloseableHttpClient
private static CloseableHttpClient httpClient = null;
// 这里就直接默认固定了,因为以下三个参数在新建的method中仍然可以重新配置并被覆盖.
static final int connectionRequestTimeout = 30000;// ms毫秒,从池中获取链接超时时间
static final int connectTimeout = 60000;// ms毫秒,建立链接超时时间
static final int socketTimeout = 60000;// ms毫秒,读取超时时间
//这里就直接默认固定了,因为以下三个参数在新建的method中仍然可以重新配置并被覆盖.
static final int connectionRequestTimeout = 30000;//ms毫秒,从池中获取链接超时时间
static final int connectTimeout = 60000;//ms毫秒,建立链接超时时间
static final int socketTimeout = 60000;//ms毫秒,读取超时时间
// 总配置,主要涉及是以下两个参数,如果要作调整没有用到properties会比较后麻烦,但鉴于一经粘贴,随处可用的特点,就不再做依赖性配置化处理了.
// 而且这个参数同一家公司基本不会变动.
static final int maxTotal = 500;// 最大总并发,很重要的参数
static final int maxPerRoute = 100;// 每路并发,很重要的参数
//总配置,主要涉及是以下两个参数,如果要作调整没有用到properties会比较后麻烦,但鉴于一经粘贴,随处可用的特点,就不再做依赖性配置化处理了.
//而且这个参数同一家公司基本不会变动.
static final int maxTotal = 500;//最大总并发,很重要的参数
static final int maxPerRoute = 100;//每路并发,很重要的参数
// 正常情况这里应该配成MAP或LIST
// 细化配置参数,用来对每路参数做精细化处理,可以管控各ip的流量,比如默认配置请求baidu:80端口最大100个并发链接,
static final String detailHostName = "http://www.baidu.com";// 每个细化配置之ip(不重要,在特殊场景很有用)
// 每个细化配置之port(不重要,在特殊场景很有用)
//正常情况这里应该配成MAP或LIST
//细化配置参数,用来对每路参数做精细化处理,可以管控各ip的流量,比如默认配置请求baidu:80端口最大100个并发链接,
static final String detailHostName = "http://www.baidu.com";//每个细化配置之ip(不重要,在特殊场景很有用)
//每个细化配置之port(不重要,在特殊场景很有用)
static final int detailPort = 80;
// 每个细化配置之最大并发数(不重要,在特殊场景很有用)
//每个细化配置之最大并发数(不重要,在特殊场景很有用)
static final int detailMaxPerRoute = 100;
private synchronized static CloseableHttpClient getHttpClient() {
@ -71,51 +72,51 @@ public class HttpClientUtils {
private static CloseableHttpClient init() {
CloseableHttpClient newHotpoint;
// 设置连接池
//设置连接池
ConnectionSocketFactory plainsf = PlainConnectionSocketFactory.getSocketFactory();
LayeredConnectionSocketFactory sslsf = SSLConnectionSocketFactory.getSocketFactory();
Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create().register("http", plainsf).register("https", sslsf).build();
PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(registry);
// 将最大连接数增加
//将最大连接数增加
cm.setMaxTotal(maxTotal);
// 将每个路由基础的连接增加
//将每个路由基础的连接增加
cm.setDefaultMaxPerRoute(maxPerRoute);
// 细化配置开始,其实这里用Map或List的for循环来配置每个链接,在特殊场景很有用.
// 将每个路由基础的连接做特殊化配置,一般用不着
//细化配置开始,其实这里用Map或List的for循环来配置每个链接,在特殊场景很有用.
//将每个路由基础的连接做特殊化配置,一般用不着
HttpHost httpHost = new HttpHost(detailHostName, detailPort);
// 将目标主机的最大连接数增加
//将目标主机的最大连接数增加
cm.setMaxPerRoute(new HttpRoute(httpHost), detailMaxPerRoute);
// 细化配置结束
//细化配置结束
// 请求重试处理
//请求重试处理
HttpRequestRetryHandler httpRequestRetryHandler = (exception, executionCount, context) -> {
if (executionCount >= 2) {// 如果已经重试了2次就放弃
if (executionCount >= 2) {//如果已经重试了2次就放弃
return false;
}
if (exception instanceof NoHttpResponseException) {// 如果服务器丢掉了连接那么就重试
if (exception instanceof NoHttpResponseException) {//如果服务器丢掉了连接那么就重试
return true;
}
if (exception instanceof SSLHandshakeException) {// 不要重试SSL握手异常
if (exception instanceof SSLHandshakeException) {//不要重试SSL握手异常
return false;
}
if (exception instanceof InterruptedIOException) {// 超时
if (exception instanceof InterruptedIOException) {//超时
return false;
}
if (exception instanceof UnknownHostException) {// 目标服务器不可达
if (exception instanceof UnknownHostException) {//目标服务器不可达
return false;
}
if (exception instanceof SSLException) {// SSL握手异常
if (exception instanceof SSLException) {//SSL握手异常
return false;
}
HttpClientContext clientContext = HttpClientContext.adapt(context);
HttpRequest request = clientContext.getRequest();
// 如果请求是幂等的就再次尝试
//如果请求是幂等的就再次尝试
return !(request instanceof HttpEntityEnclosingRequest);
};
// 配置请求的超时设置
//配置请求的超时设置
RequestConfig requestConfig = RequestConfig.custom().setConnectionRequestTimeout(connectionRequestTimeout).setConnectTimeout(connectTimeout).setSocketTimeout(socketTimeout).build();
newHotpoint = HttpClients.custom().setConnectionManager(cm).setDefaultRequestConfig(requestConfig).setRetryHandler(httpRequestRetryHandler).build();
return newHotpoint;
@ -123,13 +124,13 @@ public class HttpClientUtils {
public static String doGet(String url, Map<String, String> param) {
// httpClient
//httpClient
CloseableHttpClient httpClient = getHttpClient();
String resultString = "";
CloseableHttpResponse response = null;
try {
// 创建uri
//创建uri
URIBuilder builder = new URIBuilder(url);
if (param != null) {
for (String key : param.keySet()) {
@ -138,19 +139,17 @@ public class HttpClientUtils {
}
URI uri = builder.build();
// 创建http GET请求
//创建http GET请求
HttpGet httpGet = new HttpGet(uri);
// 执行请求
//执行请求
response = httpClient.execute(httpGet);
// 判断返回状态是否为200
//判断返回状态是否为200
if (response.getStatusLine().getStatusCode() == 200) {
resultString = EntityUtils.toString(response.getEntity(), "UTF-8");
} else {
System.out.println(response.getStatusLine().getStatusCode());
}
} catch (Exception e) {
e.printStackTrace();
log.error("get请求错误",e);
} finally {
try {
if (response != null) {
@ -158,71 +157,9 @@ public class HttpClientUtils {
}
httpClient.close();
} catch (IOException e) {
e.printStackTrace();
log.error("Get错误",e);
}
}
return resultString;
}
public static String doPost(String url, Map<String, String> param) {
// 创建HttpClient对象
CloseableHttpClient httpClient = getHttpClient();
CloseableHttpResponse response = null;
String resultString = "";
try {
// 创建Http Post请求
HttpPost httpPost = new HttpPost(url);
// 创建参数列表
if (param != null) {
List<NameValuePair> paramList = new ArrayList<>();
for (String key : param.keySet()) {
paramList.add(new BasicNameValuePair(key, param.get(key)));
}
// 模拟表单
UrlEncodedFormEntity entity = new UrlEncodedFormEntity(paramList, "utf-8");
httpPost.setEntity(entity);
}
// 执行http请求
response = httpClient.execute(httpPost);
resultString = EntityUtils.toString(response.getEntity(), "utf-8");
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
response.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return resultString;
}
public static String doPostJson(String url, String json) {
// 创建HttpClient对象
CloseableHttpClient httpClient = getHttpClient();
CloseableHttpResponse response = null;
String resultString = "";
try {
// 创建Http Post请求
HttpPost httpPost = new HttpPost(url);
// 创建请求内容
StringEntity entity = new StringEntity(json, ContentType.APPLICATION_JSON);
httpPost.setEntity(entity);
// 执行http请求
response = httpClient.execute(httpPost);
resultString = EntityUtils.toString(response.getEntity(), "utf-8");
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
response.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return resultString;
}
}

View File

@ -90,7 +90,7 @@ public class PageUtil {
*/
public static <T> QueryWrapper<T> initWrapper(Object object, SearchVO searchVo) {
QueryWrapper<T> queryWrapper = new QueryWrapper<>();
// 创建时间区间判定
//创建时间区间判定
if (searchVo != null && StrUtil.isNotBlank(searchVo.getStartDate()) && StrUtil.isNotBlank(searchVo.getEndDate())) {
Date start = cn.hutool.core.date.DateUtil.parse(searchVo.getStartDate());
Date end = cn.hutool.core.date.DateUtil.parse(searchVo.getEndDate());

View File

@ -50,11 +50,11 @@ public class PasswordUtil {
* @return Key PBE算法密钥
*/
private static Key getPBEKey(String password) throws Exception {
// 实例化使用的算法
//实例化使用的算法
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(ALGORITHM);
// 设置PBE密钥参数
//设置PBE密钥参数
PBEKeySpec keySpec = new PBEKeySpec(password.toCharArray());
// 生成密钥
//生成密钥
SecretKey secretKey = keyFactory.generateSecret(keySpec);
return secretKey;

View File

@ -1,13 +1,12 @@
package cn.lili.common.utils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.DefaultTypedTuple;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
@ -17,6 +16,7 @@ import java.util.concurrent.TimeUnit;
* @author paulG
* @since 2020/11/7
**/
@Slf4j
@Component
public class RedisUtil {
@Autowired
@ -38,51 +38,11 @@ public class RedisUtil {
}
return true;
} catch (Exception e) {
e.printStackTrace();
log.error("指定缓存失效时间错误",e);
return false;
}
}
/**
* 根据key 获取过期时间
*
* @param key 不能为null
* @return 时间() 返回0代表为永久有效
*/
public long getExpire(String key) {
return redisTemplate.getExpire(key, TimeUnit.SECONDS);
}
/**
* 判断key是否存在
*
* @param key
* @return true 存在 false不存在
*/
public boolean hasKey(String key) {
try {
return redisTemplate.hasKey(key);
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 删除缓存
*
* @param key 可以传一个值 或多个
*/
@SuppressWarnings("unchecked")
public void del(String... key) {
if (key != null && key.length > 0) {
if (key.length == 1) {
redisTemplate.delete(key[0]);
} else {
redisTemplate.delete(CollectionUtils.arrayToList(key));
}
}
}
//============================String=============================
@ -120,7 +80,7 @@ public class RedisUtil {
redisTemplate.opsForValue().set(key, value);
return true;
} catch (Exception e) {
e.printStackTrace();
log.error("缓存放入错误",e);
return false;
}
@ -143,215 +103,13 @@ public class RedisUtil {
}
return true;
} catch (Exception e) {
e.printStackTrace();
log.error("普通缓存放入并设置时间错误",e);
return false;
}
}
/**
* 递增
*
* @param key
* @return
*/
public long incr(String key, long delta) {
if (delta < 0) {
throw new RuntimeException("递增因子必须大于0");
}
return redisTemplate.opsForValue().increment(key, delta);
}
/**
* 递减
*
* @param key
* @return
*/
public long decr(String key, long delta) {
if (delta < 0) {
throw new RuntimeException("递减因子必须大于0");
}
return redisTemplate.opsForValue().increment(key, -delta);
}
//================================Map=================================
/**
* HashGet
*
* @param key 不能为null
* @param item 不能为null
* @return
*/
public Object hget(String key, String item) {
return redisTemplate.opsForHash().get(key, item);
}
/**
* 获取hashKey对应的所有键值
*
* @param key
* @return 对应的多个键值
*/
public Map<Object, Object> hmget(String key) {
return redisTemplate.opsForHash().entries(key);
}
/**
* HashSet
*
* @param key
* @param map 对应多个键值
* @return true 成功 false 失败
*/
public boolean hmset(String key, Map<String, Object> map) {
try {
redisTemplate.opsForHash().putAll(key, map);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* HashSet 并设置时间
*
* @param key
* @param map 对应多个键值
* @param time 时间()
* @return true成功 false失败
*/
public boolean hmset(String key, Map<String, Object> map, long time) {
try {
redisTemplate.opsForHash().putAll(key, map);
if (time > 0) {
expire(key, time);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 向一张hash表中放入数据,如果不存在将创建
*
* @param key
* @param item
* @param value
* @return true 成功 false失败
*/
public boolean hset(String key, String item, Object value) {
try {
redisTemplate.opsForHash().put(key, item, value);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 向一张hash表中放入数据,如果不存在将创建
*
* @param key
* @param item
* @param value
* @param time 时间() 注意:如果已存在的hash表有时间,这里将会替换原有的时间
* @return true 成功 false失败
*/
public boolean hset(String key, String item, Object value, long time) {
try {
redisTemplate.opsForHash().put(key, item, value);
if (time > 0) {
expire(key, time);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 删除hash表中的值
*
* @param key 不能为null
* @param item 可以使多个 不能为null
*/
public void hdel(String key, Object... item) {
redisTemplate.opsForHash().delete(key, item);
}
/**
* 判断hash表中是否有该项的值
*
* @param key 不能为null
* @param item 不能为null
* @return true 存在 false不存在
*/
public boolean hHasKey(String key, String item) {
return redisTemplate.opsForHash().hasKey(key, item);
}
/**
* hash递增 如果不存在,就会创建一个 并把新增后的值返回
*
* @param key
* @param item
* @param by 要增加几(大于0)
* @return
*/
public double hincr(String key, String item, double by) {
return redisTemplate.opsForHash().increment(key, item, by);
}
/**
* hash递减
*
* @param key
* @param item
* @param by 要减少记(小于0)
* @return
*/
public double hdecr(String key, String item, double by) {
return redisTemplate.opsForHash().increment(key, item, -by);
}
//============================set=============================
/**
* 根据key获取Set中的所有值
*
* @param key
* @return
*/
public Set<Object> sGet(String key) {
try {
return redisTemplate.opsForSet().members(key);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* 根据value从一个set中查询,是否存在
*
* @param key
* @param value
* @return true 存在 false不存在
*/
public boolean sHasKey(String key, Object value) {
try {
return redisTemplate.opsForSet().isMember(key, value);
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 将数据放入set缓存
@ -364,112 +122,11 @@ public class RedisUtil {
try {
return redisTemplate.opsForSet().add(key, values);
} catch (Exception e) {
e.printStackTrace();
log.error("将数据放入set缓存错误",e);
return 0;
}
}
/**
* 将set数据放入缓存
*
* @param key
* @param time 时间()
* @param values 可以是多个
* @return 成功个数
*/
public long sSetAndTime(String key, long time, Object... values) {
try {
Long count = redisTemplate.opsForSet().add(key, values);
if (time > 0) {
expire(key, time);
}
return count;
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}
/**
* 获取set缓存的长度
*
* @param key
* @return
*/
public long sGetSetSize(String key) {
try {
return redisTemplate.opsForSet().size(key);
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}
/**
* 移除值为value的
*
* @param key
* @param values 可以是多个
* @return 移除的个数
*/
public long setRemove(String key, Object... values) {
try {
Long count = redisTemplate.opsForSet().remove(key, values);
return count;
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}
//===============================listByParentId=================================
/**
* 获取list缓存的内容
*
* @param key
* @param start 开始
* @param end 结束 0 -1代表所有值
* @return
*/
public List<Object> lGet(String key, long start, long end) {
try {
return redisTemplate.opsForList().range(key, start, end);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* 获取list缓存的长度
*
* @param key
* @return
*/
public long lGetListSize(String key) {
try {
return redisTemplate.opsForList().size(key);
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}
/**
* 通过索引 获取list中的值
*
* @param key
* @param index 索引 index>=0时 0 表头1 第二个元素依次类推index<0时-1表尾-2倒数第二个元素依次类推
* @return
*/
public Object lGetIndex(String key, long index) {
try {
return redisTemplate.opsForList().index(key, index);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* 将list放入缓存
@ -483,7 +140,7 @@ public class RedisUtil {
redisTemplate.opsForList().rightPush(key, value);
return true;
} catch (Exception e) {
e.printStackTrace();
log.error("将list放入缓存错误",e);
return false;
}
}
@ -504,7 +161,7 @@ public class RedisUtil {
}
return true;
} catch (Exception e) {
e.printStackTrace();
log.error("将list放入缓存错误",e);
return false;
}
}
@ -521,27 +178,11 @@ public class RedisUtil {
redisTemplate.opsForList().rightPushAll(key, value);
return true;
} catch (Exception e) {
e.printStackTrace();
log.error("将list放入缓存错误",e);
return false;
}
}
/**
* 将list放入缓存
*
* @param key
* @param value
* @return
*/
public <T> boolean lPush(String key, List<T> value) {
try {
redisTemplate.opsForList().leftPushAll(key, value);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 将list放入缓存
@ -559,46 +200,12 @@ public class RedisUtil {
}
return true;
} catch (Exception e) {
e.printStackTrace();
log.error("将list放入缓存错误",e);
return false;
}
}
/**
* 根据索引修改list中的某条数据
*
* @param key
* @param index 索引
* @param value
* @return
*/
public boolean lUpdateIndex(String key, long index, Object value) {
try {
redisTemplate.opsForList().set(key, index, value);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 移除N个值为value
*
* @param key
* @param count 移除多少个
* @param value
* @return 移除的个数
*/
public long lRemove(String key, long count, Object value) {
try {
Long remove = redisTemplate.opsForList().remove(key, count, value);
return remove;
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}
//===============================ZSet=================================
/**

View File

@ -17,10 +17,10 @@ import org.springframework.expression.spel.support.StandardEvaluationContext;
public class SpelUtil {
// spel表达式解析器
//spel表达式解析器
private static SpelExpressionParser spelExpressionParser = new SpelExpressionParser();
// 参数名发现器
//参数名发现器
private static DefaultParameterNameDiscoverer parameterNameDiscoverer = new DefaultParameterNameDiscoverer();
/**
@ -30,8 +30,8 @@ public class SpelUtil {
* @param spel
* @return
*/
public static String compileParams(JoinPoint joinPoint, String spel) { // Spel表达式解析日志信息
// 获得方法参数名数组
public static String compileParams(JoinPoint joinPoint, String spel) { //Spel表达式解析日志信息
//获得方法参数名数组
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
String[] parameterNames = parameterNameDiscoverer.getParameterNames(signature.getMethod());
@ -41,7 +41,7 @@ public class SpelUtil {
//获取方法参数值
Object[] args = joinPoint.getArgs();
for (int i = 0; i < args.length; i++) {
context.setVariable(parameterNames[i], args[i]); // 替换spel里的变量值为实际值 比如 #user --> user对象
context.setVariable(parameterNames[i], args[i]); //替换spel里的变量值为实际值 比如 #user --> user对象
}
return spelExpressionParser.parseExpression(spel).getValue(context).toString();
}
@ -55,8 +55,8 @@ public class SpelUtil {
* @param spel
* @return
*/
public static String compileParams(JoinPoint joinPoint, Object rvt, String spel) { // Spel表达式解析日志信息
// 获得方法参数名数组
public static String compileParams(JoinPoint joinPoint, Object rvt, String spel) { //Spel表达式解析日志信息
//获得方法参数名数组
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
String[] parameterNames = parameterNameDiscoverer.getParameterNames(signature.getMethod());
@ -66,7 +66,7 @@ public class SpelUtil {
//获取方法参数值
Object[] args = joinPoint.getArgs();
for (int i = 0; i < args.length; i++) {
context.setVariable(parameterNames[i], args[i]); // 替换spel里的变量值为实际值 比如 #user --> user对象
context.setVariable(parameterNames[i], args[i]); //替换spel里的变量值为实际值 比如 #user --> user对象
}
context.setVariable("rvt", rvt);
return spelExpressionParser.parseExpression(spel).getValue(context).toString();

View File

@ -22,13 +22,13 @@ public class ImageUtil {
*/
public static void addWatermark(BufferedImage oriImage, String text) {
Graphics2D graphics2D = oriImage.createGraphics();
// 设置水印文字颜色
//设置水印文字颜色
graphics2D.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
// 设置水印文字Font
//设置水印文字Font
graphics2D.setColor(Color.black);
// 设置水印文字透明度
//设置水印文字透明度
graphics2D.setFont(new Font("宋体", Font.BOLD, 30));
// 第一参数->设置的内容后面两个参数->文字在图片上的坐标位置(x,y)
//第一参数->设置的内容后面两个参数->文字在图片上的坐标位置(x,y)
graphics2D.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, 0.4f));
graphics2D.drawString(text, 10, 40);
graphics2D.dispose();
@ -44,40 +44,40 @@ public class ImageUtil {
*/
public static void cutByTemplate(BufferedImage oriImage, BufferedImage templateImage, BufferedImage newImage,
int x, int y) {
// 临时数组遍历用于高斯模糊存周边像素值
//临时数组遍历用于高斯模糊存周边像素值
int[][] matrix = new int[3][3];
int[] values = new int[9];
int xLength = templateImage.getWidth();
int yLength = templateImage.getHeight();
// 模板图像宽度
//模板图像宽度
for (int i = 0; i < xLength; i++) {
// 模板图片高度
//模板图片高度
for (int j = 0; j < yLength; j++) {
// 如果模板图像当前像素点不是透明色 copy源文件信息到目标图片中
//如果模板图像当前像素点不是透明色 copy源文件信息到目标图片中
int rgb = templateImage.getRGB(i, j);
if (rgb < 0) {
newImage.setRGB(i, j, oriImage.getRGB(x + i, y + j));
// 抠图区域高斯模糊
//抠图区域高斯模糊
readPixel(oriImage, x + i, y + j, values);
fillMatrix(matrix, values);
oriImage.setRGB(x + i, y + j, avgMatrix(matrix));
}
// 防止数组越界判断
//防止数组越界判断
if (i == (xLength - 1) || j == (yLength - 1)) {
continue;
}
int rightRgb = templateImage.getRGB(i + 1, j);
int downRgb = templateImage.getRGB(i, j + 1);
// 描边处理,取带像素和无像素的界点判断该点是不是临界轮廓点,如果是设置该坐标像素是白色
//描边处理,取带像素和无像素的界点判断该点是不是临界轮廓点,如果是设置该坐标像素是白色
if ((rgb >= 0 && rightRgb < 0) || (rgb < 0 && rightRgb >= 0) || (rgb >= 0 && downRgb < 0)
|| (rgb < 0 && downRgb >= 0)) {
newImage.setRGB(i, j, Color.GRAY.getRGB());
// oriImage.setRGB(x + i, y + j, Color.white.getRGB());
// oriImage.setRGB(x + i, y + j, Color.white.getRGB());
}
}
}

View File

@ -44,34 +44,34 @@ public class SliderImageUtil {
Random random = new Random();
Map<String, Object> pictureMap = new HashMap<>();
// 拼图
//拼图
BufferedImage sliderImage = ImageIO.read(Base64DecodeMultipartFile.base64ToInputStream(sliderFile.getBase64()));
int sliderWidth = sliderImage.getWidth();
int sliderHeight = sliderImage.getHeight();
// 原图
//原图
BufferedImage originalImage = ImageIO.read(Base64DecodeMultipartFile.base64ToInputStream(originalFile.getBase64()));
int originalWidth = originalImage.getWidth();
int originalHeight = originalImage.getHeight();
// 随机生成抠图坐标X,Y
// X轴距离右端targetWidth Y轴距离底部targetHeight以上
//随机生成抠图坐标X,Y
//X轴距离右端targetWidth Y轴距离底部targetHeight以上
int randomX = random.nextInt(originalWidth - 3 * sliderWidth) + 2 * sliderWidth;
int randomY = random.nextInt(originalHeight - sliderHeight);
log.info("原图大小{} x {},随机生成的坐标 X,Y 为({}{}", originalWidth, originalHeight, randomX, randomY);
// 新建一个和模板一样大小的图像TYPE_4BYTE_ABGR表示具有8位RGBA颜色分量的图像正常取imageTemplate.getType()
//新建一个和模板一样大小的图像TYPE_4BYTE_ABGR表示具有8位RGBA颜色分量的图像正常取imageTemplate.getType()
BufferedImage newImage = new BufferedImage(sliderWidth, sliderHeight, sliderImage.getType());
// 得到画笔对象
//得到画笔对象
Graphics2D graphics = newImage.createGraphics();
// 如果需要生成RGB格式需要做如下配置,Transparency 设置透明
//如果需要生成RGB格式需要做如下配置,Transparency 设置透明
newImage = graphics.getDeviceConfiguration().createCompatibleImage(sliderWidth, sliderHeight,
Transparency.TRANSLUCENT);
// 新建的图像根据模板颜色赋值,源图生成遮罩
//新建的图像根据模板颜色赋值,源图生成遮罩
ImageUtil.cutByTemplate(originalImage, sliderImage, newImage, randomX, randomY);
// 设置抗锯齿的属性
//设置抗锯齿的属性
graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
graphics.setStroke(new BasicStroke(BOLD, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL));
graphics.drawImage(newImage, 0, 0, null);
@ -79,19 +79,19 @@ public class SliderImageUtil {
//添加水印
ImageUtil.addWatermark(originalImage, "请滑动拼图");
ByteArrayOutputStream newImageOs = new ByteArrayOutputStream();// 新建流
ImageIO.write(newImage, TEMP_IMG_FILE_TYPE, newImageOs);// 利用ImageIO类提供的write方法将bi以png图片的数据模式写入流
ByteArrayOutputStream newImageOs = new ByteArrayOutputStream();//新建流
ImageIO.write(newImage, TEMP_IMG_FILE_TYPE, newImageOs);//利用ImageIO类提供的write方法将bi以png图片的数据模式写入流
byte[] newImagery = newImageOs.toByteArray();
ByteArrayOutputStream oriImagesOs = new ByteArrayOutputStream();// 新建流
ImageIO.write(originalImage, IMG_FILE_TYPE, oriImagesOs);// 利用ImageIO类提供的write方法将bi以jpg图片的数据模式写入流
ByteArrayOutputStream oriImagesOs = new ByteArrayOutputStream();//新建流
ImageIO.write(originalImage, IMG_FILE_TYPE, oriImagesOs);//利用ImageIO类提供的write方法将bi以jpg图片的数据模式写入流
byte[] oriImageByte = oriImagesOs.toByteArray();
pictureMap.put("slidingImage", "data:image/png;base64," + Base64Utils.encodeToString(newImagery));
pictureMap.put("backImage", "data:image/png;base64," + Base64Utils.encodeToString(oriImageByte));
// x轴
// x轴
pictureMap.put("randomX", randomX);
// y轴
// y轴
pictureMap.put("randomY", randomY);
pictureMap.put("originalHeight", originalHeight);

View File

@ -58,14 +58,14 @@ public class VerificationServiceImpl implements VerificationService {
Random random = new Random();
// 随机选择需要切的图下标
//随机选择需要切的图下标
int resourceNum = random.nextInt(verificationResources.size());
// 随机选择剪切模版下标
//随机选择剪切模版下标
int sliderNum = random.nextInt(verificationSlider.size());
// 随机选择需要切的图片地址
//随机选择需要切的图片地址
String originalResource = verificationResources.get(resourceNum).getResource();
// 随机选择剪切模版图片地址
//随机选择剪切模版图片地址
String sliderResource = verificationSlider.get(sliderNum).getResource();
try {
@ -73,16 +73,16 @@ public class VerificationServiceImpl implements VerificationService {
SerializableStream originalFile = getInputStream(originalResource);
SerializableStream sliderFile = getInputStream(sliderResource);
Map<String, Object> resultMap = SliderImageUtil.pictureTemplatesCut(sliderFile, originalFile);
// 生成验证参数 120可以验证 无需手动清除120秒有效时间自动清除
//生成验证参数 120可以验证 无需手动清除120秒有效时间自动清除
cache.put(cacheKey(verificationEnums, uuid), resultMap.get("randomX"), 120L);
resultMap.put("key", cacheKey(verificationEnums, uuid));
// 移除横坐标移动距离
//移除横坐标移动距离
resultMap.remove("randomX");
return resultMap;
} catch (ServiceException e) {
throw e;
} catch (Exception e) {
e.printStackTrace();
log.error("创建校验错误",e);
return null;
}
}

View File

@ -83,10 +83,10 @@ public class RedisConfig extends CachingConfigurerSupport {
RedisTemplate<Object, Object> template = new RedisTemplate<>();
//使用fastjson序列化
FastJsonRedisSerializer fastJsonRedisSerializer = new FastJsonRedisSerializer(Object.class);
// value值的序列化采用fastJsonRedisSerializer
//value值的序列化采用fastJsonRedisSerializer
template.setValueSerializer(fastJsonRedisSerializer);
template.setHashValueSerializer(fastJsonRedisSerializer);
// key的序列化采用StringRedisSerializer
//key的序列化采用StringRedisSerializer
template.setKeySerializer(new StringRedisSerializer());
template.setHashKeySerializer(new StringRedisSerializer());
template.setConnectionFactory(lettuceConnectionFactory);
@ -102,19 +102,19 @@ public class RedisConfig extends CachingConfigurerSupport {
return (target, method, params) -> {
Map<String, Object> container = new HashMap<>(3);
Class<?> targetClassClass = target.getClass();
// 类地址
//类地址
container.put("class", targetClassClass.toGenericString());
// 方法名称
//方法名称
container.put("methodName", method.getName());
// 包名称
//包名称
container.put("package", targetClassClass.getPackage());
// 参数列表
//参数列表
for (int i = 0; i < params.length; i++) {
container.put(String.valueOf(i), params[i]);
}
// 转为JSON字符串
//转为JSON字符串
String jsonString = JSON.toJSONString(container);
// 做SHA256 Hash计算得到一个SHA256摘要作为Key
//做SHA256 Hash计算得到一个SHA256摘要作为Key
return DigestUtils.sha256Hex(jsonString);
};
}
@ -122,7 +122,7 @@ public class RedisConfig extends CachingConfigurerSupport {
@Bean
@Override
public CacheErrorHandler errorHandler() {
// 异常处理当Redis发生异常时打印日志但是程序正常走
//异常处理当Redis发生异常时打印日志但是程序正常走
log.info("初始化 -> [{}]", "Redis CacheErrorHandler");
return new CacheErrorHandler() {
@Override

View File

@ -1,6 +1,7 @@
package cn.lili.config.elasticsearch;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpHost;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
@ -27,6 +28,7 @@ import java.util.List;
* @author paulG
* @since 2020/10/13
**/
@Slf4j
@Configuration
@RequiredArgsConstructor(onConstructor_ = @Autowired)
public class ElasticsearchConfig extends AbstractElasticsearchConfiguration {
@ -60,9 +62,9 @@ public class ElasticsearchConfig extends AbstractElasticsearchConfiguration {
}
restBuilder.setRequestConfigCallback(requestConfigBuilder ->
requestConfigBuilder.setConnectTimeout(1000) // time until a connection with the server is established.
.setSocketTimeout(12 * 1000) // time of inactivity to wait for packets[data] to receive.
.setConnectionRequestTimeout(2 * 1000)); // time to fetch a connection from the connection pool 0 for infinite.
requestConfigBuilder.setConnectTimeout(1000) //time until a connection with the server is established.
.setSocketTimeout(12 * 1000) //time of inactivity to wait for packets[data] to receive.
.setConnectionRequestTimeout(2 * 1000)); //time to fetch a connection from the connection pool 0 for infinite.
client = new RestHighLevelClient(restBuilder);
return client;
@ -96,7 +98,7 @@ public class ElasticsearchConfig extends AbstractElasticsearchConfiguration {
try {
this.client.close();
} catch (IOException e) {
e.printStackTrace();
log.error("es clientClose错误",e);
}
}

View File

@ -23,11 +23,11 @@ public class UrlConfiguration implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 注册拦截器
//注册拦截器
InterceptorRegistration ir = registry.addInterceptor(requestInterceptorAdapter);
// 配置拦截的路径
//配置拦截的路径
ir.addPathPatterns("/**");
// 配置不拦截的路径
//配置不拦截的路径
ir.excludePathPatterns(ignoredUrlsProperties.getUrls());
}
@ -36,7 +36,7 @@ public class UrlConfiguration implements WebMvcConfigurer {
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/statics/**").addResourceLocations("classpath:/statics/");
registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
// 解决 SWAGGER 404报错
//解决 SWAGGER 404报错
registry.addResourceHandler("/swagger-ui.html").addResourceLocations("classpath:/META-INF/resources/");
}

View File

@ -61,4 +61,8 @@ public class RocketmqCustomProperties {
private String afterSaleGroup;
private String broadcastTopic;
private String broadcastGroup;
}

View File

@ -37,9 +37,9 @@ public class CreateTimeShardingTableAlgorithmBak implements PreciseShardingAlgor
//循环增加区间的查询条件
// 因为考虑到 假设2019-052020-05
// 这快是没办法处理的因为分库分表之后每个库都要进行查询如果操作为1-4月那么2020年数据查询正确了可是2019年到5-12月数据就查询不到了
// 这里需要做一些性能的浪费现在看来是没办法处理到
//因为考虑到 假设2019-052020-05
//这快是没办法处理的因为分库分表之后每个库都要进行查询如果操作为1-4月那么2020年数据查询正确了可是2019年到5-12月数据就查询不到了
//这里需要做一些性能的浪费现在看来是没办法处理到
for (Integer i = 1; i <= 12; i++) {
collect.add("li_order_" + i);

View File

@ -73,8 +73,8 @@ public class Swagger2Config {
return new Docket(DocumentationType.SWAGGER_2)
.groupName("商品")
.apiInfo(apiInfo()).select()
// 扫描所有有注解的api用这种方式更灵活
// .apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
//扫描所有有注解的api用这种方式更灵活
// .apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
.apis(RequestHandlerSelectors.basePackage("cn.lili.controller.goods"))
.paths(PathSelectors.any())
.build()
@ -87,7 +87,7 @@ public class Swagger2Config {
return new Docket(DocumentationType.SWAGGER_2)
.groupName("会员")
.apiInfo(apiInfo()).select()
// 扫描所有有注解的api用这种方式更灵活
//扫描所有有注解的api用这种方式更灵活
.apis(RequestHandlerSelectors.basePackage("cn.lili.controller.member"))
.paths(PathSelectors.any())
.build()
@ -100,7 +100,7 @@ public class Swagger2Config {
return new Docket(DocumentationType.SWAGGER_2)
.groupName("促销")
.apiInfo(apiInfo()).select()
// 扫描所有有注解的api用这种方式更灵活
//扫描所有有注解的api用这种方式更灵活
.apis(RequestHandlerSelectors.basePackage("cn.lili.controller.promotion"))
.paths(PathSelectors.any())
.build()
@ -113,7 +113,7 @@ public class Swagger2Config {
return new Docket(DocumentationType.SWAGGER_2)
.groupName("店铺")
.apiInfo(apiInfo()).select()
// 扫描所有有注解的api用这种方式更灵活
//扫描所有有注解的api用这种方式更灵活
.apis(RequestHandlerSelectors.basePackage("cn.lili.controller.store"))
.paths(PathSelectors.any())
.build()
@ -126,7 +126,7 @@ public class Swagger2Config {
return new Docket(DocumentationType.SWAGGER_2)
.groupName("交易")
.apiInfo(apiInfo()).select()
// 扫描所有有注解的api用这种方式更灵活
//扫描所有有注解的api用这种方式更灵活
.apis(RequestHandlerSelectors.basePackage("cn.lili.controller.trade"))
.paths(PathSelectors.any())
.build()
@ -140,7 +140,7 @@ public class Swagger2Config {
return new Docket(DocumentationType.SWAGGER_2)
.groupName("设置")
.apiInfo(apiInfo()).select()
// 扫描所有有注解的api用这种方式更灵活
//扫描所有有注解的api用这种方式更灵活
.apis(RequestHandlerSelectors.basePackage("cn.lili.controller.setting"))
.paths(PathSelectors.any())
.build()
@ -153,7 +153,7 @@ public class Swagger2Config {
return new Docket(DocumentationType.SWAGGER_2)
.groupName("权限")
.apiInfo(apiInfo()).select()
// 扫描所有有注解的api用这种方式更灵活
//扫描所有有注解的api用这种方式更灵活
.apis(RequestHandlerSelectors.basePackage("cn.lili.controller.permission"))
.paths(PathSelectors.any())
.build()
@ -166,7 +166,7 @@ public class Swagger2Config {
return new Docket(DocumentationType.SWAGGER_2)
.groupName("其他")
.apiInfo(apiInfo()).select()
// 扫描所有有注解的api用这种方式更灵活
//扫描所有有注解的api用这种方式更灵活
.apis(RequestHandlerSelectors.basePackage("cn.lili.controller.other"))
.paths(PathSelectors.any())
.build()
@ -179,7 +179,7 @@ public class Swagger2Config {
return new Docket(DocumentationType.SWAGGER_2)
.groupName("通用")
.apiInfo(apiInfo()).select()
// 扫描所有有注解的api用这种方式更灵活
//扫描所有有注解的api用这种方式更灵活
.apis(RequestHandlerSelectors.basePackage("cn.lili.controller.common"))
.paths(PathSelectors.any())
.build()
@ -191,7 +191,7 @@ public class Swagger2Config {
return new Docket(DocumentationType.SWAGGER_2)
.groupName("分销")
.apiInfo(apiInfo()).select()
// 扫描所有有注解的api用这种方式更灵活
//扫描所有有注解的api用这种方式更灵活
.apis(RequestHandlerSelectors.basePackage("cn.lili.controller.distribution"))
.paths(PathSelectors.any())
.build()
@ -204,7 +204,7 @@ public class Swagger2Config {
return new Docket(DocumentationType.SWAGGER_2)
.groupName("统计")
.apiInfo(apiInfo()).select()
// 扫描所有有注解的api用这种方式更灵活
//扫描所有有注解的api用这种方式更灵活
.apis(RequestHandlerSelectors.basePackage("cn.lili.controller.statistics"))
.paths(PathSelectors.any())
.build()
@ -217,7 +217,7 @@ public class Swagger2Config {
return new Docket(DocumentationType.SWAGGER_2)
.groupName("支付")
.apiInfo(apiInfo()).select()
// 扫描所有有注解的api用这种方式更灵活
//扫描所有有注解的api用这种方式更灵活
.apis(RequestHandlerSelectors.basePackage("cn.lili.controller.payment"))
.paths(PathSelectors.any())
.build()
@ -230,7 +230,7 @@ public class Swagger2Config {
return new Docket(DocumentationType.SWAGGER_2)
.groupName("登录")
.apiInfo(apiInfo()).select()
// 扫描所有有注解的api用这种方式更灵活
//扫描所有有注解的api用这种方式更灵活
.apis(RequestHandlerSelectors.basePackage("cn.lili.controller.passport"))
.paths(PathSelectors.any())
.build()

View File

@ -27,15 +27,15 @@ public class ThreadConfig implements AsyncConfigurer {
@Override
public Executor getAsyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
// 核心线程数默认为5
// 核心线程数默认为5
executor.setCorePoolSize(threadProperties.getCorePoolSize());
// 最大线程数默认为10
// 最大线程数默认为10
executor.setMaxPoolSize(threadProperties.getMaxPoolSize());
// 队列最大长度一般需要设置值为足够大
// 队列最大长度一般需要设置值为足够大
executor.setQueueCapacity(threadProperties.getQueueCapacity());
// 线程池维护线程所允许的空闲时间默认为60s
// 线程池维护线程所允许的空闲时间默认为60s
executor.setKeepAliveSeconds(threadProperties.getKeepAliveSeconds());
// 允许超时关闭
// 允许超时关闭
executor.setAllowCoreThreadTimeOut(threadProperties.getAllowCoreThreadTimeOut());
executor.initialize();
return executor;

View File

@ -20,7 +20,7 @@ public class WebSocketStompConfig implements WebSocketMessageBrokerConfigurer {
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
// 允许使用socketJs方式访问 即可通过http://IP:PORT/manager/ws来和服务端websocket连接
//允许使用socketJs方式访问 即可通过http://IP:PORT/manager/ws来和服务端websocket连接
registry.addEndpoint("/ws").setAllowedOrigins("*").withSockJS();
}
@ -31,11 +31,11 @@ public class WebSocketStompConfig implements WebSocketMessageBrokerConfigurer {
@Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
// 订阅Broker名称 user点对点 topic广播即群发
//订阅Broker名称 user点对点 topic广播即群发
registry.enableSimpleBroker("/user","/topic");
// 全局(客户端)使用的消息前缀
//全局(客户端)使用的消息前缀
registry.setApplicationDestinationPrefixes("/app");
// 点对点使用的前缀 无需配置 默认/user
//点对点使用的前缀 无需配置 默认/user
registry.setUserDestinationPrefix("/user");
}
}

View File

@ -100,14 +100,14 @@ public class CodeGenerator {
* @throws IOException
*/
public static void main(String[] args) throws IOException {
// 模板路径
//模板路径
ClasspathResourceLoader resourceLoader = new ClasspathResourceLoader("/templates/");
Configuration cfg = Configuration.defaultConfiguration();
GroupTemplate gt = new GroupTemplate(resourceLoader, cfg);
// 生成代码
//生成代码
generateCode(gt);
//根据类名删除生成的代码
// deleteCode(className);
// deleteCode(className);
}
/**
@ -152,7 +152,7 @@ public class CodeGenerator {
entityDir.mkdirs();
}
if (!entityFile.exists()) {
// 若文件存在则不重新生成
//若文件存在则不重新生成
entityFile.createNewFile();
out = new FileOutputStream(entityFile);
entityTemplate.renderTo(out);
@ -170,7 +170,7 @@ public class CodeGenerator {
daoDir.mkdirs();
}
if (!daoFile.exists()) {
// 若文件存在则不重新生成
//若文件存在则不重新生成
daoFile.createNewFile();
out = new FileOutputStream(daoFile);
daoTemplate.renderTo(out);
@ -188,7 +188,7 @@ public class CodeGenerator {
serviceDir.mkdirs();
}
if (!serviceFile.exists()) {
// 若文件存在则不重新生成
//若文件存在则不重新生成
serviceFile.createNewFile();
out = new FileOutputStream(serviceFile);
serviceTemplate.renderTo(out);
@ -207,7 +207,7 @@ public class CodeGenerator {
serviceImplDir.mkdirs();
}
if (!serviceImplFile.exists()) {
// 若文件存在则不重新生成
//若文件存在则不重新生成
serviceImplFile.createNewFile();
out = new FileOutputStream(serviceImplFile);
serviceImplTemplate.renderTo(out);
@ -225,7 +225,7 @@ public class CodeGenerator {
controllerDir.mkdirs();
}
if (!controllerFile.exists()) {
// 若文件存在则不重新生成
//若文件存在则不重新生成
controllerFile.createNewFile();
out = new FileOutputStream(controllerFile);
controllerTemplate.renderTo(out);
@ -243,7 +243,7 @@ public class CodeGenerator {
mapperXmlDir.mkdirs();
}
if (!mapperXmlFile.exists()) {
// 若文件存在则不重新生成
//若文件存在则不重新生成
mapperXmlFile.createNewFile();
out = new FileOutputStream(mapperXmlFile);
mapperXmlTemplate.renderTo(out);

View File

@ -58,7 +58,7 @@ public class RegionServiceImpl extends ServiceImpl<RegionMapper, Region> impleme
//删除缓存
cache.vagueDel("{regions}");
} catch (Exception e) {
e.printStackTrace();
log.error("同步行政数据错误",e);
}
}
@ -141,25 +141,25 @@ public class RegionServiceImpl extends ServiceImpl<RegionMapper, Region> impleme
*/
private List<Region> initData(String jsonString) {
// 最终数据承载对象
//最终数据承载对象
List<Region> regions = new ArrayList<>();
JSONObject jsonObject = JSONObject.parseObject(jsonString);
//获取到国家及下面所有的信息 开始循环插入这里可以写成递归调用但是不如这样方便查看理解
JSONArray countryAll = jsonObject.getJSONArray("districts");
for (int i = 0; i < countryAll.size(); i++) {
JSONObject contry = countryAll.getJSONObject(i);
// String citycode0 = contry.getString("citycode");
// String adcode0 = contry.getString("adcode");
// String name0 = contry.getString("name");
// String center0 = contry.getString("center");
// String country = contry.getString("level");
// int level = 0;
// if (country.equals("country")) {
// level = 0;
// }
// 插入国家
// Integer id1 = insert(0, adcode0, citycode0, name0, center0, level, name0);
// Integer id1 = insert(0, adcode0, citycode0, name0, center0, level);
// String citycode0 = contry.getString("citycode");
// String adcode0 = contry.getString("adcode");
// String name0 = contry.getString("name");
// String center0 = contry.getString("center");
// String country = contry.getString("level");
// int level = 0;
// if (country.equals("country")) {
// level = 0;
// }
// 插入国家
// Integer id1 = insert(0, adcode0, citycode0, name0, center0, level, name0);
// Integer id1 = insert(0, adcode0, citycode0, name0, center0, level);
String id1 = "0";
JSONArray provinceAll = contry.getJSONArray("districts");
for (int j = 0; j < provinceAll.size(); j++) {
@ -192,7 +192,7 @@ public class RegionServiceImpl extends ServiceImpl<RegionMapper, Region> impleme
String level3 = district.getString("level");
//插入区县
String id4 = insert(regions, id3, citycode3, adcode3, name3, center3, level3, w, id1, id2, id3);
// JSONArray street = street3.getJSONArray("districts");
// JSONArray street = street3.getJSONArray("districts");
//有需要可以继续向下遍历
JSONArray streetAll = district.getJSONArray("districts");
for (int r = 0; r < streetAll.size(); r++) {
@ -232,11 +232,11 @@ public class RegionServiceImpl extends ServiceImpl<RegionMapper, Region> impleme
* @return
*/
public String insert(List<Region> regions, String parentId, String cityCode, String adCode, String name, String center, String level, Integer order, String... ids) {
// \"citycode\": [],\n" +
// " \"adcode\": \"100000\",\n" +
// " \"name\": \"中华人民共和国\",\n" +
// " \"center\": \"116.3683244,39.915085\",\n" +
// " \"level\": \"country\",\n" +
// \"citycode\": [],\n" +
// " \"adcode\": \"100000\",\n" +
// " \"name\": \"中华人民共和国\",\n" +
// " \"center\": \"116.3683244,39.915085\",\n" +
// " \"level\": \"country\",\n" +
Region record = new Region();
if (!adCode.equals("[]")) {
record.setAdCode(adCode);

View File

@ -0,0 +1,64 @@
package cn.lili.modules.broadcast.entity.dos;
import cn.lili.base.BaseEntity;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.persistence.Entity;
import javax.persistence.Table;
/**
* 小程序直播商品
* @author Bulbasaur
* @date: 2021/5/17 9:34 上午
*
*/
@Data
@Entity
@ApiModel(value = "Commodity", description = "直播商品")
@TableName("li_commodity")
@Table(name = "li_commodity")
public class Commodity extends BaseEntity {
@ApiModelProperty(value = "图片")
private String goodsImage;
@ApiModelProperty(value = "商品名称")
private String name;
//1一口价只需要传入priceprice2不传
//2价格区间price字段为左边界price2字段为右边界price和price2必传
//3显示折扣价price字段为原价price2字段为现价 price和price2必传
@ApiModelProperty(value = "价格类型")
private Integer priceType;
@ApiModelProperty(value = "价格")
private Double price;
@ApiModelProperty(value = "价格2")
private Double price2;
@ApiModelProperty(value = "商品详情页的小程序路径")
private String url;
@ApiModelProperty(value = "微信程序直播商品ID")
private Integer liveGoodsId;
@ApiModelProperty(value = "审核单ID")
private String auditId;
@ApiModelProperty(value = "审核状态")
private String auditStatus;
@ApiModelProperty(value = "店铺ID")
private String storeId;
@ApiModelProperty(value = "商品ID")
private String goodsId;
@ApiModelProperty(value = "规格ID")
private String skuId;
}

View File

@ -0,0 +1,97 @@
package cn.lili.modules.broadcast.entity.dos;
import cn.lili.base.BaseEntity;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.persistence.Entity;
import javax.persistence.Table;
/**
* 小程序直播间
*
* @author Bulbasaur
* @date: 2021/5/17 9:47 上午
*/
@Data
@Entity
@ApiModel(value = "直播间")
@TableName("li_studio")
@Table(name = "li_studio")
public class Studio extends BaseEntity {
/**
* 直播间名字最短3个汉字最长17个汉字1个汉字相当于2个字符
*/
@ApiModelProperty(value = "直播间名字")
private String name;
/**
* 背景图填入mediaIDmediaID获取后三天内有效图片mediaID的获取请参考以下文档 https://developers.weixin.qq.com/doc/offiaccount/Asset_Management/New_temporary_materials.html直播间背景图图片规则建议像素1080*1920大小不超过2M
*/
@ApiModelProperty(value = "背景图")
private String coverImg;
/**
* 直播计划开始时间开播时间需要在当前时间的10分钟后 并且 开始时间不能在 6 个月后
*/
@ApiModelProperty(value = "开始时间")
private String startTime;
/**
* 直播计划结束时间开播时间和结束时间间隔不得短于30分钟不得超过24小时
*/
@ApiModelProperty(value = "结束时间")
private String endTime;
/**
* 主播昵称最短2个汉字最长15个汉字1个汉字相当于2个字符
*/
@ApiModelProperty(value = "主播昵称")
private String anchorName;
/**
* 主播微信号如果未实名认证需要先前往小程序直播小程序进行实名验证, 小程序二维码链接https://res.wx.qq.com/op_res/9rSix1dhHfK4rR049JL0PHJ7TpOvkuZ3mE0z7Ou_Etvjf-w1J_jVX0rZqeStLfwh
*/
@ApiModelProperty(value = "主播微信号")
private String anchorWechat;
/**
* 分享图填入mediaIDmediaID获取后三天内有效图片mediaID的获取请参考以下文档 https://developers.weixin.qq.com/doc/offiaccount/Asset_Management/New_temporary_materials.html直播间分享图图片规则建议像素800*640大小不超过1M
*/
@ApiModelProperty(value = "分享图")
private String shareImg;
/**
* 购物直播频道封面图填入mediaIDmediaID获取后三天内有效图片mediaID的获取请参考以下文档 https://developers.weixin.qq.com/doc/offiaccount/Asset_Management/New_temporary_materials.html; 购物直播频道封面图图片规则建议像素800*800大小不超过100KB
*/
@ApiModelProperty(value = "封面图")
private String feedsImg;
@ApiModelProperty(value = "回放视频链接")
private String mediaUrl;
@ApiModelProperty(value = "房间ID")
private Integer roomId;
@ApiModelProperty(value = "小程序直播码")
private String qrCodeUrl;
@ApiModelProperty(value = "店铺ID")
private String storeId;
@ApiModelProperty(value = "直播间商品数量")
private Integer roomGoodsNum;
@ApiModelProperty(value = "直播间商品(最多展示两个商品name/goodsImage)")
private String roomGoodsList;
@ApiModelProperty(value = "推荐直播间")
private boolean recommend;
@ApiModelProperty(value = "直播间状态")
private String status;
}

View File

@ -0,0 +1,47 @@
package cn.lili.modules.broadcast.entity.dos;
import com.baomidou.mybatisplus.annotation.TableField;
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.NoArgsConstructor;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
/**
* 直播商品
*
* @author Bulbasaur
* @date: 2021/5/18 5:42 下午
*/
@Data
@Entity
@ApiModel(value = "直播商品")
@TableName("li_studio_commodity")
@Table(name = "li_studio_commodity")
@NoArgsConstructor
public class StudioCommodity {
@Id
@TableId
@TableField
@Column(columnDefinition = "bigint(20)")
@ApiModelProperty(value = "唯一标识", hidden = true)
private String id;
@ApiModelProperty(value = "房间ID")
private Integer roomId;
@ApiModelProperty(value = "商品ID")
private Integer goodsId;
public StudioCommodity(Integer roomId, Integer goodsId) {
this.roomId = roomId;
this.goodsId = goodsId;
}
}

View File

@ -0,0 +1,22 @@
package cn.lili.modules.broadcast.entity.dto;
import lombok.Data;
/**
* 直播商品DTO
* 用于获取直播商品状态时使用
*
* @author Bulbasaur
* @date: 2021/5/25 12:12 下午
*/
@Data
public class CommodityDTO {
//商品ID
private Integer goods_id;
//商品名称
private String name;
//地址
private String url;
//审核状态
private Integer audit_status;
}

View File

@ -0,0 +1,43 @@
package cn.lili.modules.broadcast.entity.dto;
import cn.lili.common.utils.BeanUtil;
import cn.lili.modules.broadcast.entity.dos.Commodity;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* 微信小程序直播商品DTO
* @author Bulbasaur
* @date: 2021/5/17 11:03 上午
*
*/
@Data
@NoArgsConstructor
public class GoodsInfo {
@ApiModelProperty(value = "图片mediaID")
private String coverImgUrl;
@ApiModelProperty(value = "商品名称")
private String name;
//1一口价只需要传入priceprice2不传
//2价格区间price字段为左边界price2字段为右边界price和price2必传
//3显示折扣价price字段为原价price2字段为现价 price和price2必传
@ApiModelProperty(value = "价格类型")
private Integer priceType;
@ApiModelProperty(value = "价格")
private Double price;
@ApiModelProperty(value = "价格2")
private Double price2;
@ApiModelProperty(value = "商品详情页的小程序路径")
private String url;
public GoodsInfo(Commodity commodity){
BeanUtil.copyProperties(commodity, this);
}
}

View File

@ -0,0 +1,18 @@
package cn.lili.modules.broadcast.entity.dto;
import io.swagger.annotations.ApiModelProperty;
/**
* 用于直播间前台使用的直播间商品DTO
*
* @author Bulbasaur
* @date: 2021/5/20 2:34 下午
*/
public class SimpleCommodity {
@ApiModelProperty(value = "图片")
private String goodsImage;
@ApiModelProperty(value = "商品名称")
private String name;
}

View File

@ -0,0 +1,27 @@
package cn.lili.modules.broadcast.entity.enums;
/**
* 直播间状态
* @author Bulbasaur
* @date: 2021/5/31 10:32 上午
*
*/
public enum StudioStatusEnum {
NEW("新建"), START("开始"), END("结束");
private final String clientName;
StudioStatusEnum(String des) {
this.clientName = des;
}
public String clientName() {
return this.clientName;
}
public String value() {
return this.name();
}
}

View File

@ -0,0 +1,21 @@
package cn.lili.modules.broadcast.entity.vos;
import cn.lili.modules.broadcast.entity.dos.Commodity;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* 直播商品VO
*
* @author Bulbasaur
* @date: 2021/5/26 6:09 下午
*/
@Data
public class CommodityVO extends Commodity {
@ApiModelProperty(value = "SKU库存")
private Integer quantity;
@ApiModelProperty(value = "店铺名称")
private String storeName;
}

View File

@ -0,0 +1,22 @@
package cn.lili.modules.broadcast.entity.vos;
import cn.lili.modules.broadcast.entity.dos.Commodity;
import cn.lili.modules.broadcast.entity.dos.Studio;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.List;
/**
* 直播间VO
*
* @author Bulbasaur
* @date: 2021/5/31 11:58 上午
*/
@Data
public class StudioVO extends Studio {
@ApiModelProperty(value = "直播间商品列表")
private List<Commodity> commodityList;
}

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