Browse Source

接quick和361sdk

Jim 11 tháng trước cách đây
mục cha
commit
e9e74e66e5

+ 227 - 0
src/main/java/com/ljsd/channel/Mock361YXSDK.java

@@ -0,0 +1,227 @@
+package com.ljsd.channel;
+
+import com.google.gson.Gson;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import com.ljsd.util.BaseGlobal;
+import com.ljsd.util.TimeUtil;
+import com.ljsd.util.XmlParser;
+import com.mongodb.BasicDBObject;
+import com.mongodb.DBObject;
+import org.apache.http.HttpEntity;
+import org.apache.http.NameValuePair;
+import org.apache.http.client.entity.UrlEncodedFormEntity;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.client.utils.URIBuilder;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.message.BasicNameValuePair;
+import org.apache.http.util.EntityUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.servlet.http.HttpServletRequest;
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
+import java.nio.charset.StandardCharsets;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+public class Mock361YXSDK {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(Mock361YXSDK.class);
+    private static final String APP_ID="39bee2c821834c32";
+    private static final String LOGIN_KEY="3dc60d6756c04f4ca23c6addba1e400e";
+    private static final String PAY_KEY="befa74b8ed734b01afb34b64f56c8cc2";
+    private static final String VERIFY_API_URL="http://sdk.361yx.com/tools/gamefactor.ashx?action=factor_login";
+    private static final CloseableHttpClient httpClient = HttpClients.createDefault();
+    private final static String _COLLECTION_PAY = "pay";
+    private static final Gson GSON = new Gson();
+    public static boolean verifyUser(String uid) {
+        try {
+            Map<String, String> params = new HashMap<>();
+            params.put("app_id",APP_ID);
+            params.put("uid",uid);
+            params.put("timestamp",String.valueOf(TimeUtil.getTimeNow()));
+            params.put("pay_key", PAY_KEY);
+
+            // 构建排序后的查询字符串
+            String sortedQuery = buildSortedQuery(params);
+            LOGGER.info("排序后的查询字符串:{}", sortedQuery);
+            String sign = md5(sortedQuery);
+
+            // 域名+/tools/gamefactor.ashx?action=factor_login
+            List<NameValuePair> formParams = new ArrayList<>();
+            formParams.add(new BasicNameValuePair("app_id", APP_ID));       // app_id 参数
+            formParams.add(new BasicNameValuePair("uid", uid));             // uid 参数
+            formParams.add(new BasicNameValuePair("timestamp",  params.get("timestamp"))); // timestamp 参数
+            formParams.add(new BasicNameValuePair("sign", sign));
+            HttpPost httpPost  = new HttpPost(VERIFY_API_URL);
+            UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(formParams, StandardCharsets.UTF_8);
+            httpPost.setEntity(formEntity);
+            CloseableHttpResponse response = httpClient.execute(httpPost);
+
+            String responseStr = EntityUtils.toString(response.getEntity(), "UTF-8");
+            JsonObject jsonObject = GSON.fromJson(responseStr, JsonObject.class);
+            int status = jsonObject.get("status").getAsInt();
+            String realname = jsonObject.has("realname") ? jsonObject.get("realname").getAsString() : null;
+            String idcard = jsonObject.has("idcard") ? jsonObject.get("idcard").getAsString() : null;
+            String msg = jsonObject.has("msg") ? jsonObject.get("msg").getAsString() : null;
+            response.close();
+            if (status == 1) {
+                LOGGER.info("验证成功!真实姓名:{},身份证号:{}", realname, idcard);
+                return true;
+            } else {
+                LOGGER.error("验证失败,原因:{}", msg);
+                return false;
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+            LOGGER.error("361yx 验证异常:", e);
+            return false;
+        }
+
+    }
+
+    public static String md5(String input) throws NoSuchAlgorithmException {
+        MessageDigest md = MessageDigest.getInstance("MD5");
+
+        byte[] hashBytes = md.digest(input.getBytes(StandardCharsets.UTF_8));
+
+        StringBuilder hexString = new StringBuilder();
+        for (byte b : hashBytes) {
+            String hex = Integer.toHexString(0xFF & b);
+            if (hex.length() == 1) {
+                hexString.append('0'); // 补前导零(如 0x0A → "0a")
+            }
+            hexString.append(hex);
+        }
+       return hexString.toString();
+    }
+
+    public static boolean verifyCallback(HttpServletRequest request) throws NoSuchAlgorithmException {
+        String appId = request.getParameter("app_id");
+        String cpOrderId = request.getParameter("cp_order_id");
+        String orderAmount = request.getParameter("order_amount");
+        String orderId = request.getParameter("order_id");
+        String roleId = request.getParameter("role_id");
+        String serverId = request.getParameter("server_id");
+        String timestamp = request.getParameter("timestamp");
+        String uid = request.getParameter("uid");
+        String sign = request.getParameter("sign");
+        Map<String, String> params = new HashMap<>();
+        params.put("app_id",appId);
+        params.put("cp_order_id",cpOrderId);
+        params.put("order_amount",orderAmount);
+        params.put("order_id",  orderId);
+        params.put("role_id", roleId);
+        params.put("server_id", serverId);
+        params.put("timestamp", timestamp);
+        params.put("uid", uid);
+        params.put("pay_key", PAY_KEY); // 包含特殊字符
+
+        // 构建排序后的查询字符串
+        String sortedQuery = buildSortedQuery(params);
+        LOGGER.info("排序后的查询字符串:{}", sortedQuery);
+
+        String signCheck = md5(sortedQuery);
+        return signCheck.equals(sign);
+    }
+
+    public static String buildSortedQuery(Map<String, String> params) {
+        // 1. 分离 pay_key 和其他参数(其他参数需非空)
+        Map<String, String> otherParams = new HashMap<>();
+        String payKeyValue = params.get("pay_key");
+
+        // 过滤其他参数(非 pay_key 且值非空)
+        for (Map.Entry<String, String> entry : params.entrySet()) {
+            String key = entry.getKey();
+            String value = entry.getValue();
+            if (!"pay_key".equals(key) && value != null && !value.trim().isEmpty()) {
+                otherParams.put(key, value);
+            }
+        }
+
+        // 2. 对其他参数按键的 ASCII 字典序排序
+        List<String> sortedOtherKeys = otherParams.keySet().stream()
+                .sorted() // 按 String 自然顺序(ASCII 字典序)排序
+                .collect(Collectors.toList());
+
+        // 3. 拼接其他参数(已排序)
+        StringBuilder otherParamsStr = new StringBuilder();
+        for (String key : sortedOtherKeys) {
+            String value = otherParams.get(key);
+            try {
+                String encodedValue = URLEncoder.encode(value, StandardCharsets.UTF_8.name());
+                otherParamsStr.append(key).append("=").append(encodedValue).append("&");
+            } catch (UnsupportedEncodingException e) {
+                // 理论上不会触发,此处处理异常
+                otherParamsStr.append(key).append("=").append(value).append("&");
+            }
+        }
+        // 移除末尾多余的 &
+        if (otherParamsStr.length() > 0) {
+            otherParamsStr.deleteCharAt(otherParamsStr.length() - 1);
+        }
+
+        // 4. 拼接 pay_key(始终在最后)
+        StringBuilder finalQuery = new StringBuilder(otherParamsStr); // 初始化为其他参数的拼接结果
+
+        // 拼接 pay_key(如果有值)
+        if (payKeyValue != null && !payKeyValue.trim().isEmpty()) {
+            try {
+                String encodedPayKey = URLEncoder.encode(payKeyValue, StandardCharsets.UTF_8.name());
+                if (finalQuery.length() > 0) {
+                    finalQuery.append("&").append("pay_key=").append(encodedPayKey);
+                } else {
+                    finalQuery.append("pay_key=").append(encodedPayKey);
+                }
+            } catch (UnsupportedEncodingException e) {
+                if (finalQuery.length() > 0) {
+                    finalQuery.append("&").append("pay_key=").append(payKeyValue);
+                } else {
+                    finalQuery.append("pay_key=").append(payKeyValue);
+                }
+            }
+        }
+
+        return finalQuery.toString();
+    }
+
+    public static DBObject saveDB(HttpServletRequest request) throws Exception {
+        LOGGER.info("request = {}", request);
+
+        String orderId = request.getParameter("cp_order_id");
+        DBObject payInfo = new BasicDBObject();
+        payInfo.put("cporderId", orderId);
+
+        List<DBObject> payInfoList = BaseGlobal.getInstance().mongoDBPool.find(_COLLECTION_PAY, payInfo);
+        if (payInfoList.size() != 1) {
+            return null;
+        }
+        payInfo.put("billno", request.getParameter("order_id"));
+
+        payInfo.put("uid", request.getParameter("role_id"));
+        payInfo.put("openId", request.getParameter("open_id"));
+        payInfo.put("region", request.getParameter("server_id"));
+        payInfo.put("channel", "361yx");
+//        payInfo.put("gameorderId", request.getParameter("game_order"));
+//            dbObject.put("cporderId", platform);
+        payInfo.put("creattime",request.getParameter("pay_time"));
+        payInfo.put("callbaktime", TimeUtil.getTimeNow());
+        BaseGlobal.getInstance().mongoDBPool.save(_COLLECTION_PAY, payInfo);
+        return payInfo;
+    }
+
+    private static String generateSign(String appId, String appSecret, String userId) {
+        String raw = appId + appSecret + userId;
+        return raw.hashCode() + "";
+    }
+}

+ 121 - 0
src/main/java/com/ljsd/channel/MockQuickSDK.java

@@ -0,0 +1,121 @@
+package com.ljsd.channel;
+
+import com.ljsd.redis.RedisUtil;
+import com.ljsd.util.BaseGlobal;
+import com.ljsd.util.TimeUtil;
+import com.ljsd.util.XmlParser;
+import com.mongodb.BasicDBObject;
+import com.mongodb.DBObject;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.utils.URIBuilder;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.util.EntityUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.nio.charset.StandardCharsets;
+import java.security.MessageDigest;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+import static javax.management.Query.eq;
+
+public class MockQuickSDK {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(MockQuickSDK.class);
+    private static final String QUICK_SDK_PRODUCT_CODE="74323196251398220690098816635773";
+    private static final String QUICK_SDK_PRODUCT_KEY="20562534";
+    private static final String QUICK_SDK_CALLBACK_KEY="05803023623721638274057263988239";
+    private static final String QUICK_SDK_VERIFY_API_URL="https://checkuser.gamedachen.com/v2/checkUserInfo";
+    private static final CloseableHttpClient httpClient = HttpClients.createDefault();
+    private final static String _COLLECTION_PAY = "pay";
+    public static boolean verifyUser(String uid, String token) {
+        try {
+            URIBuilder uriBuilder = new URIBuilder(QUICK_SDK_VERIFY_API_URL);
+            uriBuilder.addParameter("token", token);
+            uriBuilder.addParameter("product_code", QUICK_SDK_PRODUCT_CODE);
+            uriBuilder.addParameter("uid", uid);
+            uriBuilder.addParameter("channel_code", ""); // 必须传渠道 ID
+
+            HttpGet httpGet = new HttpGet(uriBuilder.build().toString());
+            CloseableHttpResponse response = httpClient.execute(httpGet);
+
+            String result = EntityUtils.toString(response.getEntity());
+            response.close();
+            return result.equals("1");
+        } catch (Exception e) {
+            e.printStackTrace();
+            LOGGER.error("QuickSDK 验证异常:", e);
+            return false;
+        }
+
+    }
+
+    public static boolean verifyCallback(String nt_data, String sign, String md5Sign) {
+        if (nt_data == null || sign == null || md5Sign == null) {
+            LOGGER.error("参数不可为空,nt_data={}, sign={}, md5Sign={}", nt_data, sign, md5Sign);
+            return false;
+        }
+        String rawString = nt_data + sign + QUICK_SDK_CALLBACK_KEY;
+
+        try {
+            MessageDigest md = MessageDigest.getInstance("MD5");
+
+            byte[] hashBytes = md.digest(rawString.getBytes(StandardCharsets.UTF_8));
+
+            StringBuilder hexString = new StringBuilder();
+            for (byte b : hashBytes) {
+                String hex = Integer.toHexString(0xFF & b);
+                if (hex.length() == 1) {
+                    hexString.append('0'); // 补前导零(如 0x0A → "0a")
+                }
+                hexString.append(hex);
+            }
+            boolean success = hexString.toString().equals(md5Sign);
+            if (success) {
+
+            }
+            return hexString.toString().equals(md5Sign);
+        } catch (Exception e) {
+            e.printStackTrace();
+            LOGGER.error("MD5 算法不可用:", e);
+            return false;
+        }
+    }
+
+    public static DBObject saveDB(String nt_data) throws Exception {
+        Map<String, String> fields = XmlParser.parseNtData(nt_data);
+        String param = fields.get("extras_params");
+        LOGGER.info("param = {}", param);
+
+        String orderId = fields.get("game_order");
+        DBObject payInfo = new BasicDBObject();
+        payInfo.put("cporderId", orderId);
+
+        List<DBObject> payInfoList = BaseGlobal.getInstance().mongoDBPool.find(_COLLECTION_PAY, payInfo);
+        if (payInfoList.size() != 1) {
+            return null;
+        }
+        payInfo = new BasicDBObject();
+        payInfo.put("billno", fields.get("order_no"));
+
+        payInfo.put("uid", fields.get("channel_uid"));
+//        payInfo.put("openId", uid);
+//            dbObject.put("region", serverId);
+        payInfo.put("channel", "quick");
+//        payInfo.put("gameorderId", fields.get("game_order"));
+//            dbObject.put("cporderId", platform);
+        payInfo.put("creattime", fields.get("pay_time"));
+        payInfo.put("callbaktime", TimeUtil.getTimeNow());
+        BaseGlobal.getInstance().mongoDBPool.save(_COLLECTION_PAY, payInfo);
+        return payInfo;
+    }
+
+    private static String generateSign(String appId, String appSecret, String userId) {
+        String raw = appId + appSecret + userId;
+        return raw.hashCode() + "";
+    }
+}

+ 135 - 0
src/main/java/com/ljsd/controller/CreateOrderController.java

@@ -0,0 +1,135 @@
+package com.ljsd.controller;
+
+import com.google.gson.Gson;
+import com.ljsd.channel.Mock361YXSDK;
+import com.ljsd.channel.MockQuickSDK;
+import com.ljsd.pojo.ResMsg;
+import com.ljsd.util.BaseGlobal;
+import com.ljsd.util.StringUtils;
+import com.ljsd.util.TimeUtil;
+import com.mongodb.BasicDBObject;
+import com.mongodb.DBObject;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.utils.URIBuilder;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.util.EntityUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.security.SecureRandom;
+import java.util.HashMap;
+import java.util.Map;
+
+public class CreateOrderController extends HttpServlet {
+    private static final Logger LOGGER = LoggerFactory.getLogger(CreateOrderController.class);
+    private static Gson gson = new Gson();
+    private final static String _COLLECTION_PAY = "pay";
+
+    public CreateOrderController() {
+        super();
+    }
+
+    public void destroy() {
+        super.destroy();
+    }
+    public void doGet(HttpServletRequest request, HttpServletResponse response)
+            throws ServletException, IOException {
+        this.doPost(request, response);
+    }
+
+    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+        request.setCharacterEncoding("UTF-8");
+        response.setCharacterEncoding("UTF-8");
+        response.setContentType("application/json; charset=utf-8");
+        // /CreatOrder?openid=test001&uid=10000026&region=10001&channel=Android_QuickGame&pay_item=4000&price=1800
+        String uid = request.getParameter("uid");
+        String openId = request.getParameter("openid");
+        String serverId = request.getParameter("region");
+        String channel = request.getParameter("channel");
+        String payItem = request.getParameter("pay_item");
+        String price = request.getParameter("price");
+        LOGGER.info("CreateOrderController request = {}", request);
+        ResMsg resMsg = new ResMsg();
+        resMsg.setCode(1);
+        String orderId = generateOrderNumber(uid);
+
+        DBObject payInfo = new BasicDBObject();
+        payInfo.put("uid", uid);
+        payInfo.put("pay_item", payItem);
+        payInfo.put("region", serverId);
+        payInfo.put("channel", channel);
+        payInfo.put("cp_order_id", orderId);
+        payInfo.put("openid", openId);
+        payInfo.put("creattime", TimeUtil.getTimeNow());
+        payInfo.put("money", price);
+        BaseGlobal.getInstance().mongoDBPool.save(_COLLECTION_PAY, payInfo);
+
+        Map<String,String> parms = new HashMap<>();
+        parms.put("orderId", orderId);
+        resMsg.setParms(parms);
+        resMsg.setParms(parms);
+        resMsg.setCode(1);
+        try (PrintWriter out = response.getWriter();){
+            resMsg.setCode(0);
+            out.print(gson.toJson(resMsg));
+        }catch (Exception e){
+            e.printStackTrace();
+        }
+    }
+
+
+    // 订单号规则:玩家uid-6位随机数-校验码
+    // 订单号各部分长度(可根据需求调整)
+    private static final int RANDOM_LENGTH = 6;      // 随机数长度
+    /**
+     * 生成唯一订单号
+     * @param userId 用户ID(需为正整数)
+     * @return 订单号(格式:时间戳-用户ID-随机数-校验码)
+     */
+    public static String generateOrderNumber(String userId) {
+        // 1. 生成6位随机数(000000-999999)
+        String randomPart = generateRandomString(RANDOM_LENGTH);
+
+        // 2. 计算校验码(简单示例:前几位的和模100)
+        String checksum = calculateChecksum(userId + randomPart);
+
+        // 3. 拼接最终订单号
+        return String.join("-", userId, randomPart, checksum);
+    }
+
+    /**
+     * 生成指定长度的随机数字字符串
+     */
+    private static String generateRandomString(int length) {
+        SecureRandom random = new SecureRandom(); // 更安全的随机数生成器
+        StringBuilder sb = new StringBuilder();
+        for (int i = 0; i < length; i++) {
+            sb.append(random.nextInt(10)); // 0-9随机数
+        }
+        return sb.toString();
+    }
+
+    /**
+     * 计算简单校验码(示例:前N位之和模100)
+     * @param source 源字符串(如时间戳+用户ID+随机数)
+     * @return 校验码(2位数字)
+     */
+    private static String calculateChecksum(String source) {
+        int sum = 0;
+        for (char c : source.toCharArray()) {
+            if (Character.isDigit(c)) {
+                sum += Character.getNumericValue(c);
+            }
+        }
+        int checksum = sum % 100; // 模100得到两位数
+        return String.format("%02d", checksum);
+    }
+}

+ 1 - 1
src/main/java/com/ljsd/controller/GetNoticeController.java

@@ -69,7 +69,7 @@ public class GetNoticeController extends HttpServlet {
                 res = highLevelList.last();
             } else if(mediumLevelList.size() > 0){
                 res = mediumLevelList.last();
-            } else {
+            } else if (normalList.size() > 0) {
                 res = normalList.last();
             }
             Map<String, String> parms = new HashMap<>();

+ 3 - 3
src/main/java/com/ljsd/controller/GetUserController.java

@@ -181,9 +181,9 @@ public class GetUserController extends HttpServlet {
 
 
     public boolean vertify(HttpServletResponse response,HttpServletRequest request,String admin,String platform,String pid,String openId,String token){
-                    try {
-                        if(!KTSDKConstans.appsecret.equals(admin)) {
-                            if (isTestLan == 1) { //test
+        try {
+            if(!KTSDKConstans.appsecret.equals(admin)) {
+                if (isTestLan == 1) { //test
                     boolean result = loginVerfifyByTestLan(openId, token);
                     if (!result) {
                         //response.sendError(400, "verify fail");

+ 175 - 0
src/main/java/com/ljsd/controller/GetUserV2Controller.java

@@ -0,0 +1,175 @@
+package com.ljsd.controller;
+
+import com.alibaba.fastjson.JSONObject;
+import com.ljsd.redis.RedisKey;
+import com.ljsd.util.BaseGlobal;
+import com.ljsd.util.HttpUtils;
+import com.ljsd.util.KTSDKConstans;
+import com.ljsd.util.MHTSDKConstans;
+import com.mongodb.BasicDBObject;
+import com.mongodb.DBObject;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.*;
+
+public class GetUserV2Controller extends HttpServlet {
+    private final static String _COLLECTION_NAME = "user_info";
+    private static final Logger LOGGER = LoggerFactory.getLogger(GetUserV2Controller.class);
+
+    public GetUserV2Controller() {
+        super();
+    }
+
+    public void destroy() {
+        super.destroy();
+    }
+
+    public void doGet(HttpServletRequest request, HttpServletResponse response)
+            throws ServletException, IOException {
+        request.setCharacterEncoding("UTF-8");
+        response.setCharacterEncoding("UTF-8");
+        String openId = request.getParameter("openId");
+        if (openId == null || openId.isEmpty()) {
+            response.sendError(400, "openId is empety");
+            return;
+        }
+        String version = request.getParameter("version");
+        if (version == null)  {
+            version="未知版本号";
+        }
+        LOGGER.info("the opendId = {}, version{}",openId,version);
+        String serverId = request.getParameter("serverId");
+        if (serverId == null || serverId.isEmpty()) {
+            response.sendError(400, "serverId is empety");
+            return;
+        }
+        String token = request.getParameter("token");
+        if (token == null || serverId.isEmpty()) {
+            response.sendError(400, "token is empety");
+            return;
+        }
+        String platform = request.getParameter("platform"); //平台类型
+        if (platform == null || platform.isEmpty()) {
+            response.sendError(400, "platform is empety");
+            return;
+        }
+        String admin = request.getParameter("admin"); //平台类型
+
+        String gid = request.getParameter("gid"); //gid
+        String pid = request.getParameter("pid"); //pid
+
+        /*if (StringUtils.checkIsEmpty(admin)) {
+            response.sendError(400, "platform is empety");
+            return;
+        }*/
+        LOGGER.info("the opendId = {},token={},platform={}",openId,token,platform);
+        try {
+            boolean ok = verifyToken(openId, token);
+            if(!ok){
+                PrintWriter out = response.getWriter();
+                out.print("fail");//认证失败
+                out.flush();
+                out.close();
+                LOGGER.error("verify fail");
+                return;
+            }
+            response.setCharacterEncoding("UTF-8");
+            response.setContentType("application/json; charset=utf-8");
+            DBObject dbObject = new BasicDBObject();
+            dbObject.put("openId", openId);
+            dbObject.put("serverId", serverId);
+            dbObject.put("platform", platform);
+
+            int uid = 0;
+            List<DBObject> userInfos = BaseGlobal.getInstance().mongoDBPool.find(_COLLECTION_NAME, dbObject);
+            DBObject res = new BasicDBObject();
+            if (userInfos.size() == 0) {
+                uid = BaseGlobal.getInstance().mongoDBPool.inc("uid") + 10000000;
+                dbObject.put("uid", uid);
+                dbObject.put("_id", uid);
+                userInfos.add(dbObject);
+                if (gid != null && !gid.isEmpty()) {
+                    dbObject.put("gid", gid);
+                }
+                if (pid != null && !pid.isEmpty()) {
+                    dbObject.put("pid", pid);
+                }
+                BaseGlobal.getInstance().mongoDBPool.save(_COLLECTION_NAME, dbObject);
+
+                //记录日志,为了数据后台
+                logRegister(openId,uid,serverId);
+
+            }
+            Random random = new Random();
+            int utoken = Math.abs(random.nextInt());
+            uid = (int) userInfos.get(0).get("uid");
+            res.put("uid", uid);
+            res.put("token", utoken);
+            BaseGlobal.getInstance().redisApp.set(RedisKey.TOKEN, String.valueOf(uid), utoken, -1, false);
+            BaseGlobal.getInstance().redisApp.set(RedisKey.PIDGIDTEMP, String.valueOf(uid), pid+"#"+gid, -1, false);
+            //记录日志,为了数据后台
+            logLogin(openId,uid,serverId);
+
+
+            PrintWriter out = response.getWriter();
+            out.print(res);
+            out.flush();
+            out.close();
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+    //注册 用户id,角色id,serverid,时间 放到一个表里
+    private void logRegister(String openId,int uid,String serverId){
+        Date date = new Date();
+        long loginTime = date.getTime();
+        DBObject doc = new BasicDBObject();
+        DBObject doc1 = new BasicDBObject();
+        //doc.put("_id",);
+        doc1.put("openId",openId);
+        doc1.put("uid",uid);
+        doc1.put("serverId",serverId);
+        doc1.put("registerTime",loginTime);
+        doc.put("register",doc1);
+        BaseGlobal.getInstance().mongoDBPool.save("logRegister", doc);
+    }
+    //登录 用户id,角色id,serverid,时间 按天放到一个表里
+    private void logLogin(String openId,int uid,String serverId){
+        //DateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");
+        Date date = new Date();
+        //long loginTime = Long.parseLong(dateFormat.format(date));
+        long loginTime = date.getTime();
+        DBObject doc = new BasicDBObject();
+        DBObject doc1 = new BasicDBObject();
+        //doc.put("_id",);
+        doc1.put("openId",openId);
+        doc1.put("uid",uid);
+        doc1.put("serverId",serverId);
+        doc1.put("loginTime",loginTime);
+        doc.put("loginTime",doc1);
+        BaseGlobal.getInstance().mongoDBPool.save("logLogin", doc);
+    }
+
+    public void doPost(HttpServletRequest request, HttpServletResponse response)
+            throws ServletException, IOException {
+        this.doGet(request, response);
+    }
+
+    public static boolean verifyToken(String openId,String token) throws Exception {
+        String tokenInRedis = BaseGlobal.getInstance().redisApp.get(RedisKey.LOGIN_TOKEN, openId, String.class, -1);
+        LOGGER.info("tokenInRedis={}",tokenInRedis);
+        return token.equals(tokenInRedis);
+    }
+
+    public static void main(String[] args) {
+//        boolean mht = loginVerfify("MHT", "2318137", "be385683efe228aadac0c8b5822a6fba");
+    }
+
+}

+ 88 - 0
src/main/java/com/ljsd/controller/LoginV2Controller.java

@@ -0,0 +1,88 @@
+package com.ljsd.controller;
+
+import com.google.gson.Gson;
+import com.ljsd.channel.Mock361YXSDK;
+import com.ljsd.channel.MockQuickSDK;
+import com.ljsd.pojo.ResMsg;
+import com.ljsd.redis.RedisKey;
+import com.ljsd.util.BaseGlobal;
+import com.ljsd.util.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Random;
+
+public class LoginV2Controller extends HttpServlet {
+    private static final Logger LOGGER = LoggerFactory.getLogger(LoginV2Controller.class);
+    private static Gson gson = new Gson();
+
+    public LoginV2Controller() {
+        super();
+    }
+
+    public void destroy() {
+        super.destroy();
+    }
+    public void doGet(HttpServletRequest request, HttpServletResponse response)
+            throws ServletException, IOException {
+        this.doPost(request, response);
+    }
+    @Override
+    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+        request.setCharacterEncoding("UTF-8");
+        response.setCharacterEncoding("UTF-8");
+        response.setContentType("application/json; charset=utf-8");
+        String uid = request.getParameter("userId");
+        String token = request.getParameter("token");
+        String channel = request.getParameter("channel");
+        LOGGER.info("LoginV2Controller uid={}, token={}, channel={}",uid,token,channel);
+        ResMsg resMsg = new ResMsg();
+        resMsg.setCode(1);
+        try (PrintWriter out = response.getWriter()){
+            if(StringUtils.checkIsEmpty(uid) || StringUtils.checkIsEmpty(channel)){
+                resMsg.setMsg("参数不能为空");
+                out.print(gson.toJson(resMsg));
+                return;
+            }
+
+            boolean ok = false;
+            if (channel.equals("quick")) {
+                ok = MockQuickSDK.verifyUser(uid, token);
+            } else if (channel.equals("361yx")) {
+                ok = Mock361YXSDK.verifyUser(uid);
+            } else {
+                resMsg.setMsg("不支持该渠道");
+                out.print(gson.toJson(resMsg));
+                return;
+            }
+            if (!ok) {
+                resMsg.setMsg("登录验证失败");
+                out.print(gson.toJson(resMsg));
+                return;
+//                throw new RuntimeException("登录验证失败");
+            }
+
+            Map<String,String> parms = new HashMap<>();
+            parms.put("openId",uid);
+            int tokenKey = new Random().nextInt(1024) +10000;
+            parms.put("token",Integer.toString(tokenKey));
+            BaseGlobal.getInstance().redisApp.set(RedisKey.LOGIN_TOKEN,uid,tokenKey,-1, false);
+
+            int code = 0;
+            resMsg.setCode(code);//正常
+
+            resMsg.setParms(parms);
+            out.print(gson.toJson(resMsg));
+        }catch (Exception e){
+            e.printStackTrace();
+        }
+    }
+}

+ 120 - 0
src/main/java/com/ljsd/controller/PayCallbackController.java

@@ -0,0 +1,120 @@
+package com.ljsd.controller;
+
+import com.google.gson.Gson;
+import com.ljsd.channel.Mock361YXSDK;
+import com.ljsd.channel.MockQuickSDK;
+import com.ljsd.pojo.ResMsg;
+import com.ljsd.redis.RedisKey;
+import com.ljsd.util.BaseGlobal;
+import com.ljsd.util.StringUtils;
+import com.ljsd.util.TimeUtil;
+import com.ljsd.util.XmlParser;
+import com.mongodb.BasicDBObject;
+import com.mongodb.DBObject;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.utils.URIBuilder;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.util.EntityUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.net.URISyntaxException;
+import java.util.*;
+
+public class PayCallbackController extends HttpServlet {
+    private static final Logger LOGGER = LoggerFactory.getLogger(PayCallbackController.class);
+    private static Gson gson = new Gson();
+    private final static String _COLLECTION_PAY = "pay";
+    private static final CloseableHttpClient httpClient = HttpClients.createDefault();
+
+    public PayCallbackController() {
+        super();
+    }
+
+    public void destroy() {
+        super.destroy();
+    }
+    public void doGet(HttpServletRequest request, HttpServletResponse response)
+            throws ServletException, IOException {
+        this.doPost(request, response);
+    }
+
+    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+        request.setCharacterEncoding("UTF-8");
+        response.setCharacterEncoding("UTF-8");
+        response.setContentType("application/json; charset=utf-8");
+//        String uid = request.getParameter("userId");
+        String sign = request.getParameter("sign");
+        String nt_data = request.getParameter("nt_data");
+        String md5Sign = request.getParameter("md5Sign");
+        LOGGER.info("PayCallbackController request = {}", request);
+        ResMsg resMsg = new ResMsg();
+        resMsg.setCode(1);
+        DBObject payInfo = new BasicDBObject();
+        try (PrintWriter out = response.getWriter();){
+            boolean ok = false;
+            if(!StringUtils.checkIsEmpty(md5Sign) && !StringUtils.checkIsEmpty(nt_data) && !StringUtils.checkIsEmpty(sign)){
+                ok = MockQuickSDK.verifyCallback(nt_data, sign, md5Sign);
+                if (ok) {
+                    payInfo = MockQuickSDK.saveDB(nt_data);
+                }
+            } else if (!StringUtils.checkIsEmpty(request.getParameter("app_id"))) {
+                ok = Mock361YXSDK.verifyCallback(request);
+                if (ok) {
+                    payInfo = Mock361YXSDK.saveDB(request);
+                }
+            } else {
+                resMsg.setMsg("不支持该渠道");
+                out.print(gson.toJson(resMsg));
+                return;
+            }
+
+            if (!ok) {
+                resMsg.setMsg("支付sign验证失败");
+                out.print(gson.toJson(resMsg));
+                return;
+            }
+
+            // 订单入库, 结构根据gameserver的PayVo推测的
+            // mongo db:x5_tk_login collect:pay
+            // status 怀疑没有使用,发货成功后,会把handlestatus置为1
+            // 放在各sdk实例的saveDB中
+
+            // todo 通知发货
+            // todo 各区服分配端口
+            URIBuilder uriBuilder = new URIBuilder("127.0.0.1:7915/deliveryRecharge");
+            uriBuilder.addParameter("uid", (String) payInfo.get("uid"));
+            uriBuilder.addParameter("goodsId", (String) payInfo.get("pay_item"));
+            uriBuilder.addParameter("openId", (String) payInfo.get("open_id"));
+            uriBuilder.addParameter("orderId", (String) payInfo.get("cporderId"));
+            uriBuilder.addParameter("orderTime", String.valueOf((long) payInfo.get("creattime")));
+            uriBuilder.addParameter("amount", String.valueOf((int) payInfo.get("amount")));
+
+            HttpGet httpGet = new HttpGet(uriBuilder.build().toString());
+            CloseableHttpResponse resp = httpClient.execute(httpGet);
+
+            String result = EntityUtils.toString(resp.getEntity());
+            LOGGER.info("通知发货结果:{}", result);
+
+            resp.close();
+            if (!result.equals("1")){
+                resMsg.setCode(1);
+                resMsg.setMsg("发货失败");
+                return;
+            }
+            resMsg.setCode(0);
+            out.print(gson.toJson(resMsg));
+        }catch (Exception e){
+            e.printStackTrace();
+        }
+    }
+
+}

+ 7 - 0
src/main/java/com/ljsd/util/TimeUtil.java

@@ -74,4 +74,11 @@ public class TimeUtil {
         int week = calendar.get(Calendar.DAY_OF_WEEK) - 1;
         return (week == 0) ? 7 : week;
     }
+
+    public static long getTimeNow() {
+        long currentTimeMillis = System.currentTimeMillis();
+
+        // 转换为秒级时间戳(10位)
+        return currentTimeMillis / 1000;
+    }
 }

+ 54 - 0
src/main/java/com/ljsd/util/XmlParser.java

@@ -0,0 +1,54 @@
+package com.ljsd.util;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import java.io.ByteArrayInputStream;
+import java.util.HashMap;
+import java.util.Map;
+
+public class XmlParser {
+
+    /**
+     * 解析 nt_data XML 字符串,提取 message 下的所有字段
+     * @param xmlStr nt_data 的 XML 字符串(如用户提供的格式)
+     * @return 包含所有字段的 Map(键为字段名,值为字段值)
+     */
+    public static Map<String, String> parseNtData(String xmlStr) {
+        Map<String, String> result = new HashMap<>();
+        try {
+            // 1. 解析 XML 字符串为 Document 对象
+            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+            DocumentBuilder builder = factory.newDocumentBuilder();
+            Document doc = builder.parse(new ByteArrayInputStream(xmlStr.getBytes("UTF-8")));
+
+            // 2. 获取根元素 <quicksdk_message>
+            Element root = doc.getDocumentElement();
+
+            // 3. 获取 <message> 子元素
+            NodeList messageNodes = root.getElementsByTagName("message");
+            if (messageNodes.getLength() == 0) {
+                return result; // 无 message 节点,返回空 Map
+            }
+            Element messageElem = (Element) messageNodes.item(0);
+
+            // 4. 提取所有子节点的值(如 is_test、channel 等)
+            NodeList childNodes = messageElem.getChildNodes();
+            for (int i = 0; i < childNodes.getLength(); i++) {
+                Node node = childNodes.item(i);
+                if (node instanceof Element) { // 过滤文本节点(如换行符)
+                    String nodeName = node.getNodeName();
+                    String nodeValue = node.getTextContent().trim();
+                    result.put(nodeName, nodeValue);
+                }
+            }
+
+        } catch (Exception e) {
+            e.printStackTrace(); // 或记录日志
+        }
+        return result;
+    }
+}

+ 23 - 15
src/main/resources/application.properties

@@ -1,34 +1,42 @@
-#mogodb服务地址
 #mongodb_url = mongodb://admin:123456@120.92.119.145:27020/?&authSource=admin
 #mongodb_url = mongodb://ljkji54$^fj5K:dk3$k8G5^a67@10.2.0.3:27020/?&authSource=admin
 #mongodb_url = mongodb://root:123456@10.255.255.4:27020/?&authSource=admin
-mongodb_url = mongodb://root:kjm2022&WH@10.0.0.92:27020/?&authSource=admin
-#mongodb_name = m5_tk_login
+mongodb_url = mongodb://root:f7bd979b98fb334d@127.0.0.1:27017/?&authSource=admin
+mongodb_name = m5_tk_login
 #mongodb_name = m5_x1_login
-mongodb_name = x1_cn_test_login
-#与目标数据库可以建立的最大链接数
+#mongodb_name = x1_cn_test_login
+
+# ????????????????
 mongodb_maximumNumberOfConnections = 100
-#与数据库建立链接的超时时间 2分钟
+
+# ??????????????2???
 mongodb_connectTimeout = 1200000
-#一个线程成功获取到一个可用数据库之前的最大等待时间 3秒
+
+# ?????????????????????????3??
 mongodb_maxWaitTime = 30000
-#最多xx个线程等级一个链接,推荐配置为5
+
+# ??xx?????????????????5?
 mongodb_threadsAllowedToBlockForConnectionMultiplier = 5
-#最大空闲时间,为0时,表示没有限制
+
+# ???????0??????
 mongodb_maxConnectionIdleTime = 0
-#最大生存时间,为0时,表示没有限制
+
+# ???????0??????
 mongodb_maxConnectionLifeTime = 0
-#连接过期时间
+
+# ???????0??????
 mongodb_socketTimeout = 0
-#连接保持活跃
+
+# ??????????
 mongodb_socketKeepAlive = true
 
 
+# Redis ????
 #redis_host = 120.92.119.145
 #redis_host = 10.255.255.4
 redis_host = 127.0.0.1
-redis_port=6080
-redis_password=kjm2022@WH_redis
+redis_port=6379
+redis_password=f7bd979b98fb334d
 #redis_password=@emiplay_m5fangzhi_redis
 redis_maxTotal = 10
 redis_minIdle = 3
@@ -38,5 +46,5 @@ redis_testOnBorrow = false
 
 isTestLan = 1
 
-#防沉迷开关
+# ?????
 openAdultCheck = false

+ 40 - 0
src/main/webapp/WEB-INF/web.xml

@@ -80,6 +80,16 @@
         <url-pattern>/getUserInfo</url-pattern>
     </servlet-mapping>
 
+    <servlet>
+        <servlet-name>getUserV2</servlet-name>
+        <servlet-class>com.ljsd.controller.GetUserV2Controller</servlet-class>
+    </servlet>
+
+    <servlet-mapping>
+        <servlet-name>getUserV2</servlet-name>
+        <url-pattern>/getUserV2</url-pattern>
+    </servlet-mapping>
+
     <servlet>
         <servlet-name>registerUser</servlet-name>
         <servlet-class>com.ljsd.controller.UserRegisterController</servlet-class>
@@ -123,6 +133,36 @@
         <url-pattern>/userLogin</url-pattern>
     </servlet-mapping>
 
+    <servlet>
+        <servlet-name>loginV2</servlet-name>
+        <servlet-class>com.ljsd.controller.LoginV2Controller</servlet-class>
+    </servlet>
+
+    <servlet-mapping>
+        <servlet-name>loginV2</servlet-name>
+        <url-pattern>/loginV2</url-pattern>
+    </servlet-mapping>
+
+    <servlet>
+        <servlet-name>createOrder</servlet-name>
+        <servlet-class>com.ljsd.controller.CreateOrderController</servlet-class>
+    </servlet>
+
+    <servlet-mapping>
+        <servlet-name>createOrder</servlet-name>
+        <url-pattern>/createOrder</url-pattern>
+    </servlet-mapping>
+
+    <servlet>
+        <servlet-name>payCallback</servlet-name>
+        <servlet-class>com.ljsd.controller.PayCallbackController</servlet-class>
+    </servlet>
+
+    <servlet-mapping>
+        <servlet-name>payCallback</servlet-name>
+        <url-pattern>/payCallback</url-pattern>
+    </servlet-mapping>
+
     <servlet>
         <servlet-name>serverList</servlet-name>
         <servlet-class>com.ljsd.controller.ServerListController</servlet-class>