|  | @@ -2,11 +2,14 @@ package cn.com.ctop.job.bytedance.data.service.impl;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  import cn.com.ctop.job.bytedance.data.constant.BytedanceConstant;
 | 
	
		
			
				|  |  |  import cn.com.ctop.job.bytedance.data.entity.BytedanceCdpProject;
 | 
	
		
			
				|  |  | +import cn.com.ctop.job.bytedance.data.entity.MediaSendAlarmRecord;
 | 
	
		
			
				|  |  |  import cn.com.ctop.job.bytedance.data.entity.OauthToken;
 | 
	
		
			
				|  |  |  import cn.com.ctop.job.bytedance.data.mapper.BytedanceProjectMapper;
 | 
	
		
			
				|  |  | +import cn.com.ctop.job.bytedance.data.mapper.OauthTokenMapper;
 | 
	
		
			
				|  |  |  import cn.com.ctop.job.bytedance.data.service.IBytedanceProjectService;
 | 
	
		
			
				|  |  |  import cn.com.ctop.job.bytedance.data.utils.Check;
 | 
	
		
			
				|  |  |  import cn.com.ctop.job.bytedance.data.utils.HttpUtils;
 | 
	
		
			
				|  |  | +import cn.com.ctop.job.bytedance.data.utils.weixin.CorpWexinUtils;
 | 
	
		
			
				|  |  |  import cn.com.ctop.job.bytedance.utils.RedisUtil;
 | 
	
		
			
				|  |  |  import com.alibaba.fastjson.JSONArray;
 | 
	
		
			
				|  |  |  import com.alibaba.fastjson.JSONObject;
 | 
	
	
		
			
				|  | @@ -16,8 +19,11 @@ import org.springframework.beans.factory.annotation.Value;
 | 
	
		
			
				|  |  |  import org.springframework.stereotype.Service;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  import javax.annotation.Resource;
 | 
	
		
			
				|  |  | +import java.math.BigDecimal;
 | 
	
		
			
				|  |  |  import java.util.ArrayList;
 | 
	
		
			
				|  |  | +import java.util.HashMap;
 | 
	
		
			
				|  |  |  import java.util.List;
 | 
	
		
			
				|  |  | +import java.util.Map;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  /**
 | 
	
		
			
				|  |  |   * 获取项目列表
 | 
	
	
		
			
				|  | @@ -32,8 +38,13 @@ public class BytedanceProjectServiceImpl implements IBytedanceProjectService {
 | 
	
		
			
				|  |  |      BytedanceProjectMapper projectListMapper;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      @Autowired
 | 
	
		
			
				|  |  | +    private OauthTokenMapper tokenMapper;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    @Autowired
 | 
	
		
			
				|  |  |      private RedisUtil redisUtil;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +    @Resource
 | 
	
		
			
				|  |  | +    private CorpWexinUtils corpWexinUtils;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      @Override
 | 
	
		
			
				|  |  |      public void getProjectList(OauthToken oauthToken, String startDate, String endDate, int page) {
 | 
	
	
		
			
				|  | @@ -81,16 +92,353 @@ public class BytedanceProjectServiceImpl implements IBytedanceProjectService {
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    public void updProjectStatus(OauthToken token, Long projectId, String disable) {
 | 
	
		
			
				|  |  | +    @Override
 | 
	
		
			
				|  |  | +    public void updProjectStatus(String token, Long accountId, Long projectId, String disable) {
 | 
	
		
			
				|  |  |          JSONObject params = new JSONObject();
 | 
	
		
			
				|  |  | -        params.put("advertiser_id", token.getAccountId());
 | 
	
		
			
				|  |  | +        params.put("advertiser_id", accountId);
 | 
	
		
			
				|  |  |          JSONObject data = new JSONObject();
 | 
	
		
			
				|  |  |          data.put("project_id", projectId);
 | 
	
		
			
				|  |  | -        data.put("opt_status", disable);
 | 
	
		
			
				|  |  | +        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.getAccessToken(), url, params);
 | 
	
		
			
				|  |  | +        JSONObject object = HttpUtils.bytedancePostRequest(token, url, params);
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    @Override
 | 
	
		
			
				|  |  | +    public void checkAdvertiserList(OauthToken oauthToken, Long projectId, String date, int page, List<JSONObject> advertiserList) {
 | 
	
		
			
				|  |  | +        // 请求地址
 | 
	
		
			
				|  |  | +        String url = bytedanceApiUrl + BytedanceConstant.BYTEDANCE_V3_PROMOTION_LIST_GET;
 | 
	
		
			
				|  |  | +        JSONObject param = new JSONObject();
 | 
	
		
			
				|  |  | +        param.put("advertiser_id", oauthToken.getAccountId());
 | 
	
		
			
				|  |  | +        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(oauthToken.getAccessToken(), url, param);
 | 
	
		
			
				|  |  | +        if (Check.isNull(resultObject)) {
 | 
	
		
			
				|  |  | +            log.error("获取广告列表异常==》accountId:{},调用结果为null", oauthToken.getAccountId());
 | 
	
		
			
				|  |  | +            return;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        Integer code = resultObject.getInteger("code");
 | 
	
		
			
				|  |  | +        if (null == code || !code.equals(0)) {
 | 
	
		
			
				|  |  | +            log.error("获取广告列表接口异常==》accountId:{},message:{},code{}", oauthToken.getAccountId(), resultObject.getString("message"), code);
 | 
	
		
			
				|  |  | +            return;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        JSONArray data = resultObject.getJSONObject("data").getJSONArray("list");
 | 
	
		
			
				|  |  | +        if (null == data || data.isEmpty()) {
 | 
	
		
			
				|  |  | +            log.info("获取广告列表数据为空==》accountId:{},message:{},code{}", oauthToken.getAccountId(), resultObject.getString("message"), code);
 | 
	
		
			
				|  |  | +            return;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        for (int i = 0; i < data.size(); i++) {
 | 
	
		
			
				|  |  | +            JSONObject dataObject = data.getJSONObject(i);
 | 
	
		
			
				|  |  | +            System.out.println("账户ID:" + projectId + "数据:" + dataObject);
 | 
	
		
			
				|  |  | +            advertiserList.add(dataObject);
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        int totalPage = resultObject.getJSONObject("data").getJSONObject("page_info").getInteger("total_page");
 | 
	
		
			
				|  |  | +        if (page <= totalPage) {
 | 
	
		
			
				|  |  | +            checkAdvertiserList(oauthToken, projectId, date, page + 1, advertiserList);
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    @Override
 | 
	
		
			
				|  |  | +    public void checkAdvertiserProject(OauthToken oauthToken, String date, int page) {
 | 
	
		
			
				|  |  | +//       一个小时内,发送2次以后拒绝发送
 | 
	
		
			
				|  |  | +        if (!checkThreeRejections(oauthToken.getAccountId())) {
 | 
	
		
			
				|  |  | +            return;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        try {
 | 
	
		
			
				|  |  | +            // 请求地址
 | 
	
		
			
				|  |  | +            String url = bytedanceApiUrl + BytedanceConstant.BYTEDANCE_V3_PROJECT_LIST_GET;
 | 
	
		
			
				|  |  | +            JSONObject param = new JSONObject();
 | 
	
		
			
				|  |  | +            param.put("advertiser_id", oauthToken.getAccountId());
 | 
	
		
			
				|  |  | +            param.put("page", page);
 | 
	
		
			
				|  |  | +            param.put("page_size", 100);
 | 
	
		
			
				|  |  | +            JSONObject filtering = new JSONObject();
 | 
	
		
			
				|  |  | +            filtering.put("status", "PROJECT_STATUS_ENABLE");//项目 仅查询启动状态
 | 
	
		
			
				|  |  | +            param.put("filtering", filtering);
 | 
	
		
			
				|  |  | +            JSONObject resultObject = HttpUtils.bytedanceGetRequest(oauthToken.getAccessToken(), url, param);
 | 
	
		
			
				|  |  | +            if (Check.isNull(resultObject)) {
 | 
	
		
			
				|  |  | +                log.error("checkAdvertiserProject异常==》accountId:{},结果为null", oauthToken.getAccountId());
 | 
	
		
			
				|  |  | +                return;
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +            Integer code = resultObject.getInteger("code");
 | 
	
		
			
				|  |  | +            if (null == code || !code.equals(0)) {
 | 
	
		
			
				|  |  | +                log.error("checkAdvertiserProject接口==》accountId:{},message:{},code{}", oauthToken.getAccountId(), resultObject.getString("message"), code);
 | 
	
		
			
				|  |  | +                return;
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +            JSONArray data = resultObject.getJSONObject("data").getJSONArray("list");
 | 
	
		
			
				|  |  | +            if (null == data || data.isEmpty()) {
 | 
	
		
			
				|  |  | +                log.info("checkAdvertiserProject数据为空==》accountId:{},message:{},code:{}", oauthToken.getAccountId(), resultObject.getString("message"), code);
 | 
	
		
			
				|  |  | +                return;
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +            for (int i = 0; i < data.size(); i++) {
 | 
	
		
			
				|  |  | +                JSONObject dataObject = data.getJSONObject(i);
 | 
	
		
			
				|  |  | +                System.out.println("-------项目数据:" + dataObject);
 | 
	
		
			
				|  |  | +                checkProjectBidType(oauthToken, date, dataObject);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +            int totalPage = resultObject.getJSONObject("data").getJSONObject("page_info").getInteger("total_page");
 | 
	
		
			
				|  |  | +            if (page <= totalPage) {
 | 
	
		
			
				|  |  | +                checkAdvertiserProject(oauthToken, date, page + 1);
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +        } catch (Exception e) {
 | 
	
		
			
				|  |  | +            e.printStackTrace();
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    //检查 发送3次以后拒绝发送
 | 
	
		
			
				|  |  | +    private boolean checkThreeRejections(Long accountId) {
 | 
	
		
			
				|  |  | +        Long projectId = projectListMapper.getProjectId(accountId);
 | 
	
		
			
				|  |  | +        List<Long> ids = projectListMapper.getSpecialProject();
 | 
	
		
			
				|  |  | +        if (ids.contains(accountId) || ids.contains(projectId)) {
 | 
	
		
			
				|  |  | +            //过滤标记 都不发送
 | 
	
		
			
				|  |  | +            return false;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        List<Long> accountIds = projectListMapper.getBytedanceRefusalSend();
 | 
	
		
			
				|  |  | +        if (!Check.isNull(accountIds)) {
 | 
	
		
			
				|  |  | +            return !accountIds.contains(accountId);
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        return true;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    /**
 | 
	
		
			
				|  |  | +     * 校验转化出价,并预警
 | 
	
		
			
				|  |  | +     */
 | 
	
		
			
				|  |  | +    public void checkProjectBidType(OauthToken oauthToken, String date, JSONObject detail) {
 | 
	
		
			
				|  |  | +        Long accountId = detail.getLong("advertiser_id");
 | 
	
		
			
				|  |  | +        //项目ID
 | 
	
		
			
				|  |  | +        Long projectId = detail.getLong("project_id");
 | 
	
		
			
				|  |  | +        JSONObject json = tokenMapper.getProjectByAccountId(accountId);
 | 
	
		
			
				|  |  | +        if (Check.isNull(json) || Check.isNull(detail)) {
 | 
	
		
			
				|  |  | +            return;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        Map<String, String> textMap = new HashMap<>();
 | 
	
		
			
				|  |  | +        List<JSONObject> lists = tokenMapper.getBytedanceOcpxTypeList();
 | 
	
		
			
				|  |  | +        for (JSONObject da : lists) {
 | 
	
		
			
				|  |  | +            textMap.put(da.getString("ocpxActionType"), da.getString("ocpxActionName"));
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        //转化目标map
 | 
	
		
			
				|  |  | +        Map<String, String> ocpxMap = new HashMap<>();
 | 
	
		
			
				|  |  | +        String ocpxTypeStr = json.getString("ocpxActionType");
 | 
	
		
			
				|  |  | +        if (!Check.isNull(ocpxTypeStr)) {
 | 
	
		
			
				|  |  | +            JSONArray ocpxArr = JSONArray.parseArray(ocpxTypeStr);
 | 
	
		
			
				|  |  | +            StringBuffer nameStr = new StringBuffer();
 | 
	
		
			
				|  |  | +            for (int i = 0; i < ocpxArr.size(); i++) {
 | 
	
		
			
				|  |  | +                JSONObject obj = ocpxArr.getJSONObject(i);
 | 
	
		
			
				|  |  | +                ocpxMap.put(obj.getString("ocpxCode"), obj.getString("maxValue"));
 | 
	
		
			
				|  |  | +                nameStr.append(textMap.get(obj.getString("ocpxCode"))).append(" ");
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +            if (ocpxArr.size() > 0) {
 | 
	
		
			
				|  |  | +                ocpxMap.put("nameStr", nameStr.toString());
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        //深度转化目标map
 | 
	
		
			
				|  |  | +        Map<String, String> deepMap = new HashMap<>();
 | 
	
		
			
				|  |  | +        String deepTypeStr = json.getString("deepConversionType");
 | 
	
		
			
				|  |  | +        if (!Check.isNull(deepTypeStr)) {
 | 
	
		
			
				|  |  | +            JSONArray deepArr = JSONArray.parseArray(deepTypeStr);
 | 
	
		
			
				|  |  | +            StringBuffer nameStr = new StringBuffer();
 | 
	
		
			
				|  |  | +            for (int i = 0; i < deepArr.size(); i++) {
 | 
	
		
			
				|  |  | +                JSONObject obj = deepArr.getJSONObject(i);
 | 
	
		
			
				|  |  | +                deepMap.put(obj.getString("deepCode"), obj.getString("deepValue"));
 | 
	
		
			
				|  |  | +                nameStr.append(textMap.get(obj.getString("deepCode"))).append(" ");
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +            if (deepArr.size() > 0) {
 | 
	
		
			
				|  |  | +                deepMap.put("nameStr", nameStr.toString());
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        //操作状态
 | 
	
		
			
				|  |  | +        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");
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            List<JSONObject> advertiserList = new ArrayList<>();
 | 
	
		
			
				|  |  | +            if (Check.isNull(cpaBid) || Check.isNull(deepConversionBid)) {
 | 
	
		
			
				|  |  | +                this.checkAdvertiserList(oauthToken, projectId, date, 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)) {
 | 
	
		
			
				|  |  | +                            checkLogic("ad", detail, ocpxMap, textMap, deepMap, adObj.getString("cpa_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)) {
 | 
	
		
			
				|  |  | +                                checkLogic("ad", detail, ocpxMap, textMap, deepMap, adObj.getString("cpa_bid"),
 | 
	
		
			
				|  |  | +                                        adObj.getString("deep_cpabid"), json.getString("projectName"), adObj);
 | 
	
		
			
				|  |  | +                            }
 | 
	
		
			
				|  |  | +                        }
 | 
	
		
			
				|  |  | +                    }
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +            } else {
 | 
	
		
			
				|  |  | +                checkLogic("project", detail, ocpxMap, textMap, deepMap, cpaBid,
 | 
	
		
			
				|  |  | +                        deepConversionBid, json.getString("projectName"), new JSONObject());
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    //判断逻辑
 | 
	
		
			
				|  |  | +    private void checkLogic(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");
 | 
	
		
			
				|  |  | +        JSONObject data = new JSONObject();
 | 
	
		
			
				|  |  | +        //转化目标
 | 
	
		
			
				|  |  | +        String ocpxActionType = detail.getJSONObject("optimize_goal").getString("external_action");
 | 
	
		
			
				|  |  | +        //深度转化目标
 | 
	
		
			
				|  |  | +        String deepConversionType = detail.getJSONObject("optimize_goal").getString("deep_external_action");
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        StringBuffer msgType = new StringBuffer();
 | 
	
		
			
				|  |  | +        StringBuffer msgBid = new StringBuffer();
 | 
	
		
			
				|  |  | +        //转化目标标识
 | 
	
		
			
				|  |  | +        Boolean typeFalg = true;
 | 
	
		
			
				|  |  | +        //出价标识
 | 
	
		
			
				|  |  | +        Boolean bidFalg = true;
 | 
	
		
			
				|  |  | +        //转化目标
 | 
	
		
			
				|  |  | +        if (!Check.isNull(ocpxActionType)) {
 | 
	
		
			
				|  |  | +            if (ocpxMap.isEmpty()) {
 | 
	
		
			
				|  |  | +                typeFalg = false;
 | 
	
		
			
				|  |  | +                String msg = Check.isNull(textMap.get(ocpxActionType)) ? ocpxActionType : textMap.get(ocpxActionType);
 | 
	
		
			
				|  |  | +                msgType.append("未设转化,目标转化:").append(msg);
 | 
	
		
			
				|  |  | +            } else {
 | 
	
		
			
				|  |  | +                //转化出价
 | 
	
		
			
				|  |  | +                String ocpxBid = ocpxMap.get(ocpxActionType);
 | 
	
		
			
				|  |  | +                //通过转化目标没有查询到转化出价,判断为转化目标不一致,触发关停
 | 
	
		
			
				|  |  | +                if (Check.isNull(ocpxBid)) {
 | 
	
		
			
				|  |  | +                    typeFalg = false;
 | 
	
		
			
				|  |  | +                    String msg = Check.isNull(textMap.get(ocpxActionType)) ? ocpxActionType : textMap.get(ocpxActionType);
 | 
	
		
			
				|  |  | +                    msgType.append("已设转化:").append(ocpxMap.get("nameStr")).append("<br/>").append("目标转化:").append(msg);
 | 
	
		
			
				|  |  | +                } else {
 | 
	
		
			
				|  |  | +                    //未查询到转化出价,说明出价不一致,触发出价关停。
 | 
	
		
			
				|  |  | +                    if (Check.isNull(cpaBid)) {
 | 
	
		
			
				|  |  | +                        bidFalg = false;
 | 
	
		
			
				|  |  | +                        msgBid.append("目标出价为空");
 | 
	
		
			
				|  |  | +                    } 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(cpaBid);
 | 
	
		
			
				|  |  | +                        }
 | 
	
		
			
				|  |  | +                    }
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        //深度转化目标
 | 
	
		
			
				|  |  | +        if (typeFalg && bidFalg) {
 | 
	
		
			
				|  |  | +            if (!Check.isNull(deepConversionType) && deepMap.isEmpty()) {
 | 
	
		
			
				|  |  | +                typeFalg = false;
 | 
	
		
			
				|  |  | +                String msg = Check.isNull(textMap.get(deepConversionType)) ? deepConversionType : textMap.get(deepConversionType);
 | 
	
		
			
				|  |  | +                msgType.append("未设深度转化,目标深度转化:").append(msg);
 | 
	
		
			
				|  |  | +            } else if (!Check.isNull(deepConversionType)) {
 | 
	
		
			
				|  |  | +                String deepBid = deepMap.get(deepConversionType);
 | 
	
		
			
				|  |  | +                if (Check.isNull(deepBid)) {
 | 
	
		
			
				|  |  | +                    //通过key未获取值,说明不包含该目标,进行关停
 | 
	
		
			
				|  |  | +                    typeFalg = false;
 | 
	
		
			
				|  |  | +                    String msg = Check.isNull(textMap.get(deepConversionType)) ? deepConversionType : textMap.get(deepConversionType);
 | 
	
		
			
				|  |  | +                    msgType.append("已设深度:").append(deepMap.get("nameStr")).append("<br/>").append("目标深度:").append(msg);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +                } else {
 | 
	
		
			
				|  |  | +                    //未查询到转化出价,说明出价不一致,触发出价关停。
 | 
	
		
			
				|  |  | +                    if (Check.isNull(deepConversionBid)) {
 | 
	
		
			
				|  |  | +                        bidFalg = false;
 | 
	
		
			
				|  |  | +                        msgBid.append("目标深度出价为空");
 | 
	
		
			
				|  |  | +                    } 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(deepConversionBid);
 | 
	
		
			
				|  |  | +                        }
 | 
	
		
			
				|  |  | +                    }
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        if (!typeFalg) { // 出价方式设置非法
 | 
	
		
			
				|  |  | +            String text = getProjectBidTypeText(localProject, accountId, projectId, projectName, adObj.getLong("promotion_id"), adObj.getString("promotion_name"), msgType.toString());
 | 
	
		
			
				|  |  | +            sendMsg(accountId, projectId, text);
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        if (!bidFalg) {
 | 
	
		
			
				|  |  | +            String text = getProjectOverBidMessage(localProject, accountId, projectId, projectName, adObj.getLong("promotion_id"), adObj.getString("promotion_name"), msgBid.toString());
 | 
	
		
			
				|  |  | +            sendMsg(accountId, projectId, text);
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    private void sendMsg(Long accountId, Long projectId, String text) {
 | 
	
		
			
				|  |  | +        try {
 | 
	
		
			
				|  |  | +            MediaSendAlarmRecord record = new MediaSendAlarmRecord(accountId, "1", text);
 | 
	
		
			
				|  |  | +            record.setProjectId(projectId);
 | 
	
		
			
				|  |  | +            //关停计划
 | 
	
		
			
				|  |  | +//        String token = tokenMapper.getByAccountId(accountId);
 | 
	
		
			
				|  |  | +//        this.updProjectStatus(token, accountId, projectId, "DISABLE");
 | 
	
		
			
				|  |  | +//        log.info(">预警<,账户:{}=>计划:{}现已【关停】---> {}", accountId, projectId, text);
 | 
	
		
			
				|  |  | +            List<JSONObject> list = projectListMapper.getWChatIdsByAccountId(accountId);
 | 
	
		
			
				|  |  | +            for (JSONObject object : list) {
 | 
	
		
			
				|  |  | +                corpWexinUtils.sendMessageByWeChatId(object, text);
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +            //添加记录 ctop_media_send_alarm_record
 | 
	
		
			
				|  |  | +            projectListMapper.insertSendRecord(record);
 | 
	
		
			
				|  |  | +            //当前已发送次数
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            Integer i = projectListMapper.getrefusalAccountCounts(accountId);
 | 
	
		
			
				|  |  | +            //更新计数
 | 
	
		
			
				|  |  | +            projectListMapper.insertSendAccountId(accountId, (Check.isNull(i) ? 0 : i) + 1);
 | 
	
		
			
				|  |  | +        } catch (Exception e) {
 | 
	
		
			
				|  |  | +            e.printStackTrace();
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    //转化方式错误消息生成
 | 
	
		
			
				|  |  | +    private String getProjectBidTypeText(String projectName, Long advertiserId, Long unitId, String unit_name, Long adId, String adName, 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/>");
 | 
	
		
			
				|  |  | +        if (!Check.isNull(adId)) {
 | 
	
		
			
				|  |  | +            text.append("广告id:").append(adId).append("<br/>").append("广告名称:").append(adName).append("<br/>");
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        text.append("出价方式设置错误。").append("<br/>").append(msgType).append("<br/>").append("请您及时查看!");
 | 
	
		
			
				|  |  | +        return text.toString();
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    //出价过高预警消息生成
 | 
	
		
			
				|  |  | +    private String getProjectOverBidMessage(String projectName, Long accountId, Long planId, String planName, Long adId, String adName, 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/>");
 | 
	
		
			
				|  |  | +        if (!Check.isNull(adId)) {
 | 
	
		
			
				|  |  | +            text.append("广告id:").append(adId).append("<br/>").append("广告名称:").append(adName).append("<br/>");
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        text.append("出价设置过高。").append("<br/>").append(msgBid).append("<br/>").append("请您及时查看!");
 | 
	
		
			
				|  |  | +        return text.toString();
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  }
 |