|
@@ -2,25 +2,35 @@ package cn.com.ctop.job.kuaishou.data.service.impl;
|
|
|
|
|
|
import cn.com.ctop.job.kuaishou.data.constant.KuaishouConstant;
|
|
import cn.com.ctop.job.kuaishou.data.constant.KuaishouConstant;
|
|
import cn.com.ctop.job.kuaishou.data.entity.CompassBindAdvertisers;
|
|
import cn.com.ctop.job.kuaishou.data.entity.CompassBindAdvertisers;
|
|
|
|
+import cn.com.ctop.job.kuaishou.data.entity.KuaishouAdUnitList;
|
|
import cn.com.ctop.job.kuaishou.data.entity.KuaishouCampaignReportDaily;
|
|
import cn.com.ctop.job.kuaishou.data.entity.KuaishouCampaignReportDaily;
|
|
import cn.com.ctop.job.kuaishou.data.entity.KuaishouMaterialVideoReportDaily;
|
|
import cn.com.ctop.job.kuaishou.data.entity.KuaishouMaterialVideoReportDaily;
|
|
import cn.com.ctop.job.kuaishou.data.entity.KuaishouUnitReportDaily;
|
|
import cn.com.ctop.job.kuaishou.data.entity.KuaishouUnitReportDaily;
|
|
|
|
+import cn.com.ctop.job.kuaishou.data.entity.KuaishouVideoList;
|
|
|
|
+import cn.com.ctop.job.kuaishou.data.enums.MaterialEnum;
|
|
import cn.com.ctop.job.kuaishou.data.mapper.CompassBindAdvertisersMapper;
|
|
import cn.com.ctop.job.kuaishou.data.mapper.CompassBindAdvertisersMapper;
|
|
import cn.com.ctop.job.kuaishou.data.service.CompassBindAdvertisersService;
|
|
import cn.com.ctop.job.kuaishou.data.service.CompassBindAdvertisersService;
|
|
|
|
+import cn.com.ctop.job.kuaishou.data.service.IAdUnitReportService;
|
|
import cn.com.ctop.job.kuaishou.data.utils.Check;
|
|
import cn.com.ctop.job.kuaishou.data.utils.Check;
|
|
import cn.com.ctop.job.kuaishou.data.utils.DateUtils;
|
|
import cn.com.ctop.job.kuaishou.data.utils.DateUtils;
|
|
import cn.com.ctop.job.kuaishou.data.utils.HttpUtils;
|
|
import cn.com.ctop.job.kuaishou.data.utils.HttpUtils;
|
|
|
|
+import cn.com.ctop.job.kuaishou.utils.RedisUtil;
|
|
import com.alibaba.fastjson.JSONArray;
|
|
import com.alibaba.fastjson.JSONArray;
|
|
import com.alibaba.fastjson.JSONObject;
|
|
import com.alibaba.fastjson.JSONObject;
|
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|
import lombok.extern.slf4j.Slf4j;
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
import org.springframework.beans.factory.annotation.Value;
|
|
import org.springframework.beans.factory.annotation.Value;
|
|
import org.springframework.stereotype.Service;
|
|
import org.springframework.stereotype.Service;
|
|
|
|
|
|
|
|
+import java.math.BigDecimal;
|
|
|
|
+import java.math.RoundingMode;
|
|
import java.util.ArrayList;
|
|
import java.util.ArrayList;
|
|
|
|
+import java.util.Arrays;
|
|
import java.util.HashMap;
|
|
import java.util.HashMap;
|
|
import java.util.List;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
import java.util.Map;
|
|
|
|
+import java.util.concurrent.TimeUnit;
|
|
|
|
|
|
@Slf4j
|
|
@Slf4j
|
|
@Service
|
|
@Service
|
|
@@ -29,6 +39,8 @@ public class CompassBindAdvertisersServiceImpl extends ServiceImpl<CompassBindAd
|
|
@Value("${api.kuaishou.postUrl}")
|
|
@Value("${api.kuaishou.postUrl}")
|
|
private String postUrl;
|
|
private String postUrl;
|
|
|
|
|
|
|
|
+ @Autowired
|
|
|
|
+ private IAdUnitReportService unitReportService;
|
|
|
|
|
|
@Override
|
|
@Override
|
|
public void openapiGwUcV1Advertisers(Long advertiserId, String token) {
|
|
public void openapiGwUcV1Advertisers(Long advertiserId, String token) {
|
|
@@ -593,4 +605,210 @@ public class CompassBindAdvertisersServiceImpl extends ServiceImpl<CompassBindAd
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ @Override
|
|
|
|
+ public void checkCompassAdvertisersUnit(Long advertiserId, String accessToken, String startDate, String endDate, int page) {
|
|
|
|
+ String url = postUrl + KuaishouConstant.UNIT_REPORT;
|
|
|
|
+ Map<String, String> headers = new HashMap<>();
|
|
|
|
+ headers.put("Access-Token", accessToken);
|
|
|
|
+ Map<String, Object> param = new HashMap<>();
|
|
|
|
+ param.put("start_date", startDate);
|
|
|
|
+ param.put("end_date", endDate);
|
|
|
|
+ param.put("advertiser_id", advertiserId);
|
|
|
|
+ param.put("temporal_granularity", "DAILY");
|
|
|
|
+ Integer page_size = 2000;
|
|
|
|
+ param.put("page_size", page_size);
|
|
|
|
+ param.put("page", page);
|
|
|
|
+ String result = HttpUtils.httpPostRequest(url, param, headers);
|
|
|
|
+ JSONObject resultJson = JSONObject.parseObject(result);
|
|
|
|
+ Integer code = resultJson.getInteger("code");
|
|
|
|
+ String message = resultJson.getString("message");
|
|
|
|
+ if (null == code || code != 0) {
|
|
|
|
+ log.error("查询快手[罗盘广告主]广告组异常:{},accountId:{}", message, advertiserId);
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ JSONArray details = resultJson.getJSONObject("data").getJSONArray("details");
|
|
|
|
+ if (null == details || details.size() <= 0) {
|
|
|
|
+// log.error("[罗盘广告主]快手组详情为空,accountId:{}", advertiserId);
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ Boolean toGet = true;
|
|
|
|
+ if (details.size() < page_size) {
|
|
|
|
+ toGet = false;
|
|
|
|
+ }
|
|
|
|
+ for (int i = 0; i < details.size(); i++) {
|
|
|
|
+ JSONObject returnJson = details.getJSONObject(i);
|
|
|
|
+ BigDecimal charge = returnJson.getBigDecimal("charge").setScale(2, RoundingMode.HALF_UP);
|
|
|
|
+ Long unitId = returnJson.getLong("unit_id");
|
|
|
|
+ BigDecimal payPurchaseAmount = returnJson.getBigDecimal("event_pay_purchase_amount").setScale(2, RoundingMode.HALF_UP);
|
|
|
|
+ if (charge.signum() != 0) {
|
|
|
|
+ //付费金额/消耗
|
|
|
|
+ BigDecimal roi = payPurchaseAmount.divide(charge, 2, RoundingMode.HALF_UP);
|
|
|
|
+ //1、消耗大于30,并且roi(付费金额/消耗)低于0.8的【自动关停】
|
|
|
|
+ if (charge.compareTo(new BigDecimal("30")) > 0 && roi.compareTo(new BigDecimal("0.8")) < 0) {
|
|
|
|
+ unitReportService.updateUnitStatus(accessToken, advertiserId, unitId, 2);
|
|
|
|
+ String text = "消耗:" + charge + ",大于30;并且roi(付费金额:" + payPurchaseAmount + " /消耗):" + roi + ",低于0.8,自动关停!!!";
|
|
|
|
+ insertRecord(advertiserId, unitId, "关停", text);
|
|
|
|
+ }
|
|
|
|
+ //2、roi 大于1的广告组【自动开启】
|
|
|
|
+ if (roi.compareTo(new BigDecimal("1.0")) > 0) {
|
|
|
|
+ Integer unitStatus = getAdUnitStatus(advertiserId, unitId, accessToken);
|
|
|
|
+ if (unitStatus == 2) {
|
|
|
|
+ //1:投放中;2:暂停 3:删除
|
|
|
|
+ unitReportService.updateUnitStatus(accessToken, advertiserId, unitId, 1);
|
|
|
|
+ insertRecord(advertiserId, unitId, "开启", "roi:" + roi + "大于1");
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+ if (toGet) {
|
|
|
|
+ getCompassAdvertisersUnitReportDaily(advertiserId, accessToken, startDate, endDate, page + 1);
|
|
|
|
+ } else {
|
|
|
|
+ log.info("罗盘广告主-广告组校验完成:accountId:{}", advertiserId);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private void insertRecord(Long advertiserId, Long unitId, String type, String text) {
|
|
|
|
+ StringBuilder alarmDetail = new StringBuilder();
|
|
|
|
+ alarmDetail.append("账户ID:").append(advertiserId)
|
|
|
|
+ .append("下的广告组ID:").append(unitId).append(",")
|
|
|
|
+ .append(type).append("原因:").append(text);
|
|
|
|
+ baseMapper.insertRecord(advertiserId, unitId, alarmDetail.toString());
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ private Integer getAdUnitStatus(Long advertiserId, Long unitId, String accessToken) {
|
|
|
|
+ JSONObject param = new JSONObject();
|
|
|
|
+ param.put("advertiser_id", advertiserId);
|
|
|
|
+ param.put("unit_id", unitId);
|
|
|
|
+ Map<String, String> headers = new HashMap<>();
|
|
|
|
+ headers.put("Access-Token", accessToken);
|
|
|
|
+ headers.put("Content-Type", "application/json");
|
|
|
|
+
|
|
|
|
+ String result = HttpUtils.kuaiShouhttpPostRequest(postUrl + KuaishouConstant.AD_UNIT_LIST, param.toJSONString(), headers);
|
|
|
|
+ JSONObject resultJson = JSONObject.parseObject(result);
|
|
|
|
+ if (Check.isNull(resultJson)) {
|
|
|
|
+ log.info("accountId:{} 广告组数据信息为空!", advertiserId);
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+ Integer code = resultJson.getInteger("code");
|
|
|
|
+ String message = resultJson.getString("message");
|
|
|
|
+ if (null == code || code != 0) {
|
|
|
|
+ log.error("查询广告组数据异常:{},accountId:{}", message, advertiserId);
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+ JSONArray details = resultJson.getJSONObject("data").getJSONArray("details");
|
|
|
|
+ if (null == details || details.size() <= 0) {
|
|
|
|
+ log.info("快手广告组数据为空=》accountId:{}", advertiserId);
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+ //投放状态(操作结果) 1:投放中;2:暂停 3:删除
|
|
|
|
+ return details.getJSONObject(0).getInteger("put_status");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ @Autowired
|
|
|
|
+ private RedisUtil redisUtil;
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public void getVideoList(Long advertiserId, String token, String startDate, String endDate, int page) {
|
|
|
|
+ log.info("短剧-开始获取所有视频信息 accountID:{},page:{}", advertiserId, page);
|
|
|
|
+ List<Object> adAccountList = redisUtil.getList("com_kuaiShou_allVideo_list", null);
|
|
|
|
+ String url = postUrl + KuaishouConstant.VIDEO_LIST;
|
|
|
|
+ Map<String, String> headers = new HashMap<>();
|
|
|
|
+ headers.put("Access-Token", token);
|
|
|
|
+ Map<String, Object> param = new HashMap<>();
|
|
|
|
+ param.put("advertiser_id", advertiserId);
|
|
|
|
+ Integer page_size = 500;
|
|
|
|
+ param.put("page_size", page_size);
|
|
|
|
+ param.put("page", page);
|
|
|
|
+ if (!Check.isNull(startDate) && !Check.isNull(endDate)) {
|
|
|
|
+ param.put("start_date", startDate);
|
|
|
|
+ param.put("end_date", endDate);
|
|
|
|
+ }
|
|
|
|
+ String result = HttpUtils.httpPostRequest(url, param, headers);
|
|
|
|
+ JSONObject resultJson = JSONObject.parseObject(result);
|
|
|
|
+ if (Check.isNull(resultJson)) {
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ Integer code = resultJson.getInteger("code");
|
|
|
|
+ String message = resultJson.getString("message");
|
|
|
|
+ if (null == code || code != 0) {
|
|
|
|
+ log.error("短剧-获取快手视频列表数据异常:{},accountId:{}", message, advertiserId);
|
|
|
|
+
|
|
|
|
+ //请求过于频繁
|
|
|
|
+ if (400001 == code) {
|
|
|
|
+ log.info("短剧-定时任务-->>allVideoList<<<<----获取所有快手视频请求频繁,code:{},准备重试,accountId:{},错误消息:{}", code, advertiserId, message);
|
|
|
|
+ //添加重试
|
|
|
|
+ if (Check.isNull(adAccountList)) {
|
|
|
|
+ redisUtil.add("com_kuaiShou_allVideo_list", Arrays.asList(advertiserId), 1, TimeUnit.HOURS);
|
|
|
|
+ } else {
|
|
|
|
+ adAccountList.add(advertiserId);
|
|
|
|
+ redisUtil.add("com_kuaiShou_allVideo_list", adAccountList, 1, TimeUnit.HOURS);
|
|
|
|
+ }
|
|
|
|
+ } else {
|
|
|
|
+ if (adAccountList.contains(advertiserId)) {
|
|
|
|
+ adAccountList.remove(advertiserId);
|
|
|
|
+ redisUtil.add("com_kuaiShou_allVideo_list", advertiserId, 1, TimeUnit.HOURS);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ JSONArray details = resultJson.getJSONObject("data").getJSONArray("details");
|
|
|
|
+ if (null == details || details.size() <= 0) {
|
|
|
|
+ log.info("快手视频列表信息为空=》accountId:{}", advertiserId);
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ Boolean toGet = true;
|
|
|
|
+ if (details.size() < page_size) {
|
|
|
|
+ toGet = false;
|
|
|
|
+ }
|
|
|
|
+ List<KuaishouVideoList> videoGetList = new ArrayList<>();
|
|
|
|
+ for (int i = 0; i < details.size(); i++) {
|
|
|
|
+ JSONObject detailJson = details.getJSONObject(i);
|
|
|
|
+ if (Check.isNull(detailJson)) {
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+ KuaishouVideoList videoList = new KuaishouVideoList();
|
|
|
|
+ String photo_id = detailJson.getString("photo_id");
|
|
|
|
+ videoList.setAccountId(advertiserId);
|
|
|
|
+ videoList.setCoverUrl(detailJson.getString("cover_url"));
|
|
|
|
+ videoList.setPhotoId(photo_id);
|
|
|
|
+ videoList.setPhotoName(detailJson.getString("photo_name"));
|
|
|
|
+ videoList.setStatDate(detailJson.getDate("upload_time"));
|
|
|
|
+ String signature = detailJson.getString("signature");
|
|
|
|
+ videoList.setSignature(signature);
|
|
|
|
+ Integer source = detailJson.getInteger("source");
|
|
|
|
+ if (source == 2) {
|
|
|
|
+ videoList.setChannelType(1);
|
|
|
|
+ } else {
|
|
|
|
+ videoList.setChannelType(0);
|
|
|
|
+ }
|
|
|
|
+ Integer new_status = detailJson.getInteger("new_status");
|
|
|
|
+ if (new_status == 1) {
|
|
|
|
+ videoList.setStatus(0);
|
|
|
|
+ } else {
|
|
|
|
+ videoList.setStatus(1);
|
|
|
|
+ }
|
|
|
|
+ videoList.setUrl(detailJson.getString("url"));
|
|
|
|
+ Integer width = detailJson.getInteger("width");
|
|
|
|
+ videoList.setWidth(width);
|
|
|
|
+ Integer height = detailJson.getInteger("height");
|
|
|
|
+ videoList.setHeight(height);
|
|
|
|
+ Integer type = MaterialEnum.getTypeBySize(width, height);
|
|
|
|
+ if (!Check.isNull(type)) {
|
|
|
|
+ videoList.setMaterialType(type);
|
|
|
|
+ }
|
|
|
|
+ videoGetList.add(videoList);
|
|
|
|
+ }
|
|
|
|
+ if (!Check.isNull(videoGetList)) {
|
|
|
|
+ baseMapper.replaceBatchVideoList(videoGetList);
|
|
|
|
+ }
|
|
|
|
+ if (toGet) {
|
|
|
|
+ getVideoList(advertiserId, token, startDate, endDate, page + 1);
|
|
|
|
+ } else {
|
|
|
|
+ log.info("短剧-视频列表数据获取完成:accountId:{}", advertiserId);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
}
|
|
}
|