فهرست منبع

腾讯-扣量

yumeng 1 ماه پیش
والد
کامیت
07675d5558

+ 1 - 1
src/main/java/com/adx/tencent/conversionsync/ConversionSyncService.java

@@ -1149,7 +1149,7 @@ public class ConversionSyncService {
         record.setAttempt(1);
         record.setErrorMessage("deducted_by_new_link_rate");
         record.setDispatchStatus(MediaCallbackRecord.DISPATCH_STATUS_DEDUCTED);
-        record.setTrackingVersion(resolveTrackingVersion(task.tencentBid));
+        record.setTrackingVersion(String.valueOf(resolveDeductionRate(task.tencentBid)));
         record.setCreatedAt(now);
         int deductionRate = resolveDeductionRate(task.tencentBid);
         log.info("[ConversionSync] 腾讯转化扣量 | qk={} | act={} | rate={} | tagId={} | accountId={} | callbackKey={}",

+ 8 - 4
src/main/java/com/adx/tencent/httpapi/TrackingController.java

@@ -70,10 +70,12 @@ public class TrackingController {
      * 限制最多50个线程同时执行。
      */
     @GetMapping("/tencent/impression")
-    public Object tencentImpression(HttpServletRequest request) throws Exception {
+    public Object tencentImpression(HttpServletRequest request,
+                                    @RequestParam(name = "deductionRate", required = false, defaultValue = "0") int deductionRate)
+            throws Exception {
         impressionSemaphore.acquire();
         try {
-            return doImpression(request, "v1", 0);
+            return doImpression(request, "v1", deductionRate);
         } finally {
             impressionSemaphore.release();
         }
@@ -181,11 +183,13 @@ public class TrackingController {
      * 限制最多50个线程同时执行。
      */
     @GetMapping("/tencent/click")
-    public Object tencentClick(HttpServletRequest request, HttpServletResponse response)
+    public Object tencentClick(HttpServletRequest request,
+                               HttpServletResponse response,
+                               @RequestParam(name = "deductionRate", required = false, defaultValue = "0") int deductionRate)
             throws Exception {
         clickSemaphore.acquire();
         try {
-            return doClick(request, response, "v1", 0);
+            return doClick(request, response, "v1", deductionRate);
         } finally {
             clickSemaphore.release();
         }

+ 10 - 6
src/main/java/com/adx/tencent/storage/TiDBColdStore.java

@@ -119,7 +119,7 @@ public class TiDBColdStore {
                 error_message TEXT,
                 request_body TEXT,
                 dispatch_status VARCHAR(32) NOT NULL DEFAULT 'SENT',
-                tracking_version VARCHAR(16) NOT NULL DEFAULT 'v1',
+                tracking_version VARCHAR(16) NOT NULL DEFAULT '0',
                 created_at TIMESTAMP(3) NOT NULL,
                 KEY idx_tencent_media_callbacks_dedupe_ok_created_at (dedupe_key, ok, created_at),
                 KEY idx_tencent_media_callbacks_qk_created_at (qk, created_at),
@@ -173,10 +173,10 @@ public class TiDBColdStore {
                 stmt.execute("UPDATE tencent_media_callbacks SET dispatch_status = 'SENT' WHERE dispatch_status IS NULL OR dispatch_status = ''");
             } catch (Exception ignored) {}
             try {
-                stmt.execute("ALTER TABLE tencent_media_callbacks ADD COLUMN tracking_version VARCHAR(16) NOT NULL DEFAULT 'v1' AFTER dispatch_status");
+                stmt.execute("ALTER TABLE tencent_media_callbacks ADD COLUMN tracking_version VARCHAR(16) NOT NULL DEFAULT '0' AFTER dispatch_status");
             } catch (Exception ignored) {}
             try {
-                stmt.execute("UPDATE tencent_media_callbacks SET tracking_version = 'v1' WHERE tracking_version IS NULL OR tracking_version = ''");
+                stmt.execute("UPDATE tencent_media_callbacks SET tracking_version = '0' WHERE tracking_version IS NULL OR tracking_version = ''");
             } catch (Exception ignored) {}
             try {
                 stmt.execute("ALTER TABLE tencent_tag_event ADD COLUMN baidu_act INT NULL COMMENT '百度转化行为' AFTER tag_id");
@@ -301,7 +301,7 @@ public class TiDBColdStore {
             record.setDispatchStatus(MediaCallbackRecord.DISPATCH_STATUS_SENT);
         }
         if (record.getTrackingVersion() == null || record.getTrackingVersion().isBlank()) {
-            record.setTrackingVersion("v1");
+            record.setTrackingVersion(defaultTrackingVersion(record.getMedia()));
         }
         try (SqlSession session = sqlSessionFactory.openSession(true)) {
             MediaCallbackMapper mapper = session.getMapper(MediaCallbackMapper.class);
@@ -325,7 +325,7 @@ public class TiDBColdStore {
                 record.setDispatchStatus(MediaCallbackRecord.DISPATCH_STATUS_SENT);
             }
             if (record.getTrackingVersion() == null || record.getTrackingVersion().isBlank()) {
-                record.setTrackingVersion("v1");
+                record.setTrackingVersion(defaultTrackingVersion(record.getMedia()));
             }
         }
         try (SqlSession session = sqlSessionFactory.openSession(ExecutorType.BATCH, false)) {
@@ -401,7 +401,7 @@ public class TiDBColdStore {
             record.setDispatchStatus(MediaCallbackRecord.DISPATCH_STATUS_SENT);
         }
         if (record.getTrackingVersion() == null || record.getTrackingVersion().isBlank()) {
-            record.setTrackingVersion("v1");
+            record.setTrackingVersion(defaultTrackingVersion(record.getMedia()));
         }
         try (SqlSession session = sqlSessionFactory.openSession(true)) {
             MediaCallbackMapper mapper = session.getMapper(MediaCallbackMapper.class);
@@ -409,6 +409,10 @@ public class TiDBColdStore {
         }
     }
 
+    private static String defaultTrackingVersion(String media) {
+        return "tencent".equalsIgnoreCase(media) ? "0" : "v1";
+    }
+
     // ─── 查询:广告位回传方式配置 ──────────────────────────────────────────────
 
     public List<TagEventRecord> listAllTagEvents() {

+ 20 - 1
src/main/java/com/adx/tencent/tencent/TencentClient.java

@@ -82,7 +82,7 @@ public class TencentClient {
         record.setPurchase(payment.getPayment());
         record.setAttempt(1);
         record.setDispatchStatus(MediaCallbackRecord.DISPATCH_STATUS_SENT);
-        record.setTrackingVersion(resolveTrackingVersion(bid));
+        record.setTrackingVersion(String.valueOf(resolveDeductionRate(bid)));
         record.setCreatedAt(Instant.now());
 
         // 取 callback URL
@@ -282,6 +282,25 @@ public class TencentClient {
         return (version == null || version.isBlank()) ? "v1" : version;
     }
 
+    private static int resolveDeductionRate(BidRecord bid) {
+        if (bid == null || bid.getMediaParams() == null) {
+            return 0;
+        }
+        String rawRate = bid.getMediaParams().get(BidRecord.DEDUCTION_RATE_KEY);
+        if (rawRate == null || rawRate.isBlank()) {
+            return 0;
+        }
+        try {
+            int rate = Integer.parseInt(rawRate.trim());
+            if (rate < 0) {
+                return 0;
+            }
+            return Math.min(rate, 100);
+        } catch (NumberFormatException ignored) {
+            return 0;
+        }
+    }
+
     private String buildOuterActionId(BidRecord bid, PaymentInfo payment, String actionType) {
         String source = String.join("|",
                 safe(payment.getQk()),

+ 2 - 1
src/main/resources/schema.sql

@@ -88,7 +88,7 @@ CREATE TABLE IF NOT EXISTS tencent_media_callbacks (
     error_message TEXT COMMENT '错误信息',
     request_body TEXT COMMENT '请求体',
     dispatch_status VARCHAR(32) NOT NULL DEFAULT 'SENT' COMMENT '回传处理状态(SENT/DEDUCTED)',
-    tracking_version VARCHAR(16) NOT NULL DEFAULT 'v1' COMMENT '监测链接版本(v1/v2/v3)',
+    tracking_version VARCHAR(16) NOT NULL DEFAULT '0' COMMENT '腾讯扣量值(0=不扣量)',
     created_at TIMESTAMP(3) NOT NULL COMMENT '创建时间',
     KEY idx_tencent_media_callbacks_dedupe_ok_created_at (dedupe_key, ok, created_at),
     KEY idx_tencent_media_callbacks_qk_created_at (qk, created_at),
@@ -126,7 +126,7 @@ CREATE TABLE IF NOT EXISTS tencent_tag_event (
 -- 如果旧表没有 request_body / dispatch_status 字段
 -- ALTER TABLE tencent_media_callbacks ADD COLUMN request_body TEXT AFTER error_message;
 -- ALTER TABLE tencent_media_callbacks ADD COLUMN dispatch_status VARCHAR(32) NOT NULL DEFAULT 'SENT' AFTER request_body;
+-- ALTER TABLE tencent_media_callbacks ADD COLUMN tracking_version VARCHAR(16) NOT NULL DEFAULT '0' AFTER dispatch_status;
 
 -- 如果旧表没有 event_type 字段
 -- ALTER TABLE tencent_ad_bid_events ADD COLUMN event_type VARCHAR(16) COMMENT '事件类型(impression/click)' AFTER account_id;