|
@@ -0,0 +1,225 @@
|
|
|
|
|
+package com.sptg.ad.biz.quartz;
|
|
|
|
|
+
|
|
|
|
|
+import com.baomidou.mybatisplus.mapper.EntityWrapper;
|
|
|
|
|
+import com.baomidou.mybatisplus.mapper.Wrapper;
|
|
|
|
|
+import com.baomidou.mybatisplus.plugins.Page;
|
|
|
|
|
+import com.sptg.ad.api.entity.*;
|
|
|
|
|
+import com.sptg.ad.api.stream.AdvertTaskCallbackProduceInterface;
|
|
|
|
|
+import com.sptg.ad.biz.service.*;
|
|
|
|
|
+import com.sptg.common.core.beans.PageBean;
|
|
|
|
|
+import com.sptg.common.core.constant.OperationConstant;
|
|
|
|
|
+import com.sptg.common.core.entity.PublishTask;
|
|
|
|
|
+import com.sptg.common.core.entity.PublishTaskResult;
|
|
|
|
|
+import com.sptg.common.core.enums.Instruct;
|
|
|
|
|
+import com.sptg.device.api.entity.Device;
|
|
|
|
|
+import com.sptg.device.api.feigns.DeviceFeign;
|
|
|
|
|
+import com.sptg.device.api.feigns.MsgPublishFeign;
|
|
|
|
|
+import com.sptg.permissions.api.dto.RegionAuthorizeDto;
|
|
|
|
|
+import com.sptg.permissions.api.entity.RegionAuthorize;
|
|
|
|
|
+import com.sptg.permissions.api.feigns.RegionAuthorizeFeign;
|
|
|
|
|
+import com.sptg.statistics.api.dto.StatisticsAdPushCountDto;
|
|
|
|
|
+import com.sptg.statistics.api.entity.StatisticsAdPushCount;
|
|
|
|
|
+import com.sptg.statistics.api.feigns.StatisticsAdPushCountFeign;
|
|
|
|
|
+import lombok.AllArgsConstructor;
|
|
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
|
|
+import org.springframework.data.redis.core.RedisTemplate;
|
|
|
|
|
+import org.springframework.data.redis.core.ValueOperations;
|
|
|
|
|
+import org.springframework.integration.support.MessageBuilder;
|
|
|
|
|
+import org.springframework.scheduling.annotation.Scheduled;
|
|
|
|
|
+import org.springframework.stereotype.Component;
|
|
|
|
|
+import org.springframework.util.StringUtils;
|
|
|
|
|
+
|
|
|
|
|
+import java.util.*;
|
|
|
|
|
+import java.util.stream.Collectors;
|
|
|
|
|
+
|
|
|
|
|
+/**
|
|
|
|
|
+ *
|
|
|
|
|
+ *
|
|
|
|
|
+ * description: 广告定时任务
|
|
|
|
|
+ */
|
|
|
|
|
+@Slf4j
|
|
|
|
|
+@Component
|
|
|
|
|
+@AllArgsConstructor
|
|
|
|
|
+public class AdvertQuartzTask {
|
|
|
|
|
+
|
|
|
|
|
+ private final AdPushTaskDetailsServiceInterface adPushTaskDetailsServiceInterface;
|
|
|
|
|
+ private final AdPushTaskServiceInterface adPushTaskServiceInterface;
|
|
|
|
|
+ private final AdPushContentServiceInterface adPushContentServiceInterface;
|
|
|
|
|
+ private final AdPushContentImgServiceInterface adPushContentImgServiceInterface;
|
|
|
|
|
+ private final MsgPublishFeign msgPublishFeign;
|
|
|
|
|
+ private final DeviceFeign deviceFeign;
|
|
|
|
|
+ private final RegionAuthorizeFeign regionAuthorizeFeign;
|
|
|
|
|
+ private final RedisTemplate<String,String> redisTemplate;
|
|
|
|
|
+ private final StatisticsAdPushCountFeign statisticsAdPushCountFeign;
|
|
|
|
|
+ private final ThresholdConfigService thresholdConfigService;
|
|
|
|
|
+ private final DeviceAdvertStatisticsService deviceAdvertStatisticsService;
|
|
|
|
|
+ private final AdvertTaskCallbackProduceInterface advertTaskCallbackProduceInterface;
|
|
|
|
|
+
|
|
|
|
|
+ private final static String REDIS_KEY = "advert.quartz";
|
|
|
|
|
+
|
|
|
|
|
+ @Scheduled(cron = "0/30 * * * * *")
|
|
|
|
|
+ public void run(){
|
|
|
|
|
+ ValueOperations<String, String> operations = this.redisTemplate.opsForValue();
|
|
|
|
|
+ String value = operations.get(REDIS_KEY);
|
|
|
|
|
+ // 值存在,则结束定时器
|
|
|
|
|
+ if (StringUtils.hasText(value)){
|
|
|
|
|
+ return;
|
|
|
|
|
+ }else {
|
|
|
|
|
+ operations.set(REDIS_KEY,"advert quartz running");
|
|
|
|
|
+ }
|
|
|
|
|
+ Wrapper<AdPushTask> wrapper = new EntityWrapper<>();
|
|
|
|
|
+ //发布状态{ -1:发布失败,0:待发布,1:发布成功,2:已撤销 }
|
|
|
|
|
+ wrapper.eq("i_push_status",0);
|
|
|
|
|
+ //当天凌晨2:00需要发布的任务
|
|
|
|
|
+ wrapper.le("t_estimate_push_date",new Date());
|
|
|
|
|
+ //查询满足条件需要发布的任务
|
|
|
|
|
+ List<AdPushTask> list = this.adPushTaskServiceInterface.selectList(wrapper);
|
|
|
|
|
+
|
|
|
|
|
+ list.forEach(task -> {
|
|
|
|
|
+ try {
|
|
|
|
|
+ //任务体
|
|
|
|
|
+ List<AdPushContent> contentList = this.adPushContentServiceInterface.getAdPushContents(task.getId());
|
|
|
|
|
+ contentList.forEach(content -> {
|
|
|
|
|
+ //获取广告图片
|
|
|
|
|
+ List<AdPushContentImg> imgList = adPushContentImgServiceInterface.getAdPushContentImgs(content.getId());
|
|
|
|
|
+ content.setAdPushContentImgs(imgList);
|
|
|
|
|
+ });
|
|
|
|
|
+ task.setAdPushContents(contentList);
|
|
|
|
|
+ // 详情
|
|
|
|
|
+ List<AdPushTaskDetails> taskDetails = this.adPushTaskDetailsServiceInterface.getAdPushTaskDetails(task.getId());
|
|
|
|
|
+ // 获取关联外键Id列表
|
|
|
|
|
+ List<Long> fkIdList = taskDetails.stream().map(AdPushTaskDetails::getFkId).collect(Collectors.toList());
|
|
|
|
|
+ List<Long> deviceIdList = new ArrayList<>();
|
|
|
|
|
+ switch (task.getPushType()) {
|
|
|
|
|
+ // 小区发布
|
|
|
|
|
+ case 1:
|
|
|
|
|
+ this.getDeviceIdByXqs(deviceIdList,fkIdList);
|
|
|
|
|
+ break;
|
|
|
|
|
+ // 单元发布
|
|
|
|
|
+ case 2:
|
|
|
|
|
+ this.getDeviceIdByUnits(deviceIdList,fkIdList);
|
|
|
|
|
+ break;
|
|
|
|
|
+ // 设备发布
|
|
|
|
|
+ case 3:
|
|
|
|
|
+ deviceIdList.addAll(fkIdList);
|
|
|
|
|
+ break;
|
|
|
|
|
+ // 区域发布
|
|
|
|
|
+ case 4:
|
|
|
|
|
+ this.getDeviceIdByRegions(deviceIdList,fkIdList,task.getOrgPosition());
|
|
|
|
|
+ break;
|
|
|
|
|
+ default:
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ // 更新任务状态
|
|
|
|
|
+ task.setPushStatus(OperationConstant.ONE);
|
|
|
|
|
+ task.setPushCount((long) deviceIdList.size());
|
|
|
|
|
+ // 阈值校验
|
|
|
|
|
+ this.fazhiCheck(task,deviceIdList);
|
|
|
|
|
+
|
|
|
|
|
+ if (deviceIdList.size() > 0) {
|
|
|
|
|
+ // 判断是人脸广告还是闲时广告
|
|
|
|
|
+ Instruct instruct = task.getTaskType() == 1 ? Instruct.add_face_advert_task : Instruct.add_leisure_advert_task;
|
|
|
|
|
+ // 构建任务体,并发布
|
|
|
|
|
+ PublishTask publishTask = new PublishTask(task.getId(), instruct, task, deviceIdList);
|
|
|
|
|
+ // 任务类型:{ 1:广告,2:策略,3:公告 }
|
|
|
|
|
+ publishTask.setTaskType(1);
|
|
|
|
|
+ publishTask.setOrgId(task.getRootOrgId());
|
|
|
|
|
+ Map<String,String> map = new HashMap<>();
|
|
|
|
|
+ this.msgPublishFeign.publishTask(publishTask,map);
|
|
|
|
|
+ }
|
|
|
|
|
+ StatisticsAdPushCountDto statisticsAdPushCountDto=new StatisticsAdPushCountDto();
|
|
|
|
|
+ statisticsAdPushCountDto.setAdPushTaskId(task.getId());
|
|
|
|
|
+ //查询是否已经添加记录
|
|
|
|
|
+ StatisticsAdPushCount statisticsAdPushCount = this.statisticsAdPushCountFeign.getStatisticsAdPushCountByTaskId(statisticsAdPushCountDto);
|
|
|
|
|
+ if(statisticsAdPushCount==null){
|
|
|
|
|
+ statisticsAdPushCountDto.setCount(task.getContentCount());
|
|
|
|
|
+ //推送状态
|
|
|
|
|
+ statisticsAdPushCountDto.setPushState(OperationConstant.ZERO);
|
|
|
|
|
+ statisticsAdPushCountDto.setCreateDate(new Date());
|
|
|
|
|
+ statisticsAdPushCountDto.setRootOrgId(task.getRootOrgId());
|
|
|
|
|
+ statisticsAdPushCountDto.setOrgPosition(task.getOrgPosition());
|
|
|
|
|
+ this.statisticsAdPushCountFeign.addAdPushCount(statisticsAdPushCountDto);
|
|
|
|
|
+ }
|
|
|
|
|
+ }catch (Exception e){
|
|
|
|
|
+ log.error(e.getMessage(),e);
|
|
|
|
|
+ }finally {
|
|
|
|
|
+ this.adPushTaskServiceInterface.updateAdPushTask(task);
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+ // 定时器运行完后删除Key
|
|
|
|
|
+ this.redisTemplate.delete(REDIS_KEY);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private void fazhiCheck(AdPushTask task,List<Long> deviceIdList){
|
|
|
|
|
+ // 判断是否启用阈值配置
|
|
|
|
|
+ boolean isEnableFaZhi = null == task.getEnableThreshold() || 1 == task.getEnableThreshold();
|
|
|
|
|
+ // 校验阈值
|
|
|
|
|
+ if (isEnableFaZhi){
|
|
|
|
|
+ List<Device> deviceList = this.deviceFeign.getListByIds(deviceIdList);
|
|
|
|
|
+ Map<String, List<Device>> map = deviceList.stream().collect(Collectors.groupingBy(Device::getRegionCity));
|
|
|
|
|
+ map.forEach((city,values) -> {
|
|
|
|
|
+ // 获取市阈值
|
|
|
|
|
+ ThresholdConfig config = this.thresholdConfigService.selectByRegionCode(task.getRootOrgId(), task.getTaskType(), city);
|
|
|
|
|
+ if (null == config){
|
|
|
|
|
+ // 获取省阈值
|
|
|
|
|
+ config = this.thresholdConfigService.selectByRegionCode(task.getRootOrgId(), task.getTaskType(), values.get(0).getRegionProvince());
|
|
|
|
|
+ }
|
|
|
|
|
+ if (null != config){
|
|
|
|
|
+ for (Device device : values){
|
|
|
|
|
+ // 获取设备的广告数量
|
|
|
|
|
+ DeviceAdvertStatistics statistics = this.deviceAdvertStatisticsService.selectCurrentMonthAdvertStatistics(device.getId(), task.getTaskType());
|
|
|
|
|
+ if (statistics.getAdCount() > config.getValue()){
|
|
|
|
|
+ PublishTaskResult taskResult = new PublishTaskResult();
|
|
|
|
|
+ taskResult.setTaskId(task.getId());
|
|
|
|
|
+ taskResult.setDeviceId(device.getId());
|
|
|
|
|
+ taskResult.setDeviceName(device.getName());
|
|
|
|
|
+ taskResult.setSerialNumber(device.getSerialNumber());
|
|
|
|
|
+ taskResult.setInstallPath(device.getInstallPath());
|
|
|
|
|
+ taskResult.setXqName(device.getXqName());
|
|
|
|
|
+ taskResult.setDyName(device.getDyName());
|
|
|
|
|
+ taskResult.setPushStatus(2);
|
|
|
|
|
+ taskResult.setRemark("超出阈值");
|
|
|
|
|
+ this.advertTaskCallbackProduceInterface.output().send(MessageBuilder.withPayload(taskResult).build());
|
|
|
|
|
+ // 移除超过阈值的设备
|
|
|
|
|
+ deviceIdList.remove(device.getId());
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private void getDeviceIdByRegions(List<Long> deviceIdList,List<Long> fkIdList,String position){
|
|
|
|
|
+ PageBean<RegionAuthorize, RegionAuthorizeDto> pageBean = new PageBean<>(1,100);
|
|
|
|
|
+ RegionAuthorizeDto dto = new RegionAuthorizeDto();
|
|
|
|
|
+ dto.setUserOrgPosition(position);
|
|
|
|
|
+ dto.setAreaIdList(fkIdList);
|
|
|
|
|
+ pageBean.setDto(dto);
|
|
|
|
|
+ List<Long> xqIdList = new ArrayList<>();
|
|
|
|
|
+ int pageNo = 0;
|
|
|
|
|
+ while (true){
|
|
|
|
|
+ ++ pageNo;
|
|
|
|
|
+ pageBean.setCurrent(pageNo);
|
|
|
|
|
+ // 得到授权小区列表
|
|
|
|
|
+ Page<RegionAuthorize> page = this.regionAuthorizeFeign.pagingQuery(pageBean);
|
|
|
|
|
+ if (page.getRecords().size() == 0){
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ page.getRecords().forEach(authorize -> xqIdList.add(authorize.getXqId()));
|
|
|
|
|
+ }
|
|
|
|
|
+ this.getDeviceIdByXqs(deviceIdList,xqIdList);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private void getDeviceIdByXqs(List<Long> deviceIdList,List<Long> fkIdList){
|
|
|
|
|
+ fkIdList.forEach(xqId -> {
|
|
|
|
|
+ List<Device> deviceList = this.deviceFeign.getListByXqId(xqId);
|
|
|
|
|
+ deviceList.forEach(device -> deviceIdList.add(device.getId()));
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private void getDeviceIdByUnits(List<Long> deviceIdList,List<Long> fkIdList){
|
|
|
|
|
+ List<Device> deviceList = this.deviceFeign.getListByUnitIds(fkIdList);
|
|
|
|
|
+ deviceList.forEach(device -> deviceIdList.add(device.getId()));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+}
|