create: 新增抖店订单推送,抓取
This commit is contained in:
parent
6e1da5f795
commit
2e351ce1ff
|
@ -48,4 +48,6 @@ public interface ErrorCodeConstants {
|
|||
ErrorCode BLACK_LIST_NOT_EXISTS = new ErrorCode(1_824_003_005, "黑名单不存在");
|
||||
ErrorCode SMS_TASK_NOT_EXISTS = new ErrorCode(1_824_123_005, "短信任务不存在");
|
||||
ErrorCode ORDER_OPERATE_LOG_NOT_EXISTS = new ErrorCode(1_826_001_001, "订单操作日志不存在");
|
||||
|
||||
ErrorCode ORDER_SYNC_LOG_NOT_EXISTS = new ErrorCode(1_827_001_001, "抓单记录不存在");
|
||||
}
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
package cn.iocoder.yudao.module.haoka.controller.admin.orderCatch;
|
||||
|
||||
|
||||
import cn.iocoder.yudao.module.haoka.controller.admin.orderCatch.po.Message;
|
||||
import cn.iocoder.yudao.module.haoka.controller.admin.orderCatch.vo.OrderCatchRepVO;
|
||||
import cn.iocoder.yudao.module.haoka.service.orderCatch.OrderCatchService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.annotation.security.PermitAll;
|
||||
import jakarta.validation.Valid;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Tag(name = "抓取订单")
|
||||
@RestController
|
||||
@RequestMapping("/haoka/orderCatch")
|
||||
@Validated
|
||||
@PermitAll
|
||||
public class OrderCatchController {
|
||||
|
||||
@Resource
|
||||
private OrderCatchService orderCatchService;
|
||||
|
||||
@PermitAll
|
||||
@RequestMapping("/catch")
|
||||
@Operation(summary = "抓取订单")
|
||||
public String catchOrders(@Valid @RequestBody List<Message> messages) {
|
||||
// 异步处理订单数据
|
||||
execCatchOrders(messages);
|
||||
// 立即返回推送所需的响应数据
|
||||
return "{\"code\":0,\"msg\":\"success\"}";
|
||||
}
|
||||
|
||||
/**
|
||||
* 异步处理订单数据
|
||||
* @param messages
|
||||
*/
|
||||
@Async
|
||||
public void execCatchOrders(List<Message> messages) {
|
||||
orderCatchService.catchOrders(messages);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
package cn.iocoder.yudao.module.haoka.controller.admin.orderCatch.po;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
public class Message<T> {
|
||||
@JsonProperty("tag")
|
||||
private String tag;
|
||||
|
||||
@JsonProperty("msg_id")
|
||||
private String msgId;
|
||||
|
||||
@JsonProperty("data")
|
||||
private T data;
|
||||
|
||||
// Getters and Setters
|
||||
public String getTag() {
|
||||
return tag;
|
||||
}
|
||||
|
||||
public void setTag(String tag) {
|
||||
this.tag = tag;
|
||||
}
|
||||
|
||||
public String getMsgId() {
|
||||
return msgId;
|
||||
}
|
||||
|
||||
public void setMsgId(String msgId) {
|
||||
this.msgId = msgId;
|
||||
}
|
||||
|
||||
public T getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
public void setData(T data) {
|
||||
this.data = data;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
package cn.iocoder.yudao.module.haoka.controller.admin.orderCatch.vo;
|
||||
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
@Schema(description = "抖音消息推送接收实体")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
@ToString(callSuper = true)
|
||||
public class OrderCatchRepVO {
|
||||
@Schema(description = "消息", example = "success")
|
||||
private String tag;
|
||||
@Schema(description = "消息", example = "success")
|
||||
private String msg_id;
|
||||
@Schema(description = "消息", example = "success")
|
||||
private String data;
|
||||
|
||||
}
|
|
@ -294,5 +294,34 @@ public class OrdersRespVO {
|
|||
*/
|
||||
@Schema(description = "身份证人脸")
|
||||
private String face;
|
||||
|
||||
/**
|
||||
* 店铺ID
|
||||
*/
|
||||
@Schema(description = "店铺ID")
|
||||
private String shopId;
|
||||
/**
|
||||
* 店铺名称
|
||||
*/
|
||||
@Schema(description = "店铺名称")
|
||||
private String shopName;
|
||||
/**
|
||||
* 直播间ID
|
||||
*/
|
||||
@Schema(description = "直播间ID")
|
||||
private String roomId;
|
||||
/**
|
||||
* 直播间名称
|
||||
*/
|
||||
@Schema(description = "直播间名称")
|
||||
private String roomName;
|
||||
/**
|
||||
* 销售归属
|
||||
*/
|
||||
@Schema(description = "销售归属")
|
||||
private String salesAttribution;
|
||||
/**
|
||||
* 销售归属名称
|
||||
*/
|
||||
@Schema(description = "销售归属名称")
|
||||
private String salesAttributionName;
|
||||
}
|
||||
|
|
|
@ -223,4 +223,34 @@ public class OrdersSaveReqVO {
|
|||
*/
|
||||
@Schema(description = "上游订单状态")
|
||||
private Integer upstreamOrderStatus;
|
||||
/**
|
||||
* 店铺ID
|
||||
*/
|
||||
@Schema(description = "店铺ID")
|
||||
private String shopId;
|
||||
/**
|
||||
* 店铺名称
|
||||
*/
|
||||
@Schema(description = "店铺名称")
|
||||
private String shopName;
|
||||
/**
|
||||
* 直播间ID
|
||||
*/
|
||||
@Schema(description = "直播间ID")
|
||||
private String roomId;
|
||||
/**
|
||||
* 直播间名称
|
||||
*/
|
||||
@Schema(description = "直播间名称")
|
||||
private String roomName;
|
||||
/**
|
||||
* 销售归属
|
||||
*/
|
||||
@Schema(description = "销售归属")
|
||||
private String salesAttribution;
|
||||
/**
|
||||
* 销售归属名称
|
||||
*/
|
||||
@Schema(description = "销售归属名称")
|
||||
private String salesAttributionName;
|
||||
}
|
||||
|
|
|
@ -27,6 +27,10 @@ public class OrderSourceRespVO {
|
|||
@DictFormat("haoka_order_channel") // TODO 代码优化:建议设置到对应的 DictTypeConstants 枚举类中
|
||||
private Long channel;
|
||||
|
||||
@Schema(description = "店铺ID", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@ExcelProperty(value = "店铺ID")
|
||||
private Long shopId;
|
||||
|
||||
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@ExcelProperty("创建时间")
|
||||
private LocalDateTime createTime;
|
||||
|
|
|
@ -0,0 +1,95 @@
|
|||
package cn.iocoder.yudao.module.haoka.controller.admin.ordersynclog;
|
||||
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
|
||||
import jakarta.validation.constraints.*;
|
||||
import jakarta.validation.*;
|
||||
import jakarta.servlet.http.*;
|
||||
import java.util.*;
|
||||
import java.io.IOException;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
|
||||
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
|
||||
|
||||
import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
|
||||
import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.*;
|
||||
|
||||
import cn.iocoder.yudao.module.haoka.controller.admin.ordersynclog.vo.*;
|
||||
import cn.iocoder.yudao.module.haoka.dal.dataobject.ordersynclog.OrderSyncLogDO;
|
||||
import cn.iocoder.yudao.module.haoka.service.ordersynclog.OrderSyncLogService;
|
||||
|
||||
@Tag(name = "管理后台 - 抓单记录")
|
||||
@RestController
|
||||
@RequestMapping("/haoka/order-sync-log")
|
||||
@Validated
|
||||
public class OrderSyncLogController {
|
||||
|
||||
@Resource
|
||||
private OrderSyncLogService orderSyncLogService;
|
||||
|
||||
@PostMapping("/create")
|
||||
@Operation(summary = "创建抓单记录")
|
||||
@PreAuthorize("@ss.hasPermission('haoka:order-sync-log:create')")
|
||||
public CommonResult<Long> createOrderSyncLog(@Valid @RequestBody OrderSyncLogSaveReqVO createReqVO) {
|
||||
return success(orderSyncLogService.createOrderSyncLog(createReqVO));
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
@Operation(summary = "更新抓单记录")
|
||||
@PreAuthorize("@ss.hasPermission('haoka:order-sync-log:update')")
|
||||
public CommonResult<Boolean> updateOrderSyncLog(@Valid @RequestBody OrderSyncLogSaveReqVO updateReqVO) {
|
||||
orderSyncLogService.updateOrderSyncLog(updateReqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete")
|
||||
@Operation(summary = "删除抓单记录")
|
||||
@Parameter(name = "id", description = "编号", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('haoka:order-sync-log:delete')")
|
||||
public CommonResult<Boolean> deleteOrderSyncLog(@RequestParam("id") Long id) {
|
||||
orderSyncLogService.deleteOrderSyncLog(id);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping("/get")
|
||||
@Operation(summary = "获得抓单记录")
|
||||
@Parameter(name = "id", description = "编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('haoka:order-sync-log:query')")
|
||||
public CommonResult<OrderSyncLogRespVO> getOrderSyncLog(@RequestParam("id") Long id) {
|
||||
OrderSyncLogDO orderSyncLog = orderSyncLogService.getOrderSyncLog(id);
|
||||
return success(BeanUtils.toBean(orderSyncLog, OrderSyncLogRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(summary = "获得抓单记录分页")
|
||||
@PreAuthorize("@ss.hasPermission('haoka:order-sync-log:query')")
|
||||
public CommonResult<PageResult<OrderSyncLogRespVO>> getOrderSyncLogPage(@Valid OrderSyncLogPageReqVO pageReqVO) {
|
||||
PageResult<OrderSyncLogDO> pageResult = orderSyncLogService.getOrderSyncLogPage(pageReqVO);
|
||||
return success(BeanUtils.toBean(pageResult, OrderSyncLogRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping("/export-excel")
|
||||
@Operation(summary = "导出抓单记录 Excel")
|
||||
@PreAuthorize("@ss.hasPermission('haoka:order-sync-log:export')")
|
||||
@ApiAccessLog(operateType = EXPORT)
|
||||
public void exportOrderSyncLogExcel(@Valid OrderSyncLogPageReqVO pageReqVO,
|
||||
HttpServletResponse response) throws IOException {
|
||||
pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
|
||||
List<OrderSyncLogDO> list = orderSyncLogService.getOrderSyncLogPage(pageReqVO).getList();
|
||||
// 导出 Excel
|
||||
ExcelUtils.write(response, "抓单记录.xls", "数据", OrderSyncLogRespVO.class,
|
||||
BeanUtils.toBean(list, OrderSyncLogRespVO.class));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
package cn.iocoder.yudao.module.haoka.controller.admin.ordersynclog.vo;
|
||||
|
||||
import lombok.*;
|
||||
import java.util.*;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
||||
|
||||
@Schema(description = "管理后台 - 抓单记录分页 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class OrderSyncLogPageReqVO extends PageParam {
|
||||
|
||||
@Schema(description = "同步类型(电商渠道)", example = "1")
|
||||
private String syncType;
|
||||
|
||||
@Schema(description = "同步店铺ID", example = "13239")
|
||||
private String syncShopId;
|
||||
|
||||
@Schema(description = "同步结束时间")
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
private Long[] syncEndTime;
|
||||
|
||||
@Schema(description = "同步开始时间")
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
private Long[] syncCreateTime;
|
||||
|
||||
@Schema(description = "创建时间")
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
private LocalDateTime[] createTime;
|
||||
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
package cn.iocoder.yudao.module.haoka.controller.admin.ordersynclog.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.*;
|
||||
import java.util.*;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
import java.time.LocalDateTime;
|
||||
import com.alibaba.excel.annotation.*;
|
||||
import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;
|
||||
import cn.iocoder.yudao.framework.excel.core.convert.DictConvert;
|
||||
|
||||
@Schema(description = "管理后台 - 抓单记录 Response VO")
|
||||
@Data
|
||||
@ExcelIgnoreUnannotated
|
||||
public class OrderSyncLogRespVO {
|
||||
|
||||
@Schema(description = "主键ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "28786")
|
||||
@ExcelProperty("主键ID")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "同步类型(电商渠道)", example = "1")
|
||||
@ExcelProperty(value = "同步类型(电商渠道)", converter = DictConvert.class)
|
||||
@DictFormat("haoka_order_channel") // TODO 代码优化:建议设置到对应的 DictTypeConstants 枚举类中
|
||||
private String syncType;
|
||||
|
||||
@Schema(description = "同步店铺ID", example = "13239")
|
||||
@ExcelProperty("同步店铺ID")
|
||||
private String syncShopId;
|
||||
|
||||
@Schema(description = "同步结束时间")
|
||||
@ExcelProperty("同步结束时间")
|
||||
private Long syncEndTime;
|
||||
|
||||
@Schema(description = "同步开始时间")
|
||||
@ExcelProperty("同步开始时间")
|
||||
private Long syncCreateTime;
|
||||
|
||||
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@ExcelProperty("创建时间")
|
||||
private LocalDateTime createTime;
|
||||
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
package cn.iocoder.yudao.module.haoka.controller.admin.ordersynclog.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.*;
|
||||
import java.util.*;
|
||||
import jakarta.validation.constraints.*;
|
||||
|
||||
@Schema(description = "管理后台 - 抓单记录新增/修改 Request VO")
|
||||
@Data
|
||||
public class OrderSyncLogSaveReqVO {
|
||||
|
||||
@Schema(description = "主键ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "28786")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "同步类型(电商渠道)", example = "1")
|
||||
private String syncType;
|
||||
|
||||
@Schema(description = "同步店铺ID", example = "13239")
|
||||
private String syncShopId;
|
||||
|
||||
@Schema(description = "同步结束时间")
|
||||
private Long syncEndTime;
|
||||
|
||||
@Schema(description = "同步开始时间")
|
||||
private Long syncCreateTime;
|
||||
|
||||
}
|
|
@ -326,5 +326,29 @@ public class OrdersDO extends BaseDO {
|
|||
* 是否加急 0或空 不加急 1 加急
|
||||
*/
|
||||
private Integer isUrgent;
|
||||
/**
|
||||
* 店铺ID
|
||||
*/
|
||||
private String shopId;
|
||||
/**
|
||||
* 店铺名称
|
||||
*/
|
||||
private String shopName;
|
||||
/**
|
||||
* 直播间ID
|
||||
*/
|
||||
private String roomId;
|
||||
/**
|
||||
* 直播间名称
|
||||
*/
|
||||
private String roomName;
|
||||
/**
|
||||
* 销售归属
|
||||
*/
|
||||
private String salesAttribution;
|
||||
/**
|
||||
* 销售归属名称
|
||||
*/
|
||||
private String salesAttributionName;
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
package cn.iocoder.yudao.module.haoka.dal.dataobject.ordersynclog;
|
||||
|
||||
import lombok.*;
|
||||
import java.util.*;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalDateTime;
|
||||
import com.baomidou.mybatisplus.annotation.*;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
|
||||
|
||||
/**
|
||||
* 抓单记录 DO
|
||||
*
|
||||
* @author 超级管理员
|
||||
*/
|
||||
@TableName("haoka_order_sync_log")
|
||||
@KeySequence("haoka_order_sync_log_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class OrderSyncLogDO extends BaseDO {
|
||||
|
||||
/**
|
||||
* 主键ID
|
||||
*/
|
||||
@TableId(type = IdType.ASSIGN_ID)
|
||||
private Long id;
|
||||
/**
|
||||
* 同步类型(电商渠道)
|
||||
*
|
||||
* 枚举 {@link TODO haoka_order_channel 对应的类}
|
||||
*/
|
||||
private String syncType;
|
||||
/**
|
||||
* 同步店铺ID
|
||||
*/
|
||||
private String syncShopId;
|
||||
/**
|
||||
* 同步结束时间
|
||||
*/
|
||||
private Long syncEndTime;
|
||||
/**
|
||||
* 同步开始时间
|
||||
*/
|
||||
private Long syncCreateTime;
|
||||
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
package cn.iocoder.yudao.module.haoka.dal.mysql.ordersynclog;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
|
||||
import cn.iocoder.yudao.module.haoka.dal.dataobject.ordersynclog.OrderSyncLogDO;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import cn.iocoder.yudao.module.haoka.controller.admin.ordersynclog.vo.*;
|
||||
|
||||
/**
|
||||
* 抓单记录 Mapper
|
||||
*
|
||||
* @author 超级管理员
|
||||
*/
|
||||
@Mapper
|
||||
public interface OrderSyncLogMapper extends BaseMapperX<OrderSyncLogDO> {
|
||||
|
||||
default PageResult<OrderSyncLogDO> selectPage(OrderSyncLogPageReqVO reqVO) {
|
||||
return selectPage(reqVO, new LambdaQueryWrapperX<OrderSyncLogDO>()
|
||||
.eqIfPresent(OrderSyncLogDO::getSyncType, reqVO.getSyncType())
|
||||
.eqIfPresent(OrderSyncLogDO::getSyncShopId, reqVO.getSyncShopId())
|
||||
.betweenIfPresent(OrderSyncLogDO::getSyncEndTime, reqVO.getSyncEndTime())
|
||||
.betweenIfPresent(OrderSyncLogDO::getSyncCreateTime, reqVO.getSyncCreateTime())
|
||||
.betweenIfPresent(OrderSyncLogDO::getCreateTime, reqVO.getCreateTime())
|
||||
.orderByDesc(OrderSyncLogDO::getCreateTime));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,109 @@
|
|||
package cn.iocoder.yudao.module.haoka.schedule;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.module.haoka.controller.admin.ordersynclog.vo.OrderSyncLogPageReqVO;
|
||||
import cn.iocoder.yudao.module.haoka.controller.admin.ordersynclog.vo.OrderSyncLogSaveReqVO;
|
||||
import cn.iocoder.yudao.module.haoka.dal.dataobject.ordersynclog.OrderSyncLogDO;
|
||||
import cn.iocoder.yudao.module.haoka.service.orderCatch.OrderCatchService;
|
||||
import cn.iocoder.yudao.module.haoka.service.ordersynclog.OrderSyncLogService;
|
||||
import com.doudian.open.core.AccessToken;
|
||||
import com.doudian.open.core.AccessTokenBuilder;
|
||||
import com.doudian.open.core.GlobalConfig;
|
||||
import jakarta.annotation.Resource;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneId;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
|
||||
/**
|
||||
* 抖音抓单
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class DouDianOrderCatchSchdule {
|
||||
|
||||
private static final String SYNC_APP_KEY = "7381306825771091495"; // initAppKey
|
||||
private static final String SYNC_APP_SECRET = "09c06553-b77c-4712-aed9-84cbfe16ca13"; // initAppSecret
|
||||
/**
|
||||
* 天猫 0
|
||||
* 快手 1
|
||||
* 抖音 2
|
||||
* 拼多多 3
|
||||
* 京东 4
|
||||
*/
|
||||
private static final String SYNC_TYPE = "2"; // 同步类型 抖音
|
||||
private static final Long SYNC_SHOP_ID = 20811777L; // 抖店店铺id
|
||||
@Resource
|
||||
OrderCatchService orderCatchService;
|
||||
|
||||
@Resource
|
||||
private OrderSyncLogService orderSyncLogService;
|
||||
/**
|
||||
* 每20分钟执行一次
|
||||
*/
|
||||
// @Scheduled(cron = "0 */20 * * * ?")
|
||||
public void catchOrder() {
|
||||
// refreshToken();
|
||||
GlobalConfig.initAppKey(SYNC_APP_KEY);
|
||||
GlobalConfig.initAppSecret(SYNC_APP_SECRET);
|
||||
//入参为code
|
||||
AccessToken accessToken= AccessTokenBuilder.build(SYNC_SHOP_ID);
|
||||
// 从数据库获取上一次同步的结束时间
|
||||
Long lastSyncTime = getLatestSyncTime();
|
||||
|
||||
// 获取当前时间
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
long currentTimestamp = now.atZone(ZoneId.systemDefault()).toEpochSecond();
|
||||
|
||||
// 如果没有同步记录,初始化为1天前
|
||||
LocalDateTime startDateTime;
|
||||
if (lastSyncTime == null) {
|
||||
startDateTime = now.minus(1, ChronoUnit.DAYS);
|
||||
} else {
|
||||
startDateTime = Instant.ofEpochSecond(lastSyncTime).atZone(ZoneId.systemDefault()).toLocalDateTime();
|
||||
}
|
||||
|
||||
// 将LocalDateTime转换为秒级时间戳
|
||||
long createTimeStart = startDateTime.atZone(ZoneId.systemDefault()).toEpochSecond();
|
||||
long createTimeEnd = currentTimestamp;
|
||||
orderCatchService.syncOrder(accessToken, createTimeStart, createTimeEnd);
|
||||
log.info("结束-----------抖音--更新订单结束--------------------");
|
||||
}
|
||||
|
||||
/**
|
||||
* 从数据库获取上一次同步的结束时间
|
||||
*
|
||||
* @return 上一次同步的结束时间戳
|
||||
*/
|
||||
private Long getLatestSyncTime() {
|
||||
// 示例代码,实际需要通过你的数据库操作类获取
|
||||
OrderSyncLogPageReqVO orderSyncLogPageReqVO = new OrderSyncLogPageReqVO();
|
||||
orderSyncLogPageReqVO.setSyncType(SYNC_TYPE);
|
||||
orderSyncLogPageReqVO.setSyncShopId(String.valueOf(SYNC_SHOP_ID));
|
||||
PageResult<OrderSyncLogDO> orderSyncLogPage = orderSyncLogService.getOrderSyncLogPage(orderSyncLogPageReqVO);
|
||||
Long total = orderSyncLogPage.getTotal();
|
||||
if(total>0){
|
||||
return orderSyncLogPage.getList().get(0).getSyncEndTime();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存同步记录到数据库
|
||||
*
|
||||
* @param createTimeEnd 同步结束时间
|
||||
* @param createTimeStart 同步开始时间
|
||||
*/
|
||||
private void saveSyncLog(long createTimeEnd,long createTimeStart) {
|
||||
OrderSyncLogSaveReqVO saveReqVO = new OrderSyncLogSaveReqVO();
|
||||
saveReqVO.setSyncType(SYNC_TYPE);
|
||||
saveReqVO.setSyncEndTime(createTimeEnd);
|
||||
saveReqVO.setSyncCreateTime(createTimeStart); // 当前时间戳
|
||||
orderSyncLogService.createOrderSyncLog(saveReqVO); // 插入同步记录
|
||||
}
|
||||
}
|
|
@ -0,0 +1,651 @@
|
|||
package cn.iocoder.yudao.module.haoka.service.orderCatch;
|
||||
|
||||
import cn.hutool.core.collection.CollectionUtil;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||
import cn.iocoder.yudao.module.haoka.controller.admin.onsaleproduct.vo.OnSaleProductPreOrderRespVO;
|
||||
import cn.iocoder.yudao.module.haoka.controller.admin.orderCatch.po.Message;
|
||||
import cn.iocoder.yudao.module.haoka.controller.admin.orderCatch.vo.OrderCatchRepVO;
|
||||
import cn.iocoder.yudao.module.haoka.controller.admin.ordersynclog.vo.OrderSyncLogPageReqVO;
|
||||
import cn.iocoder.yudao.module.haoka.controller.admin.ordersynclog.vo.OrderSyncLogSaveReqVO;
|
||||
import cn.iocoder.yudao.module.haoka.dal.dataobject.onsaleproduct.OnSaleProductDO;
|
||||
import cn.iocoder.yudao.module.haoka.dal.dataobject.orders.OrdersDO;
|
||||
import cn.iocoder.yudao.module.haoka.dal.dataobject.ordersynclog.OrderSyncLogDO;
|
||||
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.ordersynclog.OrderSyncLogService;
|
||||
import cn.iocoder.yudao.module.haoka.service.ordersynclog.OrderSyncLogServiceImpl;
|
||||
import cn.iocoder.yudao.module.haoka.utils.GroupListUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
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_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_searchList.OrderSearchListRequest;
|
||||
import com.doudian.open.api.order_searchList.OrderSearchListResponse;
|
||||
import com.doudian.open.api.order_searchList.data.*;
|
||||
import com.doudian.open.api.order_searchList.param.OrderSearchListParam;
|
||||
import com.doudian.open.api.token_refresh.TokenRefreshRequest;
|
||||
import com.doudian.open.api.token_refresh.TokenRefreshResponse;
|
||||
import com.doudian.open.api.token_refresh.param.TokenRefreshParam;
|
||||
import com.doudian.open.core.AccessToken;
|
||||
import com.doudian.open.core.AccessTokenBuilder;
|
||||
import com.doudian.open.core.GlobalConfig;
|
||||
import com.doudian.open.gson.Gson;
|
||||
import com.doudian.open.msg.refund_RefundAgreed.param.RefundRefundAgreedParam;
|
||||
import com.doudian.open.msg.refund_RefundCreated.param.RefundRefundCreatedParam;
|
||||
import com.doudian.open.msg.refund_ReturnApplyAgreed.param.RefundReturnApplyAgreedParam;
|
||||
import com.doudian.open.msg.trade_TradeCanceled.param.TradeTradeCanceledParam;
|
||||
import com.doudian.open.msg.trade_TradePaid.param.TradeTradePaidParam;
|
||||
import com.doudian.open.msg.trade_TradePending.param.TradeTradePendingParam;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneId;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
@Service
|
||||
@Validated
|
||||
public class DouDianOrderCatchServiceImpl implements OrderCatchService {
|
||||
|
||||
|
||||
private static final String SYNC_APP_KEY = "7381306825771091495"; // initAppKey
|
||||
private static final String SYNC_APP_SECRET = "09c06553-b77c-4712-aed9-84cbfe16ca13"; // initAppSecret
|
||||
private static final String SYNC_TYPE = "2"; // 同步类型 抖店
|
||||
private static final Long SYNC_SHOP_ID = 20811777L; // 抖店店铺id
|
||||
|
||||
@Resource
|
||||
private OrdersMapper ordersMapper;
|
||||
@Resource
|
||||
private OnSaleProductMapper onSaleProductMapper;
|
||||
@Resource
|
||||
private OnSaleProductService onSaleProductService;
|
||||
@Resource
|
||||
private OrderSyncLogService orderSyncLogService;
|
||||
@Override
|
||||
public void syncOrder(AccessToken accessToken, long createTimeStart, long createTimeEnd) {
|
||||
// 分页查询订单
|
||||
List<ShopOrderListItem> allOrders = fetchOrders(accessToken, createTimeStart, createTimeEnd);
|
||||
// 将获取的订单插入到数据库
|
||||
insertOrdersToDatabase(allOrders);
|
||||
}
|
||||
|
||||
/**
|
||||
* 抖音消息推送订单,抓取/更新 订单
|
||||
* @param catchRepVO
|
||||
*/
|
||||
@Override
|
||||
public void catchOrders(List<Message> catchRepVO) {
|
||||
// 插入日志
|
||||
Gson gson = new Gson();
|
||||
for (Message message : catchRepVO) {
|
||||
String tag = message.getTag();
|
||||
String msgId = message.getMsgId();
|
||||
Object data = message.getData();
|
||||
// 插入日志
|
||||
if("doudian_refund_RefundCreated".equals(tag)){
|
||||
// 买家发起售后申请消息
|
||||
RefundRefundCreatedParam refundRefundCreatedParam = gson.fromJson(message.getData()+"", RefundRefundCreatedParam.class);
|
||||
} else if("doudian_refund_RefundAgreed".equals(tag)) {
|
||||
// 同意退款消息
|
||||
RefundRefundAgreedParam refundRefundAgreedParam = gson.fromJson(message.getData()+"", RefundRefundAgreedParam.class);
|
||||
} else if("doudian_refund_ReturnApplyAgreed".equals(tag)) {
|
||||
// 同意退货申请消息
|
||||
RefundReturnApplyAgreedParam refundReturnApplyAgreedParam = gson.fromJson(message.getData()+"", RefundReturnApplyAgreedParam.class);
|
||||
} else if("doudian_trade_TradePaid".equals(tag)) {
|
||||
// 订单支付/确认消息 抓取订单
|
||||
TradeTradePaidParam tradeTradePaidParam = gson.fromJson(message.getData()+"", TradeTradePaidParam.class);
|
||||
// 订单id
|
||||
Long pId = tradeTradePaidParam.getPId();
|
||||
// 根据订单id查询订单详情
|
||||
OrderOrderDetailData orderDetail = orderDetail(String.valueOf(pId));
|
||||
ShopOrderDetail order = orderDetail.getShopOrderDetail();
|
||||
// 所有的订单数据
|
||||
List<com.doudian.open.api.order_orderDetail.data.SkuOrderListItem> skuOrderList = order.getSkuOrderList();
|
||||
// 店铺信息
|
||||
Long shopId = order.getShopId();
|
||||
String shopName = order.getShopName();
|
||||
// 物流信息
|
||||
List<com.doudian.open.api.order_orderDetail.data.LogisticsInfoItem> logisticsInfo = order.getLogisticsInfo();
|
||||
/**
|
||||
* 需判断订单是否存在
|
||||
* 1.不存在 --- 新增
|
||||
* 2.存在 --- 更新
|
||||
* 2.1 需更新的数据: 订单状态 退款状态
|
||||
*/
|
||||
// 所有在售商品
|
||||
List<OnSaleProductDO> onSaleProductDOS = onSaleProductMapper.selectList(new QueryWrapper<OnSaleProductDO>().eq("deleted", 0).eq("onSale", true));
|
||||
// 所有在售商品sku
|
||||
List<String> skuList = onSaleProductDOS.stream().map(OnSaleProductDO::getSku).toList();
|
||||
// 买家备注
|
||||
String buyerWords = order.getBuyerWords();
|
||||
// 收件人电话
|
||||
// String postTel = order.getPostTel();
|
||||
String encryptPostTel = order.getEncryptPostTel();
|
||||
// 收件人姓名
|
||||
// String postReceiver = order.getPostReceiver();
|
||||
String encryptPostReceiver = order.getEncryptPostReceiver();
|
||||
// 收件人地址
|
||||
com.doudian.open.api.order_orderDetail.data.PostAddr postAddr = order.getPostAddr();
|
||||
// 省
|
||||
com.doudian.open.api.order_orderDetail.data.Province province = postAddr.getProvince();
|
||||
// 市
|
||||
com.doudian.open.api.order_orderDetail.data.City city = postAddr.getCity();
|
||||
// 区
|
||||
com.doudian.open.api.order_orderDetail.data.Town town = postAddr.getTown();
|
||||
// 街道/镇
|
||||
com.doudian.open.api.order_orderDetail.data.Street street = postAddr.getStreet();
|
||||
// String detail = postAddr.getDetail();
|
||||
String encryptDetail = postAddr.getEncryptDetail();
|
||||
//用户信息
|
||||
com.doudian.open.api.order_orderDetail.data.UserIdInfo userIdInfo = order.getUserIdInfo();
|
||||
// String idCardNo = userIdInfo.getIdCardNo();
|
||||
String encryptIdCardNo = userIdInfo.getEncryptIdCardNo();
|
||||
// String idCardName = userIdInfo.getIdCardName();
|
||||
String encryptIdCardName = userIdInfo.getEncryptIdCardName();
|
||||
List<OrdersDO> orderList = new ArrayList<>();
|
||||
List<OrdersDO> orderListAll = new ArrayList<>();
|
||||
for (com.doudian.open.api.order_orderDetail.data.SkuOrderListItem skuOrderListItem : skuOrderList) {
|
||||
String orderId = skuOrderListItem.getOrderId();
|
||||
OrdersDO ordersDO = new OrdersDO();
|
||||
// 售后信息
|
||||
com.doudian.open.api.order_orderDetail.data.AfterSaleInfo afterSaleInfo = skuOrderListItem.getAfterSaleInfo();
|
||||
// 售后状态 0-售后初始化, 6-售后申请, 7-售后退货中, 27-拒绝售后申请, 12-售后成功, 28-售后失败, 11-售后已发货, 29-退货后拒绝退款, 13-售后换货商家发货, 14-售后换货用户收货, 51-取消成功, 53-逆向交易完成
|
||||
Long afterSaleStatus = afterSaleInfo.getAfterSaleStatus();
|
||||
// 1-待退款;3-退款成功; 4-退款失败;当买家发起售后后又主动取消售后,此时after_sale_status=28并且refund_status=1的状态不变,不会流转至4状态;
|
||||
Long refundStatus = afterSaleInfo.getRefundStatus();
|
||||
// 商品sku 判断是否抓单
|
||||
String code = skuOrderListItem.getCode();
|
||||
if(skuList.contains(code)){
|
||||
for (OnSaleProductDO onSaleProductDO : onSaleProductDOS) {
|
||||
if(onSaleProductDO.getSku().equals(code)){
|
||||
// 注入产品生产方式 记录初始产品+接口相关信息
|
||||
OnSaleProductPreOrderRespVO onSaleProductPreOrder = onSaleProductService.getOnSaleProductPreOrder(onSaleProductDO.getId());
|
||||
ordersDO.setAutoType(onSaleProductPreOrder.getParentProduct().getAutoType());
|
||||
ordersDO.setOnSaleProductId(onSaleProductPreOrder.getId());
|
||||
ordersDO.setProductId(onSaleProductPreOrder.getParentProduct().getId());
|
||||
ordersDO.setSuperiorProductConfigId(onSaleProductPreOrder.getSuperiorProductConfigRespVO().getId());
|
||||
ordersDO.setSuperiorApiId(onSaleProductPreOrder.getSuperiorApiRespVO().getId());
|
||||
}
|
||||
}
|
||||
// 在售商品
|
||||
ordersDO.setSupplierProductSku(code);
|
||||
Long orderStatus = skuOrderListItem.getOrderStatus();
|
||||
// 1 待确认/待支付-订单创建完毕;105-已支付; 2-备货中; 101-部分发货; 3-已发货(全部发货);4- 已取消;5 已完成(已收货);
|
||||
Long HaokaOrderStatus;// 号卡订单状态
|
||||
Long HaokaOrderRefundStatus;// 号卡订单退款状态
|
||||
// 解析订单状态
|
||||
if(orderStatus == 105L){
|
||||
HaokaOrderStatus = 100L;
|
||||
ordersDO.setStatus(HaokaOrderStatus);
|
||||
}else if(orderStatus == 101L || orderStatus == 3L){
|
||||
HaokaOrderStatus = 500L;
|
||||
ordersDO.setStatus(HaokaOrderStatus);
|
||||
}else {
|
||||
// 更新订单退款状态 订单状态不变
|
||||
}
|
||||
ordersDO.setStatusName(skuOrderListItem.getOrderStatusDesc());
|
||||
// 解析售后状态
|
||||
if(0L == afterSaleStatus){
|
||||
// 未进入售后
|
||||
HaokaOrderRefundStatus = 800L;
|
||||
} else if(afterSaleStatus == 28L || refundStatus == 1L){
|
||||
// 未进入售后
|
||||
HaokaOrderRefundStatus = 800L;
|
||||
} else if(refundStatus == 3L){
|
||||
// 进入售后
|
||||
HaokaOrderRefundStatus = 300L;
|
||||
} else {
|
||||
// 进入售后
|
||||
HaokaOrderRefundStatus = 200L;
|
||||
}
|
||||
ordersDO.setRefundStatus(String.valueOf(HaokaOrderRefundStatus));
|
||||
// 获取计划手机号
|
||||
for (com.doudian.open.api.order_orderDetail.data.LogisticsInfoItem logisticsInfoItem : logisticsInfo) {
|
||||
for (com.doudian.open.api.order_orderDetail.data.ProductInfoItem productInfoItem : logisticsInfoItem.getProductInfo()) {
|
||||
String skuOrderId = productInfoItem.getSkuOrderId();
|
||||
if(skuOrderId.equals(orderId)){
|
||||
String productName = productInfoItem.getProductName();
|
||||
ordersDO.setSupplierProductName(productName);
|
||||
List<com.doudian.open.api.order_orderDetail.data.SkuSpecsItem> skuSpecs = productInfoItem.getSkuSpecs();
|
||||
for (com.doudian.open.api.order_orderDetail.data.SkuSpecsItem skuSpec : skuSpecs) {
|
||||
String name = skuSpec.getName();
|
||||
String planMobile = getPlanMobile(name);
|
||||
if(planMobile != null){
|
||||
ordersDO.setPlanMobile(planMobile);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// 查询订单是否存在 不存在则新增,存在则更新
|
||||
List<OrdersDO> ordersDOS = ordersMapper.selectList(new QueryWrapper<OrdersDO>().eq("real_source_id", orderId).eq("deleted", 0));
|
||||
if(CollectionUtil.isNotEmpty(ordersDOS)){
|
||||
// 更新订单
|
||||
OrdersDO ordersDO1 = ordersDOS.get(0);
|
||||
ordersDO1.setRefundStatus(String.valueOf(HaokaOrderRefundStatus));
|
||||
ordersMapper.updateById(ordersDO1);
|
||||
}else {
|
||||
// 新增订单
|
||||
ordersDO.setShopId(String.valueOf(shopId));
|
||||
ordersDO.setShopName(shopName);
|
||||
ordersDO.setRoomId(skuOrderListItem.getRoomIdStr());
|
||||
// 真实订单
|
||||
ordersDO.setRealSourceId(orderId);
|
||||
ordersDO.setSourceId(orderId);
|
||||
// 买家备注
|
||||
ordersDO.setBuyerMemo(buyerWords);
|
||||
//证件信息
|
||||
// ordersDO.setIdCardNum(idCardNo);
|
||||
ordersDO.setEncryptIdCardNum(encryptIdCardNo);
|
||||
// ordersDO.setIdCardName(idCardName);
|
||||
ordersDO.setEncryptIdCardName(encryptIdCardName);
|
||||
// 收件人信息
|
||||
// ordersDO.setAddressMobile(postTel);
|
||||
ordersDO.setEncryptAddressMobile(encryptPostTel);
|
||||
// ordersDO.setAddressName(postReceiver);
|
||||
ordersDO.setEncryptAddressName(encryptPostReceiver);
|
||||
// 收件人地址 省
|
||||
ordersDO.setAddressProvince(province.getName());
|
||||
ordersDO.setAddressProvinceCode(province.getId());
|
||||
// 市
|
||||
ordersDO.setAddressCity(city.getName());
|
||||
ordersDO.setAddressCityCode(city.getId());
|
||||
// 区
|
||||
ordersDO.setAddressDistrict(town.getName());
|
||||
ordersDO.setAddressDistrictCode(town.getId());
|
||||
// 街道/镇
|
||||
ordersDO.setTown(street.getName());
|
||||
// 详细地址
|
||||
// ordersDO.setAddress(detail);
|
||||
ordersDO.setEncryptAddress(encryptDetail);
|
||||
orderList.add(ordersDO);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
orderListAll.addAll(orderList);
|
||||
ordersMapper.insertBatch(orderList);
|
||||
// 执行解密,解密后更新数据库
|
||||
for (List<OrdersDO> ordersDOS : GroupListUtil.groupList(orderListAll, 50)) {
|
||||
batchDecryptOrderAndUpdate(ordersDOS);
|
||||
}
|
||||
} else if("doudian_trade_TradeCanceled".equals(tag)) {
|
||||
// 订单取消消息
|
||||
TradeTradeCanceledParam tradeTradeCanceledParam = gson.fromJson(message.getData()+"", TradeTradeCanceledParam.class);
|
||||
} else if("doudian_trade_TradePending".equals(tag)) {
|
||||
// 订单已支付待处理
|
||||
TradeTradePendingParam tradeTradePendingParam = gson.fromJson(message.getData()+"", TradeTradePendingParam.class);
|
||||
} else {
|
||||
// 未接入的消息类型
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 将订单数据插入到数据库
|
||||
* @param orders 订单数据
|
||||
*/
|
||||
private void insertOrdersToDatabase(List<ShopOrderListItem> orders) {
|
||||
// 所有在售商品
|
||||
List<OnSaleProductDO> onSaleProductDOS = onSaleProductMapper.selectList(new QueryWrapper<OnSaleProductDO>().eq("deleted", 0).eq("onSale", true));
|
||||
// 所有在售商品sku
|
||||
List<String> skuList = onSaleProductDOS.stream().map(OnSaleProductDO::getSku).toList();
|
||||
//数据分片处理 分片理由 每次最多徐解密50条数据,一条订单解密5个数据,10个订单解密50条
|
||||
List<OrdersDO> orderListAll = new ArrayList<>();
|
||||
List<List<ShopOrderListItem>> orderGroupList = GroupListUtil.groupList(orders, 10);
|
||||
// orderGroupList 的 size 最大为10
|
||||
for (List<ShopOrderListItem> orderListItems : orderGroupList) {
|
||||
List<OrdersDO> orderList = new ArrayList<>();
|
||||
for (ShopOrderListItem order : orderListItems) {
|
||||
// 抖音订单id
|
||||
// String orderId = order.getOrderId();
|
||||
// 买家备注
|
||||
String buyerWords = order.getBuyerWords();
|
||||
// 店铺id
|
||||
Long shopId = order.getShopId();
|
||||
// 店铺名称
|
||||
String shopName = order.getShopName();
|
||||
// 收件人电话
|
||||
// String postTel = order.getPostTel();
|
||||
String encryptPostTel = order.getEncryptPostTel();
|
||||
// 收件人姓名
|
||||
// String postReceiver = order.getPostReceiver();
|
||||
String encryptPostReceiver = order.getEncryptPostReceiver();
|
||||
// 收件人地址
|
||||
PostAddr postAddr = order.getPostAddr();
|
||||
// 省
|
||||
Province province = postAddr.getProvince();
|
||||
// 市
|
||||
City city = postAddr.getCity();
|
||||
// 区
|
||||
Town town = postAddr.getTown();
|
||||
// 街道/镇
|
||||
Street street = postAddr.getStreet();
|
||||
// String detail = postAddr.getDetail();
|
||||
String encryptDetail = postAddr.getEncryptDetail();
|
||||
//用户信息
|
||||
UserIdInfo userIdInfo = order.getUserIdInfo();
|
||||
// String idCardNo = userIdInfo.getIdCardNo();
|
||||
String encryptIdCardNo = userIdInfo.getEncryptIdCardNo();
|
||||
// String idCardName = userIdInfo.getIdCardName();
|
||||
String encryptIdCardName = userIdInfo.getEncryptIdCardName();
|
||||
// 商品信息
|
||||
List<SkuOrderListItem> skuOrderList = order.getSkuOrderList();
|
||||
List<LogisticsInfoItem> logisticsInfo = order.getLogisticsInfo();
|
||||
|
||||
for (SkuOrderListItem skuOrderListItem : skuOrderList) {
|
||||
String orderId = skuOrderListItem.getOrderId();
|
||||
OrdersDO ordersDO = new OrdersDO();
|
||||
// 售后信息
|
||||
AfterSaleInfo afterSaleInfo = skuOrderListItem.getAfterSaleInfo();
|
||||
// 售后状态 0-售后初始化, 6-售后申请, 7-售后退货中, 27-拒绝售后申请, 12-售后成功, 28-售后失败, 11-售后已发货, 29-退货后拒绝退款, 13-售后换货商家发货, 14-售后换货用户收货, 51-取消成功, 53-逆向交易完成
|
||||
Long afterSaleStatus = afterSaleInfo.getAfterSaleStatus();
|
||||
// 1-待退款;3-退款成功; 4-退款失败;当买家发起售后后又主动取消售后,此时after_sale_status=28并且refund_status=1的状态不变,不会流转至4状态;
|
||||
Long refundStatus = afterSaleInfo.getRefundStatus();
|
||||
// 商品sku 判断是否抓单
|
||||
String code = skuOrderListItem.getCode();
|
||||
if(skuList.contains(code)){
|
||||
for (OnSaleProductDO onSaleProductDO : onSaleProductDOS) {
|
||||
if(onSaleProductDO.getSku().equals(code)){
|
||||
// 注入产品生产方式 记录初始产品+接口相关信息
|
||||
OnSaleProductPreOrderRespVO onSaleProductPreOrder = onSaleProductService.getOnSaleProductPreOrder(onSaleProductDO.getId());
|
||||
ordersDO.setAutoType(onSaleProductPreOrder.getParentProduct().getAutoType());
|
||||
ordersDO.setOnSaleProductId(onSaleProductPreOrder.getId());
|
||||
ordersDO.setProductId(onSaleProductPreOrder.getParentProduct().getId());
|
||||
ordersDO.setSuperiorProductConfigId(onSaleProductPreOrder.getSuperiorProductConfigRespVO().getId());
|
||||
ordersDO.setSuperiorApiId(onSaleProductPreOrder.getSuperiorApiRespVO().getId());
|
||||
}
|
||||
}
|
||||
// 在售商品
|
||||
ordersDO.setSupplierProductSku(code);
|
||||
Long orderStatus = skuOrderListItem.getOrderStatus();
|
||||
// 1 待确认/待支付-订单创建完毕;105-已支付; 2-备货中; 101-部分发货; 3-已发货(全部发货);4- 已取消;5 已完成(已收货);
|
||||
Long HaokaOrderStatus;// 号卡订单状态
|
||||
Long HaokaOrderRefundStatus;// 号卡订单退款状态
|
||||
// 解析订单状态
|
||||
if(orderStatus == 105L){
|
||||
HaokaOrderStatus = 100L;
|
||||
ordersDO.setStatus(HaokaOrderStatus);
|
||||
}else if(orderStatus == 101L || orderStatus == 3L){
|
||||
HaokaOrderStatus = 500L;
|
||||
ordersDO.setStatus(HaokaOrderStatus);
|
||||
}else {
|
||||
// 更新订单退款状态 订单状态不变
|
||||
}
|
||||
// 解析售后状态
|
||||
if(0L == afterSaleStatus){
|
||||
// 未进入售后
|
||||
HaokaOrderRefundStatus = 800L;
|
||||
} else if(afterSaleStatus == 28L || refundStatus == 1L){
|
||||
// 未进入售后
|
||||
HaokaOrderRefundStatus = 800L;
|
||||
} else if(refundStatus == 3L){
|
||||
// 进入售后
|
||||
HaokaOrderRefundStatus = 300L;
|
||||
} else {
|
||||
// 进入售后
|
||||
HaokaOrderRefundStatus = 200L;
|
||||
}
|
||||
ordersDO.setRefundStatus(String.valueOf(HaokaOrderRefundStatus));
|
||||
ordersDO.setStatusName(skuOrderListItem.getOrderStatusDesc());
|
||||
// 获取计划手机号
|
||||
for (LogisticsInfoItem logisticsInfoItem : logisticsInfo) {
|
||||
for (ProductInfoItem productInfoItem : logisticsInfoItem.getProductInfo()) {
|
||||
String skuOrderId = productInfoItem.getSkuOrderId();
|
||||
if(skuOrderId.equals(orderId)){
|
||||
String productName = productInfoItem.getProductName();
|
||||
ordersDO.setSupplierProductName(productName);
|
||||
List<SkuSpecsItem> skuSpecs = productInfoItem.getSkuSpecs();
|
||||
for (SkuSpecsItem skuSpec : skuSpecs) {
|
||||
String name = skuSpec.getName();
|
||||
String planMobile = getPlanMobile(name);
|
||||
if(planMobile != null){
|
||||
ordersDO.setPlanMobile(planMobile);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// 查询订单是否存在 不存在则新增,存在则更新
|
||||
List<OrdersDO> ordersDOS = ordersMapper.selectList(new QueryWrapper<OrdersDO>().eq("real_source_id", orderId).eq("deleted", 0));
|
||||
if(CollectionUtil.isNotEmpty(ordersDOS)){
|
||||
// 更新订单
|
||||
OrdersDO ordersDO1 = ordersDOS.get(0);
|
||||
ordersDO1.setRefundStatus(String.valueOf(HaokaOrderRefundStatus));
|
||||
ordersMapper.updateById(ordersDO1);
|
||||
}else {
|
||||
// 新增订单
|
||||
ordersDO.setShopId(String.valueOf(shopId));
|
||||
ordersDO.setShopName(shopName);
|
||||
// 真实订单
|
||||
ordersDO.setRealSourceId(orderId);
|
||||
ordersDO.setSourceId(orderId);
|
||||
// 买家备注
|
||||
ordersDO.setBuyerMemo(buyerWords);
|
||||
//证件信息
|
||||
// ordersDO.setIdCardNum(idCardNo);
|
||||
ordersDO.setEncryptIdCardNum(encryptIdCardNo);
|
||||
// ordersDO.setIdCardName(idCardName);
|
||||
ordersDO.setEncryptIdCardName(encryptIdCardName);
|
||||
// 收件人信息
|
||||
// ordersDO.setAddressMobile(postTel);
|
||||
ordersDO.setEncryptAddressMobile(encryptPostTel);
|
||||
// ordersDO.setAddressName(postReceiver);
|
||||
ordersDO.setEncryptAddressName(encryptPostReceiver);
|
||||
// 收件人地址 省
|
||||
ordersDO.setAddressProvince(province.getName());
|
||||
ordersDO.setAddressProvinceCode(province.getId());
|
||||
// 市
|
||||
ordersDO.setAddressCity(city.getName());
|
||||
ordersDO.setAddressCityCode(city.getId());
|
||||
// 区
|
||||
ordersDO.setAddressDistrict(town.getName());
|
||||
ordersDO.setAddressDistrictCode(town.getId());
|
||||
// 街道/镇
|
||||
ordersDO.setTown(street.getName());
|
||||
// 详细地址
|
||||
// ordersDO.setAddress(detail);
|
||||
ordersDO.setEncryptAddress(encryptDetail);
|
||||
orderList.add(ordersDO);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
orderListAll.addAll(orderList);
|
||||
ordersMapper.insertBatch(orderList);
|
||||
}
|
||||
// 执行解密,解密后更新数据库
|
||||
for (List<OrdersDO> ordersDOS : GroupListUtil.groupList(orderListAll, 50)) {
|
||||
batchDecryptOrderAndUpdate(ordersDOS);
|
||||
}
|
||||
}
|
||||
private CipherInfosItem createCipherItem(String cipherText, String authId) {
|
||||
CipherInfosItem item = new CipherInfosItem();
|
||||
item.setCipherText(cipherText);
|
||||
item.setAuthId(authId);
|
||||
return item;
|
||||
}
|
||||
private void updateOrderFields(OrdersDO order, String cipherText, String decryptText) {
|
||||
// 检查并更新每个加密字段
|
||||
if (cipherText.equals(order.getEncryptAddress())) {
|
||||
order.setEncryptAddress(decryptText); // 更新为解密后的值
|
||||
} else if (cipherText.equals(order.getEncryptIdCardName())) {
|
||||
order.setEncryptIdCardName(decryptText);
|
||||
} else if (cipherText.equals(order.getEncryptAddressName())) {
|
||||
order.setEncryptAddressName(decryptText);
|
||||
} else if (cipherText.equals(order.getEncryptIdCardNum())) {
|
||||
order.setEncryptIdCardNum(decryptText);
|
||||
} else if (cipherText.equals(order.getEncryptAddressMobile())) {
|
||||
order.setEncryptAddressMobile(decryptText);
|
||||
}
|
||||
}
|
||||
private void batchDecryptOrderAndUpdate(List<OrdersDO> orderList) {
|
||||
List<CipherInfosItem> cipherInfos = new ArrayList<>();
|
||||
for (OrdersDO ordersDO : orderList) {
|
||||
// 构建 CipherInfosItem 列表
|
||||
cipherInfos.add(createCipherItem(ordersDO.getEncryptAddress(), ordersDO.getRealSourceId()));
|
||||
cipherInfos.add(createCipherItem(ordersDO.getEncryptIdCardName(), ordersDO.getRealSourceId()));
|
||||
cipherInfos.add(createCipherItem(ordersDO.getEncryptAddressName(), ordersDO.getRealSourceId()));
|
||||
cipherInfos.add(createCipherItem(ordersDO.getEncryptIdCardNum(), ordersDO.getRealSourceId()));
|
||||
cipherInfos.add(createCipherItem(ordersDO.getEncryptAddressMobile(), ordersDO.getRealSourceId()));
|
||||
|
||||
}
|
||||
List<DecryptInfosItem> objects = batchDecrypt(cipherInfos);
|
||||
for (DecryptInfosItem object : objects) {
|
||||
String authId = object.getAuthId();
|
||||
String decryptText = object.getDecryptText();
|
||||
String cipherText = object.getCipherText();
|
||||
|
||||
for (OrdersDO ordersDO : orderList) {
|
||||
if (ordersDO.getRealSourceId().equals(authId)) {
|
||||
// 将解密后的字段替换到 order 中
|
||||
updateOrderFields(ordersDO, cipherText, decryptText);
|
||||
}
|
||||
}
|
||||
}
|
||||
ordersMapper.updateBatch(orderList);
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用正则表达式获取手机号
|
||||
* @param skuName
|
||||
* @return
|
||||
*/
|
||||
private String getPlanMobile(String skuName) {
|
||||
// 去除空格
|
||||
String noSpace = StringUtils.deleteWhitespace(skuName);
|
||||
String pattern = "(?<=\\/)\\d{11}";
|
||||
Pattern compile = Pattern.compile(pattern);
|
||||
Matcher matcher = compile.matcher(noSpace);
|
||||
if(matcher.find()){
|
||||
// 找到匹配手机号
|
||||
return matcher.group(1);
|
||||
}else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 分页查询订单
|
||||
* @param accessToken 访问令牌
|
||||
* @param createTimeStart 创建时间起始
|
||||
* @param createTimeEnd 创建时间结束
|
||||
* @return 所有订单数据
|
||||
*/
|
||||
private List<ShopOrderListItem> fetchOrders(AccessToken accessToken, long createTimeStart, long createTimeEnd) {
|
||||
OrderSearchListRequest request = new OrderSearchListRequest();
|
||||
OrderSearchListParam param = request.getParam();
|
||||
// param.setProduct("3473196049974326153");
|
||||
// param.setBType(2L);
|
||||
param.setAfterSaleStatusDesc("refund_success");
|
||||
// param.setTrackingNo("435435");
|
||||
// param.setPresellType(0L);
|
||||
// param.setOrderType(1L);
|
||||
param.setCreateTimeStart(createTimeStart);
|
||||
param.setCreateTimeEnd(createTimeEnd);
|
||||
// param.setAbnormalOrder(1L);
|
||||
// param.setTradeType(1L);
|
||||
// param.setUpdateTimeStart(1617355413L);
|
||||
// param.setUpdateTimeEnd(1617355413L);
|
||||
param.setSize(100L);
|
||||
param.setPage(0L);
|
||||
param.setOrderBy("create_time");
|
||||
param.setOrderAsc(false);
|
||||
// param.setFulfilStatus("no_accept");
|
||||
|
||||
List<ShopOrderListItem> allOrders = new ArrayList<>();
|
||||
|
||||
while (true) {
|
||||
try {
|
||||
OrderSearchListResponse response = request.execute(accessToken);
|
||||
OrderSearchListData data = response.getData();
|
||||
List<ShopOrderListItem> shopOrderList = data.getShopOrderList();
|
||||
Long total = data.getTotal();
|
||||
Long size = data.getSize();
|
||||
Long currentPage = data.getPage();
|
||||
allOrders.addAll(shopOrderList);
|
||||
|
||||
if (currentPage * size >= total) {
|
||||
break;
|
||||
}
|
||||
|
||||
param.setPage(++currentPage);
|
||||
} catch (Exception e) {
|
||||
// do nothing
|
||||
break;
|
||||
}
|
||||
}
|
||||
return allOrders;
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量解密接口
|
||||
* @param cipherInfos 待解密数据 一次性最多50条
|
||||
* @return
|
||||
*/
|
||||
private List<DecryptInfosItem> batchDecrypt(List<CipherInfosItem> cipherInfos){
|
||||
GlobalConfig.initAppKey(SYNC_APP_KEY);
|
||||
GlobalConfig.initAppSecret(SYNC_APP_SECRET);
|
||||
//入参为code
|
||||
AccessToken accessToken= AccessTokenBuilder.build(SYNC_SHOP_ID);
|
||||
OrderBatchDecryptRequest request = new OrderBatchDecryptRequest();
|
||||
OrderBatchDecryptParam param = request.getParam();
|
||||
param.setCipherInfos(cipherInfos);
|
||||
OrderBatchDecryptResponse response = request.execute(accessToken);
|
||||
OrderBatchDecryptData data = response.getData();
|
||||
List<DecryptInfosItem> decryptInfos = data.getDecryptInfos();
|
||||
return decryptInfos;
|
||||
}
|
||||
|
||||
|
||||
public OrderOrderDetailData orderDetail(String shopOrderId) {
|
||||
GlobalConfig.initAppKey(SYNC_APP_KEY);
|
||||
GlobalConfig.initAppSecret(SYNC_APP_SECRET);
|
||||
//入参为code
|
||||
AccessToken accessToken= AccessTokenBuilder.build(SYNC_SHOP_ID);
|
||||
OrderOrderDetailRequest request = new OrderOrderDetailRequest();
|
||||
OrderOrderDetailParam param = request.getParam();
|
||||
param.setShopOrderId(shopOrderId);
|
||||
OrderOrderDetailResponse response = request.execute(accessToken);
|
||||
return response.getData();
|
||||
}
|
||||
public void refreshToken() {
|
||||
//设置appKey和appSecret,全局设置一次
|
||||
GlobalConfig.initAppKey("7381306825771091495");
|
||||
GlobalConfig.initAppSecret("09c06553-b77c-4712-aed9-84cbfe16ca13");
|
||||
//入参为code
|
||||
AccessToken accessToken= AccessTokenBuilder.build(20811777L);
|
||||
String refreshToken = accessToken.getRefreshToken();//16dde1a3-2d6f-4946-aef2-afbd29d2eb92是code
|
||||
TokenRefreshRequest request = new TokenRefreshRequest();
|
||||
TokenRefreshParam param = request.getParam();
|
||||
param.setRefreshToken(refreshToken);
|
||||
param.setGrantType("refresh_token");
|
||||
TokenRefreshResponse response = request.execute(accessToken);
|
||||
String refreshToken1 = response.getData().getRefreshToken();
|
||||
System.out.println(response);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
package cn.iocoder.yudao.module.haoka.service.orderCatch;
|
||||
|
||||
import cn.iocoder.yudao.module.haoka.controller.admin.orderCatch.po.Message;
|
||||
import cn.iocoder.yudao.module.haoka.controller.admin.orderCatch.vo.OrderCatchRepVO;
|
||||
import com.doudian.open.core.AccessToken;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface OrderCatchService {
|
||||
/**
|
||||
* 查询订单列表
|
||||
*/
|
||||
void syncOrder(AccessToken accessToken, long createTimeStart, long createTimeEnd);
|
||||
|
||||
void catchOrders(List<Message> catchRepVO);
|
||||
}
|
|
@ -114,7 +114,7 @@ public class OrdersServiceImpl extends ServiceImpl<OrdersMapper, OrdersDO> imple
|
|||
OnSaleProductPreOrderRespVO onSaleProductPreOrder = onSaleProductService.getOnSaleProductPreOrder(createReqVO.getOnSaleProductId());
|
||||
orders.setAutoType(onSaleProductPreOrder.getParentProduct().getAutoType());
|
||||
orders.setOnSaleProductId(onSaleProductPreOrder.getId());
|
||||
orders.setProducerId(onSaleProductPreOrder.getParentProduct().getId());
|
||||
orders.setProductId(onSaleProductPreOrder.getParentProduct().getId());
|
||||
orders.setSuperiorProductConfigId(onSaleProductPreOrder.getSuperiorProductConfigRespVO().getId());
|
||||
orders.setSuperiorApiId(onSaleProductPreOrder.getSuperiorApiRespVO().getId());
|
||||
// 订单就绪
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
package cn.iocoder.yudao.module.haoka.service.ordersynclog;
|
||||
|
||||
import java.util.*;
|
||||
import jakarta.validation.*;
|
||||
import cn.iocoder.yudao.module.haoka.controller.admin.ordersynclog.vo.*;
|
||||
import cn.iocoder.yudao.module.haoka.dal.dataobject.ordersynclog.OrderSyncLogDO;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||
|
||||
/**
|
||||
* 抓单记录 Service 接口
|
||||
*
|
||||
* @author 超级管理员
|
||||
*/
|
||||
public interface OrderSyncLogService {
|
||||
|
||||
/**
|
||||
* 创建抓单记录
|
||||
*
|
||||
* @param createReqVO 创建信息
|
||||
* @return 编号
|
||||
*/
|
||||
Long createOrderSyncLog(@Valid OrderSyncLogSaveReqVO createReqVO);
|
||||
|
||||
/**
|
||||
* 更新抓单记录
|
||||
*
|
||||
* @param updateReqVO 更新信息
|
||||
*/
|
||||
void updateOrderSyncLog(@Valid OrderSyncLogSaveReqVO updateReqVO);
|
||||
|
||||
/**
|
||||
* 删除抓单记录
|
||||
*
|
||||
* @param id 编号
|
||||
*/
|
||||
void deleteOrderSyncLog(Long id);
|
||||
|
||||
/**
|
||||
* 获得抓单记录
|
||||
*
|
||||
* @param id 编号
|
||||
* @return 抓单记录
|
||||
*/
|
||||
OrderSyncLogDO getOrderSyncLog(Long id);
|
||||
|
||||
/**
|
||||
* 获得抓单记录分页
|
||||
*
|
||||
* @param pageReqVO 分页查询
|
||||
* @return 抓单记录分页
|
||||
*/
|
||||
PageResult<OrderSyncLogDO> getOrderSyncLogPage(OrderSyncLogPageReqVO pageReqVO);
|
||||
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
package cn.iocoder.yudao.module.haoka.service.ordersynclog;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.*;
|
||||
import cn.iocoder.yudao.module.haoka.controller.admin.ordersynclog.vo.*;
|
||||
import cn.iocoder.yudao.module.haoka.dal.dataobject.ordersynclog.OrderSyncLogDO;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||
|
||||
import cn.iocoder.yudao.module.haoka.dal.mysql.ordersynclog.OrderSyncLogMapper;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
import static cn.iocoder.yudao.module.haoka.enums.ErrorCodeConstants.*;
|
||||
|
||||
/**
|
||||
* 抓单记录 Service 实现类
|
||||
*
|
||||
* @author 超级管理员
|
||||
*/
|
||||
@Service
|
||||
@Validated
|
||||
public class OrderSyncLogServiceImpl implements OrderSyncLogService {
|
||||
|
||||
@Resource
|
||||
private OrderSyncLogMapper orderSyncLogMapper;
|
||||
|
||||
@Override
|
||||
public Long createOrderSyncLog(OrderSyncLogSaveReqVO createReqVO) {
|
||||
// 插入
|
||||
OrderSyncLogDO orderSyncLog = BeanUtils.toBean(createReqVO, OrderSyncLogDO.class);
|
||||
orderSyncLogMapper.insert(orderSyncLog);
|
||||
// 返回
|
||||
return orderSyncLog.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateOrderSyncLog(OrderSyncLogSaveReqVO updateReqVO) {
|
||||
// 校验存在
|
||||
validateOrderSyncLogExists(updateReqVO.getId());
|
||||
// 更新
|
||||
OrderSyncLogDO updateObj = BeanUtils.toBean(updateReqVO, OrderSyncLogDO.class);
|
||||
orderSyncLogMapper.updateById(updateObj);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteOrderSyncLog(Long id) {
|
||||
// 校验存在
|
||||
validateOrderSyncLogExists(id);
|
||||
// 删除
|
||||
orderSyncLogMapper.deleteById(id);
|
||||
}
|
||||
|
||||
private void validateOrderSyncLogExists(Long id) {
|
||||
if (orderSyncLogMapper.selectById(id) == null) {
|
||||
throw exception(ORDER_SYNC_LOG_NOT_EXISTS);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public OrderSyncLogDO getOrderSyncLog(Long id) {
|
||||
return orderSyncLogMapper.selectById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageResult<OrderSyncLogDO> getOrderSyncLogPage(OrderSyncLogPageReqVO pageReqVO) {
|
||||
return orderSyncLogMapper.selectPage(pageReqVO);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
package cn.iocoder.yudao.module.haoka.utils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author xiongxiong
|
||||
* @description: 数组分片工具
|
||||
* @date 2024/12/30
|
||||
*/
|
||||
public class GroupListUtil {
|
||||
public static <T> List<List<T>> groupList(List<T> originalList, int groupSize) {
|
||||
if (groupSize <= 0) {
|
||||
throw new IllegalArgumentException("Group size must be positive.");
|
||||
}
|
||||
List<List<T>> result = new ArrayList<>();
|
||||
int size = originalList.size();
|
||||
for (int i = 0; i < size; i += groupSize) {
|
||||
int endIndex = i + groupSize;
|
||||
if (endIndex > size) {
|
||||
endIndex = size;
|
||||
}
|
||||
List<T> sub = new ArrayList<>(originalList.subList(i, endIndex));
|
||||
result.add(sub);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
<?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="cn.iocoder.yudao.module.haoka.dal.mysql.ordersynclog.OrderSyncLogMapper">
|
||||
|
||||
<!--
|
||||
一般情况下,尽可能使用 Mapper 进行 CRUD 增删改查即可。
|
||||
无法满足的场景,例如说多表关联查询,才使用 XML 编写 SQL。
|
||||
代码生成器暂时只生成 Mapper XML 文件本身,更多推荐 MybatisX 快速开发插件来生成查询。
|
||||
文档可见:https://www.iocoder.cn/MyBatis/x-plugins/
|
||||
-->
|
||||
|
||||
</mapper>
|
|
@ -0,0 +1,55 @@
|
|||
package cn.iocoder.yudao.module.haoka.service.orderCatch;
|
||||
|
||||
import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
|
||||
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_orderDetail.data.OrderOrderDetailData;
|
||||
import com.doudian.open.gson.Gson;
|
||||
import com.doudian.open.msg.refund_RefundCreated.param.RefundRefundCreatedParam;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Import(DouDianOrderCatchServiceImpl.class)
|
||||
public class DouDianOrderCatchServiceImplTest extends BaseDbUnitTest {
|
||||
@Resource
|
||||
private DouDianOrderCatchServiceImpl orderCatchService;
|
||||
@Test
|
||||
public void syncOrder() {
|
||||
// long createTimeStart, long createTimeEnd
|
||||
// orderCatchService.syncOrder();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOrderDetail() {
|
||||
// 创建 DouDianOrderCatchServiceImpl 对象
|
||||
DouDianOrderCatchServiceImpl service = new DouDianOrderCatchServiceImpl();
|
||||
|
||||
// 模拟传入的 shopOrderId
|
||||
String shopOrderId = "6939514703116113670";
|
||||
|
||||
// 调用 orderDetail 方法
|
||||
OrderOrderDetailData data = service.orderDetail(shopOrderId);
|
||||
|
||||
// 进行断言,检查返回的数据是否符合预期
|
||||
System.out.println(data);
|
||||
// 可以根据具体的业务逻辑添加更多的断言
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOrderDetail1() {
|
||||
String orderString = "[{\"tag\":\"xxx\",\"msgId\":\"0443477XXXXXXX48874::xxx:1618990587:6837374XXXXXXX89128\",\"data\":{\"aftersale_id\":7000893114000949000,\"aftersale_status\":6,\"aftersale_type\":2,\"apply_time\":1630022518,\"p_id\":4835804142146757000,\"reason_code\":1,\"refund_amount\":8900,\"refund_post_amount\":0,\"refund_voucher_num\":0,\"return_book_info\":{\"encrypt_addr\":\"北京市海淀区海淀街道海淀街道海淀大街x号xx大厦x楼xxx室\",\"send_type\":1,\"time_begin\":\"09:00\",\"time_end\":\"11:00\"},\"s_id\":4835804142146757000,\"shop_id\":10437917,\"update_time\":\"2022-09-02T10:27:50+08:00\"}}]";
|
||||
Gson gson = new Gson();
|
||||
List<Message> parse = JSON.parseArray(orderString, Message.class);
|
||||
for (Message message : parse) {
|
||||
RefundRefundCreatedParam refundRefundCreatedParam = gson.fromJson(message.getData()+"", RefundRefundCreatedParam.class);
|
||||
System.out.println();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,146 @@
|
|||
package cn.iocoder.yudao.module.haoka.service.ordersynclog;
|
||||
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
|
||||
import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
|
||||
|
||||
import cn.iocoder.yudao.module.haoka.controller.admin.ordersynclog.vo.*;
|
||||
import cn.iocoder.yudao.module.haoka.dal.dataobject.ordersynclog.OrderSyncLogDO;
|
||||
import cn.iocoder.yudao.module.haoka.dal.mysql.ordersynclog.OrderSyncLogMapper;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import java.util.*;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import static cn.hutool.core.util.RandomUtil.*;
|
||||
import static cn.iocoder.yudao.module.haoka.enums.ErrorCodeConstants.*;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.*;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*;
|
||||
import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.*;
|
||||
import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.*;
|
||||
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.*;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
/**
|
||||
* {@link OrderSyncLogServiceImpl} 的单元测试类
|
||||
*
|
||||
* @author 超级管理员
|
||||
*/
|
||||
@Import(OrderSyncLogServiceImpl.class)
|
||||
public class OrderSyncLogServiceImplTest extends BaseDbUnitTest {
|
||||
|
||||
@Resource
|
||||
private OrderSyncLogServiceImpl orderSyncLogService;
|
||||
|
||||
@Resource
|
||||
private OrderSyncLogMapper orderSyncLogMapper;
|
||||
|
||||
@Test
|
||||
public void testCreateOrderSyncLog_success() {
|
||||
// 准备参数
|
||||
OrderSyncLogSaveReqVO createReqVO = randomPojo(OrderSyncLogSaveReqVO.class).setId(null);
|
||||
|
||||
// 调用
|
||||
Long orderSyncLogId = orderSyncLogService.createOrderSyncLog(createReqVO);
|
||||
// 断言
|
||||
assertNotNull(orderSyncLogId);
|
||||
// 校验记录的属性是否正确
|
||||
OrderSyncLogDO orderSyncLog = orderSyncLogMapper.selectById(orderSyncLogId);
|
||||
assertPojoEquals(createReqVO, orderSyncLog, "id");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateOrderSyncLog_success() {
|
||||
// mock 数据
|
||||
OrderSyncLogDO dbOrderSyncLog = randomPojo(OrderSyncLogDO.class);
|
||||
orderSyncLogMapper.insert(dbOrderSyncLog);// @Sql: 先插入出一条存在的数据
|
||||
// 准备参数
|
||||
OrderSyncLogSaveReqVO updateReqVO = randomPojo(OrderSyncLogSaveReqVO.class, o -> {
|
||||
o.setId(dbOrderSyncLog.getId()); // 设置更新的 ID
|
||||
});
|
||||
|
||||
// 调用
|
||||
orderSyncLogService.updateOrderSyncLog(updateReqVO);
|
||||
// 校验是否更新正确
|
||||
OrderSyncLogDO orderSyncLog = orderSyncLogMapper.selectById(updateReqVO.getId()); // 获取最新的
|
||||
assertPojoEquals(updateReqVO, orderSyncLog);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateOrderSyncLog_notExists() {
|
||||
// 准备参数
|
||||
OrderSyncLogSaveReqVO updateReqVO = randomPojo(OrderSyncLogSaveReqVO.class);
|
||||
|
||||
// 调用, 并断言异常
|
||||
assertServiceException(() -> orderSyncLogService.updateOrderSyncLog(updateReqVO), ORDER_SYNC_LOG_NOT_EXISTS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteOrderSyncLog_success() {
|
||||
// mock 数据
|
||||
OrderSyncLogDO dbOrderSyncLog = randomPojo(OrderSyncLogDO.class);
|
||||
orderSyncLogMapper.insert(dbOrderSyncLog);// @Sql: 先插入出一条存在的数据
|
||||
// 准备参数
|
||||
Long id = dbOrderSyncLog.getId();
|
||||
|
||||
// 调用
|
||||
orderSyncLogService.deleteOrderSyncLog(id);
|
||||
// 校验数据不存在了
|
||||
assertNull(orderSyncLogMapper.selectById(id));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteOrderSyncLog_notExists() {
|
||||
// 准备参数
|
||||
Long id = randomLongId();
|
||||
|
||||
// 调用, 并断言异常
|
||||
assertServiceException(() -> orderSyncLogService.deleteOrderSyncLog(id), ORDER_SYNC_LOG_NOT_EXISTS);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Disabled // TODO 请修改 null 为需要的值,然后删除 @Disabled 注解
|
||||
public void testGetOrderSyncLogPage() {
|
||||
// mock 数据
|
||||
OrderSyncLogDO dbOrderSyncLog = randomPojo(OrderSyncLogDO.class, o -> { // 等会查询到
|
||||
o.setSyncType(null);
|
||||
o.setSyncShopId(null);
|
||||
o.setSyncEndTime(null);
|
||||
o.setSyncCreateTime(null);
|
||||
o.setCreateTime(null);
|
||||
});
|
||||
orderSyncLogMapper.insert(dbOrderSyncLog);
|
||||
// 测试 syncType 不匹配
|
||||
orderSyncLogMapper.insert(cloneIgnoreId(dbOrderSyncLog, o -> o.setSyncType(null)));
|
||||
// 测试 syncShopId 不匹配
|
||||
orderSyncLogMapper.insert(cloneIgnoreId(dbOrderSyncLog, o -> o.setSyncShopId(null)));
|
||||
// 测试 syncEndTime 不匹配
|
||||
orderSyncLogMapper.insert(cloneIgnoreId(dbOrderSyncLog, o -> o.setSyncEndTime(null)));
|
||||
// 测试 syncCreateTime 不匹配
|
||||
orderSyncLogMapper.insert(cloneIgnoreId(dbOrderSyncLog, o -> o.setSyncCreateTime(null)));
|
||||
// 测试 createTime 不匹配
|
||||
orderSyncLogMapper.insert(cloneIgnoreId(dbOrderSyncLog, o -> o.setCreateTime(null)));
|
||||
// 准备参数
|
||||
OrderSyncLogPageReqVO reqVO = new OrderSyncLogPageReqVO();
|
||||
reqVO.setSyncType(null);
|
||||
reqVO.setSyncShopId(null);
|
||||
// reqVO.setSyncEndTime(buildBetweenTime(2023, 2, 1, 2023, 2, 28));
|
||||
// reqVO.setSyncCreateTime(buildBetweenTime(2023, 2, 1, 2023, 2, 28));
|
||||
reqVO.setCreateTime(buildBetweenTime(2023, 2, 1, 2023, 2, 28));
|
||||
|
||||
// 调用
|
||||
PageResult<OrderSyncLogDO> pageResult = orderSyncLogService.getOrderSyncLogPage(reqVO);
|
||||
// 断言
|
||||
assertEquals(1, pageResult.getTotal());
|
||||
assertEquals(1, pageResult.getList().size());
|
||||
assertPojoEquals(dbOrderSyncLog, pageResult.getList().get(0));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
-- 订单新增参数
|
||||
delete from haoka_orders;
|
||||
ALTER TABLE haoka_orders
|
||||
ADD COLUMN shop_id varchar(50) COMMENT '店铺ID' AFTER is_urgent,
|
||||
ADD COLUMN shop_name varchar(50) COMMENT '店铺名称' AFTER shop_id,
|
||||
ADD COLUMN room_id varchar(50) COMMENT '直播间ID' AFTER shop_name,
|
||||
ADD COLUMN room_name varchar(50) COMMENT '直播间名称' AFTER room_id,
|
||||
ADD COLUMN sales_attribution varchar(50) COMMENT '销售归属' AFTER room_name,
|
||||
ADD COLUMN sales_attribution_name varchar(50) COMMENT '销售归属名称' AFTER sales_attribution;
|
|
@ -0,0 +1,70 @@
|
|||
-- 菜单 SQL
|
||||
INSERT INTO system_menu(
|
||||
name, permission, type, sort, parent_id,
|
||||
path, icon, component, status, component_name
|
||||
)
|
||||
VALUES (
|
||||
'抓单记录管理', '', 2, 0, 3016,
|
||||
'order-sync-log', '', 'haoka/ordersynclog/index', 0, 'OrderSyncLog'
|
||||
);
|
||||
|
||||
-- 按钮父菜单ID
|
||||
-- 暂时只支持 MySQL。如果你是 Oracle、PostgreSQL、SQLServer 的话,需要手动修改 @parentId 的部分的代码
|
||||
SELECT @parentId := LAST_INSERT_ID();
|
||||
|
||||
-- 按钮 SQL
|
||||
INSERT INTO system_menu(
|
||||
name, permission, type, sort, parent_id,
|
||||
path, icon, component, status
|
||||
)
|
||||
VALUES (
|
||||
'抓单记录查询', 'haoka:order-sync-log:query', 3, 1, @parentId,
|
||||
'', '', '', 0
|
||||
);
|
||||
INSERT INTO system_menu(
|
||||
name, permission, type, sort, parent_id,
|
||||
path, icon, component, status
|
||||
)
|
||||
VALUES (
|
||||
'抓单记录创建', 'haoka:order-sync-log:create', 3, 2, @parentId,
|
||||
'', '', '', 0
|
||||
);
|
||||
INSERT INTO system_menu(
|
||||
name, permission, type, sort, parent_id,
|
||||
path, icon, component, status
|
||||
)
|
||||
VALUES (
|
||||
'抓单记录更新', 'haoka:order-sync-log:update', 3, 3, @parentId,
|
||||
'', '', '', 0
|
||||
);
|
||||
INSERT INTO system_menu(
|
||||
name, permission, type, sort, parent_id,
|
||||
path, icon, component, status
|
||||
)
|
||||
VALUES (
|
||||
'抓单记录删除', 'haoka:order-sync-log:delete', 3, 4, @parentId,
|
||||
'', '', '', 0
|
||||
);
|
||||
INSERT INTO system_menu(
|
||||
name, permission, type, sort, parent_id,
|
||||
path, icon, component, status
|
||||
)
|
||||
VALUES (
|
||||
'抓单记录导出', 'haoka:order-sync-log:export', 3, 5, @parentId,
|
||||
'', '', '', 0
|
||||
);
|
||||
CREATE TABLE `haoka_order_sync_log` (
|
||||
`id` bigint(20) NOT NULL COMMENT '主键ID',
|
||||
`sync_type` varchar(50) DEFAULT NULL COMMENT '同步类型(电商渠道)',
|
||||
`sync_shop_id` varchar(50) DEFAULT NULL COMMENT '同步店铺ID',
|
||||
`sync_end_time` bigint(20) DEFAULT NULL COMMENT '同步结束时间',
|
||||
`sync_create_time` bigint(20) DEFAULT NULL COMMENT '同步开始时间',
|
||||
`creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '创建者',
|
||||
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci 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 COMMENT='抓单记录表';
|
||||
|
Loading…
Reference in New Issue