|
@@ -43,99 +43,59 @@ public class BytedanceProjectServiceImpl implements IBytedanceProjectService {
|
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
@Override
|
|
|
- public void updProjectStatus(String token, Long accountId, Long projectId, String disable) {
|
|
|
|
|
- JSONObject params = new JSONObject();
|
|
|
|
|
- params.put("advertiser_id", accountId);
|
|
|
|
|
- JSONObject data = new JSONObject();
|
|
|
|
|
- data.put("project_id", projectId);
|
|
|
|
|
- data.put("opt_status", disable);//ENABLE 启用项目、 DISABLE 暂停项目
|
|
|
|
|
- List<JSONObject> list = new ArrayList<>();
|
|
|
|
|
- list.add(data);
|
|
|
|
|
- params.put("data", list);
|
|
|
|
|
- String url = bytedanceApiUrl + "/v3.0/project/status/update/";
|
|
|
|
|
- JSONObject object = HttpUtils.bytedancePostRequest(token, url, params);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
- @Override
|
|
|
|
|
- public void checkAdvertiserProject(Long accountId, String accessToken, List<Long> ids, int page) {
|
|
|
|
|
- try {
|
|
|
|
|
- // 请求地址
|
|
|
|
|
- String url = bytedanceApiUrl + "/v3.0/project/list/";
|
|
|
|
|
- JSONObject param = new JSONObject();
|
|
|
|
|
- param.put("advertiser_id", accountId);
|
|
|
|
|
- param.put("page", page);
|
|
|
|
|
- param.put("page_size", 100);
|
|
|
|
|
- JSONObject filtering = new JSONObject();
|
|
|
|
|
- if (!Check.isNull(ids)) {
|
|
|
|
|
- filtering.put("ids", new ArrayList<>(ids));
|
|
|
|
|
- }
|
|
|
|
|
- param.put("filtering", filtering);
|
|
|
|
|
- JSONObject resultObject = HttpUtils.bytedanceGetRequest(accessToken, url, param);
|
|
|
|
|
- if (Check.isNull(resultObject)) {
|
|
|
|
|
- log.error("checkAdvertiserProject异常==》accountId:{},结果为null", accountId);
|
|
|
|
|
- return;
|
|
|
|
|
- }
|
|
|
|
|
- Integer code = resultObject.getInteger("code");
|
|
|
|
|
- if (null == code || !code.equals(0)) {
|
|
|
|
|
- log.error("checkAdvertiserProject接口==》accountId:{},message:{},code{}", accountId, resultObject.getString("message"), code);
|
|
|
|
|
- return;
|
|
|
|
|
- }
|
|
|
|
|
- JSONArray data = resultObject.getJSONObject("data").getJSONArray("list");
|
|
|
|
|
- if (null == data || data.isEmpty()) {
|
|
|
|
|
- log.info("checkAdvertiserProject数据为空==》accountId:{},message:{},code:{}", accountId, resultObject.getString("message"), code);
|
|
|
|
|
- return;
|
|
|
|
|
- }
|
|
|
|
|
- for (int i = 0; i < data.size(); i++) {
|
|
|
|
|
- JSONObject dataObject = data.getJSONObject(i);
|
|
|
|
|
- checkProjectBidType(accessToken, dataObject);
|
|
|
|
|
-
|
|
|
|
|
- }
|
|
|
|
|
- int totalPage = resultObject.getJSONObject("data").getJSONObject("page_info").getInteger("total_page");
|
|
|
|
|
- if (page <= totalPage) {
|
|
|
|
|
- checkAdvertiserProject(accountId, accessToken, ids, page + 1);
|
|
|
|
|
- }
|
|
|
|
|
- } catch (Exception e) {
|
|
|
|
|
- e.printStackTrace();
|
|
|
|
|
|
|
+ public void getPromotionList(Long accountId, String token, List<Long> ids, Map<Long, JSONObject> projectMap, int page) {
|
|
|
|
|
+ String url = bytedanceApiUrl + "/v3.0/promotion/list/";
|
|
|
|
|
+ JSONObject param = new JSONObject();
|
|
|
|
|
+ param.put("advertiser_id", accountId);
|
|
|
|
|
+ param.put("page", page);
|
|
|
|
|
+ param.put("page_size", 20);
|
|
|
|
|
+ JSONObject filtering = new JSONObject();
|
|
|
|
|
+ filtering.put("ids", ids);
|
|
|
|
|
+ param.put("filtering", filtering);
|
|
|
|
|
+ JSONObject resultObject = HttpUtils.bytedanceGetRequest(token, url, param);
|
|
|
|
|
+ if (Check.isNull(resultObject)) {
|
|
|
|
|
+ log.error("获取广告列表异常==》accountId:{},调用结果为null", accountId);
|
|
|
|
|
+ return;
|
|
|
}
|
|
}
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- @Override
|
|
|
|
|
- public String getTokenByAccountId(Long advertiserId) {
|
|
|
|
|
- return projectListMapper.getTokenByAccountId(advertiserId);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
- //检查过滤账户和项目 flag为1 过滤掉
|
|
|
|
|
- private boolean checkThreeRejections(Long accountId) {
|
|
|
|
|
- Long projectId = projectListMapper.getProjectId(accountId);
|
|
|
|
|
- List<Long> ids = projectListMapper.getSpecialProject();
|
|
|
|
|
- if (ids.contains(accountId) || ids.contains(projectId)) {
|
|
|
|
|
- //过滤标记 都不发送
|
|
|
|
|
- return false;
|
|
|
|
|
|
|
+ Integer code = resultObject.getInteger("code");
|
|
|
|
|
+ if (null == code || !code.equals(0)) {
|
|
|
|
|
+ log.error("获取广告列表接口异常==》accountId:{},message:{},code{}", accountId, resultObject.getString("message"), code);
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ JSONArray data = resultObject.getJSONObject("data").getJSONArray("list");
|
|
|
|
|
+ if (null == data || data.isEmpty()) {
|
|
|
|
|
+ log.info("获取广告列表数据为空==》accountId:{},message:{},code{}", accountId, resultObject.getString("message"), code);
|
|
|
|
|
+ return;
|
|
|
}
|
|
}
|
|
|
- return true;
|
|
|
|
|
- }
|
|
|
|
|
|
|
|
|
|
- //检查广告ID 发送2次以后拒绝发送
|
|
|
|
|
- private boolean checkAdSendCounts(Long accountId, Long adId) {
|
|
|
|
|
- List<Long> adIds = projectListMapper.getBytedanceRefusalSend(accountId);
|
|
|
|
|
- if (!Check.isNull(adIds)) {
|
|
|
|
|
- return !adIds.contains(adId);
|
|
|
|
|
|
|
+ Map<Long, Long> projectIdMap = new HashMap<>();
|
|
|
|
|
+ List<JSONObject> promotionList = new ArrayList<>();
|
|
|
|
|
+ for (int i = 0; i < data.size(); i++) {
|
|
|
|
|
+ JSONObject dataObject = data.getJSONObject(i);
|
|
|
|
|
+ JSONObject promotionJson = new JSONObject();
|
|
|
|
|
+ Long projectId = dataObject.getLong("project_id");
|
|
|
|
|
+ promotionJson.put("projectId", projectId);
|
|
|
|
|
+ BigDecimal deepCpabid = dataObject.getBigDecimal("deep_cpabid");
|
|
|
|
|
+ promotionJson.put("deepCpabid", deepCpabid);
|
|
|
|
|
+ BigDecimal cpaBid = dataObject.getBigDecimal("cpa_bid");
|
|
|
|
|
+ promotionJson.put("cpaBid", cpaBid);
|
|
|
|
|
+ BigDecimal bid = dataObject.getBigDecimal("bid");
|
|
|
|
|
+ promotionJson.put("bid", bid);
|
|
|
|
|
+ promotionList.add(promotionJson);
|
|
|
|
|
+ projectIdMap.put(projectId, projectId);
|
|
|
}
|
|
}
|
|
|
- return true;
|
|
|
|
|
|
|
+ List<Long> projectIds = new ArrayList<>();
|
|
|
|
|
+ for (Map.Entry<Long, Long> entry : projectIdMap.entrySet()) {
|
|
|
|
|
+ projectIds.add(entry.getValue());
|
|
|
|
|
+ }
|
|
|
|
|
+ Map<Long, JSONObject> projectInfo = getProjectInfo(accountId, token, projectIds, 1);
|
|
|
|
|
+ this.check(accountId, token, promotionList, projectInfo);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
- /**
|
|
|
|
|
- * 校验转化出价,并预警
|
|
|
|
|
- */
|
|
|
|
|
- public void checkProjectBidType(String accessToken, JSONObject detail) {
|
|
|
|
|
- Long accountId = detail.getLong("advertiser_id");
|
|
|
|
|
- Long projectId = detail.getLong("project_id");
|
|
|
|
|
- //项目ID
|
|
|
|
|
|
|
+ private void check(Long accountId, String token, List<JSONObject> promotionList, Map<Long, JSONObject> projectInfo) {
|
|
|
JSONObject json = projectListMapper.getProjectByAccountId(accountId);
|
|
JSONObject json = projectListMapper.getProjectByAccountId(accountId);
|
|
|
- if (Check.isNull(json) || Check.isNull(detail)) {
|
|
|
|
|
|
|
+ if (Check.isNull(promotionList) || Check.isNull(projectInfo)) {
|
|
|
return;
|
|
return;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -177,213 +137,208 @@ public class BytedanceProjectServiceImpl implements IBytedanceProjectService {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- //操作状态
|
|
|
|
|
- String optStatus = detail.getString("opt_status");// ENABLE 启用项目、 DISABLE 暂停项目
|
|
|
|
|
- if ("ENABLE".equals(optStatus)) {
|
|
|
|
|
- //转化目标出价
|
|
|
|
|
- String cpaBid = detail.getJSONObject("delivery_setting").getString("cpa_bid");
|
|
|
|
|
- //深度转化目标出价
|
|
|
|
|
- String deepConversionBid = detail.getJSONObject("delivery_setting").getString("deep_cpabid");
|
|
|
|
|
-
|
|
|
|
|
- String pricing = detail.getString("pricing");
|
|
|
|
|
- List<JSONObject> advertiserList = new ArrayList<>();
|
|
|
|
|
- if (Check.isNull(cpaBid) && Check.isNull(deepConversionBid)) {
|
|
|
|
|
- this.checkAdvertiserList(accountId, accessToken, projectId, 1, advertiserList);
|
|
|
|
|
-
|
|
|
|
|
- if (advertiserList.size() > 0) {
|
|
|
|
|
- for (JSONObject adObj : advertiserList) {
|
|
|
|
|
- String statusFirst = adObj.getString("status_first");
|
|
|
|
|
- //一级状态:PROMOTION_STATUS_ENABLE 投放中
|
|
|
|
|
- if ("PROMOTION_STATUS_ENABLE".equals(statusFirst)) {
|
|
|
|
|
- if (!checkAdSendCounts(detail.getLong("advertiser_id"), adObj.getLong("promotion_id"))) {
|
|
|
|
|
- continue;
|
|
|
|
|
- }
|
|
|
|
|
- String bid = adObj.getString("cpa_bid");
|
|
|
|
|
- if ("PRICING_CPM".equals(pricing) || "PRICING_CPC".equals(pricing)) {
|
|
|
|
|
- bid = adObj.getString("bid");
|
|
|
|
|
- }
|
|
|
|
|
- checkLogic(accessToken, "ad", detail, ocpxMap, textMap, deepMap, bid,
|
|
|
|
|
- adObj.getString("deep_cpabid"), json.getString("projectName"), adObj);
|
|
|
|
|
- } else if ("PROMOTION_STATUS_DISABLE".equals(statusFirst)) {
|
|
|
|
|
- String statusSecond = adObj.getString("status_second");
|
|
|
|
|
- //除了广告二级状态 已暂停的状态,其他状态都需要预警
|
|
|
|
|
- if (!"DISABLE_BY_QUOTA".equals(statusSecond)) {
|
|
|
|
|
- if (!checkAdSendCounts(detail.getLong("advertiser_id"), adObj.getLong("promotion_id"))) {
|
|
|
|
|
- continue;
|
|
|
|
|
- }
|
|
|
|
|
- String bid = adObj.getString("cpa_bid");
|
|
|
|
|
- if ("PRICING_CPM".equals(pricing)) {
|
|
|
|
|
- bid = adObj.getString("bid");
|
|
|
|
|
- }
|
|
|
|
|
- checkLogic(accessToken, "ad", detail, ocpxMap, textMap, deepMap, bid,
|
|
|
|
|
- adObj.getString("deep_cpabid"), json.getString("projectName"), adObj);
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- } else {
|
|
|
|
|
- checkLogic(accessToken, "project", detail, ocpxMap, textMap, deepMap, cpaBid,
|
|
|
|
|
- deepConversionBid, json.getString("projectName"), new JSONObject());
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- private void checkAdvertiserList(Long accountId, String token, Long projectId, int page, List<JSONObject> advertiserList) {
|
|
|
|
|
- // 请求地址
|
|
|
|
|
- String url = bytedanceApiUrl + "/v3.0/promotion/list/";
|
|
|
|
|
- JSONObject param = new JSONObject();
|
|
|
|
|
- param.put("advertiser_id", accountId);
|
|
|
|
|
- param.put("page", page);
|
|
|
|
|
- param.put("page_size", 20);
|
|
|
|
|
- JSONObject filtering = new JSONObject();
|
|
|
|
|
- // filtering.put("promotion_modify_time", date);
|
|
|
|
|
- filtering.put("project_id", projectId);
|
|
|
|
|
- param.put("filtering", filtering);
|
|
|
|
|
- JSONObject resultObject = HttpUtils.bytedanceGetRequest(token, url, param);
|
|
|
|
|
- if (Check.isNull(resultObject)) {
|
|
|
|
|
- log.error("获取广告列表异常==》accountId:{},调用结果为null", accountId);
|
|
|
|
|
- return;
|
|
|
|
|
- }
|
|
|
|
|
- Integer code = resultObject.getInteger("code");
|
|
|
|
|
- if (null == code || !code.equals(0)) {
|
|
|
|
|
- log.error("获取广告列表接口异常==》accountId:{},message:{},code{}", accountId, resultObject.getString("message"), code);
|
|
|
|
|
- return;
|
|
|
|
|
- }
|
|
|
|
|
- JSONArray data = resultObject.getJSONObject("data").getJSONArray("list");
|
|
|
|
|
- if (null == data || data.isEmpty()) {
|
|
|
|
|
- log.info("获取广告列表数据为空==》accountId:{},message:{},code{}", accountId, resultObject.getString("message"), code);
|
|
|
|
|
- return;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- for (int i = 0; i < data.size(); i++) {
|
|
|
|
|
- JSONObject dataObject = data.getJSONObject(i);
|
|
|
|
|
- advertiserList.add(dataObject);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- int totalPage = resultObject.getJSONObject("data").getJSONObject("page_info").getInteger("total_page");
|
|
|
|
|
- if (page <= totalPage) {
|
|
|
|
|
- checkAdvertiserList(accountId, token, projectId, page + 1, advertiserList);
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
|
|
|
|
|
- //判断逻辑
|
|
|
|
|
- private void checkLogic(String token, String type, JSONObject detail, Map<String, String> ocpxMap, Map<String, String> textMap, Map<String, String> deepMap,
|
|
|
|
|
- String cpaBid, String deepConversionBid, String localProject, JSONObject adObj) {
|
|
|
|
|
- Long accountId = detail.getLong("advertiser_id");
|
|
|
|
|
- //广告项目ID
|
|
|
|
|
- Long projectId = detail.getLong("project_id");
|
|
|
|
|
- //广告项目名称
|
|
|
|
|
- String projectName = detail.getString("name");
|
|
|
|
|
- //广告ID
|
|
|
|
|
- Long adId = adObj.getLong("promotion_id");
|
|
|
|
|
-
|
|
|
|
|
- JSONObject data = new JSONObject();
|
|
|
|
|
- //转化目标
|
|
|
|
|
- String ocpxActionType = detail.getJSONObject("optimize_goal").getString("external_action");
|
|
|
|
|
- //深度转化目标
|
|
|
|
|
- String deepConversionType = detail.getJSONObject("optimize_goal").getString("deep_external_action");
|
|
|
|
|
-
|
|
|
|
|
- //为NO_BID时,不校验出价
|
|
|
|
|
- String bidType = detail.getJSONObject("delivery_setting").getString("bid_type");
|
|
|
|
|
-
|
|
|
|
|
- StringBuffer msgType = new StringBuffer();
|
|
|
|
|
- StringBuffer msgBid = new StringBuffer();
|
|
|
|
|
- //转化目标标识
|
|
|
|
|
- Boolean typeFalg = true;
|
|
|
|
|
- //出价标识
|
|
|
|
|
- Boolean bidFalg = true;
|
|
|
|
|
- //转化目标
|
|
|
|
|
- if (!Check.isNull(ocpxActionType)) {
|
|
|
|
|
- String octypeName = Check.isNull(textMap.get(ocpxActionType)) ? ocpxActionType : textMap.get(ocpxActionType);
|
|
|
|
|
- if (ocpxMap.isEmpty()) {
|
|
|
|
|
- typeFalg = false;
|
|
|
|
|
- msgType.append("未设转化,目标转化:").append(octypeName);
|
|
|
|
|
- } else {
|
|
|
|
|
- //转化出价
|
|
|
|
|
- String ocpxBid = ocpxMap.get(ocpxActionType);
|
|
|
|
|
- //通过转化目标没有查询到转化出价,判断为转化目标不一致,触发关停
|
|
|
|
|
- if (Check.isNull(ocpxBid)) {
|
|
|
|
|
|
|
+ for (JSONObject promotionJson : promotionList) {
|
|
|
|
|
+ //广告项目ID
|
|
|
|
|
+ Long projectId = promotionJson.getLong("projectId");
|
|
|
|
|
+ BigDecimal cpaBid = promotionJson.getBigDecimal("cpaBid");
|
|
|
|
|
+ BigDecimal deepCpabid = promotionJson.getBigDecimal("deepCpabid");
|
|
|
|
|
+ JSONObject projectJson = projectInfo.get(projectId);
|
|
|
|
|
+ //广告项目名称
|
|
|
|
|
+ String projectName = projectJson.getString("projectName");
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ //转化目标
|
|
|
|
|
+ String ocpxActionType = projectJson.getString("externalAction");
|
|
|
|
|
+ //深度转化目标
|
|
|
|
|
+ String deepExternalAction = projectJson.getString("deepExternalAction");
|
|
|
|
|
+
|
|
|
|
|
+ //为NO_BID时,不校验出价
|
|
|
|
|
+ String bidType = projectJson.getString("bidType");
|
|
|
|
|
+
|
|
|
|
|
+ StringBuffer msgType = new StringBuffer();
|
|
|
|
|
+ StringBuffer msgBid = new StringBuffer();
|
|
|
|
|
+ //转化目标标识
|
|
|
|
|
+ Boolean typeFalg = true;
|
|
|
|
|
+ //出价标识
|
|
|
|
|
+ Boolean bidFalg = true;
|
|
|
|
|
+ //转化目标
|
|
|
|
|
+ if (!Check.isNull(ocpxActionType)) {
|
|
|
|
|
+ String octypeName = Check.isNull(textMap.get(ocpxActionType)) ? ocpxActionType : textMap.get(ocpxActionType);
|
|
|
|
|
+ if (ocpxMap.isEmpty()) {
|
|
|
typeFalg = false;
|
|
typeFalg = false;
|
|
|
- msgType.append("已设转化:").append(ocpxMap.get("nameStr")).append("<br/>").append("目标转化:").append(octypeName);
|
|
|
|
|
|
|
+ msgType.append("未设转化,目标转化:").append(octypeName);
|
|
|
} else {
|
|
} else {
|
|
|
- //未查询到转化出价,说明出价不一致,触发出价关停。
|
|
|
|
|
- if (!Check.isNull(cpaBid)) {
|
|
|
|
|
|
|
+ //转化出价
|
|
|
|
|
+ String ocpxBid = ocpxMap.get(ocpxActionType);
|
|
|
|
|
+ //通过转化目标没有查询到转化出价,判断为转化目标不一致,触发关停
|
|
|
|
|
+ if (Check.isNull(ocpxBid)) {
|
|
|
|
|
+ typeFalg = false;
|
|
|
|
|
+ msgType.append("已设转化:").append(ocpxMap.get("nameStr")).append("<br/>").append("目标转化:").append(octypeName);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ //未查询到转化出价,说明出价不一致,触发出价关停。
|
|
|
|
|
+ if (!Check.isNull(cpaBid)) {
|
|
|
// if (!"NO_BID".equals(bidType)) {
|
|
// if (!"NO_BID".equals(bidType)) {
|
|
|
// bidFalg = false;
|
|
// bidFalg = false;
|
|
|
// msgBid.append("[").append(octypeName).append("]目标出价为空");
|
|
// msgBid.append("[").append(octypeName).append("]目标出价为空");
|
|
|
// }
|
|
// }
|
|
|
// } else {
|
|
// } else {
|
|
|
- BigDecimal cpa = new BigDecimal(cpaBid).multiply(new BigDecimal("1000"));
|
|
|
|
|
- BigDecimal ocpx = new BigDecimal(ocpxBid);//本地设置
|
|
|
|
|
- if (cpa.compareTo(ocpx) == 1) {
|
|
|
|
|
- //计划转化出价cpa 大于 项目设置最大转化出价,则关停
|
|
|
|
|
- bidFalg = false;
|
|
|
|
|
- msgBid.append("[").append(octypeName).append("]最高出价:").append(ocpx.divide(new BigDecimal("1000"))).append("<br/>");
|
|
|
|
|
- msgBid.append("目标出价:").append(cpaBid);
|
|
|
|
|
|
|
+ BigDecimal cpa = cpaBid.multiply(new BigDecimal("1000"));
|
|
|
|
|
+ BigDecimal ocpx = new BigDecimal(ocpxBid);//本地设置
|
|
|
|
|
+ if (cpa.compareTo(ocpx) == 1) {
|
|
|
|
|
+ //计划转化出价cpa 大于 项目设置最大转化出价,则关停
|
|
|
|
|
+ bidFalg = false;
|
|
|
|
|
+ msgBid.append("[").append(octypeName).append("]最高出价:").append(ocpx.divide(new BigDecimal("1000"))).append("<br/>");
|
|
|
|
|
+ msgBid.append("目标出价:").append(cpaBid);
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
- }
|
|
|
|
|
- //深度转化目标
|
|
|
|
|
- if (typeFalg && bidFalg) {
|
|
|
|
|
- String depTypeName = Check.isNull(textMap.get(deepConversionType)) ? deepConversionType : textMap.get(deepConversionType);
|
|
|
|
|
- if (!Check.isNull(deepConversionType) && deepMap.isEmpty()) {
|
|
|
|
|
- typeFalg = false;
|
|
|
|
|
- msgType.append("未设深度转化,目标深度转化:").append(depTypeName);
|
|
|
|
|
- } else if (!Check.isNull(deepConversionType)) {
|
|
|
|
|
- String deepBid = deepMap.get(deepConversionType);
|
|
|
|
|
- if (Check.isNull(deepBid)) {
|
|
|
|
|
- //通过key未获取值,说明不包含该目标,进行关停
|
|
|
|
|
|
|
+ //深度转化目标
|
|
|
|
|
+ if (typeFalg && bidFalg) {
|
|
|
|
|
+ String depTypeName = Check.isNull(textMap.get(deepExternalAction)) ? deepExternalAction : textMap.get(deepExternalAction);
|
|
|
|
|
+ if (!Check.isNull(deepExternalAction) && deepMap.isEmpty()) {
|
|
|
typeFalg = false;
|
|
typeFalg = false;
|
|
|
- msgType.append("已设深度:").append(deepMap.get("nameStr")).append("<br/>").append("目标深度:").append(depTypeName);
|
|
|
|
|
- } else {
|
|
|
|
|
- //未查询到转化出价,说明出价不一致,触发出价关停。
|
|
|
|
|
- if (!Check.isNull(deepConversionBid)) {
|
|
|
|
|
|
|
+ msgType.append("未设深度转化,目标深度转化:").append(depTypeName);
|
|
|
|
|
+ } else if (!Check.isNull(deepExternalAction)) {
|
|
|
|
|
+ String deepBid = deepMap.get(deepExternalAction);
|
|
|
|
|
+ if (Check.isNull(deepBid)) {
|
|
|
|
|
+ //通过key未获取值,说明不包含该目标,进行关停
|
|
|
|
|
+ typeFalg = false;
|
|
|
|
|
+ msgType.append("已设深度:").append(deepMap.get("nameStr")).append("<br/>").append("目标深度:").append(depTypeName);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ //未查询到转化出价,说明出价不一致,触发出价关停。
|
|
|
|
|
+ if (!Check.isNull(deepCpabid)) {
|
|
|
/* bidFalg = false;
|
|
/* bidFalg = false;
|
|
|
msgBid.append("[").append(depTypeName).append("]目标深度出价为空");
|
|
msgBid.append("[").append(depTypeName).append("]目标深度出价为空");
|
|
|
} else {*/
|
|
} else {*/
|
|
|
- BigDecimal cpa = new BigDecimal(deepConversionBid).multiply(new BigDecimal("1000"));
|
|
|
|
|
- BigDecimal ocpx = new BigDecimal(deepBid);
|
|
|
|
|
- if (cpa.compareTo(ocpx) == 1) {
|
|
|
|
|
- //计划转化出价cpa 大于 项目设置最大转化出价,则关停
|
|
|
|
|
- bidFalg = false;
|
|
|
|
|
- msgBid.append("[").append(depTypeName).append("]最高深度出价:").append(ocpx.divide(new BigDecimal("1000"))).append("<br/>");
|
|
|
|
|
- msgBid.append("目标深度出价:").append(deepConversionBid);
|
|
|
|
|
|
|
+ BigDecimal cpa = deepCpabid.multiply(new BigDecimal("1000"));
|
|
|
|
|
+ BigDecimal ocpx = new BigDecimal(deepBid);
|
|
|
|
|
+ if (cpa.compareTo(ocpx) == 1) {
|
|
|
|
|
+ //计划转化出价cpa 大于 项目设置最大转化出价,则关停
|
|
|
|
|
+ bidFalg = false;
|
|
|
|
|
+ msgBid.append("[").append(depTypeName).append("]最高深度出价:").append(ocpx.divide(new BigDecimal("1000"))).append("<br/>");
|
|
|
|
|
+ msgBid.append("目标深度出价:").append(deepCpabid);
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
- }
|
|
|
|
|
|
|
|
|
|
- if (!typeFalg) { // 出价方式设置非法
|
|
|
|
|
- String text = getProjectBidTypeText(localProject, accountId, projectId, projectName, adId, adObj.getString("promotion_name"), msgType.toString());
|
|
|
|
|
- sendMsg(accountId, token, projectId, adId, text);
|
|
|
|
|
|
|
+
|
|
|
|
|
+ if (!typeFalg || !bidFalg) {
|
|
|
|
|
+ this.updProjectStatus(token, accountId, projectId, "DISABLE");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (!typeFalg) { // 出价方式设置非法
|
|
|
|
|
+ String text = getProjectBidTypeText(json.getString("projectName"), accountId, projectId, projectName, null, null, msgType.toString());
|
|
|
|
|
+ sendMsg(accountId, text);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (!bidFalg) {
|
|
|
|
|
+ String text = getProjectOverBidMessage(json.getString("projectName"), accountId, projectId, projectName, null, null, msgBid.toString());
|
|
|
|
|
+ sendMsg(accountId, text);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
}
|
|
}
|
|
|
- if (!bidFalg) {
|
|
|
|
|
- String text = getProjectOverBidMessage(localProject, accountId, projectId, projectName, adId, adObj.getString("promotion_name"), msgBid.toString());
|
|
|
|
|
- sendMsg(accountId, token, projectId, adId, text);
|
|
|
|
|
|
|
+
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ private Map<Long, JSONObject> getProjectInfo(Long accountId, String accessToken, List<Long> ids, int page) {
|
|
|
|
|
+ Map<Long, JSONObject> returnMap = new HashMap<>();
|
|
|
|
|
+ try {
|
|
|
|
|
+ // 请求地址
|
|
|
|
|
+ String url = bytedanceApiUrl + "/v3.0/project/list/";
|
|
|
|
|
+ JSONObject param = new JSONObject();
|
|
|
|
|
+ param.put("advertiser_id", accountId);
|
|
|
|
|
+ param.put("page", page);
|
|
|
|
|
+ param.put("page_size", 100);
|
|
|
|
|
+ JSONObject filtering = new JSONObject();
|
|
|
|
|
+ if (!Check.isNull(ids)) {
|
|
|
|
|
+ filtering.put("ids", new ArrayList<>(ids));
|
|
|
|
|
+ }
|
|
|
|
|
+ param.put("filtering", filtering);
|
|
|
|
|
+ JSONObject resultObject = HttpUtils.bytedanceGetRequest(accessToken, url, param);
|
|
|
|
|
+ if (Check.isNull(resultObject)) {
|
|
|
|
|
+ log.error("checkAdvertiserProject异常==》accountId:{},结果为null", accountId);
|
|
|
|
|
+ return returnMap;
|
|
|
|
|
+ }
|
|
|
|
|
+ Integer code = resultObject.getInteger("code");
|
|
|
|
|
+ if (null == code || !code.equals(0)) {
|
|
|
|
|
+ log.error("checkAdvertiserProject接口==》accountId:{},message:{},code{}", accountId, resultObject.getString("message"), code);
|
|
|
|
|
+ return returnMap;
|
|
|
|
|
+ }
|
|
|
|
|
+ JSONArray data = resultObject.getJSONObject("data").getJSONArray("list");
|
|
|
|
|
+ System.err.println(data);
|
|
|
|
|
+ if (null == data || data.isEmpty()) {
|
|
|
|
|
+ log.info("checkAdvertiserProject数据为空==》accountId:{},message:{},code:{}", accountId, resultObject.getString("message"), code);
|
|
|
|
|
+ return returnMap;
|
|
|
|
|
+ }
|
|
|
|
|
+ for (int i = 0; i < data.size(); i++) {
|
|
|
|
|
+ JSONObject dataObject = data.getJSONObject(i);
|
|
|
|
|
+ JSONObject mapJson = new JSONObject();
|
|
|
|
|
+ //广告项目ID
|
|
|
|
|
+ Long projectId = dataObject.getLong("project_id");
|
|
|
|
|
+ mapJson.put("projectId", projectId);
|
|
|
|
|
+ //广告项目名称
|
|
|
|
|
+ String projectName = dataObject.getString("name");
|
|
|
|
|
+ mapJson.put("projectName", projectName);
|
|
|
|
|
+ //转化目标
|
|
|
|
|
+ String externalAction = dataObject.getJSONObject("optimize_goal").getString("external_action");
|
|
|
|
|
+ mapJson.put("externalAction", externalAction);
|
|
|
|
|
+ //深度转化目标
|
|
|
|
|
+ String deepExternalAction = dataObject.getJSONObject("optimize_goal").getString("deep_external_action");
|
|
|
|
|
+ mapJson.put("deepExternalAction", deepExternalAction);
|
|
|
|
|
+ //为NO_BID时,不校验出价
|
|
|
|
|
+ String bidType = dataObject.getJSONObject("delivery_setting").getString("bid_type");
|
|
|
|
|
+ mapJson.put("bidType", bidType);
|
|
|
|
|
+ returnMap.put(projectId, mapJson);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
|
+ e.printStackTrace();
|
|
|
}
|
|
}
|
|
|
|
|
+ return returnMap;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- private void sendMsg(Long accountId, String token, Long projectId, Long adId, String text) {
|
|
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public void updProjectStatus(String token, Long accountId, Long projectId, String disable) {
|
|
|
|
|
+ JSONObject params = new JSONObject();
|
|
|
|
|
+ params.put("advertiser_id", accountId);
|
|
|
|
|
+ JSONObject data = new JSONObject();
|
|
|
|
|
+ data.put("project_id", projectId);
|
|
|
|
|
+ data.put("opt_status", disable);//ENABLE 启用项目、 DISABLE 暂停项目
|
|
|
|
|
+ List<JSONObject> list = new ArrayList<>();
|
|
|
|
|
+ list.add(data);
|
|
|
|
|
+ params.put("data", list);
|
|
|
|
|
+ String url = bytedanceApiUrl + "/v3.0/project/status/update/";
|
|
|
|
|
+ JSONObject object = HttpUtils.bytedancePostRequest(token, url, params);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public String getTokenByAccountId(Long advertiserId) {
|
|
|
|
|
+ return projectListMapper.getTokenByAccountId(advertiserId);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ //判断逻辑
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ private void sendMsg(Long accountId, String text) {
|
|
|
try {
|
|
try {
|
|
|
- MediaSendAlarmRecord record = new MediaSendAlarmRecord(accountId, "1", text);
|
|
|
|
|
- record.setProjectId(projectId);
|
|
|
|
|
|
|
+
|
|
|
//关停计划
|
|
//关停计划
|
|
|
- this.updProjectStatus(token, accountId, projectId, "DISABLE");
|
|
|
|
|
- log.info(">预警<,账户:{}=>计划:{}现已【关停】---> {}", accountId, projectId, text);
|
|
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
List<JSONObject> list = projectListMapper.getWChatIdsByAccountId(accountId);
|
|
List<JSONObject> list = projectListMapper.getWChatIdsByAccountId(accountId);
|
|
|
for (JSONObject object : list) {
|
|
for (JSONObject object : list) {
|
|
|
corpWexinUtils.sendMessageByWeChatId(object, text);
|
|
corpWexinUtils.sendMessageByWeChatId(object, text);
|
|
|
}
|
|
}
|
|
|
- //添加记录 ctop_media_send_alarm_record
|
|
|
|
|
- projectListMapper.insertSendRecord(record);
|
|
|
|
|
- //当前已发送次数
|
|
|
|
|
-
|
|
|
|
|
- Integer i = projectListMapper.getrefusalAccountCounts(accountId, adId);
|
|
|
|
|
- //更新计数
|
|
|
|
|
- projectListMapper.insertSendAccountId(accountId, adId, (Check.isNull(i) ? 0 : i) + 1);
|
|
|
|
|
} catch (Exception e) {
|
|
} catch (Exception e) {
|
|
|
e.printStackTrace();
|
|
e.printStackTrace();
|
|
|
}
|
|
}
|