Procházet zdrojové kódy

coding:微信配置

zhangqin před 20 hodinami
rodič
revize
f6c30279f5

+ 1 - 1
fs-ad-new-api/src/main/java/com/fs/app/controller/CallbackController.java

@@ -111,7 +111,7 @@ public class CallbackController {
         IAccessTokenClient tokenClient = (IAccessTokenClient) apiClient;
         AccessTokenVo accessToken = tokenClient.getAccessTokenByAuthCode(AccessTokenByAuthCodeVo
                 .builder()
-                .userId(byId.getAdAccountId())
+                .adAccountId(byId.getAdAccountId())
                 .appId(byId.getAppId())
                 .authCode(authCode)
                 .appSecret(byId.getAppSecret())

+ 47 - 27
fs-ad-new-api/src/main/java/com/fs/app/controller/WeChatController.java

@@ -4,9 +4,12 @@ import cn.hutool.http.HttpRequest;
 import cn.hutool.http.HttpResponse;
 import cn.hutool.json.JSONUtil;
 import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.fs.app.facade.CallbackProcessingFacadeService;
 import com.fs.common.constant.SystemConstant;
 import com.fs.common.result.Result;
+import com.fs.newAdv.domain.AdvMiniConfig;
+import com.fs.newAdv.service.IAdvMiniConfigService;
 import com.fs.wx.miniapp.config.WxMaProperties;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -15,7 +18,9 @@ import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.RestController;
 
+import java.time.LocalDateTime;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 
 /**
@@ -34,34 +39,49 @@ public class WeChatController {
     @Autowired
     private WxMaProperties properties;
 
+    @Autowired
+    private IAdvMiniConfigService advMiniConfigService;
+
     @GetMapping("/getSchemeUrl")
     public Result<String> getSchemeUrl(@RequestParam(value = "traceId") String traceId) {
-        String appId = "wx0447a16ef6199f03";
-        String secret = "f063fcd818e31d4c89013a67f5123990";
-        HttpResponse execute2 = HttpRequest.get("https://api.weixin.qq.com/cgi-bin/token")
-                .form("grant_type", "client_credential")
-                .form("appid", appId)
-                .form("secret", secret)
-                .timeout(SystemConstant.API_TIMEOUT)
-                .execute();
-        JSONObject obj = JSONObject.parseObject(execute2.body());
-        String access_token = obj.getString("access_token");
-
-        Map<String, Object> map = new HashMap<>();
-        Map<String, Object> map2 = new HashMap<>();
-        map2.put("path", "/pages/shopping/productDetails");
-        map2.put("query", "traceId=" + traceId);
-        //map2.put("env_version", "trial");
-        map.put("jump_wxa", map2);
-        map.put("is_expire", false);
-        HttpResponse execute = HttpRequest.post("https://api.weixin.qq.com/wxa/generatescheme?access_token=" + access_token)
-                .header("Content-Type", "application/json")
-                .body(JSONUtil.toJsonStr(map))
-                .timeout(SystemConstant.API_TIMEOUT)
-                .execute();
-        log.info("getSchemeUrl:{}", execute.body());
-        obj = JSONObject.parseObject(execute.body());
-        //response.addHeader("Access-Control-Allow-Origin", "*");
-        return Result.success(obj.getString("openlink"));
+        List<AdvMiniConfig> list = advMiniConfigService.list(new LambdaQueryWrapper<AdvMiniConfig>()
+                .eq(AdvMiniConfig::getStatus, 1));
+        for (AdvMiniConfig advMiniConfig : list) {
+            try {
+                String access_token = advMiniConfig.getAccessToken();
+                // 判断token是否过期
+                if (advMiniConfig.getExpiresIn().isBefore(LocalDateTime.now().plusMinutes(10))) {
+                    HttpResponse execute2 = HttpRequest.get("https://api.weixin.qq.com/cgi-bin/token")
+                            .form("grant_type", "client_credential")
+                            .form("appid", advMiniConfig.getAppId())
+                            .form("secret", advMiniConfig.getAppSecret())
+                            .timeout(SystemConstant.API_TIMEOUT)
+                            .execute();
+                    JSONObject obj = JSONObject.parseObject(execute2.body());
+                    access_token = obj.getString("access_token");
+                    advMiniConfig.setAccessToken(access_token);
+                    advMiniConfigService.updateById(advMiniConfig);
+                }
+                Map<String, Object> map = new HashMap<>();
+                Map<String, Object> map2 = new HashMap<>();
+                map2.put("path", "pages/home/productList");
+                map2.put("query", "traceId=" + traceId);
+                map2.put("env_version", "trial");
+                map.put("jump_wxa", map2);
+                map.put("is_expire", false);
+                HttpResponse execute = HttpRequest.post("https://api.weixin.qq.com/wxa/generatescheme?access_token=" + access_token)
+                        .header("Content-Type", "application/json")
+                        .body(JSONUtil.toJsonStr(map))
+                        .timeout(SystemConstant.API_TIMEOUT)
+                        .execute();
+                log.info("getSchemeUrl:{}", execute.body());
+                JSONObject jsonObject = JSONObject.parseObject(execute.body());
+                //response.addHeader("Access-Control-Allow-Origin", "*");
+                return Result.success(jsonObject.getString("openlink"));
+            }catch (Exception e){
+                log.error("getSchemeUrl error:{}",advMiniConfig.getAppId(), e);
+            }
+        }
+        return Result.success("");
     }
 }

+ 1 - 0
fs-ad-new-api/src/main/java/com/fs/app/facade/CallbackProcessingFacadeServiceImpl.java

@@ -221,6 +221,7 @@ public class CallbackProcessingFacadeServiceImpl implements CallbackProcessingFa
                                                Integer allocationRule,
                                                Long allocationRuleId,
                                                Lead byTraceId) {
+
         // 二维码
         String qrCode = "";
         if (allocationRule == 1) {

+ 1 - 0
fs-ad-new-api/src/main/resources/application.yml

@@ -7,3 +7,4 @@ spring:
     active: dev
 #    active: druid-ylrz
 
+#

+ 18 - 0
fs-service/src/main/java/com/fs/newAdv/controller/AdvMiniConfigController.java

@@ -0,0 +1,18 @@
+package com.fs.newAdv.controller;
+
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * <p>
+ * 广告微信小程序配置 前端控制器
+ * </p>
+ *
+ * @author zhangqin
+ * @since 2025-12-19
+ */
+@RestController
+@RequestMapping("/advMiniConfig")
+public class AdvMiniConfigController {
+
+}

+ 58 - 0
fs-service/src/main/java/com/fs/newAdv/domain/AdvMiniConfig.java

@@ -0,0 +1,58 @@
+package com.fs.newAdv.domain;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.io.Serializable;
+import java.time.LocalDateTime;
+
+/**
+ * <p>
+ * 广告微信小程序配置
+ * </p>
+ *
+ * @author zhangqin
+ * @since 2025-12-19
+ */
+@Getter
+@Setter
+@TableName("adv_mini_config")
+@ApiModel(value = "AdvMiniConfig对象", description = "广告微信小程序配置")
+public class AdvMiniConfig extends Model<AdvMiniConfig> {
+
+    private static final long serialVersionUID = 1L;
+
+    @TableId("id")
+    private Integer id;
+
+    @TableField("app_id")
+    private String appId;
+
+    @TableField("app_secret")
+    private String appSecret;
+
+    @TableField("access_token")
+    private String accessToken;
+
+    @ApiModelProperty("小程序状态1启用 0停用")
+    @TableField("status")
+    private Integer status;
+
+    @ApiModelProperty("过期时间")
+    @TableField("expires_in")
+    private LocalDateTime expiresIn;
+
+    @TableField("create_time")
+    private LocalDateTime createTime;
+
+    @Override
+    public Serializable pkVal() {
+        return this.id;
+    }
+}

+ 2 - 2
fs-service/src/main/java/com/fs/newAdv/domain/PromotionAccount.java

@@ -71,9 +71,9 @@ public class PromotionAccount implements Serializable {
     private Integer apiSwitch;
 
     /**
-     * 推广账户密码(加密存储)
+     * 推拓展字段
      */
-    private String accountPassword;
+    private String extendedField;
     /**
      * 1线上 2线下
      */

+ 2 - 2
fs-service/src/main/java/com/fs/newAdv/integration/client/advertiser/BaiduApiClient.java

@@ -123,7 +123,7 @@ public class BaiduApiClient extends AbstractApiClient implements IAccessTokenCli
         Map<String, Object> map = new HashMap<>();
         Map<String, Object> header = new HashMap<>();
         header.put("accessToken", account.getAccessToken());
-        header.put("userName", account.getAccountShortName());
+        header.put("userName", account.getExtendedField());
         map.put("header", header);
         Map<String, Object> body = new HashMap<>();
         // 基础信息
@@ -197,7 +197,7 @@ public class BaiduApiClient extends AbstractApiClient implements IAccessTokenCli
             requestMap.put("secretKey", codeVo.getAppSecret());
             requestMap.put("authCode", codeVo.getAuthCode());
             requestMap.put("grantType", "access_token");
-            requestMap.put("userId", codeVo.getUserId());
+            requestMap.put("userId", codeVo.getAdAccountId());
             // 发送HTTP请求
             return HttpRequest.post(ACCESS_TOKEN_URL)
                     .header("Content-Type", "application/json")

+ 44 - 6
fs-service/src/main/java/com/fs/newAdv/integration/client/advertiser/TencentApiClient.java

@@ -1,6 +1,8 @@
 package com.fs.newAdv.integration.client.advertiser;
 
 import cn.hutool.http.HttpRequest;
+import cn.hutool.http.HttpResponse;
+import cn.hutool.json.JSONArray;
 import cn.hutool.json.JSONObject;
 import cn.hutool.json.JSONUtil;
 import com.fs.common.constant.SystemConstant;
@@ -15,11 +17,9 @@ import com.fs.newAdv.vo.AccessTokenVo;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Component;
 
+import java.math.BigDecimal;
 import java.time.LocalDateTime;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
 
 /**
  * 腾讯广点通API客户端
@@ -34,6 +34,7 @@ public class TencentApiClient extends AbstractApiClient implements IAccessTokenC
 
     private static final String CONVERSION_API_URL = "https://api.e.qq.com/user_actions/add";
     private static final String TOKEN_API_URL = "https://api.e.qq.com/oauth/token";
+    private static final String REPORTS_API_URL = "https://api.e.qq.com/v3.0/daily_reports/get?access_token=%s&timestamp=%s&nonce=%s";
 
     /**
      * 回传转化数据
@@ -84,7 +85,44 @@ public class TencentApiClient extends AbstractApiClient implements IAccessTokenC
 
     @Override
     public SiteStatistics getDataReport(PromotionAccount account, String ideaId, String startDate, String endDate) {
-        return null;
+        // 构建请求参数
+        Map<String, Object> body = new HashMap<>();
+        // 基础信息
+        //报告名称: 信息流整体账户报告
+        //reportType: 2172649
+        //支持的时间单位: HOUR DAY WEEK MONTH SUMMARY
+        //支持的最大时间区间: 824天
+        body.put("account_id", account.getAdAccountId());
+        body.put("level", "REPORT_LEVEL_ADGROUP");
+        Map<String, Object> date_range = new HashMap<>();
+        date_range.put("start_date", startDate);
+        date_range.put("end_date", endDate);
+        body.put("date_range", date_range);
+
+        Map<String, Object> filtering = new HashMap<>();
+        filtering.put("field", "dynamic_creative_id");
+        filtering.put("operator", "IN");
+        filtering.put("values", Arrays.asList(ideaId));
+        body.put("filtering", date_range);
+
+        log.info("腾讯数据请求参数:{}", JSONUtil.toJsonStr(body));
+        HttpResponse execute = HttpRequest.get(String.format(REPORTS_API_URL, account.getAccessToken(), new Date().getTime(), SnowflakeUtil.randomUUID()))
+                .form(body)
+                .timeout(SystemConstant.API_TIMEOUT)
+                .execute();
+        JSONObject jsonObject = JSONUtil.parseObj(execute.body());
+        log.info("腾讯数据返回结果:{}", execute.body());
+        JSONObject data = jsonObject.getJSONObject("body").getJSONObject("data");
+        JSONArray rows = data.getJSONArray("list");
+        JSONObject jsonObject1 = rows.getJSONObject(0);
+        SiteStatistics siteStatistics = new SiteStatistics();
+        siteStatistics.setImpressionCount(Integer.valueOf(jsonObject1.getStr("view_count")));
+        siteStatistics.setClickCount(Integer.valueOf(jsonObject1.getStr("valid_click_count")));
+        siteStatistics.setActualCost(new BigDecimal(jsonObject1.getStr("cost")));
+        siteStatistics.setAccountCost(new BigDecimal(jsonObject1.getStr("cost")));
+        siteStatistics.setClickRate(new BigDecimal(jsonObject1.getStr("ctr")));
+        siteStatistics.setAvgClickPrice(new BigDecimal(jsonObject1.getStr("cpc")));
+        return siteStatistics;
     }
 
 
@@ -110,7 +148,7 @@ public class TencentApiClient extends AbstractApiClient implements IAccessTokenC
                     .form("client_secret", codeVo.getAppSecret())
                     .form("grant_type", "authorization_code")
                     .form("authorization_code", codeVo.getAuthCode())
-                    .form("redirect_uri", "authorization_code")
+                    // .form("redirect_uri", "authorization_code")
                     .timeout(SystemConstant.API_TIMEOUT)
                     .execute();
         });

+ 18 - 0
fs-service/src/main/java/com/fs/newAdv/mapper/AdvMiniConfigMapper.java

@@ -0,0 +1,18 @@
+package com.fs.newAdv.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.fs.newAdv.domain.AdvMiniConfig;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * <p>
+ * 广告微信小程序配置 Mapper 接口
+ * </p>
+ *
+ * @author zhangqin
+ * @since 2025-12-19
+ */
+@Mapper
+public interface AdvMiniConfigMapper extends BaseMapper<AdvMiniConfig> {
+
+}

+ 16 - 0
fs-service/src/main/java/com/fs/newAdv/service/IAdvMiniConfigService.java

@@ -0,0 +1,16 @@
+package com.fs.newAdv.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.fs.newAdv.domain.AdvMiniConfig;
+
+/**
+ * <p>
+ * 广告微信小程序配置 服务类
+ * </p>
+ *
+ * @author zhangqin
+ * @since 2025-12-19
+ */
+public interface IAdvMiniConfigService extends IService<AdvMiniConfig> {
+
+}

+ 1 - 1
fs-service/src/main/java/com/fs/newAdv/service/ILeadService.java

@@ -41,7 +41,7 @@ public interface ILeadService extends IService<Lead> {
      * @param mpOpenId
      * @param phone
      */
-    void weChatAuthorizationLead(String traceId, String unionId, String mpOpenId, String phone);
+    void weChatAuthorizationLead(String traceId, String unionId, String maOpenId, String phone);
 
     /**
      * 小程序授权落地页访问线索处理

+ 20 - 0
fs-service/src/main/java/com/fs/newAdv/service/impl/AdvMiniConfigServiceImpl.java

@@ -0,0 +1,20 @@
+package com.fs.newAdv.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.fs.newAdv.domain.AdvMiniConfig;
+import com.fs.newAdv.mapper.AdvMiniConfigMapper;
+import com.fs.newAdv.service.IAdvMiniConfigService;
+import org.springframework.stereotype.Service;
+
+/**
+ * <p>
+ * 广告微信小程序配置 服务实现类
+ * </p>
+ *
+ * @author zhangqin
+ * @since 2025-12-19
+ */
+@Service
+public class AdvMiniConfigServiceImpl extends ServiceImpl<AdvMiniConfigMapper, AdvMiniConfig> implements IAdvMiniConfigService {
+
+}

+ 6 - 4
fs-service/src/main/java/com/fs/newAdv/service/impl/LeadServiceImpl.java

@@ -118,20 +118,22 @@ public class LeadServiceImpl extends ServiceImpl<LeadMapper, Lead> implements IL
 
     @Override
     @Async
-    public void weChatAuthorizationLead(String traceId, String unionId, String mpOpenId, String phone) {
+    public void weChatAuthorizationLead(String traceId, String unionId, String maOpenId, String phone) {
        try{
            Lead byTraceId = this.getByTraceId(traceId);
            if (byTraceId == null) {
                return;
            }
+           log.info("用户微信授权线索信息:{}", traceId);
            this.update(new LambdaUpdateWrapper<Lead>()
                    .eq(Lead::getTraceId, traceId)
-                   .set(Lead::getUnionid, unionId)
-                   .set(Lead::getPhone, phone)
-                   .set(Lead::getOpenid, mpOpenId)
+                   .set(ObjectUtil.isNotEmpty(unionId),Lead::getUnionid, unionId)
+                   .set(ObjectUtil.isNotEmpty(phone),Lead::getPhone, phone)
+                   .set(ObjectUtil.isNotEmpty(maOpenId),Lead::getOpenid, maOpenId)
                    .set(Lead::getMiniAuth, 1));
            if (ObjectUtil.isNotEmpty(byTraceId.getLandingPageTs()) && byTraceId.getLandingPageTs().toLocalDate().isEqual(LocalDate.now())) {
                // 微信授权且当日创建事件
+               log.info("用户微信授权线索事件回传:{}", traceId);
                conversionEventPublisher.publishConversionEvent(traceId, SystemEventTypeEnum.AUTH_TODAY_CREATE);
            }
        }catch (Exception e){

+ 1 - 1
fs-service/src/main/java/com/fs/newAdv/vo/AccessTokenByAuthCodeVo.java

@@ -11,7 +11,7 @@ public class AccessTokenByAuthCodeVo implements Serializable {
     private String appId;
     private String appSecret;
     private String authCode;
-    private String userId;
+    private String adAccountId;
 
 
 

+ 1 - 1
fs-user-app/src/main/java/com/fs/app/controller/store/WxUserScrmController.java

@@ -371,7 +371,7 @@ public class WxUserScrmController extends AppBaseController {
             userService.handleFsUserWx(user,loginMaWxParam,session);
             String token = jwtUtils.generateToken(user.getUserId());
             // 广告线索
-            leadService.weChatAuthorizationLead(param.getTraceId(), user.getUnionId(),user.getMpOpenId(),user.getPhone());
+            leadService.weChatAuthorizationLead(param.getTraceId(), user.getUnionId(),user.getMaOpenId(),user.getPhone());
             return R.ok("登录成功").put("token",token).put("user", user);
         } catch (WxErrorException e) {
             //this.logger.error(e.getMessage(), e);