wcc hai 1 ano
pai
achega
72d89bfd17
Modificáronse 21 ficheiros con 856 adicións e 26 borrados
  1. 31 0
      game-back/game-back-base/src/main/java/com/zanxiang/game/back/base/oceanengine/pojo/dto/AccountReportRpcDTO.java
  2. 55 0
      game-back/game-back-base/src/main/java/com/zanxiang/game/back/base/oceanengine/pojo/dto/OrderReportRpcDTO.java
  3. 0 10
      game-back/game-back-base/src/main/java/com/zanxiang/game/back/base/oceanengine/pojo/dto/OrderRpcDTO.java
  4. 22 13
      game-back/game-back-base/src/main/java/com/zanxiang/game/back/base/oceanengine/pojo/dto/UserActiveReportRpcDTO.java
  5. 9 3
      game-back/game-back-base/src/main/java/com/zanxiang/game/back/base/oceanengine/rpc/IWechatMiniGameDataReportRpc.java
  6. 7 0
      game-back/game-back-serve/src/main/java/com/zanxiang/game/back/serve/dao/mapper/GameOceanengineBackLogMapper.java
  7. 7 0
      game-back/game-back-serve/src/main/java/com/zanxiang/game/back/serve/dao/mapper/GameOceanengineOrderLogMapper.java
  8. 7 0
      game-back/game-back-serve/src/main/java/com/zanxiang/game/back/serve/dao/mapper/GameOceanengineUserLogMapper.java
  9. 98 0
      game-back/game-back-serve/src/main/java/com/zanxiang/game/back/serve/oceanengine/MiniGameCallback.java
  10. 15 0
      game-back/game-back-serve/src/main/java/com/zanxiang/game/back/serve/oceanengine/OceanengineCallbackException.java
  11. 77 0
      game-back/game-back-serve/src/main/java/com/zanxiang/game/back/serve/pojo/entity/GameOceanengineBackLog.java
  12. 84 0
      game-back/game-back-serve/src/main/java/com/zanxiang/game/back/serve/pojo/entity/GameOceanengineOrderLog.java
  13. 84 0
      game-back/game-back-serve/src/main/java/com/zanxiang/game/back/serve/pojo/entity/GameOceanengineUserLog.java
  14. 25 0
      game-back/game-back-serve/src/main/java/com/zanxiang/game/back/serve/pojo/enums/BackStatusEnum.java
  15. 70 0
      game-back/game-back-serve/src/main/java/com/zanxiang/game/back/serve/rpc/impl/WechatMiniGameDataReportRpcImpl.java
  16. 7 0
      game-back/game-back-serve/src/main/java/com/zanxiang/game/back/serve/service/IGameOceanengineBackLogService.java
  17. 9 0
      game-back/game-back-serve/src/main/java/com/zanxiang/game/back/serve/service/IGameOceanengineOrderLogService.java
  18. 9 0
      game-back/game-back-serve/src/main/java/com/zanxiang/game/back/serve/service/IGameOceanengineUserLogService.java
  19. 14 0
      game-back/game-back-serve/src/main/java/com/zanxiang/game/back/serve/service/impl/GameOceanengineBackLogServiceImpl.java
  20. 140 0
      game-back/game-back-serve/src/main/java/com/zanxiang/game/back/serve/service/impl/GameOceanengineOrderLogServiceImpl.java
  21. 86 0
      game-back/game-back-serve/src/main/java/com/zanxiang/game/back/serve/service/impl/GameOceanengineUserLogServiceImpl.java

+ 31 - 0
game-back/game-back-base/src/main/java/com/zanxiang/game/back/base/oceanengine/pojo/dto/AccountReportRpcDTO.java

@@ -0,0 +1,31 @@
+package com.zanxiang.game.back.base.oceanengine.pojo.dto;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+
+/**
+ * 头条小游戏回传信息(跟小游戏有关联,但是有时候同一个小游戏会有不同 token和 url。所以只能绑到广告账号上)
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@Builder
+public class AccountReportRpcDTO implements Serializable {
+    private static final long serialVersionUID = 1L;
+    /**
+     * 广告账号 ID
+     */
+    private Long accountId;
+    /**
+     * 上报 Token
+     */
+    private String reportToken;
+    /**
+     * 上报地址
+     */
+    private String reportUrl;
+}

+ 55 - 0
game-back/game-back-base/src/main/java/com/zanxiang/game/back/base/oceanengine/pojo/dto/OrderReportRpcDTO.java

@@ -0,0 +1,55 @@
+package com.zanxiang.game.back.base.oceanengine.pojo.dto;
+
+import lombok.Data;
+
+import java.io.Serializable;
+import java.time.LocalDateTime;
+
+@Data
+public class OrderReportRpcDTO implements Serializable {
+    private static final long serialVersionUID = 1L;
+    /**
+     * 游戏 id
+     */
+    private Long gameId;
+    /**
+     * 微信小游戏上报组件
+     */
+    private AccountReportRpcDTO accountReport;
+    /**
+     * 小游戏 appId
+     */
+    private String wechatAppId;
+    /**
+     * 小游戏 openId
+     */
+    private String wechatOpenId;
+    /**
+     * 小游戏 unionId
+     */
+    private String wechatUnionId;
+    /**
+     * 订单编号
+     */
+    private String orderId;
+    /**
+     * 渠道标识
+     */
+    private String agentKey;
+    /**
+     * 订单金额(分)
+     */
+    private Long rechargeMoney;
+    /**
+     * 支付状态,0 : 预下单, 1 : 待支付,2 : 支付成功,-1 : 已取消
+     */
+    private Integer orderStatus;
+    /**
+     * 下单时间
+     */
+    private LocalDateTime createTime;
+    /**
+     * 支付时间
+     */
+    private LocalDateTime payTime;
+}

+ 0 - 10
game-back/game-back-base/src/main/java/com/zanxiang/game/back/base/oceanengine/pojo/dto/OrderRpcDTO.java

@@ -1,10 +0,0 @@
-package com.zanxiang.game.back.base.oceanengine.pojo.dto;
-
-import lombok.Data;
-
-import java.io.Serializable;
-
-@Data
-public class OrderRpcDTO implements Serializable {
-    private static final long serialVersionUID = 1L;
-}

+ 22 - 13
game-back/game-back-base/src/main/java/com/zanxiang/game/back/base/oceanengine/pojo/dto/UserActiveRpcDTO.java → game-back/game-back-base/src/main/java/com/zanxiang/game/back/base/oceanengine/pojo/dto/UserActiveReportRpcDTO.java

@@ -6,8 +6,29 @@ import java.io.Serializable;
 import java.time.LocalDateTime;
 
 @Data
-public class UserActiveRpcDTO implements Serializable {
+public class UserActiveReportRpcDTO implements Serializable {
     private static final long serialVersionUID = 1L;
+
+    /**
+     * 游戏 id
+     */
+    private Long gameId;
+    /**
+     * 小游戏 appId
+     */
+    private String wechatAppId;
+    /**
+     * 小游戏 openId
+     */
+    private String wechatOpenId;
+    /**
+     * 小游戏 unionId
+     */
+    private String wechatUnionId;
+    /**
+     * 微信小游戏上报组件
+     */
+    private AccountReportRpcDTO accountReport;
     /**
      * 渠道标识
      */
@@ -32,18 +53,6 @@ public class UserActiveRpcDTO implements Serializable {
      * 请求下发的id。如果广告主在计划创编时填写第三方监控链接,可请求获取request_id和其他需要的参数(如IMEI、IDFA、OS等,具体参考文档监测链接发送服务),然后与path下发的req_id进行映射。
      */
     private String reqId;
-    /**
-     * 小游戏 appId
-     */
-    private String appId;
-    /**
-     * 小游戏 openId
-     */
-    private String openId;
-    /**
-     * 小游戏 unionId
-     */
-    private String unionId;
     /**
      * 激活/注册时间
      */

+ 9 - 3
game-back/game-back-base/src/main/java/com/zanxiang/game/back/base/oceanengine/rpc/WechatMiniGameDataReportRpc.java → game-back/game-back-base/src/main/java/com/zanxiang/game/back/base/oceanengine/rpc/IWechatMiniGameDataReportRpc.java

@@ -1,16 +1,22 @@
 package com.zanxiang.game.back.base.oceanengine.rpc;
 
-import com.zanxiang.game.back.base.oceanengine.pojo.dto.UserActiveRpcDTO;
+import com.zanxiang.game.back.base.oceanengine.pojo.dto.OrderReportRpcDTO;
+import com.zanxiang.game.back.base.oceanengine.pojo.dto.UserActiveReportRpcDTO;
 import com.zanxiang.module.util.pojo.ResultVO;
 
 /**
  * 微信小游戏头条上报
  * 参考文档:https://bytedance.feishu.cn/docx/doxcnsCqXkvxoAg36GDzkRRRuAq
  */
-public interface WechatMiniGameDataReportRpc {
+public interface IWechatMiniGameDataReportRpc {
 
     /**
      * 用户激活、注册等上报
      */
-    ResultVO<Boolean> userActive(UserActiveRpcDTO userActive);
+    ResultVO<Boolean> userActiveReport(UserActiveReportRpcDTO dto);
+
+    /**
+     * 用户下单、支付上报
+     */
+    ResultVO<Boolean> orderReport(OrderReportRpcDTO dto);
 }

+ 7 - 0
game-back/game-back-serve/src/main/java/com/zanxiang/game/back/serve/dao/mapper/GameOceanengineBackLogMapper.java

@@ -0,0 +1,7 @@
+package com.zanxiang.game.back.serve.dao.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.zanxiang.game.back.serve.pojo.entity.GameOceanengineBackLog;
+
+public interface GameOceanengineBackLogMapper extends BaseMapper<GameOceanengineBackLog> {
+}

+ 7 - 0
game-back/game-back-serve/src/main/java/com/zanxiang/game/back/serve/dao/mapper/GameOceanengineOrderLogMapper.java

@@ -0,0 +1,7 @@
+package com.zanxiang.game.back.serve.dao.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.zanxiang.game.back.serve.pojo.entity.GameOceanengineOrderLog;
+
+public interface GameOceanengineOrderLogMapper extends BaseMapper<GameOceanengineOrderLog> {
+}

+ 7 - 0
game-back/game-back-serve/src/main/java/com/zanxiang/game/back/serve/dao/mapper/GameOceanengineUserLogMapper.java

@@ -0,0 +1,7 @@
+package com.zanxiang.game.back.serve.dao.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.zanxiang.game.back.serve.pojo.entity.GameOceanengineUserLog;
+
+public interface GameOceanengineUserLogMapper extends BaseMapper<GameOceanengineUserLog> {
+}

+ 98 - 0
game-back/game-back-serve/src/main/java/com/zanxiang/game/back/serve/oceanengine/MiniGameCallback.java

@@ -0,0 +1,98 @@
+package com.zanxiang.game.back.serve.oceanengine;
+
+import com.zanxiang.module.util.encryption.ShaUtil;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.ResponseEntity;
+import org.springframework.stereotype.Component;
+import org.springframework.web.client.RestTemplate;
+
+import java.util.Arrays;
+import java.util.concurrent.ThreadLocalRandom;
+
+@Component
+public class MiniGameCallback {
+    private static final ThreadLocalRandom RANDOM = ThreadLocalRandom.current();
+    @Autowired
+    private RestTemplate restTemplate;
+
+    public void doCallback(String url, String token, MiniGameCallbackRequest request) throws OceanengineCallbackException {
+        int time = Long.valueOf(System.currentTimeMillis() / 1000).intValue();
+        int nonce = RANDOM.nextInt();
+        String[] arr = {token, String.valueOf(nonce), String.valueOf(time)};
+        Arrays.sort(arr);
+        String signature = ShaUtil.encryptSHA1(arr[0] + arr[1] + arr[2]);
+
+        String params = "timestamp=" + time + "&nonce=" + nonce + "&signature=" + signature;
+        url = url.contains("?") ? (url + "&" + params) : (url + "?" + params);
+        ResponseEntity<String> response = restTemplate.postForEntity(url, request, String.class);
+        if (response.getStatusCode().is2xxSuccessful()) {
+            return;
+        }
+        throw new OceanengineCallbackException(response.getStatusCodeValue(), response.getBody());
+    }
+
+    @Getter
+    public enum EventType {
+        /**
+         * 投放微信小游戏时,可将首次「调起微信小游戏」定义为激活事件
+         * 即,新用户/新设备首次联网打开(不同客户定义口径存在差异,可自行调整)微信小游戏
+         */
+        ACTIVE(0),
+        /**
+         * 在调起微信小游戏后,且在联网环境下,在微信小游戏「完成创角」定义为注册事件
+         */
+        ACTIVE_REGISTER(1),
+        /**
+         * 在调起微信小游戏后,且在联网环境下,「发生交易并完成的每一笔付款」定义为付费事件,付费事件应包括首充及复充数据,并回传付费金额
+         * 付费金额回传要求
+         * props:{"pay_amount":xxx}
+         * xxx单位为分,格式int
+         */
+        ACTIVE_PAY(2),
+        /**
+         * 常见的关键行为有:IPU次数、观看激励视频次数、游戏时长等。具体可参考文档游戏IAA专项_关键行为(api)_使用宝典:从入门到精通 [对外]
+         * https://bytedance.feishu.cn/docs/doccn7kCEIE7oh4RtjoUK4cIiwd
+         */
+        GAME_ADDICTION(25),
+        /**
+         * 用户激活后次日在互联网环境下打开微信小游戏
+         */
+        NEXT_DAY_OPEN(6);
+
+        private final Integer eventType;
+
+        EventType(Integer eventType) {
+            this.eventType = eventType;
+        }
+    }
+
+    @Data
+    @NoArgsConstructor
+    @AllArgsConstructor
+    @Builder
+    public static class MiniGameCallbackRequest {
+        private String clue_token;
+
+        private String open_id;
+
+        private String union_id;
+
+        private String event_type;
+
+        private MiniGameCallbackRequestProps props;
+
+        @Data
+        @NoArgsConstructor
+        @AllArgsConstructor
+        @Builder
+        public static class MiniGameCallbackRequestProps {
+
+            private Long pay_amount;
+        }
+    }
+}

+ 15 - 0
game-back/game-back-serve/src/main/java/com/zanxiang/game/back/serve/oceanengine/OceanengineCallbackException.java

@@ -0,0 +1,15 @@
+package com.zanxiang.game.back.serve.oceanengine;
+
+import lombok.Getter;
+
+@Getter
+public class OceanengineCallbackException extends Exception {
+    private final int httpCode;
+    private final String msg;
+
+    public OceanengineCallbackException(int httpCode, String msg) {
+        super(msg);
+        this.httpCode = httpCode;
+        this.msg = msg;
+    }
+}

+ 77 - 0
game-back/game-back-serve/src/main/java/com/zanxiang/game/back/serve/pojo/entity/GameOceanengineBackLog.java

@@ -0,0 +1,77 @@
+package com.zanxiang.game.back.serve.pojo.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+import java.time.LocalDateTime;
+
+/**
+ * 头条订单上报日志
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@Builder
+@TableName("t_game_ocenaengine_back_log")
+public class GameOceanengineBackLog implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    public static final Integer BACK_STATUS_SUCCESS = 0;
+    public static final Integer BACK_STATUS_FAILED = -1;
+
+    @TableId(value = "id", type = IdType.AUTO)
+    private Long id;
+    /**
+     * 小游戏 id
+     */
+    private String appId;
+    /**
+     * 用户 open_id
+     */
+    private String openId;
+    /**
+     * 用户 union_id
+     */
+    private String unionId;
+    /**
+     * 游戏 id
+     */
+    private Long gameId;
+
+    private Long accountId;
+    /**
+     * 广告回传 token
+     */
+    private String clueToken;
+    /**
+     * 事件类型
+     */
+    private String eventType;
+    /**
+     * 触发回传的日志 id
+     */
+    private Long eventLogId;
+    /**
+     * 支付回传的支付金额
+     */
+    private Long payAmount;
+    /**
+     * 回传状态(0:成功、-1:失败)
+     */
+    private Integer backStatus;
+    /**
+     * 回传失败的错误日志
+     */
+    private String errMsg;
+    /**
+     * 回传时间
+     */
+    private LocalDateTime createTime;
+
+}

+ 84 - 0
game-back/game-back-serve/src/main/java/com/zanxiang/game/back/serve/pojo/entity/GameOceanengineOrderLog.java

@@ -0,0 +1,84 @@
+package com.zanxiang.game.back.serve.pojo.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+import java.time.LocalDateTime;
+
+/**
+ * 头条订单上报日志
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@Builder
+@TableName("t_game_oceanengine_order_log")
+public class GameOceanengineOrderLog implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    @TableId(value = "id", type = IdType.AUTO)
+    private Long id;
+    /**
+     * 小游戏 id
+     */
+    private String appId;
+    /**
+     * 用户 open_id
+     */
+    private String openId;
+    /**
+     * 用户 union_id
+     */
+    private String unionId;
+    /**
+     * 游戏 id
+     */
+    private Long gameId;
+    /**
+     * 广告账号_id
+     */
+    private Long accountId;
+    /**
+     * 广告回传 token
+     */
+    private String accountReportToken;
+    /**
+     * 广告回传 url
+     */
+    private String accountReportUrl;
+    /**
+     * 渠道标识
+     */
+    private String agentKey;
+    /**
+     * 订单编号
+     */
+    private String orderNo;
+    /**
+     * 订单金额(分)
+     */
+    private Long amount;
+    /**
+     * 支付状态,0 : 预下单, 1 : 待支付,2 : 支付成功,-1 : 已取消
+     */
+    private Integer orderStatus;
+    /**
+     * 下单时间
+     */
+    private LocalDateTime createTime;
+    /**
+     * 支付时间
+     */
+    private LocalDateTime payTime;
+    /**
+     * 回传状态
+     */
+    private Integer backStatus;
+
+}

+ 84 - 0
game-back/game-back-serve/src/main/java/com/zanxiang/game/back/serve/pojo/entity/GameOceanengineUserLog.java

@@ -0,0 +1,84 @@
+package com.zanxiang.game.back.serve.pojo.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+import java.time.LocalDateTime;
+
+/**
+ * 头条订单上报日志
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@Builder
+@TableName("t_game_oceanengine_user_log")
+public class GameOceanengineUserLog implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    @TableId(value = "id", type = IdType.AUTO)
+    private Long id;
+    /**
+     * 小游戏 id
+     */
+    private String appId;
+    /**
+     * 用户 open_id
+     */
+    private String openId;
+    /**
+     * 用户 union_id
+     */
+    private String unionId;
+    /**
+     * 游戏 id
+     */
+    private Long gameId;
+    /**
+     * 广告账号_id
+     */
+    private Long accountId;
+    /**
+     * 广告回传 token
+     */
+    private String accountReportToken;
+    /**
+     * 广告回传 url
+     */
+    private String accountReportUrl;
+    /**
+     * 渠道标识
+     */
+    private String agentKey;
+    /**
+     * 注册 token
+     */
+    private String clueToken;
+    /**
+     * 头条2.0-项目 id
+     */
+    private Long projectId;
+    /**
+     * 头条2.0-广告 id
+     */
+    private Long promotionId;
+    /**
+     * 请求 id
+     */
+    private String reqId;
+    /**
+     * 注册/激活时间
+     */
+    private LocalDateTime activeTime;
+    /**
+     * 回传状态
+     */
+    private Integer backStatus;
+
+}

+ 25 - 0
game-back/game-back-serve/src/main/java/com/zanxiang/game/back/serve/pojo/enums/BackStatusEnum.java

@@ -0,0 +1,25 @@
+package com.zanxiang.game.back.serve.pojo.enums;
+
+import lombok.Getter;
+
+@Getter
+public enum BackStatusEnum {
+    /**
+     * 未回传
+     */
+    NO(0),
+    /**
+     * 回传成功
+     */
+    SUCCESS(1),
+    /**
+     * 回传失败
+     */
+    FAILED(-1);
+
+    private final Integer backStatus;
+
+    BackStatusEnum(Integer backStatus) {
+        this.backStatus = backStatus;
+    }
+}

+ 70 - 0
game-back/game-back-serve/src/main/java/com/zanxiang/game/back/serve/rpc/impl/WechatMiniGameDataReportRpcImpl.java

@@ -0,0 +1,70 @@
+package com.zanxiang.game.back.serve.rpc.impl;
+
+import com.zanxiang.game.back.base.oceanengine.pojo.dto.OrderReportRpcDTO;
+import com.zanxiang.game.back.base.oceanengine.pojo.dto.UserActiveReportRpcDTO;
+import com.zanxiang.game.back.base.oceanengine.rpc.IWechatMiniGameDataReportRpc;
+import com.zanxiang.game.back.serve.pojo.entity.GameOceanengineOrderLog;
+import com.zanxiang.game.back.serve.pojo.entity.GameOceanengineUserLog;
+import com.zanxiang.game.back.serve.pojo.enums.BackStatusEnum;
+import com.zanxiang.game.back.serve.service.IGameOceanengineOrderLogService;
+import com.zanxiang.game.back.serve.service.IGameOceanengineUserLogService;
+import com.zanxiang.module.util.pojo.ResultVO;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.dubbo.config.annotation.DubboService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
+
+@Slf4j
+@DubboService
+public class WechatMiniGameDataReportRpcImpl implements IWechatMiniGameDataReportRpc {
+    @Autowired
+    private IGameOceanengineUserLogService gameOceanengineUserLogService;
+    @Autowired
+    private IGameOceanengineOrderLogService gameOceanengineOrderLogService;
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public ResultVO<Boolean> userActiveReport(UserActiveReportRpcDTO dto) {
+        GameOceanengineUserLog userLog = GameOceanengineUserLog.builder()
+                .appId(dto.getWechatAppId())
+                .openId(dto.getWechatOpenId())
+                .unionId(dto.getWechatUnionId())
+                .gameId(dto.getGameId())
+                .accountId(dto.getAccountReport().getAccountId())
+                .accountReportToken(dto.getAccountReport().getReportToken())
+                .accountReportUrl(dto.getAccountReport().getReportUrl())
+                .agentKey(dto.getAgentKey())
+                .clueToken(dto.getClueToken())
+                .projectId(dto.getProjectId())
+                .promotionId(dto.getPromotionId())
+                .reqId(dto.getReqId())
+                .activeTime(dto.getActiveTime())
+                .backStatus(BackStatusEnum.NO.getBackStatus())
+                .build();
+        gameOceanengineUserLogService.save(userLog);
+        return ResultVO.ok(gameOceanengineUserLogService.callback(userLog, false));
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public ResultVO<Boolean> orderReport(OrderReportRpcDTO dto) {
+        GameOceanengineOrderLog orderLog = GameOceanengineOrderLog.builder()
+                .appId(dto.getWechatAppId())
+                .openId(dto.getWechatOpenId())
+                .unionId(dto.getWechatUnionId())
+                .gameId(dto.getGameId())
+                .accountId(dto.getAccountReport().getAccountId())
+                .accountReportToken(dto.getAccountReport().getReportToken())
+                .accountReportUrl(dto.getAccountReport().getReportUrl())
+                .agentKey(dto.getAgentKey())
+                .orderNo(dto.getOrderId())
+                .amount(dto.getRechargeMoney())
+                .orderStatus(dto.getOrderStatus())
+                .createTime(dto.getCreateTime())
+                .payTime(dto.getPayTime())
+                .backStatus(BackStatusEnum.NO.getBackStatus())
+                .build();
+        gameOceanengineOrderLogService.save(orderLog);
+        return ResultVO.ok(gameOceanengineOrderLogService.callback(orderLog, false));
+    }
+}

+ 7 - 0
game-back/game-back-serve/src/main/java/com/zanxiang/game/back/serve/service/IGameOceanengineBackLogService.java

@@ -0,0 +1,7 @@
+package com.zanxiang.game.back.serve.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.zanxiang.game.back.serve.pojo.entity.GameOceanengineBackLog;
+
+public interface IGameOceanengineBackLogService extends IService<GameOceanengineBackLog> {
+}

+ 9 - 0
game-back/game-back-serve/src/main/java/com/zanxiang/game/back/serve/service/IGameOceanengineOrderLogService.java

@@ -0,0 +1,9 @@
+package com.zanxiang.game.back.serve.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.zanxiang.game.back.serve.pojo.entity.GameOceanengineOrderLog;
+
+public interface IGameOceanengineOrderLogService extends IService<GameOceanengineOrderLog> {
+
+    boolean callback(GameOceanengineOrderLog orderLog, boolean mustBack);
+}

+ 9 - 0
game-back/game-back-serve/src/main/java/com/zanxiang/game/back/serve/service/IGameOceanengineUserLogService.java

@@ -0,0 +1,9 @@
+package com.zanxiang.game.back.serve.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.zanxiang.game.back.serve.pojo.entity.GameOceanengineUserLog;
+
+public interface IGameOceanengineUserLogService extends IService<GameOceanengineUserLog> {
+
+    boolean callback(GameOceanengineUserLog userLog, boolean mustBack);
+}

+ 14 - 0
game-back/game-back-serve/src/main/java/com/zanxiang/game/back/serve/service/impl/GameOceanengineBackLogServiceImpl.java

@@ -0,0 +1,14 @@
+package com.zanxiang.game.back.serve.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.zanxiang.game.back.serve.dao.mapper.GameOceanengineBackLogMapper;
+import com.zanxiang.game.back.serve.pojo.entity.GameOceanengineBackLog;
+import com.zanxiang.game.back.serve.service.IGameOceanengineBackLogService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+@Slf4j
+@Service
+public class GameOceanengineBackLogServiceImpl extends ServiceImpl<GameOceanengineBackLogMapper, GameOceanengineBackLog>
+        implements IGameOceanengineBackLogService {
+}

+ 140 - 0
game-back/game-back-serve/src/main/java/com/zanxiang/game/back/serve/service/impl/GameOceanengineOrderLogServiceImpl.java

@@ -0,0 +1,140 @@
+package com.zanxiang.game.back.serve.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.zanxiang.game.back.serve.dao.mapper.GameOceanengineOrderLogMapper;
+import com.zanxiang.game.back.serve.oceanengine.MiniGameCallback;
+import com.zanxiang.game.back.serve.oceanengine.OceanengineCallbackException;
+import com.zanxiang.game.back.serve.pojo.entity.GameBackPolicy;
+import com.zanxiang.game.back.serve.pojo.entity.GameOceanengineBackLog;
+import com.zanxiang.game.back.serve.pojo.entity.GameOceanengineOrderLog;
+import com.zanxiang.game.back.serve.pojo.entity.GameOceanengineUserLog;
+import com.zanxiang.game.back.serve.pojo.enums.BackStatusEnum;
+import com.zanxiang.game.back.serve.service.IGameBackPolicyService;
+import com.zanxiang.game.back.serve.service.IGameOceanengineBackLogService;
+import com.zanxiang.game.back.serve.service.IGameOceanengineOrderLogService;
+import com.zanxiang.game.back.serve.service.IGameOceanengineUserLogService;
+import com.zanxiang.game.back.serve.utils.BackPolicyUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections4.CollectionUtils;
+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.List;
+
+@Slf4j
+@Service
+public class GameOceanengineOrderLogServiceImpl extends ServiceImpl<GameOceanengineOrderLogMapper, GameOceanengineOrderLog>
+        implements IGameOceanengineOrderLogService {
+    @Autowired
+    private MiniGameCallback miniGameCallback;
+    @Autowired
+    private IGameBackPolicyService gameBackPolicyService;
+    @Autowired
+    private IGameOceanengineUserLogService gameOceanengineUserLogService;
+    @Autowired
+    private IGameOceanengineBackLogService gameOceanengineBackLogService;
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean callback(GameOceanengineOrderLog orderLog, boolean mustBack) {
+        boolean doBack = false;
+        if (mustBack) {
+            doBack = true;
+        } else {
+            if (orderLog.getOrderStatus() != 2) {
+                // 头条只要回传支付订单
+                return false;
+            }
+            List<GameBackPolicy> gameBackPolicyList = gameBackPolicyService.list(new LambdaQueryWrapper<GameBackPolicy>()
+                    .eq(GameBackPolicy::getAccountId, orderLog.getAccountId())
+                    .or().eq(GameBackPolicy::getGameId, orderLog.getGameId())
+            );
+            if (CollectionUtils.isEmpty(gameBackPolicyList)) {
+                // 没有回传策略,则直接全量回传
+                doBack = true;
+            } else {
+                GameBackPolicy gameBackPolicy = gameBackPolicyList.get(0);
+                if (gameBackPolicyList.size() > 1) {
+                    GameBackPolicy temp = gameBackPolicyList.get(1);
+                    if (temp.getAccountId() != null && temp.getAccountId() > 0) {
+                        gameBackPolicy = temp;
+                    }
+                }
+                doBack = BackPolicyUtil.isBackOrder(gameBackPolicy, orderLog.getAmount());
+            }
+        }
+        if (doBack) {
+            BackStatusEnum backStatus = doCallback(orderLog);
+            update(new LambdaUpdateWrapper<GameOceanengineOrderLog>()
+                    .set(GameOceanengineOrderLog::getBackStatus, backStatus.getBackStatus())
+                    .eq(GameOceanengineOrderLog::getId, orderLog.getId())
+            );
+            return true;
+        }
+        return false;
+    }
+
+    private BackStatusEnum doCallback(GameOceanengineOrderLog orderLog) {
+        GameOceanengineUserLog userLog = gameOceanengineUserLogService.getOne(new LambdaQueryWrapper<GameOceanengineUserLog>()
+                .eq(GameOceanengineUserLog::getGameId, orderLog.getGameId())
+                .eq(GameOceanengineUserLog::getAppId, orderLog.getAppId())
+                .eq(GameOceanengineUserLog::getOpenId, orderLog.getOpenId())
+                .eq(GameOceanengineUserLog::getAccountId, orderLog.getAccountId())
+                .last("limit 1")
+        );
+        if (userLog == null) {
+            gameOceanengineBackLogService.save(GameOceanengineBackLog.builder()
+                    .appId(orderLog.getAppId())
+                    .openId(orderLog.getOpenId())
+                    .unionId(orderLog.getUnionId())
+                    .gameId(orderLog.getGameId())
+                    .accountId(orderLog.getAccountId())
+                    .clueToken("")
+                    .eventType(String.valueOf(MiniGameCallback.EventType.ACTIVE_PAY.getEventType()))
+                    .eventLogId(orderLog.getId())
+                    .createTime(LocalDateTime.now())
+                    .backStatus(GameOceanengineBackLog.BACK_STATUS_FAILED)
+                    .errMsg("找不到用户注册信息")
+                    .build());
+            return BackStatusEnum.FAILED;
+        }
+        MiniGameCallback.MiniGameCallbackRequest request = MiniGameCallback.MiniGameCallbackRequest.builder()
+                .clue_token(userLog.getClueToken())
+                .open_id(orderLog.getOpenId())
+                .union_id(orderLog.getUnionId())
+                .event_type(String.valueOf(MiniGameCallback.EventType.ACTIVE_PAY.getEventType()))
+                .props(MiniGameCallback.MiniGameCallbackRequest.MiniGameCallbackRequestProps.builder()
+                        .pay_amount(orderLog.getAmount())
+                        .build())
+                .build();
+        Integer backStatus = GameOceanengineBackLog.BACK_STATUS_SUCCESS;
+        String errMsg = null;
+        try {
+            miniGameCallback.doCallback(userLog.getAccountReportUrl(), userLog.getAccountReportToken(), request);
+        } catch (OceanengineCallbackException e) {
+            backStatus = GameOceanengineBackLog.BACK_STATUS_FAILED;
+            errMsg = e.getMsg();
+        } catch (Exception e) {
+            backStatus = GameOceanengineBackLog.BACK_STATUS_FAILED;
+            errMsg = "系统异常:" + e.getMessage();
+        }
+        gameOceanengineBackLogService.save(GameOceanengineBackLog.builder()
+                .appId(orderLog.getAppId())
+                .openId(orderLog.getOpenId())
+                .unionId(orderLog.getUnionId())
+                .gameId(orderLog.getGameId())
+                .accountId(orderLog.getAccountId())
+                .clueToken(userLog.getClueToken())
+                .eventType(request.getEvent_type())
+                .eventLogId(orderLog.getId())
+                .createTime(LocalDateTime.now())
+                .backStatus(backStatus)
+                .errMsg(errMsg)
+                .build());
+        return backStatus.equals(GameOceanengineBackLog.BACK_STATUS_SUCCESS) ? BackStatusEnum.SUCCESS : BackStatusEnum.FAILED;
+    }
+}

+ 86 - 0
game-back/game-back-serve/src/main/java/com/zanxiang/game/back/serve/service/impl/GameOceanengineUserLogServiceImpl.java

@@ -0,0 +1,86 @@
+package com.zanxiang.game.back.serve.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.zanxiang.game.back.serve.dao.mapper.GameOceanengineUserLogMapper;
+import com.zanxiang.game.back.serve.oceanengine.MiniGameCallback;
+import com.zanxiang.game.back.serve.oceanengine.OceanengineCallbackException;
+import com.zanxiang.game.back.serve.pojo.entity.GameOceanengineBackLog;
+import com.zanxiang.game.back.serve.pojo.entity.GameOceanengineUserLog;
+import com.zanxiang.game.back.serve.pojo.enums.BackStatusEnum;
+import com.zanxiang.game.back.serve.service.IGameOceanengineBackLogService;
+import com.zanxiang.game.back.serve.service.IGameOceanengineUserLogService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Propagation;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.time.LocalDateTime;
+
+@Slf4j
+@Service
+public class GameOceanengineUserLogServiceImpl extends ServiceImpl<GameOceanengineUserLogMapper, GameOceanengineUserLog>
+        implements IGameOceanengineUserLogService {
+
+    @Autowired
+    private MiniGameCallback miniGameCallback;
+    @Autowired
+    private IGameOceanengineBackLogService gameOceanengineBackLogService;
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean callback(GameOceanengineUserLog userLog, boolean mustBack) {
+        BackStatusEnum backStatus = doCallback(userLog, mustBack);
+        return update(new LambdaUpdateWrapper<GameOceanengineUserLog>()
+                .set(GameOceanengineUserLog::getBackStatus, backStatus.getBackStatus())
+                .eq(GameOceanengineUserLog::getId, userLog.getId())
+        );
+    }
+
+    private BackStatusEnum doCallback(GameOceanengineUserLog userLog, boolean mustBack) {
+        // 是否已经回传过
+        boolean isBack = mustBack ? false : gameOceanengineBackLogService.count(new LambdaQueryWrapper<GameOceanengineBackLog>()
+                .eq(GameOceanengineBackLog::getGameId, userLog.getGameId())
+                .eq(GameOceanengineBackLog::getAppId, userLog.getAppId())
+                .eq(GameOceanengineBackLog::getOpenId, userLog.getOpenId())
+                .eq(GameOceanengineBackLog::getAccountId, userLog.getAccountId())
+                .eq(GameOceanengineBackLog::getBackStatus, GameOceanengineBackLog.BACK_STATUS_SUCCESS)
+        ) > 0;
+        if (isBack) {
+            return BackStatusEnum.NO;
+        }
+        MiniGameCallback.MiniGameCallbackRequest request = MiniGameCallback.MiniGameCallbackRequest.builder()
+                .clue_token(userLog.getClueToken())
+                .open_id(userLog.getOpenId())
+                .union_id(userLog.getUnionId())
+                .event_type(String.valueOf(MiniGameCallback.EventType.ACTIVE.getEventType()))
+                .build();
+        Integer backStatus = GameOceanengineBackLog.BACK_STATUS_SUCCESS;
+        String errMsg = null;
+        try {
+            miniGameCallback.doCallback(userLog.getAccountReportUrl(), userLog.getAccountReportToken(), request);
+        } catch (OceanengineCallbackException e) {
+            backStatus = GameOceanengineBackLog.BACK_STATUS_FAILED;
+            errMsg = e.getMsg();
+        } catch (Exception e) {
+            backStatus = GameOceanengineBackLog.BACK_STATUS_FAILED;
+            errMsg = "系统异常:" + e.getMessage();
+        }
+        gameOceanengineBackLogService.save(GameOceanengineBackLog.builder()
+                .appId(userLog.getAppId())
+                .openId(userLog.getOpenId())
+                .unionId(userLog.getUnionId())
+                .gameId(userLog.getGameId())
+                .accountId(userLog.getAccountId())
+                .clueToken(userLog.getClueToken())
+                .eventType(request.getEvent_type())
+                .eventLogId(userLog.getId())
+                .createTime(LocalDateTime.now())
+                .backStatus(backStatus)
+                .errMsg(errMsg)
+                .build());
+        return backStatus.equals(GameOceanengineBackLog.BACK_STATUS_SUCCESS) ? BackStatusEnum.SUCCESS : BackStatusEnum.FAILED;
+    }
+}