update:bug修改

This commit is contained in:
Damonny 2025-03-02 02:53:02 +08:00
parent 8a67786220
commit 83b6913648
20 changed files with 569 additions and 30 deletions

View File

@ -31,7 +31,8 @@
<dependency>
<groupId>org.springframework.amqp</groupId>
<artifactId>spring-rabbit</artifactId>
<optional>true</optional>
<!-- 按照教程删除-->
<!-- <optional>true</optional>-->
</dependency>
<dependency>
<groupId>org.apache.rocketmq</groupId>

View File

@ -93,5 +93,10 @@
<groupId>io.github.openfeign</groupId>
<artifactId>feign-slf4j</artifactId>
</dependency>
<!-- 消息队列-->
<dependency>
<groupId>cn.iocoder.boot</groupId>
<artifactId>yudao-spring-boot-starter-mq</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -4,6 +4,7 @@ package cn.iocoder.yudao.module.haoka.controller.admin.orderCatch;
import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder;
import cn.iocoder.yudao.module.haoka.controller.admin.orderCatch.po.Message;
import cn.iocoder.yudao.module.haoka.service.orderCatch.OrderCatchService;
import cn.iocoder.yudao.module.haoka.service.orderCatch.OrderMessageProducer;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
@ -24,13 +25,15 @@ public class OrderCatchController {
@Resource
private OrderCatchService orderCatchService;
@Resource
OrderMessageProducer orderMessageProducer;
@PermitAll
@RequestMapping("/catch")
@Operation(summary = "抓取订单")
public String catchOrders(@Valid @RequestBody List<Message> messages) {
// 异步处理订单数据
execCatchOrders(messages);
// execCatchOrders(messages);
orderMessageProducer.sendSmsSendMessage(messages);
// 立即返回推送所需的响应数据
return "{\"code\":0,\"msg\":\"success\"}";
}

View File

@ -0,0 +1,21 @@
package cn.iocoder.yudao.module.haoka.controller.admin.orderCatch.po;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
/**
* 抖音订单mq消息
*/
@Data
public class DouDianOrderMessage implements Serializable {
/**
* 队列名称
*/
public static final String QUEUE = "SEND_DOUDIAN_ORDER_MESSAGE_QUEUE";
/**
* 消息内容
*/
private List<Message> messages;
}

View File

@ -2,7 +2,9 @@ package cn.iocoder.yudao.module.haoka.controller.admin.orderCatch.po;
import com.fasterxml.jackson.annotation.JsonProperty;
public class Message<T> {
import java.io.Serializable;
public class Message<T> implements Serializable {
@JsonProperty("tag")
private String tag;

View File

@ -65,8 +65,8 @@ public class OrdersPageReqVO extends PageParam {
@Schema(description = "激活状态", example = "2")
private String activeStatus;
@Schema(description = "ICCID", example = "3384")
private String iccid;
@Schema(description = "购买号码", example = "3384")
private String planMobile;
@Schema(description = "外部订单编号", example = "3091")
private String realSourceId;

View File

@ -2,6 +2,8 @@ package cn.iocoder.yudao.module.haoka.controller.admin.orders.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.math.BigDecimal;
import java.util.*;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
@ -324,4 +326,14 @@ public class OrdersRespVO {
*/
@Schema(description = "销售归属名称")
private String salesAttributionName;
/*
* 订单金额
*/
@Schema(description = "订单金额")
private BigDecimal orderAmount;
/**
* 支付金额
*/
@Schema(description = "支付金额")
private BigDecimal payAmount;
}

View File

@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.haoka.dal.dataobject.orders;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.math.BigDecimal;
import java.util.*;
import java.time.LocalDateTime;
import java.time.LocalDateTime;
@ -350,5 +351,13 @@ public class OrdersDO extends BaseDO {
* 销售归属名称
*/
private String salesAttributionName;
/*
* 订单金额
*/
private BigDecimal orderAmount;
/**
* 支付金额
*/
private BigDecimal payAmount;
}

View File

@ -36,7 +36,7 @@ public interface OrdersMapper extends BaseMapperX<OrdersDO> {
.betweenIfPresent(OrdersDO::getStatusUpdatedAt, reqVO.getStatusUpdatedAt())
.eqIfPresent(OrdersDO::getRefundStatus, reqVO.getRefundStatus())
.eqIfPresent(OrdersDO::getActiveStatus, reqVO.getActiveStatus())
.eqIfPresent(OrdersDO::getIccid, reqVO.getIccid())
.eqIfPresent(OrdersDO::getPlanMobile, reqVO.getPlanMobile())
.eqIfPresent(OrdersDO::getIsUrgent, reqVO.getIsUrgent())
.eqIfPresent(OrdersDO::getRealSourceId, reqVO.getRealSourceId())
.eqIfPresent(OrdersDO::getAddressMobile, reqVO.getAddressMobile())

View File

@ -12,20 +12,36 @@ import cn.iocoder.yudao.module.haoka.dal.mysql.onsaleproduct.OnSaleProductMapper
import cn.iocoder.yudao.module.haoka.dal.mysql.orders.OrdersMapper;
import cn.iocoder.yudao.module.haoka.service.onsaleproduct.OnSaleProductService;
import cn.iocoder.yudao.module.haoka.service.orders.OrdersService;
import cn.iocoder.yudao.module.haoka.service.ordersynclog.OrderSyncLogService;
import cn.iocoder.yudao.module.haoka.utils.GroupListUtil;
import cn.iocoder.yudao.module.haoka.utils.ConvertUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.doudian.open.api.order_addOrderRemark.OrderAddOrderRemarkRequest;
import com.doudian.open.api.order_addOrderRemark.OrderAddOrderRemarkResponse;
import com.doudian.open.api.order_addOrderRemark.param.OrderAddOrderRemarkParam;
import com.doudian.open.api.order_batchDecrypt.OrderBatchDecryptRequest;
import com.doudian.open.api.order_batchDecrypt.OrderBatchDecryptResponse;
import com.doudian.open.api.order_batchDecrypt.data.DecryptInfosItem;
import com.doudian.open.api.order_batchDecrypt.data.OrderBatchDecryptData;
import com.doudian.open.api.order_batchDecrypt.param.CipherInfosItem;
import com.doudian.open.api.order_batchDecrypt.param.OrderBatchDecryptParam;
import com.doudian.open.api.order_logisticsAdd.OrderLogisticsAddRequest;
import com.doudian.open.api.order_logisticsAdd.OrderLogisticsAddResponse;
import com.doudian.open.api.order_logisticsAdd.param.OrderLogisticsAddParam;
import com.doudian.open.api.order_logisticsCompanyList.OrderLogisticsCompanyListRequest;
import com.doudian.open.api.order_logisticsCompanyList.OrderLogisticsCompanyListResponse;
import com.doudian.open.api.order_logisticsCompanyList.data.DataItem;
import com.doudian.open.api.order_logisticsCompanyList.param.OrderLogisticsCompanyListParam;
import com.doudian.open.api.order_orderDetail.OrderOrderDetailRequest;
import com.doudian.open.api.order_orderDetail.OrderOrderDetailResponse;
import com.doudian.open.api.order_orderDetail.data.OrderOrderDetailData;
import com.doudian.open.api.order_orderDetail.data.ShopOrderDetail;
import com.doudian.open.api.order_orderDetail.param.OrderOrderDetailParam;
import com.doudian.open.api.order_queryLogisticsCompanyList.OrderQueryLogisticsCompanyListRequest;
import com.doudian.open.api.order_queryLogisticsCompanyList.OrderQueryLogisticsCompanyListResponse;
import com.doudian.open.api.order_queryLogisticsCompanyList.param.OrderQueryLogisticsCompanyListParam;
import com.doudian.open.api.order_review.OrderReviewRequest;
import com.doudian.open.api.order_review.OrderReviewResponse;
import com.doudian.open.api.order_review.param.OrderReviewParam;
import com.doudian.open.api.order_searchList.OrderSearchListRequest;
import com.doudian.open.api.order_searchList.OrderSearchListResponse;
import com.doudian.open.api.order_searchList.data.*;
@ -49,6 +65,9 @@ import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
@ -107,6 +126,7 @@ public class DouDianOrderCatchServiceImpl implements OrderCatchService {
if(CollectionUtil.isNotEmpty(ordersDOS)){
OrdersDO ordersDO = ordersDOS.get(0);
ordersDO.setRefundStatus("200");
ordersDO.setStatusUpdatedAt(LocalDateTime.now());
ordersMapper.updateById(ordersDO);
}
} else if("201".equals(tag)) {
@ -118,6 +138,7 @@ public class DouDianOrderCatchServiceImpl implements OrderCatchService {
if(CollectionUtil.isNotEmpty(ordersDOS)){
OrdersDO ordersDO = ordersDOS.get(0);
ordersDO.setRefundStatus("300");
ordersDO.setStatusUpdatedAt(LocalDateTime.now());
ordersMapper.updateById(ordersDO);
}
} else if("202".equals(tag)) {
@ -129,6 +150,7 @@ public class DouDianOrderCatchServiceImpl implements OrderCatchService {
if(CollectionUtil.isNotEmpty(ordersDOS)){
OrdersDO ordersDO = ordersDOS.get(0);
ordersDO.setRefundStatus("300");
ordersDO.setStatusUpdatedAt(LocalDateTime.now());
ordersMapper.updateById(ordersDO);
}
} else if("101".equals(tag)) {
@ -149,6 +171,7 @@ public class DouDianOrderCatchServiceImpl implements OrderCatchService {
if(CollectionUtil.isNotEmpty(ordersDOS)){
OrdersDO ordersDO = ordersDOS.get(0);
ordersDO.setRefundStatus("300");
ordersDO.setStatusUpdatedAt(LocalDateTime.now());
ordersMapper.updateById(ordersDO);
}
} else if("110".equals(tag)) {
@ -179,6 +202,9 @@ public class DouDianOrderCatchServiceImpl implements OrderCatchService {
// 店铺信息
Long shopId = order.getShopId();
String shopName = order.getShopName();
//下单时间信息
Long createTime = order.getCreateTime();
Long updateTime = order.getUpdateTime();
// 物流信息
List<com.doudian.open.api.order_orderDetail.data.LogisticsInfoItem> logisticsInfo = order.getLogisticsInfo();
/**
@ -242,6 +268,7 @@ public class DouDianOrderCatchServiceImpl implements OrderCatchService {
ordersDO.setSuperiorProductConfigId(onSaleProductPreOrder.getSuperiorProductConfigRespVO().getId());
ordersDO.setSuperiorApiId(onSaleProductPreOrder.getSuperiorApiRespVO().getId());
ordersDO.setProductSku(onSaleProductPreOrder.getParentProduct().getSku());
ordersDO.setSupplierProductName(onSaleProductDO.getName());
}
}
// 在售商品
@ -277,8 +304,6 @@ public class DouDianOrderCatchServiceImpl implements OrderCatchService {
}
ordersDO.setRefundStatus(String.valueOf(HaokaOrderRefundStatus));
// 获取计划手机号
String productName = skuOrderListItem.getProductName();
ordersDO.setSupplierProductName(productName);
for (com.doudian.open.api.order_orderDetail.data.SpecItem specItem : skuOrderListItem.getSpec()) {
String value = specItem.getValue();
String planMobile = getPlanMobile(value);
@ -292,6 +317,8 @@ public class DouDianOrderCatchServiceImpl implements OrderCatchService {
// 更新订单
OrdersDO ordersDO1 = ordersDOS.get(0);
ordersDO.setId(ordersDO1.getId());
// 时间戳转成时间
ordersDO.setStatusUpdatedAt(ConvertUtil.timestampToLocalDateTime(updateTime));
ordersMapper.updateById(ordersDO);
}else {
// 新增订单
@ -327,6 +354,18 @@ public class DouDianOrderCatchServiceImpl implements OrderCatchService {
// 详细地址
// ordersDO.setAddress(detail);
ordersDO.setEncryptAddress(encryptDetail);
// 取时间
ordersDO.setOrderedAt(ConvertUtil.timestampToLocalDateTime(createTime));
ordersDO.setStatusUpdatedAt(ConvertUtil.timestampToLocalDateTime(updateTime));
// 取价格
Long orderAmount = skuOrderListItem.getOrderAmount();
Long payAmount = skuOrderListItem.getPayAmount();
BigDecimal orderAmount1 = ConvertUtil.convertFenToYuan(orderAmount);
BigDecimal payAmount1 = ConvertUtil.convertFenToYuan(payAmount);
ordersDO.setOrderAmount(orderAmount1);
ordersDO.setPayAmount(payAmount1);
// 渠道 抖音
ordersDO.setSource(SYNC_TYPE);
orderList.add(ordersDO);
}
@ -339,7 +378,12 @@ public class DouDianOrderCatchServiceImpl implements OrderCatchService {
for (OrdersDO ordersDO : orderList) {
OrdersSaveReqVO ordersSaveReqVO = new OrdersSaveReqVO();
BeanUtils.copyProperties(ordersDO,ordersSaveReqVO);
ordersSaveReqVO.setSellerMemo("《已抓单》");
ordersService.createOrders(ordersSaveReqVO);
OrderAddOrderRemarkParam param = new OrderAddOrderRemarkParam();
param.setOrderId(ordersDO.getUpstreamOrderId());
param.setRemark("《已抓单》");
addOrderRemark(param);
}
// ordersMapper.insertBatch(orderList);
@ -368,6 +412,8 @@ public class DouDianOrderCatchServiceImpl implements OrderCatchService {
// String orderId = order.getOrderId();
// 买家备注
String buyerWords = order.getBuyerWords();
Long createTime = order.getCreateTime();
Long updateTime = order.getUpdateTime();
// 店铺id
Long shopId = order.getShopId();
// 店铺名称
@ -422,6 +468,7 @@ public class DouDianOrderCatchServiceImpl implements OrderCatchService {
ordersDO.setSuperiorProductConfigId(onSaleProductPreOrder.getSuperiorProductConfigRespVO().getId());
ordersDO.setSuperiorApiId(onSaleProductPreOrder.getSuperiorApiRespVO().getId());
ordersDO.setProductSku(onSaleProductPreOrder.getParentProduct().getSku());
ordersDO.setSupplierProductName(onSaleProductDO.getName());
}
}
// 在售商品
@ -457,8 +504,6 @@ public class DouDianOrderCatchServiceImpl implements OrderCatchService {
ordersDO.setRefundStatus(String.valueOf(HaokaOrderRefundStatus));
ordersDO.setStatusName(skuOrderListItem.getOrderStatusDesc());
// 获取计划手机号
String productName = skuOrderListItem.getProductName();
ordersDO.setSupplierProductName(productName);
for (SpecItem specItem : skuOrderListItem.getSpec()) {
String value = specItem.getValue();
String planMobile = getPlanMobile(value);
@ -472,6 +517,7 @@ public class DouDianOrderCatchServiceImpl implements OrderCatchService {
// 更新订单
OrdersDO ordersDO1 = ordersDOS.get(0);
ordersDO.setId(ordersDO1.getId());
ordersDO.setStatusUpdatedAt(LocalDateTime.now());
ordersMapper.updateById(ordersDO);
}else {
// 新增订单
@ -506,6 +552,18 @@ public class DouDianOrderCatchServiceImpl implements OrderCatchService {
// 详细地址
// ordersDO.setAddress(detail);
ordersDO.setEncryptAddress(encryptDetail);
// 取时间
ordersDO.setOrderedAt(ConvertUtil.timestampToLocalDateTime(createTime));
ordersDO.setStatusUpdatedAt(ConvertUtil.timestampToLocalDateTime(updateTime));
// 取价格
Long orderAmount = skuOrderListItem.getOrderAmount();
Long payAmount = skuOrderListItem.getPayAmount();
BigDecimal orderAmount1 = ConvertUtil.convertFenToYuan(orderAmount);
BigDecimal payAmount1 = ConvertUtil.convertFenToYuan(payAmount);
ordersDO.setOrderAmount(orderAmount1);
ordersDO.setPayAmount(payAmount1);
// 渠道 抖音
ordersDO.setSource(SYNC_TYPE);
orderList.add(ordersDO);
}
@ -520,7 +578,12 @@ public class DouDianOrderCatchServiceImpl implements OrderCatchService {
for (OrdersDO ordersDO : orderList) {
OrdersSaveReqVO ordersSaveReqVO = new OrdersSaveReqVO();
BeanUtils.copyProperties(ordersDO,ordersSaveReqVO);
ordersSaveReqVO.setSellerMemo("《已抓单》");
ordersService.createOrders(ordersSaveReqVO);
OrderAddOrderRemarkParam param = new OrderAddOrderRemarkParam();
param.setOrderId(ordersDO.getUpstreamOrderId());
param.setRemark("《已抓单》");
addOrderRemark(param);
}
// ordersMapper.insertBatch(orderList);
}
@ -692,5 +755,95 @@ public class DouDianOrderCatchServiceImpl implements OrderCatchService {
System.out.println(response);
}
/**
* 给订单返回备注
*/
public void addOrderRemark(OrderAddOrderRemarkParam param){
OrderAddOrderRemarkRequest request = new OrderAddOrderRemarkRequest();
// OrderAddOrderRemarkParam param = request.getParam();
// param.setOrderId("6496679971677798670");
// param.setRemark("这是具体的备注内容");
// param.setIsAddStar("true");
// param.setStar("2");
request.setParam(param);
GlobalConfig.initAppKey(SYNC_APP_KEY);
GlobalConfig.initAppSecret(SYNC_APP_SECRET);
//入参为code
AccessToken accessToken= AccessTokenBuilder.build(SYNC_SHOP_ID);
OrderAddOrderRemarkResponse response = request.execute(accessToken);
if("10000".equals(response.getCode())){
// 加入备注成功
log.error("加入备注成功,{}",response.getMsg());
}else {
// 加入备注失败
log.error("加入备注失败,{}",response.getMsg());
}
}
/**
* 订单审核
* @param rejectCode
* @param objectId
*/
public void reviewOrder(Long rejectCode,String objectId){
try {
OrderReviewRequest request = new OrderReviewRequest();
OrderReviewParam param = request.getParam();
param.setTaskType(3001L);
param.setRejectCode(rejectCode);
param.setObjectId(objectId);
request.setParam(param);
GlobalConfig.initAppKey(SYNC_APP_KEY);
GlobalConfig.initAppSecret(SYNC_APP_SECRET);
//入参为code
AccessToken accessToken= AccessTokenBuilder.build(SYNC_SHOP_ID);
OrderReviewResponse response = request.execute(accessToken);
} catch (Exception e) {
log.error("订单审核失败,{}",e.getMessage());
}
}
/**
*获取快递公司列表
*/
public static List<DataItem> logisticsCompanyList(){
OrderLogisticsCompanyListRequest request = new OrderLogisticsCompanyListRequest();
GlobalConfig.initAppKey(SYNC_APP_KEY);
GlobalConfig.initAppSecret(SYNC_APP_SECRET);
//入参为code
AccessToken accessToken= AccessTokenBuilder.build(SYNC_SHOP_ID);
OrderLogisticsCompanyListResponse response = request.execute(accessToken);
String code = response.getCode();
if("10000".equals(code)){
return response.getData();
}
return null;
}
/**
* 订单发货
* @param OrderId 订单id
* @param company 快递公司
* @param companyCode 快递公司编码
* @param logisticsCode 物流单号
*/
public void logisticsAdd(String OrderId,String company,String companyCode,String logisticsCode){
try {
OrderLogisticsAddRequest request = new OrderLogisticsAddRequest();
OrderLogisticsAddParam param = request.getParam();
param.setOrderId(OrderId);
param.setCompany(company);
param.setCompanyCode(companyCode);
param.setLogisticsCode(logisticsCode);
param.setIsRefundReject(false);
param.setIsRejectRefund(false);
GlobalConfig.initAppKey(SYNC_APP_KEY);
GlobalConfig.initAppSecret(SYNC_APP_SECRET);
//入参为code
AccessToken accessToken= AccessTokenBuilder.build(SYNC_SHOP_ID);
OrderLogisticsAddResponse response = request.execute(accessToken);
} catch (Exception e) {
log.error("订单发货失败,{}",e.getMessage());
}
}
}

View File

@ -0,0 +1,41 @@
package cn.iocoder.yudao.module.haoka.service.orderCatch;
import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder;
import cn.iocoder.yudao.module.haoka.controller.admin.orderCatch.po.DouDianOrderMessage;
import com.doudian.open.utils.JsonUtil;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.support.AmqpHeaders;
import org.springframework.messaging.handler.annotation.Header;
import org.springframework.stereotype.Component;
import com.rabbitmq.client.Channel;
@Component
@RabbitListener(queuesToDeclare = { @Queue(value = DouDianOrderMessage.QUEUE,durable = "true", autoDelete = "false") }, ackMode = "MANUAL")
@Slf4j
public class OrderMessageConsumer {
@Resource
private OrderCatchService orderCatchService;
@RabbitListener(queuesToDeclare = { @Queue(value = DouDianOrderMessage.QUEUE,durable = "true", autoDelete = "false") }, ackMode = "MANUAL")
public void onMessage(DouDianOrderMessage message, Channel channel, @Header(AmqpHeaders.DELIVERY_TAG) long deliveryTag) {
try {
log.info("[onMessage][消息内容({})]", JsonUtil.toJson(message));
TenantContextHolder.setTenantId(162L);
orderCatchService.catchOrders(message.getMessages());
// 手动确认消息
channel.basicAck(deliveryTag, false);
} catch (Exception e) {
try {
// 处理失败拒绝消息
channel.basicNack(deliveryTag, false, true);
} catch (Exception ex) {
log.error("消息确认失败", ex);
}
log.error("消息处理失败", e);
}
}
}

View File

@ -0,0 +1,32 @@
package cn.iocoder.yudao.module.haoka.service.orderCatch;
import cn.iocoder.yudao.module.haoka.controller.admin.orderCatch.po.DouDianOrderMessage;
import cn.iocoder.yudao.module.haoka.controller.admin.orderCatch.po.Message;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.UUID;
@Slf4j
@Component
public class OrderMessageProducer {
@Resource
private RabbitTemplate rabbitTemplate;
/**
* 发送 {@link DouDianOrderMessage} 消息
*
* @param messages 消息内容
*/
public void sendSmsSendMessage(List<Message> messages) {
DouDianOrderMessage message = new DouDianOrderMessage();
message.setMessages(messages);
// 为消息添加唯一ID
CorrelationData correlationData = new CorrelationData(UUID.randomUUID().toString());
rabbitTemplate.convertAndSend(DouDianOrderMessage.QUEUE, message, correlationData);
}
}

View File

@ -3,29 +3,37 @@ package cn.iocoder.yudao.module.haoka.service.orders;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.iocoder.yudao.module.haoka.api.ApiFrom;
import cn.iocoder.yudao.module.haoka.api.liantong.util.StringUtils;
import cn.iocoder.yudao.module.haoka.controller.admin.onsaleproduct.vo.OnSaleProductPreOrderRespVO;
import cn.iocoder.yudao.module.haoka.controller.admin.orderoperatelog.vo.OrderOperateLogSaveReqVO;
import cn.iocoder.yudao.module.haoka.controller.admin.product.vo.HaoKaProductRespVO;
import cn.iocoder.yudao.module.haoka.controller.admin.product.vo.ProductLimitAreaRespVO;
import cn.iocoder.yudao.module.haoka.controller.admin.product.vo.ProductLimitCardRespVO;
import cn.iocoder.yudao.module.haoka.controller.admin.product.vo.ProductLimitRespVO;
import cn.iocoder.yudao.module.haoka.dal.dataobject.blacklist.BlackListDO;
import cn.iocoder.yudao.module.haoka.service.api.models.ApiDealResp;
import cn.iocoder.yudao.module.haoka.service.api.ApiDealStrategyService;
import cn.iocoder.yudao.module.haoka.service.api.models.OrderApiCreateParam;
import cn.iocoder.yudao.module.haoka.service.api.models.OrderApiCreateResp;
import cn.iocoder.yudao.module.haoka.service.blacklist.BlackListService;
import cn.iocoder.yudao.module.haoka.service.onsaleproduct.OnSaleProductService;
import cn.iocoder.yudao.module.haoka.service.orderCatch.DouDianOrderCatchServiceImpl;
import cn.iocoder.yudao.module.haoka.service.orderoperatelog.OrderOperateLogService;
import cn.iocoder.yudao.module.haoka.service.product.ProductLimitService;
import cn.iocoder.yudao.module.haoka.service.smstask.SmsTaskService;
import cn.iocoder.yudao.module.haoka.utils.IdCardAgeCalculator;
import cn.iocoder.yudao.module.haoka.utils.SnowflakeId;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.doudian.open.api.order_addOrderRemark.param.OrderAddOrderRemarkParam;
import com.google.common.collect.Lists;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import jakarta.annotation.Resource;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionSynchronizationAdapter;
import org.springframework.transaction.support.TransactionSynchronizationManager;
import org.springframework.validation.annotation.Validated;
import cn.iocoder.yudao.module.haoka.controller.admin.orders.vo.*;
@ -37,6 +45,8 @@ import cn.iocoder.yudao.module.haoka.dal.mysql.orders.OrdersMapper;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
@ -66,6 +76,9 @@ public class OrdersServiceImpl extends ServiceImpl<OrdersMapper, OrdersDO> imple
@Resource
private OrderOperateLogService orderOperateLogService;
@Resource
private BlackListService blackListService;
/**
* 重新提交订单
*
@ -97,9 +110,14 @@ public class OrdersServiceImpl extends ServiceImpl<OrdersMapper, OrdersDO> imple
logSaveReqVO.setMsgType("0");
logSaveReqVO.setMsgSource("0");
orderOperateLogService.createOrderOperateLog(logSaveReqVO);
return createOrder(ordersDO);
return createOrderToOperators(ordersDO);
}
/**
* 在号卡系统创建订单
* @param createReqVO 创建信息
* @return
*/
// 19547688 -> 电信 19547688 湖南电信号码+号码ID
@Override
@ -139,10 +157,35 @@ public class OrdersServiceImpl extends ServiceImpl<OrdersMapper, OrdersDO> imple
ordersDO.getAddressMobile(),
ordersDO
);
// 异步判断是否自动提交审核订单
TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() {
@Override
public void afterCommit() {
//异步操作
asyncSubmitAuditOrders(ordersDO);
}
});
// 返回
return orders.getId();
}
/**
* 异步判断是否自动提交审核订单
* @param ordersDO
*/
@Async
public void asyncSubmitAuditOrders(OrdersDO ordersDO){
// 是否自动生产
Integer autoType = ordersDO.getAutoType();
if(2 == autoType){
// 自动生产 调用提交初审
OrdersSaveReqVO ordersSaveReqVO = new OrdersSaveReqVO();
ordersSaveReqVO.setId(ordersDO.getId());
ordersSaveReqVO.setStatus(120L);
this.updateOrders(ordersSaveReqVO);
}
}
@Override
public void updateOrders(OrdersSaveReqVO updateReqVO) {
// 校验存在
@ -152,7 +195,11 @@ public class OrdersServiceImpl extends ServiceImpl<OrdersMapper, OrdersDO> imple
throw exception(ORDERS_NOT_EXISTS);
}
OrdersDO updateObj = BeanUtils.toBean(updateReqVO, OrdersDO.class);
if ("120".equals(String.valueOf(updateReqVO.getStatus()))) {
// 是否审核通过
boolean canAudit = true;
// 是否提交初审
boolean submit = "120".equals(String.valueOf(updateReqVO.getStatus()));
if (submit) {
// 提交初审时判断限制条件
OnSaleProductPreOrderRespVO onSaleProductPreOrder = onSaleProductService.getOnSaleProductPreOrder(oldOrderDo.getOnSaleProductId());
ProductLimitRespVO productLimit = productLimitService.getProductLimit(onSaleProductPreOrder.getParentProduct().getHaokaProductLimitId());
@ -174,6 +221,9 @@ public class OrdersServiceImpl extends ServiceImpl<OrdersMapper, OrdersDO> imple
logSaveReqVO.setMsgSource("0");
orderOperateLogService.createOrderOperateLog(logSaveReqVO);
updateObj.setStatus(-451L);
updateObj.setReason(oldOrderDo.getReason() + "\n"+ "提交初审:年龄限制校验不通过");
// 初审不通过
canAudit = false;
}
List<ProductLimitCardRespVO> productLimitCardRespVO = productLimit.getProductLimitCardRespVO();
if (ObjectUtil.isNotEmpty(productLimitCardRespVO)) {
@ -188,6 +238,9 @@ public class OrdersServiceImpl extends ServiceImpl<OrdersMapper, OrdersDO> imple
logSaveReqVO.setMsgSource("0");
orderOperateLogService.createOrderOperateLog(logSaveReqVO);
updateObj.setStatus(-451L);
// 初审不通过
updateObj.setReason(oldOrderDo.getReason() + "\n"+ "提交初审:身份证号码限制校验不通过");
canAudit = false;
break;
}
}
@ -213,6 +266,9 @@ public class OrdersServiceImpl extends ServiceImpl<OrdersMapper, OrdersDO> imple
logSaveReqVO.setMsgType("1");
logSaveReqVO.setMsgSource("0");
orderOperateLogService.createOrderOperateLog(logSaveReqVO);
// 初审不通过
updateObj.setReason(oldOrderDo.getReason() + "\n"+ "提交初审:敏感地区待审核");
canAudit = false;
}
List<String> notAllowedAreaCode = productLimitAreaVos
@ -229,13 +285,73 @@ public class OrdersServiceImpl extends ServiceImpl<OrdersMapper, OrdersDO> imple
logSaveReqVO.setMsgType("1");
logSaveReqVO.setMsgSource("0");
orderOperateLogService.createOrderOperateLog(logSaveReqVO);
// 初审不通过
updateObj.setReason(oldOrderDo.getReason() + "\n"+ "提交初审:敏感地区待审核");
canAudit = false;
}
}
// 黑名单判断
List<BlackListDO> list = blackListService.list();
boolean blacklisted = isBlacklisted(list, oldOrderDo.getAddressMobile(), idCardNum);
if(blacklisted){
updateObj.setStatus(-451L);
OrderOperateLogSaveReqVO logSaveReqVO = new OrderOperateLogSaveReqVO();
logSaveReqVO.setOrderId(updateObj.getId());
logSaveReqVO.setMsg("提交初审:该订单身份证号码或手机号在系统黑名单中");
logSaveReqVO.setMsgType("1");
logSaveReqVO.setMsgSource("0");
orderOperateLogService.createOrderOperateLog(logSaveReqVO);
// 初审不通过
updateObj.setReason(oldOrderDo.getReason() + "\n"+ "提交初审:该订单身份证号码或手机号在系统黑名单中");
canAudit = false;
}
}
this.updateOrderById(updateObj);
// 异步处理 审核成功是否自动进单
Integer autoType = oldOrderDo.getAutoType();
// 联合条件 自动生产 && 审核通过 && 提交初审
if(2 == autoType && canAudit && submit){
TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() {
@Override
public void afterCommit() {
//异步操作
OrdersSaveReqVO ordersSaveReqVO = new OrdersSaveReqVO();
ordersSaveReqVO.setId(updateObj.getId());
auditOrders(ordersSaveReqVO);
}
});
}
}
/**
* 判断手机号和身份证是否在黑名单中
* @param list
* @param phoneNumber
* @param idcard
* @return
*/
public static boolean isBlacklisted(List<BlackListDO> list, String phoneNumber, String idcard) {
if(CollectionUtil.isEmpty(list)){
return false;
}
Set<String> phoneSet = list.stream()
.map(BlackListDO::getAddressPhone)
.filter(Objects::nonNull)
.collect(Collectors.toSet());
Set<String> idcardSet = list.stream()
.map(BlackListDO::getPersonIdCard)
.filter(Objects::nonNull)
.collect(Collectors.toSet());
boolean isPhoneBlacklisted = phoneSet.contains(phoneNumber);
boolean isIdcardBlacklisted = idcardSet.contains(idcard);
// 如果手机号或身份证号在黑名单中返回 true
return isPhoneBlacklisted || isIdcardBlacklisted;
}
private void updateOrderById(OrdersDO updateObj){
OrdersDO oldOrderDo = ordersMapper.selectById(updateObj.getId());
@ -248,6 +364,30 @@ public class OrdersServiceImpl extends ServiceImpl<OrdersMapper, OrdersDO> imple
updateObj.setSuperiorProductConfigId(oldOrderDo.getSuperiorProductConfigId());
updateObj.setSuperiorApiId(oldOrderDo.getSuperiorApiId());
ordersMapper.updateById(updateObj);
// 抖音订单判断备注更新
if("2".equals(oldOrderDo.getSource())){
String sellerMemo = oldOrderDo.getSellerMemo();
String sellerMemo1 = updateObj.getSellerMemo();
if(StringUtils.isNotBlank(sellerMemo) && StringUtils.isNotBlank(sellerMemo1) && !sellerMemo.equals(sellerMemo1)){
OrderAddOrderRemarkParam param = new OrderAddOrderRemarkParam();
param.setOrderId(oldOrderDo.getUpstreamOrderId());
param.setRemark(sellerMemo1);
Long flag = updateObj.getFlag();
if(null != flag){
param.setIsAddStar("true");
param.setStar(String.valueOf(flag));
}
DouDianOrderCatchServiceImpl douDianOrderCatchService = new DouDianOrderCatchServiceImpl();
douDianOrderCatchService.addOrderRemark(param);
}
// 抖音判断发货
String trackingNumber = updateObj.getTrackingNumber();
if(StringUtils.isNotBlank(trackingNumber)){
Long trackingCompanyId = updateObj.getTrackingCompanyId();
DouDianOrderCatchServiceImpl douDianOrderCatchService = new DouDianOrderCatchServiceImpl();
douDianOrderCatchService.logisticsAdd(updateObj.getRealSourceId(),"","",trackingNumber);
}
}
// 状态变化发送短信提醒
if (updateObj.getStatus() != null && updateObj.getStatus().equals(oldOrderDo.getStatus())) {
@ -291,7 +431,7 @@ public class OrdersServiceImpl extends ServiceImpl<OrdersMapper, OrdersDO> imple
logSaveReqVO.setMsgType("0");
logSaveReqVO.setMsgSource("1");
orderOperateLogService.createOrderOperateLog(logSaveReqVO);
createOrder(updateObj);
createOrderToOperators(updateObj);
} else {
// 手动生产
updateObj.setStatus(450L);
@ -299,8 +439,20 @@ public class OrdersServiceImpl extends ServiceImpl<OrdersMapper, OrdersDO> imple
}
}
// 如果是抖音订单 则需要调用抖音接口 返回审核结果
String source = ordersOld.getSource();
if("2".equals(source)){
if(status != null && status == 450L){
//审核通过
DouDianOrderCatchServiceImpl douDianOrderCatchService = new DouDianOrderCatchServiceImpl();
douDianOrderCatchService.reviewOrder(0L,updateObj.getRealSourceId());
}
if(status != null && status == -450L){
//审核不通过
DouDianOrderCatchServiceImpl douDianOrderCatchService = new DouDianOrderCatchServiceImpl();
douDianOrderCatchService.reviewOrder(200005L,updateObj.getRealSourceId());
}
}
// 状态变化发送短信提醒
if (updateObj.getStatus() != null && !updateObj.getStatus().equals(ordersOld.getStatus())) {
smsTaskService.sendSMS(
@ -325,7 +477,7 @@ public class OrdersServiceImpl extends ServiceImpl<OrdersMapper, OrdersDO> imple
public void submitOrders(OrdersSaveReqVO updateReqVO) {
// OrdersDO updateObj = BeanUtils.toBean(updateReqVO, OrdersDO.class);
OrdersDO ordersDO = ordersMapper.selectById(updateReqVO.getId());
createOrder(ordersDO);
createOrderToOperators(ordersDO);
}
@Override
@ -354,11 +506,11 @@ public class OrdersServiceImpl extends ServiceImpl<OrdersMapper, OrdersDO> imple
}
/**
* 调用运营商产生订单
* 调用运营商产生订单(在运营商侧创建订单)
*
* @param ordersDO
*/
private OrdersDO createOrder(OrdersDO ordersDO) {
private OrdersDO createOrderToOperators(OrdersDO ordersDO) {
// 向上游提交订单
OrderApiCreateParam param = new OrderApiCreateParam();
BeanUtils.copyProperties(ordersDO, param);

View File

@ -0,0 +1,34 @@
package cn.iocoder.yudao.module.haoka.utils;
import java.math.BigDecimal;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
/**
* 时间戳转时间工具类
* @author xiongxiong
*/
public class ConvertUtil {
public static LocalDateTime timestampToLocalDateTime(Long timestampInSeconds) {
// 转换为 LocalDateTime指定时区
return timestampToLocalDateTimeByZoneId(timestampInSeconds, ZoneId.of("Asia/Shanghai"));
}
public static LocalDateTime timestampToLocalDateTimeByZoneId(Long timestampInSeconds, ZoneId zoneId) {
// 将时间戳从秒转换为毫秒
Long timestampInMilliseconds = timestampInSeconds * 1000;
// 将时间戳转换为 Instant
Instant instant = Instant.ofEpochMilli(timestampInMilliseconds);
// 转换为 LocalDateTime指定时区
return instant.atZone(zoneId).toLocalDateTime();
}
public static BigDecimal convertFenToYuan(long amountInFen) {
// 使用 BigDecimal 确保精度
return new BigDecimal(amountInFen).divide(new BigDecimal(100));
}
}

View File

@ -5,6 +5,7 @@ import cn.iocoder.yudao.module.haoka.controller.admin.orderCatch.po.Message;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.doudian.open.api.order_logisticsCompanyList.data.DataItem;
import com.doudian.open.api.order_orderDetail.data.OrderOrderDetailData;
import com.doudian.open.gson.Gson;
import com.doudian.open.msg.refund_RefundCreated.param.RefundRefundCreatedParam;
@ -51,5 +52,15 @@ String orderString = "[{\"tag\":\"xxx\",\"msgId\":\"0443477XXXXXXX48874::xxx:161
}
}
@Test
public void logisticsCompanyList() {
// 创建 DouDianOrderCatchServiceImpl 对象
DouDianOrderCatchServiceImpl service = new DouDianOrderCatchServiceImpl();
List<DataItem> dataItems = orderCatchService.logisticsCompanyList();
System.out.println(dataItems);
}
}

View File

@ -194,7 +194,6 @@ public class OrdersServiceImplTest extends BaseDbUnitTest {
reqVO.setStatusUpdatedAt(buildBetweenTime(2023, 2, 1, 2023, 2, 28));
reqVO.setRefundStatus(null);
reqVO.setActiveStatus(null);
reqVO.setIccid(null);
reqVO.setRealSourceId(null);
reqVO.setAddressMobile(null);
reqVO.setTrackingNumber(null);

View File

@ -115,10 +115,24 @@ rocketmq:
spring:
# RabbitMQ 配置项,对应 RabbitProperties 配置类
rabbitmq:
host: 127.0.0.1 # RabbitMQ 服务的地址
host: forz.fun # RabbitMQ 服务的地址
port: 5672 # RabbitMQ 服务的端口
username: rabbit # RabbitMQ 服务的账号
password: rabbit # RabbitMQ 服务的密码
username: admin # RabbitMQ 服务的账号
password: K18LepU5YBpSl8 # RabbitMQ 服务的密码
publisher-confirm-type: correlated # 开启生产者确认
publisher-returns: true # 开启返回消息
template:
retry:
enabled: true # 开启发送失败重试
initial-interval: 1000ms # 重试间隔
max-attempts: 3 # 最大重试次数
listener:
simple:
acknowledge-mode: manual # 手动确认
retry:
enabled: true # 开启消费失败重试
initial-interval: 1000ms # 重试间隔
max-attempts: 3 # 最大重试次数
# Kafka 配置项,对应 KafkaProperties 配置类
kafka:
bootstrap-servers: 127.0.0.1:9092 # 指定 Kafka Broker 地址,可以设置多个,以逗号分隔

View File

@ -117,8 +117,22 @@ spring:
rabbitmq:
host: 172.18.0.1 # RabbitMQ 服务的地址
port: 5672 # RabbitMQ 服务的端口
username: rabbit # RabbitMQ 服务的账号
password: rabbit # RabbitMQ 服务的密码
username: admin # RabbitMQ 服务的账号
password: K18LepU5YBpSl8 # RabbitMQ 服务的密码
publisher-confirm-type: correlated # 开启生产者确认
publisher-returns: true # 开启返回消息
template:
retry:
enabled: true # 开启发送失败重试
initial-interval: 1000ms # 重试间隔
max-attempts: 3 # 最大重试次数
listener:
simple:
acknowledge-mode: manual # 手动确认
retry:
enabled: true # 开启消费失败重试
initial-interval: 1000ms # 重试间隔
max-attempts: 3 # 最大重试次数
# Kafka 配置项,对应 KafkaProperties 配置类
kafka:
bootstrap-servers: 172.18.0.1:9092 # 指定 Kafka Broker 地址,可以设置多个,以逗号分隔

View File

@ -115,10 +115,24 @@ rocketmq:
spring:
# RabbitMQ 配置项,对应 RabbitProperties 配置类
rabbitmq:
host: 127.0.0.1 # RabbitMQ 服务的地址
host: forz.fun # RabbitMQ 服务的地址
port: 5672 # RabbitMQ 服务的端口
username: rabbit # RabbitMQ 服务的账号
password: rabbit # RabbitMQ 服务的密码
username: admin # RabbitMQ 服务的账号
password: K18LepU5YBpSl8 # RabbitMQ 服务的密码
publisher-confirm-type: correlated # 开启生产者确认
publisher-returns: true # 开启返回消息
template:
retry:
enabled: true # 开启发送失败重试
initial-interval: 1000ms # 重试间隔
max-attempts: 3 # 最大重试次数
listener:
simple:
acknowledge-mode: manual # 手动确认
retry:
enabled: true # 开启消费失败重试
initial-interval: 1000ms # 重试间隔
max-attempts: 3 # 最大重试次数
# Kafka 配置项,对应 KafkaProperties 配置类
kafka:
bootstrap-servers: 127.0.0.1:9092 # 指定 Kafka Broker 地址,可以设置多个,以逗号分隔

View File

@ -0,0 +1,22 @@
CREATE TABLE `haoka_clock_record` (
`id` bigint(20) NOT NULL COMMENT 'ID',
`clock_type` int(11) DEFAULT NULL COMMENT '打卡类型',
`clock_user_id` varchar(100) NOT NULL COMMENT '用户ID',
`clock_shop_id` varchar(11) DEFAULT NULL COMMENT '店铺ID',
`clock_room_id` varchar(100) NOT NULL COMMENT '直播间ID',
`clock_time` datetime NOT NULL COMMENT '打卡时间',
`clock_shop_name` varchar(255) DEFAULT NULL COMMENT '店铺名称',
`clock_user_name` varchar(255) DEFAULT NULL COMMENT '姓名',
`dept_id` bigint(20) DEFAULT NULL COMMENT '部门ID',
`creator` varchar(64) NOT NULL DEFAULT '' COMMENT '创建者',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`updater` varchar(64) NOT NULL DEFAULT '' COMMENT '更新者',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
`tenant_id` bigint(20) NOT NULL DEFAULT '0' COMMENT '租户编号',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC COMMENT='打卡记录表';
-- 订单新增参数
ALTER TABLE `haoka_orders`
ADD COLUMN `order_amount` decimal(10, 2) NULL COMMENT '订单金额' AFTER `sales_attribution_name`,
ADD COLUMN `pay_amount` decimal(10, 2) NULL COMMENT '支付金额' AFTER `order_amount`;