|
@@ -1,13 +1,20 @@
|
|
package cn.com.ctop.kuaishou.modules.report.service.impl;
|
|
package cn.com.ctop.kuaishou.modules.report.service.impl;
|
|
|
|
|
|
|
|
+import cn.com.ctop.common.module.entity.CtopOauthToken;
|
|
import cn.com.ctop.common.module.mapper.UserAllocationMapper;
|
|
import cn.com.ctop.common.module.mapper.UserAllocationMapper;
|
|
|
|
+import cn.com.ctop.common.module.service.ICtopOauthTokenService;
|
|
import cn.com.ctop.common.module.service.IMessageTemplate;
|
|
import cn.com.ctop.common.module.service.IMessageTemplate;
|
|
import cn.com.ctop.common.module.service.ISendMessageService;
|
|
import cn.com.ctop.common.module.service.ISendMessageService;
|
|
import cn.com.ctop.common.module.utils.Check;
|
|
import cn.com.ctop.common.module.utils.Check;
|
|
|
|
+import cn.com.ctop.common.module.utils.HttpUtils;
|
|
|
|
+import cn.com.ctop.common.module.utils.KuaishouInterfaceConstant;
|
|
|
|
+import cn.com.ctop.common.module.utils.PropertiesUtils;
|
|
|
|
+import cn.com.ctop.kuaishou.modules.batch.service.IKuaiShouUpdateService;
|
|
import cn.com.ctop.kuaishou.modules.report.entity.KuaishouZombieCreative;
|
|
import cn.com.ctop.kuaishou.modules.report.entity.KuaishouZombieCreative;
|
|
import cn.com.ctop.kuaishou.modules.report.mapper.KuaishouReportDailyCreativeMapper;
|
|
import cn.com.ctop.kuaishou.modules.report.mapper.KuaishouReportDailyCreativeMapper;
|
|
import cn.com.ctop.kuaishou.modules.report.mapper.KuaishouZombieCreativeMapper;
|
|
import cn.com.ctop.kuaishou.modules.report.mapper.KuaishouZombieCreativeMapper;
|
|
import cn.com.ctop.kuaishou.modules.report.service.IKuaishouZombieCreativeService;
|
|
import cn.com.ctop.kuaishou.modules.report.service.IKuaishouZombieCreativeService;
|
|
|
|
+import com.alibaba.fastjson.JSONArray;
|
|
import com.alibaba.fastjson.JSONObject;
|
|
import com.alibaba.fastjson.JSONObject;
|
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|
@@ -41,6 +48,10 @@ public class KuaishouZombieCreativeServiceImpl extends ServiceImpl<KuaishouZombi
|
|
private IMessageTemplate messageTemplate;
|
|
private IMessageTemplate messageTemplate;
|
|
@Autowired
|
|
@Autowired
|
|
private UserAllocationMapper userAllocationMapper;
|
|
private UserAllocationMapper userAllocationMapper;
|
|
|
|
+ @Autowired
|
|
|
|
+ private ICtopOauthTokenService oauthTokenService;
|
|
|
|
+ @Autowired
|
|
|
|
+ private IKuaiShouUpdateService kuaiShouUpdateService;
|
|
|
|
|
|
/**
|
|
/**
|
|
* 筛选僵尸计划
|
|
* 筛选僵尸计划
|
|
@@ -48,7 +59,7 @@ public class KuaishouZombieCreativeServiceImpl extends ServiceImpl<KuaishouZombi
|
|
* 1、以当天时间为节点,往前取五天的数据,若创意消耗(花费)都为0,则获取其数据,并insert为待确认状态的僵尸创意。
|
|
* 1、以当天时间为节点,往前取五天的数据,若创意消耗(花费)都为0,则获取其数据,并insert为待确认状态的僵尸创意。
|
|
* 2、获取前一天存储的待确认僵尸计划
|
|
* 2、获取前一天存储的待确认僵尸计划
|
|
* 3、步骤二和步骤一的数据作比对筛选,若两组数据都含有该创意时,并且为了保证数据的准确性,还需调用API接口获取当天实时消耗明细,
|
|
* 3、步骤二和步骤一的数据作比对筛选,若两组数据都含有该创意时,并且为了保证数据的准确性,还需调用API接口获取当天实时消耗明细,
|
|
- * 若消耗不为0,则表明为真正的僵尸创意,3.1更新其状态;3.2同时关停创意;3.3最后发送“关停通知”消息。
|
|
|
|
|
|
+ * 若消耗不为0,则表明为真正的僵尸创意,3.1关停创意;3.2然后发送“关停通知”消息;3.3最后更新其状态。
|
|
* 4、步骤二存在,步骤一不存在说明创意已经活跃,更新其状态为“2”已活跃、反之则是新的待确认僵尸创意,作insert操作
|
|
* 4、步骤二存在,步骤一不存在说明创意已经活跃,更新其状态为“2”已活跃、反之则是新的待确认僵尸创意,作insert操作
|
|
* 5、insert操作时,考虑到数据重复的问题,需先查询全部僵尸计划,作筛选比对,已有则更新,否则就新增。
|
|
* 5、insert操作时,考虑到数据重复的问题,需先查询全部僵尸计划,作筛选比对,已有则更新,否则就新增。
|
|
* **凡insert数据皆为状态0,待确认僵尸创意,且要发送“提醒通知”。
|
|
* **凡insert数据皆为状态0,待确认僵尸创意,且要发送“提醒通知”。
|
|
@@ -82,14 +93,24 @@ public class KuaishouZombieCreativeServiceImpl extends ServiceImpl<KuaishouZombi
|
|
if (zombie.getAccountId() - obj.getInteger("accountId") == 0 && zombie.getCreativeId() - obj.getInteger("creativeId") == 0) {
|
|
if (zombie.getAccountId() - obj.getInteger("accountId") == 0 && zombie.getCreativeId() - obj.getInteger("creativeId") == 0) {
|
|
QueryWrapper<KuaishouZombieCreative> wrapper = new QueryWrapper<>();
|
|
QueryWrapper<KuaishouZombieCreative> wrapper = new QueryWrapper<>();
|
|
wrapper.eq("id", zombie.getId());
|
|
wrapper.eq("id", zombie.getId());
|
|
- zombie.setStatus(NoEn.NO1.valueStr());
|
|
|
|
- //3.1更新状态
|
|
|
|
|
|
+ CtopOauthToken token = oauthTokenService.getTokenByAccountId(zombie.getAccountId());
|
|
|
|
+ //校验当天是不是依旧不活跃,是则关停,否则更新激活状态
|
|
|
|
+ if (isActivation(token, zombie.getCreativeId())) {
|
|
|
|
+ //3.1关停创意
|
|
|
|
+ Map<String, Object> updateMap = kuaiShouUpdateService.updateCreativeStatus(token.getAccessToken(), zombie.getAccountId(), zombie.getCreativeId(), NoEn.NO2.valueInt(), obj.getString("userId"));
|
|
|
|
+ if (!Check.isNull(updateMap) && (boolean) updateMap.get("success")) {
|
|
|
|
+ //3.2发送创意关停通知
|
|
|
|
+ sendMsg(NoEn.NO2.valueStr(), obj);
|
|
|
|
+ }
|
|
|
|
+ zombie.setStatus(NoEn.NO1.valueStr());
|
|
|
|
+ //记录已确认的僵尸计划集
|
|
|
|
+ zombiePlans.add(zombie);
|
|
|
|
+ zombieList.add(obj);
|
|
|
|
+ } else {
|
|
|
|
+ zombie.setStatus(NoEn.NO2.valueStr());
|
|
|
|
+ }
|
|
|
|
+ //3.3更新状态
|
|
KuaishouZombieCreativeMapper.update(zombie, wrapper);
|
|
KuaishouZombieCreativeMapper.update(zombie, wrapper);
|
|
- //已确认的僵尸计划集
|
|
|
|
- zombiePlans.add(zombie);
|
|
|
|
- zombieList.add(obj);
|
|
|
|
- //TODO 3.3发送创意关停通知
|
|
|
|
- sendMsg(NoEn.NO1.valueStr(), obj.getLong("accountId"), obj.getString("creativeName"));
|
|
|
|
}
|
|
}
|
|
});
|
|
});
|
|
});
|
|
});
|
|
@@ -165,14 +186,13 @@ public class KuaishouZombieCreativeServiceImpl extends ServiceImpl<KuaishouZombi
|
|
list.forEach(obj -> {
|
|
list.forEach(obj -> {
|
|
KuaishouZombieCreative create = new KuaishouZombieCreative();
|
|
KuaishouZombieCreative create = new KuaishouZombieCreative();
|
|
create.setAccountId(obj.getLong("accountId"));
|
|
create.setAccountId(obj.getLong("accountId"));
|
|
- create.setCreativeId(obj.getInteger("creativeId"));
|
|
|
|
|
|
+ create.setCreativeId(obj.getLong("creativeId"));
|
|
create.setCreativeName(obj.getString("creativeName"));
|
|
create.setCreativeName(obj.getString("creativeName"));
|
|
create.setRecordTime(DateUtils.getNowDate(DateUtils.WEB_FORMAT));
|
|
create.setRecordTime(DateUtils.getNowDate(DateUtils.WEB_FORMAT));
|
|
//状态 0-待确认,1-是僵尸计划,2-已活跃,不是僵尸计划
|
|
//状态 0-待确认,1-是僵尸计划,2-已活跃,不是僵尸计划
|
|
create.setStatus(NoEn.NO0.valueStr());
|
|
create.setStatus(NoEn.NO0.valueStr());
|
|
KuaishouZombieCreativeMapper.insert(create);
|
|
KuaishouZombieCreativeMapper.insert(create);
|
|
- //TODO 发送待确认通知
|
|
|
|
- sendMsg(NoEn.NO1.valueStr(), obj.getLong("accountId"), obj.getString("creativeName"));
|
|
|
|
|
|
+ sendMsg(NoEn.NO1.valueStr(), obj);
|
|
});
|
|
});
|
|
}
|
|
}
|
|
|
|
|
|
@@ -184,16 +204,76 @@ public class KuaishouZombieCreativeServiceImpl extends ServiceImpl<KuaishouZombi
|
|
* @throws
|
|
* @throws
|
|
* @author ZHAOXA
|
|
* @author ZHAOXA
|
|
*/
|
|
*/
|
|
- private void sendMsg(String type, long accountId, String creativeName) {
|
|
|
|
- String userId = userAllocationMapper.queryUserIdByAccountId(accountId);
|
|
|
|
|
|
+ private void sendMsg(String type, JSONObject obj) {
|
|
|
|
+ String userId = userAllocationMapper.queryUserIdByAccountId(obj.getLong("accountId"));
|
|
String message = "";
|
|
String message = "";
|
|
if (NoEn.NO1.valueStr().equals(type)) {
|
|
if (NoEn.NO1.valueStr().equals(type)) {
|
|
//提醒通知
|
|
//提醒通知
|
|
- message = messageTemplate.getZombieCreativeRemindTemplate(accountId, creativeName);
|
|
|
|
|
|
+ message = messageTemplate.getZombieCreativeRemindTemplate(obj);
|
|
} else {
|
|
} else {
|
|
//关停通知
|
|
//关停通知
|
|
- message = messageTemplate.getZombieCreativeRemindTemplate(accountId, creativeName);
|
|
|
|
|
|
+ message = messageTemplate.getZombieCreativeShutDownTemplate(obj);
|
|
}
|
|
}
|
|
sendMessageService.sendMessage(userId, message);
|
|
sendMessageService.sendMessage(userId, message);
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 检查创意是否激活
|
|
|
|
+ *
|
|
|
|
+ * @param
|
|
|
|
+ * @return boolean
|
|
|
|
+ * @throws
|
|
|
|
+ * @author ZHAOXA
|
|
|
|
+ */
|
|
|
|
+ private boolean isActivation(CtopOauthToken oauthToken, long creativeId) {
|
|
|
|
+ boolean flag = true;
|
|
|
|
+ try {
|
|
|
|
+ JSONArray creativeIds = new JSONArray();
|
|
|
|
+ creativeIds.add(creativeId);
|
|
|
|
+ JSONObject info = getAdvertiserCreativeReportDailyInfo(oauthToken, new Date(), new Date(), creativeIds);
|
|
|
|
+ if (!Check.isNull(info) && !Check.isNull(info.getBigDecimal("charge"))) {
|
|
|
|
+ flag = false;
|
|
|
|
+ }
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
+ log.error("校验创意是否激活,异常", e);
|
|
|
|
+ //异常时,默认为激活状态
|
|
|
|
+ flag = false;
|
|
|
|
+ }
|
|
|
|
+ return flag;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private JSONObject getAdvertiserCreativeReportDailyInfo(CtopOauthToken token, Date startDate, Date endDate, JSONArray creativeIds) throws Exception {
|
|
|
|
+ String url = PropertiesUtils.getConfig("kuaishou_api_url") + KuaishouInterfaceConstant.CREATIVE_REPORT;
|
|
|
|
+ Map<String, String> headers = new HashMap<String, String>();
|
|
|
|
+ headers.put("Content-Type", "application/json");
|
|
|
|
+ headers.put("Access-Token", token.getAccessToken());
|
|
|
|
+ Map<String, Object> param = new HashMap<String, Object>();
|
|
|
|
+ if (!Check.isNull(startDate)) {
|
|
|
|
+ param.put("start_date", DateUtils.formatDate(startDate));
|
|
|
|
+ }
|
|
|
|
+ if (!Check.isNull(endDate)) {
|
|
|
|
+ param.put("end_date", DateUtils.formatDate(endDate));
|
|
|
|
+ }
|
|
|
|
+ if (!Check.isNull(creativeIds) && creativeIds.size() > 0) {
|
|
|
|
+ param.put("creative_ids", creativeIds);
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+ param.put("advertiser_id", token.getAccountId());
|
|
|
|
+ param.put("temporal_granularity", "DAILY");
|
|
|
|
+
|
|
|
|
+ String result = HttpUtils.httpPostRequest(url, param, headers);
|
|
|
|
+ JSONObject resultJson = JSONObject.parseObject(result);
|
|
|
|
+ Integer code = resultJson.getInteger("code");
|
|
|
|
+ String message = resultJson.getString("message");
|
|
|
|
+ if (null == code || code != 0) {
|
|
|
|
+ throw new Exception("获取快手广告创意分天报表异常:" + message + ",accountId:" + token.getAccountId());
|
|
|
|
+ }
|
|
|
|
+ JSONArray details = resultJson.getJSONObject("data").getJSONArray("details");
|
|
|
|
+ if (null == details || details.size() <= 0) {
|
|
|
|
+ return null;
|
|
|
|
+ }
|
|
|
|
+ return (JSONObject) details.get(0);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
}
|
|
}
|