Explorar el Código

商品库上传任务重构

zhaotx hace 1 año
padre
commit
e59e03ffe1

+ 37 - 0
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/data/entity/AigcProductAlbum.java

@@ -0,0 +1,37 @@
+package cn.com.ctop.job.bytedance.data.entity;
+
+import lombok.Data;
+
+@Data
+public class AigcProductAlbum {
+    /*
+    third.album_id, third.platform_type, detail.platform_config, video.id as video_id, detail.id as video_detail_id, video.name as name, video.cover_img as img,ifnull(category.name, '其他') as 'theme', video.play_platform,
+        '天津星链视界信息技术有限公司' as copyright_owner, '其他' as playlet_gender, video.update_sort as playlet_num, '2' as playlet_duration,
+        payinfo.sort as start_pay_playlet, '5' as membership_types, '2' as has_motivation_types,
+        payinfo.maxpay as max_charge, payinfo.minpay as min_charge, maxpay as recommended_charge, maxpay as price,
+         1 as has_motivation_content
+     */
+    private String albumId;
+    private String platformType;
+    private String platformConfig;
+    private Long videoId;
+    private Long videoDetailId;
+    private String name;
+    private String img;
+    private String theme;
+    private String playPlatform;
+    private String copyrightOwner;
+    private String playletGender;
+    private Integer playletNum;
+    private String playletDuration;
+    private Integer startPayPlaylet;
+    private String membershipTypes;
+    private String hasMotivationTypes;
+    private Integer maxCharge;
+    private Integer minCharge;
+    private Integer recommendedCharge;
+    private Integer price;
+    private Integer hasMotivationContent;
+
+    private Integer startingUnlockEpisode;
+}

+ 31 - 0
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/data/entity/AigcProductPlatform.java

@@ -0,0 +1,31 @@
+package cn.com.ctop.job.bytedance.data.entity;
+
+import lombok.Data;
+
+@Data
+public class AigcProductPlatform {
+    private String platformId;//商品库ID
+    private String advertiserId;//所属主账户ID
+    private Integer type;//商品库类型 1:免费 2:付费
+    private Integer platformType;//商品库定位分类 1:抖音小程序(+微信小程序) 2:仅微信小程序
+    private String platformName;//商品库名称
+    private String miniInstanceId;//字节小程序实例ID
+    private String updateTime;//更新时间
+    private String createTime;//创建时间
+    private String miAppid;//使用的小程序ID
+    private Integer membershipTypes;//设置的字节会员类型
+    private Double maxCharge;//最大充值金额
+    private Double minCharge;//最小充值金额
+    private Double recommendedCharge;//推荐充值金额
+    private Double singlePrice;//单价
+    private Integer status;//状态 0:使用中 1:废弃
+    private String socialCreditCode;//管家账号社会信用代码
+    private Integer movieAuthStatus;//剧目认证状态,0-未认证,1-已认证
+    private Integer isBytedance;//投放载体-字节小程序 1:开启 0:关闭
+    private Integer isWechat;//投放载体-微信小程序 1:开启 0:关闭
+    private Integer isDys;//投放载体-端原生 1:开启 0:关闭
+    private Integer source;//短剧来源:1-自投;2-穿山甲,3-爱奇艺
+    private String accessToken;//商品库主账户access_token
+
+
+}

+ 8 - 6
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/data/mapper/BytedanceProductUpdateMapper.java

@@ -1,5 +1,7 @@
 package cn.com.ctop.job.bytedance.data.mapper;
 
+import cn.com.ctop.job.bytedance.data.entity.AigcProductAlbum;
+import cn.com.ctop.job.bytedance.data.entity.AigcProductPlatform;
 import com.alibaba.fastjson.JSONObject;
 import org.apache.ibatis.annotations.Param;
 
@@ -7,14 +9,14 @@ import java.util.List;
 
 public interface BytedanceProductUpdateMapper {
 
-    List<JSONObject> getIAPPlatformInitList();
-    List<JSONObject> getIAPPlatformList();
-    List<JSONObject> getIAPVideoList();
+    List<AigcProductPlatform> getIAPPlatformInitList();
+    List<AigcProductPlatform> getIAPPlatformList();
+    List<AigcProductAlbum> getIAPVideoList();
     List<JSONObject> getIAPProductTypeEnums();
 
-    List<JSONObject> getIAAPlatformInitList();
-    List<JSONObject> getIAAPlatformList();
-    List<JSONObject> getIAAVideoList();
+    List<AigcProductPlatform> getIAAPlatformInitList();
+    List<AigcProductPlatform> getIAAPlatformList();
+    List<AigcProductAlbum> getIAAVideoList();
     List<JSONObject> getIAAProductTypeEnums();
 
     int updateInstanceId(@Param("advertiserId") String advertiserId, @Param("instanceId") String instanceId);

+ 11 - 10
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/data/mapper/xml/BytedanceProductUpdateMapper.xml

@@ -10,7 +10,7 @@
     <update id="updateInstanceId">
         update deepthink.bytedance_product_main_advertiser
         set mini_instance_id = #{instanceId}
-        where advertiser_id = #{advertiserId}
+        where advertiser_id = #{advertiserId} and source=3
     </update>
     <update id="updateAlbumInfo">
         update deepthink.bytedance_upload_album
@@ -24,35 +24,35 @@
     </update>
 
 
-    <select id="getIAPPlatformList" resultType="com.alibaba.fastjson.JSONObject">
+    <select id="getIAPPlatformList" resultType="cn.com.ctop.job.bytedance.data.entity.AigcProductPlatform">
         select t1.*, t3.access_token
         FROM deepthink.bytedance_product_main_advertiser t1
         left join deepthink.bytedance_advertiser_list t2 on t1.advertiser_id=t2.advertiser_id
         left join deepthink.bytedance_auth_list t3 on t2.admin_advertiser_id=t3.admin_advertiser_id
         where t1.`type`=2 and t1.`_status`=0 and platform_type=1 and t1.mini_instance_id is not null
     </select>
-    <select id="getIAPPlatformInitList" resultType="com.alibaba.fastjson.JSONObject">
+    <select id="getIAPPlatformInitList" resultType="cn.com.ctop.job.bytedance.data.entity.AigcProductPlatform">
         select t1.*, t3.access_token
         FROM deepthink.bytedance_product_main_advertiser t1
         left join deepthink.bytedance_advertiser_list t2 on t1.advertiser_id=t2.advertiser_id
         left join deepthink.bytedance_auth_list t3 on t2.admin_advertiser_id=t3.admin_advertiser_id
         where t1.`type`=2 and t1.`_status`=0 and platform_type=1
     </select>
-    <select id="getIAAPlatformList" resultType="com.alibaba.fastjson.JSONObject">
+    <select id="getIAAPlatformList" resultType="cn.com.ctop.job.bytedance.data.entity.AigcProductPlatform">
         select t1.*, t3.access_token
         FROM deepthink.bytedance_product_main_advertiser t1
         left join deepthink.bytedance_advertiser_list t2 on t1.advertiser_id=t2.advertiser_id
         left join deepthink.bytedance_auth_list t3 on t2.admin_advertiser_id=t3.admin_advertiser_id
         where t1.`type`=1 and t1.`_status`=0 and platform_type=1 and t1.mini_instance_id is not null
     </select>
-    <select id="getIAAPlatformInitList" resultType="com.alibaba.fastjson.JSONObject">
+    <select id="getIAAPlatformInitList" resultType="cn.com.ctop.job.bytedance.data.entity.AigcProductPlatform">
         select t1.*, t3.access_token
         FROM deepthink.bytedance_product_main_advertiser t1
         left join deepthink.bytedance_advertiser_list t2 on t1.advertiser_id=t2.advertiser_id
         left join deepthink.bytedance_auth_list t3 on t2.admin_advertiser_id=t3.admin_advertiser_id
         where t1.`type`=1 and t1.`_status`=0 and platform_type=1
     </select>
-    <select id="getIAPVideoList" resultType="com.alibaba.fastjson.JSONObject">
+    <select id="getIAPVideoList" resultType="cn.com.ctop.job.bytedance.data.entity.AigcProductAlbum">
         select third.album_id, third.platform_type, detail.platform_config, video.id as video_id, detail.id as video_detail_id, video.name as name, video.cover_img as img,ifnull(category.name, '其他') as 'theme', video.play_platform,
         '天津星链视界信息技术有限公司' as copyright_owner, '其他' as playlet_gender, video.update_sort as playlet_num, '2' as playlet_duration,
         payinfo.sort as start_pay_playlet, '5' as membership_types, '2' as has_motivation_types,
@@ -67,10 +67,10 @@
         LEFT JOIN thirtpart.ly_video_category category ON video.category_id = category.id
         LEFT JOIN (select video_id, min(sort) as sort, max(pay_amount/100.0) as maxpay, min(pay_amount/100.0) as minpay from thirtpart.ly_video_details where is_pay=1 group by video_id) payinfo ON video.id = payinfo.video_id
         where (video.is_free = 1 or (payinfo.sort is not null and maxpay>0))
-        and video.source=1 and video.created_at > 1743436800
-        and video.created_at > unix_timestamp(date_sub(now(), interval 3 day))
+        and video.created_at > 1743436800
+        and video.source in (1,3)
     </select>
-    <select id="getIAAVideoList" resultType="com.alibaba.fastjson.JSONObject">
+    <select id="getIAAVideoList" resultType="cn.com.ctop.job.bytedance.data.entity.AigcProductAlbum">
         select third.album_id, third.platform_type, detail.platform_config, video.id as video_id, detail.id as video_detail_id, video.name as name, video.cover_img as img,ifnull(category.name, '其他') as 'theme', video.play_platform,
         '天津星链视界信息技术有限公司' as copyright_owner, '其他' as playlet_gender, video.update_sort as playlet_num, '2' as playlet_duration,
         '5' as membership_types, '1' as has_paid_content, '2' as has_motivation_types,payinfo.sort as starting_unlock_episode
@@ -82,7 +82,8 @@
         LEFT JOIN (select * from thirtpart.ly_videos where play_platform like '%2%') video ON third.video_id = video.id
         LEFT JOIN thirtpart.ly_video_category category ON video.category_id = category.id
         LEFT JOIN (select video_id, max(sort) as sort from thirtpart.ly_video_details where is_pay=0 group by video_id) payinfo ON video.id = payinfo.video_id
-        where video.is_free = 0 and video.source=1 and video.created_at > 1743436800
+        where video.is_iaa_show=1 and video.created_at > 1743436800
+        and video.source in (1,3)
     </select>
     <select id="getIAPProductTypeEnums" resultType="com.alibaba.fastjson.JSONObject">
         select first_type_name, first_type_id, second_type_name, second_type_id, third_type_name, third_type_id

+ 205 - 279
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/data/service/impl/BytedanceProductUpdateServiceImpl.java

@@ -1,5 +1,7 @@
 package cn.com.ctop.job.bytedance.data.service.impl;
 
+import cn.com.ctop.job.bytedance.data.entity.AigcProductAlbum;
+import cn.com.ctop.job.bytedance.data.entity.AigcProductPlatform;
 import cn.com.ctop.job.bytedance.data.mapper.BytedanceProductUpdateMapper;
 import cn.com.ctop.job.bytedance.data.service.IBytedanceProductUpdateService;
 import cn.com.ctop.job.bytedance.data.utils.Check;
@@ -27,6 +29,12 @@ public class BytedanceProductUpdateServiceImpl implements IBytedanceProductUpdat
 
     public static final String DOUYIN_MOVIE_SOURCE_APP="ttd652a0ef496310bd01";
 
+    //枚举值:is_pay: IAA, IAP
+    enum BusinessType {
+        IAA,
+        IAP
+    }
+
 
     //商品上传结果通知群
     public static final String HOOK_URL = "https://open.feishu.cn/open-apis/bot/v2/hook/92e2445e-76df-44fb-8f61-f55ac94f49bd";
@@ -35,11 +43,32 @@ public class BytedanceProductUpdateServiceImpl implements IBytedanceProductUpdat
     public void run() throws Exception {
         Set<String> errors = new HashSet<>();
         log.info("付费商品库更新中...");
-        iapProductUpdate(errors);
+        List<AigcProductPlatform> iapPlatformList = bytedanceProductUpdateMapper.getIAPPlatformList(); //商品库列表
+        List<AigcProductAlbum> iapVideoList = bytedanceProductUpdateMapper.getIAPVideoList(); //剧目列表
+        List<JSONObject> iapProductTypeEnums = bytedanceProductUpdateMapper.getIAPProductTypeEnums(); //商品类型
+        Map<String, JSONObject> iapProductTypeMap = iapProductTypeEnums.stream().collect(Collectors.toMap(
+                obj -> obj.getString("third_type_name"),
+                obj -> obj,
+                (existing, replacement) -> replacement
+        ));
+        runProductTask(iapPlatformList, iapVideoList, iapProductTypeMap, errors, BusinessType.IAP);
         log.info("付费商品库更新完成");
+
+
+
         log.info("免费商品库更新中...");
-//        iaaProductUpdate(errors);
+        List<AigcProductPlatform> iaaPlatformList = bytedanceProductUpdateMapper.getIAAPlatformList(); //商品库列表
+        List<AigcProductAlbum> iaaVideoList = bytedanceProductUpdateMapper.getIAAVideoList(); //剧目列表
+        List<JSONObject> iaaProductTypeEnums = bytedanceProductUpdateMapper.getIAAProductTypeEnums(); //商品类型
+        Map<String, JSONObject> iaaProductTypeMap = iaaProductTypeEnums.stream().collect(Collectors.toMap(
+                obj -> obj.getString("third_type_name"),
+                obj -> obj,
+                (existing, replacement) -> replacement
+        ));
+        runProductTask(iaaPlatformList, iaaVideoList, iaaProductTypeMap, errors, BusinessType.IAA);
         log.info("免费商品库更新完成");
+
+
         if (!Check.isNull(errors)){
             List<String> info = new ArrayList<>();
             info.add("商品上传报错通知");
@@ -48,6 +77,92 @@ public class BytedanceProductUpdateServiceImpl implements IBytedanceProductUpdat
         }
     }
 
+    private void runProductTask(List<AigcProductPlatform> platformList, List<AigcProductAlbum> albums, Map<String, JSONObject> productTypeMap, Set<String> errors, BusinessType businessType) throws IOException {
+        for (AigcProductPlatform platform : platformList){
+            // 拉取已上传剧目,对比,得到未上传剧目列表
+            List<String> hasUpload = hasUploadProductList(platform);
+            List<AigcProductAlbum> toUpload = albums.stream().filter(o -> !hasUpload.contains(o.getAlbumId())).collect(Collectors.toList());
+            //获取未上传剧目的推广链接
+            List<AigcProductAlbum> douyinUploadList = toUpload.stream().filter(o -> Objects.equals(o.getPlatformType(), "1")).collect(Collectors.toList());
+            Map<String, String> albumIdToLinkMap = getBytedancePlayletPromoteLink(platform.getAdvertiserId(), platform.getAccessToken(), platform.getMiniInstanceId(), douyinUploadList, errors);
+            //未上传剧目:对比平台类型;确定商品分类;获取推广链接
+            for (AigcProductAlbum album : toUpload){
+                if (!Objects.equals(album.getPlatformType(), String.valueOf(platform.getPlatformType()))){
+                    continue;
+                }
+                if (!productTypeMap.containsKey(album.getTheme())){
+                    errors.add("上传商品:没有找到对应的产品类型:" + album.getTheme());
+                    System.out.println(">>>>没有找到对应的产品类型:" + album.getTheme());
+                    System.out.println("\n\n\n");
+                    continue;
+                }
+                String schemaLink = null;
+                if (platform.getIsBytedance()==1){
+                    if (!albumIdToLinkMap.containsKey(album.getAlbumId())){
+                        errors.add("上传商品:没有找到对应的推广链接,无法上传商品,剧目ID:" + album.getAlbumId() + ", 剧目名称:" + album.getName());
+                        System.out.println(">>>>没有找到对应的推广链接,无法上传商品,剧目ID:" + album.getAlbumId() + ", 剧目名称:" + album.getName());
+                        System.out.println("\n\n\n");
+                        continue;
+                    }else {
+                        schemaLink = albumIdToLinkMap.get(album.getAlbumId());
+                    }
+                }
+                uploadProduct(platform, album, schemaLink, errors, productTypeMap.get(album.getTheme()), businessType);
+            }
+        }
+    }
+
+    /**
+     * 当前商品库中,已经上传的商品列表
+     * @param platform
+     * @return
+     */
+    private List<String> hasUploadProductList(AigcProductPlatform platform){
+        return hasUploadProductPageList(platform, 1, 100);
+    }
+
+    private List<String> hasUploadProductPageList(AigcProductPlatform platform, int page, int pageSize){
+        String url = "https://api.oceanengine.com/open_api/2/dpa/detail/get/";
+        Map<String, String> headers = new HashMap<>();
+        headers.put("Access-Token", platform.getAccessToken());
+        Map<String, Object> params = new HashMap<>();
+        params.put("advertiser_id", Long.valueOf(platform.getAdvertiserId()));
+        params.put("product_platform_id", Long.valueOf(platform.getPlatformId()));
+        params.put("page", String.valueOf(page));
+        params.put("page_size", String.valueOf(pageSize));
+        String res = HttpUtils.httpGet(url, params, headers);
+        if (res == null || res.isEmpty()) {
+            System.out.println("获取已上传商品列表失败, 广告账号ID:" + platform.getAdvertiserId() + ", 商品库ID:" + platform.getPlatformId());
+            return new ArrayList<>();
+        }else {
+            JSONObject jsonObject = JSONObject.parseObject(res);
+            int code = jsonObject.getIntValue("code");
+            if (code != 0) {
+                System.out.println("获取已上传商品列表失败,code: " + code + ", msg: " + jsonObject.getString("message") + ", 广告账号ID:" + platform.getAdvertiserId() + ", 商品库ID:" + platform.getPlatformId());
+                return new ArrayList<>();
+            }else {
+                JSONArray list = jsonObject.getJSONObject("data").getJSONArray("list");
+                if (list == null || list.isEmpty()){
+                    return new ArrayList<>();
+                }
+                List<String> resList = new ArrayList<>(list.size());
+                for (int i = 0; i < list.size(); i++) {
+                    JSONObject obj = list.getJSONObject(i);
+                    resList.add(String.valueOf(obj.getLongValue("product_id")));
+                }
+                JSONObject page_info = jsonObject.getJSONObject("data").getJSONObject("page_info");
+                int total_page = page_info.getIntValue("total_page");
+                if (total_page > page){
+                    //递归获取下一页
+                    List<String> nextPage = hasUploadProductPageList(platform, page + 1, pageSize);
+                    resList.addAll(nextPage);
+                }
+                return resList;
+            }
+        }
+    }
+
+
     @Override
     public void authMovieResource() {
         //原片授权
@@ -57,7 +172,7 @@ public class BytedanceProductUpdateServiceImpl implements IBytedanceProductUpdat
                 String tokenKey = "client-token-key_"+ DOUYIN_MOVIE_SOURCE_APP;
                 String token = (String) redis2Template_db5.opsForValue().get(tokenKey);
                 if (Check.isNull(token)){
-                    log.warn("没有找到字节小程序access_token,无法进行原片授权");
+                    log.warn("没有找到字节小程序access_token,无法进行  原片授权");
                     return;
                 }
                 for (JSONObject obj : authList){
@@ -101,8 +216,8 @@ public class BytedanceProductUpdateServiceImpl implements IBytedanceProductUpdat
      */
     @Override
     public void initNew(){
-        List<JSONObject> iapPlatformList = bytedanceProductUpdateMapper.getIAPPlatformInitList();
-        List<JSONObject> iaaPlatformList = bytedanceProductUpdateMapper.getIAAPlatformInitList();
+//        List<AigcProductPlatform> iapPlatformList = bytedanceProductUpdateMapper.getIAPPlatformInitList();
+        List<AigcProductPlatform> iaaPlatformList = bytedanceProductUpdateMapper.getIAAPlatformInitList();
         initNew(iaaPlatformList);
 //        initNew(iapPlatformList);
         authMovieResource();
@@ -120,23 +235,23 @@ public class BytedanceProductUpdateServiceImpl implements IBytedanceProductUpdat
 
     }
 
-    public void initNew(List<JSONObject> platformList)  {
+    public void initNew(List<AigcProductPlatform> platformList)  {
         //为广告主账户创建新的字节小程序
         //step1 查询表里广告主是否都有自己的字节小程序、
         //step2 如果没有,创建新的字节小程序
-        for (JSONObject obj : platformList){
-            if (obj.containsKey("mini_instance_id") && !Check.isNull(obj.get("mini_instance_id"))){
+        for (AigcProductPlatform obj : platformList){
+            if (!Check.isNull(obj.getMiniInstanceId())){
                 //已经有字节小程序了
                 continue;
             }
             String createLinkUrl = "https://api.oceanengine.com/open_api/v3.0/tools/micro_app/create/";
-            String advertiser_id = obj.getString("advertiser_id");
-            String access_token = obj.getString("access_token");
+            String advertiser_id = obj.getAdvertiserId();
+            String access_token = obj.getAccessToken();
             Map<String, String> headers = new HashMap<>();
             headers.put("Access-Token", access_token);
             JSONObject requestBody = new JSONObject();
             requestBody.put("advertiser_id", Long.parseLong(advertiser_id));
-            requestBody.put("app_id", obj.getString("mi_appid"));
+            requestBody.put("app_id", obj.getMiAppid());
             requestBody.put("remark", "商品库管理用");
             requestBody.put("tag_info", "1050107001");
             JSONObject app_page = new JSONObject();
@@ -166,82 +281,27 @@ public class BytedanceProductUpdateServiceImpl implements IBytedanceProductUpdat
     }
 
     /**
-     * 付费短剧更新
-     * @param errorBlanket
-     */
-    private void iapProductUpdate(Set<String> errorBlanket){
-        //IAP
-        List<JSONObject> iapPlatformList = bytedanceProductUpdateMapper.getIAPPlatformList(); //商品库列表
-        List<JSONObject> iapVideoList = bytedanceProductUpdateMapper.getIAPVideoList(); //剧目列表
-        System.out.println("待上传付费商品数: " + iapVideoList.size());
-        List<JSONObject> iapProductTypeEnums = bytedanceProductUpdateMapper.getIAPProductTypeEnums(); //商品类型
-        Map<String, Map<String, String>> advertiserToLinkMap = new HashMap<>();
-
-        for (JSONObject obj : iapPlatformList){
-            String advertiserId = obj.getString("advertiser_id");
-            String accessToken = obj.getString("access_token");
-            String instanceId = obj.getString("mini_instance_id");
-            List<JSONObject> iapVideoDouyinList = iapVideoList.stream().filter(obj1 -> "1".equals(obj1.getString("platform_type"))).collect(Collectors.toList());
-            System.out.println(">>查找小程序付费推广链接: 小程序id: "+instanceId);
-            long st = System.currentTimeMillis();
-            Map<String, String> albumIdToLinkMap = getBytedancePlayletPromoteLink(advertiserId, accessToken, instanceId, iapVideoDouyinList, errorBlanket);
-            long ed = System.currentTimeMillis();
-            System.out.println(">>查找小程序"+instanceId+"付费推广链接完成, 耗时: " + (ed-st) + "ms");
-            advertiserToLinkMap.put(advertiserId, albumIdToLinkMap);
-        }
-
-        Map<String, JSONObject> iapProductTypeMap = iapProductTypeEnums.stream().collect(Collectors.toMap(
-                obj -> obj.getString("third_type_name"),
-                obj -> obj,
-                (existing, replacement) -> replacement
-        ));
-        for (JSONObject obj : iapVideoList){
-            String theme = obj.getString("theme");
-            if (!iapProductTypeMap.containsKey(theme)){
-                errorBlanket.add("上传商品:没有找到对应的产品类型:" + theme);
-                System.out.println(">>>>没有找到对应的产品类型:" + theme);
-                System.out.println("\n\n\n");
-                continue;
-            }
-            Integer platformType1 = obj.getInteger("platform_type");
-
-            for (JSONObject platform : iapPlatformList) {
-                Integer platformType2 = platform.getInteger("platform_type");
-                if (!Objects.equals(platformType1, platformType2)){
-                    continue;
-                }
-                int rescode = uploadIapProduct(platform, obj, advertiserToLinkMap, errorBlanket, iapProductTypeMap.get(theme));
-                if (rescode!= 0){
-//                    return;
-                }
-//                System.out.println("\n\n\n");
-            }
-        }
-    }
-
-    /**
-     * 付费短剧更新
+     * 短剧更新
      * @param platform 商品库信息
      * @param album 剧信息
-     * @param advertiserToLinkMap
+     * @param schemaLink 小程序推广链接 schemaLink(sslocal://sxxxxx
      * @param errorBlanket
      * @param productType 商品短剧类型
      */
-    private int uploadIapProduct(JSONObject platform, JSONObject album,
-                                  Map<String, Map<String, String>> advertiserToLinkMap,
-                                  Set<String> errorBlanket,
-                                  JSONObject productType){
+    private void uploadProduct(AigcProductPlatform platform, AigcProductAlbum album,
+                                  String schemaLink, Set<String> errorBlanket, JSONObject productType,
+                              BusinessType businessType){
         String url = "https://ad.oceanengine.com/open_api/2/dpa/product/update/";
         Map<String, String> headers = new HashMap<>();
-        headers.put("Access-Token", platform.getString("access_token"));
+        headers.put("Access-Token", platform.getAccessToken());
         headers.put("Content-Type", "application/json");
 
         JSONObject request = new JSONObject();
-        String album_id = album.getString("album_id");
-        request.put("product_id", album.getLongValue("album_id"));
+        String album_id = album.getAlbumId();
+        request.put("product_id", Long.valueOf(album_id));
         JSONObject product_info = new JSONObject();
-        product_info.put("name", album.getString("name"));
-        product_info.put("image_url", album.getString("img"));
+        product_info.put("name", album.getName());
+        product_info.put("image_url", album.getImg());
         product_info.put("status", 1);
         product_info.put("stock", 1);
         product_info.put("first_category_id", productType.getString("first_type_id"));
@@ -250,65 +310,55 @@ public class BytedanceProductUpdateServiceImpl implements IBytedanceProductUpdat
         product_info.put("first_category", productType.getString("first_type_name"));
         product_info.put("sub_category", productType.getString("second_type_name"));
         product_info.put("third_category", productType.getString("third_type_name"));
-        request.put("advertiser_id", platform.getLongValue("advertiser_id"));
-        request.put("platform_id", platform.getLongValue("platform_id"));
+        request.put("advertiser_id", Long.valueOf(platform.getAdvertiserId()));
+        request.put("platform_id", Long.valueOf(platform.getPlatformId()));
         JSONObject profession = new JSONObject();
-        profession.put("copyright_owner", album.getString("copyright_owner"));
+        profession.put("copyright_owner", album.getCopyrightOwner());
         profession.put("playlet_gender", "3");
-        profession.put("playlet_num", album.getString("playlet_num"));
-        profession.put("playlet_duration", album.getString("playlet_duration"));
-        profession.put("start_pay_playlet", album.getString("start_pay_playlet"));
-        if (platform.getDouble("max_charge") > 0.0){
-            profession.put("max_charge", platform.getString("max_charge"));
-        }
-        if (platform.getDouble("min_charge") > 0.0){
-            profession.put("min_charge", platform.getString("min_charge"));
-        }
-        if (platform.getDouble("recommended_charge") > 0.0){
-            profession.put("recommended_charge", platform.getString("recommended_charge"));
-        }
-        profession.put("has_paid_content", "1");
-        profession.put("has_motivation_content", "2");
-        profession.put("membership_types", platform.getString("membership_types"));
-        Map<String, String> linkObj = advertiserToLinkMap.get(platform.getString("advertiser_id"));
-        String play_platform = album.getString("play_platform");
+        profession.put("playlet_num", String.valueOf(album.getPlayletNum()));
+        profession.put("playlet_duration", album.getPlayletDuration());
+        if (businessType==BusinessType.IAP){
+            profession.put("start_pay_playlet", String.valueOf(album.getStartPayPlaylet()));
+            if (platform.getMaxCharge() > 0.0){
+                profession.put("max_charge", String.valueOf(platform.getMaxCharge()));
+            }
+            if (platform.getMinCharge() > 0.0){
+                profession.put("min_charge", String.valueOf(platform.getMinCharge()));
+            }
+            if (platform.getRecommendedCharge() > 0.0){
+                profession.put("recommended_charge", String.valueOf(platform.getRecommendedCharge()));
+            }
+            profession.put("has_paid_content", "1");
+            profession.put("has_motivation_content", "2");
+            profession.put("membership_types", String.valueOf(platform.getMembershipTypes()));
+
+            //price_info
+            JSONObject price_info = new JSONObject();
+            price_info.put("price", platform.getSinglePrice());
+            product_info.put("price_info", price_info);
+        }else { //IAA
+            profession.put("has_paid_content", "2");
+            profession.put("has_motivation_content", "2");
+            profession.put("membership_types", "5");
+            profession.put("starting_unlock_episode", String.valueOf(album.getStartingUnlockEpisode()));
+        }
+//        String play_platform = album.getPlay_platform();
         List<String> ad_carrier = new ArrayList<>();
-//        if (linkObj != null){
-//            profession.put("micro_app_link", linkObj.get(album_id));
-//            ad_carrier.add("字节小程序");
-//            if (play_platform.contains("1")){
-//                if (bytedanceProductUpdateMapper.getWeixinAuditStatus(album.getLong("video_id"))>0){
-//                    ad_carrier.add("微信小程序");
-//                }
-//            }
-//        }else {
-//            profession.put("album_id", album_id);
-//            ad_carrier.add("微信小程序");
-//        }
-        Integer is_bytedance = platform.getInteger("is_bytedance");
-        Integer is_wechat = platform.getInteger("is_wechat");
-        Integer is_dys = platform.getInteger("is_dys");
-        if (is_bytedance == 1){
+        if (platform.getIsBytedance() == 1){
             ad_carrier.add("字节小程序");
         }
-        if (is_wechat == 1){
+        if (platform.getIsWechat() == 1){
             ad_carrier.add("微信小程序");
         }
-        if (is_dys == 1){
+        if (platform.getIsDys() == 1){
             ad_carrier.add("端原生组件");
         }
-
-        if (is_bytedance == 1){
-            profession.put("micro_app_link", linkObj.get(album_id));
+        if (platform.getIsBytedance() == 1){
+            profession.put("micro_app_link", schemaLink);
         }else {
             profession.put("album_id", album_id);
         }
         profession.put("ad_carrier", JSON.toJSONString(ad_carrier));
-
-        //price_info
-        JSONObject price_info = new JSONObject();
-        price_info.put("price", platform.getDoubleValue("single_price"));
-        product_info.put("price_info", price_info);
         product_info.put("profession", profession);
         request.put("product_info", product_info);
 
@@ -320,136 +370,9 @@ public class BytedanceProductUpdateServiceImpl implements IBytedanceProductUpdat
         JSONObject btRes = JSONObject.parseObject(res);
         int code = btRes.getIntValue("code");
         if (code != 0){
-            errorBlanket.add("上传付费商品失败,code: " + code + ", msg: " + btRes.getString("message")+", 关联剧目: " + album.getString("name"));
-        }
-        return code;
-    }
-
-    private void iaaProductUpdate(Set<String> errorBlanket){
-        //IAA
-        List<JSONObject> iaaPlatformList = bytedanceProductUpdateMapper.getIAAPlatformList();
-        List<JSONObject> iaaVideoList = bytedanceProductUpdateMapper.getIAAVideoList();
-        List<JSONObject> iaaProductTypeEnums = bytedanceProductUpdateMapper.getIAAProductTypeEnums();
-
-        Map<String, Map<String, String>> advertiserToLinkMap = new HashMap<>();
-
-        for (JSONObject obj : iaaPlatformList){
-            String advertiserId = obj.getString("advertiser_id");
-            String accessToken = obj.getString("access_token");
-            String instanceId = obj.getString("mini_instance_id");
-
-            List<JSONObject> iaaVideoDouyinList = iaaVideoList.stream().filter(obj1 -> "1".equals(obj1.getString("platform_type"))).collect(Collectors.toList());
-            Map<String, String> albumIdToLinkMap = getBytedancePlayletPromoteLink(advertiserId, accessToken, instanceId, iaaVideoDouyinList, errorBlanket);
-            advertiserToLinkMap.put(advertiserId, albumIdToLinkMap);
-        }
-
-        Map<String, JSONObject> iaaProductTypeMap = iaaProductTypeEnums.stream().collect(Collectors.toMap(
-                obj -> obj.getString("third_type_name"),
-                obj -> obj,
-                (existing, replacement) -> replacement
-        ));
-        for (JSONObject obj : iaaVideoList){
-            String theme = obj.getString("theme");
-            if (!iaaProductTypeMap.containsKey(theme)){
-                errorBlanket.add("上传商品:没有找到对应的产品类型:" + theme);
-                System.out.println(">>>>没有找到对应的产品类型:" + theme);
-                System.out.println("\n\n\n");
-                continue;
-            }
-            Integer platformType1 = obj.getInteger("platform_type");
-
-            for (JSONObject platform : iaaPlatformList) {
-                Integer platformType2 = platform.getInteger("platform_type");
-                if (!Objects.equals(platformType1, platformType2)){
-                    continue;
-                }
-                int code = uploadIaaProduct(platform, obj, advertiserToLinkMap, errorBlanket, iaaProductTypeMap.get(theme));
-                if (code !=0){
-
-                }
-//                System.out.println(res);
-//                System.out.println("\n\n\n");
-            }
-        }
-    }
-
-    private int uploadIaaProduct(JSONObject platform, JSONObject album, Map<String,
-            Map<String, String>> advertiserToLinkMap,
-                                  Set<String> errorBlanket,
-                                  JSONObject productType){
-        String url = "https://ad.oceanengine.com/open_api/2/dpa/product/update/";
-        Map<String, String> headers = new HashMap<>();
-        headers.put("Access-Token", platform.getString("access_token"));
-        headers.put("Content-Type", "application/json");
-        String album_id = album.getString("album_id");
-        JSONObject request = new JSONObject();
-        request.put("product_id", album.getLongValue("album_id"));
-        JSONObject product_info = new JSONObject();
-        product_info.put("name", album.getString("name"));
-        product_info.put("image_url", album.getString("img"));
-        product_info.put("status", 1);
-        product_info.put("stock", 1);
-        product_info.put("first_category_id", productType.getString("first_type_id"));
-        product_info.put("sub_category_id", productType.getString("second_type_id"));
-        product_info.put("third_category_id", productType.getString("third_type_id"));
-        product_info.put("first_category", productType.getString("first_type_name"));
-        product_info.put("sub_category", productType.getString("second_type_name"));
-        product_info.put("third_category", productType.getString("third_type_name"));
-        JSONObject profession = new JSONObject();
-        profession.put("copyright_owner", album.getString("copyright_owner"));
-        profession.put("playlet_gender", "3");
-        profession.put("playlet_num", album.getString("playlet_num"));
-        profession.put("playlet_duration", album.getString("playlet_duration"));
-        profession.put("has_paid_content", "2");
-        profession.put("has_motivation_content", "2");
-        profession.put("membership_types", "5");
-        profession.put("starting_unlock_episode", album.getString("starting_unlock_episode"));
-        Map<String, String> linkObj = advertiserToLinkMap.get(platform.getString("advertiser_id"));
-        List<String> ad_carrier = new ArrayList<>();
-//        if (linkObj != null){
-//            profession.put("micro_app_link", linkObj.get(album_id));
-//            ad_carrier.add("字节小程序");
-//        }else {
-//            profession.put("album_id", album_id);
-//            ad_carrier.add("微信小程序");
-//        }
-        Integer is_bytedance = platform.getInteger("is_bytedance");
-        Integer is_wechat = platform.getInteger("is_wechat");
-        Integer is_dys = platform.getInteger("is_dys");
-        if (is_bytedance == 1){
-            ad_carrier.add("字节小程序");
-        }
-        if (is_wechat == 1){
-            ad_carrier.add("微信小程序");
-        }
-        if (is_dys == 1){
-            ad_carrier.add("端原生组件");
-        }
-
-        if (is_bytedance == 1){
-            profession.put("micro_app_link", linkObj.get(album_id));
-        }else {
-            profession.put("album_id", album_id);
-        }
-
-        profession.put("ad_carrier", JSON.toJSONString(ad_carrier));
-
-        product_info.put("profession", profession);
-        request.put("product_info", product_info);
-        request.put("advertiser_id", platform.getLongValue("advertiser_id"));
-        request.put("platform_id", platform.getLongValue("platform_id"));
-
-//                System.out.println("请求地址:" + url);
-//                System.out.println("请求头:" + headers);
-//                System.out.println("请求参数:" + request.toJSONString());
-        String res = HttpUtils.httpPostRequest(url, request, headers);
-        JSONObject btRes = JSONObject.parseObject(res);
-        int code = btRes.getIntValue("code");
-        if (code != 0){
-            System.out.println("上传免费商品失败,code: " + code + ", msg: " + btRes.getString("message")+", 关联剧目: " + album.getString("name"));
-            errorBlanket.add("上传免费商品失败,code: " + code + ", msg: " + btRes.getString("message")+", 关联剧目: " + album.getString("name"));
+            String payName = businessType==BusinessType.IAP?"付费":"免费";
+            errorBlanket.add("上传"+payName+"商品失败,code: " + code + ", msg: " + btRes.getString("message")+", 关联剧目: " + album.getName());
         }
-        return code;
     }
 
     /**
@@ -459,14 +382,14 @@ public class BytedanceProductUpdateServiceImpl implements IBytedanceProductUpdat
      * @param instanceId 字节小程序的实例ID
      * @return map key: album_id, value: 对应的字节小程序推广链接,sslocal开头
      */
-    private Map<String, String> getBytedancePlayletPromoteLink(String advertiserId, String accessToken, String instanceId, List<JSONObject> requests, Set<String> errorBlanket){
+    private Map<String, String> getBytedancePlayletPromoteLink(String advertiserId, String accessToken, String instanceId, List<AigcProductAlbum> requests, Set<String> errorBlanket){
         List<String> reqAlbumIds = requests.stream()
-                .map(obj -> obj.getString("album_id"))
+                .map(obj -> obj.getAlbumId())
                 .collect(Collectors.toList());
         Map<String, String> res = new HashMap<>(reqAlbumIds.size());
 
-        List<JSONObject> unfound = new ArrayList<>(requests);
-        for (int page=1; page<=5; page++){
+        List<AigcProductAlbum> unfound = new ArrayList<>(requests);
+        for (int page=1; page<=20; page++){
             JSONArray playletDetailInfo = getPlayletDetail(advertiserId, accessToken, instanceId, errorBlanket,page);
             if (playletDetailInfo == null || playletDetailInfo.isEmpty()){
                 break;
@@ -481,7 +404,7 @@ public class BytedanceProductUpdateServiceImpl implements IBytedanceProductUpdat
                 }
             }
              unfound = requests.stream()
-                    .filter(obj -> !res.containsKey(obj.getString("album_id")))
+                    .filter(obj -> !res.containsKey(obj.getAlbumId()))
                     .collect(Collectors.toList());
             if (unfound.isEmpty()){
                 break;
@@ -500,7 +423,7 @@ public class BytedanceProductUpdateServiceImpl implements IBytedanceProductUpdat
             System.out.println("有" + unfound.size() + "个剧目没有找到对应的推广链接,准备新建链接");
         }
         //没有找到对应的album_id,需要新建链接
-        for (JSONObject obj : unfound){
+        for (AigcProductAlbum obj : unfound){
             String editLinkUrl = "https://api.oceanengine.com/open_api/v3.0/tools/micro_app/update/";
             Map<String, String> headers = new HashMap<>();
             headers.put("Access-Token", accessToken);
@@ -508,16 +431,16 @@ public class BytedanceProductUpdateServiceImpl implements IBytedanceProductUpdat
             requestBody.put("advertiser_id", Long.parseLong(advertiserId));
             requestBody.put("instance_id", Long.parseLong(instanceId));
             JSONObject app_page = new JSONObject();
-            String name = obj.getString("name");
+            String name = obj.getName();
             app_page.put("link", "");
             app_page.put("remark", "生成商品用-"+name);
             app_page.put("link_remark", "生成商品用-"+name);
             app_page.put("operate_type", "NEW");
             app_page.put("start_page", "pages/index/index");
-            String video_id = obj.getString("video_id");
-            String album_id = obj.getString("album_id");
-            String video_detail_id = obj.getString("video_detail_id");
-            String platform_config = obj.getString("platform_config");
+            String video_id = String.valueOf(obj.getVideoId());
+            String album_id = obj.getAlbumId();
+            String video_detail_id = String.valueOf(obj.getVideoDetailId());
+            String platform_config = obj.getPlatformConfig();
             JSONObject pconfig = JSONObject.parseObject(platform_config);
             String tt_episode_id = pconfig.getJSONObject("douyinyun").getString("episode_id");
             String start_param = "tt_album_id=" + album_id + "&video_id=" + video_id + "&video_detail_id=" + video_detail_id + "&tt_episode_id=" + tt_episode_id + "&source=link&type=1";
@@ -526,9 +449,6 @@ public class BytedanceProductUpdateServiceImpl implements IBytedanceProductUpdat
             app_page_list.add(app_page);
             requestBody.put("app_page", app_page_list);
             requestBody.put("tag_info", "1050107001");
-//            System.out.println("\n\n请求地址:" + editLinkUrl);
-//            System.out.println("请求头:" + headers);
-//            System.out.println("请求参数:" + requestBody.toJSONString());
 
             String rr = HttpUtils.httpPostRequest(editLinkUrl, requestBody, headers);
             if (rr == null || rr.isEmpty()){
@@ -543,17 +463,22 @@ public class BytedanceProductUpdateServiceImpl implements IBytedanceProductUpdat
                     System.out.println("创建字节小程序推广链接失败,code: " + code + ", msg: " + jsonObject.getString("message"));
                     continue;
                 }else {
-                    String instanceid = jsonObject.getJSONObject("data").getString("instance_id");
-                    JSONArray newPlayletDetailInfo = getPlayletDetail(advertiserId, accessToken, instanceid, errorBlanket,1);
-                    if (newPlayletDetailInfo == null || newPlayletDetailInfo.isEmpty()){
-                        continue;
-                    }
-                    for (int i = 0; i < newPlayletDetailInfo.size(); i++) {
-                        JSONObject link = newPlayletDetailInfo.getJSONObject(i);
-                        String startParam = link.getString("start_param");
-                        if (startParam.contains("tt_album_id="+album_id)){
-                            res.put(album_id, link.getString("link"));
-                        }
+
+                }
+            }
+        }
+        int maxPage = unfound.size() / 100 + 1;
+        for (int p = 0; p < maxPage; p++) {
+            JSONArray newPlayletDetailInfo = getPlayletDetail(advertiserId, accessToken, instanceId, errorBlanket,p+1);
+            if (newPlayletDetailInfo == null || newPlayletDetailInfo.isEmpty()){
+                break;
+            }
+            for (int i = 0; i < newPlayletDetailInfo.size(); i++) {
+                JSONObject obj = newPlayletDetailInfo.getJSONObject(i);
+                String startParam = obj.getString("start_param");
+                for (AigcProductAlbum album : unfound){
+                    if (startParam.contains("tt_album_id="+album.getAlbumId())){
+                        res.put(album.getAlbumId(), obj.getString("link"));
                     }
                 }
             }
@@ -588,13 +513,14 @@ public class BytedanceProductUpdateServiceImpl implements IBytedanceProductUpdat
         String res = HttpUtils.httpGet(getPlayletDetailUrl, params, headers);
         if (res == null || res.isEmpty()) {
             errorBlanket.add("获取字节小程序推广链接失败, 广告账号ID:" + advertiserId + ", 小程序资产ID:" + instanceId);
+            System.out.println("获取字节小程序推广链接失败, 广告账号ID:" + advertiserId + ", 小程序资产ID:" + instanceId);
             return new JSONArray();
         }else {
             JSONObject jsonObject = JSONObject.parseObject(res);
             int code = jsonObject.getIntValue("code");
             if (code != 0) {
                 errorBlanket.add("获取字节小程序推广链接失败,code: " + code + ", msg: " + jsonObject.getString("message") + ", 广告账号ID:" + advertiserId + ", 小程序资产ID:" + instanceId);
-                System.out.println("获取字节小程序推广链接失败,code: " + code + ", msg: " + jsonObject.getString("message"));
+                System.out.println("获取字节小程序推广链接失败,code: " + code + ", msg: " + jsonObject.getString("message") + ", 广告账号ID:" + advertiserId + ", 小程序资产ID:" + instanceId);
                 return new JSONArray();
             }else {
                 JSONArray list = jsonObject.getJSONObject("data").getJSONArray("list");
@@ -630,7 +556,7 @@ public class BytedanceProductUpdateServiceImpl implements IBytedanceProductUpdat
         }
         for (JSONObject vi : wxVideoInfos){
             Long videoId = vi.getLong("id");
-            String albumId = uploadAlbum(videoId, appId, appAccessToken);
+            String albumId = uploadWxAlbum(videoId, appId, appAccessToken);
             if (albumId == null){
                 info.add("上传短剧失败,videoId: " + videoId + ", 剧目名称: " + vi.getString("name"));
             }else {
@@ -708,7 +634,7 @@ public class BytedanceProductUpdateServiceImpl implements IBytedanceProductUpdat
      * @param videoId from ly_videos
      * @return albumId
      */
-    private String uploadAlbum(long videoId, Long appId, String appAccessToken){
+    private String uploadWxAlbum(long videoId, Long appId, String appAccessToken){
         JSONObject video = bytedanceProductUpdateMapper.getVideoInfo(videoId);
         if (video == null){
             System.out.println("没有找到视频信息,videoId: " + videoId);