|
@@ -0,0 +1,153 @@
|
|
|
|
|
+package cn.com.ctop.job.bytedance.data.service.impl;
|
|
|
|
|
+
|
|
|
|
|
+import cn.com.ctop.job.bytedance.data.entity.BytedanceErrorLog;
|
|
|
|
|
+import cn.com.ctop.job.bytedance.data.mapper.BytedanceMiniAppMapper;
|
|
|
|
|
+import cn.com.ctop.job.bytedance.data.mapper.BytedancePromoterReportMapper;
|
|
|
|
|
+import cn.com.ctop.job.bytedance.data.service.IBytedanceMiniAppService;
|
|
|
|
|
+import cn.com.ctop.job.bytedance.data.utils.Check;
|
|
|
|
|
+import cn.com.ctop.job.bytedance.data.utils.DateUtils;
|
|
|
|
|
+import cn.com.ctop.job.bytedance.data.utils.HttpUtils;
|
|
|
|
|
+import com.alibaba.fastjson.JSONArray;
|
|
|
|
|
+import com.alibaba.fastjson.JSONObject;
|
|
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
|
|
+import org.springframework.data.redis.core.RedisTemplate;
|
|
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
|
|
+
|
|
|
|
|
+import javax.annotation.Resource;
|
|
|
|
|
+import java.util.HashMap;
|
|
|
|
|
+import java.util.List;
|
|
|
|
|
+import java.util.Map;
|
|
|
|
|
+
|
|
|
|
|
+@Service
|
|
|
|
|
+@Slf4j
|
|
|
|
|
+public class BytedanceMiniAppServiceImpl implements IBytedanceMiniAppService {
|
|
|
|
|
+ @Resource
|
|
|
|
|
+ private RedisTemplate redis2Template_db5;
|
|
|
|
|
+
|
|
|
|
|
+ @Autowired
|
|
|
|
|
+ private BytedanceMiniAppMapper bytedanceMiniAppMapper;
|
|
|
|
|
+
|
|
|
|
|
+ @Autowired
|
|
|
|
|
+ private BytedancePromoterReportMapper promoterReportMapper;
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public List<String> getIaaAppIds() {
|
|
|
|
|
+ return bytedanceMiniAppMapper.getIaaAppIds();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public List<JSONObject> getMaEcpmRetryJob() {
|
|
|
|
|
+ return bytedanceMiniAppMapper.getMaEcpmRetryJob();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public void getMaEcpm(String startDt, String endDt, String appId, Integer isLog, Long errId, Integer isSend) {
|
|
|
|
|
+ try {
|
|
|
|
|
+ Long dataRangeSeconds = 3600L;
|
|
|
|
|
+ String startTime = startDt + (startDt.contains(" ") ? "" : " 00:00:00");
|
|
|
|
|
+ Long startT = DateUtils.getTimestampFormat("yyyy-MM-dd HH:mm:ss", startTime);
|
|
|
|
|
+ String endTime = endDt + (endDt.contains(" ") ? "" : " 23:59:59");
|
|
|
|
|
+ Long endT = DateUtils.getTimestampFormat("yyyy-MM-dd HH:mm:ss", endTime) + 1;
|
|
|
|
|
+ boolean hasMoreTime = true;
|
|
|
|
|
+ while (hasMoreTime) {
|
|
|
|
|
+ Long thisEndT = startT + dataRangeSeconds;
|
|
|
|
|
+ if (thisEndT >= endT) {
|
|
|
|
|
+ thisEndT = endT;
|
|
|
|
|
+ }
|
|
|
|
|
+ String endEventTime = DateUtils.formatTimestamp("yyyy-MM-dd HH:mm:ss", thisEndT);
|
|
|
|
|
+ Integer endEventDate = Integer.parseInt(DateUtils.formatTimestamp("yyyyMMdd", thisEndT));
|
|
|
|
|
+ String startEventTime = DateUtils.formatTimestamp("yyyy-MM-dd HH:mm:ss", startT);
|
|
|
|
|
+ Integer startEventDate = Integer.parseInt(DateUtils.formatTimestamp("yyyyMMdd", startT));
|
|
|
|
|
+ List<String> ecpmKeys = bytedanceMiniAppMapper.getEcpmKeys(startEventDate, endEventDate, startEventTime, endEventTime);
|
|
|
|
|
+ String nextCursor = null;
|
|
|
|
|
+ boolean hasMore = true;
|
|
|
|
|
+ while (hasMore) {
|
|
|
|
|
+ log.info("抖小ma_ecpm拉取 [{}] {}~{} {}", appId, startEventTime, endEventTime, nextCursor);
|
|
|
|
|
+ String url = "https://open.douyin.com/api/traffic/v2/rt_ecpm/query/";
|
|
|
|
|
+ Object tokenObj = redis2Template_db5.opsForValue().get("client-token-key_" + appId);
|
|
|
|
|
+ if (tokenObj == null) {
|
|
|
|
|
+ log.error("抖小ma_ecpm拉取获取token为空 [{}] {}~{} {}", appId, startEventTime, endEventTime, nextCursor);
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ Map<String, Object> params = new JSONObject();
|
|
|
|
|
+ params.put("start_date", startEventTime);
|
|
|
|
|
+ params.put("end_date", endEventTime);
|
|
|
|
|
+ params.put("page_size", 500);
|
|
|
|
|
+ if (nextCursor != null) {
|
|
|
|
|
+ params.put("cursor", nextCursor);
|
|
|
|
|
+ }
|
|
|
|
|
+ HashMap<String, String> headers = new HashMap<>();
|
|
|
|
|
+ headers.put("access-token", tokenObj.toString());
|
|
|
|
|
+ headers.put("Content-Type", "application/json; charset=UTF-8");
|
|
|
|
|
+
|
|
|
|
|
+ String s = HttpUtils.httpPostRequest(url, params, headers);
|
|
|
|
|
+ JSONObject jsonObject = JSONObject.parseObject(s);
|
|
|
|
|
+ JSONArray content = new JSONArray();
|
|
|
|
|
+ if (!Check.isNull(jsonObject)) {
|
|
|
|
|
+ Integer code = jsonObject.getInteger("err_no");
|
|
|
|
|
+ if (code == 0) {
|
|
|
|
|
+ JSONObject data = jsonObject.getJSONObject("data");
|
|
|
|
|
+
|
|
|
|
|
+ nextCursor = data.getString("next_cursor");
|
|
|
|
|
+ JSONArray result = data.getJSONArray("records");
|
|
|
|
|
+ if (!Check.isNull(result)) {
|
|
|
|
|
+ for (int i = 0; i < result.size(); i++) {
|
|
|
|
|
+ JSONObject resultJson = result.getJSONObject(i);
|
|
|
|
|
+ String eventTime = resultJson.getString("event_time");
|
|
|
|
|
+ String openId = resultJson.getString("open_id");
|
|
|
|
|
+ String cost = resultJson.getString("cost");
|
|
|
|
|
+ if (ecpmKeys.contains(eventTime + openId + cost)) {
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+ content.add(resultJson);
|
|
|
|
|
+ }
|
|
|
|
|
+ } else {
|
|
|
|
|
+ hasMore = false;
|
|
|
|
|
+ }
|
|
|
|
|
+ } else {
|
|
|
|
|
+ log.error("[{}]抖小ma_ecpm拉取失败{}~{},返回信息:{}", appId, startEventTime, endEventTime, s);
|
|
|
|
|
+ insertErrorLog(isLog, startEventTime, endTime, "ma_ecpm:" + appId, "daily", s);
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ } else {
|
|
|
|
|
+ log.error("[{}]抖小ma_ecpm拉取返回数据为空{}~{}", appId, startEventTime, endEventTime);
|
|
|
|
|
+ insertErrorLog(isLog, startEventTime, endTime, "ma_ecpm:" + appId, "daily", "数据返回空");
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (!content.isEmpty()) {
|
|
|
|
|
+ String pushUrl = "https://push.artlinkworld.cn/bytedance/push/miniapp/webhook";
|
|
|
|
|
+ JSONObject pushParam = new JSONObject();
|
|
|
|
|
+ pushParam.put("content", content.toJSONString());
|
|
|
|
|
+ pushParam.put("client_key", appId);
|
|
|
|
|
+ pushParam.put("event", "ma_ecpm");
|
|
|
|
|
+ HttpUtils.httpPostRequest(pushUrl, pushParam, null);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ hasMoreTime = thisEndT < endT;
|
|
|
|
|
+ startT = thisEndT;
|
|
|
|
|
+ if (errId != null) {
|
|
|
|
|
+ promoterReportMapper.deleteInfoByErrorId(errId);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ log.info("[{}]抖小ma_ecpm拉取完成{}~{}.", appId, startDt, endDt);
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
|
+ e.printStackTrace();
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private void insertErrorLog(Integer isLog, String startDate, String endDate, String dataDimension, String dataType, String msg) {
|
|
|
|
|
+ if (isLog != null && 1 == isLog) {
|
|
|
|
|
+ BytedanceErrorLog errorInfo = new BytedanceErrorLog();
|
|
|
|
|
+ errorInfo.setAdvertiserId(-1L);
|
|
|
|
|
+ errorInfo.setStartDate(startDate);
|
|
|
|
|
+ errorInfo.setEndDate(endDate);
|
|
|
|
|
+ errorInfo.setDataDimension(dataDimension);
|
|
|
|
|
+ errorInfo.setDataType(dataType);
|
|
|
|
|
+ errorInfo.setMsg(msg);
|
|
|
|
|
+ promoterReportMapper.replaceErrorInfo(errorInfo);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+}
|