MrShi
8 小时以前 9eeb62c02a7b3c7b95c20678b6a9c74e7f12f943
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
package com.doumee.core.douyin.dto;
 
import com.alibaba.fastjson.annotation.JSONField;
import lombok.Data;
 
import java.util.List;
 
/**
 * 抖音商品项(online/query 返回的 products 元素)。
 * <p>抖音 online/query 的 products 元素为<strong>嵌套结构</strong>:在线状态、SKU 列表在顶层,
 * 商品基础信息(product_id/product_name/product_type/category/out_id 等)藏在 {@code product} 子对象里。
 * 故本类顶层只持有 onlineStatus / skus / product 三个字段。
 * <p>早期版本把 productId 等平铺在顶层,与抖音真实返回层级不符,导致除 onlineStatus 外字段全空,已校正。
 *
 * @author rk
 * @date 2026/06/22
 */
@Data
public class DouyinProductDTO {
 
    /** 在线状态 1在线 2下线 3封禁(顶层字段) */
    @JSONField(name = "online_status")
    private Integer onlineStatus;
 
    /** 多规格商品的 SKU 规格列表(复数节点,顶层字段);单 SKU 团购此为空数组 */
    @JSONField(name = "skus")
    private List<DouyinSkuDTO> skus;
 
    /**
     * 单 SKU 商品(如团购 product_type=1)的 SKU 明细(单数节点,顶层字段)。
     * <p>抖音 online/query 对单 SKU 团购返回 {@code sku}(单数对象)且 {@code skus}(复数)为空数组;
     * 多规格商品则相反(走 skus)。入库时两者归集统一处理,见 upsertProduct。
     */
    @JSONField(name = "sku")
    private DouyinSkuDTO sku;
 
    /** 商品基础信息(嵌套子对象,承载 product_id/product_name/product_type/category/out_id 等) */
    @JSONField(name = "product")
    private DouyinProductInfoDTO product;
 
    /**
     * 抖音 online/query 的 product 子对象(商品基础信息)。
     * <p>对应抖音返回 products[].product 节点。
     */
    @Data
    public static class DouyinProductInfoDTO {
 
        /** 抖音侧商品ID(业务唯一键,用于本地 upsert 与核销匹配) */
        @JSONField(name = "product_id")
        private String productId;
 
        /** 商品名称 */
        @JSONField(name = "product_name")
        private String productName;
 
        /** 商品类型 */
        @JSONField(name = "product_type")
        private Integer productType;
 
        /** 类目ID(数字,超出 int 范围用 Long) */
        @JSONField(name = "category_id")
        private Long categoryId;
 
        /** 类目全名(如"本地生活/餐饮/...",文本,展示用) */
        @JSONField(name = "category_full_name")
        private String categoryFullName;
 
        /** 抖音原始 out_id;本地 out_id 由管理端绑定套餐(discount.id),同步时【不入库】 */
        @JSONField(name = "out_id")
        private String outId;
 
        /** 归属账户ID(来客商户根账户,数字转字符串后落库) */
        @JSONField(name = "owner_account_id")
        private Long ownerAccountId;
    }
}