|
|
@@ -0,0 +1,276 @@
|
|
|
+package com.fs.app.facade;
|
|
|
+
|
|
|
+import cn.hutool.core.util.ObjectUtil;
|
|
|
+import cn.hutool.core.util.StrUtil;
|
|
|
+import cn.hutool.json.JSONArray;
|
|
|
+import cn.hutool.json.JSONObject;
|
|
|
+import cn.hutool.json.JSONUtil;
|
|
|
+import com.fs.newAdv.integration.adapter.IAdvertiserAdapter;
|
|
|
+import com.fs.newAdv.integration.factory.AdvertiserHandlerFactory;
|
|
|
+import com.fs.common.exception.base.BusinessException;
|
|
|
+import com.fs.common.utils.RedisUtil;
|
|
|
+import com.fs.newAdv.domain.LandingPageTemplate;
|
|
|
+import com.fs.newAdv.domain.Lead;
|
|
|
+import com.fs.newAdv.domain.Site;
|
|
|
+import com.fs.newAdv.dto.req.WeChatLandingIndexReq;
|
|
|
+import com.fs.newAdv.dto.res.LandingIndexRes;
|
|
|
+import com.fs.newAdv.enums.AdvertiserTypeEnum;
|
|
|
+import com.fs.newAdv.service.ILandingPageTemplateService;
|
|
|
+import com.fs.newAdv.service.ILeadService;
|
|
|
+import com.fs.newAdv.service.ISiteService;
|
|
|
+import com.fs.qw.domain.QwAssignRule;
|
|
|
+import com.fs.qw.domain.QwAssignRuleUser;
|
|
|
+import com.fs.qw.domain.QwContactWay;
|
|
|
+import com.fs.qw.domain.QwGroupActual;
|
|
|
+import com.fs.qw.service.IQwAssignRuleService;
|
|
|
+import com.fs.qw.service.IQwAssignRuleUserService;
|
|
|
+import com.fs.qw.service.IQwContactWayService;
|
|
|
+import com.fs.qw.service.IQwGroupActualService;
|
|
|
+import com.fs.qwApi.Result.QwAddContactWayResult;
|
|
|
+import com.fs.qwApi.param.QwAddContactWayParam;
|
|
|
+import com.fs.qwApi.service.QwApiService;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
+import org.springframework.transaction.annotation.Transactional;
|
|
|
+
|
|
|
+import java.time.LocalDateTime;
|
|
|
+import java.util.*;
|
|
|
+import java.util.concurrent.TimeUnit;
|
|
|
+import java.util.concurrent.atomic.AtomicReference;
|
|
|
+
|
|
|
+@Service
|
|
|
+@Slf4j
|
|
|
+public class CallbackProcessingFacadeServiceImpl implements CallbackProcessingFacadeService {
|
|
|
+ @Autowired
|
|
|
+ private AdvertiserHandlerFactory handlerFactory;
|
|
|
+ @Autowired
|
|
|
+ private ILeadService leadService;
|
|
|
+ @Autowired
|
|
|
+ private ISiteService siteService;
|
|
|
+ @Autowired
|
|
|
+ private IQwAssignRuleUserService assignRuleUserService;
|
|
|
+ @Autowired
|
|
|
+ private IQwAssignRuleService assignRuleService;
|
|
|
+ @Autowired
|
|
|
+ private ILandingPageTemplateService landingPageTemplateService;
|
|
|
+ @Autowired
|
|
|
+ private IQwGroupActualService actualService;
|
|
|
+ @Autowired
|
|
|
+ private QwApiService qwApiService;
|
|
|
+ @Autowired
|
|
|
+ private IQwContactWayService contactWayService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private RedisUtil redisUtil;
|
|
|
+
|
|
|
+ private static final String TEMPLATE_DATA = "new-adv:template-data:";
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void saveClickTrace(Long advertiserCode, Map<String, String> allParams) {
|
|
|
+ IAdvertiserAdapter advertiserAdapter = handlerFactory.getAdapter(AdvertiserTypeEnum.getByCode(advertiserCode));
|
|
|
+ Lead lead = advertiserAdapter.adaptCallbackData(allParams);
|
|
|
+ Lead byTraceId = leadService.getByTraceId(lead.getTraceId());
|
|
|
+ if (ObjectUtil.isNotEmpty(byTraceId)) {
|
|
|
+ throw new BusinessException("监测信息已存在: " + lead.getTraceId());
|
|
|
+ }
|
|
|
+ lead.setStatus(0);
|
|
|
+ lead.setClickTrigger(1);
|
|
|
+ lead.setTraceRawParams(JSONUtil.toJsonStr(allParams));
|
|
|
+ boolean saved = leadService.save(lead);
|
|
|
+ if (!saved) {
|
|
|
+ log.error("线索保存失败:{}", lead);
|
|
|
+ throw new RuntimeException("线索保存失败");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private String getTraceIdByAdvertiser(AdvertiserTypeEnum byCode, Map<String, String> allParams) {
|
|
|
+ String traceId;
|
|
|
+ switch (byCode) {
|
|
|
+ case OCEANENGINE:
|
|
|
+ case TENCENT:
|
|
|
+ case OPPO:
|
|
|
+ traceId = allParams.get("click_id");
|
|
|
+ break;
|
|
|
+ case BAIDU:
|
|
|
+ traceId = allParams.get("bd_vid");
|
|
|
+ break;
|
|
|
+ case VIVO:
|
|
|
+ traceId = allParams.get("requestId");
|
|
|
+ break;
|
|
|
+ case IQIYI:
|
|
|
+ traceId = allParams.get("traceId");
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ traceId = "ylrz_test";
|
|
|
+ }
|
|
|
+ if (StrUtil.isEmpty(traceId)) {
|
|
|
+ traceId = "ylrz_test";
|
|
|
+ }
|
|
|
+
|
|
|
+ return traceId;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
+ public LandingIndexRes getLandingIndexBySiteId(Map<String, String> allParams) {
|
|
|
+ // 站点信息
|
|
|
+ String paramsSiteId = allParams.get("siteId");
|
|
|
+ if (ObjectUtil.isEmpty(paramsSiteId)) {
|
|
|
+ log.info("站点id不存在:{}", paramsSiteId);
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ Long siteId = Long.valueOf(paramsSiteId);
|
|
|
+ Site byId = siteService.getById(siteId);
|
|
|
+ if (ObjectUtil.isEmpty(byId)) {
|
|
|
+ log.info("站点信息不存在:{}", siteId);
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ // 广告商信息
|
|
|
+ Long advertiserId = byId.getAdvertiserId();
|
|
|
+ // 访问链路id
|
|
|
+ String traceId = getTraceIdByAdvertiser(Objects.requireNonNull(AdvertiserTypeEnum.getByCode(advertiserId)), allParams);
|
|
|
+ // 线索信息
|
|
|
+ Lead byTraceId = leadService.getByTraceId(traceId);
|
|
|
+ boolean isNewLead = ObjectUtil.isEmpty(byTraceId);
|
|
|
+ if (isNewLead) {
|
|
|
+ byTraceId = new Lead();
|
|
|
+ byTraceId.setAdvertiserId(advertiserId);
|
|
|
+ byTraceId.setSiteId(siteId);
|
|
|
+ byTraceId.setTraceId(traceId);
|
|
|
+ } else {
|
|
|
+ // 检查站点和广告商信息是否异常
|
|
|
+ if (!Objects.equals(byTraceId.getSiteId(), siteId)) {
|
|
|
+ log.info("落地页站点信息异常:{}---{}", byTraceId.getSiteId(), siteId);
|
|
|
+ }
|
|
|
+ if (!Objects.equals(byTraceId.getAdvertiserId(), advertiserId)) {
|
|
|
+ log.info("落地页广告商信息异常:{}---{}", byTraceId.getAdvertiserId(), advertiserId);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 模板缓存
|
|
|
+ Object ca = redisUtil.get(TEMPLATE_DATA + traceId);
|
|
|
+ String templateData;
|
|
|
+ if (ca != null) {
|
|
|
+ templateData = String.valueOf(ca);
|
|
|
+ } else {
|
|
|
+ // 查询模板数据
|
|
|
+ LandingPageTemplate landingPageTemplate = landingPageTemplateService.getById(byId.getLaunchPageId());
|
|
|
+ JSONObject jsonObject = JSONUtil.parseObj(landingPageTemplate.getTemplateData());
|
|
|
+ // 替换二维码链接
|
|
|
+ updateQrCodeInTemplate(jsonObject, traceId, byId, byTraceId);
|
|
|
+ templateData = JSONUtil.toJsonStr(jsonObject);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ // 保存或更新 线索信息
|
|
|
+ LocalDateTime now = LocalDateTime.now();
|
|
|
+ byTraceId.setLandingPageRawParams(JSONUtil.toJsonStr(allParams));
|
|
|
+ byTraceId.setLandingPageTrigger(1);
|
|
|
+ byTraceId.setLandingPageTs(now);
|
|
|
+ byTraceId.setUpdateTime(now);
|
|
|
+ if (isNewLead) {
|
|
|
+ leadService.save(byTraceId);
|
|
|
+ } else {
|
|
|
+ leadService.updateById(byTraceId);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 封装返回结果
|
|
|
+ LandingIndexRes res = new LandingIndexRes();
|
|
|
+ redisUtil.set(TEMPLATE_DATA + traceId, templateData, 24, TimeUnit.HOURS);
|
|
|
+ res.setTemplateData(templateData);
|
|
|
+ res.setTraceId(byTraceId.getTraceId());
|
|
|
+ return res;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 更新模板中的二维码信息
|
|
|
+ */
|
|
|
+ private void updateQrCodeInTemplate(JSONObject templateData, String traceId, Site site, Lead lead) {
|
|
|
+ JSONArray configList = templateData.getJSONArray("configList");
|
|
|
+ if (configList == null || configList.isEmpty()) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ AtomicReference<String> qrCode = new AtomicReference<>("");
|
|
|
+ configList.stream()
|
|
|
+ .map(config -> (JSONObject) config)
|
|
|
+ .map(config -> config.getJSONArray("moduleList"))
|
|
|
+ .filter(ObjectUtil::isNotEmpty)
|
|
|
+ .flatMap(Collection::stream)
|
|
|
+ .map(module -> (JSONObject) module)
|
|
|
+ .filter(module -> "h5-qrcode".equals(module.getStr("type")))
|
|
|
+ .forEach(module -> {
|
|
|
+ if (StrUtil.isEmpty(qrCode.get())) {
|
|
|
+ qrCode.set(getQrCodeByAllocationRuleId(site.getLaunchType(), site.getAllocationRule(), site.getAllocationRuleId(), lead));
|
|
|
+ }
|
|
|
+ module.set("workUrl", qrCode.get());
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ private String getQrCodeByAllocationRuleId(Integer launchType,
|
|
|
+ Integer allocationRule,
|
|
|
+ Long allocationRuleId,
|
|
|
+ Lead byTraceId) {
|
|
|
+ // 二维码
|
|
|
+ String qrCode = "";
|
|
|
+ if (allocationRule == 1) {
|
|
|
+ // 个人分配规则
|
|
|
+ QwAssignRule byId1 = assignRuleService.getById(allocationRuleId);
|
|
|
+ QwAssignRuleUser qwAssignRuleUser = assignRuleUserService.getUserByAllocationRuleId(allocationRuleId, byId1.getAssignType());
|
|
|
+ byTraceId.setQwAssignRuleUserId(qwAssignRuleUser.getId());
|
|
|
+ if (byId1.getAssignType().equals(3)) {
|
|
|
+ List<String> users = Collections.singletonList(qwAssignRuleUser.getQwUserId());
|
|
|
+ QwAddContactWayParam qwAddContactWayParam = new QwAddContactWayParam();
|
|
|
+ qwAddContactWayParam.setType(1);
|
|
|
+ qwAddContactWayParam.setScene(2);
|
|
|
+ qwAddContactWayParam.setUser(users);
|
|
|
+ qwAddContactWayParam.setSkip_verify(true);
|
|
|
+ QwAddContactWayResult qwAddContactWayResult = qwApiService.addContactWay(qwAddContactWayParam, qwAssignRuleUser.getCorpId());
|
|
|
+ qrCode = qwAddContactWayResult.getQr_code();
|
|
|
+ }
|
|
|
+ } else if (allocationRule == 2) {
|
|
|
+ // 活码分配规则
|
|
|
+ if (launchType.equals(1)) {
|
|
|
+ // 线上规则--群活码
|
|
|
+ QwGroupActual qwGroupActual = actualService.getGroupActualByAllocationRuleId(allocationRuleId);
|
|
|
+ byTraceId.setQwGroupActualId(qwGroupActual.getId());
|
|
|
+ byTraceId.setQwGroupLiveCodeId(qwGroupActual.getLiveCodeId());
|
|
|
+ qrCode = qwGroupActual.getGroupUrl();
|
|
|
+ } else if (launchType.equals(2)) {
|
|
|
+ // 线下规则--个人活码
|
|
|
+ QwContactWay qwContactWay = contactWayService.selectQwContactWayById(allocationRuleId);
|
|
|
+ byTraceId.setQwContactWayId(qwContactWay.getId());
|
|
|
+ qrCode = qwContactWay.getQrCode();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ log.info("落地页广告获取二维码: {}", qrCode);
|
|
|
+ return qrCode;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void gdtGetAuthCode(Integer code, Long state) {
|
|
|
+ /* if (code == null || state == null) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ PromotionAccount byId = promotionAccountService.getById(state);
|
|
|
+ if (byId == null) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ IApiClient apiClient = handlerFactory.getApiClient(AdvertiserTypeEnum.TENCENT);
|
|
|
+ if (apiClient instanceof IAccessTokenClient) {
|
|
|
+ IAccessTokenClient tokenClient = (IAccessTokenClient) apiClient;
|
|
|
+ Map<String, String> accessToken = tokenClient.getAccessToken(code, byId.getAppId(), byId.getAppSecret(), byId.getCallbackUrl());
|
|
|
+ byId.setAccessToken(accessToken.get("access_token"));
|
|
|
+ byId.setRefreshToken(accessToken.get("refresh_token"));
|
|
|
+ }*/
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public LandingIndexRes getWxLandingIndexBySiteId(WeChatLandingIndexReq req) {
|
|
|
+ // 更新授权页访问信息记录
|
|
|
+ leadService.updateAuthIndex(req.getTraceId(),req.getType());
|
|
|
+ String templateData = String.valueOf(redisUtil.get(TEMPLATE_DATA + req.getTraceId()));
|
|
|
+ LandingIndexRes landingIndexRes = new LandingIndexRes();
|
|
|
+ landingIndexRes.setTemplateData(templateData);
|
|
|
+ return landingIndexRes;
|
|
|
+ }
|
|
|
+}
|