提交 56aa4a93 authored 作者: 刘海泉's avatar 刘海泉

Merge remote-tracking branch 'origin/v29.7_pending_freight_20241017' into test_jdk17

# Conflicts: # clx-performance-web/src/main/java/com/clx/performance/dao/OrderChildDao.java # clx-performance-web/src/main/java/com/clx/performance/dao/OrderGoodsDao.java # clx-performance-web/src/main/java/com/clx/performance/dao/impl/OrderChildDaoImpl.java # clx-performance-web/src/main/java/com/clx/performance/dao/impl/OrderGoodsDaoImpl.java # clx-performance-web/src/main/java/com/clx/performance/listener/OrderChildDtsListener.java Former-commit-id: 926a4186
......@@ -299,6 +299,112 @@ public class RabbitBeanConfig {
/**
* 监听运单同步履约进度表
*/
@Bean
public Queue syncPendingFreight4OrderInfoQueue() {
return new Queue(RabbitKeyConstants.SYNC_PENDING_FREIGHT_FOR_ORDER_INFO_QUEUE,
true, false, false);
}
/**
* 监听运单同步履约进度表
**/
@Bean
public DirectExchange syncPendingFreight4OrderInfoExchange() {
return new DirectExchange(RabbitKeyConstants.SYNC_PENDING_FREIGHT_FOR_ORDER_INFO_EXCHANGE);
}
/**
* 监听运单同步履约进度表
*/
@Bean
public Binding syncPendingFreight4OrderInfoBind() {
return BindingBuilder.bind(syncPendingFreight4OrderInfoQueue()).to(syncPendingFreight4OrderInfoExchange())
.with(RabbitKeyConstants.SYNC_PENDING_FREIGHT_FOR_ORDER_INFO_ROUTING_KEY);
}
/**
* 监听运单同步履约进度表
*/
@Bean
public Queue syncPendingFreight4InternalReportQueue() {
return new Queue(RabbitKeyConstants.SYNC_PENDING_FREIGHT_FOR_INTERNAL_REPORT_QUEUE,
true, false, false);
}
/**
* 监听运单同步履约进度表
**/
@Bean
public DirectExchange syncPendingFreight4InternalReportExchange() {
return new DirectExchange(RabbitKeyConstants.SYNC_PENDING_FREIGHT_FOR_INTERNAL_REPORT_EXCHANGE);
}
/**
* 监听运单同步履约进度表
*/
@Bean
public Binding syncPendingFreight4InternalReportBind() {
return BindingBuilder.bind(syncPendingFreight4InternalReportQueue()).to(syncPendingFreight4InternalReportExchange())
.with(RabbitKeyConstants.SYNC_PENDING_FREIGHT_FOR_INTERNAL_REPORT_ROUTING_KEY);
}
/**
* 监听货单同步到挂单运费表
*/
@Bean
public Queue syncPendingFreight4OrderGoodsQueue() {
return new Queue(RabbitKeyConstants.SYNC_PENDING_FREIGHT_FOR_ORDER_GOODS_QUEUE,
true, false, false);
}
/**
* 监听货单同步到挂单运费表
**/
@Bean
public DirectExchange syncPendingFreight4OrderGoodsExchange() {
return new DirectExchange(RabbitKeyConstants.SYNC_PENDING_FREIGHT_FOR_ORDER_GOODS_EXCHANGE);
}
/**
* 监听货单同步到挂单运费表
*/
@Bean
public Binding syncPendingFreight4OrderGoodsBind() {
return BindingBuilder.bind(syncPendingFreight4OrderGoodsQueue()).to(syncPendingFreight4OrderGoodsExchange())
.with(RabbitKeyConstants.SYNC_PENDING_FREIGHT_FOR_ORDER_GOODS_ROUTING_KEY);
}
/**
* 监听运单同步到挂单运费表
*/
@Bean
public Queue syncPendingFreight4OrderChildQueue() {
return new Queue(RabbitKeyConstants.SYNC_PENDING_FREIGHT_FOR_ORDER_CHILD_QUEUE,
true, false, false);
}
/**
* 监听运单同步到挂单运费表
**/
@Bean
public DirectExchange syncPendingFreight4OrderChildExchange() {
return new DirectExchange(RabbitKeyConstants.SYNC_PENDING_FREIGHT_FOR_ORDER_CHILD_EXCHANGE);
}
/**
* 监听运单同步到挂单运费表
*/
@Bean
public Binding syncPendingFreight4OrderChildBind() {
return BindingBuilder.bind(syncPendingFreight4OrderChildQueue()).to(syncPendingFreight4OrderChildExchange())
.with(RabbitKeyConstants.SYNC_PENDING_FREIGHT_FOR_ORDER_CHILD_ROUTING_KEY);
}
}
......@@ -150,4 +150,54 @@ public class RabbitKeyConstants {
//保存货单调价记录routing_key
public static final String SAVE_ORDER_GOODS_ADJUSTMENT_PRICE_ROUTING_KEY = "clx_performance.save.order.goods.adjustment.price.routing.key";
//订单同步挂单运费表queue
public static final String SYNC_PENDING_FREIGHT_FOR_ORDER_INFO_QUEUE = "clx_performance.sync.pending.freight.for.order.info.queue";
//订单同步挂单运费表exchange
public static final String SYNC_PENDING_FREIGHT_FOR_ORDER_INFO_EXCHANGE = "clx_performance.sync.pending.freight.for.order.info.exchange";
//订单同步挂单运费表routing_key
public static final String SYNC_PENDING_FREIGHT_FOR_ORDER_INFO_ROUTING_KEY = "clx_performance.sync.pending.freight.for.order.info.routing.key";
//内部上报同步挂单运费表queue
public static final String SYNC_PENDING_FREIGHT_FOR_INTERNAL_REPORT_QUEUE = "clx_performance.sync.pending.freight.for.internal.report.queue";
//内部上报同步挂单运费表exchange
public static final String SYNC_PENDING_FREIGHT_FOR_INTERNAL_REPORT_EXCHANGE = "clx_performance.sync.pending.freight.for.internal.report.exchange";
//内部上报同步挂单运费表routing_key
public static final String SYNC_PENDING_FREIGHT_FOR_INTERNAL_REPORT_ROUTING_KEY = "clx_performance.sync.pending.freight.for.internal.report.routing.key";
//货单同步挂单运费表queue
public static final String SYNC_PENDING_FREIGHT_FOR_ORDER_GOODS_QUEUE = "clx_performance.sync.pending.freight.for.order.goods.queue";
//货单同步挂单运费表exchange
public static final String SYNC_PENDING_FREIGHT_FOR_ORDER_GOODS_EXCHANGE = "clx_performance.sync.pending.freight.for.order.goods.exchange";
//货单同步挂单运费表routing_key
public static final String SYNC_PENDING_FREIGHT_FOR_ORDER_GOODS_ROUTING_KEY = "clx_performance.sync.pending.freight.for.order.goods.routing.key";
//货单同步挂单运费表queue
public static final String SYNC_PENDING_FREIGHT_FOR_ORDER_CHILD_QUEUE = "clx_performance.sync.pending.freight.for.order.child.queue";
//货单同步挂单运费表exchange
public static final String SYNC_PENDING_FREIGHT_FOR_ORDER_CHILD_EXCHANGE = "clx_performance.sync.pending.freight.for.order.child.exchange";
//货单同步挂单运费表routing_key
public static final String SYNC_PENDING_FREIGHT_FOR_ORDER_CHILD_ROUTING_KEY = "clx_performance.sync.pending.freight.for.order.child.routing.key";
}
package com.clx.performance.controller.pc;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.clx.performance.param.pc.PagePendingFreightParam;
import com.clx.performance.service.PendingFreightService;
import com.clx.performance.vo.pc.PagePendingFreightVO;
import com.msl.common.base.PageData;
import com.msl.common.convertor.aspect.UnitCovert;
import com.msl.common.result.Result;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletResponse;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @ClassName PendingFreightController
* @Description
* @Author kavin
* @Date 2024/10/21 9:47
* @Version 1.0
*/
@Slf4j
@RestController
@RequestMapping(value="/pc/pendingFreight")
@Validated
@Tag(name = "挂单运费")
@AllArgsConstructor
public class PendingFreightController {
private final PendingFreightService pendingFreightService;
@Operation(summary = "查看挂单运费分页列表", description = "<br>By:刘海泉")
@PostMapping("/pagePendingFreight")
@UnitCovert(param = false)
public Result<PageData<PagePendingFreightVO>> pagePendingFreight(@RequestBody @Validated PagePendingFreightParam param) {
IPage<PagePendingFreightVO> page = pendingFreightService.pagePendingFreight(param);
return Result.page(page.getRecords(), page.getTotal(), page.getPages());
}
@Operation(summary = "导出挂单运费", description = "<br>By:刘海泉")
@PostMapping("/exportPendingFreight")
@UnitCovert(param = false)
public void exportPendingFreight(@RequestBody @Validated PagePendingFreightParam param, HttpServletResponse response) throws Exception {
SXSSFWorkbook workbook = pendingFreightService.exportPendingFreight(param);
response.setHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_OCTET_STREAM_VALUE);
workbook.write(response.getOutputStream());
}
}
......@@ -225,4 +225,6 @@ public interface OrderChildDao extends BaseDao<OrderChildMapper, OrderChild, Int
Long countNotCancelOrderChild(List<String> cancelOrderGoodsNo);
Long queryNoCancelChildByOrderGoodsNo(String orderGoodsNo, Integer code);
List<OrderChild> listNoCancelOrderChild(String orderNo);
}
......@@ -116,4 +116,7 @@ public interface OrderGoodsDao extends BaseDao<OrderGoodsMapper, OrderGoods, Int
void batchCancelOrderGoodsWeight(List<OrderGoodsCancelWeightDTO> cancelOrderGoodsList);
boolean updateExtractWeightAndNeedTruckNum(String orderGoodsNo, BigDecimal extractWeight, Integer needTruckNum);
OrderGoods queryLineNewestPendingFreight(Integer sendAddressId,Integer receiveAddressId);
List<OrderGoods> queryLineAvgPendingFreight(Integer sendAddressId, Integer receiveAddressId,LocalDateTime begin,LocalDateTime end);
}
package com.clx.performance.dao;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.clx.performance.param.pc.PagePendingFreightParam;
import com.msl.common.dao.BaseDao;
import com.clx.performance.mapper.PendingFreightMapper;
import com.clx.performance.model.PendingFreight;
import java.math.BigDecimal;
/**
* @author kavin
* Date 2024-10-17
* Time 19:37
*/
public interface PendingFreightDao extends BaseDao<PendingFreightMapper, PendingFreight, Integer> {
long updateInternalReportData(String orderNo, String name, BigDecimal logisticsFreight);
void updateOrderedAndLoadTruckRate(String orderNo, BigDecimal orderedRate, BigDecimal loadTruckRate);
IPage<PendingFreight> pagePendingFreight(PagePendingFreightParam param);
void updatePendingFreight(String orderNo, BigDecimal pendingFreight, BigDecimal avgPendingFreight);
}
......@@ -741,4 +741,13 @@ public class OrderChildDaoImpl extends BaseDaoImpl<OrderChildMapper, OrderChild,
.lt(ObjectUtil.isNotEmpty(status),OrderChild::getStatus, status)
);
}
@Override
public List<OrderChild> listNoCancelOrderChild(String orderNo) {
return list(lQrWrapper()
.eq(OrderChild :: getOrderNo, orderNo)
.lt(OrderChild :: getStatus,OrderChildEnum.Status.DRIVER_CANCEL.getCode())
);
}
}
......@@ -324,4 +324,26 @@ public class OrderGoodsDaoImpl extends BaseDaoImpl<OrderGoodsMapper, OrderGoods,
.set(OrderGoods :: getNeedTruckNum,needTruckNum)
);
}
@Override
public OrderGoods queryLineNewestPendingFreight(Integer sendAddressId,Integer receiveAddressId) {
LambdaQueryWrapper<OrderGoods> query = new LambdaQueryWrapper<>();
query.eq(OrderGoods :: getSendAddressId,sendAddressId);
query.eq(OrderGoods :: getReceiveAddressId,receiveAddressId);
query.orderByDesc(OrderGoods :: getId);
query.last("limit 1");
return baseMapper.selectOne(query);
}
@Override
public List<OrderGoods> queryLineAvgPendingFreight(Integer sendAddressId, Integer receiveAddressId,
LocalDateTime begin,LocalDateTime end) {
LambdaQueryWrapper<OrderGoods> query = new LambdaQueryWrapper<>();
query.eq(OrderGoods :: getSendAddressId,sendAddressId);
query.eq(OrderGoods :: getReceiveAddressId,receiveAddressId);
query.ge(OrderGoods :: getCreateTime,begin);
query.le(OrderGoods :: getCreateTime,end);
return baseMapper.selectList(query);
}
}
package com.clx.performance.dao.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.clx.performance.dao.PendingFreightDao;
import com.clx.performance.mapper.PendingFreightMapper;
import com.clx.performance.model.PendingFreight;
import com.clx.performance.param.pc.PagePendingFreightParam;
import com.msl.common.dao.impl.BaseDaoImpl;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Repository;
import java.math.BigDecimal;
import java.util.Objects;
/**
* @author kavin
* Date 2024-10-17
* Time 19:37
*/
@Repository
public class PendingFreightDaoImpl extends BaseDaoImpl<PendingFreightMapper, PendingFreight, Integer> implements PendingFreightDao {
@Override
public long updateInternalReportData(String orderNo, String name, BigDecimal logisticsFreight) {
LambdaUpdateWrapper<PendingFreight> update = new LambdaUpdateWrapper<>();
update.set(StringUtils.isNotBlank(name),PendingFreight :: getSeniorLogisticsManagerName,name);
update.set(Objects.nonNull(logisticsFreight),PendingFreight :: getLogisticsFreight,logisticsFreight);
update.eq(PendingFreight :: getOrderNo,orderNo);
return baseMapper.update(update);
}
@Override
public void updateOrderedAndLoadTruckRate(String orderNo, BigDecimal orderedRate, BigDecimal loadTruckRate) {
LambdaUpdateWrapper<PendingFreight> update = new LambdaUpdateWrapper<>();
update.set(PendingFreight :: getOrderedRate,orderedRate);
update.set(PendingFreight :: getLoadTruckRate,loadTruckRate);
update.eq(PendingFreight :: getOrderNo,orderNo);
baseMapper.update(update);
}
@Override
public IPage<PendingFreight> pagePendingFreight(PagePendingFreightParam param) {
LambdaQueryWrapper<PendingFreight> query = new LambdaQueryWrapper<>();
query.orderByDesc(PendingFreight :: getId);
return baseMapper.selectPage(Page.of(param.getPage(),param.getPageSize()),query);
}
@Override
public void updatePendingFreight(String orderNo, BigDecimal pendingFreight, BigDecimal avgPendingFreight) {
LambdaUpdateWrapper<PendingFreight> update = new LambdaUpdateWrapper<>();
update.set(PendingFreight :: getHistoryFreight,pendingFreight);
update.set(PendingFreight :: getHistoryAvgFreight,avgPendingFreight);
update.eq(PendingFreight :: getOrderNo,orderNo);
baseMapper.update(update);
}
}
package com.clx.performance.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Getter;
import lombok.Setter;
import java.math.BigDecimal;
/**
* @ClassName OrderedAndLoadTruckRateDTO
* @Description
* @Author kavin
* @Date 2024/10/18 16:25
* @Version 1.0
*/
@Getter
@Setter
public class OrderedAndLoadTruckRateDTO {
@Schema(description="订单号")
private String orderNo;
@Schema(description="挂单吨数")
private BigDecimal pendingWeight;
@Schema(description="装车吨数")
private BigDecimal loadNet;
@Schema(description="已拉运吨数")
private BigDecimal alreadyTransportWeight;
@Schema(description="接单率")
BigDecimal orderedRate;
@Schema(description="装车率")
BigDecimal loadTruckRate;
}
......@@ -99,6 +99,7 @@ public class OrderChildDtsListener {
log.info("修改:{}",JSON.toJSONString(after));
syncPerformanceProgress(before,after,DtsOperationTypeEnum.UPDATE.getCode());
log.info("修改1, childNo:{}", before.getChildNo());
syncPendingFreight(before,after);
if(OrderChildEnum.SYNC_STATUS_lIST.contains(after.getStatus()) &&
(!Objects.equals(before.getStatus(),after.getStatus()) ||
!Objects.equals(before.getLoadNet(),after.getLoadNet())) ||
......@@ -303,6 +304,24 @@ public class OrderChildDtsListener {
}
}
//同步挂单运费表-----运单部分
public void syncPendingFreight(OrderChild before,OrderChild after){
//状态发生变化,并且是取消
if((!Objects.equals(before.getStatus(),after.getStatus())
&& after.getStatus() > OrderChildEnum.Status.COMPLETE.getCode())
// 装车吨数发生变化
|| Objects.equals(after.getLoadNet(),before.getLoadNet())
){
log.info("开始发送同步挂单运费表消息,订单号:{},运单号:{}", after.getOrderNo(),after.getChildNo());
Message body = MessageBuilder.withBody(JSON.toJSONString(new MqWrapper<>(after)).getBytes()).build();
rabbitTemplate.send(SYNC_PENDING_FREIGHT_FOR_ORDER_CHILD_EXCHANGE,
SYNC_PENDING_FREIGHT_FOR_ORDER_CHILD_ROUTING_KEY, body);
log.info("结束发送同步挂单运费表消息,订单号:{},运单号:{}", after.getOrderNo(),after.getChildNo());
}
}
/**
* 后续逻辑处理
* @param before
......
......@@ -88,6 +88,31 @@ public class OrderGoodsDtsListener {
}
}
//同步挂单运费
public void syncPendingFreight(OrderGoods before,OrderGoods after, Integer updateType) {
boolean isSend = false;
if(Objects.equals(updateType,DtsOperationTypeEnum.INSERT.getCode())){
isSend = true;
}else{
if(!Objects.equals(before.getOrderGoodsStatus(),after.getOrderGoodsStatus())
|| !Objects.equals(before.getAlreadyTransportWeight(),after.getAlreadyTransportWeight())
|| !Objects.equals(before.getExtractWeight(),after.getExtractWeight())
|| !Objects.equals(before.getPendingOrderFreight(),after.getPendingOrderFreight())){
isSend = true;
}
}
if(isSend){
log.info("开始发送同步挂单运费表消息,订单号:{},货单号:{}", after.getOrderNo(),after.getOrderGoodsNo());
Message body = MessageBuilder.withBody(JSON.toJSONString(new MqWrapper<>(after)).getBytes()).build();
rabbitTemplate.send(SYNC_PENDING_FREIGHT_FOR_ORDER_GOODS_EXCHANGE,
SYNC_PENDING_FREIGHT_FOR_ORDER_GOODS_ROUTING_KEY, body);
log.info("结束发送同步挂单运费表消息,订单号:{},货单号:{}", after.getOrderNo(),after.getOrderGoodsNo());
}
}
//保存货单调价记录
public void sendSaveOrderGoodsAdjustmentPriceMessage(OrderGoods before,OrderGoods after, Integer updateType){
boolean isSend = false;
......
package com.clx.performance.listener;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.clx.order.param.mq.SyncPendingFreightInternalReportParam;
import com.clx.performance.common.MqWrapper;
import com.clx.performance.constant.RabbitKeyConstants;
import com.clx.performance.service.PendingFreightService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
/**
* 处理货单取消吨数回填
*/
@Slf4j
@Component
@AllArgsConstructor
public class SyncPendingFreight4InternalReportListener {
private final PendingFreightService pendingFreightService;
@RabbitListener(queues = RabbitKeyConstants.SYNC_PENDING_FREIGHT_FOR_INTERNAL_REPORT_QUEUE)
public void onMessage(Message message) {
try{
log.info("监听到同步挂单运费表---内部上报信息部分,消息内容{}", new String(message.getBody()));
SyncPendingFreightInternalReportParam data = JSON.parseObject(new String(message.getBody()),
new TypeReference<MqWrapper<SyncPendingFreightInternalReportParam>>() {
}).getData();
pendingFreightService.dealPendingFreight4InternalReport(data);
}catch (Exception e){
log.info("监听到同步挂单运费表---内部上报信息部分发生异常,异常原因:{}", ExceptionUtils.getStackTrace(e));
}
}
}
package com.clx.performance.listener;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.clx.performance.common.MqWrapper;
import com.clx.performance.constant.RabbitKeyConstants;
import com.clx.performance.model.OrderChild;
import com.clx.performance.service.PendingFreightService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
/**
* 处理货单取消吨数回填
*/
@Slf4j
@Component
@AllArgsConstructor
public class SyncPendingFreight4OrderChildListener {
private final PendingFreightService pendingFreightService;
@RabbitListener(queues = RabbitKeyConstants.SYNC_PENDING_FREIGHT_FOR_ORDER_GOODS_QUEUE)
public void onMessage(Message message) {
try{
log.info("监听到同步挂单运费表---运单信息部分,消息内容{}", new String(message.getBody()));
OrderChild data = JSON.parseObject(new String(message.getBody()),
new TypeReference<MqWrapper<OrderChild>>() {
}).getData();
pendingFreightService.dealPendingFreight4OrderChild(data.getOrderNo());
}catch (Exception e){
log.info("监听到同步挂单运费表---运单信息部分发生异常,异常原因:{}", ExceptionUtils.getStackTrace(e));
}
}
}
package com.clx.performance.listener;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.clx.performance.common.MqWrapper;
import com.clx.performance.constant.RabbitKeyConstants;
import com.clx.performance.model.OrderGoods;
import com.clx.performance.service.PendingFreightService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
/**
* 处理货单取消吨数回填
*/
@Slf4j
@Component
@AllArgsConstructor
public class SyncPendingFreight4OrderGoodsListener {
private final PendingFreightService pendingFreightService;
@RabbitListener(queues = RabbitKeyConstants.SYNC_PENDING_FREIGHT_FOR_ORDER_GOODS_QUEUE)
public void onMessage(Message message) {
try{
log.info("监听到同步挂单运费表---货单信息部分,消息内容{}", new String(message.getBody()));
OrderGoods data = JSON.parseObject(new String(message.getBody()),
new TypeReference<MqWrapper<OrderGoods>>() {
}).getData();
pendingFreightService.dealPendingFreight4OrderGoods(data);
}catch (Exception e){
log.info("监听到同步挂单运费表---货单信息部分发生异常,异常原因:{}", ExceptionUtils.getStackTrace(e));
}
}
}
package com.clx.performance.listener;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.clx.open.sdk.callback.message.OrderInfoMessage;
import com.clx.performance.common.MqWrapper;
import com.clx.performance.constant.RabbitKeyConstants;
import com.clx.performance.service.PendingFreightService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
/**
* 同步
*/
@Slf4j
@Component
@AllArgsConstructor
public class SyncPendingFreight4OrderInfoListener {
private final PendingFreightService pendingFreightService;
@RabbitListener(queues = RabbitKeyConstants.SYNC_PENDING_FREIGHT_FOR_ORDER_INFO_QUEUE)
public void onMessage(Message message) {
try{
log.info("监听到同步挂单运费表---订单信息部分,消息内容{}", new String(message.getBody()));
OrderInfoMessage data = JSON.parseObject(new String(message.getBody()),
new TypeReference<MqWrapper<OrderInfoMessage>>() {
}).getData();
pendingFreightService.dealPendingFreight4OrderInfo(data);
}catch (Exception e){
log.info("监听到同步挂单运费表---订单信息部分发生异常,异常原因:{}", ExceptionUtils.getStackTrace(e));
}
}
}
package com.clx.performance.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.clx.performance.model.PendingFreight;
/**
* @author kavin
* Date 2024-10-17
* Time 19:37
*/
public interface PendingFreightMapper extends BaseMapper<PendingFreight> {
}
package com.clx.performance.model;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.msl.common.config.KeyColumn;
import com.msl.common.model.HasKey;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.Accessors;
import java.math.BigDecimal;
import java.time.LocalDateTime;
/**
* @author kavin
* Date 2024-10-17
* Time 19:37
*/
@Getter
@Setter
@Accessors(chain = true)
@TableName("pending_freight")
public class PendingFreight implements HasKey<Integer> {
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
@TableField("order_no")
@Schema(description="订单编号")
private String orderNo;
@TableField("order_status")
@Schema(description="订单状态")
private Integer orderStatus;
@TableField("send_address_id")
@Schema(description="发货-地址id")
private Integer sendAddressId;
@TableField("send_address_shorter")
@Schema(description="货源地简称")
private String sendAddressShorter;
@TableField("send_address")
@Schema(description="煤源位置")
private String sendAddress;
@TableField("receive_address_id")
@Schema(description="收货-地址id")
private Integer receiveAddressId;
@TableField("receive_address_shorter")
@Schema(description="目的地简称")
private String receiveAddressShorter;
@TableField("senior_logistics_manager_name")
@Schema(description="高级物流经理姓名数组")
private String seniorLogisticsManagerName;
@TableField("goods_name_id")
@Schema(description="货物名称id")
private Integer goodsNameId;
@TableField("goods_name")
@Schema(description="货物名称")
private String goodsName;
@TableField("goods_type_code")
@Schema(description="热值编码")
private String goodsTypeCode;
@TableField("goods_type_name")
@Schema(description="热值名称")
private String goodsTypeName;
@TableField("send_over_standard")
@Schema(description="是否C类煤源 0 否 1 是")
private Integer sendOverStandard;
@TableField("task_weight")
@Schema(description="任务吨数")
private BigDecimal taskWeight;
@TableField("ordered_rate")
@Schema(description="接单率")
private BigDecimal orderedRate;
@TableField("load_truck_rate")
@Schema(description="装车率")
private BigDecimal loadTruckRate;
@TableField("order_distance")
@Schema(description="重车运距(公里)")
private BigDecimal orderDistance;
@TableField("send_address_expenses")
@Schema(description="煤源地开支")
private String sendAddressExpenses;
@TableField("history_freight")
@Schema(description="历史运费")
private BigDecimal historyFreight;
@TableField("history_avg_freight")
@Schema(description="历史平均运费")
private BigDecimal historyAvgFreight;
@TableField("prediction_freight_price")
@Schema(description="测算运费")
private BigDecimal predictionFreightPrice;
@TableField("logistics_freight")
@Schema(description="物流运费")
private BigDecimal logisticsFreight;
@TableField("create_time")
@Schema(description="创建时间")
private LocalDateTime createTime;
@TableField("modified_time")
@Schema(description="修改时间")
private LocalDateTime modifiedTime;
@Override
@KeyColumn("id")
public Integer gainKey() {
return this.id;
}
}
package com.clx.performance.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.clx.open.sdk.callback.message.OrderInfoMessage;
import com.clx.order.param.mq.SyncPendingFreightInternalReportParam;
import com.clx.performance.model.OrderGoods;
import com.clx.performance.param.pc.PagePendingFreightParam;
import com.clx.performance.vo.pc.PagePendingFreightVO;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
/**
* @author kavin
* Date 2024-10-17
* Time 19:37
*/
public interface PendingFreightService {
void dealPendingFreight4OrderInfo(OrderInfoMessage data);
void dealPendingFreight4InternalReport(SyncPendingFreightInternalReportParam param);
void dealPendingFreight4OrderGoods(OrderGoods orderGoods);
void dealPendingFreight4OrderChild(String orderNo);
IPage<PagePendingFreightVO> pagePendingFreight(PagePendingFreightParam param);
SXSSFWorkbook exportPendingFreight(PagePendingFreightParam param);
}
package com.clx.performance.service.impl;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.clx.open.sdk.callback.message.OrderInfoMessage;
import com.clx.order.param.mq.SyncPendingFreightInternalReportParam;
import com.clx.order.vo.feign.FeignAddressVO;
import com.clx.performance.dao.OrderChildDao;
import com.clx.performance.dao.OrderGoodsDao;
import com.clx.performance.dao.PendingFreightDao;
import com.clx.performance.dto.OrderedAndLoadTruckRateDTO;
import com.clx.performance.dto.gd.GdRouteDTO;
import com.clx.performance.enums.ResultEnum;
import com.clx.performance.extranal.user.AddressService;
import com.clx.performance.model.OrderChild;
import com.clx.performance.model.OrderGoods;
import com.clx.performance.model.PendingFreight;
import com.clx.performance.param.pc.PagePendingFreightParam;
import com.clx.performance.service.PendingFreightService;
import com.clx.performance.service.PerformanceProgressService;
import com.clx.performance.struct.PendingFreightStruct;
import com.clx.performance.utils.excel.ExcelData;
import com.clx.performance.utils.excel.ExcelField;
import com.clx.performance.utils.excel.ExcelSheet;
import com.clx.performance.utils.excel.ExcelUtil;
import com.clx.performance.utils.gd.GdService;
import com.clx.performance.vo.pc.PagePendingFreightVO;
import com.msl.common.base.Optional;
import com.msl.common.exception.ServiceSystemException;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
/**
* @author kavin
* Date 2024-10-17
* Time 19:37
*/
@Service
@Slf4j
@AllArgsConstructor
public class PendingFreightServiceImpl implements PendingFreightService {
private final PendingFreightDao pendingFreightDao;
private final AddressService addressService;
private final GdService gdService;
private final PerformanceProgressService performanceProgressService;
private final OrderGoodsDao orderGoodsDao;
private final OrderChildDao orderChildDao;
private final PendingFreightStruct pendingFreightStruct;
//处理挂单运费订单部分
@Transactional(rollbackFor = Exception.class)
@Override
public void dealPendingFreight4OrderInfo(OrderInfoMessage data) {
Optional<PendingFreight> pendingFreightOptional = pendingFreightDao.getOneByField(PendingFreight::getOrderNo,
data.getOrderNo());
PendingFreight item = new PendingFreight();
item.setOrderStatus(data.getOrderStatus());
item.setSendAddressId(data.getSendAddressId());
item.setSendAddressShorter(data.getSendAddressShorter());
item.setGoodsTypeCode(data.getGoodsTypeCode());
item.setGoodsTypeName(data.getGoodsTypeName());
item.setGoodsNameId(data.getGoodsNameId());
item.setGoodsName(data.getGoodsName());
item.setSendOverStandard(data.getOverWeight());
item.setTaskWeight(data.getTransportWeight());
item.setSendAddressExpenses(data.getSendPayFeeBegin().movePointLeft(2)+"元-"+ data.getSendPayFeeEnd().movePointLeft(2) +"元");
if(pendingFreightOptional.isPresent()){
PendingFreight pendingFreight = pendingFreightOptional.get();
item.setId(pendingFreight.getId());
if(!Objects.equals(pendingFreight.getSendAddressId(),data.getSendAddressId())
|| !Objects.equals(pendingFreight.getReceiveAddressId(),data.getReveiveAddressId())){
//查询收发货地址
Optional<FeignAddressVO> sendAndReceiveAddress = getAddressDetail(data);
FeignAddressVO.Address sendAddress = sendAndReceiveAddress.get().getSendAddress();
FeignAddressVO.Address receiveAddress = sendAndReceiveAddress.get().getReceiveAddress();
item.setSendAddress(addressService.generateAddressDetail(sendAddress.getProvince(),
sendAddress.getCity(),sendAddress.getCounty(),sendAddress.getAddress()));
//计算重车运距
item.setOrderDistance(calcOrderDistance(sendAddress,receiveAddress,data.getOrderNo()));
}
pendingFreightDao.updateEntityByKey(item);
}else{
item.setOrderNo(data.getOrderNo());
//查询收发货地址
Optional<FeignAddressVO> sendAndReceiveAddress = getAddressDetail(data);
FeignAddressVO.Address sendAddress = sendAndReceiveAddress.get().getSendAddress();
FeignAddressVO.Address receiveAddress = sendAndReceiveAddress.get().getReceiveAddress();
item.setSendAddress(addressService.generateAddressDetail(sendAddress.getProvince(),
sendAddress.getCity(),sendAddress.getCounty(),sendAddress.getAddress()));
//计算重车运距
item.setOrderDistance(calcOrderDistance(sendAddress,receiveAddress,data.getOrderNo()));
pendingFreightDao.saveEntity(item);
}
}
//处理挂单运费内部上报数据
@Transactional(rollbackFor = Exception.class)
@Override
public void dealPendingFreight4InternalReport(SyncPendingFreightInternalReportParam param) {
log.info("开始更新挂单运费===内部上报数据,订单号:{} ,物流经理:{} ,物流运费:{} ",param.getOrderNo(),param.getName(),param.getLogisticsFreight());
long count = pendingFreightDao.updateInternalReportData(param.getOrderNo(),param.getName(),param.getLogisticsFreight());
log.info("结束更新挂单运费===内部上报数据,订单号:{} ,更新数量:{} ",param.getOrderNo(),count);
}
//处理挂单运费货单数据
@Transactional(rollbackFor = Exception.class)
@Override
public void dealPendingFreight4OrderGoods(OrderGoods orderGoods) {
String orderNo = orderGoods.getOrderNo();
//计算历史运费和历史平均运费
OrderedAndLoadTruckRateDTO dto = calcOrderedAndLoadTruckRate(orderNo);
//计算线路挂单运费
BigDecimal pendingFreight = this.queryLinePendingFreight(orderGoods.getSendAddressId(),
orderGoods.getReceiveAddressId());
//计算线路平均挂单运费
BigDecimal avgPendingFreight = this.queryLineAvgPendingFreight(orderGoods.getSendAddressId(),
orderGoods.getReceiveAddressId());
pendingFreightDao.updateOrderedAndLoadTruckRate(orderNo,dto.getOrderedRate(),dto.getLoadTruckRate());
pendingFreightDao.updatePendingFreight(orderNo,pendingFreight,avgPendingFreight);
}
//查询该线路最新的历史运费
public BigDecimal queryLinePendingFreight(Integer sendAddressId,Integer receiveAddressId){
OrderGoods orderGoods = orderGoodsDao.queryLineNewestPendingFreight(sendAddressId,receiveAddressId);
return orderGoods.getPendingOrderFreight().movePointLeft(2);
}
//查询该线路最新的历史平均运费
public BigDecimal queryLineAvgPendingFreight(Integer sendAddressId,Integer receiveAddressId){
LocalDateTime now = LocalDateTime.now();
LocalDateTime monthAgo = now.minusMonths(1);
List<OrderGoods> list = orderGoodsDao.queryLineAvgPendingFreight(sendAddressId,receiveAddressId,monthAgo,now);
if(CollectionUtils.isEmpty(list)){
return null;
}
BigDecimal total = BigDecimal.ZERO;
for (OrderGoods orderGoods : list) {
total = total.add(orderGoods.getPendingOrderFreight());
}
return total.movePointLeft(2).divide(new BigDecimal(list.size()),2, RoundingMode.HALF_UP);
}
//处理挂单运费运单数据
@Override
public void dealPendingFreight4OrderChild(String orderNo) {
OrderedAndLoadTruckRateDTO dto = calcOrderedAndLoadTruckRate(orderNo);
pendingFreightDao.updateOrderedAndLoadTruckRate(orderNo,dto.getOrderedRate(),dto.getLoadTruckRate());
}
//计算接单率和装车率
public OrderedAndLoadTruckRateDTO calcOrderedAndLoadTruckRate(String orderNo){
List<OrderGoods> orderGoods = orderGoodsDao.listByField(OrderGoods::getOrderNo, orderNo);
BigDecimal pendingWeight = BigDecimal.ZERO; //挂单量
BigDecimal alreadyTransportWeight = BigDecimal.ZERO; //已拉运吨数
BigDecimal orderedRate; //接单率
BigDecimal loadTruckRate; //装车率
BigDecimal loadNet = BigDecimal.ZERO; //总的装车吨数
for (OrderGoods item : orderGoods) {
alreadyTransportWeight = alreadyTransportWeight.add(item.getAlreadyTransportWeight());
pendingWeight = pendingWeight.add(performanceProgressService.calcPendingWeight(item));
}
//计算接单率
orderedRate = alreadyTransportWeight.divide(pendingWeight,3, RoundingMode.HALF_UP).multiply(new BigDecimal("100"));
//计算装车率
List<OrderChild> childList = orderChildDao.listNoCancelOrderChild(orderNo);
if(CollectionUtils.isNotEmpty(childList)){
for (OrderChild child : childList) {
if(Objects.nonNull(child.getLoadNet())){
loadNet = loadNet.add(child.getLoadNet());
}
}
}
loadTruckRate = loadNet.divide(pendingWeight,3, RoundingMode.HALF_UP).multiply(new BigDecimal("100"));
OrderedAndLoadTruckRateDTO dto = new OrderedAndLoadTruckRateDTO();
dto.setOrderNo(orderNo);
dto.setPendingWeight(pendingWeight);
dto.setAlreadyTransportWeight(alreadyTransportWeight);
dto.setLoadNet(loadNet);
dto.setLoadTruckRate(loadTruckRate);
dto.setOrderedRate(orderedRate);
return dto;
}
public Optional<FeignAddressVO> getAddressDetail(OrderInfoMessage data){
Optional<FeignAddressVO> sendAndReceiveAddress = addressService.getSendAndReceiveAddress(
data.getSendAddressId(), data.getReveiveAddressId());
if (Objects.isNull(sendAndReceiveAddress.get().getSendAddress()) ||
Objects.isNull(sendAndReceiveAddress.get().getReceiveAddress())) {
log.warn("通过发货地址Id:{},收货地址Id:{} 查询对应的地址信息结果:{}",
data.getSendAddressId(),data.getReveiveAddressId(),sendAndReceiveAddress);
throw new ServiceSystemException(ResultEnum.DATA_ERROR,"挂单运费表订单对应的收发货地址信息为空");
}
return sendAndReceiveAddress;
}
public BigDecimal calcOrderDistance(FeignAddressVO.Address sendAddress,FeignAddressVO.Address receiveAddress,String orderNo){
BigDecimal distance = null;
//重车运距(收发货地址距离)
try{
List<GdRouteDTO> route = gdService.getRoute(sendAddress.getLongitude(), sendAddress.getLatitude(),
receiveAddress.getLongitude(), receiveAddress.getLatitude());
if (!route.isEmpty()){
distance = new BigDecimal(route.get(0).getDistance() /1000);
}
}catch (Exception e){
log.warn("订单计算重车运距失败,订单号:{},失败原因:{}",orderNo, ExceptionUtils.getStackTrace(e));
}
return distance;
}
@Override
public IPage<PagePendingFreightVO> pagePendingFreight(PagePendingFreightParam param) {
IPage<PendingFreight> page = pendingFreightDao.pagePendingFreight(param);
List<PagePendingFreightVO> list = pendingFreightStruct.convertList(page.getRecords());
return new Page<PagePendingFreightVO>().setRecords(list).setTotal(page.getTotal()).setPages(page.getPages());
}
@Override
public SXSSFWorkbook exportPendingFreight(PagePendingFreightParam param) {
param.setPage(1);
param.setPageSize(1000000);
IPage<PagePendingFreightVO> page = pagePendingFreight(param);
List<PagePendingFreightVO> list = page.getRecords();
// 组装表头
List<ExcelField> fieldList = new ArrayList<>();
fieldList.add(new ExcelField(0, "序号", "seq", 5000));
fieldList.add(new ExcelField(1, "货源地", "sendAddressShorter", 5000));
fieldList.add(new ExcelField(2, "煤源位置", "sendAddress", 5000));
fieldList.add(new ExcelField(3, "物流经理", "seniorLogisticsManagerName", 5000));
fieldList.add(new ExcelField(4, "货物名称", "goodsName", 5000));
fieldList.add(new ExcelField(5, "热值", "goodsTypeName", 5000));
fieldList.add(new ExcelField(6, "是否C类煤源", "sendOverStandardMsg", 5000));
fieldList.add(new ExcelField(7, "任务吨数(吨)", "taskWeight", 5000));
fieldList.add(new ExcelField(8, "接单率", "orderedRate", 5000));
fieldList.add(new ExcelField(9, "装车率", "loadTruckRate", 5000));
fieldList.add(new ExcelField(10, "重车运距(公里)", "orderDistance", 5000));
fieldList.add(new ExcelField(11, "煤源地开支(元)", "sendAddressExpenses", 5000));
fieldList.add(new ExcelField(12, "历史运费(元)", "historyFreight", 5000));
fieldList.add(new ExcelField(13, "历史平均运费(元)", "historyAvgFreight", 5000));
fieldList.add(new ExcelField(14, "测算运费(元)", "predictionFreightPrice", 5000));
fieldList.add(new ExcelField(15, "物流运费(元)", "logisticsFreight", 5000));
fieldList.add(new ExcelField(16, "挂单运费", "pendingFreight", 5000));
// 组装数据
List<List<ExcelData>> dataList = new ArrayList<>();
for (int i=0; i<list.size(); i++){
List<ExcelData> rowData = new ArrayList<>();
PagePendingFreightVO vo = list.get(i);
rowData.add(new ExcelData(i+1));
rowData.add(new ExcelData(vo.getSendAddressShorter(),"-"));
rowData.add(new ExcelData(vo.getSendAddress(),"-"));
rowData.add(new ExcelData(vo.getSeniorLogisticsManagerName(),"-"));
rowData.add(new ExcelData(vo.getGoodsName(), "-"));
rowData.add(new ExcelData(vo.getGoodsTypeName(), "-"));
rowData.add(new ExcelData(vo.getSendOverStandardMsg(), "-"));
rowData.add(new ExcelData(vo.getTaskWeight(), "-"));
rowData.add(new ExcelData(vo.getOrderedRate(), "-"));
rowData.add(new ExcelData(vo.getLoadTruckRate(), "-"));
rowData.add(new ExcelData(vo.getOrderDistance(), "-"));
rowData.add(new ExcelData(vo.getSendAddressExpenses(), "-"));
rowData.add(new ExcelData(vo.getHistoryFreight(), "-"));
rowData.add(new ExcelData(vo.getHistoryAvgFreight(), "-"));
rowData.add(new ExcelData(vo.getPredictionFreightPrice(), "-"));
rowData.add(new ExcelData(vo.getLogisticsFreight(), "-"));
rowData.add(new ExcelData(""));
dataList.add(rowData);
}
ExcelSheet excelSheet = new ExcelSheet("挂单运费表", "挂单运费表", fieldList, dataList);
//创建excel
return ExcelUtil.create(excelSheet);
}
}
package com.clx.performance.struct;
import com.clx.performance.model.PendingFreight;
import com.clx.performance.vo.pc.PagePendingFreightVO;
import com.msl.common.utils.DateStructUtil;
import com.msl.common.utils.DateUtils;
import org.mapstruct.Mapper;
import java.util.List;
@Mapper(componentModel = "spring", uses = DateStructUtil.class, imports = {DateUtils.class})
public interface PendingFreightStruct {
List<PagePendingFreightVO> convertList(List<PendingFreight> records);
}
package com.clx.performance.param.pc;
import com.msl.common.base.PageParam;
/**
* @ClassName PagePendingFreightParam
* @Description
* @Author kavin
* @Date 2024/10/21 9:50
* @Version 1.0
*/
public class PagePendingFreightParam extends PageParam {
}
package com.clx.performance.vo.pc;
import com.clx.performance.enums.OrderEnum;
import com.msl.common.convertor.type.MoneyOutConvert;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Getter;
import lombok.Setter;
import java.math.BigDecimal;
/**
* @ClassName PagePendingFreightVO
* @Description
* @Author kavin
* @Date 2024/10/21 9:51
* @Version 1.0
*/
@Getter
@Setter
public class PagePendingFreightVO {
private Integer id;
@Schema(description="订单编号")
private String orderNo;
@Schema(description="订单状态")
private Integer orderStatus;
@Schema(description="货源地")
private String sendAddressShorter;
@Schema(description="煤源位置")
private String sendAddress;
@Schema(description="物流经理")
private String seniorLogisticsManagerName;
@Schema(description="货物名称id")
private Integer goodsNameId;
@Schema(description="货物名称")
private String goodsName;
@Schema(description="热值编码")
private String goodsTypeCode;
@Schema(description="热值名称")
private String goodsTypeName;
@Schema(description="是否C类煤源 0 否 1 是")
private Integer sendOverStandard;
public String sendOverStandardMsg;
public String getSendOverStandardMsg(){
return OrderEnum.OverWeight.getNameByCode(sendOverStandard);
}
@Schema(description="任务吨数")
private BigDecimal taskWeight;
@Schema(description="接单率")
private BigDecimal orderedRate;
@Schema(description="装车率")
private BigDecimal loadTruckRate;
@Schema(description="重车运距(公里)")
private BigDecimal orderDistance;
@Schema(description="煤源地开支")
private String sendAddressExpenses;
@Schema(description="历史运费")
@MoneyOutConvert
private BigDecimal historyFreight;
@Schema(description="历史平均运费")
@MoneyOutConvert
private BigDecimal historyAvgFreight;
@Schema(description="测算运费")
@MoneyOutConvert
private BigDecimal predictionFreightPrice;
@Schema(description="物流运费")
@MoneyOutConvert
private BigDecimal logisticsFreight;
@Schema(description="创建时间")
private String createTime;
}
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论