初始化代码 2022-02-11前 最新版本

This commit is contained in:
itheinjury@163.com
2022-02-11 19:30:50 +08:00
commit bf8f8d9382
1399 changed files with 165963 additions and 0 deletions

View File

@@ -0,0 +1,104 @@
package cn.lili.timetask;
import cn.lili.timetask.handler.EveryDayExecute;
import cn.lili.timetask.handler.EveryHourExecute;
import cn.lili.timetask.handler.EveryMinuteExecute;
import com.xxl.job.core.biz.model.ReturnT;
import com.xxl.job.core.handler.annotation.XxlJob;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.List;
/**
* 定时器任务
*
* @author Chopper
* @version v1.0
* 2020-12-24 11:51
*/
@Slf4j
@Component
public class TimedTaskJobHandler {
@Autowired(required = false)
private List<EveryMinuteExecute> everyMinuteExecutes;
@Autowired(required = false)
private List<EveryHourExecute> everyHourExecutes;
@Autowired(required = false)
private List<EveryDayExecute> everyDayExecutes;
/**
* 每分钟任务
*
* @throws Exception
*/
@XxlJob("everyMinuteExecute")
public ReturnT<String> everyMinuteExecute(String param) {
log.info("每分钟任务执行");
if (everyMinuteExecutes == null || everyMinuteExecutes.size() == 0) {
return ReturnT.SUCCESS;
}
for (int i = 0; i < everyMinuteExecutes.size(); i++) {
try {
everyMinuteExecutes.get(i).execute();
} catch (Exception e) {
log.error("每分钟任务异常", e);
}
}
return ReturnT.SUCCESS;
}
/**
* 每小时任务
*
* @throws Exception
*/
@XxlJob("everyHourExecuteJobHandler")
public ReturnT<String> everyHourExecuteJobHandler(String param) {
log.info("每小时任务执行");
if (everyHourExecutes == null || everyHourExecutes.size() == 0) {
return ReturnT.SUCCESS;
}
for (int i = 0; i < everyHourExecutes.size(); i++) {
try {
everyHourExecutes.get(i).execute();
} catch (Exception e) {
log.error("每分钟任务异常", e);
}
}
return ReturnT.SUCCESS;
}
/**
* 每日任务
*
* @throws Exception
*/
@XxlJob("everyDayExecuteJobHandler")
public ReturnT<String> everyDayExecuteJobHandler(String param) {
log.info("每日任务执行");
if (everyDayExecutes == null || everyDayExecutes.size() == 0) {
return ReturnT.SUCCESS;
}
for (int i = 0; i < everyDayExecutes.size(); i++) {
try {
everyDayExecutes.get(i).execute();
} catch (Exception e) {
log.error("每分钟任务异常", e);
}
}
return ReturnT.SUCCESS;
}
}

View File

@@ -0,0 +1,78 @@
package cn.lili.timetask.config;
import com.xxl.job.core.executor.impl.XxlJobSpringExecutor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* xxl-job config
*
* @author xuxueli 2017-04-28
*/
@Configuration
public class XxlJobConfig {
private final Logger logger = LoggerFactory.getLogger(XxlJobConfig.class);
@Value("${xxl.job.admin.addresses:}")
private String adminAddresses;
@Value("${xxl.job.accessToken:}")
private String accessToken;
@Value("${xxl.job.executor.appname}")
private String appname;
@Value("${xxl.job.executor.address}")
private String address;
@Value("${xxl.job.executor.ip}")
private String ip;
@Value("${xxl.job.executor.port}")
private int port;
@Value("${xxl.job.executor.logpath}")
private String logPath;
@Value("${xxl.job.executor.logretentiondays}")
private int logRetentionDays;
@Bean
public XxlJobSpringExecutor xxlJobExecutor() {
logger.info(">>>>>>>>>>> xxl-job config init.");
XxlJobSpringExecutor xxlJobSpringExecutor = new XxlJobSpringExecutor();
xxlJobSpringExecutor.setAdminAddresses(adminAddresses);
xxlJobSpringExecutor.setAppname(appname);
xxlJobSpringExecutor.setAddress(address);
xxlJobSpringExecutor.setIp(ip);
xxlJobSpringExecutor.setPort(port);
xxlJobSpringExecutor.setAccessToken(accessToken);
xxlJobSpringExecutor.setLogPath(logPath);
xxlJobSpringExecutor.setLogRetentionDays(logRetentionDays);
return xxlJobSpringExecutor;
}
/**
* 针对多网卡、容器内部署等情况,可借助 "spring-cloud-commons" 提供的 "InetUtils" 组件灵活定制注册IP
*
* 1、引入依赖
* <dependency>
* <groupId>org.springframework.cloud</groupId>
* <artifactId>spring-cloud-commons</artifactId>
* <version>${version}</version>
* </dependency>
*
* 2、配置文件或者容器启动变量
* spring.cloud.inetutils.preferred-networks: 'xxx.xxx.xxx.'
*
* 3、获取IP
* String ip_ = inetUtils.findFirstNonLoopbackHostInfo().getIpAddress();
*/
}

View File

@@ -0,0 +1,18 @@
package cn.lili.timetask.handler;
/**
* 每日任务
* 每日凌晨1点执行
*
* @author Chopper
* @since 2020/12/24 11:52
*/
public interface EveryDayExecute {
/**
* 执行每日任务
*/
void execute();
}

View File

@@ -0,0 +1,17 @@
package cn.lili.timetask.handler;
/**
* 每小时任务
*
* @author Chopper
* @since 2020/12/24 11:52
*/
public interface EveryHourExecute {
/**
* 执行
*/
void execute();
}

View File

@@ -0,0 +1,17 @@
package cn.lili.timetask.handler;
/**
* 每分钟任务
*
* @author Chopper
* @since 2020/12/24 11:52
*/
public interface EveryMinuteExecute {
/**
* 执行
*/
void execute();
}

View File

@@ -0,0 +1,60 @@
package cn.lili.timetask.handler.impl.bill;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.lili.modules.store.entity.dto.StoreSettlementDay;
import cn.lili.modules.store.service.BillService;
import cn.lili.modules.store.service.StoreDetailService;
import cn.lili.timetask.handler.EveryDayExecute;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.List;
/**
* 店铺结算执行
*
* @author Bulbasaur
* @since 2021/2/18 3:45 下午
*/
@Component
public class BillExecute implements EveryDayExecute {
/**
* 结算单
*/
@Autowired
private BillService billService;
/**
* 店铺详情
*/
@Autowired
private StoreDetailService storeDetailService;
/**
* 1.查询今日待结算的商家
* 2.查询商家上次结算日期,生成本次结算单
* 3.记录商家结算日
*/
@Override
public void execute() {
//获取当前天数
int day = DateUtil.date().dayOfMonth();
//获取待结算商家列表
List<StoreSettlementDay> storeList = storeDetailService.getSettlementStore(day);
//获取当前时间
DateTime endTime = DateUtil.date();
//批量商家结算
for (StoreSettlementDay storeSettlementDay : storeList) {
//生成结算单
billService.createBill(storeSettlementDay.getStoreId(), storeSettlementDay.getSettlementDay(), endTime);
//修改店铺结算时间
storeDetailService.updateSettlementDay(storeSettlementDay.getStoreId(), endTime);
}
}
}

View File

@@ -0,0 +1,25 @@
package cn.lili.timetask.handler.impl.broadcast;
import cn.lili.modules.goods.service.CommodityService;
import cn.lili.timetask.handler.EveryHourExecute;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* 小程序直播状态获取
*
* @author Bulbasaur
* @since 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,56 @@
package cn.lili.timetask.handler.impl.coupon;
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;
import java.util.Calendar;
import java.util.Date;
/**
* 优惠券状态监测
*
* @author Bulbasaur
* @since 2021/5/24 10:08 上午
*/
@Component
public class CouponExecute implements EveryDayExecute {
/**
* 过期常量,过期后或者使用后一定时间内,删除无效的优惠券,物理删除
*/
static final int EXPIRATION_DAY = 3;
@Autowired
private MemberCouponService memberCouponService;
/**
* 检测优惠券的使用时间,超期未使用则失效
* 此方法用于领取*天后失效优惠券使用
*/
@Override
public void execute() {
//将过期优惠券变更为过期状体
LambdaUpdateWrapper<MemberCoupon> updateWrapper = new LambdaUpdateWrapper<MemberCoupon>()
.eq(MemberCoupon::getMemberCouponStatus, MemberCouponStatusEnum.NEW.name())
.le(MemberCoupon::getEndTime, new Date())
.set(MemberCoupon::getMemberCouponStatus, MemberCouponStatusEnum.EXPIRE.name());
this.memberCouponService.update(updateWrapper);
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.DAY_OF_MONTH, calendar.get(Calendar.DAY_OF_MONTH) - EXPIRATION_DAY);
Date removeTime = calendar.getTime();
//删除过期/已使用的优惠券
LambdaUpdateWrapper<MemberCoupon> deleteWrapper = new LambdaUpdateWrapper<MemberCoupon>()
//如果结束时间小于 当前时间增加指定删除日期,则删除
.le(MemberCoupon::getEndTime, removeTime);
this.memberCouponService.remove(deleteWrapper);
}
}

View File

@@ -0,0 +1,52 @@
package cn.lili.timetask.handler.impl.goods;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.lili.modules.goods.mapper.GoodsMapper;
import cn.lili.modules.member.entity.dos.MemberEvaluation;
import cn.lili.modules.member.mapper.MemberEvaluationMapper;
import cn.lili.timetask.handler.EveryDayExecute;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
/**
* 商品定时器
*
* @author Chopper
* @since 2021/3/18 3:23 下午
*/
@Component
public class GoodsExecute implements EveryDayExecute {
/**
* 会员评价
*/
@Resource
private MemberEvaluationMapper memberEvaluationMapper;
/**
* 商品
*/
@Resource
private GoodsMapper goodsMapper;
/**
* 查询已上架的商品的评价数量并赋值
*/
@Override
public void execute() {
//查询上次统计到本次的评价数量
List<Map<String, Object>> list = memberEvaluationMapper.memberEvaluationNum(
new QueryWrapper<MemberEvaluation>()
.between("create_time", DateUtil.yesterday(), new DateTime()));
for (Map<String, Object> map : list) {
goodsMapper.addGoodsCommentNum(Convert.toInt(map.get("num").toString()), map.get("goods_id").toString());
}
}
}

View File

@@ -0,0 +1,30 @@
package cn.lili.timetask.handler.impl.hotwords;
import cn.lili.cache.Cache;
import cn.lili.cache.CachePrefix;
import cn.lili.timetask.handler.EveryDayExecute;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* @author paulG
* @since 2021/3/11
**/
@Slf4j
@Component
public class HotWordsEveryDayTaskExecute implements EveryDayExecute {
@Autowired
private Cache cache;
/**
* 执行每日任务
*/
@Override
public void execute() {
//移除昨日的热搜词
cache.remove(CachePrefix.HOT_WORD.getPrefix());
}
}

View File

@@ -0,0 +1,61 @@
package cn.lili.timetask.handler.impl.order;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.json.JSONUtil;
import cn.lili.modules.order.order.entity.dos.Order;
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.OrderSetting;
import cn.lili.modules.system.entity.enums.SettingEnum;
import cn.lili.modules.system.service.SettingService;
import cn.lili.timetask.handler.EveryMinuteExecute;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.stream.Collectors;
/**
* 订单自动取消(每分钟执行)
*
* @author paulG
* @since 2021/3/11
**/
@Slf4j
@Component
public class CancelOrderTaskExecute implements EveryMinuteExecute {
/**
* 订单
*/
@Autowired
private OrderService orderService;
/**
* 设置
*/
@Autowired
private SettingService settingService;
@Override
public void execute() {
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());
for (String sn : cancelSnList) {
orderService.systemCancel(sn, "超时未支付自动取消");
}
}
}
}

View File

@@ -0,0 +1,217 @@
package cn.lili.timetask.handler.impl.order;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.json.JSONUtil;
import cn.lili.common.enums.ResultCode;
import cn.lili.common.exception.ServiceException;
import cn.lili.modules.member.entity.dto.MemberEvaluationDTO;
import cn.lili.modules.member.entity.enums.EvaluationGradeEnum;
import cn.lili.modules.member.service.MemberEvaluationService;
import cn.lili.modules.order.aftersale.service.AfterSaleService;
import cn.lili.modules.order.order.entity.dos.Order;
import cn.lili.modules.order.order.entity.dos.OrderItem;
import cn.lili.modules.order.order.entity.enums.CommentStatusEnum;
import cn.lili.modules.order.order.entity.enums.OrderComplaintStatusEnum;
import cn.lili.modules.order.order.entity.enums.OrderItemAfterSaleStatusEnum;
import cn.lili.modules.order.order.entity.enums.OrderStatusEnum;
import cn.lili.modules.order.order.mapper.OrderItemMapper;
import cn.lili.modules.order.order.service.OrderItemService;
import cn.lili.modules.order.order.service.OrderService;
import cn.lili.modules.system.entity.dos.Setting;
import cn.lili.modules.system.entity.dto.OrderSetting;
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.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;
/**
* @author paulG
* @since 2021/3/11
**/
@Slf4j
@Component
public class OrderEveryDayTaskExecute implements EveryDayExecute {
/**
* 订单
*/
@Autowired
private OrderService orderService;
/**
* 订单货物
*/
@Autowired
private OrderItemService orderItemService;
@Resource
private OrderItemMapper orderItemMapper;
/**
* 设置
*/
@Autowired
private SettingService settingService;
/**
* 会员评价
*/
@Autowired
private MemberEvaluationService memberEvaluationService;
@Autowired
private AfterSaleService afterSaleService;
/**
* 执行每日任务
*/
@Override
public void execute() {
Setting setting = settingService.get(SettingEnum.ORDER_SETTING.name());
//订单设置
OrderSetting orderSetting = JSONUtil.toBean(setting.getSettingValue(), OrderSetting.class);
if (orderSetting == null) {
throw new ServiceException(ResultCode.ORDER_SETTING_ERROR);
}
//自动确认收货
completedOrder(orderSetting);
//自动好评
memberEvaluation(orderSetting);
//关闭允许售后申请
closeAfterSale(orderSetting);
//关闭允许投诉
closeComplaint(orderSetting);
}
/**
* 自动确认收获,订单完成
*
* @param orderSetting 订单设置
*/
private void completedOrder(OrderSetting orderSetting) {
//订单自动收货时间 = 当前时间 - 自动收货时间天数
DateTime receiveTime = DateUtil.offsetDay(DateUtil.date(), -orderSetting.getAutoReceive());
LambdaQueryWrapper<Order> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(Order::getOrderStatus, OrderStatusEnum.DELIVERED.name());
//订单发货时间 >= 订单自动收货时间
queryWrapper.le(Order::getLogisticsTime, receiveTime);
List<Order> list = orderService.list(queryWrapper);
//判断是否有符合条件的订单,进行订单完成处理
if (!list.isEmpty()) {
List<String> receiveSnList = list.stream().map(Order::getSn).collect(Collectors.toList());
for (String orderSn : receiveSnList) {
orderService.systemComplete(orderSn);
}
}
}
/**
* 自动好评
*
* @param orderSetting 订单设置
*/
private void memberEvaluation(OrderSetting orderSetting) {
//订单自动收货时间 = 当前时间 - 自动收货时间天数
DateTime receiveTime = DateUtil.offsetDay(DateUtil.date(), -orderSetting.getAutoEvaluation());
//订单完成时间 <= 订单自动好评时间
QueryWrapper queryWrapper = new QueryWrapper();
queryWrapper.le("o.complete_time", receiveTime);
queryWrapper.eq("oi.comment_status", CommentStatusEnum.UNFINISHED.name());
List<OrderItem> orderItems = orderItemMapper.waitOperationOrderItem(queryWrapper);
//判断是否有符合条件的订单,进行自动评价处理
if (!orderItems.isEmpty()) {
for (OrderItem orderItem : orderItems) {
MemberEvaluationDTO memberEvaluationDTO = new MemberEvaluationDTO();
memberEvaluationDTO.setOrderItemSn(orderItem.getSn());
memberEvaluationDTO.setContent("系统默认好评");
memberEvaluationDTO.setGoodsId(orderItem.getGoodsId());
memberEvaluationDTO.setSkuId(orderItem.getSkuId());
memberEvaluationDTO.setGrade(EvaluationGradeEnum.GOOD.name());
memberEvaluationDTO.setDeliveryScore(5);
memberEvaluationDTO.setDescriptionScore(5);
memberEvaluationDTO.setServiceScore(5);
memberEvaluationService.addMemberEvaluation(memberEvaluationDTO, false);
}
}
}
/**
* 关闭允许售后申请
*
* @param orderSetting 订单设置
*/
private void closeAfterSale(OrderSetting orderSetting) {
//订单关闭售后申请时间 = 当前时间 - 自动关闭售后申请天数
DateTime receiveTime = DateUtil.offsetDay(DateUtil.date(), -orderSetting.getAutoEvaluation());
//关闭售后订单=未售后订单+小于订单关闭售后申请时间
QueryWrapper queryWrapper = new QueryWrapper();
queryWrapper.le("o.complete_time", receiveTime);
queryWrapper.eq("oi.after_sale_status", OrderItemAfterSaleStatusEnum.NOT_APPLIED.name());
List<OrderItem> orderItems = orderItemMapper.waitOperationOrderItem(queryWrapper);
//判断是否有符合条件的订单,关闭允许售后申请处理
if (!orderItems.isEmpty()) {
//获取订单货物ID
List<String> orderItemIdList = orderItems.stream().map(OrderItem::getId).collect(Collectors.toList());
//修改订单售后状态
LambdaUpdateWrapper<OrderItem> lambdaUpdateWrapper = new LambdaUpdateWrapper<OrderItem>()
.set(OrderItem::getAfterSaleStatus, OrderItemAfterSaleStatusEnum.EXPIRED.name())
.in(OrderItem::getId, orderItemIdList);
orderItemService.update(lambdaUpdateWrapper);
}
}
/**
* 关闭允许交易投诉
*
* @param orderSetting 订单设置
*/
private void closeComplaint(OrderSetting orderSetting) {
//订单关闭交易投诉申请时间 = 当前时间 - 自动关闭交易投诉申请天数
DateTime receiveTime = DateUtil.offsetDay(DateUtil.date(), -orderSetting.getCloseComplaint());
//关闭售后订单=未售后订单+小于订单关闭售后申请时间
QueryWrapper queryWrapper = new QueryWrapper();
queryWrapper.le("o.complete_time", receiveTime);
queryWrapper.eq("oi.complain_status", OrderComplaintStatusEnum.NO_APPLY.name());
List<OrderItem> orderItems = orderItemMapper.waitOperationOrderItem(queryWrapper);
//判断是否有符合条件的订单,关闭允许售后申请处理
if (!orderItems.isEmpty()) {
//获取订单货物ID
List<String> orderItemIdList = orderItems.stream().map(OrderItem::getId).collect(Collectors.toList());
//修改订单投诉状态
LambdaUpdateWrapper<OrderItem> lambdaUpdateWrapper = new LambdaUpdateWrapper<OrderItem>()
.set(OrderItem::getComplainStatus, OrderItemAfterSaleStatusEnum.EXPIRED.name())
.in(OrderItem::getId, orderItemIdList);
orderItemService.update(lambdaUpdateWrapper);
}
}
}

View File

@@ -0,0 +1,61 @@
package cn.lili.timetask.handler.impl.order;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.json.JSONUtil;
import cn.lili.modules.order.order.entity.enums.PayStatusEnum;
import cn.lili.modules.system.entity.dos.Setting;
import cn.lili.modules.system.entity.dto.OrderSetting;
import cn.lili.modules.system.entity.enums.SettingEnum;
import cn.lili.modules.system.service.SettingService;
import cn.lili.modules.wallet.entity.dos.Recharge;
import cn.lili.modules.wallet.service.RechargeService;
import cn.lili.timetask.handler.EveryMinuteExecute;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.stream.Collectors;
/**
* 充值订单自动取消(每分钟执行)
*
* @author zhuhai
* @since 2021/3/11
**/
@Slf4j
@Component
public class RechargeOrderTaskExecute implements EveryMinuteExecute {
/**
* 充值
*/
@Autowired
private RechargeService rechargeService;
/**
* 设置
*/
@Autowired
private SettingService settingService;
@Override
public void execute() {
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<Recharge> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(Recharge::getPayStatus, PayStatusEnum.UNPAID.name());
//充值订单创建时间 <= 订单自动取消时间
queryWrapper.le(Recharge::getCreateTime, cancelTime);
List<Recharge> list = rechargeService.list(queryWrapper);
List<String> cancelSnList = list.stream().map(Recharge::getRechargeSn).collect(Collectors.toList());
for (String sn : cancelSnList) {
rechargeService.rechargeOrderCancel(sn);
}
}
}
}

View File

@@ -0,0 +1,67 @@
package cn.lili.timetask.handler.impl.promotion;
import cn.lili.modules.promotion.entity.dos.Seckill;
import cn.lili.modules.promotion.service.SeckillService;
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.google.gson.Gson;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* 促销活动每日定时器
*
* @author Chopper
* @since 2021/3/18 3:23 下午
*/
@Slf4j
@Component
public class PromotionEverydayExecute implements EveryDayExecute {
/**
* ES商品索引
*/
@Autowired
private EsGoodsIndexService esGoodsIndexService;
/**
* 系统设置
*/
@Autowired
private SettingService settingService;
/**
* 秒杀活动
*/
@Autowired
private SeckillService seckillService;
/**
* 将已过期的促销活动置为结束
*/
@Override
public void execute() {
//清除所以商品索引的无效促销活动
this.esGoodsIndexService.cleanInvalidPromotion();
//定时创建活动
addSeckill();
}
/**
* 添加秒杀活动
* 从系统设置中获取秒杀活动的配置
* 添加30天后的秒杀活动
*/
private void addSeckill() {
Setting setting = settingService.get(SettingEnum.SECKILL_SETTING.name());
SeckillSetting seckillSetting = new Gson().fromJson(setting.getSettingValue(), SeckillSetting.class);
for (int i = 1; i <= SeckillService.PRE_CREATION; i++) {
Seckill seckill = new Seckill(i, seckillSetting.getHours(), seckillSetting.getSeckillRule());
seckillService.savePromotions(seckill);
}
}
}

View File

@@ -0,0 +1,55 @@
package cn.lili.timetask.handler.impl.statistics;
import cn.lili.modules.statistics.entity.dos.MemberStatisticsData;
import cn.lili.modules.statistics.service.MemberStatisticsService;
import cn.lili.timetask.handler.EveryDayExecute;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Calendar;
import java.util.Date;
/**
* 会员数据统计
*
* @author Chopper
* @since 2021-03-02 14:56
*/
@Slf4j
@Component
public class MemberStatisticsExecute implements EveryDayExecute {
/**
* 会员统计
*/
@Autowired
private MemberStatisticsService memberStatisticsService;
@Override
public void execute() {
try {
//统计的时间(开始。结束时间)
Date startTime, endTime;
//初始值
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 1);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.HOUR_OF_DAY, 0);
endTime = calendar.getTime();
//-1天即为开始时间
calendar.set(Calendar.DAY_OF_MONTH, calendar.get(Calendar.DAY_OF_MONTH) - 1);
startTime = calendar.getTime();
MemberStatisticsData memberStatisticsData = new MemberStatisticsData();
memberStatisticsData.setMemberCount(memberStatisticsService.memberCount(endTime));
memberStatisticsData.setCreateDate(startTime);
memberStatisticsData.setActiveQuantity(memberStatisticsService.activeQuantity(startTime));
memberStatisticsData.setNewlyAdded(memberStatisticsService.newlyAdded(startTime, endTime));
memberStatisticsService.save(memberStatisticsData);
} catch (Exception e) {
log.error("每日会员统计功能异常:", e);
}
}
}

View File

@@ -0,0 +1,104 @@
package cn.lili.timetask.handler.impl.statistics;
import cn.lili.cache.Cache;
import cn.lili.cache.CachePrefix;
import cn.lili.common.security.enums.UserEnums;
import cn.lili.common.properties.StatisticsProperties;
import cn.lili.modules.statistics.entity.vo.OnlineMemberVO;
import cn.lili.timetask.handler.EveryHourExecute;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
/**
* 实时在线人数统计
*
* @author Chopper
* @since 2021-02-21 09:47
*/
@Component
public class OnlineMemberStatistics implements EveryHourExecute {
/**
* 缓存
*/
@Autowired
private Cache<List<OnlineMemberVO>> cache;
/**
* 统计小时
*/
@Autowired
private StatisticsProperties statisticsProperties;
@Override
public void execute() {
Calendar calendar = Calendar.getInstance();
List<OnlineMemberVO> onlineMemberVOS = cache.get(CachePrefix.ONLINE_MEMBER.getPrefix());
if (onlineMemberVOS == null) {
onlineMemberVOS = new ArrayList<>();
}
//过滤 有效统计时间
calendar.set(Calendar.HOUR_OF_DAY, calendar.get(Calendar.HOUR_OF_DAY) - statisticsProperties.getOnlineMember());
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
Calendar finalCalendar = calendar;
onlineMemberVOS = onlineMemberVOS.stream()
.filter(onlineMemberVO -> onlineMemberVO.getDate().after(finalCalendar.getTime()))
.collect(Collectors.toList());
//计入新数据
calendar = Calendar.getInstance();
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
onlineMemberVOS.add(new OnlineMemberVO(calendar.getTime(), cache.keys(CachePrefix.ACCESS_TOKEN.getPrefix(UserEnums.MEMBER) + "*").size()));
//写入缓存
cache.put(CachePrefix.ONLINE_MEMBER.getPrefix(), onlineMemberVOS);
}
/**
* 手动设置某一时间,活跃人数
*
* @param time 时间
* @param num 人数
*/
public void execute(Date time, Integer num) {
List<OnlineMemberVO> onlineMemberVOS = cache.get(CachePrefix.ONLINE_MEMBER.getPrefix());
if (onlineMemberVOS == null) {
onlineMemberVOS = new ArrayList<>();
}
Calendar calendar = Calendar.getInstance();
calendar.setTime(time);
//过滤 有效统计时间
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
calendar.set(Calendar.HOUR_OF_DAY, calendar.get(Calendar.HOUR_OF_DAY) - 48);
onlineMemberVOS = onlineMemberVOS.stream()
.filter(onlineMemberVO -> onlineMemberVO.getDate().after(calendar.getTime()))
.collect(Collectors.toList());
onlineMemberVOS.add(new OnlineMemberVO(time, num));
//写入缓存
cache.put(CachePrefix.ONLINE_MEMBER.getPrefix(), onlineMemberVOS);
}
}

View File

@@ -0,0 +1,65 @@
package cn.lili.timetask.handler.impl.storerating;
import cn.lili.common.enums.SwitchEnum;
import cn.lili.modules.member.entity.dos.MemberEvaluation;
import cn.lili.modules.member.entity.vo.StoreRatingVO;
import cn.lili.modules.member.mapper.MemberEvaluationMapper;
import cn.lili.modules.store.entity.dos.Store;
import cn.lili.modules.store.entity.enums.StoreStatusEnum;
import cn.lili.modules.store.service.StoreService;
import cn.lili.timetask.handler.EveryDayExecute;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.List;
/**
* 店铺评分
*
* @author Chopper
* @since 2021/3/15 5:30 下午
*/
@Component
public class StoreRatingExecute implements EveryDayExecute {
/**
* 店铺
*/
@Autowired
private StoreService storeService;
/**
* 会员评价
*/
@Resource
private MemberEvaluationMapper memberEvaluationMapper;
@Override
public void execute() {
//获取所有开启的店铺
List<Store> storeList = storeService.list(new LambdaQueryWrapper<Store>().eq(Store::getStoreDisable, StoreStatusEnum.OPEN.name()));
for (Store store : storeList) {
//店铺所有开启的评价
LambdaQueryWrapper<MemberEvaluation> lambdaQueryWrapper = Wrappers.lambdaQuery();
lambdaQueryWrapper.eq(MemberEvaluation::getStoreId, store.getId());
lambdaQueryWrapper.eq(MemberEvaluation::getStatus, SwitchEnum.OPEN.name());
StoreRatingVO storeRatingVO = memberEvaluationMapper.getStoreRatingVO(lambdaQueryWrapper);
if (storeRatingVO != null) {
//保存评分
LambdaUpdateWrapper<Store> lambdaUpdateWrapper = Wrappers.lambdaUpdate();
lambdaUpdateWrapper.eq(Store::getId, store.getId());
lambdaUpdateWrapper.set(Store::getDescriptionScore, storeRatingVO.getDescriptionScore());
lambdaUpdateWrapper.set(Store::getDeliveryScore, storeRatingVO.getDeliveryScore());
lambdaUpdateWrapper.set(Store::getServiceScore, storeRatingVO.getServiceScore());
storeService.update(lambdaUpdateWrapper);
}
}
}
}

View File

@@ -0,0 +1,195 @@
package cn.lili.timetask.handler.impl.view;
import cn.hutool.core.convert.Convert;
import cn.lili.cache.Cache;
import cn.lili.cache.CachePrefix;
import cn.lili.common.utils.BeanUtil;
import cn.lili.modules.statistics.entity.dos.PlatformViewData;
import cn.lili.modules.statistics.service.PlatformViewService;
import cn.lili.timetask.handler.EveryDayExecute;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
/**
* 统计 入库
*
* @author Chopper
* @since 2021-01-15 18:20
*/
@Slf4j
@Component
public class PageViewStatisticsExecute implements EveryDayExecute {
/**
* 缓存
*/
@Autowired
private Cache cache;
/**
* 平台PV统计
*/
@Autowired
private PlatformViewService platformViewService;
@Override
public void execute() {
//1、缓存keys 模糊匹配
//2、过滤今日的数据即今天只能统计今日以前的数据
//4对key value 分别代表平台PV、平台UV、店铺PV、店铺UV
List<String> pvKeys = filterKeys(cache.keys(CachePrefix.PV.getPrefix() + "*"));
List<Integer> pvValues = cache.multiGet(pvKeys);
List<String> storePVKeys = filterKeys(cache.keys(CachePrefix.STORE_PV.getPrefix() + "*"));
List<Integer> storePvValues = cache.multiGet(storePVKeys);
//备份UV数据这里赋值之后会被删除
List<String> uvKeys = new ArrayList<>();
List<String> storeUvKeys = new ArrayList<>();
log.debug("开始统计平台数据PV共计【{}】条", pvKeys.size());
log.debug("开始统计店铺数据PV共计【{}】条", storePvValues.size());
//定义要统计的数据
List<PlatformViewData> platformViewDataList = new ArrayList<>();
//PV 统计
if (pvKeys.size() > 0) {
for (int i = 0; i < pvKeys.size(); i++) {
String key = pvKeys.get(i);
PageViewStatistics pageViewStatistics = new PageViewStatistics(key);
PlatformViewData platformPVData = new PlatformViewData();
BeanUtil.copyProperties(pageViewStatistics, platformPVData);
platformPVData.setPvNum(pvValues.get(i).longValue());
//根据pvkey 获取 uvkey
String uvKey = getUvKey(key);
uvKeys.add(uvKey);
platformPVData.setUvNum(cache.counter(uvKey));
platformPVData.setStoreId("-1");
platformViewDataList.add(platformPVData);
}
batchSave(pvKeys, uvKeys, platformViewDataList);
}
//店铺 PV 统计
if (storePVKeys.size() > 0) {
platformViewDataList = new ArrayList<>();
for (int i = 0; i < storePVKeys.size(); i++) {
String key = storePVKeys.get(i);
PageViewStatistics pageViewStatistics = new PageViewStatistics(key);
PlatformViewData storePVData = new PlatformViewData();
BeanUtil.copyProperties(pageViewStatistics, storePVData);
storePVData.setPvNum(storePvValues.get(i).longValue());
//根据pvkey 获取 uvkey
String uvKey = getUvKey(key);
uvKeys.add(uvKey);
storePVData.setUvNum(cache.counter(uvKey));
platformViewDataList.add(storePVData);
}
batchSave(storePVKeys, storeUvKeys, platformViewDataList);
}
}
/**
* 根据缓存的PVkey 获取对应的UVkey
*
* @param key
* @return
*/
private String getUvKey(String key) {
if (StringUtils.isNotEmpty(key)) {
key = key.replace(CachePrefix.PV.getPrefix(), CachePrefix.UV.getPrefix());
key = key.replace(CachePrefix.STORE_PV.getPrefix(), CachePrefix.STORE_UV.getPrefix());
return key;
}
return key;
}
/**
* 批量保存数据&&清除保存数据的缓存
*
* @param pvKeys PV key
* @param uvKeys UV key
* @param platformViewData DOS
*/
@Transactional(rollbackFor = Exception.class)
void batchSave(List<String> pvKeys, List<String> uvKeys, List<PlatformViewData> platformViewData) {
log.debug("批量保存流量数据,共计【{}】条", platformViewData.size());
platformViewService.saveBatch(platformViewData);
//批量删除缓存key
cache.multiDel(pvKeys);
cache.multiDel(uvKeys);
log.debug("流量数据保存完成");
}
/**
* 过滤缓存key
*
* @param keys 缓存key集合
*/
private static List<String> filterKeys(List<String> keys) {
//只统计一天前的数据
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, -24);
List<String> result = new ArrayList<>();
for (String key : keys) {
PageViewStatistics temp = new PageViewStatistics(key);
//如果需要统计则将key写入集合
if (temp.getDate().before(calendar.getTime())) {
result.add(key);
}
}
return result;
}
}
/**
* 根据缓存key 获取其中需要的参数,年月日,以及店铺信息
*/
@Data
class PageViewStatistics {
/**
* 年 、 月 、 日 、 店铺id
*/
private Date date;
private String storeId;
public PageViewStatistics(String str) {
//将字符串解析成需要的对象
str = str.substring(str.indexOf("}") + 2);
String[] dateStr = str.split("-");
Integer year = Convert.toInt(dateStr[0]);
Integer month = Convert.toInt(dateStr[1]);
Integer day;
//是否有店铺id
if (dateStr.length > 3) {
day = Convert.toInt(dateStr[2]);
this.storeId = dateStr[3];
} else {
day = Convert.toInt(dateStr[2]);
}
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.YEAR, year);
calendar.set(Calendar.MONTH, month - 1);
calendar.set(Calendar.DAY_OF_MONTH, day);
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
this.date = calendar.getTime();
}
}