Kaynağa Gözat

Merge branch 'zhaotx'

zhaotx 1 yıl önce
ebeveyn
işleme
cf35c2883e

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

@@ -17,4 +17,21 @@ public interface BytedanceProductUpdateMapper {
 
     int updateInstanceId(@Param("advertiserId") String advertiserId, @Param("instanceId") String instanceId);
 
+    JSONObject getVideoInfo(@Param("videoId") Long videoId);
+    List<JSONObject> getVideoDetail(@Param("videoId") Long videoId);
+
+
+    List<JSONObject> getUploadList();
+
+    JSONObject getDeveloperAccount();
+
+    int insertAlbumInfo(@Param("albumId") String albumId,
+                        @Param("videoId") Long videoId);
+
+    List<JSONObject> selectWaitingAlbums();
+
+    int updateAlbumInfo(@Param("albumId") String albumId,
+                        @Param("canPromotion") int status,
+                        @Param("cannotReason") String failReason);
+
 }

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

@@ -1,11 +1,22 @@
 <?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.com.ctop.job.bytedance.data.mapper.BytedanceProductUpdateMapper">
+    <insert id="insertAlbumInfo">
+        insert into deepthink.bytedance_upload_album
+        (album_id, ly_video_id)
+        values
+        (#{albumId}, #{videoId})
+    </insert>
     <update id="updateInstanceId">
         update deepthink.bytedance_product_main_advertiser
         set mini_instance_id = #{instanceId}
         where advertiser_id = #{advertiserId}
     </update>
+    <update id="updateAlbumInfo">
+        update deepthink.bytedance_upload_album
+        set can_promotion = #{canPromotion}, cannot_reason = #{cannotReason}
+        where album_id = #{albumId}
+    </update>
 
 
     <select id="getIAPPlatformList" resultType="com.alibaba.fastjson.JSONObject">
@@ -23,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',
+        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',
+        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
@@ -60,4 +73,27 @@
         from deepthink.bytedance_product_group_types
         where `type`=1
     </select>
+    <select id="getVideoInfo" resultType="com.alibaba.fastjson.JSONObject">
+        select id, name, label, cover_img, sylloge from thirtpart.ly_videos where id = #{videoId}
+    </select>
+    <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="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))
+        and id in (select video_id from thirtpart.ly_third_videos where platform=1)
+    </select>
+    <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="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>

+ 25 - 25
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/data/mapper/xml/ReportsAdPushMapper.xml

@@ -6,6 +6,7 @@
         concat(round(if(ifnull(sum(real_cost_amount),0)=0, 0, (ifnull(sum(share_iaa_amount),0)+ifnull(sum(share_pay_amount),0))/sum(real_cost_amount)*100), 2), '%') AS real_roi,
         ifnull(sum(cost_amount),0) AS cost_amount,
         round(ifnull(sum(pay_amount), 0), 2) AS pay_amount,
+        ifnull(sum(share_iaa_amount), 0) as share_iaa_amount,
         ifnull(sum(share_iaa_amount), 0) + ifnull(sum(share_pay_amount), 0) - ifnull(round(sum(real_cost_amount), 2), 0) AS real_profit,
         ifnull(sum(iaa_amount), 0) + ifnull(sum(pay_amount), 0) - ifnull(sum(cost_amount), 0) AS water_profit,
         ifnull(sum(share_iaa_amount), 0) + ifnull(sum(share_pay_amount), 0) as end_amount,
@@ -26,6 +27,7 @@
         concat(round(if(ifnull(sum(real_cost_amount),0)=0, 0, (ifnull(sum(share_iaa_amount),0)+ifnull(sum(share_pay_amount),0))/sum(real_cost_amount)*100), 2), '%') AS real_roi,
         ifnull(sum(cost_amount),0) AS cost_amount,
         round(ifnull(sum(pay_amount), 0), 2) AS pay_amount,
+        ifnull(sum(share_iaa_amount), 0) as share_iaa_amount,
         ifnull(sum(share_iaa_amount), 0) + ifnull(sum(share_pay_amount), 0) - ifnull(round(sum(real_cost_amount), 2), 0) AS real_profit,
         ifnull(sum(iaa_amount), 0) + ifnull(sum(pay_amount), 0) - ifnull(sum(cost_amount), 0) AS water_profit,
         ifnull(sum(share_iaa_amount), 0) + ifnull(sum(share_pay_amount), 0) as end_amount
@@ -41,34 +43,32 @@
         ) tb2
     </select>
     <select id="tmpTopMovie" resultType="java.util.Map">
-        select case ot1.movie_source when 2 then movie_name else concat('欢瑞自制-', movie_name) end as movie_name,
-        ot1.rk, ot1.share_end_amount, ot1.end_amount,  ot2.cost_amount, ot2.real_cost_amount,
-        concat(round(if(ifnull(cost_amount,0)=0, 0, end_amount/cost_amount*100), 2), '%') AS water_roi,
-        concat(round(if(ifnull(real_cost_amount,0)=0, 0, share_end_amount/real_cost_amount*100), 2), '%') AS real_roi
-        FROM
-        (select ifnull(tb2.movie_name, tb1.movie_id) as movie_name, movie_source,
-        rank() over (order by sum(end_amount) desc) as rk, sum(end_amount) as end_amount, sum(share_end_amount) as share_end_amount
+        select tb4.standard_movie_id, tb4.standard_movie_name as movie_name, group_concat(distinct case tb4.movie_source when 2 then 2 else 1 end) as movie_source,
+        rank() over (order by sum(end_amount) desc) as rk,
+        sum(share_end_amount) as share_end_amount, sum(end_amount) as end_amount,  sum(cost_amount) as cost_amount, sum(real_cost_amount) as real_cost_amount,
+        concat(round(if(ifnull(sum(cost_amount),0)=0, 0, sum(end_amount)/sum(cost_amount)*100), 2), '%') AS water_roi,
+        concat(round(if(ifnull(sum(real_cost_amount),0)=0, 0, sum(share_end_amount)/sum(real_cost_amount)*100), 2), '%') AS real_roi
         from
-        (select
-        ifnull(sum(iaa_amount), 0) + ifnull(sum(pay_amount), 0) as end_amount,
-        ifnull(sum(share_iaa_amount), 0) + ifnull(sum(share_pay_amount), 0) as share_end_amount,
-        movie_id
-        from
-        application.user_data_report_daily udrd
-        where stat_date = ${date} and movie_id != '-9999'
-        group by movie_id
-        having ifnull(sum(share_iaa_amount), 0) + ifnull(sum(share_pay_amount), 0)>0
-        order by end_amount desc
-        ) tb1
+        (select product_id from application.media_product_report_daily where stat_date=${date}
+        union select movie_id from application.user_data_report_daily where stat_date=${date}) tb1
         left join
-        (select distinct moive_id, REGEXP_REPLACE(movie_name, '[^a-zA-Z一-龥]', '') as movie_name, movie_source from deepthink.all_moive) tb2 on tb1.movie_id=tb2.moive_id
-        group by movie_name order by rk limit 10) ot1
+        (select product_id, round(ifnull(sum(cost_amount),0),2) as cost_amount, sum(real_cost_amount) as real_cost_amount
+        from application.media_product_report_daily where stat_date=${date}
+        group by product_id
+        ) tb2 on tb1.product_id=tb2.product_id
         left join
-        (select REGEXP_REPLACE(product_name, '[^a-zA-Z一-龥]', '') as product_name, round(ifnull(sum(cost_amount),0),2) as cost_amount, sum(real_cost_amount) as real_cost_amount
-        from application.media_product_report_daily where stat_date=${date} group by REGEXP_REPLACE(product_name, '[^a-zA-Z一-龥]', '')
-        ) ot2 on ot1.movie_name=ot2.product_name
-        group by case ot1.movie_source when 2 then movie_name else concat('欢瑞自制-', movie_name) end
-        order by rk
+        (select movie_id, ifnull(sum(iaa_amount), 0) + ifnull(sum(pay_amount), 0) as end_amount,
+        ifnull(sum(share_iaa_amount), 0) + ifnull(sum(share_pay_amount), 0) as share_end_amount
+        from application.user_data_report_daily where stat_date=${date}
+        group by movie_id
+        ) tb3 on tb1.product_id=tb3.movie_id
+        left join
+        (select moive_id, standard_movie_id, standard_movie_name, movie_source from deepthink.all_moive
+        ) tb4 on tb1.product_id=tb4.moive_id
+        where 1=1 and tb1.product_id!='-9999'
+        group by tb4.standard_movie_name
+        order by sum(end_amount) desc
+        limit 10
     </select>
 
 

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

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

+ 2 - 0
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/data/service/IReportsAdPushService.java

@@ -3,4 +3,6 @@ package cn.com.ctop.job.bytedance.data.service;
 public interface IReportsAdPushService {
 
     void send();
+
+    void preSend();
 }

+ 369 - 109
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();
@@ -51,6 +53,18 @@ public class BytedanceProductUpdateServiceImpl implements IBytedanceProductUpdat
         initNew(iapPlatformList);
     }
 
+    @Override
+    public void test() throws Exception {
+//        uploadAlbum(31084L, 1742489802322972L, "d22b45ce9033303d22c5f34abcd4600811b18d88");
+//        uploadAlbum();
+//        Thread.sleep(1000);
+        refreshAlbumStatus();
+//        List<String> errors = new ArrayList<>();
+//        iapProductUpdate(errors);
+//        System.out.println(errors);
+
+    }
+
     public void initNew(List<JSONObject> platformList)  {
         //为广告主账户创建新的字节小程序
         //step1 查询表里广告主是否都有自己的字节小程序、
@@ -96,11 +110,15 @@ public class BytedanceProductUpdateServiceImpl implements IBytedanceProductUpdat
         }
     }
 
+    /**
+     * 付费短剧更新
+     * @param errorBlanket
+     */
     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){
@@ -112,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);
         }
 
@@ -129,69 +148,106 @@ public class BytedanceProductUpdateServiceImpl implements IBytedanceProductUpdat
                 System.out.println("\n\n\n");
                 continue;
             }
+            Integer platformType1 = obj.getInteger("platform_type");
+
             for (JSONObject platform : iapPlatformList) {
-                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");
-
-                JSONObject request = new JSONObject();
-                String album_id = obj.getString("album_id");
-                request.put("product_id", obj.getLongValue("album_id"));
-                JSONObject product_info = new JSONObject();
-                product_info.put("name", obj.getString("name"));
-                product_info.put("image_url", obj.getString("img"));
-                product_info.put("status", 1);
-                product_info.put("stock", 1);
-                JSONObject productType = iapProductTypeMap.get(theme);
-                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"));
-                request.put("advertiser_id", platform.getLongValue("advertiser_id"));
-                request.put("platform_id", platform.getLongValue("platform_id"));
-                JSONObject profession = new JSONObject();
-                profession.put("copyright_owner", obj.getString("copyright_owner"));
-                profession.put("playlet_gender", "3");
-                profession.put("playlet_num", obj.getString("playlet_num"));
-                profession.put("playlet_duration", obj.getString("playlet_duration"));
-                profession.put("start_pay_playlet", obj.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"));
+                Integer platformType2 = platform.getInteger("platform_type");
+                if (!Objects.equals(platformType1, platformType2)){
+                    continue;
                 }
-                if (platform.getDouble("recommended_charge") > 0.0){
-                    profession.put("recommended_charge", platform.getString("recommended_charge"));
+                int rescode = uploadIapProduct(platform, obj, advertiserToLinkMap, errorBlanket, iapProductTypeMap.get(theme));
+                if (rescode!= 0){
+//                    return;
                 }
-                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));
-                //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);
+//                System.out.println("\n\n\n");
+            }
+        }
+    }
 
+    /**
+     * 付费短剧更新
+     * @param platform 商品库信息
+     * @param album 剧信息
+     * @param advertiserToLinkMap
+     * @param errorBlanket
+     * @param productType 商品短剧类型
+     */
+    private int uploadIapProduct(JSONObject platform, JSONObject album,
+                                  Map<String, Map<String, String>> advertiserToLinkMap,
+                                  List<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");
 
-//                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){
-                    errorBlanket.add("上传付费商品失败,code: " + code + ", msg: " + btRes.getString("message")+", 关联剧目: " + obj.getString("name"));
-                }
-//                System.out.println("\n\n\n");
+        JSONObject request = new JSONObject();
+        String album_id = album.getString("album_id");
+        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"));
+        request.put("advertiser_id", platform.getLongValue("advertiser_id"));
+        request.put("platform_id", platform.getLongValue("platform_id"));
+        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("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");
+        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("album_id", album_id);
+            ad_carrier.add("微信小程序");
+        }
+        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);
+
+
+//        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){
+            errorBlanket.add("上传付费商品失败,code: " + code + ", msg: " + btRes.getString("message")+", 关联剧目: " + album.getString("name"));
         }
+        return code;
     }
 
     private void iaaProductUpdate(List<String> errorBlanket){
@@ -211,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);
         }
@@ -228,51 +285,16 @@ public class BytedanceProductUpdateServiceImpl implements IBytedanceProductUpdat
                 System.out.println("\n\n\n");
                 continue;
             }
-
+            Integer platformType1 = obj.getInteger("platform_type");
 
             for (JSONObject platform : iaaPlatformList) {
-                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 = obj.getString("album_id");
-                JSONObject request = new JSONObject();
-                request.put("product_id", obj.getLongValue("album_id"));
-                JSONObject product_info = new JSONObject();
-                product_info.put("name", obj.getString("name"));
-                product_info.put("image_url", obj.getString("img"));
-                product_info.put("status", 1);
-                product_info.put("stock", 1);
-                JSONObject productType = iaaProductTypeMap.get(theme);
-                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", obj.getString("copyright_owner"));
-                profession.put("playlet_gender", "3");
-                profession.put("playlet_num", obj.getString("playlet_num"));
-                profession.put("playlet_duration", obj.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", obj.getString("starting_unlock_episode"));
-                profession.put("micro_app_link", advertiserToLinkMap.get(platform.getString("advertiser_id")).get(album_id));
-                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){
-                    errorBlanket.add("上传免费商品失败,code: " + code + ", msg: " + btRes.getString("message")+", 关联剧目: " + obj.getString("name"));
+                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;
                 }
 //                System.out.println(res);
 //                System.out.println("\n\n\n");
@@ -280,6 +302,69 @@ public class BytedanceProductUpdateServiceImpl implements IBytedanceProductUpdat
         }
     }
 
+    private int uploadIaaProduct(JSONObject platform, JSONObject album, Map<String,
+            Map<String, String>> advertiserToLinkMap,
+                                  List<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"));
+        String play_platform = album.getString("play_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")){
+                ad_carrier.add("微信小程序");
+            }
+        }else {
+            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"));
+        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){
+            errorBlanket.add("上传免费商品失败,code: " + code + ", msg: " + btRes.getString("message")+", 关联剧目: " + album.getString("name"));
+        }
+        return code;
+    }
+
     /**
      *
      * @param advertiserId 商品库主账户ID,也是创建字节小程序的ID
@@ -404,4 +489,179 @@ public class BytedanceProductUpdateServiceImpl implements IBytedanceProductUpdat
 
     }
 
+
+    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 (JSONObject vi : wxVideoInfos){
+            Long videoId = vi.getLong("video_id");
+            String albumId = uploadAlbum(videoId, appId, appAccessToken);
+            if (albumId == null){
+                info.add("上传短剧失败,videoId: " + videoId + ", 剧目名称: " + vi.getString("name"));
+            }else {
+                bytedanceProductUpdateMapper.insertAlbumInfo(albumId, videoId);
+                info.add("上传短剧成功,videoId: " + videoId + ", 剧目名称: " + vi.getString("name") + ", albumId: " + albumId);
+            }
+        }
+        FeishuRobotUtil.sendTextToWebhook(StringUtils.join(info, "\n"), HOOK_URL);
+    }
+
+    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");
+        String appAccessToken = getAppAccessToken(app_id, app_secret);
+        if (appAccessToken == null){
+            System.out.println("获取app_access_token失败");
+            return;
+        }
+
+        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);
+            Map<String, Object> params = new HashMap<>();
+            params.put("album_id", al);
+            params.put("app_id", app_id);
+            String res = HttpUtils.httpGet(url, params, headers);
+            if (res == null || res.isEmpty()){
+                System.out.println("获取短剧状态失败,albumId: " + al);
+            }else {
+                JSONObject resObj = JSONObject.parseObject(res);
+                int code = resObj.getIntValue("code");
+                if (code != 0){
+                    info.add("获取短剧状态失败,code: " + code + ", msg: " + resObj.getString("message")+", 剧目名称: " + albumName);
+                    continue;
+                }else {
+                    JSONObject data = resObj.getJSONObject("data");
+                    boolean isSuccess = data.getBooleanValue("can_promotion");
+                    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);
+    }
+
+
+    /**
+     * 上传短剧
+     * @param videoId from ly_videos
+     * @return albumId
+     */
+    private String uploadAlbum(long videoId, Long appId, String appAccessToken){
+        JSONObject video = bytedanceProductUpdateMapper.getVideoInfo(videoId);
+        if (video == null){
+            System.out.println("没有找到视频信息,videoId: " + videoId);
+            return null;
+        }
+        String videoName = video.getString("name");
+        Integer sylloge = video.getInteger("sylloge");//总集数
+        List<JSONObject> videoDetail = bytedanceProductUpdateMapper.getVideoDetail(videoId);
+        if (videoDetail == null || videoDetail.isEmpty()){
+            System.out.println("没有找到视频剧集详情,videoId: " + videoId);
+            return null;
+        }
+
+        JSONObject requestBody = new JSONObject();
+        requestBody.put("album_title", videoName);
+        requestBody.put("seq_num", sylloge);
+        requestBody.put("app_id", appId);
+
+        List<JSONObject> videoDetailList = new ArrayList<>();
+        for (JSONObject obj : videoDetail){
+            String videoUrl = obj.getString("url").replaceAll("oss\\.artlinkworld\\.cn", "bydance.artlinkworld.cn");//使用单独的域名
+            String title = obj.getString("name");
+            Integer seq = obj.getInteger("sort");
+
+            JSONObject meta = new JSONObject();
+            meta.put("url", videoUrl);
+            meta.put("title", title);
+            meta.put("seq", seq);
+            videoDetailList.add(meta);
+        }
+        requestBody.put("video_meta_mico", videoDetailList);
+
+        String url = "https://api.oceanengine.com/open_api/v3.0/dpa/album/create/";
+        Map<String, String> headers = new HashMap<>();
+        headers.put("App-Access-Token", appAccessToken);
+        headers.put("Content-Type", "application/json");
+
+        System.out.println(requestBody.toJSONString());
+//        return null;
+        String res = HttpUtils.httpPostRequest(url, requestBody, headers);
+        System.out.println(">>> "+res);
+        if (res == null || res.isEmpty()){
+            System.out.println("上传短剧失败, 返回null");
+            return null;
+        }else {
+            JSONObject resObj = JSONObject.parseObject(res);
+            int code = resObj.getIntValue("code");
+            if (code != 0){
+                System.out.println("上传短剧失败,code: " + code + ", msg: " + resObj.getString("message"));
+                return null;
+            }else {
+                String albumId = resObj.getJSONObject("data").getString("album_id");
+                return albumId;
+            }
+        }
+    }
+
+
+    private String getAppAccessToken(Long app_id, String app_secret){
+        String url = "https://open.oceanengine.com/open_api/oauth2/app_access_token/";
+        if (app_id == null || app_secret == null){
+            return null;
+        }
+        JSONObject body = new JSONObject();
+        body.put("app_id", app_id);
+        body.put("secret", app_secret);
+        Map<String, String> headers = new HashMap<>();
+        headers.put("Content-Type", "application/json");
+        String res = HttpUtils.httpPostRequest(url, body, headers);
+        if (res == null || res.isEmpty()){
+            return null;
+        }else {
+            JSONObject resObj = JSONObject.parseObject(res);
+            int code = resObj.getIntValue("code");
+            if (code != 0){
+                System.out.println("获取app_access_token失败,code: " + code + ", msg: " + resObj.getString("message"));
+                return null;
+            }else {
+                return resObj.getJSONObject("data").getString("access_token");
+            }
+        }
+    }
+
+
 }

+ 11 - 5
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/data/service/impl/DateReportsPushServiceImpl.java

@@ -74,7 +74,7 @@ public class DateReportsPushServiceImpl implements IDateReportsPushService {
         List<String> chatid = Arrays.asList(
                 "oc_275f17aa4bf8fae649ef281a2b9250f6"
         );
-        sendParam("注:当天ROI数据有微小1%-2%差异,以次日10点推送为准,番茄ROI数据需要次日9点左右获取", userIds, chatid);
+        sendParam("注:当天ROI数据有微小1%-2%差异,以次日10点推送为准,番茄ROI数据需要次日9点左右获取;暂不包含广点通数据", userIds, chatid);
     }
 
     /**
@@ -91,7 +91,7 @@ public class DateReportsPushServiceImpl implements IDateReportsPushService {
         );
         List<String> chatid = Arrays.asList(
         );
-        sendParam("", userIds, chatid);
+        sendParam("暂不包含广点通数据", userIds, chatid);
     }
 
 
@@ -117,9 +117,10 @@ public class DateReportsPushServiceImpl implements IDateReportsPushService {
                 new Pair<>("cost_amount", "消耗金额"),
                 new Pair<>("end_amount", "结算金额"),
                 new Pair<>("pay_amount", "充值金额"),
-                new Pair<>("water_roi", "流水ROI"),
+                new Pair<>("share_iaa_amount", "广告预估收入"),
+//                new Pair<>("water_roi", "流水ROI"),
                 new Pair<>("real_roi", "真实ROI"),
-                new Pair<>("water_profit", "流水利润"),
+//                new Pair<>("water_profit", "流水利润"),
                 new Pair<>("real_profit", "真实利润")
         );
         JSONArray dateIndicatorTable = new JSONArray();
@@ -164,8 +165,13 @@ public class DateReportsPushServiceImpl implements IDateReportsPushService {
         JSONArray movieRankTable = new JSONArray();
         for (Map<String, String> movie : movieData){
             JSONObject obj = new JSONObject();
+            String movieSource = String.valueOf(movie.get("movie_source"));
+            String movieName = String.valueOf(movie.get("movie_name"));
+            if (!Check.isNull(movieSource) && movieSource.contains("1")){
+                movieName = "欢瑞自制-"+movieName;
+            }
             obj.put("rank", String.valueOf(movie.get("rk")));
-            obj.put("movieName", String.valueOf(movie.get("movie_name")));
+            obj.put("movieName", movieName);
             obj.put("endAmount", String.valueOf(movie.get("share_end_amount")));
             obj.put("realROI", String.valueOf(movie.get("real_roi")));
             movieRankTable.add(obj);

Dosya farkı çok büyük olduğundan ihmal edildi
+ 38 - 19
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/data/service/impl/ReportsAdPushServiceImpl.java


+ 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();
+    }
 }