|
@@ -3,19 +3,41 @@ package org.jeecg.modules.bytedance.advertise.service.impl;
|
|
|
import com.alibaba.fastjson.JSONArray;
|
|
|
import com.alibaba.fastjson.JSONObject;
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
-import org.jeecg.modules.bytedance.advertise.entity.*;
|
|
|
+import org.jeecg.modules.bytedance.advertise.dockapi.MarketingService;
|
|
|
+import org.jeecg.modules.bytedance.advertise.entity.ByteDanceAdvertisePlan;
|
|
|
+import org.jeecg.modules.bytedance.advertise.entity.ByteDanceCreative;
|
|
|
+import org.jeecg.modules.bytedance.advertise.entity.ByteDanceVideoInfo;
|
|
|
+import org.jeecg.modules.bytedance.advertise.entity.BytedanceImageInfo;
|
|
|
import org.jeecg.modules.bytedance.advertise.mapper.ByteDanceCreativeMapper;
|
|
|
-import org.jeecg.modules.bytedance.advertise.service.*;
|
|
|
+import org.jeecg.modules.bytedance.advertise.mapper.MonitorBytedanceActionTrackUrlMapper;
|
|
|
+import org.jeecg.modules.bytedance.advertise.service.IByteDanceAdvertisePlanService;
|
|
|
+import org.jeecg.modules.bytedance.advertise.service.IByteDanceAdvertiserDataService;
|
|
|
+import org.jeecg.modules.bytedance.advertise.service.IByteDanceCreativeMaterialService;
|
|
|
+import org.jeecg.modules.bytedance.advertise.service.IByteDanceVideoInfoService;
|
|
|
+import org.jeecg.modules.bytedance.advertise.service.IBytedanceImageInfoService;
|
|
|
import org.jeecg.modules.bytedance.common.entity.CtopOauthToken;
|
|
|
+import org.jeecg.modules.bytedance.common.entity.UserAllocation;
|
|
|
import org.jeecg.modules.bytedance.common.service.ICtopOauthTokenService;
|
|
|
-import org.jeecg.modules.bytedance.common.utils.*;
|
|
|
+import org.jeecg.modules.bytedance.common.service.IUserAllocationService;
|
|
|
+import org.jeecg.modules.bytedance.common.utils.Check;
|
|
|
+import org.jeecg.modules.bytedance.common.utils.CorpWexinUtils;
|
|
|
+import org.jeecg.modules.bytedance.common.utils.HttpUtils;
|
|
|
+import org.jeecg.modules.bytedance.common.utils.PropertiesUtils;
|
|
|
+import org.jeecg.modules.bytedance.common.utils.StringUtils;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
import org.springframework.beans.factory.annotation.Value;
|
|
|
import org.springframework.context.annotation.Primary;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
|
|
|
+import javax.annotation.Resource;
|
|
|
import java.math.BigDecimal;
|
|
|
-import java.util.*;
|
|
|
+import java.util.ArrayList;
|
|
|
+import java.util.Arrays;
|
|
|
+import java.util.Collections;
|
|
|
+import java.util.HashMap;
|
|
|
+import java.util.List;
|
|
|
+import java.util.Map;
|
|
|
+import java.util.TreeMap;
|
|
|
|
|
|
/**
|
|
|
* @author 宋英豪
|
|
@@ -43,6 +65,15 @@ public class ByteDanceAdvertiserDataServiceImpl implements IByteDanceAdvertiserD
|
|
|
private ByteDanceCreativeMapper creativeMapper;
|
|
|
@Autowired
|
|
|
private IByteDanceVideoInfoService videoInfoService;
|
|
|
+ @Autowired
|
|
|
+ private IUserAllocationService userAllocationService;
|
|
|
+ @Resource
|
|
|
+ private CorpWexinUtils corpWexinUtils;
|
|
|
+ @Resource
|
|
|
+ private MonitorBytedanceActionTrackUrlMapper monitorBytedanceActionTrackUrlMapper;
|
|
|
+ @Resource
|
|
|
+ private MarketingService marketingServiceImpl;
|
|
|
+
|
|
|
|
|
|
@Override
|
|
|
public JSONObject getAdvertiserList(String token, Long accountId) {
|
|
@@ -156,7 +187,7 @@ public class ByteDanceAdvertiserDataServiceImpl implements IByteDanceAdvertiserD
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
- public ByteDanceAdvertisePlan getSinglePlanById(CtopOauthToken token, String id){
|
|
|
+ public ByteDanceAdvertisePlan getSinglePlanById(CtopOauthToken token, String id) {
|
|
|
JSONArray getIds = new JSONArray();
|
|
|
getIds.add(id);
|
|
|
// 请求地址
|
|
@@ -232,6 +263,7 @@ public class ByteDanceAdvertiserDataServiceImpl implements IByteDanceAdvertiserD
|
|
|
}
|
|
|
for (int i = 0; i < data.size(); i++) {
|
|
|
JSONObject dataObject = data.getJSONObject(i);
|
|
|
+ checkBidType(token.getAccountId(), dataObject);
|
|
|
ByteDanceAdvertisePlan advertisePlan = new ByteDanceAdvertisePlan(dataObject, String.valueOf(token.getAccountId()));
|
|
|
BigDecimal deepCpabid = dataObject.getBigDecimal("deep_cpabid");
|
|
|
if (null != deepCpabid) {
|
|
@@ -242,6 +274,169 @@ public class ByteDanceAdvertiserDataServiceImpl implements IByteDanceAdvertiserD
|
|
|
getAd(token, pageNum + 1, ids, date, updateDate);
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * 校验转化出价,并预警
|
|
|
+ */
|
|
|
+ private void checkBidType(Long accountId, JSONObject detail) {
|
|
|
+ JSONObject json = userAllocationService.getProjectByAccountId(accountId);
|
|
|
+ if (Check.isNull(json) || Check.isNull(detail)) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ //转化目标map
|
|
|
+ Map<String, String> ocpxMap = new HashMap<>();
|
|
|
+ String ocpxTypeStr = json.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.getString("ocpxCode"), obj.getString("maxValue"));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (ocpxMap.isEmpty()) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ //深度转化目标map
|
|
|
+ Map<String, String> deepMap = new HashMap<>();
|
|
|
+ String deepTypeStr = json.getString("deepConversionType");
|
|
|
+ if (!Check.isNull(deepTypeStr)) {
|
|
|
+ JSONArray deepArr = JSONArray.parseArray(deepTypeStr);
|
|
|
+ for (int i = 0; i < deepArr.size(); i++) {
|
|
|
+ JSONObject obj = deepArr.getJSONObject(i);
|
|
|
+ deepMap.put(obj.getString("deepCode"), obj.getString("deepValue"));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ //转化目标
|
|
|
+ String ocpxActionType = detail.getString("external_action");
|
|
|
+ //转化目标出价
|
|
|
+ String cpaBid = detail.getString("cpa_bid");
|
|
|
+ //深度转化目标
|
|
|
+ String deepConversionType = detail.getString("deep_external_action");
|
|
|
+ //深度转化目标出价
|
|
|
+ String deepConversionBid = detail.getString("deep_cpabid");
|
|
|
+
|
|
|
+ //计划ID
|
|
|
+ Long planId = detail.getLong("ad_id");
|
|
|
+ //计划名称
|
|
|
+ String planName = detail.getString("name");
|
|
|
+ //投放状态
|
|
|
+ String status = detail.getString("status");
|
|
|
+ //操作状态
|
|
|
+ String optStatus = detail.getString("opt_status");
|
|
|
+ if ("AD_STATUS_ENABLE".equals(optStatus) && "AD_STATUS_DELIVERY_OK".equals(status)) { // 操作状态为‘启用’,广告计划投放状态 为‘投放中’
|
|
|
+ String msgType = "";
|
|
|
+ String msgBid = "";
|
|
|
+
|
|
|
+ //转化目标标识
|
|
|
+ Boolean typeFalg = true;
|
|
|
+ //出价标识
|
|
|
+ Boolean bidFalg = true;
|
|
|
+ //转化目标
|
|
|
+ if (!Check.isNull(ocpxActionType)) {
|
|
|
+ //转化出价
|
|
|
+ String ocpxBid = ocpxMap.get(ocpxActionType);
|
|
|
+ //通过转化目标没有查询到转化出价,判断为转化目标不一致,触发关停
|
|
|
+ if (Check.isNull(ocpxBid)) {
|
|
|
+ typeFalg = false;
|
|
|
+ msgType = "转化:" + ocpxActionType;
|
|
|
+ } else {
|
|
|
+ //未查询到转化出价,说明出价不一致,触发出价关停。
|
|
|
+ if (Check.isNull(cpaBid)) {
|
|
|
+ bidFalg = false;
|
|
|
+ msgBid = "出价为空";
|
|
|
+ } else {
|
|
|
+ BigDecimal cpa = new BigDecimal(cpaBid);
|
|
|
+ BigDecimal ocpx = new BigDecimal(ocpxBid);
|
|
|
+ if (cpa.compareTo(ocpx) == 1) {
|
|
|
+ //计划转化出价cpa 大于 项目设置最大转化出价,则关停
|
|
|
+ bidFalg = false;
|
|
|
+ msgBid = "计划出价:" + cpaBid;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ //深度转化目标
|
|
|
+ if (typeFalg && bidFalg) {
|
|
|
+ if (!Check.isNull(deepConversionType) && !deepMap.isEmpty()) {
|
|
|
+ String deepBid = deepMap.get(deepConversionType);
|
|
|
+ if (Check.isNull(deepBid)) {
|
|
|
+ //通过key未获取值,说明不包含该目标,进行关停
|
|
|
+ typeFalg = false;
|
|
|
+ msgType = "(深度)转化:" + deepConversionType;
|
|
|
+ } else {
|
|
|
+ //未查询到转化出价,说明出价不一致,触发出价关停。
|
|
|
+ if (Check.isNull(deepConversionBid)) {
|
|
|
+ bidFalg = false;
|
|
|
+ msgBid = "(深度)出价为空";
|
|
|
+ } else {
|
|
|
+ BigDecimal cpa = new BigDecimal(deepConversionBid);
|
|
|
+ BigDecimal ocpx = new BigDecimal(deepBid);
|
|
|
+ if (cpa.compareTo(ocpx) == 1) {
|
|
|
+ //计划转化出价cpa 大于 项目设置最大转化出价,则关停
|
|
|
+ bidFalg = false;
|
|
|
+ msgBid = "(深度)计划出价:" + cpaBid;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (!typeFalg) { // 出价方式设置非法
|
|
|
+ String text = getBidTypeText(json.getString("projectName"), accountId, planId, planName, msgType);
|
|
|
+ sendMsg(accountId, planId, text);
|
|
|
+ }
|
|
|
+ if (!bidFalg) {
|
|
|
+ String text = getOverBidMessage(json.getString("projectName"), accountId, planId, planName, msgBid);
|
|
|
+ sendMsg(accountId, planId, text);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ private void sendMsg(Long accountId, Long planId, String text) {
|
|
|
+ //关停计划
|
|
|
+ CtopOauthToken token = tokenService.getTokenByAccountId(accountId);
|
|
|
+ marketingServiceImpl.updPlanStatus(token, Arrays.asList(planId), "disable");
|
|
|
+ log.info("出价方式预警,accountId:{}==>计划id:{}=====转化目标不一致,计划已【关停】============", accountId, planId);
|
|
|
+ try {
|
|
|
+ UserAllocation account = userAllocationService.getByAccountId(accountId);
|
|
|
+ String userId = "";
|
|
|
+ if (!Check.isNull(account)) {
|
|
|
+ userId = account.getUserId();
|
|
|
+ }
|
|
|
+ JSONObject jsonObject = monitorBytedanceActionTrackUrlMapper.getWChatIdByUserId(userId);
|
|
|
+ corpWexinUtils.sendMessageByWeChatId(jsonObject, text);
|
|
|
+ } catch (Exception e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ //转化方式错误消息生成
|
|
|
+ private String getBidTypeText(String projectName, Long advertiserId, Long unitId, String unit_name, String msgType) {
|
|
|
+ StringBuilder text = new StringBuilder();
|
|
|
+ text.append("出价方式错误预警").append("<br/>")
|
|
|
+ .append("您的项目:").append(projectName + ",").append("<br/>")
|
|
|
+ .append("下的账户:").append(advertiserId + ",").append("<br/>")
|
|
|
+ .append("广告计划id:").append(unitId).append("<br/>")
|
|
|
+ .append("广告计划名称:").append(unit_name).append("<br/>")
|
|
|
+ .append("出价方式设置错误。").append(msgType).append("<br/>")
|
|
|
+ .append("系统已执行暂停此计划,请您及时查看!");
|
|
|
+ return text.toString();
|
|
|
+ }
|
|
|
+
|
|
|
+ //出价过高预警消息生成
|
|
|
+ private String getOverBidMessage(String projectName, Long accountId, Long planId, String planName, String msgBid) {
|
|
|
+ StringBuilder text = new StringBuilder();
|
|
|
+ text.append("出价过高预警").append("<br/>")
|
|
|
+ .append("您的项目:").append(projectName + ",").append("<br/>")
|
|
|
+ .append("下的账户:").append(accountId + ",").append("<br/>")
|
|
|
+ .append("广告计划id为:").append(planId).append("<br/>")
|
|
|
+ .append("广告计划名称为:").append(planName).append("<br/>")
|
|
|
+ .append("出价设置过高。").append(msgBid).append("<br/>")
|
|
|
+ .append("系统已执行暂停此计划,请您及时查看!");
|
|
|
+ return text.toString();
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
@Override
|
|
|
public Map<String, Object> getAdvertiserPlan(CtopOauthToken token, String ids, String date, String updateDate) {
|
|
|
getAd(token, 1, ids, date, updateDate);
|
|
@@ -286,8 +481,6 @@ public class ByteDanceAdvertiserDataServiceImpl implements IByteDanceAdvertiserD
|
|
|
}
|
|
|
|
|
|
|
|
|
-
|
|
|
-
|
|
|
private void getCreativeByPage(CtopOauthToken token, String date, int pageNum) {
|
|
|
JSONObject resultObject = getCreative(token, date, pageNum);
|
|
|
Integer code = resultObject.getInteger("code");
|
|
@@ -475,8 +668,6 @@ public class ByteDanceAdvertiserDataServiceImpl implements IByteDanceAdvertiserD
|
|
|
}
|
|
|
|
|
|
|
|
|
-
|
|
|
-
|
|
|
/**
|
|
|
* 获取流量包数据接口
|
|
|
*
|