Sfoglia il codice sorgente

1、米大师支付
2、用户授权信息上报

xufeng 2 anni fa
parent
commit
114ffac66c
24 ha cambiato i file con 1035 aggiunte e 70 eliminazioni
  1. 49 0
      game-module/game-common/src/main/java/com/zanxiang/common/domain/MiPayConfig.java
  2. 45 2
      game-module/game-common/src/main/java/com/zanxiang/common/enums/HttpStatusEnum.java
  3. 11 0
      game-module/game-sdk/src/main/java/com/zanxiang/sdk/common/constant/RedisKeyConstant.java
  4. 127 0
      game-module/game-sdk/src/main/java/com/zanxiang/sdk/common/miPay/MiPayClient.java
  5. 29 0
      game-module/game-sdk/src/main/java/com/zanxiang/sdk/common/miPay/RequestParam.java
  6. 187 0
      game-module/game-sdk/src/main/java/com/zanxiang/sdk/common/miPay/SnsSigCheck.java
  7. 38 0
      game-module/game-sdk/src/main/java/com/zanxiang/sdk/common/miPay/UrlConstants.java
  8. 28 0
      game-module/game-sdk/src/main/java/com/zanxiang/sdk/common/util/HttpUtil.java
  9. 57 2
      game-module/game-sdk/src/main/java/com/zanxiang/sdk/controller/OrderController.java
  10. 15 0
      game-module/game-sdk/src/main/java/com/zanxiang/sdk/controller/UserController.java
  11. 15 0
      game-module/game-sdk/src/main/java/com/zanxiang/sdk/domain/params/MPayBalanceParam.java
  12. 22 0
      game-module/game-sdk/src/main/java/com/zanxiang/sdk/domain/params/OrderCheckInfoParam.java
  13. 4 66
      game-module/game-sdk/src/main/java/com/zanxiang/sdk/domain/params/PreOrderParam.java
  14. 5 0
      game-module/game-sdk/src/main/java/com/zanxiang/sdk/domain/params/UserData.java
  15. 41 0
      game-module/game-sdk/src/main/java/com/zanxiang/sdk/domain/params/UserOauthlUpdateParam.java
  16. 21 0
      game-module/game-sdk/src/main/java/com/zanxiang/sdk/domain/vo/OrderCheckInfoVO.java
  17. 15 0
      game-module/game-sdk/src/main/java/com/zanxiang/sdk/domain/vo/PreOrderMIPayConfigVO.java
  18. 3 0
      game-module/game-sdk/src/main/java/com/zanxiang/sdk/domain/vo/PreOrderVO.java
  19. 211 0
      game-module/game-sdk/src/main/java/com/zanxiang/sdk/service/Impl/MiPayServiceImpl.java
  20. 27 0
      game-module/game-sdk/src/main/java/com/zanxiang/sdk/service/Impl/UserOauthServiceImpl.java
  21. 1 0
      game-module/game-sdk/src/main/java/com/zanxiang/sdk/service/Impl/UserServiceImpl.java
  22. 69 0
      game-module/game-sdk/src/main/java/com/zanxiang/sdk/service/MiPayService.java
  23. 13 0
      game-module/game-sdk/src/main/java/com/zanxiang/sdk/service/UserOauthService.java
  24. 2 0
      game-module/game-sdk/src/main/java/com/zanxiang/sdk/service/UserService.java

+ 49 - 0
game-module/game-common/src/main/java/com/zanxiang/common/domain/MiPayConfig.java

@@ -0,0 +1,49 @@
+package com.zanxiang.common.domain;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import org.springframework.stereotype.Component;
+
+/**
+ * @author xufeng
+ * @date 2022/7/15 12:00
+ */
+@Component
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@Builder
+public class MiPayConfig {
+    /**
+     * 米大师支付应用id
+     */
+    @ApiModelProperty(notes = "米大师支付应用id")
+    private String appId;
+
+    /**
+     * 米大师现网AppKey
+     */
+    @ApiModelProperty(notes = "米大师现网AppKey")
+    private String appKey;
+
+    /**
+     * 米大师沙箱AppKey
+     */
+    @ApiModelProperty(notes = "米大师沙箱AppKey")
+    private String appKeyDev;
+
+    /**
+     * 人民币元宝比例
+     */
+    @ApiModelProperty(notes = "人民币元宝比例")
+    private String exchangeRate;
+
+    /**
+     * IOS充值提示
+     */
+    @ApiModelProperty(notes = "IOS充值提示")
+    private String iosTips;
+}

+ 45 - 2
game-module/game-common/src/main/java/com/zanxiang/common/enums/HttpStatusEnum.java

@@ -322,15 +322,58 @@ public enum HttpStatusEnum {
      */
     MEM_NOT_REACH_STAND(41407, "玩家充值未达标"),
 
+
     /**
      * 玩家充值未达标
      */
-    ORDER_AMOUNT_IS_NULL(41500, "订单金额为空"),
+    ORDER_GAME_ID_IS_NULL(41501, "订单游戏id为空"),
+
+    /**
+     * 订单不存在
+     */
+    ORDER_NO_FIND(41502, "订单不存在"),
 
     /**
      * 玩家充值未达标
      */
-    ORDER_GAME_ID_IS_NULL(41501, "订单游戏id为空"),
+    ORDER_AMOUNT_IS_NULL(41503, "订单金额为空"),
+
+    /**
+     * 生成access_token失败
+     */
+    ACCESS_TOKEN_CREATE_ERROR(41504, "生成access_token失败"),
+
+
+    /**
+     * 米大师连接失败
+     */
+    MDS_CONNECT_ERROR(41505, "米大师连接失败"),
+
+    /**
+     * 米大师生成签名失败
+     */
+    MAKE_SIGNATURE_ERROR(41506, "米大师生成签名失败"),
+
+
+    /**
+     * 获取配置异常
+     */
+    GET_CONFIG_ERROR(41507, "获取配置异常"),
+
+    /**
+     * 获取支付盒子失败
+     */
+    GET_PAY_BOX_ERROR(41508, "获取支付盒子失败"),
+
+    /**
+     * 应用状态为下线状态
+     */
+    PAY_APPLICATION_STATUS_IS_NO(41509, "应用状态为下线状态"),
+
+    /**
+     * 微信opendId为空
+     */
+    WEIXIN_OPEN_ID_NULL(41510, "微信opendId为空"),
 
     /**
      * 参数为空

+ 11 - 0
game-module/game-sdk/src/main/java/com/zanxiang/sdk/common/constant/RedisKeyConstant.java

@@ -32,4 +32,15 @@ public class RedisKeyConstant {
      */
     public static final String AUTH_STATE_KEY = RedisKeyConstant.REDIS_PREFIX + "auth_state";
 
+
+    /**
+     * 微信ACCESS_TOKEN key
+     */
+    public static final String WEIXIN_ACCESS_TOKEN = RedisKeyConstant.REDIS_PREFIX + "access_token_";
+
+    /**
+     * 微信ACCESS_TOKEN key
+     */
+    public static final String WEIXIN_OPEN_ID = RedisKeyConstant.REDIS_PREFIX + "open_id_";
+
 }

+ 127 - 0
game-module/game-sdk/src/main/java/com/zanxiang/sdk/common/miPay/MiPayClient.java

@@ -0,0 +1,127 @@
+package com.zanxiang.sdk.common.miPay;
+
+import com.alibaba.fastjson.JSONObject;
+import com.zanxiang.common.domain.MiPayConfig;
+import com.zanxiang.common.enums.HttpStatusEnum;
+import com.zanxiang.common.exception.CustomException;
+import com.zanxiang.common.utils.StringUtils;
+import com.zanxiang.sdk.common.constant.RedisKeyConstant;
+import com.zanxiang.sdk.common.util.HttpUtil;
+import com.zanxiang.sdk.common.util.RedisUtil;
+import com.zanxiang.sdk.service.Impl.pay.WxpayServiceImpl;
+import lombok.extern.slf4j.Slf4j;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.util.HashMap;
+import java.util.Objects;
+
+/**
+ * 支付
+ *
+ * @author xufeng
+ * @date 2022/7/14 17:39
+ */
+@Slf4j
+@Component
+public class MiPayClient {
+
+    private static final Logger logger = LoggerFactory.getLogger(WxpayServiceImpl.class);
+    @Autowired
+    private RedisUtil<String> redisUtil;
+
+    private static final String method = "POST";
+
+    private static final String contentType = "application/octet-stream; charset=utf-8";
+
+
+    /**
+     * 获取AccessToken
+     *
+     * @param appId
+     * @param appSecret
+     * @return AccessToken
+     */
+    private String getAccessToken(String appId, String appSecret) {
+        String redisKey = RedisKeyConstant.WEIXIN_ACCESS_TOKEN + appId;
+        String cache = redisUtil.getCache(redisKey);
+        if (StringUtils.isNotEmpty(cache)) {
+            return cache;
+        }
+        HashMap<String, String> param = new HashMap<>();
+        param.put("grant_type", UrlConstants.CLIENT_CREDENTIAL);
+        param.put("appid", appId);
+        param.put("secret", appSecret);
+        String result = HttpUtil.postData(UrlConstants.TOKEN_URL, param);
+        if (StringUtils.isEmpty(result)) {
+            return "";
+        }
+        JSONObject data = JSONObject.parseObject(result);
+        if (Objects.isNull(data)) {
+            return "";
+        }
+        Object accessToken = data.get("access_token");
+        if (Objects.isNull(accessToken)) {
+            return "";
+        }
+        String token = accessToken.toString();
+        redisUtil.setCache(redisKey, token, Long.valueOf(data.get("expires_in").toString()));
+        return token;
+    }
+
+    /**
+     * 接口请求
+     *
+     * @param url         请求路径
+     * @param params      请求参数
+     * @param appSecret   密钥
+     * @param midasAppKey 米大师key
+     * @param sessionKey  session
+     * @return
+     */
+    public HashMap<String, String> api(String url, RequestParam params, String midasAppKey, String sessionKey, String appSecret) {
+        try {
+            if (StringUtils.isEmpty(params.getOpenid()) ||
+                    StringUtils.isEmpty(params.getAppid()) ||
+                    StringUtils.isEmpty(params.getOffer_id()) ||
+                    params.getTs() <= 0 || StringUtils.isEmpty(params.getZone_id())
+            ) {
+                throw new CustomException(HttpStatusEnum.PARAM_IS_NULL.getMsg() + JSONObject.toJSONString(params));
+            }
+            String accessToken = getAccessToken(params.getAppid(), params.getAccess_token());
+            if (StringUtils.isEmpty(accessToken)) {
+                throw new CustomException(HttpStatusEnum.ACCESS_TOKEN_CREATE_ERROR);
+            }
+            //使用沙箱时,沙箱地址替换
+            if (params.getIs_sand() == 1) {
+                url = url.replace("/cgi-bin/midas/", "/cgi-bin/midas/sandbox/");
+            }
+            HashMap<String, String> paramsMap = JSONObject.parseObject(JSONObject.toJSONString(params), HashMap.class);
+            paramsMap.remove("is_sand");
+            String sig = SnsSigCheck.makeSig(method, url, paramsMap, params.getApp_key());
+            params.setSig(sig);
+            params.setAccess_token(accessToken);
+            url += "?access_token=" + accessToken;
+            String result = HttpUtil.postData(url, JSONObject.toJSONString(params), contentType);
+            logger.info("米大师接口调用失败 url:{} params:{} result:{}", url, params, result);
+            if (StringUtils.isEmpty(result)) {
+                throw new CustomException(HttpStatusEnum.MDS_CONNECT_ERROR);
+            }
+            HashMap<String, String> data = JSONObject.parseObject(result, HashMap.class);
+            if (Objects.isNull(data)) {
+                throw new CustomException(HttpStatusEnum.MDS_CONNECT_ERROR);
+            }
+            if (!data.get("errcode").equals("0")) {
+                String errmsg = data.get("errmsg");
+                Integer errcode = Integer.valueOf(data.get("errcode"));
+                throw new CustomException(errmsg, errcode);
+            }
+            return data;
+        } catch (RuntimeException e) {
+            logger.error("米大师接口调用失败 url:{} params:{} e:{}", url, params, e);
+            throw new RuntimeException("米大师接口调用失败");
+        }
+    }
+}

+ 29 - 0
game-module/game-sdk/src/main/java/com/zanxiang/sdk/common/miPay/RequestParam.java

@@ -0,0 +1,29 @@
+package com.zanxiang.sdk.common.miPay;
+
+import lombok.Data;
+
+/**
+ * @author xufeng
+ * @date 2022/7/14 19:54
+ */
+@Data
+public class RequestParam {
+    private String openid = ""; /* 用户唯一标识符 */
+    private String appid = ""; /* 小程序 appId*/
+    private String app_key = ""; /* 米大师分配的*/
+    private String offer_id = ""; /* 米大师分配的offer_id */
+    private Long ts = System.currentTimeMillis(); /* UNIX时间戳 */
+    private String zone_id = "1"; /* 游戏服务器大区id,游戏不分大区则默认zoneId ="1",String类型。如过应用选择支持角色,则角色ID接在分区ID号后用"_"连接。 */
+    private String pf = "android"; /* 平台 安卓:android */
+    private String user_ip = ""; /* 用户外网 IP */
+    private String amt = ""; /* 扣除游戏币数量,不能为 0 */
+    private String bill_no = ""; /* 订单号,业务需要保证全局唯一;相同的订单号不会重复扣款。长度不超过63,只能是数字、大小写字母_- */
+    private String pay_item = ""; /* 道具名称 */
+    private String app_remark = ""; /* 备注。会写到账户流水 */
+    private String sig = ""; /* 以上所有参数(含可选最多11个)+uri+米大师密钥,用 HMAC-SHA256签名 */
+    private String access_token = ""; /* 接口调用凭证 */
+    private String mp_sig = ""; /* 以上所有参数(含可选最多11个)+uri+米大师密钥 */
+    private Integer is_sand = 1; /* 1 表示沙盒环境 2 表示正式环境 */
+    private Integer present_counts = 0; /* 赠送游戏币数量,不能为0 */
+    private String method = "POST"; /* 请求方式 */
+}

+ 187 - 0
game-module/game-sdk/src/main/java/com/zanxiang/sdk/common/miPay/SnsSigCheck.java

@@ -0,0 +1,187 @@
+package com.zanxiang.sdk.common.miPay;
+
+import com.zanxiang.common.enums.HttpStatusEnum;
+import org.yaml.snakeyaml.external.biz.base64Coder.Base64Coder;
+
+import javax.crypto.Mac;
+import javax.crypto.spec.SecretKeySpec;
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.util.*;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+
+/**
+ * 生成签名类
+ *
+ * @author xufeng
+ * @date 2022/7/14 17:39
+ */
+
+public class SnsSigCheck {
+
+    /**
+     * URL编码 (符合FRC1738规范)
+     *
+     * @param input 待编码的字符串
+     * @return 编码后的字符串
+     * @throws RuntimeException 不支持指定编码时抛出异常。
+     */
+    public static String encodeUrl(String input) throws RuntimeException {
+        try {
+            return URLEncoder.encode(input, CONTENT_CHARSET).replace("+", "%20").replace("*", "%2A");
+        } catch (UnsupportedEncodingException e) {
+            throw new RuntimeException(HttpStatusEnum.MAKE_SIGNATURE_ERROR.getMsg(), e);
+        }
+    }
+
+    /* 生成签名
+     *
+     * @param method HTTP请求方法 "get" / "post"
+     * @param url_path CGI名字, eg: /v3/user/get_info
+     * @param params URL请求参数
+     * @param secret 密钥
+     * @return 签名值
+     * @throws OpensnsException 不支持指定编码以及不支持指定的加密方法时抛出异常。
+     */
+    public static String makeSig(String method, String url_path, HashMap<String, String> params, String secret) throws RuntimeException {
+        String sig = null;
+        try {
+            Mac mac = Mac.getInstance(HMAC_ALGORITHM);
+            SecretKeySpec secretKey = new SecretKeySpec(secret.getBytes(CONTENT_CHARSET), mac.getAlgorithm());
+            mac.init(secretKey);
+            String mk = makeSource(method, url_path, params);
+            byte[] hash = mac.doFinal(mk.getBytes(CONTENT_CHARSET));
+            // base64
+            sig = new String(Base64Coder.encode(hash));
+        } catch (NoSuchAlgorithmException e) {
+            throw new RuntimeException(HttpStatusEnum.MAKE_SIGNATURE_ERROR.getMsg(), e);
+        } catch (UnsupportedEncodingException e) {
+            throw new RuntimeException(HttpStatusEnum.MAKE_SIGNATURE_ERROR.getMsg(), e);
+        } catch (InvalidKeyException e) {
+            throw new RuntimeException(HttpStatusEnum.MAKE_SIGNATURE_ERROR.getMsg(), e);
+        }
+        return sig;
+    }
+
+    /* 生成签名所需源串
+     *
+     * @param method HTTP请求方法 "get" / "post"
+     * @param url_path CGI名字, eg: /v3/user/get_info
+     * @param params URL请求参数
+     * @return 签名所需源串
+     */
+    public static String makeSource(String method, String url_path, HashMap<String, String> params) throws RuntimeException {
+        Object[] keys = params.keySet().toArray();
+
+        Arrays.sort(keys);
+
+        StringBuilder buffer = new StringBuilder(128);
+
+        buffer.append(method.toUpperCase()).append("&").append(encodeUrl(url_path)).append("&");
+
+        StringBuilder buffer2 = new StringBuilder();
+
+        for (int i = 0; i < keys.length; i++) {
+            buffer2.append(keys[i]).append("=").append(params.get(keys[i]));
+
+            if (i != keys.length - 1) {
+                buffer2.append("&");
+            }
+        }
+
+        buffer.append(encodeUrl(buffer2.toString()));
+
+        return buffer.toString();
+    }
+
+    public static boolean verifySig(String method, String url_path, HashMap<String, String> params, String secret, String sig) throws RuntimeException {
+        // 确保不含sig
+        params.remove("sig");
+
+        // 按照发货回调接口的编码规则对value编码
+        codePayValue(params);
+
+        // 计算签名
+        String sig_new = makeSig(method, url_path, params, secret);
+
+        // 对比和腾讯返回的签名
+        return sig_new.equals(sig);
+    }
+
+    /**
+     * 应用发货URL接口对腾讯回调传来的参数value值先进行一次编码方法,用于验签
+     * (编码规则为:除了 0~9 a~z A~Z !*() 之外其他字符按其ASCII码的十六进制加%进行表示,例如“-”编码为“%2D”)
+     * 参考 <回调发货URL的协议说明_V3>
+     *
+     * @param params 腾讯回调传参Map (key,value);
+     */
+    public static void codePayValue(Map<String, String> params) {
+        Set<String> keySet = params.keySet();
+        Iterator<String> itr = keySet.iterator();
+
+        while (itr.hasNext()) {
+            String key = (String) itr.next();
+            String value = (String) params.get(key);
+            value = encodeValue(value);
+            params.put(key, value);
+        }
+    }
+
+    /**
+     * 应用发货URL接口的编码规则
+     *
+     * @param s
+     * @return
+     */
+    public static String encodeValue(String s) {
+        String rexp = "[0-9a-zA-Z!*\\(\\)]";
+        StringBuffer sb = new StringBuffer(s);
+        StringBuffer sbRtn = new StringBuffer();
+        Pattern p = Pattern.compile(rexp);
+        char temp;
+        String tempStr;
+
+        for (int i = 0; i < sb.length(); i++) {
+            temp = sb.charAt(i);
+            tempStr = String.valueOf(temp);
+            Matcher m = p.matcher(tempStr);
+
+            boolean result = m.find();
+            if (!result) {
+                tempStr = hexString(tempStr);
+            }
+            sbRtn.append(tempStr);
+        }
+
+        return sbRtn.toString();
+    }
+
+    /**
+     * 应用发货URL 十六进制编码
+     *
+     * @param s
+     * @return
+     */
+    private static String hexString(String s) {
+        byte[] b = s.getBytes();
+        String retStr = "";
+        for (int i = 0; i < b.length; i++) {
+            String hex = Integer.toHexString(b[i] & 0xFF);
+            if (hex.length() == 1) {
+                hex = '0' + hex;
+            }
+            retStr = "%" + hex.toUpperCase();
+        }
+        return retStr;
+    }
+
+    // 编码方式
+    private static final String CONTENT_CHARSET = "UTF-8";
+
+    // HMAC算法
+    private static final String HMAC_ALGORITHM = "HmacSHA1";
+}

+ 38 - 0
game-module/game-sdk/src/main/java/com/zanxiang/sdk/common/miPay/UrlConstants.java

@@ -0,0 +1,38 @@
+package com.zanxiang.sdk.common.miPay;
+
+/**
+ * @author xufeng
+ * @date 2022/7/14 17:26
+ */
+public class UrlConstants {
+    /**
+     * 支付
+     */
+    public final static String PAY_URL = "https://api.weixin.qq.com/cgi-bin/midas/pay";
+
+    /**
+     * 赠送
+     */
+    public final static String PRESENT_URL = "https://api.weixin.qq.com/cgi-bin/midas/present";
+
+    /**
+     * 取消支付
+     */
+    public final static String CANCEL_URL = "https://api.weixin.qq.com/cgi-bin/midas/cancelpay";
+
+    /**
+     * 获取钱包
+     */
+    public final static String BALANCE_URL = "https://api.weixin.qq.com/cgi-bin/midas/getbalance";
+
+
+    /**
+     * token获取
+     */
+    public final static String TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token";
+
+    
+    public final static String CLIENT_CREDENTIAL = "client_credential";
+
+
+}

+ 28 - 0
game-module/game-sdk/src/main/java/com/zanxiang/sdk/common/util/HttpUtil.java

@@ -9,8 +9,11 @@ import java.io.InputStreamReader;
 import java.io.OutputStreamWriter;
 import java.net.URL;
 import java.net.URLConnection;
+import java.net.URLEncoder;
 import java.security.cert.CertificateException;
 import java.security.cert.X509Certificate;
+import java.util.Iterator;
+import java.util.Map;
 
 /**
  * 获取订单url
@@ -146,4 +149,29 @@ public class HttpUtil {
         }
     }
 
+    public static String postData(String urlStr, Map<String, String> data) {
+        return postData(urlStr, httpBuildQuery(data), null);
+    }
+
+    public static String httpBuildQuery(Map<String, String> array) {
+        String reString = null;
+        //遍历数组形成akey=avalue&bkey=bvalue&ckey=cvalue形式的的字符串
+        Iterator it = array.entrySet().iterator();
+        while (it.hasNext()) {
+            Map.Entry<String, String> entry = (Map.Entry) it.next();
+            String key = entry.getKey();
+            String value = entry.getValue();
+            reString += key + "=" + value + "&";
+        }
+        reString = reString.substring(0, reString.length() - 1);
+        //将得到的字符串进行处理得到目标格式的字符串
+        try {
+            reString = URLEncoder.encode(reString, "utf-8");
+        } catch (Exception e) {
+            throw new RuntimeException("http_build_query error:{}", e);
+        }
+        reString = reString.replace("%3D", "=").replace("%26", "&");
+        return reString;
+    }
+
 }

+ 57 - 2
game-module/game-sdk/src/main/java/com/zanxiang/sdk/controller/OrderController.java

@@ -1,20 +1,30 @@
 package com.zanxiang.sdk.controller;
 
 import com.zanxiang.common.domain.ResultMap;
+import com.zanxiang.common.enums.PayDeviceEnum;
+import com.zanxiang.common.exception.CustomException;
 import com.zanxiang.common.utils.StringUtils;
 import com.zanxiang.common.utils.bean.BeanUtils;
 import com.zanxiang.sdk.common.annotation.ValidLogin;
+import com.zanxiang.sdk.common.miPay.RequestParam;
 import com.zanxiang.sdk.domain.bo.PlatformOrderBO;
+import com.zanxiang.sdk.domain.dto.PlatformOrderDTO;
+import com.zanxiang.sdk.domain.params.MPayBalanceParam;
+import com.zanxiang.sdk.domain.params.OrderCheckInfoParam;
 import com.zanxiang.sdk.domain.params.PreOrderParam;
 import com.zanxiang.sdk.domain.params.UserData;
+import com.zanxiang.sdk.domain.vo.OrderCheckInfoVO;
+import com.zanxiang.sdk.domain.vo.PreOrderMIPayConfigVO;
 import com.zanxiang.sdk.domain.vo.PreOrderVO;
 import com.zanxiang.sdk.service.GameStrategyService;
+import com.zanxiang.sdk.service.MiPayService;
 import com.zanxiang.sdk.service.PlatformOrderService;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import io.swagger.annotations.ApiResponse;
 import io.swagger.annotations.ApiResponses;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
 
 /**
@@ -31,13 +41,18 @@ public class OrderController {
     @Autowired
     private GameStrategyService gameStrategyService;
 
+    @Autowired
+    private MiPayService miPayService;
+
     @ApiOperation(value = "订单生成")
     @PostMapping(value = "/preOrder")
     @ApiResponses(value = {@ApiResponse(code = 200, message = "成功", response = PreOrderVO.class)})
-    public ResultMap preOrder(@ValidLogin UserData user, @RequestBody PreOrderParam order) {
+    public ResultMap preOrder(@Validated @RequestBody PreOrderParam order, @ValidLogin UserData user) {
+        String userId = String.valueOf(user.getUserId());
         PlatformOrderBO orderBo = BeanUtils.copy(order, PlatformOrderBO.class);
+        orderBo.setUserId(userId);
+        orderBo.setPayDevice(user.getDeviceType().toString());
         Boolean paySwitch = gameStrategyService.paySwitch(user, orderBo);
-        orderBo.setIsSwitch(paySwitch);
         String orderId = orderService.create(orderBo);
         if (StringUtils.isEmpty(orderId)) {
             return ResultMap.error("生成订单失败");
@@ -45,6 +60,46 @@ public class OrderController {
         PreOrderVO data = new PreOrderVO();
         data.setOrderId(orderId);
         data.setPaySwitch(paySwitch);
+        //todo 此处切换与产品定义切换含义不一致 游戏是否切换支付方式临时为true
+        paySwitch = true;
+        if (paySwitch) {
+            RequestParam commonParam = miPayService.getCommonParam(Long.valueOf(order.getGameId()), String.valueOf(user.getUserId()));
+            //密钥不返回出去
+            commonParam.setApp_key("");
+            data.setPreOrderMIPayConfigVO(BeanUtils.copy(commonParam, PreOrderMIPayConfigVO.class));
+        }
+        orderBo.setIsSwitch(paySwitch);
+
         return ResultMap.ok(data);
     }
+
+
+    @ApiOperation(value = "小程序获取跳转支付信息")
+    @PostMapping(value = "/checkInfo")
+    @ApiResponses(value = {@ApiResponse(code = 200, message = "成功", response = PreOrderVO.class)})
+    public ResultMap checkInfo(@RequestBody OrderCheckInfoParam param, @ValidLogin UserData user) {
+        //不知道干嘛用的,临时放
+        String path = "pages/pay/index";
+        OrderCheckInfoVO result = new OrderCheckInfoVO();
+        result.setPath(path);
+        PlatformOrderDTO orderInfo = orderService.info(param.getOrderId(), param.getUserId());
+        if (PayDeviceEnum.MP.getCode().equals(user.getDeviceType())) {
+            RequestParam commonParam = miPayService.getCommonParam(orderInfo.getGameId(), param.getUserId());
+            if (StringUtils.isEmpty(commonParam.getAppid())) {
+                return ResultMap.error("获取小程序appId");
+            }
+            result.setMpId(commonParam.getAppid());
+        }
+        return ResultMap.ok(result);
+    }
+
+
+    @ApiOperation(value = "【米大师】查询余额")
+    @PostMapping(value = "/mPay_balance")
+    @ApiResponses(value = {@ApiResponse(code = 200, message = "成功", response = PreOrderVO.class)})
+    public ResultMap mPayBalance(@RequestBody MPayBalanceParam mPayBalanceParam, @ValidLogin UserData user) {
+        Boolean result = miPayService.midasGetBalance(user.getUserId(), mPayBalanceParam.getOrderId());
+        return ResultMap.ok(result);
+    }
+
 }

+ 15 - 0
game-module/game-sdk/src/main/java/com/zanxiang/sdk/controller/UserController.java

@@ -1,10 +1,13 @@
 package com.zanxiang.sdk.controller;
 
 import com.zanxiang.common.domain.ResultVo;
+import com.zanxiang.sdk.common.annotation.ValidLogin;
 import com.zanxiang.sdk.domain.params.UpdatePasswordParam;
 import com.zanxiang.sdk.domain.params.UserData;
 import com.zanxiang.sdk.domain.params.UserDetailParam;
+import com.zanxiang.sdk.domain.params.UserOauthlUpdateParam;
 import com.zanxiang.sdk.domain.vo.UserLoginVO;
+import com.zanxiang.sdk.service.UserOauthService;
 import com.zanxiang.sdk.service.UserService;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
@@ -30,6 +33,9 @@ public class UserController {
     @Autowired
     private UserService userService;
 
+    @Autowired
+    private UserOauthService userOauthService;
+
     @ApiOperation(value = "用户重置密码")
     @PostMapping("/update/password")
     @ApiResponses(value = {@ApiResponse(code = 200, message = "成功", response = UserLoginVO.class)})
@@ -43,4 +49,13 @@ public class UserController {
     public ResultVo getUserDetail(@Validated @RequestBody UserDetailParam userDetailParam, UserData userData) {
         return userService.getUserDetail(userDetailParam, userData);
     }
+
+    @ApiOperation(value = "更新用户授权信息")
+    @PostMapping("/update/user/Oauth")
+    @ApiResponses(value = {@ApiResponse(code = 200, message = "成功", response = UserLoginVO.class)})
+    public ResultVo updateUserDetail(@Validated @RequestBody UserOauthlUpdateParam param, @ValidLogin UserData userData) {
+        return userOauthService.updateUserOauth(param, userData);
+    }
+
+
 }

+ 15 - 0
game-module/game-sdk/src/main/java/com/zanxiang/sdk/domain/params/MPayBalanceParam.java

@@ -0,0 +1,15 @@
+package com.zanxiang.sdk.domain.params;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotNull;
+
+@Data
+public class MPayBalanceParam extends CommonParam {
+
+    @ApiModelProperty("orderId")
+    @NotNull(message = "orderId不可为空")
+    private String orderId;
+
+}

+ 22 - 0
game-module/game-sdk/src/main/java/com/zanxiang/sdk/domain/params/OrderCheckInfoParam.java

@@ -0,0 +1,22 @@
+package com.zanxiang.sdk.domain.params;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotNull;
+import java.math.BigDecimal;
+import java.util.Date;
+
+@Data
+public class OrderCheckInfoParam extends CommonParam {
+
+    @ApiModelProperty("orderId")
+    @NotNull(message = "orderId不可为空")
+    private String orderId;
+
+
+    @ApiModelProperty("userId")
+    @NotNull(message = "userId不可为空")
+    private String userId;
+
+}

+ 4 - 66
game-module/game-sdk/src/main/java/com/zanxiang/sdk/domain/params/PreOrderParam.java

@@ -1,13 +1,16 @@
 package com.zanxiang.sdk.domain.params;
 
 import io.swagger.annotations.ApiModelProperty;
+import lombok.AllArgsConstructor;
 import lombok.Data;
+import lombok.NoArgsConstructor;
 
 import javax.validation.constraints.NotNull;
 import java.math.BigDecimal;
-import java.util.Date;
 
 @Data
+@NoArgsConstructor
+@AllArgsConstructor
 public class PreOrderParam extends CommonParam {
 
     @ApiModelProperty("cpId")
@@ -18,22 +21,10 @@ public class PreOrderParam extends CommonParam {
     @NotNull(message = "cpOrderId不可为空")
     private String cpOrderId;
 
-    @ApiModelProperty("充值用户")
-    @NotNull(message = "userId不可为空")
-    private String userId;
-
-    @ApiModelProperty("游戏玩家ID")
-    @NotNull(message = "mgUserId不可为空")
-    private String mgUserId;
-
     @ApiModelProperty("角色id")
     @NotNull(message = "roleId不可为空")
     private String roleId;
 
-    @ApiModelProperty("游戏ID")
-    @NotNull(message = "gameId不可为空")
-    private String gameId;
-
     @ApiModelProperty("货物总价")
     @NotNull(message = "amount不可为空")
     private BigDecimal amount;
@@ -50,62 +41,9 @@ public class PreOrderParam extends CommonParam {
     @ApiModelProperty("游戏商品名称")
     private String productName;
 
-    @ApiModelProperty("优惠券抵扣")
-    private BigDecimal couponAmount;
-
-    @ApiModelProperty("平台币使用金额")
-    private BigDecimal ptbAmount;
-
-    @ApiModelProperty("游戏币使用余额")
-    private BigDecimal gmAmount;
-
-    @ApiModelProperty("使用积分")
-    private Integer integral;
-
-    @ApiModelProperty("使用积分抵多少钱")
-    private BigDecimal integralMoney;
-
-    @ApiModelProperty("返利数量 默认为0")
-    private BigDecimal rebateAmount;
-
-    @ApiModelProperty("支付平台返回交易订单号")
-    private String merchantOrderNo;
-
-    @ApiModelProperty("支付状态,1待支付,2 支付成功,-1 已取消")
-    private Integer status;
-
-    @ApiModelProperty("支付方式")
-    private String gamePaywayId;
-
-    @ApiModelProperty("支付时间")
-    private Date payTime;
-
-    @ApiModelProperty("通知次数")
-    private Integer cpNotifyCnt;
-
-    @ApiModelProperty("最近通知时间")
-    private Long lastCpNotifyTime;
-
-    @ApiModelProperty("客服处理: 2正常; 1纠纷")
-    private Integer isHandle;
-
-    @ApiModelProperty("是否已分成  1未分成 2 已分成")
-    private Integer isDistribute;
-
-    @ApiModelProperty("CP通知状态,1为待处理,2为成功,-1为失败")
-    private Integer cpStatus;
-
     @ApiModelProperty("CP附加参数")
     private String ext;
 
-    @ApiModelProperty("用户备注")
-    private String memNote;
-
-    @ApiModelProperty("管理员备注")
-    private String adminNote;
-
-    @ApiModelProperty("订单成功备注信息")
-    private String remark;
 
     @ApiModelProperty("渠道")
     private String channel;

+ 5 - 0
game-module/game-sdk/src/main/java/com/zanxiang/sdk/domain/params/UserData.java

@@ -1,5 +1,7 @@
 package com.zanxiang.sdk.domain.params;
 
+import com.zanxiang.common.enums.OsEnum;
+import com.zanxiang.common.utils.StringUtils;
 import lombok.AllArgsConstructor;
 import lombok.NoArgsConstructor;
 import lombok.Setter;
@@ -47,6 +49,9 @@ public class UserData implements Serializable {
     }
 
     public String getDeviceSystem() {
+        if (StringUtils.isEmpty(deviceSystem)) {
+            return OsEnum.SYSTEM_OTHER.getOs();
+        }
         return deviceSystem;
     }
 }

+ 41 - 0
game-module/game-sdk/src/main/java/com/zanxiang/sdk/domain/params/UserOauthlUpdateParam.java

@@ -0,0 +1,41 @@
+package com.zanxiang.sdk.domain.params;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import javax.validation.constraints.NotBlank;
+
+/**
+ * @author : lingfeng
+ * @time : 2022-06-17
+ * @description : 用户详情参数
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class UserOauthlUpdateParam extends CommonParam {
+
+    @ApiModelProperty(notes = "unionId")
+    @NotBlank(message = "唯一id")
+    private String unionId;
+
+
+    @ApiModelProperty(notes = "gender")
+    private String gender;
+
+
+    @ApiModelProperty(notes = "city")
+    private String city;
+
+
+    @ApiModelProperty(notes = "province")
+    private String province;
+
+
+    @ApiModelProperty(notes = "country")
+    private String country;
+
+
+    @ApiModelProperty(notes = "avatarUrl")
+    private String avatarUrl;
+}

+ 21 - 0
game-module/game-sdk/src/main/java/com/zanxiang/sdk/domain/vo/OrderCheckInfoVO.java

@@ -0,0 +1,21 @@
+package com.zanxiang.sdk.domain.vo;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+/**
+ * @author xufeng
+ * @date 2022/7/15 16:43
+ */
+@Data
+public class OrderCheckInfoVO {
+    @ApiModelProperty(notes = "小程序appId")
+    private String mpId;
+
+    @ApiModelProperty(notes = "路径")
+    private String path;
+
+    @ApiModelProperty(notes = "米大师支付配置")
+    private PreOrderMIPayConfigVO preOrderMIPayConfigVO;
+
+}

+ 15 - 0
game-module/game-sdk/src/main/java/com/zanxiang/sdk/domain/vo/PreOrderMIPayConfigVO.java

@@ -0,0 +1,15 @@
+package com.zanxiang.sdk.domain.vo;
+
+import com.zanxiang.sdk.common.miPay.RequestParam;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 预下单返回值
+ */
+@Data
+public class PreOrderMIPayConfigVO extends RequestParam {
+
+
+}

+ 3 - 0
game-module/game-sdk/src/main/java/com/zanxiang/sdk/domain/vo/PreOrderVO.java

@@ -16,4 +16,7 @@ public class PreOrderVO {
 
     @ApiModelProperty(notes = "支付是否切换 true 切换 false 不切换")
     private Boolean paySwitch;
+
+    @ApiModelProperty(notes = "米大师配置")
+    private PreOrderMIPayConfigVO preOrderMIPayConfigVO;
 }

+ 211 - 0
game-module/game-sdk/src/main/java/com/zanxiang/sdk/service/Impl/MiPayServiceImpl.java

@@ -0,0 +1,211 @@
+package com.zanxiang.sdk.service.Impl;
+
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.zanxiang.common.domain.MiPayConfig;
+import com.zanxiang.common.enums.HttpStatusEnum;
+import com.zanxiang.common.enums.StatusEnum;
+import com.zanxiang.common.exception.CustomException;
+import com.zanxiang.common.utils.StringUtils;
+import com.zanxiang.mybatis.entity.GamePayWay;
+import com.zanxiang.mybatis.entity.PayApplication;
+import com.zanxiang.mybatis.entity.PayBox;
+import com.zanxiang.mybatis.mapper.PayApplicationMapper;
+import com.zanxiang.mybatis.mapper.PayBoxMapper;
+import com.zanxiang.sdk.common.constant.RedisKeyConstant;
+import com.zanxiang.sdk.common.miPay.MiPayClient;
+import com.zanxiang.sdk.common.miPay.RequestParam;
+import com.zanxiang.sdk.common.miPay.UrlConstants;
+import com.zanxiang.sdk.common.util.RedisUtil;
+import com.zanxiang.sdk.domain.dto.PlatformOrderDTO;
+import com.zanxiang.sdk.service.GamePayWayService;
+import com.zanxiang.sdk.service.MiPayService;
+import com.zanxiang.sdk.service.PlatformOrderService;
+import lombok.extern.slf4j.Slf4j;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.util.HashMap;
+import java.util.Objects;
+
+/**
+ * 米大师服务实现
+ *
+ * @author xufeng
+ * @date 2022/7/14 16:33
+ */
+@Service
+@Slf4j
+public class MiPayServiceImpl implements MiPayService {
+    protected final Logger logger = LoggerFactory.getLogger(MiPayServiceImpl.class);
+
+    @Autowired
+    private RedisUtil<String> redisUtil;
+
+    @Autowired
+    private PlatformOrderService platformOrderService;
+
+    @Autowired
+    private GamePayWayService gamePayWayService;
+
+    @Resource
+    private MiPayClient miPayClient;
+
+    @Autowired
+    private PayApplicationMapper payApplicationMapper;
+
+    @Autowired
+    private PayBoxMapper payBoxMapper;
+
+    @Value("${spring.profiles.active}")
+    private String springActive;
+
+
+    @Override
+    public Boolean midasPay(Long userId, String orderId) {
+        PlatformOrderDTO orderInfo = platformOrderService.info(orderId);
+        if (Objects.isNull(orderInfo)) {
+            throw new CustomException(HttpStatusEnum.ORDER_NO_FIND);
+        }
+        if (orderInfo.getGameId() == null || orderInfo.getGameId() == 0) {
+            throw new CustomException(HttpStatusEnum.ORDER_GAME_ID_IS_NULL);
+        }
+        RequestParam commonParam = getCommonParam(orderInfo.getGameId(), orderInfo.getUserId());
+        commonParam.setBill_no(orderId);
+        HashMap<String, String> result = miPayClient.api(UrlConstants.PAY_URL, commonParam, null, null, null);
+        if (Objects.equals(HttpStatusEnum.SUCCESS.getCode().toString(), result.get("code"))) {
+            //成功
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    public Boolean midasCancelPay(Long userId, String orderId) {
+        PlatformOrderDTO orderInfo = platformOrderService.info(orderId);
+        if (Objects.isNull(orderInfo)) {
+            throw new CustomException(HttpStatusEnum.ORDER_NO_FIND);
+        }
+        if (orderInfo.getGameId() == null || orderInfo.getGameId() == 0) {
+            throw new CustomException(HttpStatusEnum.ORDER_GAME_ID_IS_NULL);
+        }
+        RequestParam commonParam = getCommonParam(orderInfo.getGameId(), orderInfo.getUserId());
+        commonParam.setBill_no(orderId);
+        HashMap<String, String> result = miPayClient.api(UrlConstants.CANCEL_URL, commonParam, null, null, null);
+        if (Objects.equals(HttpStatusEnum.SUCCESS.getCode().toString(), result.get("code"))) {
+            //成功
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    public Boolean midasGetBalance(Long userId, String orderId) {
+        PlatformOrderDTO orderInfo = platformOrderService.info(orderId);
+        if (Objects.isNull(orderInfo)) {
+            throw new CustomException(HttpStatusEnum.ORDER_NO_FIND);
+        }
+        if (orderInfo.getGameId() == null || orderInfo.getGameId() == 0) {
+            throw new CustomException(HttpStatusEnum.ORDER_GAME_ID_IS_NULL);
+        }
+        RequestParam commonParam = getCommonParam(orderInfo.getGameId(), orderInfo.getUserId());
+        commonParam.setBill_no(orderId);
+        commonParam.setPresent_counts(orderInfo.getProductCnt());
+        HashMap<String, String> result = miPayClient.api(UrlConstants.BALANCE_URL, commonParam, null, null, null);
+        if (Objects.equals(HttpStatusEnum.SUCCESS.getCode().toString(), result.get("code"))) {
+            //成功
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    public Boolean midasPresent(Long userId, String orderId, Integer presentCounts) {
+        PlatformOrderDTO orderInfo = platformOrderService.info(orderId);
+        if (Objects.isNull(orderInfo)) {
+            throw new CustomException(HttpStatusEnum.ORDER_NO_FIND);
+        }
+        if (orderInfo.getGameId() == null || orderInfo.getGameId() == 0) {
+            throw new CustomException(HttpStatusEnum.ORDER_GAME_ID_IS_NULL);
+        }
+        RequestParam commonParam = getCommonParam(orderInfo.getGameId(), orderInfo.getUserId());
+        commonParam.setBill_no(orderId);
+        commonParam.setPresent_counts(orderInfo.getProductCnt());
+        HashMap<String, String> result = miPayClient.api(UrlConstants.PRESENT_URL, commonParam, null, null, null);
+        if (Objects.equals(HttpStatusEnum.SUCCESS.getCode().toString(), result.get("code"))) {
+            //成功
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    public MiPayConfig midasConfig(Long gameId) {
+        GamePayWay one = gamePayWayService.getOne(new LambdaQueryWrapper<GamePayWay>()
+                .eq(GamePayWay::getGameId, gameId)
+                .eq(GamePayWay::getStatus, StatusEnum.YES.getCode())
+                .gt(GamePayWay::getPayBoxId, 0)
+                .last("limit 1")
+        );
+        if (Objects.isNull(one) || StringUtils.isEmpty(one.getPayConfig())) {
+            throw new CustomException(HttpStatusEnum.GET_CONFIG_ERROR);
+        }
+        return JSONObject.parseObject(one.getPayConfig(), MiPayConfig.class);
+    }
+
+
+    /**
+     * 请求通用参数生成
+     *
+     * @param gameId 游戏id
+     * @param userId 玩家
+     * @return RequestParam 请求参数
+     */
+    @Override
+    public RequestParam getCommonParam(Long gameId, String userId) {
+        GamePayWay one = gamePayWayService.getOne(new LambdaQueryWrapper<GamePayWay>()
+                .eq(GamePayWay::getGameId, gameId)
+                .eq(GamePayWay::getStatus, StatusEnum.YES.getCode())
+                .gt(GamePayWay::getPayBoxId, 0)
+                .last("limit 1")
+        );
+        if (Objects.isNull(one) || StringUtils.isEmpty(one.getPayConfig())) {
+            throw new CustomException(HttpStatusEnum.GET_CONFIG_ERROR);
+        }
+        //米大师支付配置
+        MiPayConfig miPayConfig = JSONObject.parseObject(one.getPayConfig(), MiPayConfig.class);
+        PayBox payBoxInfo = payBoxMapper.selectById(one.getPayBoxId());
+        if (Objects.isNull(payBoxInfo) || payBoxInfo.getPayApplicationId() == null || payBoxInfo.getPayApplicationId() <= 0) {
+            throw new CustomException(HttpStatusEnum.GET_PAY_BOX_ERROR);
+        }
+        PayApplication payApplicationInfo = payApplicationMapper.selectById(payBoxInfo.getPayApplicationId());
+        if (payApplicationInfo.getStatus() == StatusEnum.NO.getCode()) {
+            throw new CustomException(HttpStatusEnum.GET_PAY_BOX_ERROR);
+        }
+        String openId = redisUtil.getCache(RedisKeyConstant.WEIXIN_OPEN_ID + userId + "_" + gameId);
+        if (StringUtils.isEmpty(openId)) {
+            //todo 无openId情况
+            if (springActive.equals("dev")) {
+                openId = "1";
+            } else {
+                throw new CustomException(HttpStatusEnum.WEIXIN_OPEN_ID_NULL);
+            }
+        }
+        RequestParam requestParam = new RequestParam();
+        requestParam.setOpenid(openId);
+        requestParam.setAppid(payApplicationInfo.getAppId());
+        requestParam.setOffer_id(miPayConfig.getAppId());//实际上是米大师应用id
+        requestParam.setApp_key(miPayConfig.getAppKey());
+        //沙箱时使用沙箱key
+        if (requestParam.getIs_sand() == 1) {
+            requestParam.setApp_key(miPayConfig.getAppKeyDev());
+        }
+        return requestParam;
+    }
+
+
+}

+ 27 - 0
game-module/game-sdk/src/main/java/com/zanxiang/sdk/service/Impl/UserOauthServiceImpl.java

@@ -2,16 +2,23 @@ package com.zanxiang.sdk.service.Impl;
 
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.zanxiang.common.domain.ResultVo;
 import com.zanxiang.common.utils.bean.BeanUtils;
 import com.zanxiang.mybatis.entity.User;
 import com.zanxiang.mybatis.entity.UserOauth;
 import com.zanxiang.mybatis.mapper.UserOauthMapper;
 import com.zanxiang.sdk.domain.dto.UserOauthDTO;
+import com.zanxiang.sdk.domain.params.UserData;
+import com.zanxiang.sdk.domain.params.UserOauthlUpdateParam;
+import com.zanxiang.sdk.domain.vo.UserVO;
 import com.zanxiang.sdk.service.UserOauthService;
+import com.zanxiang.sdk.service.UserService;
 import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
 import java.util.Map;
+import java.util.Objects;
 
 /**
  * @author : lingfeng
@@ -22,6 +29,9 @@ import java.util.Map;
 @Service
 public class UserOauthServiceImpl extends ServiceImpl<UserOauthMapper, UserOauth> implements UserOauthService {
 
+    @Autowired
+    private UserService userService;
+
     /**
      * 根据openid查询用户授权信息
      *
@@ -59,4 +69,21 @@ public class UserOauthServiceImpl extends ServiceImpl<UserOauthMapper, UserOauth
         super.save(userOauth);
         return BeanUtils.copy(userOauth, UserOauthDTO.class);
     }
+
+    @Override
+    public ResultVo<UserVO> updateUserOauth(UserOauthlUpdateParam param, UserData userData) {
+        UserOauthDTO userOauth = getUserOauthByOpenId(param.getUnionId());
+        if (Objects.isNull(userOauth)) {
+            return ResultVo.fail("授权登录不存在");
+        }
+        UserOauth data = BeanUtils.copy(param, UserOauth.class);
+        data.setUserId(userData.getUserId());
+        data.setId(userOauth.getId());
+        super.updateById(data);
+        User user = userService.getById(userData.getUserId());
+        if (Objects.isNull(user)) {
+            return ResultVo.fail("获取用户信息失败");
+        }
+        return ResultVo.ok(BeanUtils.copy(user, UserVO.class));
+    }
 }

+ 1 - 0
game-module/game-sdk/src/main/java/com/zanxiang/sdk/service/Impl/UserServiceImpl.java

@@ -15,6 +15,7 @@ import com.zanxiang.sdk.domain.dto.UserTokenDTO;
 import com.zanxiang.sdk.domain.params.UpdatePasswordParam;
 import com.zanxiang.sdk.domain.params.UserData;
 import com.zanxiang.sdk.domain.params.UserDetailParam;
+import com.zanxiang.sdk.domain.params.UserOauthlUpdateParam;
 import com.zanxiang.sdk.domain.vo.UserVO;
 import com.zanxiang.sdk.service.UserService;
 import com.zanxiang.sdk.service.UserTokenService;

+ 69 - 0
game-module/game-sdk/src/main/java/com/zanxiang/sdk/service/MiPayService.java

@@ -0,0 +1,69 @@
+package com.zanxiang.sdk.service;
+
+import com.zanxiang.common.domain.MiPayConfig;
+import com.zanxiang.sdk.common.miPay.RequestParam;
+
+/**
+ * 米大师支付服务
+ *
+ * @author xufeng
+ * @date 2022-07-14
+ */
+public interface MiPayService {
+
+    /**
+     * 虚拟币扣除
+     *
+     * @param orderId 订单号
+     * @param userId  玩家id
+     * @return
+     */
+    Boolean midasPay(Long userId, String orderId);
+
+
+    /**
+     * 扣除取消
+     *
+     * @param orderId 订单号
+     * @param userId  玩家id
+     * @return
+     */
+    Boolean midasCancelPay(Long userId, String orderId);
+
+    /**
+     * 钱包余额查询
+     *
+     * @param orderId 订单号
+     * @param userId  玩家id
+     * @return
+     */
+    Boolean midasGetBalance(Long userId, String orderId);
+
+    /**
+     * 米大师赠送
+     *
+     * @param userId
+     * @param orderId
+     * @param presentCounts
+     * @return
+     */
+    Boolean midasPresent(Long userId, String orderId, Integer presentCounts);
+
+    /**
+     * 米大师配置
+     *
+     * @param gameId 游戏id
+     * @return
+     */
+    MiPayConfig midasConfig(Long gameId);
+
+    /**
+     * 米大师通过参数生成
+     *
+     * @param gameId 游戏id
+     * @param userId 玩家id
+     * @return
+     */
+    RequestParam getCommonParam(Long gameId, String userId);
+
+}

+ 13 - 0
game-module/game-sdk/src/main/java/com/zanxiang/sdk/service/UserOauthService.java

@@ -1,7 +1,11 @@
 package com.zanxiang.sdk.service;
 
+import com.zanxiang.common.domain.ResultVo;
 import com.zanxiang.mybatis.entity.User;
 import com.zanxiang.sdk.domain.dto.UserOauthDTO;
+import com.zanxiang.sdk.domain.params.UserData;
+import com.zanxiang.sdk.domain.params.UserOauthlUpdateParam;
+import com.zanxiang.sdk.domain.vo.UserVO;
 
 import java.util.Map;
 
@@ -28,4 +32,13 @@ public interface UserOauthService {
      * @return : 返回用户授权信息
      */
     UserOauthDTO createUserOauth(User user, Map<String, String> map);
+
+    /**
+     * 更新用户授权信息
+     *
+     * @param param
+     * @param userData
+     * @return
+     */
+    ResultVo<UserVO> updateUserOauth(UserOauthlUpdateParam param, UserData userData);
 }

+ 2 - 0
game-module/game-sdk/src/main/java/com/zanxiang/sdk/service/UserService.java

@@ -41,4 +41,6 @@ public interface UserService extends IService<User> {
      * @return : 返回用户信息
      */
     UserDTO getUserInfoByMobile(String mobile);
+
+
 }