This commit is contained in:
雷欧(林平凡)
2024-11-08 09:18:27 +08:00
parent 87e0e7693f
commit 19f1095a7c
9 changed files with 414 additions and 51 deletions

1
.idea/dataSources.xml generated
View File

@@ -11,6 +11,7 @@
<jdbc-additional-properties>
<property name="com.intellij.clouds.kubernetes.db.host.port" />
<property name="com.intellij.clouds.kubernetes.db.enabled" value="false" />
<property name="com.intellij.clouds.kubernetes.db.resource.type" value="Deployment" />
<property name="com.intellij.clouds.kubernetes.db.container.port" />
</jdbc-additional-properties>
<working-dir>$ProjectFileDir$</working-dir>

8
.idea/diff-generator.xml generated Normal file
View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="DiffGenerationConfig" isInitGenerateDdl="true">
<option name="initGenerateDdl" value="true" />
<option name="sourceModelValue" value="jd:jd" />
<option name="targetDbValue" value="eb8a6f9c-c8ff-4224-9875-8dd3cf91a680" />
</component>
</project>

4
.idea/jpb-settings.xml generated Normal file
View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="DatabaseMigrationSettings" lastSelectedDirectory="src\main\java\cn\van\business\model" />
</project>

7
.idea/sqldialects.xml generated Normal file
View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="SqlDialectMappings">
<file url="file://$PROJECT_DIR$/src/main/java/cn/van/business/model/update-schema.sql" dialect="GenericSQL" />
<file url="PROJECT" dialect="MySQL" />
</component>
</project>

View File

@@ -0,0 +1,39 @@
package cn.van.business.controller;
import cn.van.business.util.JDUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
/**
* @author Leo
* @version 1.0
* @create 2024/11/7 13:39
* @description
*/
@RestController
@RequestMapping("order")
public class OrderController {
public static String TOKEN = "cc0313";
@Resource
private JDUtils jdUtils;
public boolean checkToken (String token){
return TOKEN.equals(token);
}
@RequestMapping("/refreshHistory")
@ResponseBody
public String refreshHistory(String token) throws Exception {
if (checkToken(token)) {
jdUtils.fetchHistoricalOrders();
}
return "OK";
}
}

View File

@@ -0,0 +1,93 @@
package cn.van.business.model;
import javax.persistence.*;
/**
* @author Leo
* @version 1.0
* @create 2024/11/7 10:58
* @description
*/
@Entity
@Table(name = "goods_info")
public class GoodsInfoVO {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "owner")
private String owner;
@Column(name = "main_sku_id")
private String mainSkuId;
@Column(name = "product_id")
private String productId;
@Column(name = "image_url")
private String imageUrl;
@Column(name = "shop_name")
private String shopName;
@Column(name = "shop_id")
private String shopId;
// Getters and Setters
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getOwner() {
return owner;
}
public void setOwner(String owner) {
this.owner = owner;
}
public String getMainSkuId() {
return mainSkuId;
}
public void setMainSkuId(String mainSkuId) {
this.mainSkuId = mainSkuId;
}
public String getProductId() {
return productId;
}
public void setProductId(String productId) {
this.productId = productId;
}
public String getImageUrl() {
return imageUrl;
}
public void setImageUrl(String imageUrl) {
this.imageUrl = imageUrl;
}
public String getShopName() {
return shopName;
}
public void setShopName(String shopName) {
this.shopName = shopName;
}
public String getShopId() {
return shopId;
}
public void setShopId(String shopId) {
this.shopId = shopId;
}
}

View File

@@ -13,7 +13,7 @@ import java.util.Date;
@Entity
@Table(name = "order_rows")
public class OrderRowVO {
public class OrderRow {
@Id
@Column(name = "id")
private String id;
@@ -30,6 +30,7 @@ public class OrderRowVO {
@Temporal(TemporalType.TIMESTAMP)
@Column(name = "finish_time")
/**完成时间(购买用户确认收货时间),格式yyyy-MM-dd HH:mm:ss*/
private Date finishTime;
@Temporal(TemporalType.TIMESTAMP)
@@ -49,12 +50,21 @@ public class OrderRowVO {
private Long skuId;
@Column(name = "sku_name")
/**
* 商品名称
* */
private String skuName;
@Column(name = "sku_num")
/**
*
* 商品数量*/
private Integer skuNum;
@Column(name = "sku_return_num")
/**
*
* 商品已退货数量*/
private Integer skuReturnNum;
@Column(name = "sku_frozen_num")
@@ -64,6 +74,7 @@ public class OrderRowVO {
private Double price;
@Column(name = "commission_rate")
/**佣金比例(投放的广告主计划比例)*/
private Double commissionRate;
@Column(name = "sub_side_rate")
@@ -155,11 +166,8 @@ public class OrderRowVO {
@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "goods_info_id", referencedColumnName = "id")
private GoodsInfo goodsInfo;
private GoodsInfoVO goodsInfo;
@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "category_info_id", referencedColumnName = "id")
private CategoryInfoVO categoryInfoVO;
@Column(name = "express_status")
private Integer expressStatus;
@@ -179,8 +187,6 @@ public class OrderRowVO {
@Column(name = "order_tag")
private String orderTag;
public OrderRowVO() {
}
public String getId() {
return id;
@@ -542,22 +548,14 @@ public class OrderRowVO {
this.rid = rid;
}
public GoodsInfo getGoodsInfo() {
public GoodsInfoVO getGoodsInfo() {
return goodsInfo;
}
public void setGoodsInfo(GoodsInfo goodsInfo) {
public void setGoodsInfo(GoodsInfoVO goodsInfo) {
this.goodsInfo = goodsInfo;
}
public CategoryInfo getCategoryInfo() {
return categoryInfo;
}
public void setCategoryInfo(CategoryInfo categoryInfo) {
this.categoryInfo = categoryInfo;
}
public Integer getExpressStatus() {
return expressStatus;
}

View File

@@ -0,0 +1,74 @@
CREATE TABLE goods_info
(
id BIGINT AUTO_INCREMENT NOT NULL,
owner VARCHAR(255) NULL,
main_sku_id VARCHAR(255) NULL,
product_id VARCHAR(255) NULL,
image_url VARCHAR(255) NULL,
shop_name VARCHAR(255) NULL,
shop_id VARCHAR(255) NULL,
CONSTRAINT pk_goods_info PRIMARY KEY (id)
);
CREATE TABLE order_rows
(
id VARCHAR(255) NOT NULL,
order_id BIGINT NULL,
parent_id BIGINT NULL,
order_time datetime NULL,
finish_time datetime NULL,
modify_time datetime NULL,
order_emt INT NULL,
plus INT NULL,
union_id BIGINT NULL,
sku_id BIGINT NULL,
sku_name VARCHAR(255) NULL,
sku_num INT NULL,
sku_return_num INT NULL,
sku_frozen_num INT NULL,
price DOUBLE NULL,
commission_rate DOUBLE NULL,
sub_side_rate DOUBLE NULL,
subsidy_rate DOUBLE NULL,
final_rate DOUBLE NULL,
estimate_cos_price DOUBLE NULL,
estimate_fee DOUBLE NULL,
actual_cos_price DOUBLE NULL,
actual_fee DOUBLE NULL,
valid_code INT NULL,
trace_type INT NULL,
position_id BIGINT NULL,
site_id BIGINT NULL,
union_alias VARCHAR(255) NULL,
pid VARCHAR(255) NULL,
cid1 BIGINT NULL,
cid2 BIGINT NULL,
cid3 BIGINT NULL,
sub_union_id VARCHAR(255) NULL,
union_tag VARCHAR(255) NULL,
pop_id BIGINT NULL,
ext1 VARCHAR(255) NULL,
pay_month VARCHAR(255) NULL,
cp_act_id BIGINT NULL,
union_role INT NULL,
gift_coupon_ocs_amount DOUBLE NULL,
gift_coupon_key VARCHAR(255) NULL,
balance_ext VARCHAR(255) NULL,
sign VARCHAR(255) NULL,
pro_price_amount DOUBLE NULL,
rid BIGINT NULL,
goods_info_id BIGINT NULL,
express_status INT NULL,
channel_id BIGINT NULL,
sku_tag VARCHAR(255) NULL,
item_id VARCHAR(255) NULL,
caller_item_id VARCHAR(255) NULL,
order_tag VARCHAR(255) NULL,
CONSTRAINT pk_order_rows PRIMARY KEY (id)
);
ALTER TABLE order_rows
ADD CONSTRAINT uc_order_rows_goods_info UNIQUE (goods_info_id);
ALTER TABLE order_rows
ADD CONSTRAINT FK_ORDER_ROWS_ON_GOODS_INFO FOREIGN KEY (goods_info_id) REFERENCES goods_info (id);

View File

@@ -1,22 +1,32 @@
package cn.van.business.util;
import cn.van.business.model.GoodsInfoVO;
import cn.van.business.model.OrderRow;
import cn.van.business.repository.OrderRowRepository;
import com.alibaba.fastjson2.util.DateUtils;
import com.jd.open.api.sdk.DefaultJdClient;
import com.jd.open.api.sdk.JdClient;
import com.jd.open.api.sdk.domain.kplunion.OrderService.request.query.OrderRowReq;
import com.jd.open.api.sdk.domain.kplunion.OrderService.response.query.GoodsInfo;
import com.jd.open.api.sdk.domain.kplunion.OrderService.response.query.OrderRowResp;
import com.jd.open.api.sdk.request.kplunion.UnionOpenOrderRowQueryRequest;
import com.jd.open.api.sdk.response.kplunion.UnionOpenOrderRowQueryResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.SetOperations;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import static java.lang.Thread.sleep;
/**
* @author Leo
* @version 1.0
@@ -36,29 +46,19 @@ public class JDUtils {
@Autowired
private OrderRowRepository orderRowRepository;
private static final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
/**
* 写两个方法,一个拉最新的订单。一个拉历史订单
* 拉取最新的订单
*/
@Scheduled(cron = "0 0 * * * ?")
public void getHistoryOrder() {
// 因为只能一小时一小时的拉取订单,所以要循环的倒推去拉取历史订单,存到数据库
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
// 当前是2024-10-10 11:46:00 , 则生成一个 2024-10-10 11:00:00
@Scheduled(cron = "0 * * * * ?") // 每分钟执行一次
public void fetchLatestOrder() throws Exception {
LocalDateTime now = LocalDateTime.now();
LocalDateTime lastMinute = now.minusMinutes(1).withSecond(0).withNano(0);
}
@Scheduled(cron = "0 * * * * ?")
public void getNewOrder() throws Exception {
//一分钟一分钟拉取 2020-01-02 21:23:00
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String startTime = sdf.format(new Date(System.currentTimeMillis() - 1000 * 60));
String endTime = sdf.format(new Date());
UnionOpenOrderRowQueryResponse response = getUnionOpenOrderRowQueryResponse(startTime, endTime);
UnionOpenOrderRowQueryResponse response = fetchOrdersForDateTime(lastMinute, true); // 真实代表实时订单
if (response != null){
int code = response.getQueryResult().getCode();
System.out.println("响应码:" + code);
if (code == 200) {
if (response.getQueryResult().getCode() == 200) {
OrderRowResp[] orderRowResps = response.getQueryResult().getData();
@@ -67,16 +67,149 @@ public class JDUtils {
}
for (OrderRowResp orderRowResp : orderRowResps) {
// 固化到数据库
OrderRow orderRow = createOrderRow(orderRowResp);
// 订单号不存在就保存,存在就更新订单状态
orderRowRepository.save(orderRow);
}
}
}
}
}
/**
* 拉取历史订单
*/
public void fetchHistoricalOrders() throws Exception {
// 从设定的开始日期到昨天的同一时间
LocalDateTime startDate = LocalDateTime.of(2024, 7, 1, 0, 0);
LocalDateTime now = LocalDateTime.now();
LocalDateTime lastHour = now.minusHours(1).withMinute(0).withSecond(0).withNano(0);
while (!startDate.isEqual(lastHour)) {
UnionOpenOrderRowQueryResponse response = fetchOrdersForDateTime(startDate, false); // 假的代表历史订单
if (response != null){
int code = response.getQueryResult().getCode();
if (code == 200) {
if (response.getQueryResult().getCode() == 200) {
OrderRowResp[] orderRowResps = response.getQueryResult().getData();
if (orderRowResps == null) {
continue;
}
for (OrderRowResp orderRowResp : orderRowResps) {
// 固化到数据库
OrderRow orderRow = createOrderRow(orderRowResp);
// 订单号不存在就保存,存在就更新订单状态
orderRowRepository.save(orderRow);
}
}
}
sleep(1000);
}
startDate = startDate.plusHours(1);
}
}
/**
* 根据指定的日期时间拉取订单
*/
public UnionOpenOrderRowQueryResponse fetchOrdersForDateTime(LocalDateTime dateTime, boolean isRealTime) throws Exception {
LocalDateTime endTime = isRealTime ? dateTime.plusMinutes(1) : dateTime.plusHours(1);
String key = dateTime.format(DATE_TIME_FORMATTER);
String hourRange = isRealTime ? "minute" : "hour";
SetOperations<String, String> setOps = redisTemplate.opsForSet();
// 检查是否标记为已拉取
if (Boolean.TRUE.equals(setOps.isMember(key, hourRange))) {
System.out.println(dateTime.format(DATE_TIME_FORMATTER) + " 已经拉取,跳过");
return null;
}
// 调用 API 以拉取订单
UnionOpenOrderRowQueryResponse unionOpenOrderRowQueryResponse = getUnionOpenOrderRowQueryResponse(dateTime, endTime);
// 标记已拉取
setOps.add(key, hourRange);
return unionOpenOrderRowQueryResponse;
}
/**
* 将 响应参数转化为 OrderRow并返回
* */
private static OrderRow createOrderRow(OrderRowResp orderRowResp) {
OrderRow orderRow = new OrderRow();
orderRow.setOrderId(orderRowResp.getOrderId());
orderRow.setSkuId(orderRowResp.getSkuId());
orderRow.setSkuName(orderRowResp.getSkuName());
orderRow.setItemId(orderRowResp.getItemId());
orderRow.setSkuNum(orderRowResp.getSkuNum());
orderRow.setPrice(orderRowResp.getPrice());
orderRow.setActualCosPrice(orderRowResp.getActualCosPrice());
orderRow.setActualFee(orderRowResp.getActualFee());
orderRow.setEstimateCosPrice(orderRowResp.getEstimateCosPrice());
orderRow.setEstimateFee(orderRowResp.getEstimateFee());
orderRow.setSubSideRate(orderRowResp.getSubSideRate());
orderRow.setSubsidyRate(orderRowResp.getSubsidyRate());
orderRow.setCommissionRate(orderRowResp.getCommissionRate());
orderRow.setFinalRate(orderRowResp.getFinalRate());
orderRowRepository.save(orderRowResp);
}
}
}
orderRow.setOrderTime(DateUtils.parseDate(orderRowResp.getOrderTime()));
orderRow.setFinishTime(DateUtils.parseDate(orderRowResp.getFinishTime()));
orderRow.setOrderTag(orderRowResp.getOrderTag());
orderRow.setOrderEmt(orderRowResp.getOrderEmt());
orderRow.setUnionId(orderRowResp.getUnionId());
orderRow.setUnionRole(orderRowResp.getUnionRole());
orderRow.setUnionAlias(orderRowResp.getUnionAlias());
orderRow.setUnionTag(orderRowResp.getUnionTag());
orderRow.setTraceType(orderRowResp.getTraceType());
orderRow.setValidCode(orderRowResp.getValidCode());
orderRow.setPayMonth(orderRowResp.getPayMonth());
orderRow.setSiteId(orderRowResp.getSiteId());
orderRow.setParentId(orderRowResp.getParentId());
GoodsInfo goodsInfo = orderRowResp.getGoodsInfo();
GoodsInfoVO goodsInfoVO = new GoodsInfoVO();
goodsInfoVO.setShopId(String.valueOf(goodsInfo.getShopId()));
goodsInfoVO.setShopName(goodsInfo.getShopName());
goodsInfoVO.setOwner(goodsInfo.getOwner());
goodsInfoVO.setProductId(String.valueOf(goodsInfo.getProductId()));
goodsInfoVO.setImageUrl(goodsInfo.getImageUrl());
orderRow.setGoodsInfo(goodsInfoVO);
orderRow.setCallerItemId(orderRowResp.getCallerItemId());
orderRow.setPid(orderRowResp.getPid());
orderRow.setCid1(orderRowResp.getCid1());
orderRow.setCid2(orderRowResp.getCid2());
orderRow.setCid3(orderRowResp.getCid3());
orderRow.setChannelId(orderRowResp.getChannelId());
orderRow.setProPriceAmount(orderRowResp.getProPriceAmount());
orderRow.setSkuFrozenNum(orderRowResp.getSkuFrozenNum());
orderRow.setSkuReturnNum(orderRowResp.getSkuReturnNum());
orderRow.setSkuTag(orderRowResp.getSkuTag());
orderRow.setPositionId(orderRowResp.getPositionId());
orderRow.setPopId(orderRowResp.getPopId());
orderRow.setRid(orderRowResp.getRid());
orderRow.setPlus(orderRowResp.getPlus());
orderRow.setCpActId(orderRowResp.getCpActId());
orderRow.setGiftCouponKey(orderRowResp.getGiftCouponKey());
orderRow.setModifyTime(new Date());
orderRow.setSign(orderRowResp.getSign());
orderRow.setBalanceExt(orderRowResp.getBalanceExt());
orderRow.setExpressStatus(orderRowResp.getExpressStatus());
orderRow.setExt1(orderRowResp.getExt1());
orderRow.setSubUnionId(orderRowResp.getSubUnionId());
orderRow.setGiftCouponOcsAmount(orderRowResp.getGiftCouponOcsAmount());
orderRow.setTraceType(orderRowResp.getTraceType());
orderRow.setExpressStatus(orderRowResp.getExpressStatus());
orderRow.setTraceType(orderRowResp.getTraceType());
orderRow.setId(orderRowResp.getId());
orderRow.setValidCode(orderRowResp.getValidCode());
orderRow.setExpressStatus(orderRowResp.getExpressStatus());
orderRow.setTraceType(orderRowResp.getTraceType());
return orderRow;
}
/**
@@ -87,7 +220,13 @@ public class JDUtils {
* @return
* @throws Exception
*/
public UnionOpenOrderRowQueryResponse getUnionOpenOrderRowQueryResponse(String startTime, String endTime) throws Exception {
public UnionOpenOrderRowQueryResponse getUnionOpenOrderRowQueryResponse(LocalDateTime start, LocalDateTime end) throws Exception {
String startTime = start.format(DATE_TIME_FORMATTER);
String endTime = end.format(DATE_TIME_FORMATTER);
// 模拟 API 调用
System.out.println("调用API - 从 " + startTime
+ "" + endTime);
// 实际的 API 调用逻辑应在这里进行
String accessToken = "";
JdClient client = new DefaultJdClient(SERVER_URL, accessToken, APP_KEY, SECRET_KEY);
UnionOpenOrderRowQueryRequest request = new UnionOpenOrderRowQueryRequest();