更新大数据相关的测试和发送逻辑

master
土豆兄弟 4 years ago
parent 14cc1c8eed
commit ca9cdafe4b

@ -86,6 +86,15 @@
<artifactId>oshi-core</artifactId>
<version>5.0.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.locationtech.spatial4j/spatial4j -->
<!-- 经纬度计算 -->
<dependency>
<groupId>com.spatial4j</groupId>
<artifactId>spatial4j</artifactId>
<version>0.5</version>
</dependency>
</dependencies>
<!-- 打包 -->

@ -1,4 +1,4 @@
package me.zhengjie.common;
package me.zhengjie.common.http;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;

@ -1,4 +1,4 @@
package me.zhengjie.common;
package me.zhengjie.common.http;
/**
* FileName: ResponseCode

@ -1,4 +1,4 @@
package me.zhengjie.modules.taskrecord.rest.dto;
package me.zhengjie.common.json;
import lombok.AllArgsConstructor;
import lombok.Data;
@ -7,7 +7,7 @@ import lombok.NoArgsConstructor;
import java.util.List;
/**
* Json
* Json -
*/
@Data
@AllArgsConstructor

@ -16,8 +16,8 @@
package me.zhengjie.modules.abmessage.rest;
import me.zhengjie.annotation.Log;
import me.zhengjie.common.CommonResponse;
import me.zhengjie.common.ResponseCode;
import me.zhengjie.common.http.CommonResponse;
import me.zhengjie.common.http.ResponseCode;
import me.zhengjie.modules.abmessage.domain.AbMessage;
import me.zhengjie.modules.abmessage.service.AbMessageService;
import me.zhengjie.modules.abmessage.service.dto.AbMessageDto;

@ -39,8 +39,8 @@ public class BuildRecord implements Serializable {
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
@ApiModelProperty(value = "id")
private Integer id;
private Integer id;
@Column(name = "gmt_create")
@ApiModelProperty(value = "创建时间")
private Timestamp gmtCreate;
@ -89,6 +89,10 @@ public class BuildRecord implements Serializable {
@ApiModelProperty(value = "上次发送总记录数")
private Long sendTotal;
@Column(name = "task_build_id")
@ApiModelProperty(value = "活动任务ID")
private Long taskBuildId;
public void copy(BuildRecord source){
BeanUtil.copyProperties(source,this, CopyOptions.create().setIgnoreNullValue(true));
}

@ -15,19 +15,33 @@
*/
package me.zhengjie.modules.buildrecord.rest;
import cn.hutool.core.bean.BeanUtil;
import me.zhengjie.annotation.AnonymousAccess;
import me.zhengjie.annotation.Log;
import me.zhengjie.common.http.CommonResponse;
import me.zhengjie.common.http.ResponseCode;
import me.zhengjie.modules.buildrecord.domain.BuildRecord;
import me.zhengjie.modules.buildrecord.rest.vo.BuildRecordBuildVO;
import me.zhengjie.modules.buildrecord.rest.vo.BuildRecordSendVO;
import me.zhengjie.modules.buildrecord.service.BuildRecordService;
import me.zhengjie.modules.buildrecord.service.dto.BuildRecordDto;
import me.zhengjie.modules.buildrecord.service.dto.BuildRecordQueryCriteria;
import me.zhengjie.modules.buildrecord.task.ProduceBigDataTask;
import me.zhengjie.modules.buildrecord.task.SendBigDataTask;
import me.zhengjie.modules.buildrecord.task.dto.SendBigDataDTO;
import me.zhengjie.utils.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import io.swagger.annotations.*;
import java.io.IOException;
import java.util.List;
import javax.servlet.http.HttpServletResponse;
/**
@ -43,6 +57,11 @@ public class BuildRecordController {
private final BuildRecordService buildRecordService;
@Autowired
private ProduceBigDataTask produceBigDataTask;
@Autowired
private SendBigDataTask sendBigDataTask;
@Log("导出数据")
@ApiOperation("导出数据")
@GetMapping(value = "/download")
@ -84,4 +103,70 @@ public class BuildRecordController {
buildRecordService.deleteAll(ids);
return new ResponseEntity<>(HttpStatus.OK);
}
// ========================= 自定义的大数据平台相关的接口 start =========================
/**
*
*
* @param taskRecordBuildVO VO
* @return
*/
@PostMapping("/buildTask")
@Log("新建课包任务")
@ApiOperation("新建课包任务")
// @PreAuthorize("@el.check('taskRecord:add')")
@AnonymousAccess // fixme 需要测试完成后进行去除和使用上面的权限注解
public ResponseEntity<Object> buildTask(@RequestBody BuildRecordBuildVO taskRecordBuildVO){
BuildRecord resources = taskRecordBuildVO.getResource();
// 任务名称不能重复
String taskName = resources.getTaskName();
if (!checkTaskNameForBuild(taskName)){
return new ResponseEntity<>(CommonResponse.createByError(ResponseCode.TASK_NAME_IS_EXIST), HttpStatus.OK);
}
// 任务ID必须进行填写
Long taskBuildId = resources.getTaskBuildId();
if (taskBuildId == null || taskBuildId <= 0){
return new ResponseEntity<>(CommonResponse.createByError(ResponseCode.ILLEGAL_ARGUMENT), HttpStatus.OK);
}
// 启动建立数据传输任务
produceBigDataTask.doRunTask(resources);
// 返回结果
return new ResponseEntity<>(CommonResponse.createBySuccess(), HttpStatus.OK);
}
private boolean checkTaskNameForBuild(String taskName){
BuildRecordQueryCriteria criteria = new BuildRecordQueryCriteria();
criteria.setTaskName(taskName);
List<BuildRecordDto> taskRecordDtos = buildRecordService.queryAll(criteria);
if (!CollectionUtils.isEmpty(taskRecordDtos)){
return Boolean.FALSE;
}
return Boolean.TRUE;
}
/**
* ,,
*
* @param buildRecordSendVO VO
* @return
*/
@Log("发送课包任务")
@ApiOperation("发送课包任务")
// @PreAuthorize("@el.check('taskRecord:list')")
@PostMapping(value = "/sendTask")
@AnonymousAccess // fixme 需要测试完成后进行去除和使用上面的权限注解
public ResponseEntity<Object> sendTask(@RequestBody BuildRecordSendVO buildRecordSendVO){
// 参数校验
if (buildRecordSendVO == null || buildRecordSendVO.getLimit() == null || buildRecordSendVO.getTaskId() == null || StringUtils.isBlank(buildRecordSendVO.getSendName())){
return new ResponseEntity<>(CommonResponse.createByError(ResponseCode.EMPTY_ARGUMENT), HttpStatus.OK);
}
SendBigDataDTO sendBigDataDTO = new SendBigDataDTO();
BeanUtil.copyProperties(buildRecordSendVO, sendBigDataDTO);
// 调用发送课包任务,开始发送
sendBigDataTask.doRunTask(buildRecordSendVO.getResource(), sendBigDataDTO);
return new ResponseEntity<>(CommonResponse.createBySuccess(), HttpStatus.OK);
}
// ========================= 自定义的大数据平台相关的接口 start =========================
}

@ -0,0 +1,19 @@
package me.zhengjie.modules.buildrecord.rest.vo;
import lombok.Data;
import me.zhengjie.modules.buildrecord.domain.BuildRecord;
import java.io.Serializable;
@Data
public class BuildRecordBuildVO implements Serializable {
/**
*
*/
private BuildRecord resource;
}

@ -0,0 +1,41 @@
package me.zhengjie.modules.buildrecord.rest.vo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import me.zhengjie.modules.buildrecord.domain.BuildRecord;
import java.io.Serializable;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class BuildRecordSendVO implements Serializable {
/**
*
*/
private Long limit;
/**
* Id,Id
*/
private Long taskId;
/**
* , 0 ,1-5
*/
private String addressTag;
/**
*
*/
private BuildRecord resource;
/**
*
*/
private String sendName;
}

@ -66,4 +66,8 @@ public class BuildRecordDto implements Serializable {
/** 上次发送总记录数 */
private Long sendTotal;
/**
* ID
*/
private Long taskBuildId;
}

@ -26,4 +26,10 @@ import me.zhengjie.annotation.Query;
**/
@Data
public class BuildRecordQueryCriteria{
/** 模糊 */
@Query(type = Query.Type.INNER_LIKE)
private String taskName;
}

@ -0,0 +1,127 @@
package me.zhengjie.modules.buildrecord.task;
import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSON;
import com.spatial4j.core.context.SpatialContext;
import com.spatial4j.core.distance.DistanceUtils;
import com.spatial4j.core.shape.Rectangle;
import lombok.extern.slf4j.Slf4j;
import me.zhengjie.modules.buildrecord.domain.BuildRecord;
import me.zhengjie.modules.buildrecord.task.convert.BuildTaskQueryParamJsonConvert;
import me.zhengjie.modules.edu.service.EduService;
import me.zhengjie.modules.tag.service.TagService;
import me.zhengjie.modules.tag.service.dto.TagDto;
import me.zhengjie.utils.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.ArrayList;
import java.util.List;
@Component
@Scope("prototype")
@Slf4j
public class ProduceBigDataTask {
/**
* 1
*/
private static final int SUCCESS_BUILD_TAG = 1;
/**
* -
*/
private static final String SPLIT_TAG = ",";
@Autowired
private EduService eduService;
@Autowired
private TagService tagService;
@Async(value = "ProduceBigDataTaskExecutor")
public void doRunTask(BuildRecord task){
Long satrtMilliSecond = LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli();
log.info("====== [ task start running, task name is {} ] ======", "ProduceBigDataTask");
runTask(task);
Long endMilliSecond = LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli();
log.info("====== [ task start end, task name is {},cost milliSecond is {} ] ======", "ProduceBigDataTask", (endMilliSecond - satrtMilliSecond));
}
private void runTask(BuildRecord task) {
// 解析需要的查询参数
String params = task.getParams();
if (StringUtils.isBlank(params)){
return;
}
// 构建解析类对Json进行解析
BuildTaskQueryParamJsonConvert convert = JSON.parseObject(params, BuildTaskQueryParamJsonConvert.class);
// 地图点进行计算,获取选点范围
String localCode = convert.getLocalCode();
Integer range = convert.getRange();
Rectangle rectangle = null;
if (StringUtils.isNotBlank(localCode) && range != null){
rectangle = calculateLocalPoint(localCode, range);
}
if (rectangle == null && StringUtils.isNotBlank(localCode)){
log.error(" ====================== {please check localPoint calculate is ok ! } ==========================");
return;
}
// 进行两表关联进行复杂查询
Pageable pageable = PageRequest.of(0,200);
while(true){
// 分页进行查询结果
Page<String> page = eduService.queryMatchData(convert.getCityCode(), convert.getStuGrade(), rectangle, pageable);
if (CollectionUtil.isEmpty(page)){
return;
}
// 把待发送记录存入分表
List<TagDto> tagDtos = new ArrayList<>();
page.forEach(
each->{
TagDto tagDto = new TagDto();
tagDto.setUid(each.trim());
tagDto.setPushStatus(0);
tagDto.setTaskId(task.getTaskBuildId());
tagDtos.add(tagDto);
}
);
Long aLong = tagService.saveAll(tagDtos);
if (aLong <= 0){
log.error("==== [save send record fail, please check , ready insert record is {} , activity id is {}] ====", tagDtos.toString(), task.getTaskBuildId());
}
if (!page.hasNext()){
break;
}
pageable = page.nextPageable();
task.setTotal(page.getTotalElements());
}
// 生成完成后,对各种状态进行记录
task.setIsBuild(SUCCESS_BUILD_TAG);
}
private Rectangle calculateLocalPoint(String localCode, Integer range) {
// 处理切割横纵坐标字符串
String[] split = StringUtils.split(localCode.trim(), SPLIT_TAG);
if (split.length != 2){
return null;
}
// 转换类型
Double x = Double.valueOf(split[0]);
Double y = Double.valueOf(split[1]);
// 坐标计算
SpatialContext geo = SpatialContext.GEO;
Rectangle rectangle = geo.getDistCalc().calcBoxByDistFromPt(
geo.makePoint(x, y), range * DistanceUtils.KM_TO_DEG, geo, null
);
return rectangle;
}
}

@ -0,0 +1,176 @@
package me.zhengjie.modules.buildrecord.task;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.http.HttpResponse;
import com.alibaba.fastjson.JSON;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import me.zhengjie.common.json.PushDBJsonContent;
import me.zhengjie.modules.buildrecord.domain.BuildRecord;
import me.zhengjie.modules.buildrecord.service.BuildRecordService;
import me.zhengjie.modules.buildrecord.service.dto.BuildRecordDto;
import me.zhengjie.modules.buildrecord.task.dto.SendBigDataDTO;
import me.zhengjie.modules.tag.service.TagService;
import me.zhengjie.modules.tag.service.dto.TagDto;
import me.zhengjie.modules.tag.service.dto.TagQueryCriteria;
import me.zhengjie.utils.HttpUtil;
import me.zhengjie.utils.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Scope;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
@Component
@Scope("prototype")
@Slf4j
public class SendBigDataTask {
/**
*
*/
private static final int NON_FINISH_SEND_STATATUS = 0;
/**
*
*/
private static final int SEND_LIMIT = 500;
/**
*
*/
private static final int FINISH_SEND_TAG = 1;
/**
* ,
*/
public static final String BASE_URL_CHAR_NUMBER = "12345";
/**
* url
*/
@Value(value = "${req.db.url}")
private String url;
/**
* ip:
*/
@Value(value = "${req.db.host}")
private String host;
@Autowired
private BuildRecordService buildRecordService;
@Autowired
private TagService tagService;
@Async(value = "SendBigDataTaskExecutor")
public void doRunTask(BuildRecord resource, SendBigDataDTO sendBigDataDTO){
Long satrtMilliSecond = LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli();
log.info("====== [ task start running, task name is {} ] ======", "SendBigDataTask");
runTask(resource, sendBigDataDTO);
Long endMilliSecond = LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli();
log.info("====== [ task start end, task name is {},cost milliSecond is {} ] ======", "SendBigDataTask", (endMilliSecond - satrtMilliSecond));
}
private void runTask(BuildRecord resource, SendBigDataDTO sendBigDataDTO) {
// 根据发送任务的Id来读取发送号码表
Integer id = resource.getId();
if (id <= 0 ){
return;
}
BuildRecordDto buildRecordDto = buildRecordService.findById(id);
// 查询记录表,返回这个id去发送记录表中进行查找 - 构建发送体
TagQueryCriteria tagQueryCriteria = new TagQueryCriteria();
tagQueryCriteria.setTaskId((long)id);
List<TagDto> tagDtos = tagService.queryAll(tagQueryCriteria);
// 遍历查询等待发送的列表
List<TagDto> collect = tagDtos.stream()
.filter(one -> one.getPushStatus() == NON_FINISH_SEND_STATATUS)
.distinct()
.limit(sendBigDataDTO.getLimit())
.collect(Collectors.toList());
// 对需要发送的字段进行发送
batchSend(collect, sendBigDataDTO, buildRecordDto);
// 对发送后的状态进行更新
resource.setIsSend(FINISH_SEND_TAG);
}
private void batchSend(List<TagDto> collect, SendBigDataDTO sendRecordDTO, BuildRecordDto buildRecordDto) {
List<List<TagDto>> partition = Lists.partition(collect, SEND_LIMIT);
partition.forEach(
list->{
// 调用推送地址进行推送
PushDBJsonContent pushDBJsonContent = new PushDBJsonContent();
pushDBJsonContent.setActId(sendRecordDTO.getTaskId());
pushDBJsonContent.setActName(sendRecordDTO.getSendName());
// 加入每一个号码对应接口字段
List<PushDBJsonContent.Client> clientList = new ArrayList<>();
list.forEach(
each->{
PushDBJsonContent.Client client = new PushDBJsonContent.Client();
client.setCellphone(each.getUid());
clientList.add(client);
// 推送完成后修改状态为 已经推送
each.setPushStatus(FINISH_SEND_TAG);
}
);
pushDBJsonContent.setClientList(clientList);
// 进行Json解析
String jsonStr = JSON.toJSONString(pushDBJsonContent);
if (StringUtils.isNotBlank(jsonStr)){
log.info("============ [ Pre send Json is : {} ] ============", jsonStr);
int count = 1;
// 失败重发请求3次
while (count <= 3){
// 对发送请求地址进行准备
String addressTag = sendRecordDTO.getAddressTag();
String address ="";
if (StringUtils.isNotBlank(addressTag)){
address = preSendReqAddress(addressTag);
log.info("========== [DB request address is {} ] =========", address);
}
// 调用HTTP请求发送数据
HttpResponse httpResponse = HttpUtil.sendPostReq(address, jsonStr);
if (httpResponse.isOk() && httpResponse.body().contains("true")){
log.info("========== [DB request success, response is {} ] ==========", httpResponse.body());
break;
}else{
count ++;
log.error("========== [DB request fail, response is {} ] ==========", httpResponse.body());
}
}
if (count > 3) {
log.error("========== [DB update send status fail, url is {} ] ==========", url);
return;
}
}
// 把修改完状态的进行更新
Long aLong = tagService.saveAll(collect);
if (aLong <= 0){
log.error("================= [update data fail , please check it .] =================");
}
}
);
}
private String preSendReqAddress(String tag) {
StringBuilder builder = new StringBuilder();
// 处理环境选择问题, 只接受单个 a, b, c 中的任意一个输入,如果不输入就进行随机返回
tag = (StringUtils.isNotBlank(tag) && StringUtils.countMatches(BASE_URL_CHAR_NUMBER, tag.trim()) == 1)?
tag.trim(): String.valueOf(RandomUtil.randomChar(BASE_URL_CHAR_NUMBER));
// 拼接成需要的URL进行返回
builder.append(host)
.append(tag)
.append(url);
// 返回拼接结果
return builder.toString();
}
}

@ -0,0 +1,34 @@
package me.zhengjie.modules.buildrecord.task.convert;
import lombok.Data;
import java.util.List;
/**
* json
*/
@Data
public class BuildTaskQueryParamJsonConvert {
/**
*
*/
private List<Integer> cityCode;
/**
*
*/
private List<Integer> stuGrade;
/**
*
*/
private String localCode;
/**
* ,
*/
private Integer range;
}

@ -0,0 +1,29 @@
package me.zhengjie.modules.buildrecord.task.dto;
import lombok.Data;
/**
* DTOBean
*/
@Data
public class SendBigDataDTO {
/**
*
*/
private Long limit;
/**
* Id,Id
*/
private Long taskId;
/**
* , 0 ,1-5
*/
private String addressTag;
/**
*
*/
private String sendName;
}

@ -15,21 +15,23 @@
*/
package me.zhengjie.modules.taskrecord.rest;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.bean.BeanUtil;
import me.zhengjie.annotation.AnonymousAccess;
import me.zhengjie.annotation.Log;
import me.zhengjie.common.CommonResponse;
import me.zhengjie.common.ResponseCode;
import me.zhengjie.common.http.CommonResponse;
import me.zhengjie.common.http.ResponseCode;
import me.zhengjie.modules.buildrecord.task.dto.SendBigDataDTO;
import me.zhengjie.modules.taskrecord.domain.TaskRecord;
import me.zhengjie.modules.taskrecord.rest.vo.TaskRecordBuildVO;
import me.zhengjie.modules.taskrecord.rest.vo.TaskBuildRecordVO;
import me.zhengjie.modules.taskrecord.rest.vo.TaskRecordMergeVO;
import me.zhengjie.modules.taskrecord.rest.vo.TaskRecordSendVO;
import me.zhengjie.modules.taskrecord.service.TaskRecordService;
import me.zhengjie.modules.taskrecord.service.dto.TaskRecordDto;
import me.zhengjie.modules.taskrecord.service.dto.TaskRecordQueryCriteria;
import me.zhengjie.task.MergeRecordFilesTask;
import me.zhengjie.task.ProduceLocalFileTask;
import me.zhengjie.task.SendRecordTask;
import me.zhengjie.modules.taskrecord.task.MergeRecordFilesTask;
import me.zhengjie.modules.taskrecord.task.ProduceLocalFileTask;
import me.zhengjie.modules.taskrecord.task.SendRecordTask;
import me.zhengjie.modules.taskrecord.task.dto.SendRecordDTO;
import me.zhengjie.utils.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
@ -121,18 +123,18 @@ public class TaskRecordController {
@ApiOperation("新建课包任务")
// @PreAuthorize("@el.check('taskRecord:add')")
@AnonymousAccess // fixme 需要测试完成后进行去除和使用上面的权限注解
public ResponseEntity<Object> buildTask(@RequestBody TaskRecordBuildVO taskRecordBuildVO){
public ResponseEntity<Object> buildTask(@RequestBody TaskBuildRecordVO taskRecordBuildVO){
TaskRecord resources = taskRecordBuildVO.getResources();
// 任务名称不能重复
String taskName = resources.getTaskName();
if (!checkTaskNameForBuild(taskName)){
return new ResponseEntity<>(CommonResponse.createByError(ResponseCode.TASK_NAME_IS_EXIST), HttpStatus.OK);
}
// 任务ID必须进行填写
Long taskPushId = resources.getTaskPushId();
// fixme 任务ID必须进行填写
/* Long taskPushId = resources.getTaskPushId();
if (taskPushId == null || taskPushId <= 0){
return new ResponseEntity<>(CommonResponse.createByError(ResponseCode.ILLEGAL_ARGUMENT), HttpStatus.OK);
}
}*/
String tag = taskRecordBuildVO.getTag();
if (StringUtils.isBlank(tag)){
return new ResponseEntity<>(CommonResponse.createByError(ResponseCode.EMPTY_ARGUMENT), HttpStatus.OK);
@ -166,13 +168,13 @@ public class TaskRecordController {
@AnonymousAccess // fixme 需要测试完成后进行去除和使用上面的权限注解
public ResponseEntity<Object> sendTask(@RequestBody TaskRecordSendVO taskRecordSendVO){
// 参数校验
Integer id = taskRecordSendVO.getId();
Long limit = taskRecordSendVO.getLimit();
if (id == null || limit == null){
if (taskRecordSendVO == null){
return new ResponseEntity<>(CommonResponse.createByError(ResponseCode.EMPTY_ARGUMENT), HttpStatus.OK);
}
SendRecordDTO sendRecordDTO = new SendRecordDTO();
BeanUtil.copyProperties(taskRecordSendVO, sendRecordDTO);
// 调用发送课包任务,开始发送
sendRecordTask.doRunTask(id, limit);
sendRecordTask.doRunTask(sendRecordDTO);
return new ResponseEntity<>(CommonResponse.createBySuccess(), HttpStatus.OK);
}

@ -1,12 +1,13 @@
package me.zhengjie.modules.taskrecord.rest.vo;
import lombok.Data;
import me.zhengjie.modules.buildrecord.domain.BuildRecord;
import me.zhengjie.modules.taskrecord.domain.TaskRecord;
import java.io.Serializable;
@Data
public class TaskRecordBuildVO implements Serializable {
public class TaskBuildRecordVO implements Serializable {
/**

@ -19,4 +19,19 @@ public class TaskRecordSendVO implements Serializable {
*
*/
private Long limit;
/**
* Id,Id
*/
private Long taskId;
/**
* , 0 ,1-5
*/
private String addressTag;
/**
*
*/
private String sendName;
}

@ -1,4 +1,4 @@
package me.zhengjie.task;
package me.zhengjie.modules.taskrecord.task;
import cn.hutool.system.OsInfo;
import cn.hutool.system.SystemUtil;

@ -1,4 +1,4 @@
package me.zhengjie.task;
package me.zhengjie.modules.taskrecord.task;
import cn.hutool.system.OsInfo;
import cn.hutool.system.SystemUtil;

@ -1,4 +1,4 @@
package me.zhengjie.task;
package me.zhengjie.modules.taskrecord.task;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.http.HttpResponse;
@ -6,9 +6,10 @@ import com.alibaba.fastjson.JSON;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import me.zhengjie.modules.taskrecord.domain.TaskRecord;
import me.zhengjie.modules.taskrecord.rest.dto.PushDBJsonContent;
import me.zhengjie.common.json.PushDBJsonContent;
import me.zhengjie.modules.taskrecord.service.TaskRecordService;
import me.zhengjie.modules.taskrecord.service.dto.TaskRecordDto;
import me.zhengjie.modules.taskrecord.task.dto.SendRecordDTO;
import me.zhengjie.utils.HttpUtil;
import me.zhengjie.utils.StringUtils;
import org.springframework.beans.BeanUtils;
@ -76,16 +77,24 @@ public class SendRecordTask {
* @return
*/
@Async(value = "SendRecordTaskExecutor")
public void doRunTask(Integer id, Long limit){
public void doRunTask( SendRecordDTO sendRecordDTO){
Long satrtMilliSecond = LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli();
log.info("====== [ task start running, task name is {} ] ======", "SendRecordTask");
runTask(id, limit);
runTask(sendRecordDTO);
Long endMilliSecond = LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli();
log.info("====== [ task start end, task name is {},cost milliSecond is {} ] ======", "SendRecordTask", (endMilliSecond - satrtMilliSecond));
}
private void runTask(Integer id, Long limit) {
private void runTask (SendRecordDTO sendRecordDTO) {
Integer id = sendRecordDTO.getId();
if (id == null){
return;
}
Long limit = sendRecordDTO.getLimit();
// 准备所有需要发送任务
TaskRecordDto taskRecordDto = taskRecordService.findById(id);
if (BUILD_STATUS == taskRecordDto.getIsBuild() && StringUtils.isNotBlank(taskRecordDto.getLocalFilePath())){
@ -105,11 +114,11 @@ public class SendRecordTask {
List<String> collect = lines.stream()
.skip(sendTotal)
.limit(limit - sendTotal)
.limit(limit + sendTotal)
.collect(Collectors.toList());
// 分批进行发送
batchSend(collect, taskRecordDto);
batchSend(collect, sendRecordDTO, taskRecordDto);
// 对发送后的记录进行更新
TaskRecord taskRecord = new TaskRecord();
BeanUtils.copyProperties(taskRecordDto, taskRecord);
@ -123,14 +132,14 @@ public class SendRecordTask {
}
}
private void batchSend(List<String> collect, TaskRecordDto taskRecordDto) {
private void batchSend(List<String> collect, SendRecordDTO sendRecordDTO, TaskRecordDto taskRecordDto) {
List<List<String>> partition = Lists.partition(collect, SEND_LIMIT);
partition.forEach(
list->{
// TODO: 2020/9/10 0010 调用推送地址进行推送
PushDBJsonContent pushDBJsonContent = new PushDBJsonContent();
pushDBJsonContent.setActId(taskRecordDto.getTaskPushId());
pushDBJsonContent.setActName(taskRecordDto.getTaskName());
pushDBJsonContent.setActId(sendRecordDTO.getTaskId());
pushDBJsonContent.setActName(sendRecordDTO.getSendName());
// 加入每一个号码对应接口字段
List<PushDBJsonContent.Client> clientList = new ArrayList<>();
list.forEach(
@ -149,14 +158,15 @@ public class SendRecordTask {
// 失败重发请求3次
while (count <= 3){
// 对发送请求地址进行准备
String description = taskRecordDto.getDescription();
String addressTag = sendRecordDTO.getAddressTag();
String address ="";
if (StringUtils.isNotBlank(description)){
address = preSendReqAddress(description);
if (StringUtils.isNotBlank(addressTag)){
address = preSendReqAddress(addressTag);
log.info("========== [DB request address is {} ] =========", address);
}
// 调用HTTP请求发送数据
HttpResponse httpResponse = HttpUtil.sendPostReq(address, jsonStr);
if (httpResponse.isOk() && httpResponse.body().contains("success")){
if (httpResponse.isOk() && httpResponse.body().contains("true")){
log.info("========== [DB request success, response is {} ] ==========", httpResponse.body());
break;
}else{
@ -173,14 +183,14 @@ public class SendRecordTask {
);
}
private String preSendReqAddress(String desc) {
private String preSendReqAddress(String tag) {
StringBuilder builder = new StringBuilder();
// 处理环境选择问题, 只接受单个 a, b, c 中的任意一个输入,如果不输入就进行随机返回
desc = (StringUtils.isNotBlank(desc) && StringUtils.countMatches(BASE_URL_CHAR_NUMBER, desc.trim()) == 1)?
desc.trim(): String.valueOf(RandomUtil.randomChar(BASE_URL_CHAR_NUMBER));
tag = (StringUtils.isNotBlank(tag) && StringUtils.countMatches(BASE_URL_CHAR_NUMBER, tag.trim()) == 1)?
tag.trim(): String.valueOf(RandomUtil.randomChar(BASE_URL_CHAR_NUMBER));
// 拼接成需要的URL进行返回
builder.append(host)
.append(desc)
.append(tag)
.append(url);
// 返回拼接结果
return builder.toString();

@ -0,0 +1,36 @@
package me.zhengjie.modules.taskrecord.task.dto;
import lombok.Data;
/**
* DTOBean
*/
@Data
public class SendRecordDTO {
/**
* Id
*/
private Integer id;
/**
*
*/
private Long limit;
/**
* Id,Id
*/
private Long taskId;
/**
* , 0 ,1-5
*/
private String addressTag;
/**
*
*/
private String sendName;
}

@ -116,7 +116,7 @@ req:
db:
# 设置给大坝回传号码的地址
host: http://api.hzdaba.cn/aibot
url: /activity/addClient
url: /api/activity/addclient
# 线程池的相关配置
produce:
task:
@ -139,3 +139,14 @@ merge:
maxPoolSize: 16
queueCapacity: 3
ThreadNamePrefix: 'ProduceLocalFileTaskExecutor-'
# 增加日志相关的配置
logging:
level:
org.springframework.security:
- debug
- info
org.springframework.web: error
org.hibernate.SQL: debug
org.hibernate.engine.QueryParameters: debug
org.hibernate.engine.query.HQLQueryPlan: debug
org.hibernate.type.descriptor.sql.BasicBinder: trace

@ -125,7 +125,7 @@ req:
db:
# 设置给大坝回传号码的地址
host: http://api.hzdaba.cn/aibot
url: /activity/addClient
url: /api/activity/addclient
# 线程池的相关配置
produce:
task:

@ -0,0 +1,74 @@
package me.zhengjie;
import com.google.common.collect.Maps;
import com.spatial4j.core.context.SpatialContext;
import com.spatial4j.core.distance.DistanceUtils;
import com.spatial4j.core.shape.Rectangle;
import org.junit.Test;
import java.util.Map;
import java.util.Set;
public class LocalSpatial4JTest {
double lon = 11.0;
double lat = 11.0;
double radius = 1.5;// 千米
@Test
public void testSpatial4J(){
// 添加一些坐标进行测试
Map<Double, Double> map = Maps.newHashMap();
map.put(114.057437631038,37.071258077716465);
map.put(120.06353054872726,30.133873663327968);
map.put(120.12348040422445,30.280488570107618);
map.put(114.36057527828048,37.07901005308366);
map.put(120.03806942650519,30.199992151825587);
map.put(114.57392637891887,37.17160880411955);
map.put(120.13924737270503,30.28530467158395);
map.put(114.56491716785757,37.02130766904826);
map.put(120.345992475657,30.23212283958972);
map.put(120.1277435825137,30.297490241707287);
map.put(113.82913562127143,37.079889655513085);
map.put(114.02731205745539,38.4803910057633);
map.put(120.14895329424868,30.29357641622967);
map.put(113.91210108351102,37.120583116481995);
map.put(114.60211170243049,37.966762288221716);
map.put(119.95668068482375,29.902903928602015);
map.put(114.56846108819616,37.940576014434974);
map.put(120.13704984793597,30.29020418663027);
map.put(114.52153190157445,38.0483119268727);
Set<Map.Entry<Double, Double>> entries = map.entrySet();
entries.forEach(
one -> {
// 从map中进行遍历 然后进行计算坐标
SpatialContext geo = SpatialContext.GEO;
Rectangle rectangle = geo.getDistCalc().calcBoxByDistFromPt(
geo.makePoint(one.getKey(), one.getValue()), radius * DistanceUtils.KM_TO_DEG, geo, null
);
System.out.println(rectangle.getMinX() + "-" + rectangle.getMaxX());// 经度范围
System.out.println(rectangle.getMinY() + "-" + rectangle.getMaxY());// 纬度范围
}
);
/**
*
*
* SELECT id, name
* FROM customer
* WHERE (lng BETWEEN ? AND ?) AND (lat BETWEEN ? AND ?);
*
* lonlat
* INDEX `idx_lon_lat` (`lon`, `lat`)
* geohash
*/
// https://blog.csdn.net/ghsau/article/details/50591932?utm_medium=distribute.pc_relevant.none-task-blog-title-5&spm=1001.2101.3001.4242
}
}

@ -4,6 +4,8 @@ import lombok.extern.slf4j.Slf4j;
import me.zhengjie.modules.abmessage.domain.AbMessage;
import me.zhengjie.modules.abmessage.service.AbMessageService;
import me.zhengjie.modules.abmessage.service.dto.AbMessageQueryCriteria;
import me.zhengjie.modules.edu.domain.Edu;
import me.zhengjie.modules.edu.repository.EduRepository;
import me.zhengjie.modules.mnt.service.dto.AppQueryCriteria;
import me.zhengjie.modules.student.domain.Student;
import me.zhengjie.modules.student.repository.StudentRepository;
@ -41,6 +43,9 @@ public class SpringJPATest {
@Autowired
private AbMessageService abMessageService;
@Autowired
private EduRepository eduRepository;
@Test
public void testQueryBySlice() throws Exception{
@ -138,4 +143,52 @@ public class SpringJPATest {
System.out.println(stringObjectMap.toString());
}
@Test
public void testQuery(){
List<Integer> city = new ArrayList<>();
city.add(1);
city.add(2);
List<Integer> stuGrade = new ArrayList<>();
stuGrade.add(1);
stuGrade.add(3);
double minX = 1.0;
double maxX = 10.0;
double minY = 1.0;
double maxY = 10.0;
/**
* SELECT e.uid
* FROM dc_school s
* JOIN dc_edu e ON s.oldid = e.mid
* WHERE 1=1 AND e.level IN (1,3)
* AND s.city_code IN (1,2)
* AND s.lng BETWEEN 1.0 AND 10.0
* AND s.lat BETWEEN 1.0 AND 10.0;
*/
// List<String> allMatchDataBy = eduRepository.findAllMatchDataBy(city, stuGrade, minX, maxX, minY, maxY);
// 测试各种为空的判断,看是否可以使用
// List<String> allMatchDataBy1 = eduRepository.findAllMatchDataBy(null, stuGrade, minX, maxX, minY, maxY);
//
// List<String> allMatchDataBy2 = eduRepository.findAllMatchDataBy(city, null, minX, maxX, minY, maxY);
//
// List<String> allMatchDataBy3 = eduRepository.findAllMatchDataBy(city, stuGrade, null, maxX, minY, maxY);
// List<String> allMatchDataBy3 = eduRepository.findAllMatchDataByPage(null, null, null, null, null, null);
// allMatchDataBy3.forEach(System.out::println);
Pageable pageable = PageRequest.of(0, 2);
Page<String> page = eduRepository.findAllMatchDataByPage(city, stuGrade, minX, maxX, minY, maxY, pageable);
System.out.println("查询的总页数" + page.getTotalPages());
System.out.println("查询的总记录数" + page.getTotalElements());
System.out.println("查询的当前第几页" + page.getNumber() + 1);
System.out.println("查询当前页面的集合" + page.getContent());
System.out.println("查询当前页面的记录数" + page.getNumberOfElements());
}
}

Loading…
Cancel
Save