bms2相关修改;
This commit is contained in:
+1
-1
@@ -545,4 +545,4 @@ public class LeaseApplicationService {
|
||||
// }
|
||||
// leaseDO.setContainerTypeName(storageTypeDictData.getDictLabel());
|
||||
// }
|
||||
}
|
||||
}
|
||||
@@ -90,4 +90,7 @@ public class Lease extends BaseVOEntity{
|
||||
|
||||
@ApiModelProperty("结算币种")
|
||||
private String settlementCurrency;
|
||||
}
|
||||
|
||||
@ApiModelProperty("推送时间")
|
||||
private String pushTime;
|
||||
}
|
||||
+4
-1
@@ -91,4 +91,7 @@ public class LeasePO extends BaseVOEntity{
|
||||
|
||||
@ApiModelProperty("结算币种")
|
||||
private String settlementCurrency;
|
||||
}
|
||||
|
||||
@ApiModelProperty("推送时间")
|
||||
private String pushTime;
|
||||
}
|
||||
+4
-1
@@ -107,4 +107,7 @@ public class LeaseDO extends BaseVOEntity{
|
||||
|
||||
@ApiModelProperty(name = "修改时间查询条件结束日期")
|
||||
private String updateTimeEnd;
|
||||
}
|
||||
|
||||
@ApiModelProperty("推送时间")
|
||||
private String pushTime;
|
||||
}
|
||||
+59
@@ -0,0 +1,59 @@
|
||||
package com.mhd.basic.domain.scheduledTask.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import com.mhd.common.core.web.domain.BaseVOEntity;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalTime;
|
||||
import java.util.Date;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @author gen
|
||||
* @date 2024-06-07
|
||||
*/
|
||||
|
||||
@Data
|
||||
public class ScheduledTask extends BaseVOEntity {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@ApiModelProperty("id")
|
||||
@TableId(type = IdType.AUTO)
|
||||
private Long id;
|
||||
|
||||
@ApiModelProperty("类型")
|
||||
private String taskType;
|
||||
|
||||
@ApiModelProperty("参数")
|
||||
private String taskData;
|
||||
|
||||
@ApiModelProperty("业务id")
|
||||
private Long busId;
|
||||
|
||||
@ApiModelProperty("任务状态")
|
||||
private String taskStatus;
|
||||
|
||||
@ApiModelProperty("")
|
||||
private Integer retryCount;
|
||||
|
||||
@ApiModelProperty("计划执行时间")
|
||||
@JsonFormat(pattern = "yyyy-MM-dd")
|
||||
private Date executeTime;
|
||||
|
||||
|
||||
@ApiModelProperty(name = "出账日")
|
||||
private Integer billDays;
|
||||
|
||||
@ApiModelProperty("出账时间")
|
||||
@JsonFormat(timezone = "GMT+8", pattern = "HH:mm:ss")
|
||||
@DateTimeFormat(pattern = "HH:mm:ss")
|
||||
private LocalTime billTime;
|
||||
|
||||
@ApiModelProperty("推送时间")
|
||||
private String pushTime;
|
||||
}
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
package com.mhd.basic.domain.scheduledTask.repository.facade;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.mhd.basic.domain.scheduledTask.entity.ScheduledTask;
|
||||
import com.mhd.basic.domain.lease.entity.Lease;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
public interface ScheduledTaskService extends IService<ScheduledTask> {
|
||||
|
||||
public void saveBillingTask(LocalDateTime billingTime, Lease lease);
|
||||
|
||||
/**
|
||||
* 执行出账
|
||||
* @param busId 出账数据
|
||||
* @return 出账结果
|
||||
*/
|
||||
void executeBilling(Long busId);
|
||||
|
||||
//推送散租到bms
|
||||
public void ScatteredRentalSynchronization(Long busId);
|
||||
//推送整租到bms
|
||||
public void wholeRentSynchronization(Long busId);
|
||||
|
||||
}
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
package com.mhd.basic.domain.scheduledTask.repository.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.mhd.basic.domain.scheduledTask.entity.ScheduledTask;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.apache.ibatis.annotations.Update;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
public interface ScheduledTaskMapper extends BaseMapper<ScheduledTask> {
|
||||
/**
|
||||
* 查询待执行的任务
|
||||
* @param startTime 开始时间
|
||||
* @param endTime 结束时间
|
||||
* @param status 任务状态
|
||||
* @param limit 限制条数
|
||||
* @return 任务列表
|
||||
*/
|
||||
List<ScheduledTask> findPendingTasks(
|
||||
@Param("startTime") LocalDateTime startTime,
|
||||
@Param("endTime") LocalDateTime endTime,
|
||||
@Param("status") String status,
|
||||
@Param("limit") Integer limit);
|
||||
|
||||
/**
|
||||
* 通过乐观锁更新任务状态
|
||||
* @param id 任务ID
|
||||
* @param oldStatus 旧状态
|
||||
* @param newStatus 新状态
|
||||
* @return 更新的记录数
|
||||
*/
|
||||
@Update("UPDATE scheduled_task SET task_status = #{newStatus}, update_time = NOW() " +
|
||||
"WHERE id = #{id} AND task_status = #{oldStatus}")
|
||||
int updateStatusIfPending(
|
||||
@Param("id") Long id,
|
||||
@Param("oldStatus") String oldStatus,
|
||||
@Param("newStatus") String newStatus);
|
||||
|
||||
/**
|
||||
* 更新任务状态
|
||||
* @param id 任务ID
|
||||
* @param status 新状态
|
||||
* @return 更新的记录数
|
||||
*/
|
||||
@Update("UPDATE scheduled_task SET task_status = #{status}, update_time = NOW() " +
|
||||
"WHERE id = #{id}")
|
||||
int updateStatus(@Param("id") Long id, @Param("status") String status);
|
||||
|
||||
/**
|
||||
* 增加重试次数
|
||||
* @param id 任务ID
|
||||
* @return 更新的记录数
|
||||
*/
|
||||
@Update("UPDATE scheduled_task SET retry_count = retry_count + 1, update_time = NOW() " +
|
||||
"WHERE id = #{id}")
|
||||
int incrementRetryCount(@Param("id") Long id);
|
||||
}
|
||||
+162
@@ -0,0 +1,162 @@
|
||||
package com.mhd.basic.domain.scheduledTask.repository.persistence;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.mhd.basic.application.service.Lease.LeaseApplicationService;
|
||||
import com.mhd.basic.domain.scheduledTask.entity.ScheduledTask;
|
||||
import com.mhd.basic.domain.scheduledTask.repository.facade.ScheduledTaskService;
|
||||
import com.mhd.basic.domain.scheduledTask.repository.mapper.ScheduledTaskMapper;
|
||||
import com.mhd.basic.domain.lease.entity.Lease;
|
||||
import com.mhd.basic.domain.lease.repository.facade.ILeaseService;
|
||||
import com.mhd.basic.domain.lease.repository.po.LeasePO;
|
||||
import com.mhd.basic.domain.lease.repository.todo.LeaseDO;
|
||||
import com.mhd.common.core.domain.dto.BusinessDataPushDTO;
|
||||
import com.mhd.common.core.web.domain.AjaxResult;
|
||||
import com.mhd.system.api.BmsServiceFeign;
|
||||
import com.mhd.system.api.WmsServiceFeign;
|
||||
import com.mhd.system.api.domain.MaterialInventoryDTO;
|
||||
import com.mhd.system.api.domain.MaterialInventoryPO;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneId;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
public class ScheduledTaskServiceImpl extends ServiceImpl<ScheduledTaskMapper, ScheduledTask> implements ScheduledTaskService {
|
||||
|
||||
@Resource
|
||||
private ScheduledTaskMapper taskMapper;
|
||||
|
||||
@Resource
|
||||
private ObjectMapper objectMapper;
|
||||
|
||||
@Resource
|
||||
private BmsServiceFeign bmsServiceFeign;
|
||||
|
||||
@Resource
|
||||
private WmsServiceFeign WmsServiceFeign;
|
||||
|
||||
@Resource
|
||||
private LeaseApplicationService leaseApplicationService;
|
||||
|
||||
@Resource
|
||||
private ILeaseService leaseService;
|
||||
|
||||
public void saveBillingTask(LocalDateTime billingTime, Lease lease) {
|
||||
ScheduledTask task = new ScheduledTask();
|
||||
task.setTaskType("LeaseToBms");
|
||||
task.setExecuteTime(Date.from(billingTime.atZone(ZoneId.systemDefault()).toInstant()));
|
||||
task.setTaskData(JSON.toJSONString(lease));
|
||||
task.setBusId(lease.getId());
|
||||
task.setTaskStatus("PENDING");
|
||||
taskMapper.insert(task);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void executeBilling(Long busId) {
|
||||
try {
|
||||
log.info("开始执行出账业务");
|
||||
LeasePO leasePO = leaseService.getInfo(busId);
|
||||
String leaseType = leasePO.getLeaseType();
|
||||
if ("整租".equals(leaseType)) {
|
||||
wholeRentSynchronization(busId);
|
||||
} else if ("散租".equals(leaseType)) {
|
||||
ScatteredRentalSynchronization(busId);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("出账业务异常", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 定时任务整租推送到bms
|
||||
*/
|
||||
public void wholeRentSynchronization(Long busId) {
|
||||
log.info("定时任务整租推送到bms触发--开始");
|
||||
LeaseDO leaseDO = new LeaseDO();
|
||||
leaseDO.setTime(new Date());
|
||||
leaseDO.setLeaseType("整租");
|
||||
leaseDO.setId(busId);
|
||||
List<LeasePO> leasePOList = leaseApplicationService.queryList(leaseDO);
|
||||
log.info("整租数据{}", JSONObject.toJSONString(leasePOList));
|
||||
for (LeasePO leasePO: leasePOList) {
|
||||
if (leasePO.getShipperId() == null) {
|
||||
continue;
|
||||
}
|
||||
log.info("开始执行{}",JSONObject.toJSONString(leasePOList));
|
||||
BusinessDataPushDTO businessDataPushDTO = new BusinessDataPushDTO();
|
||||
businessDataPushDTO.setOrganizationId(leasePO.getOrganizationId());
|
||||
businessDataPushDTO.setTopOrganizationId(leasePO.getTopOrganizationId());
|
||||
businessDataPushDTO.setOrganizationName(leasePO.getOrganizationName());
|
||||
businessDataPushDTO.setBelongModuleCode("wms");
|
||||
// businessDataPushDTO.setBillAmount();//计费金额
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
jsonObject.put("lease_area",leasePO.getLeaseArea());//租赁面积
|
||||
jsonObject.put("jiecun_cbm",0);//结存体积
|
||||
businessDataPushDTO.setDocumentFormJson(jsonObject.toJSONString());
|
||||
businessDataPushDTO.setDocumentTypeCode("TY_ZL");
|
||||
businessDataPushDTO.setSettlementEntityId(leasePO.getShipperId());
|
||||
businessDataPushDTO.setSecondSubjectCode(leasePO.getSecondSubjectCode());
|
||||
businessDataPushDTO.setServiceItemsCode(leasePO.getServiceItemsCode());
|
||||
businessDataPushDTO.setDataSources(1);
|
||||
bmsServiceFeign.businessDocumentApiSave(businessDataPushDTO);
|
||||
}
|
||||
log.info("定时任务整租推送到bms触发--结束");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 定时任务散租推送到bms
|
||||
*/
|
||||
public void ScatteredRentalSynchronization(Long busId) {
|
||||
LeaseDO leaseDO = new LeaseDO();
|
||||
leaseDO.setTime(new Date());
|
||||
leaseDO.setLeaseType("散租");
|
||||
leaseDO.setId(busId);
|
||||
List<LeasePO> leasePOList = leaseApplicationService.queryList(leaseDO);
|
||||
for (LeasePO leasePO: leasePOList) {
|
||||
if (leasePO.getShipperId() == null) {
|
||||
continue;
|
||||
}
|
||||
MaterialInventoryDTO materialInventoryDTO = new MaterialInventoryDTO();
|
||||
materialInventoryDTO.setShipperId(leasePO.getShipperId());
|
||||
BigDecimal totalVolume = BigDecimal.ZERO;
|
||||
AjaxResult ajaxResult = WmsServiceFeign.materialInventoryApiListAll(materialInventoryDTO);
|
||||
if (ajaxResult != null && "200".equals(String.valueOf(ajaxResult.get("code")))) {
|
||||
List<MaterialInventoryPO> batchDetailFeignPOList = JSON.parseArray(
|
||||
com.alibaba.fastjson2.JSONObject.toJSONString(ajaxResult.get("data")), MaterialInventoryPO.class);
|
||||
totalVolume = batchDetailFeignPOList.stream()
|
||||
.map(MaterialInventoryPO::getVolume)
|
||||
.filter(Objects::nonNull)
|
||||
.reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||
}
|
||||
BusinessDataPushDTO businessDataPushDTO = new BusinessDataPushDTO();
|
||||
businessDataPushDTO.setOrganizationId(leasePO.getOrganizationId());
|
||||
businessDataPushDTO.setTopOrganizationId(leasePO.getTopOrganizationId());
|
||||
businessDataPushDTO.setOrganizationName(leasePO.getOrganizationName());
|
||||
businessDataPushDTO.setBelongModuleCode("wms");
|
||||
// businessDataPushDTO.setBillAmount();//计费金额
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
jsonObject.put("lease_area",0);//租赁面积
|
||||
jsonObject.put("jiecun_cbm",totalVolume);//结存体积
|
||||
businessDataPushDTO.setDocumentFormJson(jsonObject.toJSONString());
|
||||
businessDataPushDTO.setDocumentTypeCode("TY_ZL");
|
||||
businessDataPushDTO.setSettlementEntityId(leasePO.getShipperId());
|
||||
businessDataPushDTO.setSecondSubjectCode(leasePO.getSecondSubjectCode());
|
||||
businessDataPushDTO.setServiceItemsCode(leasePO.getServiceItemsCode());
|
||||
businessDataPushDTO.setDataSources(1);
|
||||
bmsServiceFeign.businessDocumentApiSave(businessDataPushDTO);
|
||||
}
|
||||
}
|
||||
}
|
||||
+69
@@ -0,0 +1,69 @@
|
||||
package com.mhd.basic.domain.scheduledTask.repository.task;
|
||||
|
||||
import com.mhd.basic.domain.scheduledTask.entity.ScheduledTask;
|
||||
import com.mhd.basic.domain.scheduledTask.repository.facade.ScheduledTaskService;
|
||||
import com.mhd.basic.domain.scheduledTask.repository.mapper.ScheduledTaskMapper;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
@Component
|
||||
public class BillingScheduler {
|
||||
|
||||
@Resource
|
||||
private ScheduledTaskMapper scheduledTaskMapper;
|
||||
|
||||
@Resource
|
||||
private ScheduledTaskService scheduledTaskService;
|
||||
|
||||
// 每10秒扫描一次
|
||||
//@Scheduled(fixedDelay = 10000)
|
||||
@Transactional
|
||||
public void scanAndExecute() {
|
||||
// 查询当前时间前1分钟内待执行的任务
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
LocalDateTime start = now.minusMinutes(1);
|
||||
|
||||
List<ScheduledTask> tasks = scheduledTaskMapper.findPendingTasks(
|
||||
start, now, "PENDING", 100);
|
||||
|
||||
for (ScheduledTask task : tasks) {
|
||||
try {
|
||||
// 乐观锁更新状态,防止重复执行
|
||||
int updated = scheduledTaskMapper.updateStatusIfPending(
|
||||
task.getId(), "PENDING", "PROCESSING");
|
||||
|
||||
if (updated > 0) {
|
||||
// 异步执行具体业务
|
||||
CompletableFuture.runAsync(() -> {
|
||||
executeTask(task);
|
||||
});
|
||||
}
|
||||
} catch (Exception e) {
|
||||
scheduledTaskMapper.updateStatus(task.getId(), "FAILED");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void executeTask(ScheduledTask task) {
|
||||
try {
|
||||
// 执行具体的出账逻辑
|
||||
scheduledTaskService.executeBilling(task.getBusId());
|
||||
|
||||
scheduledTaskMapper.updateStatus(task.getId(), "SUCCESS");
|
||||
} catch (Exception e) {
|
||||
// 重试机制
|
||||
scheduledTaskMapper.incrementRetryCount(task.getId());
|
||||
if (task.getRetryCount() < 3) {
|
||||
scheduledTaskMapper.updateStatus(task.getId(), "PENDING");
|
||||
} else {
|
||||
scheduledTaskMapper.updateStatus(task.getId(), "FAILED");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+4
-1
@@ -104,4 +104,7 @@ public class LeaseDTO extends BaseVOEntity{
|
||||
|
||||
@ApiModelProperty(name = "修改时间查询条件结束日期")
|
||||
private String updateTimeEnd;
|
||||
}
|
||||
|
||||
@ApiModelProperty("推送时间")
|
||||
private String pushTime;
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!DOCTYPE mapper
|
||||
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.mhd.basic.domain.scheduledTask.repository.mapper.ScheduledTaskMapper">
|
||||
|
||||
<!-- 通用结果映射 -->
|
||||
<resultMap id="BaseResultMap" type="com.mhd.basic.domain.scheduledTask.entity.ScheduledTask">
|
||||
<id column="id" property="id"/>
|
||||
<result column="task_type" property="taskType"/>
|
||||
<result column="execute_time" property="executeTime"/>
|
||||
<result column="task_data" property="taskData"/>
|
||||
<result column="task_status" property="taskStatus"/>
|
||||
<result column="retry_count" property="retryCount"/>
|
||||
<result column="create_time" property="createTime"/>
|
||||
<result column="update_time" property="updateTime"/>
|
||||
</resultMap>
|
||||
|
||||
<!-- 通用查询列 -->
|
||||
<sql id="Base_Column_List">
|
||||
id, task_type, execute_time, task_data, task_status, retry_count, create_time, update_time, bill_days, bill_time,bus_id
|
||||
</sql>
|
||||
|
||||
<!-- 查询待执行任务 -->
|
||||
<select id="findPendingTasks" resultMap="BaseResultMap">
|
||||
SELECT
|
||||
<include refid="Base_Column_List"/>
|
||||
FROM scheduled_task
|
||||
WHERE
|
||||
TO_DATE(
|
||||
TO_CHAR(SYSDATE, 'YYYY-MM-') || PUSH_TIME,
|
||||
'YYYY-MM-DD HH24:MI:SS'
|
||||
) BETWEEN #{startTime} AND #{endTime}
|
||||
and task_status = #{status}
|
||||
ORDER BY TO_DATE(
|
||||
TO_CHAR(SYSDATE, 'YYYY-MM-') || PUSH_TIME,
|
||||
'YYYY-MM-DD HH24:MI:SS'
|
||||
) ASC
|
||||
LIMIT #{limit}
|
||||
</select>
|
||||
|
||||
<!-- 批量更新状态(可选:用于批量处理) -->
|
||||
<update id="batchUpdateStatus" parameterType="map">
|
||||
UPDATE scheduled_task
|
||||
SET task_status = #{newStatus},
|
||||
update_time = NOW()
|
||||
WHERE id IN
|
||||
<foreach collection="ids" item="id" open="(" separator="," close=")">
|
||||
#{id}
|
||||
</foreach>
|
||||
AND task_status = #{oldStatus}
|
||||
</update>
|
||||
|
||||
<!-- 统计待处理任务数量 -->
|
||||
<select id="countPendingTasks" resultType="int">
|
||||
SELECT COUNT(*)
|
||||
FROM scheduled_task
|
||||
WHERE task_status = 'PENDING'
|
||||
AND execute_time <= NOW()
|
||||
</select>
|
||||
|
||||
<!-- 查询超时任务(处理中超过30分钟的任务) -->
|
||||
<select id="findTimeoutTasks" resultMap="BaseResultMap">
|
||||
SELECT
|
||||
<include refid="Base_Column_List"/>
|
||||
FROM scheduled_task
|
||||
WHERE
|
||||
task_status = 'PROCESSING'
|
||||
AND update_time < DATE_SUB(NOW(), INTERVAL 30 MINUTE)
|
||||
LIMIT 50
|
||||
</select>
|
||||
|
||||
</mapper>
|
||||
Reference in New Issue
Block a user