|
@@ -0,0 +1,412 @@
|
|
|
+package cn.com.ctop.kuaishou.modules.batch.service.impl;
|
|
|
+
|
|
|
+import cn.com.ctop.common.module.entity.CtopOauthToken;
|
|
|
+import cn.com.ctop.common.module.utils.Check;
|
|
|
+import cn.com.ctop.kuaishou.modules.batch.entity.KuaiShouImageGet;
|
|
|
+import cn.com.ctop.kuaishou.modules.batch.entity.KuaishouStrategy;
|
|
|
+import cn.com.ctop.kuaishou.modules.batch.mapper.KuaishouStrategyMapper;
|
|
|
+import cn.com.ctop.kuaishou.modules.batch.service.IKuaiShouImageGetService;
|
|
|
+import cn.com.ctop.kuaishou.modules.batch.service.IKuaiShouMaterialUploadService;
|
|
|
+import cn.com.ctop.kuaishou.modules.batch.service.IKuaishouInterfaceService;
|
|
|
+import cn.com.ctop.kuaishou.modules.batch.service.IKuaishouStrategyService;
|
|
|
+import com.alibaba.fastjson.JSONArray;
|
|
|
+import com.alibaba.fastjson.JSONObject;
|
|
|
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
|
|
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|
|
+import org.jeecg.common.util.DateUtils;
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
+
|
|
|
+import java.util.HashMap;
|
|
|
+import java.util.Map;
|
|
|
+
|
|
|
+/**
|
|
|
+ * 快手-优化评估策略表
|
|
|
+ *
|
|
|
+ * @author jeecg-boot
|
|
|
+ * @version V1.0
|
|
|
+ * @date 2020-12-10
|
|
|
+ */
|
|
|
+@Service
|
|
|
+public class KuaishouStrategyServiceImpl extends ServiceImpl<KuaishouStrategyMapper, KuaishouStrategy> implements IKuaishouStrategyService {
|
|
|
+ @Autowired
|
|
|
+ private IKuaishouInterfaceService kuaishouInterfaceService;
|
|
|
+ @Autowired
|
|
|
+ private IKuaiShouImageGetService imageGetService;
|
|
|
+ @Autowired
|
|
|
+ private IKuaiShouMaterialUploadService uploadService;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @param oauthToken token签名
|
|
|
+ * @param strategy 策略对象
|
|
|
+ * @param groupJson 广告计划
|
|
|
+ * @return void
|
|
|
+ * @throws
|
|
|
+ * @author ZHAOXA
|
|
|
+ */
|
|
|
+ private void createGroupLevelStrategy(CtopOauthToken oauthToken, KuaishouStrategy strategy, JSONObject groupJson) throws Exception {
|
|
|
+ JSONObject unitJson = new JSONObject();
|
|
|
+ //广告计划ID
|
|
|
+ if (!Check.isNull(groupJson.getString("campaignId"))) {
|
|
|
+ unitJson.put("campaign_id", groupJson.getString("campaignId"));
|
|
|
+ }
|
|
|
+ //广告组名称
|
|
|
+ if (!Check.isNull(groupJson.getString("unitName"))) {
|
|
|
+ unitJson.put("unit_name", groupJson.getString("unitName"));
|
|
|
+ }
|
|
|
+ // 优化目标出价类型
|
|
|
+ if (!Check.isNull(groupJson.getInteger("bidType"))) {
|
|
|
+ unitJson.put("bid_type", groupJson.getInteger("bidType"));
|
|
|
+ }
|
|
|
+ /* 资源位置
|
|
|
+ 1:优选广告位
|
|
|
+ 3:视频播放页广告-便利贴广告(不支持深度转化目标的优化);
|
|
|
+ 5:联盟广告,与其他类型互斥
|
|
|
+ 6:上下滑大屏广告;
|
|
|
+ 7:信息流广告;
|
|
|
+ 3、6、7可多选*/
|
|
|
+ Integer sceneId = groupJson.getJSONArray("sceneId").getInteger(0);
|
|
|
+ if (!Check.isNull(groupJson.getJSONArray("sceneId"))) {
|
|
|
+ unitJson.put("scene_id", groupJson.getJSONArray("sceneId"));
|
|
|
+ }
|
|
|
+ // 资源创作方式 4: 自定义;5:程序化创意 7:程序化创意2.0
|
|
|
+ if (!Check.isNull(groupJson.getInteger("unitType"))) {
|
|
|
+ unitJson.put("unit_type", groupJson.getInteger("unitType"));
|
|
|
+ }
|
|
|
+ // 创意展现方式1 - 轮播 2 - 优选
|
|
|
+ if (!Check.isNull(groupJson.getInteger("showMode"))) {
|
|
|
+ unitJson.put("show_mode", groupJson.getInteger("showMode"));
|
|
|
+ }
|
|
|
+ /**
|
|
|
+ 投放方式
|
|
|
+ 1 - 加速投放
|
|
|
+ 2 - 平滑投放
|
|
|
+ 3-优先低成本(投放时间范围只可为全天;预算不可为不限或空)
|
|
|
+ */
|
|
|
+ if (!Check.isNull(groupJson.getInteger("speed"))) {
|
|
|
+ unitJson.put("speed", groupJson.getInteger("speed"));
|
|
|
+ }
|
|
|
+
|
|
|
+ // 封面点击出价
|
|
|
+ if (!Check.isNull(strategy.getBid())) {
|
|
|
+ unitJson.put("bid", strategy.getBid());
|
|
|
+ }
|
|
|
+
|
|
|
+ // 深度转化出价
|
|
|
+ if (!Check.isNull(strategy.getCpaBid())) {
|
|
|
+ unitJson.put("cpa_bid", strategy.getCpaBid());
|
|
|
+ }
|
|
|
+ // 深度转化目标出价
|
|
|
+ if (!Check.isNull(strategy.getDeepConversionBid())) {
|
|
|
+ unitJson.put("deep_conversion_bid", strategy.getDeepConversionBid());
|
|
|
+ }
|
|
|
+ // 深度转化目标
|
|
|
+ if (!Check.isNull(strategy.getDeepConversionType())) {
|
|
|
+ unitJson.put("deep_conversion_type", strategy.getDeepConversionType());
|
|
|
+ }
|
|
|
+ // 优化目标
|
|
|
+ if (!Check.isNull(strategy.getOcpxActionType())) {
|
|
|
+ unitJson.put("ocpx_action_type", strategy.getOcpxActionType());
|
|
|
+ }
|
|
|
+ //投放开始时间
|
|
|
+ if (!Check.isNull(strategy.getBeginTime())) {
|
|
|
+ String nowDate = DateUtils.getNowDate("yyyy-MM-dd");
|
|
|
+ boolean beginTimeBoolean = DateUtils.compare(strategy.getBeginTime(), nowDate);
|
|
|
+ if (beginTimeBoolean) {
|
|
|
+ unitJson.put("begin_time", nowDate);
|
|
|
+ } else {
|
|
|
+ unitJson.put("begin_time", strategy.getBeginTime());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 投放结束时间
|
|
|
+ if (!Check.isNull(strategy.getEndTime())) {
|
|
|
+ unitJson.put("end_time", strategy.getEndTime());
|
|
|
+ }
|
|
|
+ // 投放时间段
|
|
|
+ if (!Check.isNull(strategy.getScheduleTime())) {
|
|
|
+ unitJson.put("schedule_time", strategy.getScheduleTime());
|
|
|
+ }
|
|
|
+ //定向模板id(选)
|
|
|
+ Long templateId = strategy.getTemplateId();
|
|
|
+ if (!Check.isNull(templateId)) {
|
|
|
+ unitJson.put("template_id", templateId);
|
|
|
+ }
|
|
|
+ // 优先从系统应用商店下载 1:优先从系统应用商店下载使用,默认0
|
|
|
+ if (!Check.isNull(groupJson.getInteger("useAppMarket"))) {
|
|
|
+ unitJson.put("use_app_market", groupJson.getInteger("useAppMarket"));
|
|
|
+ }
|
|
|
+ /*应用商店列表
|
|
|
+ 华为:huawei,
|
|
|
+ OPPO:oppo
|
|
|
+ VIVO:vivo
|
|
|
+ 小米:xiaomi
|
|
|
+ 魅族:meizu
|
|
|
+ 锤子:smartisan*/
|
|
|
+ if (!Check.isNull(groupJson.getJSONArray("appStore"))) {
|
|
|
+ unitJson.put("app_store", groupJson.getJSONArray("appStore"));
|
|
|
+ }
|
|
|
+ // 转化目标id
|
|
|
+ if (!Check.isNull(groupJson.getInteger("convertId"))) {
|
|
|
+ unitJson.put("convert_id", groupJson.getInteger("convertId"));
|
|
|
+ }
|
|
|
+ // 广告组单日预算 指定0表示预算不限,默认为0;不小于100元,不超过100000000元,仅支持输入数字;
|
|
|
+ if (!Check.isNull(groupJson.getLong("dayBudget"))) {
|
|
|
+ unitJson.put("day_budget", groupJson.getLong("dayBudget"));
|
|
|
+ }
|
|
|
+ // url类型
|
|
|
+ if (!Check.isNull(groupJson.getInteger("urlType"))) {
|
|
|
+ unitJson.put("url_type", groupJson.getInteger("urlType"));
|
|
|
+ }
|
|
|
+ // url类型
|
|
|
+ if (!Check.isNull(groupJson.getString("webUriType"))) {
|
|
|
+ unitJson.put("web_uri_type", groupJson.getString("webUriType"));
|
|
|
+ }
|
|
|
+ // url
|
|
|
+ if (!Check.isNull(groupJson.getString("url"))) {
|
|
|
+ unitJson.put("url", groupJson.getString("url"));
|
|
|
+ }
|
|
|
+ // appId
|
|
|
+ if (!Check.isNull(groupJson.getLong("appId"))) {
|
|
|
+ unitJson.put("app_id", groupJson.getLong("appId"));
|
|
|
+ }
|
|
|
+ // 预约广告 1:IOS预约 缺省为不传或传0
|
|
|
+ if (!Check.isNull(groupJson.getLong("siteType"))) {
|
|
|
+ unitJson.put("site_type", groupJson.getLong("siteType"));
|
|
|
+ }
|
|
|
+ // 游戏礼包码
|
|
|
+ if (!Check.isNull(groupJson.getLong("giftData"))) {
|
|
|
+ unitJson.put("gift_data", groupJson.getLong("giftData"));
|
|
|
+ }
|
|
|
+ // -----------------用户定向-----------
|
|
|
+ JSONObject targetJson = new JSONObject();
|
|
|
+ // 地域
|
|
|
+ if (!Check.isNull(strategy.getRegion())) {
|
|
|
+ targetJson.put("region", strategy.getRegion());
|
|
|
+ }
|
|
|
+ // 自定义年龄段
|
|
|
+ JSONArray ageArr = groupJson.getJSONArray("age");
|
|
|
+ if (!Check.isNull(ageArr)) {
|
|
|
+ JSONObject ageJson = new JSONObject();
|
|
|
+ ageJson.put("min", ageArr.get(0));
|
|
|
+ ageJson.put("max", ageArr.get(1));
|
|
|
+ targetJson.put("age", ageJson);
|
|
|
+ }
|
|
|
+ // 固定年龄段
|
|
|
+ if (!Check.isNull(strategy.getAgesRange())) {
|
|
|
+ targetJson.put("ages_range", strategy.getAgesRange());
|
|
|
+ }
|
|
|
+ // 性别
|
|
|
+ if (!Check.isNull(strategy.getGender())) {
|
|
|
+ targetJson.put("gender", strategy.getGender());
|
|
|
+ }
|
|
|
+ //操作系统
|
|
|
+ if (!Check.isNull(strategy.getPlatformOs())) {
|
|
|
+ targetJson.put("platform_os", strategy.getPlatformOs());
|
|
|
+ }
|
|
|
+ //Android版本
|
|
|
+ if (!Check.isNull(groupJson.getInteger("androidOsv"))) {
|
|
|
+ targetJson.put("android_osv", groupJson.getInteger("androidOsv"));
|
|
|
+ }
|
|
|
+ // iOS版本
|
|
|
+ if (!Check.isNull(groupJson.getInteger("iosOsv"))) {
|
|
|
+ targetJson.put("ios_osv", groupJson.getInteger("iosOsv"));
|
|
|
+ }
|
|
|
+ //网络环境
|
|
|
+ if (!Check.isNull(groupJson.getInteger("network"))) {
|
|
|
+ targetJson.put("network", groupJson.getInteger("network"));
|
|
|
+ }
|
|
|
+ //设备品牌
|
|
|
+ if (!Check.isNull(groupJson.getJSONArray("deviceBrand"))) {
|
|
|
+ targetJson.put("device_brand", groupJson.getJSONArray("deviceBrand"));
|
|
|
+ }
|
|
|
+ //设备价格
|
|
|
+ if (!Check.isNull(groupJson.getJSONArray("devicePrice"))) {
|
|
|
+ targetJson.put("device_price", groupJson.getJSONArray("devicePrice"));
|
|
|
+ }
|
|
|
+
|
|
|
+ if (sceneId != 5) {
|
|
|
+ //过滤已转化人群纬度
|
|
|
+ if (!Check.isNull(groupJson.getInteger("filterConvertedLevel"))) {
|
|
|
+ targetJson.put("filter_converted_level", groupJson.getInteger("filterConvertedLevel"));
|
|
|
+ }
|
|
|
+ //商业兴趣类型
|
|
|
+ if (!Check.isNull(groupJson.getInteger("businessInterestType"))) {
|
|
|
+ targetJson.put("business_interest_type", groupJson.getInteger("businessInterestType"));
|
|
|
+ }
|
|
|
+ // 商业兴趣
|
|
|
+ if (!Check.isNull(groupJson.getJSONArray("businessInterest"))) {
|
|
|
+ targetJson.put("business_interest", groupJson.getJSONArray("businessInterest"));
|
|
|
+ }
|
|
|
+ //网红粉丝
|
|
|
+ if (!Check.isNull(groupJson.getJSONArray("fansStar"))) {
|
|
|
+ targetJson.put("fans_star", groupJson.getJSONArray("fansStar"));
|
|
|
+ }
|
|
|
+ //兴趣视频用户
|
|
|
+ if (!Check.isNull(groupJson.getJSONArray("interestVideo"))) {
|
|
|
+ targetJson.put("interest_video", groupJson.getJSONArray("interestVideo"));
|
|
|
+ }
|
|
|
+ //智能扩量
|
|
|
+ JSONObject intelliExtendJson = new JSONObject();
|
|
|
+ // 开启智能扩量
|
|
|
+ if (!Check.isNull(groupJson.getInteger("isOpen"))) {
|
|
|
+ intelliExtendJson.put("is_open", groupJson.getInteger("isOpen"));
|
|
|
+ }
|
|
|
+ //不可突破年龄
|
|
|
+ if (!Check.isNull(groupJson.getInteger("noAgeBreak"))) {
|
|
|
+ intelliExtendJson.put("no_age_break", groupJson.getInteger("noAgeBreak"));
|
|
|
+ }
|
|
|
+ //不可突破性别
|
|
|
+ if (!Check.isNull(groupJson.getInteger("noGenderBreak"))) {
|
|
|
+ intelliExtendJson.put("no_gender_break", groupJson.getInteger("noGenderBreak"));
|
|
|
+ }
|
|
|
+ // 不可突破地域
|
|
|
+ if (!Check.isNull(groupJson.getInteger("noAreaBreak"))) {
|
|
|
+ intelliExtendJson.put("no_area_break", groupJson.getInteger("noAreaBreak"));
|
|
|
+ }
|
|
|
+ if (!Check.isNull(intelliExtendJson)) {
|
|
|
+ targetJson.put("intelli_extend", intelliExtendJson);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // APP行为-按分类
|
|
|
+ if (!Check.isNull(groupJson.getJSONArray("appInterest"))) {
|
|
|
+ targetJson.put("app_interest", groupJson.getJSONArray("appInterest"));
|
|
|
+ }
|
|
|
+ // APP行为-按APP名称
|
|
|
+ if (!Check.isNull(groupJson.getJSONArray("appIds"))) {
|
|
|
+ targetJson.put("app_ids", groupJson.getJSONArray("appIds"));
|
|
|
+ }
|
|
|
+ // 人群包定向
|
|
|
+ if (!Check.isNull(strategy.getPopulation())) {
|
|
|
+ targetJson.put("population", strategy.getPopulation());
|
|
|
+ }
|
|
|
+ // 人群包排除
|
|
|
+ if (!Check.isNull(strategy.getExcludePopulation())) {
|
|
|
+ targetJson.put("exclude_population", strategy.getExcludePopulation());
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!Check.isNull(groupJson.getJSONArray("thirdPlatformCode"))) {
|
|
|
+ targetJson.put("third_platform_code", groupJson.getJSONArray("thirdPlatformCode"));
|
|
|
+ }
|
|
|
+ unitJson.put("target", targetJson);
|
|
|
+ Map<String, Object> returnUnitMap = kuaishouInterfaceService.adUnitCreate(oauthToken.getAccessToken(), oauthToken.getAccountId(), unitJson, 1);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 根据策略创建创意
|
|
|
+ *
|
|
|
+ * @param
|
|
|
+ * @return com.alibaba.fastjson.JSONObject
|
|
|
+ * @throws
|
|
|
+ * @author ZHAOXA
|
|
|
+ */
|
|
|
+ private Map<String, Object> createCreativeLevelStrategy(CtopOauthToken oauthToken, KuaishouStrategy strategy, JSONObject data) {
|
|
|
+ Map<String, Object> resultMap = new HashMap<>();
|
|
|
+ JSONObject creativeJson = new JSONObject();
|
|
|
+ //广告组ID
|
|
|
+ if (!Check.isNull(data.get("unitId"))) {
|
|
|
+ creativeJson.put("unit_id", data.get("unitId"));
|
|
|
+ }
|
|
|
+ //创意名称
|
|
|
+ if (!Check.isNull(data.get("creativeName"))) {
|
|
|
+ creativeJson.put("creative_name", data.get("creativeName"));
|
|
|
+ }
|
|
|
+ //视频ID
|
|
|
+ if (!Check.isNull(data.get("photoId"))) {
|
|
|
+ creativeJson.put("photo_id", data.get("photoId"));
|
|
|
+ }
|
|
|
+ /**
|
|
|
+ * 素材类型
|
|
|
+ * 1:竖版视频
|
|
|
+ * 2:横版视频
|
|
|
+ * 4:便利贴单图图片创意
|
|
|
+ * 5:竖版图片
|
|
|
+ * 6:横版图片
|
|
|
+ */
|
|
|
+ String creativeMaterialType = data.getString("creativeMaterialType");
|
|
|
+ if (!Check.isNull(creativeMaterialType)) {
|
|
|
+ creativeJson.put("creative_material_type", creativeMaterialType);
|
|
|
+ }
|
|
|
+ //行动号召按钮文案
|
|
|
+ if (!Check.isNull(data.getString("actionBarText"))) {
|
|
|
+ creativeJson.put("action_bar_text", data.getString("actionBarText"));
|
|
|
+ }
|
|
|
+ //广告语
|
|
|
+ if (!Check.isNull(data.getString("description"))) {
|
|
|
+ creativeJson.put("description", data.getString("description"));
|
|
|
+ }
|
|
|
+ //便利贴创意短广告语
|
|
|
+ if (!Check.isNull(data.getString("shortSlogan"))) {
|
|
|
+ creativeJson.put("short_slogan", data.getString("shortSlogan"));
|
|
|
+ }
|
|
|
+ //封面广告语标题
|
|
|
+ if (!Check.isNull(data.getString("stickerTitle"))) {
|
|
|
+ creativeJson.put("sticker_title", data.getString("stickerTitle"));
|
|
|
+ }
|
|
|
+ //贴纸样式类型
|
|
|
+ if (!Check.isNull(data.getString("overlayType"))) {
|
|
|
+ creativeJson.put("overlay_type", data.getString("overlayType"));
|
|
|
+ }
|
|
|
+ //广告标签
|
|
|
+ if (!Check.isNull(data.getString("exposeTag"))) {
|
|
|
+ creativeJson.put("expose_tag", data.getString("exposeTag"));
|
|
|
+ }
|
|
|
+ //广告标签2期
|
|
|
+ if (!Check.isNull(data.getJSONArray("newExposeTag"))) {
|
|
|
+ creativeJson.put("new_expose_tag", data.getJSONArray("newExposeTag"));
|
|
|
+ }
|
|
|
+ //安卓下载中间页ID
|
|
|
+ if (!Check.isNull(data.getLong("siteId"))) {
|
|
|
+ creativeJson.put("site_id", data.getLong("siteId"));
|
|
|
+ }
|
|
|
+ String imageToken = null;
|
|
|
+ String signature = data.getString("signature");
|
|
|
+ if (!Check.isNull(signature)) {
|
|
|
+ QueryWrapper<KuaiShouImageGet> queryWrapper = new QueryWrapper<>();
|
|
|
+ queryWrapper.eq("account_id", oauthToken.getAccountId());
|
|
|
+ queryWrapper.eq("signature", signature);
|
|
|
+ queryWrapper.last("limit 1");
|
|
|
+ KuaiShouImageGet imageGet = imageGetService.getOne(queryWrapper);
|
|
|
+ if (!Check.isNull(imageGet)) {
|
|
|
+ imageToken = imageGet.getImageToken();
|
|
|
+ } else {
|
|
|
+ String url = imageGetService.getUrlByCode(signature);
|
|
|
+ imageToken = uploadService.kuauiShouImageUpload(url, signature, oauthToken.getAccountId(), oauthToken.getAccessToken());
|
|
|
+ }
|
|
|
+ if (Check.isNull(imageToken)) {
|
|
|
+ resultMap.put("success", false);
|
|
|
+ resultMap.put("creativeName", data.get("creativeName"));
|
|
|
+ resultMap.put("message", "获取图片文件失败");
|
|
|
+ return resultMap;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ JSONArray tokenArr = new JSONArray();
|
|
|
+ //封面图片token
|
|
|
+ creativeJson.put("image_token", imageToken);
|
|
|
+ //便利贴单图图片创意token
|
|
|
+ tokenArr.add(imageToken);
|
|
|
+ creativeJson.put("image_tokens", tokenArr);
|
|
|
+ if (!Check.isNull(data.getString("clickTrackUrl"))) {
|
|
|
+ //第三方点击检测链接
|
|
|
+ creativeJson.put("click_track_url", data.getString("clickTrackUrl"));
|
|
|
+ //第三方开始播放监测链接
|
|
|
+ creativeJson.put("impression_url", data.getString("clickTrackUrl"));
|
|
|
+ }
|
|
|
+ //第三方有效播放监测链接
|
|
|
+ if (!Check.isNull(data.getString("adPhotoPlayedT3sUrl"))) {
|
|
|
+ creativeJson.put("ad_photo_played_t3s_url", data.getString("adPhotoPlayedT3sUrl"));
|
|
|
+ }
|
|
|
+ //第三方点击按钮监测链接
|
|
|
+ if (!Check.isNull(data.getString("actionbarClickUrl"))) {
|
|
|
+ creativeJson.put("actionbar_click_url", data.getString("actionbarClickUrl"));
|
|
|
+ }
|
|
|
+ //创意分类
|
|
|
+ if (!Check.isNull(data.getString("creativeCategory"))) {
|
|
|
+ creativeJson.put("creative_category", data.getString("creativeCategory"));
|
|
|
+ }
|
|
|
+ //创意标签
|
|
|
+ if (!Check.isNull(data.getString("creativeTag"))) {
|
|
|
+ creativeJson.put("creative_tag", data.getString("creative_tag"));
|
|
|
+ }
|
|
|
+ return kuaishouInterfaceService.creativeCreate(oauthToken.getAccessToken(), oauthToken.getAccountId(), creativeJson, 1);
|
|
|
+ }
|
|
|
+}
|