|
@@ -1,9 +1,22 @@
|
|
|
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.entity.*;
|
|
|
-import cn.com.ctop.job.kuaishou.data.mapper.*;
|
|
|
+import cn.com.ctop.job.kuaishou.data.entity.KuaiShouDailyAgent;
|
|
|
+import cn.com.ctop.job.kuaishou.data.entity.KuaishouAccountAdSceneReportDaily;
|
|
|
+import cn.com.ctop.job.kuaishou.data.entity.KuaishouAdUnitList;
|
|
|
+import cn.com.ctop.job.kuaishou.data.entity.KuaishouAdvertiserFundDailyFlows;
|
|
|
+import cn.com.ctop.job.kuaishou.data.entity.KuaishouAdvertiserFundGet;
|
|
|
+import cn.com.ctop.job.kuaishou.data.entity.KuaishouAudienceReportDaily;
|
|
|
+import cn.com.ctop.job.kuaishou.data.entity.KuaishouCampaignList;
|
|
|
+import cn.com.ctop.job.kuaishou.data.entity.OauthAgentToken;
|
|
|
+import cn.com.ctop.job.kuaishou.data.mapper.AdUnitReportMapper;
|
|
|
+import cn.com.ctop.job.kuaishou.data.mapper.KuaishouAccountAdSceneReportDailyMapper;
|
|
|
+import cn.com.ctop.job.kuaishou.data.mapper.KuaishouAdvertiserFundDailyFlowsMapper;
|
|
|
+import cn.com.ctop.job.kuaishou.data.mapper.KuaishouAudienceReportDailyMapper;
|
|
|
+import cn.com.ctop.job.kuaishou.data.mapper.OauthAgentTokenMapper;
|
|
|
+import cn.com.ctop.job.kuaishou.data.mapper.OauthTokenMapper;
|
|
|
import cn.com.ctop.job.kuaishou.data.service.IAdUnitReportService;
|
|
|
+import cn.com.ctop.job.kuaishou.data.service.IWarningOperationService;
|
|
|
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.HttpUtils;
|
|
@@ -19,6 +32,8 @@ import java.util.ArrayList;
|
|
|
import java.util.HashMap;
|
|
|
import java.util.List;
|
|
|
import java.util.Map;
|
|
|
+import java.util.concurrent.ExecutorService;
|
|
|
+import java.util.concurrent.Executors;
|
|
|
|
|
|
/**
|
|
|
* 快手 定时任务
|
|
@@ -52,6 +67,10 @@ public class AdUnitReportServiceImpl implements IAdUnitReportService {
|
|
|
private KuaishouAdvertiserFundDailyFlowsMapper fundDailyFlowsMapper;
|
|
|
|
|
|
|
|
|
+ @Resource
|
|
|
+ private IWarningOperationService warningOperationService;
|
|
|
+
|
|
|
+
|
|
|
/**
|
|
|
* 获取广告组信息
|
|
|
*
|
|
@@ -62,7 +81,7 @@ public class AdUnitReportServiceImpl implements IAdUnitReportService {
|
|
|
* @param page
|
|
|
*/
|
|
|
@Override
|
|
|
- public void getAdUnitReport(Long advertiserId, String accessToken, String startDate, String endDate, int page) {
|
|
|
+ public void getAdUnitReport(Long advertiserId, Long unitId, String accessToken, String startDate, String endDate, int page) {
|
|
|
JSONObject param = new JSONObject();
|
|
|
param.put("advertiser_id", advertiserId);
|
|
|
param.put("page_size", 500);
|
|
@@ -71,6 +90,9 @@ public class AdUnitReportServiceImpl implements IAdUnitReportService {
|
|
|
param.put("start_date", startDate);
|
|
|
param.put("end_date", endDate);
|
|
|
}
|
|
|
+ if (unitId != null) {
|
|
|
+ param.put("unit_id", unitId);
|
|
|
+ }
|
|
|
Map<String, String> headers = new HashMap<>();
|
|
|
headers.put("Access-Token", accessToken);
|
|
|
headers.put("Content-Type", "application/json");
|
|
@@ -114,13 +136,250 @@ public class AdUnitReportServiceImpl implements IAdUnitReportService {
|
|
|
toGet = false;
|
|
|
}
|
|
|
if (toGet) {
|
|
|
- getAdUnitReport(advertiserId, accessToken, startDate, endDate, page + 1);
|
|
|
+ getAdUnitReport(advertiserId, null, accessToken, startDate, endDate, page + 1);
|
|
|
} else {
|
|
|
log.info("快手广告组数据获取完成:accountId:{}", advertiserId);
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
+ @Override
|
|
|
+ public void checkGroupInfo(Long accountId, String accessToken, String startDate, String endDate, int page) {
|
|
|
+ JSONObject param = new JSONObject();
|
|
|
+ param.put("advertiser_id", accountId);
|
|
|
+ param.put("page_size", 500);
|
|
|
+ param.put("page", page);
|
|
|
+ if (startDate != null && endDate != null) {
|
|
|
+ param.put("start_date", startDate);
|
|
|
+ param.put("end_date", endDate);
|
|
|
+ }
|
|
|
+ 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.error("accountId:{} =》=》=》AdUnitReportServiceImpl.checkGroupInfo返回广告组数据为空", accountId);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ Integer code = resultJson.getInteger("code");
|
|
|
+ String message = resultJson.getString("message");
|
|
|
+ if (null == code || code != 0) {
|
|
|
+ log.error("accountId:{} =》=》=》AdUnitReportServiceImpl.checkGroupInfo\n返回广告组数据异常,message:{}", accountId, message);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ JSONArray details = resultJson.getJSONObject("data").getJSONArray("details");
|
|
|
+ if (null == details || details.size() <= 0) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ checkAndInsertGroup(accountId, details);
|
|
|
+ //是否有下一页
|
|
|
+ Boolean toGet = true;
|
|
|
+ if (details.size() < page) {
|
|
|
+ toGet = false;
|
|
|
+ }
|
|
|
+ if (toGet) {
|
|
|
+ getAdUnitReport(accountId, null, accessToken, startDate, endDate, page + 1);
|
|
|
+ } else {
|
|
|
+ log.info(" =》AdUnitReportServiceImpl.checkGroupInfo =》快手广告组数据获取完成:accountId:{}", accountId);
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ static ExecutorService executorBidTypeService = Executors.newFixedThreadPool(20);
|
|
|
+ static ExecutorService executorMaxBidService = Executors.newFixedThreadPool(5);
|
|
|
+
|
|
|
+ private void checkAndInsertGroup(Long accountId, JSONArray details) {
|
|
|
+ JSONObject project = adUnitReportMapper.getBidTypeAndMaxBid(accountId);
|
|
|
+ if (Check.isNull(project) || Check.isNull(details)) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 最高出价
|
|
|
+ Long maxBid = project.getLong("maxBid");
|
|
|
+
|
|
|
+ //优化目标集
|
|
|
+ List<Integer> bidList = null;
|
|
|
+ String bidTypeStr = project.getString("bidType");
|
|
|
+ if (!Check.isNull(bidTypeStr)) {
|
|
|
+ bidList = JSONArray.parseArray(bidTypeStr, Integer.class);
|
|
|
+ }
|
|
|
+
|
|
|
+ //转化目标map
|
|
|
+ Map<Integer, Long> ocpxMap = new HashMap<>();
|
|
|
+ String ocpxTypeStr = project.getString("ocpxActionType");
|
|
|
+ if (!Check.isNull(ocpxTypeStr)) {
|
|
|
+ JSONArray ocpxArr = JSONArray.parseArray(ocpxTypeStr);
|
|
|
+ for (int i = 0; i < ocpxArr.size(); i++) {
|
|
|
+ JSONObject obj = ocpxArr.getJSONObject(i);
|
|
|
+ ocpxMap.put(obj.getInteger("ocpxCode"), obj.getLong("maxValue"));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ //深度转化目标map
|
|
|
+ Map<Integer, Long> deepMap = new HashMap<>();
|
|
|
+ String deepTypeStr = project.getString("deepConversionType");
|
|
|
+ if (!Check.isNull(deepTypeStr)) {
|
|
|
+ JSONArray deepArr = JSONArray.parseArray(deepTypeStr);
|
|
|
+ for (int i = 0; i < deepArr.size(); i++) {
|
|
|
+ JSONObject obj = deepArr.getJSONObject(i);
|
|
|
+ ocpxMap.put(obj.getInteger("deepCode"), obj.getLong("deepValue"));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ List<KuaishouAdUnitList> ksAdUnitList = new ArrayList<>();
|
|
|
+ for (int i = 0; i < details.size(); i++) {
|
|
|
+ JSONObject detail = JSONObject.parseObject(details.get(i).toString());
|
|
|
+ if (!Check.isNull(detail)) {
|
|
|
+ //优化目标
|
|
|
+ Integer bidType = detail.getInteger("bid_type");
|
|
|
+ //优化出价(只有单击时,才有值)
|
|
|
+ Long bid = detail.getLong("bid");
|
|
|
+ //转化目标
|
|
|
+ Integer ocpxActionType = detail.getInteger("ocpx_action_type");
|
|
|
+ //转化目标出价
|
|
|
+ Long cpaBid = detail.getLong("cpa_bid");
|
|
|
+ //深度转化目标
|
|
|
+ Integer deepConversionType = detail.getInteger("deep_conversion_type");
|
|
|
+ //深度转化目标出价
|
|
|
+ Long deepConversionBid = detail.getLong("deep_conversion_bid");
|
|
|
+ //单日预算
|
|
|
+ Long dayBudget = detail.getLong("day_budget");
|
|
|
+ //组ID
|
|
|
+ Long unitId = detail.getLong("unit_id");
|
|
|
+ //组名称
|
|
|
+ String unitName = detail.getString("unit_name");
|
|
|
+ //状态
|
|
|
+ Integer status = detail.getInteger("status");
|
|
|
+ //投放状态
|
|
|
+ Integer putStatus = detail.getInteger("put_status");
|
|
|
+ if (putStatus == 1 && status != 15) { // 组状态为 投放中的 and 广告组状态为非暂停
|
|
|
+ Boolean typeFalg = true;
|
|
|
+ Boolean bidFalg = true;
|
|
|
+
|
|
|
+ //优化目标
|
|
|
+ if (!bidList.isEmpty()) {
|
|
|
+ if (!bidList.contains(bidType)) {
|
|
|
+ //项目不包含该优化目标,则关停
|
|
|
+ typeFalg = false;
|
|
|
+ } else if (bidType == 2 && bid > maxBid) {
|
|
|
+ //若优化目标为2点击数,并且广告组出价大于项目设置最大出价,则关停
|
|
|
+ bidFalg = false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ //转化目标
|
|
|
+ if (!Check.isNull(ocpxActionType) && ocpxActionType != 0) {
|
|
|
+ //!=0是设置过转化目标
|
|
|
+ if (!Check.isNullMap(ocpxMap)) {
|
|
|
+ Long ocpxBid = ocpxMap.get(ocpxActionType);
|
|
|
+ if (Check.isNull(ocpxBid)) {
|
|
|
+ if (ocpxActionType == 2 && dayBudget != 0 && dayBudget <= 500 * 1000) {
|
|
|
+ // 转化目标为2行为数,并且预算小于等于500且不是不限,则允许启动
|
|
|
+ typeFalg = true;
|
|
|
+ }else{
|
|
|
+ //通过key未获取值,说明不包含该目标,进行关停
|
|
|
+ typeFalg = false;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ if (cpaBid > ocpxBid) {
|
|
|
+ //组转化出价 大于 项目设置最大转化出价,则关停
|
|
|
+ bidFalg = false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }else if (ocpxActionType == 2 && (dayBudget == 0 || dayBudget > 500 * 1000)) {
|
|
|
+ // 转化目标为2行为数,并且预算大于500 或者不限,则关停
|
|
|
+ typeFalg = false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ //转化目标
|
|
|
+ if (!Check.isNull(deepConversionType) && deepConversionType != 0 && !deepMap.isEmpty()) {
|
|
|
+ Long deepBid = deepMap.get(deepConversionType);
|
|
|
+ if (Check.isNull(deepBid)) {
|
|
|
+ //通过key未获取值,说明不包含该目标,进行关停
|
|
|
+ typeFalg = false;
|
|
|
+ } else {
|
|
|
+ if (deepConversionBid > deepBid) {
|
|
|
+ //组深度转化出价 大于 项目设置最大转化出价,则关停
|
|
|
+ bidFalg = false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!typeFalg) { // 出价方式设置非法
|
|
|
+ executorBidTypeService.submit(new Runnable() {
|
|
|
+ @Override
|
|
|
+ public void run() {
|
|
|
+ warningOperationService.kuaiShouWarningOperation(project.getLong("projectId"), project.getString("projectName"), accountId, unitId, unitName);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+ if (!bidFalg) {
|
|
|
+ executorMaxBidService.submit(new Runnable() {
|
|
|
+ @Override
|
|
|
+ public void run() {
|
|
|
+ warningOperationService.kuaiShouBidWarningOperation(project.getLong("projectId"), project.getString("projectName"), accountId, unitId, unitName);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+ }
|
|
|
+ for (Object deta : details) {
|
|
|
+ JSONObject unitDetail = (JSONObject) deta;
|
|
|
+ unitDetail.put("advertiser_id", accountId);
|
|
|
+ KuaishouAdUnitList ksAdunit = KuaishouAdUnitList.getAdUnitListInfo(unitDetail);
|
|
|
+ ksAdUnitList.add(ksAdunit);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (!Check.isNull(ksAdUnitList)) {
|
|
|
+ adUnitReportMapper.replaceBatchKsAdUnit(ksAdUnitList);
|
|
|
+ log.info("组数据添加成功,accountId:{},条数:{}", accountId, ksAdUnitList.size());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 修改广告组状态
|
|
|
+ * putStatus 1-投放、2-暂停、3-删除,传其他数字非法
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ public void updateUnitStatus(String token, Long acccountId, Long unitId, int putStatus) {
|
|
|
+ try {
|
|
|
+ String url = postUrl + KuaishouConstant.UPDATE_UNIT_STATUS;
|
|
|
+ Map<String, String> header = new HashMap<>();
|
|
|
+ header.put("Access-Token", token);
|
|
|
+ header.put("Content-Type", "application/json");
|
|
|
+ JSONObject params = new JSONObject();
|
|
|
+ params.put("advertiser_id", acccountId);
|
|
|
+ params.put("unit_id", unitId);
|
|
|
+ params.put("put_status", putStatus);
|
|
|
+ String result = HttpUtils.httpPostRequest(url, params, header);
|
|
|
+ JSONObject resultJson = JSONObject.parseObject(result);
|
|
|
+ if (!Check.isNull(resultJson)) {
|
|
|
+ Integer code = resultJson.getInteger("code");
|
|
|
+ if (code == 0) {
|
|
|
+ if (putStatus == 3) {
|
|
|
+ Map<String, Object> deleteMap = new HashMap<>();
|
|
|
+ deleteMap.put("accountId", acccountId);
|
|
|
+ deleteMap.put("unitId", unitId);
|
|
|
+ adUnitReportMapper.deleteByMap(deleteMap);
|
|
|
+ } else {
|
|
|
+ getAdUnitReport(acccountId, null, token, null, null, 1);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ log.error("=》=》=》AdUnitReportServiceImpl.updateUnitStatus修改广告组状态失败,advertiserId:{},unitId:{},返回信息:{}", acccountId, unitId, resultJson);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ log.error("修改广告组状态返回结果为空,advertiserId:{},unitId:{}", acccountId, unitId);
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("修改广告组状态异常,advertiserId:{},unitId:{}", acccountId, unitId);
|
|
|
+ e.printStackTrace();
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* 快手广告计划信息
|
|
|
*
|