Jelajahi Sumber

巨量商品库支持微小

zhaotx 1 tahun lalu
induk
melakukan
6fe264e909

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

@@ -21,14 +21,14 @@ public interface BytedanceProductUpdateMapper {
     List<JSONObject> getVideoDetail(@Param("videoId") Long videoId);
 
 
-    List<Long> getUploadList();
+    List<JSONObject> getUploadList();
 
     JSONObject getDeveloperAccount();
 
     int insertAlbumInfo(@Param("albumId") String albumId,
                         @Param("videoId") Long videoId);
 
-    List<String> selectWaitingAlbums();
+    List<JSONObject> selectWaitingAlbums();
 
     int updateAlbumInfo(@Param("albumId") String albumId,
                         @Param("canPromotion") int status,

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

@@ -34,29 +34,31 @@
         where t1.`type`=1 and t1.`_status`=0
     </select>
     <select id="getIAPVideoList" resultType="com.alibaba.fastjson.JSONObject">
-        select third.album_id, 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,
+        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, '1' as has_paid_content, '2' as has_motivation_types,
         payinfo.maxpay as max_charge, payinfo.minpay as min_charge, maxpay as recommended_charge, maxpay as price,
         2 as has_paid_content, 1 as has_motivation_content
-        FROM (select * from thirtpart.ly_third_videos where submission_status=2
+        FROM (select video_id, album_id, 1 as platform_type from thirtpart.ly_third_videos where submission_status=2 and platform=2
         and video_id in (select video_id from thirtpart.ly_video_audit_records where audit_status=2)
+        union select ly_video_id as video_id, album_id, 2 as platform_type from deepthink.bytedance_upload_album where can_promotion=1
         ) third
         LEFT JOIN (select * from thirtpart.ly_video_details where platform_config is not null group by video_id) detail ON third.video_id = detail.video_id
-        LEFT JOIN (select * from thirtpart.ly_videos where play_platform like '%2%') video ON third.video_id = video.id and third.platform=2
+        LEFT JOIN (select * from thirtpart.ly_videos) 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, 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
     </select>
     <select id="getIAAVideoList" resultType="com.alibaba.fastjson.JSONObject">
-        select third.album_id, 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,
+        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
-        FROM (select * from thirtpart.ly_third_videos where submission_status=2
+        FROM (select video_id, album_id, 1 as platform_type from thirtpart.ly_third_videos where submission_status=2 and platform=2
         and video_id in (select video_id from thirtpart.ly_video_audit_records where audit_status=2)
+        union select ly_video_id as video_id, album_id, 2 as platform_type from deepthink.bytedance_upload_album where can_promotion=1
         ) third
         LEFT JOIN (select * from thirtpart.ly_video_details where platform_config is not null group by video_id) detail ON third.video_id = detail.video_id
-        LEFT JOIN (select * from thirtpart.ly_videos where play_platform like '%2%') video ON third.video_id = video.id and third.platform=2
+        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
@@ -77,8 +79,9 @@
     <select id="getVideoDetail" resultType="com.alibaba.fastjson.JSONObject">
         select video_id, name, is_pay, pay_amount, url, sort from thirtpart.ly_video_details where video_id=#{videoId} order by sort
     </select>
-    <select id="getUploadList" resultType="java.lang.Long">
-        select id from thirtpart.ly_videos
+    <select id="getUploadList"  resultType="com.alibaba.fastjson.JSONObject">
+        select id,name
+        from thirtpart.ly_videos
         where id not in
         (select video_id from thirtpart.ly_third_videos where platform=2 and submission_status=2
         and video_id in (select video_id from thirtpart.ly_video_audit_records where audit_status=2))
@@ -87,7 +90,10 @@
     <select id="getDeveloperAccount" resultType="com.alibaba.fastjson.JSONObject">
         select app_id, secret as app_secret from deepthink.bytedance_auth_config where auth_status=1 limit 1
     </select>
-    <select id="selectWaitingAlbums" resultType="java.lang.String">
-        select album_id from deepthink.bytedance_upload_album where can_promotion is null or can_promotion=0
+    <select id="selectWaitingAlbums"  resultType="com.alibaba.fastjson.JSONObject">
+        select album_id, tb2.name
+        from deepthink.bytedance_upload_album tb1
+        left join thirtpart.ly_videos tb2 on tb1.ly_video_id=tb2.id
+        where can_promotion is null or can_promotion=0
     </select>
 </mapper>

+ 8 - 1
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/data/service/IBytedanceProductUpdateService.java

@@ -1,5 +1,7 @@
 package cn.com.ctop.job.bytedance.data.service;
 
+import java.io.IOException;
+
 public interface IBytedanceProductUpdateService {
 
     void run() throws Exception;
@@ -7,4 +9,9 @@ public interface IBytedanceProductUpdateService {
     void initNew();
 
     void test() throws Exception;
-}
+
+
+    void uploadAlbum() throws IOException;
+
+    void refreshAlbumStatus() throws IOException;
+}

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

@@ -5,6 +5,7 @@ import cn.com.ctop.job.bytedance.data.service.IBytedanceProductUpdateService;
 import cn.com.ctop.job.bytedance.data.utils.Check;
 import cn.com.ctop.job.bytedance.data.utils.HttpUtils;
 import cn.com.ctop.job.bytedance.utils.FeishuRobotUtil;
+import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
 import lombok.extern.slf4j.Slf4j;
@@ -12,6 +13,7 @@ import org.apache.commons.lang.StringUtils;
 import org.springframework.stereotype.Service;
 
 import javax.annotation.Resource;
+import java.io.IOException;
 import java.util.*;
 import java.util.stream.Collectors;
 @Slf4j
@@ -20,7 +22,8 @@ public class BytedanceProductUpdateServiceImpl implements IBytedanceProductUpdat
     @Resource
     BytedanceProductUpdateMapper bytedanceProductUpdateMapper;
 
-    public static final String APP_ID = "ttba3acc87250c6f7901";
+
+    //商品上传结果通知群
     public static final String HOOK_URL = "https://open.feishu.cn/open-apis/bot/v2/hook/92e2445e-76df-44fb-8f61-f55ac94f49bd";
 
     @Override
@@ -33,16 +36,15 @@ public class BytedanceProductUpdateServiceImpl implements IBytedanceProductUpdat
         iaaProductUpdate(errors);
         log.info("免费商品库更新完成");
         if (!Check.isNull(errors)){
-//            List<String> users = Arrays.asList(
-//                    "44fbaed6" //zhaotx
-//                    ,"58e7a98a"  //xsq
-//            );
+            errors.add(0, "商品上传报错通知");
             FeishuRobotUtil.sendTextToWebhook(StringUtils.join(errors, "\n"), HOOK_URL);
         }
-
     }
 
 
+    /**
+     * 初始化新的字节小程序; 新增字节用的商品库时调用
+     */
     @Override
     public void initNew(){
         List<JSONObject> iapPlatformList = bytedanceProductUpdateMapper.getIAPPlatformList();
@@ -53,13 +55,13 @@ public class BytedanceProductUpdateServiceImpl implements IBytedanceProductUpdat
 
     @Override
     public void test() throws Exception {
-//        uploadAlbum(1077L, 1742489802322972L, "ee6a92328075a92d6819107e0a98ef047cb210f9");
+//        uploadAlbum(31084L, 1742489802322972L, "d22b45ce9033303d22c5f34abcd4600811b18d88");
 //        uploadAlbum();
 //        Thread.sleep(1000);
-//        refreshAlbumStatus();
-        List<String> errors = new ArrayList<>();
-        iapProductUpdate(errors);
-        System.out.println(errors);
+        refreshAlbumStatus();
+//        List<String> errors = new ArrayList<>();
+//        iapProductUpdate(errors);
+//        System.out.println(errors);
 
     }
 
@@ -114,9 +116,9 @@ public class BytedanceProductUpdateServiceImpl implements IBytedanceProductUpdat
      */
     private void iapProductUpdate(List<String> errorBlanket){
         //IAP
-        List<JSONObject> iapPlatformList = bytedanceProductUpdateMapper.getIAPPlatformList();
-        List<JSONObject> iapVideoList = bytedanceProductUpdateMapper.getIAPVideoList();
-        List<JSONObject> iapProductTypeEnums = bytedanceProductUpdateMapper.getIAPProductTypeEnums();
+        List<JSONObject> iapPlatformList = bytedanceProductUpdateMapper.getIAPPlatformList(); //商品库列表
+        List<JSONObject> iapVideoList = bytedanceProductUpdateMapper.getIAPVideoList(); //剧目列表
+        List<JSONObject> iapProductTypeEnums = bytedanceProductUpdateMapper.getIAPProductTypeEnums(); //商品类型
         Map<String, Map<String, String>> advertiserToLinkMap = new HashMap<>();
 
         for (JSONObject obj : iapPlatformList){
@@ -128,7 +130,8 @@ public class BytedanceProductUpdateServiceImpl implements IBytedanceProductUpdat
                 System.out.println("没有找到字节小程序的实例ID: " + advertiserId);
                 continue;
             }
-            Map<String, String> albumIdToLinkMap = getBytedancePlayletPromoteLink(advertiserId, accessToken, instanceId, iapVideoList, errorBlanket);
+            List<JSONObject> iapVideoDouyinList = iapVideoList.stream().filter(obj1 -> "1".equals(obj1.getString("platform_type"))).collect(Collectors.toList());
+            Map<String, String> albumIdToLinkMap = getBytedancePlayletPromoteLink(advertiserId, accessToken, instanceId, iapVideoDouyinList, errorBlanket);
             advertiserToLinkMap.put(advertiserId, albumIdToLinkMap);
         }
 
@@ -145,7 +148,13 @@ public class BytedanceProductUpdateServiceImpl implements IBytedanceProductUpdat
                 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;
@@ -206,13 +215,20 @@ public class BytedanceProductUpdateServiceImpl implements IBytedanceProductUpdat
         profession.put("has_paid_content", "1");
         profession.put("has_motivation_content", "2");
         profession.put("membership_types", platform.getString("membership_types"));
-        profession.put("micro_app_link", advertiserToLinkMap.get(platform.getString("advertiser_id")).get(album_id));
+        Map<String, String> linkObj = advertiserToLinkMap.get(platform.getString("advertiser_id"));
         String play_platform = album.getString("play_platform");
-        if (play_platform.contains("1")){
-            profession.put("ad_carrier", "字节小程序");
+        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")){
+                ad_carrier.add("微信小程序");
+            }
         }else {
-            profession.put("ad_carrier", "字节小程序");
+            profession.put("album_id", album_id);
+            ad_carrier.add("微信小程序");
         }
+        profession.put("ad_carrier", JSON.toJSONString(ad_carrier));
 
         //price_info
         JSONObject price_info = new JSONObject();
@@ -222,11 +238,10 @@ public class BytedanceProductUpdateServiceImpl implements IBytedanceProductUpdat
         request.put("product_info", product_info);
 
 
-                System.out.println("请求地址:" + url);
-                System.out.println("请求头:" + headers);
-                System.out.println("请求参数:" + request.toJSONString());
+//        System.out.println("请求地址:" + url);
+//        System.out.println("请求头:" + headers);
+//        System.out.println("请求参数:" + request.toJSONString());
         String res = HttpUtils.httpPostRequest(url, request, headers);
-//                System.out.println(res);
         JSONObject btRes = JSONObject.parseObject(res);
         int code = btRes.getIntValue("code");
         if (code != 0){
@@ -252,6 +267,7 @@ public class BytedanceProductUpdateServiceImpl implements IBytedanceProductUpdat
                 System.out.println("没有找到字节小程序的实例ID: " + advertiserId);
                 continue; //todo
             }
+            List<JSONObject> iaaVideoDouyinList = iaaVideoList.stream().filter(obj1 -> "1".equals(obj1.getString("platform_type"))).collect(Collectors.toList());
             Map<String, String> albumIdToLinkMap = getBytedancePlayletPromoteLink(advertiserId, accessToken, instanceId, iaaVideoList, errorBlanket);
             advertiserToLinkMap.put(advertiserId, albumIdToLinkMap);
         }
@@ -269,9 +285,13 @@ public class BytedanceProductUpdateServiceImpl implements IBytedanceProductUpdat
                 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){
                     return;
@@ -313,13 +333,21 @@ public class BytedanceProductUpdateServiceImpl implements IBytedanceProductUpdat
         profession.put("has_motivation_content", "2");
         profession.put("membership_types", "5");
         profession.put("starting_unlock_episode", album.getString("starting_unlock_episode"));
-        profession.put("micro_app_link", advertiserToLinkMap.get(platform.getString("advertiser_id")).get(album_id));
+        Map<String, String> linkObj = advertiserToLinkMap.get(platform.getString("advertiser_id"));
         String play_platform = album.getString("play_platform");
-        if (play_platform.contains("1")){
-            profession.put("ad_carrier", "字节小程序,微信小程序");
+        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")){
+                ad_carrier.add("微信小程序");
+            }
         }else {
-            profession.put("ad_carrier", "字节小程序");
+            profession.put("album_id", album_id);
+            ad_carrier.add("微信小程序");
         }
+        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"));
@@ -462,26 +490,35 @@ public class BytedanceProductUpdateServiceImpl implements IBytedanceProductUpdat
     }
 
 
-    private void uploadAlbum(){
-        List<Long> videoIds = bytedanceProductUpdateMapper.getUploadList();
+    public void uploadAlbum() throws IOException {
+        List<String> info = new ArrayList<>();
+        info.add("仅微小剧目上传通知");
+        List<JSONObject> wxVideoInfos = bytedanceProductUpdateMapper.getUploadList();
         JSONObject developerAccount = bytedanceProductUpdateMapper.getDeveloperAccount();
         Long appId = developerAccount.getLong("app_id");
         String appAccessToken = getAppAccessToken(appId, developerAccount.getString("app_secret"));
         if (appAccessToken == null){
             System.out.println("获取app_access_token失败");
+            info.add("获取app_access_token失败");
+            FeishuRobotUtil.sendTextToWebhook(StringUtils.join(info, "\n"), HOOK_URL);
             return;
         }
-        for (Long videoId : videoIds){
+        for (JSONObject vi : wxVideoInfos){
+            Long videoId = vi.getLong("video_id");
             String albumId = uploadAlbum(videoId, appId, appAccessToken);
             if (albumId == null){
-                System.out.println("上传短剧失败,videoId: " + videoId);
-                continue;
+                info.add("上传短剧失败,videoId: " + videoId + ", 剧目名称: " + vi.getString("name"));
+            }else {
+                bytedanceProductUpdateMapper.insertAlbumInfo(albumId, videoId);
+                info.add("上传短剧成功,videoId: " + videoId + ", 剧目名称: " + vi.getString("name") + ", albumId: " + albumId);
             }
-            bytedanceProductUpdateMapper.insertAlbumInfo(albumId, videoId);
         }
+        FeishuRobotUtil.sendTextToWebhook(StringUtils.join(info, "\n"), HOOK_URL);
     }
 
-    private void refreshAlbumStatus(){
+    public void refreshAlbumStatus() throws IOException {
+        List<String> info = new ArrayList<>();
+        info.add("短剧审核状态更新通知");
         JSONObject developerAccount = bytedanceProductUpdateMapper.getDeveloperAccount();
         Long app_id = developerAccount.getLong("app_id");
         String app_secret = developerAccount.getString("app_secret");
@@ -491,8 +528,10 @@ public class BytedanceProductUpdateServiceImpl implements IBytedanceProductUpdat
             return;
         }
 
-        List<String> albums = bytedanceProductUpdateMapper.selectWaitingAlbums();
-        for (String al : albums){
+        List<JSONObject> listAlbum = bytedanceProductUpdateMapper.selectWaitingAlbums();
+        for (JSONObject album : listAlbum){
+            String al = album.getString("album_id");
+            String albumName = album.getString("name");
             String url = "https://api.oceanengine.com/open_api/v3.0/dpa/album_status/get/";
             Map<String, String> headers = new HashMap<>();
             headers.put("App-Access-Token", appAccessToken);
@@ -506,7 +545,7 @@ public class BytedanceProductUpdateServiceImpl implements IBytedanceProductUpdat
                 JSONObject resObj = JSONObject.parseObject(res);
                 int code = resObj.getIntValue("code");
                 if (code != 0){
-                    System.out.println("获取短剧状态失败,code: " + code + ", msg: " + resObj.getString("message"));
+                    info.add("获取短剧状态失败,code: " + code + ", msg: " + resObj.getString("message")+", 剧目名称: " + albumName);
                     continue;
                 }else {
                     JSONObject data = resObj.getJSONObject("data");
@@ -514,20 +553,24 @@ public class BytedanceProductUpdateServiceImpl implements IBytedanceProductUpdat
                     if (isSuccess) {
                         //更新状态
                         bytedanceProductUpdateMapper.updateAlbumInfo(al, 1, null);
+                        info.add("短剧审核通过,albumId: " + al + ", 剧目名称: " + albumName);
                     }else {
                         String failReason = data.getString("can_not_promotion_reason");
                         if ("RESOURCE_CREATING".equals(failReason) || "RESOURCE_AUDITING".equals(failReason)){
                             //等待中
                             bytedanceProductUpdateMapper.updateAlbumInfo(al, 0, failReason);
+                            info.add("短剧审核中,albumId: " + al + ", 剧目名称: " + albumName+", 当前状态: " + failReason);
                         }else {
                             //失败
                             bytedanceProductUpdateMapper.updateAlbumInfo(al, 2, failReason);
+                            info.add("短剧审核失败,albumId: " + al + ", 剧目名称: " + albumName + ", 原因: " + failReason);
                         }
                     }
 
                 }
             }
         }
+        FeishuRobotUtil.sendTextToWebhook(StringUtils.join(info, "\n"), HOOK_URL);
     }
 
 
@@ -557,7 +600,7 @@ public class BytedanceProductUpdateServiceImpl implements IBytedanceProductUpdat
 
         List<JSONObject> videoDetailList = new ArrayList<>();
         for (JSONObject obj : videoDetail){
-            String videoUrl = obj.getString("url");
+            String videoUrl = obj.getString("url").replaceAll("oss\\.artlinkworld\\.cn", "bydance.artlinkworld.cn");//使用单独的域名
             String title = obj.getString("name");
             Integer seq = obj.getInteger("sort");
 

+ 10 - 0
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/handler/BytedanceProductUploadJob.java

@@ -28,4 +28,14 @@ public class BytedanceProductUploadJob {
     public void initProductLinkApp(){
         bytedanceProductUpdateService.initNew();
     }
+
+    @XxlJob("bytedanceProductUploadAlbum")
+    public void uploadAlbum() throws Exception {
+        bytedanceProductUpdateService.uploadAlbum();
+    }
+
+    @XxlJob("bytedanceProductRefreshAlbumStatus")
+    public void refreshAlbumStatus() throws Exception {
+        bytedanceProductUpdateService.refreshAlbumStatus();
+    }
 }