yujian
2019-12-31 db98bb27a9240893297531e1218239222c2ba9b1
Merge branch 'div' of ssh://193.112.35.168:29418/fanli-server into div
19个文件已修改
13个文件已添加
1648 ■■■■■ 已修改文件
fanli/src/main/java/com/yeshi/fanli/aspect/RequestSerializableAspect.java 17 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/main/java/com/yeshi/fanli/aspect/RequestSerializableServiceAspect.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/main/java/com/yeshi/fanli/aspect/WXMPSignValidateAspect.java 200 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/main/java/com/yeshi/fanli/controller/wxmp/v1/ConfigController.java 88 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/main/java/com/yeshi/fanli/controller/wxmp/v1/UserAccountController.java 273 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/main/java/com/yeshi/fanli/controller/wxmp/v1/UserController.java 55 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/main/java/com/yeshi/fanli/dto/WXMPAcceptData.java 83 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/main/java/com/yeshi/fanli/dto/user/wx/WXMPLoginData.java 104 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/main/java/com/yeshi/fanli/dto/user/wx/WXMPLoginResult.java 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/main/java/com/yeshi/fanli/entity/bus/user/UserInfo.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/main/java/com/yeshi/fanli/entity/common/JumpDetailV2.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/main/java/com/yeshi/fanli/entity/push/DeviceActive.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/main/java/com/yeshi/fanli/entity/system/BusinessSystem.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/main/java/com/yeshi/fanli/mapping/UserInfoMapper.xml 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/main/java/com/yeshi/fanli/service/impl/user/UserAccountServiceImpl.java 41 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/main/java/com/yeshi/fanli/service/impl/user/UserInfoModifyRecordServiceImpl.java 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/main/java/com/yeshi/fanli/service/impl/user/invite/ThreeSaleSerivceImpl.java 32 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/main/java/com/yeshi/fanli/service/impl/user/wx/WXMPUserLoginServiceImpl.java 190 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/main/java/com/yeshi/fanli/service/inter/config/BusinessSystemService.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/main/java/com/yeshi/fanli/service/inter/user/UserAccountService.java 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/main/java/com/yeshi/fanli/service/inter/user/invite/ThreeSaleSerivce.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/main/java/com/yeshi/fanli/service/inter/user/wx/WXMPUserLoginService.java 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/main/java/com/yeshi/fanli/util/Constant.java 59 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/main/java/com/yeshi/fanli/util/JumpDetailUtil.java 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/main/java/com/yeshi/fanli/util/RedisManager.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/test/java/org/fanli/elastic/Test_Query.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
pom.xml 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
utils/src/main/java/org/yeshi/utils/StringUtil.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
utils/src/main/java/org/yeshi/utils/entity/wx/WXMPSessionInfo.java 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
utils/src/main/java/org/yeshi/utils/entity/wx/WXMPUserInfo.java 92 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
utils/src/main/java/org/yeshi/utils/exception/WXMPException.java 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
utils/src/main/java/org/yeshi/utils/wx/WXXCXUtil.java 106 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/main/java/com/yeshi/fanli/aspect/RequestSerializableAspect.java
@@ -1,6 +1,5 @@
package com.yeshi.fanli.aspect;
import java.io.IOException;
import java.io.PrintWriter;
import java.lang.reflect.Method;
import java.util.HashMap;
@@ -63,7 +62,7 @@
    }
    @Around("execution(public * com.yeshi.fanli.controller.client.*.*.*(..))")
    public Object requestSerializable(ProceedingJoinPoint joinPoint) throws IOException {
    public Object requestSerializable(ProceedingJoinPoint joinPoint) throws Throwable {
        Signature signature = joinPoint.getSignature();
        MethodSignature methodSignature = (MethodSignature) signature;
        Method targetMethod = methodSignature.getMethod();
@@ -97,14 +96,14 @@
                        cacheKey = "rs-" + StringUtil.Md5(cacheKey);
                        // jiedis原子性做拦截
                        Jedis jedis = jedisPool.getResource();
                        long threadId= Thread.currentThread().getId();
                        long threadId = Thread.currentThread().getId();
                        try {
                            Constant.waitingThreadSet.add(threadId);
                            String result = null;
                            long startTime = System.currentTimeMillis();
                            // 等待响应
                            while (StringUtil.isNullOrEmpty(result)) {
                                result = jedis.set(cacheKey, "1", new SetParams().nx().ex(30));
                                if (StringUtil.isNullOrEmpty(result)) {
                                    try {
@@ -125,9 +124,6 @@
                            if (!StringUtil.isNullOrEmpty(result)) {
                                try {
                                    return joinPoint.proceed();
                                } catch (Throwable e) {
                                    e.printStackTrace();
                                    LogHelper.errorDetailInfo(e);
                                } finally {
                                    jedis.del(cacheKey);
                                    Constant.waitingThreadSet.remove(Thread.currentThread().getId());
@@ -138,12 +134,7 @@
                        }
                    }
                } catch (Exception e) {// 原子性保护出错
                    try {
                        return joinPoint.proceed();
                    } catch (Throwable e1) {
                        e.printStackTrace();
                        LogHelper.errorDetailInfo(e1);
                    }
                    return joinPoint.proceed();
                }
            }
fanli/src/main/java/com/yeshi/fanli/aspect/RequestSerializableServiceAspect.java
@@ -17,7 +17,6 @@
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.stereotype.Component;
import com.yeshi.fanli.log.LogHelper;
import com.yeshi.fanli.util.Constant;
import com.yeshi.fanli.util.StringUtil;
import com.yeshi.fanli.util.annotation.RequestSerializableByKeyService;
@@ -92,9 +91,6 @@
                            if (!StringUtil.isNullOrEmpty(result)) {
                                try {
                                    return joinPoint.proceed();
                                } catch (Throwable e) {
                                    e.printStackTrace();
                                    LogHelper.errorDetailInfo(e);
                                } finally {
                                    jedis.del(cacheKey);
                                    Constant.waitingThreadSet.remove(Thread.currentThread().getId());
@@ -105,12 +101,7 @@
                        }
                    }
                } catch (Exception e) {// 原子性保护出错
                    try {
                        return joinPoint.proceed();
                    } catch (Throwable e1) {
                        e.printStackTrace();
                        LogHelper.errorDetailInfo(e1);
                    }
                }
            }
        } catch (NoSuchMethodException e) {
fanli/src/main/java/com/yeshi/fanli/aspect/WXMPSignValidateAspect.java
New file
@@ -0,0 +1,200 @@
package com.yeshi.fanli.aspect;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.yeshi.utils.JsonUtil;
import com.yeshi.fanli.dto.WXMPAcceptData;
import com.yeshi.fanli.entity.accept.AcceptData;
import com.yeshi.fanli.log.LogHelper;
import com.yeshi.fanli.util.Constant;
import com.yeshi.fanli.util.StringUtil;
import com.yeshi.fanli.util.ThreadUtil;
import net.sf.json.JSONObject;
/**
 * 微信小程序接口签名验证
 *
 * @author Administrator
 *
 */
@Component
@Aspect
@Order(2)
public class WXMPSignValidateAspect {
    public static final String EDP = "execution(* com.yeshi.fanli.controller.wxmp.*.*.*(..))";
    public static String KEY = "";
    static {
        KEY = Constant.systemCommonConfig.getSignKey();
    }
    @Around(EDP)
    public Object testAround(ProceedingJoinPoint joinPoint) throws IOException {
        Object[] args = joinPoint.getArgs();
        PrintWriter out = null;
        ServletRequestAttributes servletContainer = (ServletRequestAttributes) RequestContextHolder
                .getRequestAttributes();
        out = servletContainer.getResponse().getWriter();
        HttpServletRequest request = servletContainer.getRequest();
        WXMPAcceptData acceptData = null;
        for (Object obj : args) {
            if (obj instanceof WXMPAcceptData) {
                acceptData = (WXMPAcceptData) obj;
            } else if (obj instanceof HttpServletRequest) {
                request = (HttpServletRequest) obj;
            }
        }
        boolean isRight = true;
        if (acceptData == null) {
            out.print(JsonUtil.loadFalseResult(-1, "签名错误"));
            return null;
        }
        isRight = signIsRight(request);
        // 签名是否正确
        if (isRight) {
            // 判断签名超时
            if (Math.abs((acceptData.getTimeStamp()) - System.currentTimeMillis()) > 1000 * 60 * 10) {
                JSONObject data = new JSONObject();
                data.put("code", -2);
                data.put("msg", "时间错误");
                out.print(data);
                out.close();
                return null;
            }
            final String url = request.getRequestURI();
            @SuppressWarnings("unchecked")
            final Map<String, Object> params = request.getParameterMap();
            ThreadUtil.run(new Runnable() {
                @Override
                public void run() {
                    // 记录请求日志
                    LogHelper.requestInfo(url, params);
                }
            });
            // 设置device
            if (!StringUtil.isNullOrEmpty(acceptData.getOpenId())) {
                acceptData.setDevice(acceptData.getAppId() + "-" + acceptData.getOpenId());
            }
            Object obj = null;
            try {
                long startTime = System.currentTimeMillis();
                obj = joinPoint.proceed(args);
                final long responseTime = System.currentTimeMillis() - startTime;
                // 记录大于2s的请求
                if (responseTime >= 2000) {
                    ThreadUtil.run(new Runnable() {
                        @Override
                        public void run() {
                            LogHelper.requestTime(url, params, responseTime);
                        }
                    });
                }
            } catch (Throwable e) {
                LogHelper.errorDetailInfo(e, getHttpServletParams(request), request.getRequestURI().toString());
                out.print(JsonUtil.loadFalseResult(90009, "服务器内部错误"));
            }
            return obj;
        } else {
            JSONObject data = new JSONObject();
            data.put("code", -1);
            data.put("msg", "签名错误");
            out.print(data);
            out.close();
            LogHelper.error("签名错误:" + request.getRequestURI() + "-" + getHttpServletParams(request));
            return null;
        }
    }
    /**
     *
     *
     * @param request
     * @return
     */
    @SuppressWarnings("unchecked")
    private boolean signIsRight(HttpServletRequest request) {
        Map<String, Object> map = request.getParameterMap();
        Iterator<String> its = map.keySet().iterator();
        List<String> list = new ArrayList<>();
        while (its.hasNext()) {
            String key = its.next();
            if (key.equalsIgnoreCase("sign")) {
                continue;
            }
            Object value = map.get(key);
            Object[] values = (Object[]) value;
            list.add(key + "=" + values[0].toString());
        }
        Collections.sort(list);
        String str = "";
        for (String st : list) {
            str += st + "&";
        }
        String sign = null;
        sign = StringUtil.Md5(str + Constant.WXMP_SIGN_KEY);
        if (sign.equalsIgnoreCase(request.getParameter("sign") + "")) {
            return true;
        } else {
            return false;
        }
    }
    /**
     * 获取请求参数信息
     *
     * @param request
     * @return
     */
    private String getHttpServletParams(HttpServletRequest request) {
        if (request == null) {
            return "";
        }
        Map map = request.getParameterMap();
        if (map != null) {
            Iterator<String> its = map.keySet().iterator();
            JSONObject json = new JSONObject();
            while (its.hasNext()) {
                String next = its.next();
                if (map.get(next) != null) {
                    Object[] objects = (Object[]) map.get(next);
                    if (objects != null && objects.length > 0) {
                        json.put(next, objects[0].toString());
                    }
                }
            }
            return json.toString();
        }
        return "";
    }
}
fanli/src/main/java/com/yeshi/fanli/controller/wxmp/v1/ConfigController.java
New file
@@ -0,0 +1,88 @@
package com.yeshi.fanli.controller.wxmp.v1;
import java.io.PrintWriter;
import java.util.List;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.yeshi.utils.IPUtil;
import org.yeshi.utils.JsonUtil;
import com.yeshi.fanli.dto.WXMPAcceptData;
import com.yeshi.fanli.entity.push.DeviceActive;
import com.yeshi.fanli.entity.system.BusinessSystem;
import com.yeshi.fanli.entity.system.SystemClientParams;
import com.yeshi.fanli.service.inter.config.BusinessSystemService;
import com.yeshi.fanli.service.inter.config.SystemClientParamsService;
import com.yeshi.fanli.service.inter.push.DeviceActiveService;
import com.yeshi.fanli.util.StringUtil;
import com.yeshi.fanli.util.ThreadUtil;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
@Controller("WXMPConfigController")
@RequestMapping("/wxmp/api/v1/config")
public class ConfigController {
    @Resource
    private SystemClientParamsService systemClientParamsService;
    @Resource
    private BusinessSystemService businessSystemService;
    @Resource
    private DeviceActiveService deviceActiveService;
    /**
     * 获取系统配置信息
     *
     * @param acceptData
     * @param code
     * @param out
     */
    @RequestMapping("getSystemClientConfig")
    public void getOpenId(WXMPAcceptData acceptData, HttpServletRequest request, PrintWriter out) {
        BusinessSystem system = businessSystemService.getBusinessSystemCache(acceptData.getPlatform(),
                acceptData.getAppId());
        if (system == null) {
            out.print("系统不存在");
            return;
        }
        List<SystemClientParams> systemClientParamsList = systemClientParamsService
                .getSystemClientParamsBySystemId(system.getId(), Integer.parseInt(acceptData.getVersion()));
        if (systemClientParamsList == null || systemClientParamsList.size() == 0) {
            out.print(JsonUtil.loadFalseResult("暂无数据"));
            return;
        }
        JSONArray array = new JSONArray();
        for (SystemClientParams params : systemClientParamsList) {
            JSONObject item = new JSONObject();
            item.put(params.getKey(), params.getValue());
        }
        out.print(JsonUtil.loadTrueResult(array));
        String ipInfo = IPUtil.getRemotIP(request) + ":" + request.getRemotePort();
        ThreadUtil.run(new Runnable() {
            @Override
            public void run() {
                if (!StringUtil.isNullOrEmpty(acceptData.getDevice())) {
                    // 安卓平台添加设备活跃记录
                    DeviceActive da = new DeviceActive();
                    da.setDevice(acceptData.getDevice());
                    da.setPlatform(DeviceActive.PLATFORM_WXMP);
                    da.setVersionCode(Integer.parseInt(acceptData.getVersion()));
                    da.setIpInfo(ipInfo);
                    da.setChannel("wxmp");
                    da.setMac(null);
                    deviceActiveService.addDeviceActive(da);
                }
            }
        });
    }
}
fanli/src/main/java/com/yeshi/fanli/controller/wxmp/v1/UserAccountController.java
New file
@@ -0,0 +1,273 @@
package com.yeshi.fanli.controller.wxmp.v1;
import java.io.PrintWriter;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.aspectj.weaver.JoinPointSignature;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.yeshi.utils.IPUtil;
import org.yeshi.utils.JsonUtil;
import org.yeshi.utils.entity.wx.WXMPSessionInfo;
import org.yeshi.utils.entity.wx.WXMPUserInfo;
import org.yeshi.utils.wx.WXXCXUtil;
import com.google.gson.Gson;
import com.yeshi.fanli.dto.WXMPAcceptData;
import com.yeshi.fanli.dto.user.wx.WXMPLoginData;
import com.yeshi.fanli.dto.user.wx.WXMPLoginResult;
import com.yeshi.fanli.entity.bus.user.UserInfo;
import com.yeshi.fanli.exception.user.UserAccountException;
import com.yeshi.fanli.exception.user.UserInfoExtraException;
import com.yeshi.fanli.service.inter.user.UserAccountService;
import com.yeshi.fanli.service.inter.user.UserInfoExtraService;
import com.yeshi.fanli.service.inter.user.UserInfoService;
import com.yeshi.fanli.service.inter.user.wx.WXMPUserLoginService;
import com.yeshi.fanli.util.Constant;
import com.yeshi.fanli.util.RedisManager;
import com.yeshi.fanli.util.StringUtil;
import com.yeshi.fanli.util.ThreadUtil;
import com.yeshi.fanli.util.account.UserUtil;
import net.sf.json.JSONObject;
@Controller("WXMPUserAccountController")
@RequestMapping("/wxmp/api/v1/useraccount")
public class UserAccountController {
    @Resource
    private UserInfoExtraService userInfoExtraService;
    @Resource
    private UserInfoService userInfoService;
    @Resource
    private UserAccountService userAccountService;
    @Resource
    private WXMPUserLoginService wxMPUserLoginService;
    @Resource
    private RedisManager redisManager;
    /**
     * 通过邀请码获取用户信息
     *
     * @param acceptData
     * @param inviteCode
     * @param out
     */
    @RequestMapping("getInviteCodeInfo")
    public void getInviteCodeInfo(WXMPAcceptData acceptData, String inviteCode, PrintWriter out) {
        if (StringUtil.isNullOrEmpty(inviteCode)) {
            out.print(JsonUtil.loadFalseResult("邀请码为空"));
            return;
        }
        try {
            UserInfo userInfo = userInfoExtraService.getUserByInviteCode(inviteCode);
            if (userInfo != null && userInfo.getState() == UserInfo.STATE_NORMAL) {
                JSONObject json = new JSONObject();
                json.put("id", userInfo.getId());
                json.put("nickName", userInfo.getNickName());
                json.put("portrait", userInfo.getPortrait());
                JSONObject data = new JSONObject();
                data.put("user", json);
                out.print(JsonUtil.loadTrueResult(data));
                return;
            }
        } catch (UserInfoExtraException e) {
        }
        out.print(JsonUtil.loadFalseResult("邀请码不存在"));
    }
    @RequestMapping("phoneLogin")
    public void phoneLogin(WXMPAcceptData acceptData, String code, String phoneEncryptedData, String phoneIv,
            String inviteCode, String userData, HttpServletRequest request, HttpSession session, PrintWriter out) {
        if (StringUtil.isNullOrEmpty(acceptData.getOpenId())) {
            out.print(JsonUtil.loadFalseResult("openId为空"));
            return;
        }
        if (StringUtil.isNullOrEmpty(phoneEncryptedData) || StringUtil.isNullOrEmpty(phoneIv)) {
            out.print(JsonUtil.loadFalseResult("电话加密数据为空"));
            return;
        }
        String sessionKey = null;
        WXMPSessionInfo sessionInfo = (WXMPSessionInfo) session.getAttribute(UserController.WXMP_SESSION_INFO_KEY);
        if (sessionInfo == null) {
            out.print(JsonUtil.loadFalseResult(90000, "请重新登录"));
            return;
        }
        sessionKey = sessionInfo.getSessionKey();
        if (StringUtil.isNullOrEmpty(sessionKey)) {
            out.print(JsonUtil.loadFalseResult("code无效"));
            return;
        }
        String phoneNumber = WXXCXUtil.getPhoneNumber(sessionKey, phoneEncryptedData, phoneIv);
        if (StringUtil.isNullOrEmpty(phoneNumber)) {
            out.print(JsonUtil.loadFalseResult("获取电话号码失败"));
            return;
        }
        UserInfo boss = null;
        if (!StringUtil.isNullOrEmpty(inviteCode)) {
            try {
                boss = userInfoExtraService.getUserByInviteCode(inviteCode);
            } catch (UserInfoExtraException e) {
                e.printStackTrace();
            }
            if (boss != null && boss.getState() != UserInfo.STATE_NORMAL)
                boss = null;
        }
        UserInfo lastUserInfo = null;
        if (!StringUtil.isNullOrEmpty(userData)) {
            String key = StringUtil.Md5("wxmp-user-login-" + acceptData.getAppId() + "-" + acceptData.getOpenId());
            String data = redisManager.getCommonString(key);
            if (!StringUtil.isNullOrEmpty(data)) {
                lastUserInfo = new Gson().fromJson(data, UserInfo.class);
            }
        }
        try {
            WXMPLoginResult result = wxMPUserLoginService.wxmpLogin(new WXMPLoginData.Builder(Constant.APPID)
                    .setBoss(boss).setLastUser(lastUserInfo).setPhone(phoneNumber).build());
            printWXMPLoginResult(acceptData.getAppId(), acceptData.getOpenId(), result, request, out);
        } catch (UserAccountException e) {
            out.print(JsonUtil.loadFalseResult(e.getCode(), e.getMsg()));
        }
    }
    @RequestMapping("wxLogin")
    public void wxLogin(WXMPAcceptData acceptData, String wxEncryptedData, String wxIv, String inviteCode,
            HttpServletRequest request, HttpSession session, PrintWriter out) {
        if (StringUtil.isNullOrEmpty(acceptData.getOpenId())) {
            out.print(JsonUtil.loadFalseResult("openId为空"));
            return;
        }
        if (StringUtil.isNullOrEmpty(wxEncryptedData) || StringUtil.isNullOrEmpty(wxIv)) {
            out.print(JsonUtil.loadFalseResult("微信用户加密数据为空"));
            return;
        }
        WXMPSessionInfo sessionInfo = (WXMPSessionInfo) session.getAttribute(UserController.WXMP_SESSION_INFO_KEY);
        if (sessionInfo == null) {
            out.print(JsonUtil.loadFalseResult(90000, "请重新登录"));
            return;
        }
        String sessionKey = sessionInfo.getSessionKey();
        if (StringUtil.isNullOrEmpty(sessionKey)) {
            out.print(JsonUtil.loadFalseResult("code无效"));
            return;
        }
        WXMPUserInfo userInfo = WXXCXUtil.getUserInfo(sessionKey, wxEncryptedData, wxIv);
        if (userInfo == null || StringUtil.isNullOrEmpty(userInfo.getUnionId())) {
            out.print(JsonUtil.loadFalseResult("获取微信信息失败"));
            return;
        }
        try {
            WXMPLoginResult result = wxMPUserLoginService
                    .wxmpLogin(new WXMPLoginData.Builder(Constant.APPID).setWxUser(userInfo).build());
            printWXMPLoginResult(acceptData.getAppId(), acceptData.getOpenId(), result, request, out);
        } catch (UserAccountException e) {
            out.print(JsonUtil.loadFalseResult(e.getCode(), e.getMsg()));
        }
    }
    @RequestMapping("bindInviteCode")
    public void bindInviteCode(WXMPAcceptData acceptData, String inviteCode, String userData,
            HttpServletRequest request, PrintWriter out) {
        if (StringUtil.isNullOrEmpty(acceptData.getOpenId())) {
            out.print(JsonUtil.loadFalseResult("openId为空"));
            return;
        }
        if (StringUtil.isNullOrEmpty(inviteCode)) {
            out.print(JsonUtil.loadFalseResult("邀请码为空"));
            return;
        }
        String key = StringUtil.Md5("wxmp-user-login-" + acceptData.getAppId() + "-" + acceptData.getOpenId());
        UserInfo user = new Gson().fromJson(redisManager.getCommonString(key), UserInfo.class);
        if (user == null) {
            out.print(JsonUtil.loadFalseResult("用户数据为空"));
            return;
        }
        UserInfo boss = null;
        if (!StringUtil.isNullOrEmpty(inviteCode)) {
            try {
                boss = userInfoExtraService.getUserByInviteCode(inviteCode);
            } catch (UserInfoExtraException e) {
                e.printStackTrace();
            }
            if (boss != null && boss.getState() != UserInfo.STATE_NORMAL)
                boss = null;
        }
        if (boss == null) {
            out.print(JsonUtil.loadFalseResult("邀请码有误"));
            return;
        }
        try {
            WXMPLoginResult result = wxMPUserLoginService
                    .wxmpLogin(new WXMPLoginData.Builder(Constant.APPID).setLastUser(user).setBoss(boss).build());
            printWXMPLoginResult(acceptData.getAppId(), acceptData.getOpenId(), result, request, out);
        } catch (UserAccountException e) {
            out.print(JsonUtil.loadFalseResult(e.getCode(), e.getMsg()));
        }
    }
    private void printWXMPLoginResult(String appId, String openId, WXMPLoginResult result, HttpServletRequest request,
            PrintWriter out) {
        JSONObject data = new JSONObject();
        String key = StringUtil.Md5("wxmp-user-login-" + appId + "-" + openId);
        switch (result.getCode()) {
        case WXMPLoginResult.CODE_SUCCESS:
            UserInfo user = userInfoService.selectAvailableByPrimaryKey(result.getUser().getId());
            data.put("user", UserUtil.filterForClientUser(user));
            data.put("type", 0);
            out.print(JsonUtil.loadTrueResult(data));
            final String ip = IPUtil.getRemotIP(request);
            final int port = request.getRemotePort();
            ThreadUtil.run(new Runnable() {
                @Override
                public void run() {// 登录成功
                    UserInfo update = new UserInfo(user.getId());
                    update.setLastLoginTime(System.currentTimeMillis());
                    update.setLastLoginIp(ip + ":" + port);
                    userAccountService.updateUserSelective(update);
                }
            });
            break;
        case WXMPLoginResult.CODE_BIND_PHONE:
            // 需要绑定电话号码
            redisManager.saveObj(result.getUser(), key, 60 * 5);// 只缓存5分钟
            data.put("userData", key);
            data.put("type", 2);
            break;
        case WXMPLoginResult.CODE_BIND_INVITE_CODE:
            redisManager.saveObj(result.getUser(), key, 60 * 5);// 只缓存5分钟
            data.put("userData", key);
            data.put("type", 1);
            break;
        }
        out.print(JsonUtil.loadTrueResult(data));
    }
}
fanli/src/main/java/com/yeshi/fanli/controller/wxmp/v1/UserController.java
New file
@@ -0,0 +1,55 @@
package com.yeshi.fanli.controller.wxmp.v1;
import java.io.PrintWriter;
import javax.annotation.Resource;
import javax.servlet.http.HttpSession;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.yeshi.utils.JsonUtil;
import org.yeshi.utils.entity.wx.WXMPSessionInfo;
import org.yeshi.utils.wx.WXXCXUtil;
import com.yeshi.fanli.dto.WXMPAcceptData;
import com.yeshi.fanli.service.inter.user.UserInfoExtraService;
import com.yeshi.fanli.util.Constant;
import com.yeshi.fanli.util.StringUtil;
import net.sf.json.JSONObject;
@Controller
@RequestMapping("/wxmp/api/v1/user")
public class UserController {
    public final static String WXMP_SESSION_INFO_KEY = "WXMP-SESSION-INFO";
    @Resource
    private UserInfoExtraService userInfoExtraService;
    /**
     * 获取openId
     *
     * @param acceptData
     * @param code
     * @param out
     */
    @RequestMapping("getOpenId")
    public void getOpenId(WXMPAcceptData acceptData, String code, HttpSession session, PrintWriter out) {
        if (StringUtil.isNullOrEmpty(code)) {
            out.print(JsonUtil.loadFalseResult("code为空"));
            return;
        }
        WXMPSessionInfo info = WXXCXUtil.getSessionInfo(Constant.WXMP_APP_INFO, code);
        if (info != null) {
            session.setAttribute(WXMP_SESSION_INFO_KEY, info);
            JSONObject data = new JSONObject();
            data.put("openId", info.getOpenId());
            out.print(JsonUtil.loadTrueResult(data));
        } else {
            out.print(JsonUtil.loadFalseResult("openId获取失败"));
        }
    }
}
fanli/src/main/java/com/yeshi/fanli/dto/WXMPAcceptData.java
New file
@@ -0,0 +1,83 @@
package com.yeshi.fanli.dto;
/**
 * 微信接口数据接收
 *
 * @author Administrator
 *
 */
public class WXMPAcceptData {
    private long timeStamp;// 时间戳
    private String sign;// 签名
    private String platform;// 客户端平台
    private String wxVersion;// 微信版本号
    private String version;// 小程序版本
    private String appId;//
    private String openId;
    private String device;
    public String getDevice() {
        return device;
    }
    public void setDevice(String device) {
        this.device = device;
    }
    public long getTimeStamp() {
        return timeStamp;
    }
    public void setTimeStamp(long timeStamp) {
        this.timeStamp = timeStamp;
    }
    public String getSign() {
        return sign;
    }
    public void setSign(String sign) {
        this.sign = sign;
    }
    public String getPlatform() {
        return platform;
    }
    public void setPlatform(String platform) {
        this.platform = platform;
    }
    public String getWxVersion() {
        return wxVersion;
    }
    public void setWxVersion(String wxVersion) {
        this.wxVersion = wxVersion;
    }
    public String getVersion() {
        return version;
    }
    public void setVersion(String version) {
        this.version = version;
    }
    public String getAppId() {
        return appId;
    }
    public void setAppId(String appId) {
        this.appId = appId;
    }
    public String getOpenId() {
        return openId;
    }
    public void setOpenId(String openId) {
        this.openId = openId;
    }
}
fanli/src/main/java/com/yeshi/fanli/dto/user/wx/WXMPLoginData.java
New file
@@ -0,0 +1,104 @@
package com.yeshi.fanli.dto.user.wx;
import org.yeshi.utils.entity.wx.WXMPUserInfo;
import com.yeshi.fanli.entity.bus.user.UserInfo;
public class WXMPLoginData {
    private UserInfo boss;
    private UserInfo lastUser;// 上次登录的信息
    private String phone;
    private WXMPUserInfo wxUser;
    private String appId;// 系统的appId
    private WXMPLoginData(Builder builder) {
        this.boss = builder.boss;
        this.lastUser = builder.lastUser;
        this.phone = builder.phone;
        this.wxUser = builder.wxUser;
        this.appId = builder.appId;
    }
    public static class Builder {
        private UserInfo boss;
        private UserInfo lastUser;// 上次登录的信息
        private String phone;
        private WXMPUserInfo wxUser;
        private String appId;// 系统的appId
        public Builder setAppId(String appId) {
            this.appId = appId;
            return this;
        }
        public Builder setBoss(UserInfo boss) {
            this.boss = boss;
            return this;
        }
        public Builder setLastUser(UserInfo lastUser) {
            this.lastUser = lastUser;
            return this;
        }
        public Builder setPhone(String phone) {
            this.phone = phone;
            return this;
        }
        public Builder setWxUser(WXMPUserInfo wxUser) {
            this.wxUser = wxUser;
            return this;
        }
        public Builder(String appId) {
            this.appId = appId;
        }
        public WXMPLoginData build() {
            return new WXMPLoginData(this);
        }
    }
    public UserInfo getBoss() {
        return boss;
    }
    public void setBoss(UserInfo boss) {
        this.boss = boss;
    }
    public UserInfo getLastUser() {
        return lastUser;
    }
    public void setLastUser(UserInfo lastUser) {
        this.lastUser = lastUser;
    }
    public String getPhone() {
        return phone;
    }
    public void setPhone(String phone) {
        this.phone = phone;
    }
    public WXMPUserInfo getWxUser() {
        return wxUser;
    }
    public void setWxUser(WXMPUserInfo wxUser) {
        this.wxUser = wxUser;
    }
    public String getAppId() {
        return appId;
    }
    public void setAppId(String appId) {
        this.appId = appId;
    }
}
fanli/src/main/java/com/yeshi/fanli/dto/user/wx/WXMPLoginResult.java
New file
@@ -0,0 +1,33 @@
package com.yeshi.fanli.dto.user.wx;
import com.yeshi.fanli.entity.bus.user.UserInfo;
public class WXMPLoginResult {
    public final static int CODE_SUCCESS = 0;// 登录成功
    public final static int CODE_BIND_PHONE = 1;// 绑定手机号
    public final static int CODE_BIND_INVITE_CODE = 2;// 需要绑定邀请码
    private int code;
    private UserInfo user;
    public WXMPLoginResult(int code, UserInfo user) {
        this.code = code;
        this.user = user;
    }
    public int getCode() {
        return code;
    }
    public void setCode(int code) {
        this.code = code;
    }
    public UserInfo getUser() {
        return user;
    }
    public void setUser(UserInfo user) {
        this.user = user;
    }
}
fanli/src/main/java/com/yeshi/fanli/entity/bus/user/UserInfo.java
@@ -121,6 +121,17 @@
    @Column(name = "state_desc")
    private String stateDesc;
    @Column(name = "platform")
    private String platform;//来源平台
    public String getPlatform() {
        return platform;
    }
    public void setPlatform(String platform) {
        this.platform = platform;
    }
    @Transient
    @Expose
fanli/src/main/java/com/yeshi/fanli/entity/common/JumpDetailV2.java
@@ -61,6 +61,17 @@
    private Integer minAndroidAppVersion;// 最小Android版本
    @org.yeshi.utils.mybatis.Column(name = "jp_min_ios_version")
    private Integer minIOSAppVersion;// 最小ios版本
    @org.yeshi.utils.mybatis.Column(name = "jp_path")
    private String path;//小程序路径
    public String getPath() {
        return path;
    }
    public void setPath(String path) {
        this.path = path;
    }
    public Integer getMinAndroidAppVersion() {
        return minAndroidAppVersion;
fanli/src/main/java/com/yeshi/fanli/entity/push/DeviceActive.java
@@ -10,6 +10,7 @@
    public static final int PLATFORM_ANDROID = 1;
    public static final int PLATFORM_IOS = 2;
    public static final int PLATFORM_WXMP = 4;//微信小程序
    @Column(name = "da_id")
    private Long id;
fanli/src/main/java/com/yeshi/fanli/entity/system/BusinessSystem.java
@@ -27,8 +27,6 @@
    @org.yeshi.utils.mybatis.Column(name="id")
    private Long id;
    
    @org.yeshi.utils.mybatis.Column(name="name")
    @Column(name = "`name`", length = 50)
    private String name;
fanli/src/main/java/com/yeshi/fanli/mapping/UserInfoMapper.xml
@@ -115,9 +115,9 @@
    </delete>
    <insert id="insert" parameterType="com.yeshi.fanli.entity.bus.user.UserInfo"
        useGeneratedKeys="true" keyProperty="id">insert into yeshi_ec_user
        (id,identifycode,login_type,wx_open_id,wx_union_id,nick_name,tbName,tbPic,wxName,wxPic,portrait,createtime,last_logintime,loginip,type,appid,my_hongBao,pay_password,sid,rank,phone,state,state_desc)
        (id,identifycode,login_type,wx_open_id,wx_union_id,nick_name,tbName,tbPic,wxName,wxPic,portrait,createtime,last_logintime,loginip,type,appid,my_hongBao,pay_password,sid,rank,phone,state,state_desc,platform)
        values
        (#{id,jdbcType=BIGINT},#{openid,jdbcType=VARCHAR},#{loginType,jdbcType=INTEGER},#{wxOpenId,jdbcType=VARCHAR},#{wxUnionId,jdbcType=VARCHAR},#{nickName,jdbcType=VARCHAR},#{tbName,jdbcType=VARCHAR},#{tbPic,jdbcType=VARCHAR},#{wxName,jdbcType=VARCHAR},#{wxPic,jdbcType=VARCHAR},#{portrait,jdbcType=VARCHAR},#{createtime,jdbcType=BIGINT},#{lastLoginTime,jdbcType=BIGINT},#{lastLoginIp,jdbcType=VARCHAR},#{type,jdbcType=INTEGER},#{appId,jdbcType=VARCHAR},#{myHongBao,jdbcType=DECIMAL},#{payPassword,jdbcType=VARCHAR},#{system.id,jdbcType=BIGINT},#{rank,jdbcType=INTEGER},#{phone,jdbcType=VARCHAR},#{state,jdbcType=INTEGER},#{stateDesc,jdbcType=VARCHAR})
        (#{id,jdbcType=BIGINT},#{openid,jdbcType=VARCHAR},#{loginType,jdbcType=INTEGER},#{wxOpenId,jdbcType=VARCHAR},#{wxUnionId,jdbcType=VARCHAR},#{nickName,jdbcType=VARCHAR},#{tbName,jdbcType=VARCHAR},#{tbPic,jdbcType=VARCHAR},#{wxName,jdbcType=VARCHAR},#{wxPic,jdbcType=VARCHAR},#{portrait,jdbcType=VARCHAR},#{createtime,jdbcType=BIGINT},#{lastLoginTime,jdbcType=BIGINT},#{lastLoginIp,jdbcType=VARCHAR},#{type,jdbcType=INTEGER},#{appId,jdbcType=VARCHAR},#{myHongBao,jdbcType=DECIMAL},#{payPassword,jdbcType=VARCHAR},#{system.id,jdbcType=BIGINT},#{rank,jdbcType=INTEGER},#{phone,jdbcType=VARCHAR},#{state,jdbcType=INTEGER},#{stateDesc,jdbcType=VARCHAR},#{platform,jdbcType=VARCHAR})
    </insert>
    <insert id="insertSelective" parameterType="com.yeshi.fanli.entity.bus.user.UserInfo"
        useGeneratedKeys="true" keyProperty="id">
@@ -146,6 +146,7 @@
            <if test="phone != null">phone,</if>
            <if test="state != null">state,</if>
            <if test="stateDesc != null">state_desc,</if>
            <if test="platform != null">platform,</if>
        </trim>
        values
        <trim prefix="(" suffix=")" suffixOverrides=",">
@@ -172,6 +173,7 @@
            <if test="phone != null">#{phone,jdbcType=VARCHAR},</if>
            <if test="state != null">#{state,jdbcType=INTEGER},</if>
            <if test="stateDesc != null">#{stateDesc,jdbcType=VARCHAR}</if>
            <if test="platform != null">#{platform,jdbcType=VARCHAR}</if>
        </trim>
    </insert>
    <update id="updateByPrimaryKey" parameterType="com.yeshi.fanli.entity.bus.user.UserInfo">update
@@ -742,7 +744,8 @@
        LEFT JOIN `yeshi_ec_user` u ON u.`id` = t.`uie_uid`
        WHERE <![CDATA[ t.uie_active_time < '2019-06-19']]>
        AND (t.`uie_mark` IS NULL OR t.`uie_mark` = '')
        AND u.`state` = 0 AND u.`my_hongBao`<![CDATA[> 1]]>
        AND u.`state` = 0 AND
        u.`my_hongBao`<![CDATA[> 1]]>
        AND u.`wx_open_id` IS NOT NULL AND <![CDATA[LENGTH(TRIM(u.`wx_open_id`)) > 0]]>
        AND u.`wx_open_id` NOT LIKE 'o_b9%'
        LIMIT #{start},#{count}
fanli/src/main/java/com/yeshi/fanli/service/impl/user/UserAccountServiceImpl.java
@@ -27,6 +27,8 @@
import com.yeshi.fanli.dao.mybatis.AccountMessageMapper;
import com.yeshi.fanli.dao.mybatis.UserConnectHistoryMapper;
import com.yeshi.fanli.dao.mybatis.UserInfoMapper;
import com.yeshi.fanli.dto.user.wx.WXMPLoginData;
import com.yeshi.fanli.dto.user.wx.WXMPLoginResult;
import com.yeshi.fanli.dto.wx.WXAccountInfoDTO;
import com.yeshi.fanli.entity.accept.AcceptData;
import com.yeshi.fanli.entity.bus.user.BindingAccount;
@@ -42,6 +44,7 @@
import com.yeshi.fanli.entity.bus.user.UserInfoModifyRecord.ModifyTypeEnum;
import com.yeshi.fanli.entity.bus.user.WeiXinUser;
import com.yeshi.fanli.exception.user.ForbiddenUserIdentifyCodeException;
import com.yeshi.fanli.exception.user.ThreeSaleException;
import com.yeshi.fanli.exception.user.UserAccountException;
import com.yeshi.fanli.log.LogHelper;
import com.yeshi.fanli.service.inter.money.extract.BindingAccountService;
@@ -122,7 +125,7 @@
    @Resource
    private UserInfoModifyRecordService userInfoModifyRecordService;
    @Transactional(rollbackFor=Exception.class)
    @Transactional(rollbackFor = Exception.class)
    @Override
    public LoginResult login(HttpServletRequest request, AcceptData acceptData, Boolean first, String appId,
            String code, String phone, UserInfo tbUserInfo, boolean wxinstall, int loginType)
@@ -158,8 +161,7 @@
                userInfo = getUserInfoByTaoBaoOpenId(appId, tbUserInfo.getOpenid());
                // 判断用户是否被删除
                if (userInfo != null && userInfo.getState() != null
                        && (userInfo.getState() == UserInfo.STATE_DELETE_OUT_OF_DATE
                                || userInfo.getState() == UserInfo.STATE_DELETE))
                        && (userInfo.getState() != UserInfo.STATE_NORMAL))
                    userInfo = null;
                if (userInfo == null) {// 原先的账号不存在
                    userInfo = new UserInfo();
@@ -203,8 +205,8 @@
                userInfo = getUserInfoByWXUnionId(appId, weiXinUser.getUnionid());
                // 判断用户是否被删除
                if (userInfo != null && userInfo.getState() != null
                        && (userInfo.getState() == UserInfo.STATE_DELETE_OUT_OF_DATE
                                || userInfo.getState() == UserInfo.STATE_DELETE))
                        && (userInfo.getState() != UserInfo.STATE_NORMAL
                            ))
                    userInfo = null;
                // 直接用的微信登录
                if (lastUser == null) {
@@ -342,8 +344,7 @@
                userInfo = getUserInfoByPhone(appId, phone);
                // 判断用户是否被删除
                if (userInfo != null && userInfo.getState() != null
                        && (userInfo.getState() == UserInfo.STATE_DELETE_OUT_OF_DATE
                                || userInfo.getState() == UserInfo.STATE_DELETE))
                        && (userInfo.getState() != UserInfo.STATE_NORMAL))
                    userInfo = null;
                if (userInfo == null) {// 原先的账号不存在
@@ -380,7 +381,7 @@
        }
    }
    @Transactional(rollbackFor=Exception.class)
    @Transactional(rollbackFor = Exception.class)
    @Override
    public LoginResult loginNoInstallWX(AcceptData acceptData, String appId, String code, String phone,
            UserInfo tbUserInfo, int loginType) throws UserAccountException {
@@ -432,8 +433,7 @@
        }
        // 判断用户是否被删除
        if (userInfo != null && userInfo.getState() != null && (userInfo.getState() == UserInfo.STATE_DELETE_OUT_OF_DATE
                || userInfo.getState() == UserInfo.STATE_DELETE))
        if (userInfo != null && userInfo.getState() != null && (userInfo.getState() != UserInfo.STATE_NORMAL))
            userInfo = null;
        if (userInfo != null) {
@@ -503,7 +503,7 @@
        connectUsers(mainUser, lessUser);
    }
    @Transactional(rollbackFor=Exception.class)
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void connectUsers(UserInfo mainUser, UserInfo lessUser) throws UserAccountException {
        mainUser = userInfoMapper.selectByPrimaryKeyForUpdate(mainUser.getId());
@@ -594,8 +594,7 @@
        List<UserInfo> list = userInfoMapper.listByAppIdAndWXUnionId(appId, unionId);
        // 剔除被删除掉的用户
        for (int i = 0; i < list.size(); i++) {
            if (list.get(i).getState() == UserInfo.STATE_DELETE
                    || list.get(i).getState() == UserInfo.STATE_DELETE_OUT_OF_DATE) {
            if (list.get(i).getState() == UserInfo.STATE_NORMAL) {
                list.remove(i);
                i--;
            }
@@ -622,8 +621,7 @@
        // 剔除被删除掉的用户
        for (int i = 0; i < list.size(); i++) {
            if (list.get(i).getState() == UserInfo.STATE_DELETE
                    || list.get(i).getState() == UserInfo.STATE_DELETE_OUT_OF_DATE) {
            if (list.get(i).getState() != UserInfo.STATE_NORMAL) {
                list.remove(i);
                i--;
            }
@@ -651,8 +649,7 @@
        // 剔除被删除掉的用户
        for (int i = 0; i < list.size(); i++) {
            if (list.get(i).getState() == UserInfo.STATE_DELETE
                    || list.get(i).getState() == UserInfo.STATE_DELETE_OUT_OF_DATE) {
            if (list.get(i).getState() !=UserInfo.STATE_NORMAL) {
                list.remove(i);
                i--;
            }
@@ -670,7 +667,7 @@
        userInfoMapper.updateByPrimaryKeySelective(userInfo);
    }
    @Transactional(rollbackFor=Exception.class)
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void register(UserInfo userInfo) throws UserAccountException {
        if (!StringUtil.isNullOrEmpty(userInfo.getPhone())) {
@@ -975,7 +972,7 @@
        return user.getPortrait();
    }
    @Transactional(rollbackFor=Exception.class)
    @Transactional(rollbackFor = Exception.class)
    @Override
    public UserInfo loginPhone(HttpServletRequest request, int loginType, String vcode, String phone, String appId)
            throws UserAccountException {
@@ -1075,7 +1072,7 @@
        throw new UserAccountException(10, "请稍后再试");
    }
    @Transactional(rollbackFor=Exception.class)
    @Transactional(rollbackFor = Exception.class)
    @Override
    public UserInfo loginWinXin(HttpServletRequest request, AcceptData acceptData, int loginType, String code,
            String appId) throws UserAccountException {
@@ -1180,7 +1177,7 @@
        throw new UserAccountException(10, "请稍后再试");
    }
    @Transactional(rollbackFor=Exception.class)
    @Transactional(rollbackFor = Exception.class)
    @Override
    public UserInfo loginWeiXinNew(HttpServletRequest request, AcceptData acceptData, int loginType, String wxCode,
            String appId) throws UserAccountException {
@@ -1574,4 +1571,6 @@
        // 插入记录
        userInfoDeleteRecordService.addDeleteRecord(uid, UserInfo.STATE_DELETE_OUT_OF_DATE, reason);
    }
}
fanli/src/main/java/com/yeshi/fanli/service/impl/user/UserInfoModifyRecordServiceImpl.java
@@ -112,7 +112,8 @@
                    }
                    Message message = MQMsgBodyFactory.create(MQTopicName.TOPIC_USER,
                            UserTopicTagEnum.userAccountBinding, mqMsg);
                    producer.send(message);
                    if (!Constant.IS_TEST)
                        producer.send(message);
                } else {// 修改
                    if (type == ModifyTypeEnum.portrait) {
                        Message message = MQMsgBodyFactory.create(MQTopicName.TOPIC_USER,
fanli/src/main/java/com/yeshi/fanli/service/impl/user/invite/ThreeSaleSerivceImpl.java
@@ -86,7 +86,7 @@
        return threeSaleMapper.selectBoss(uid);
    }
    @Transactional(rollbackFor=Exception.class)
    @Transactional(rollbackFor = Exception.class)
    public void bind(UserInfo worker, UserInfo inviter) throws ThreeSaleException {
        if (worker == null || inviter == null)
            throw new ThreeSaleException(1, "用户信息为空");
@@ -500,7 +500,7 @@
    }
    @Override
    @Transactional(rollbackFor=Exception.class)
    @Transactional(rollbackFor = Exception.class)
    public void bindRelationshipByInviteCode(UserInfo invitee, UserInfo inviter) throws ThreeSaleException {
        if (invitee == null || inviter == null)
            throw new ThreeSaleException(1, "用户信息为空");
@@ -520,11 +520,11 @@
    }
    @Override
    @Transactional(rollbackFor=Exception.class)
    public void bindRelationshipByWX(UserInfo invitee, Long inviterId)throws ThreeSaleException {
    @Transactional(rollbackFor = Exception.class)
    public void bindRelationshipByWX(UserInfo invitee, Long inviterId) throws ThreeSaleException {
        if (invitee == null || inviterId == null)
            throw new ThreeSaleException(1, "用户信息为空");
            // 新建立确定关系
        // 新建立确定关系
        ThreeSale threeSale = new ThreeSale();
        threeSale.setBoss(new UserInfo(inviterId));
        threeSale.setWorker(invitee);
@@ -538,7 +538,7 @@
        UserInfo boss = userInfoService.selectByPKey(threeSale.getBoss().getId());
        threeSale.setBoss(boss);
        threeSale.setWorker(invitee);
        // 邀请成功:消息、相关处理
        inviteSuccess(boss.getId(), invitee.getId(), threeSale);
    }
@@ -550,13 +550,13 @@
    private void inviteSuccess(Long bossId, Long workerId, ThreeSale threeSale) {
        // 邀请消息
        UserActiveLog activeLog = userActiveLogService.getUserLatestActiveInfo(bossId);
        if (activeLog != null && VersionUtil.greaterThan_2_0_5("appstore".equalsIgnoreCase(activeLog.getChannel()) ? "ios" : "android",
                activeLog.getVersionCode())) { // 2.1版本以上
        if (activeLog != null && VersionUtil.greaterThan_2_0_5(
                "appstore".equalsIgnoreCase(activeLog.getChannel()) ? "ios" : "android", activeLog.getVersionCode())) { // 2.1版本以上
            userInviteMsgNotificationService.inviteSuccess2_1(bossId, threeSale);
        } else { // 最初消息
            userInviteMsgNotificationService.inviteSuccess(threeSale.getBoss().getId(), threeSale);
        }
        executor.execute(new Runnable() {
            @Override
            public void run() {
@@ -565,9 +565,9 @@
            }
        });
        UserInviteMQMsg msg = new UserInviteMQMsg(bossId, workerId, null, new Date(), UserInviteMQMsg.STATE_SUCCESS);
        Message message = MQMsgBodyFactory.create(MQTopicName.TOPIC_USER, UserTopicTagEnum.inviteSuccess,
                msg);
        producer.send(message);
        Message message = MQMsgBodyFactory.create(MQTopicName.TOPIC_USER, UserTopicTagEnum.inviteSuccess, msg);
        if (!Constant.IS_TEST)
            producer.send(message);
    }
    /**
@@ -590,7 +590,7 @@
    public ThreeSale selectByWorkerId(Long workerId) {
        return threeSaleMapper.selectSuccessByWorkerId(workerId);
    }
    @Override
    public ThreeSale getNearRelationByBossIdAndWorkerId(Long bossId, Long workerId) {
        return threeSaleMapper.getNearRelationByBossIdAndWorkerId(bossId, workerId);
@@ -620,15 +620,15 @@
    public ThreeSale getByWorkerIdAndTime(Long workerId, long time) {
        return threeSaleMapper.getByWorkerIdAndTime(workerId, time);
    }
    @Override
    public void inviteSeparate(Long workerId, Long bossId) {
        threeSaleMapper.inviteSeparate(workerId, bossId);
    }
    @Override
    public long getTeamOrderNumByWorkerId(Long workerId) {
        return threeSaleMapper.getTeamOrderNumByWorkerId(workerId);
    }
}
fanli/src/main/java/com/yeshi/fanli/service/impl/user/wx/WXMPUserLoginServiceImpl.java
New file
@@ -0,0 +1,190 @@
package com.yeshi.fanli.service.impl.user.wx;
import javax.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.yeshi.fanli.dto.user.wx.WXMPLoginData;
import com.yeshi.fanli.dto.user.wx.WXMPLoginResult;
import com.yeshi.fanli.entity.bus.user.ForbiddenUserIdentifyCode;
import com.yeshi.fanli.entity.bus.user.ForbiddenUserIdentifyCode.ForbiddenUserIdentifyCodeTypeEnum;
import com.yeshi.fanli.entity.bus.user.UserInfo;
import com.yeshi.fanli.exception.user.ThreeSaleException;
import com.yeshi.fanli.exception.user.UserAccountException;
import com.yeshi.fanli.service.inter.user.ForbiddenUserIdentifyCodeService;
import com.yeshi.fanli.service.inter.user.UserAccountService;
import com.yeshi.fanli.service.inter.user.UserInfoService;
import com.yeshi.fanli.service.inter.user.invite.ThreeSaleSerivce;
import com.yeshi.fanli.service.inter.user.wx.WXMPUserLoginService;
import com.yeshi.fanli.util.Constant;
import com.yeshi.fanli.util.StringUtil;
@Service
public class WXMPUserLoginServiceImpl implements WXMPUserLoginService {
    @Resource
    private ThreeSaleSerivce threeSaleSerivce;
    @Resource
    private UserAccountService userAccountService;
    @Resource
    private UserInfoService userInfoService;
    @Resource
    private ForbiddenUserIdentifyCodeService forbiddenUserIdentifyCodeService;
    @Transactional(rollbackFor = Exception.class)
    @Override
    public WXMPLoginResult wxmpLogin(WXMPLoginData loginData) throws UserAccountException {
        if (!StringUtil.isNullOrEmpty(loginData.getPhone())) {// 电话号码登录
            ForbiddenUserIdentifyCode identifyCode1 = forbiddenUserIdentifyCodeService
                    .listByTypeAndIdentifyCode(ForbiddenUserIdentifyCodeTypeEnum.phone, loginData.getPhone());
            if (identifyCode1 != null && identifyCode1.getEffective() != null && identifyCode1.getEffective())
                throw new UserAccountException(Constant.CODE_FORBIDDEN_USER, Constant.FORBIDDEN_USER_REASON_DESC);
            if (loginData.getLastUser() != null) {// 电话号码绑定
                if (loginData.getLastUser().getId() != null) {// 绑定
                    // 绑定手机号
                    userAccountService.bindPhoneNew(loginData.getLastUser().getId(), loginData.getPhone());
                    // 判定是否激活
                    UserInfo boss = threeSaleSerivce.getBoss(loginData.getLastUser().getId());
                    if (boss == null) {// 需要绑定邀请码
                        return new WXMPLoginResult(WXMPLoginResult.CODE_BIND_INVITE_CODE,
                                userInfoService.getUserById(loginData.getLastUser().getId()));
                    } else {// 已经绑定过了
                        return new WXMPLoginResult(WXMPLoginResult.CODE_SUCCESS,
                                userInfoService.getUserById(loginData.getLastUser().getId()));
                    }
                } else {
                    UserInfo userInfo = new UserInfo();
                    userInfo.setAppId(loginData.getAppId());
                    userInfo.setNickName(Constant.systemCommonConfig.getDefaultNickName());
                    userInfo.setPortrait(Constant.systemCommonConfig.getDefaultPortrait());
                    userInfo.setPhone(loginData.getPhone());
                    if (!StringUtil.isNullOrEmpty(loginData.getLastUser().getNickName()))
                        userInfo.setNickName(loginData.getLastUser().getNickName());
                    if (!StringUtil.isNullOrEmpty(loginData.getLastUser().getPortrait()))
                        userInfo.setPortrait(loginData.getLastUser().getPortrait());
                    userInfo.setWxName(loginData.getLastUser().getWxName());
                    userInfo.setWxUnionId(loginData.getLastUser().getWxUnionId());
                    userInfo.setWxPic(loginData.getLastUser().getWxPic());
                    if (loginData.getBoss() == null) {
                        return new WXMPLoginResult(WXMPLoginResult.CODE_BIND_INVITE_CODE, userInfo);
                    }
                    userInfo.setLoginType(3);
                    // 创建用户
                    addUser(userInfo);
                    // 绑定上级
                    return bindInviteCode(loginData.getBoss(), userInfo);
                }
            } else {// 登录
                UserInfo userInfo = userAccountService.getUserInfoByPhone(loginData.getAppId(), loginData.getPhone());
                if (userInfo != null) {// 已存在的用户
                    UserInfo boss = threeSaleSerivce.getBoss(userInfo.getId());
                    if (boss == null) {// 需要绑定邀请码
                        if (loginData.getBoss() != null) {
                            // 绑定上级
                            return bindInviteCode(loginData.getBoss(), userInfo);
                        } else {
                            // 提示客户端需要绑定邀请码
                            return new WXMPLoginResult(WXMPLoginResult.CODE_BIND_INVITE_CODE,
                                    userInfoService.getUserById(userInfo.getId()));
                        }
                    }
                    return new WXMPLoginResult(WXMPLoginResult.CODE_SUCCESS, userInfo);
                } else {// 新用户
                    userInfo = new UserInfo();
                    userInfo.setAppId(loginData.getAppId());
                    userInfo.setNickName(Constant.systemCommonConfig.getDefaultNickName());
                    userInfo.setPortrait(Constant.systemCommonConfig.getDefaultPortrait());
                    userInfo.setPhone(loginData.getPhone());
                    userInfo.setPlatform("wxmp");
                    if (loginData.getBoss() != null) {
                        userInfo.setLoginType(3);
                        userInfo.setLastLoginTime(System.currentTimeMillis());
                        // 注册新用户
                        addUser(userInfo);
                        // 建立邀请关系
                        // 绑定上级
                        return bindInviteCode(loginData.getBoss(), userInfo);
                    } else {
                        // 提示客户端需要绑定邀请码
                        return new WXMPLoginResult(WXMPLoginResult.CODE_BIND_INVITE_CODE, userInfo);
                    }
                }
            }
        } else if (loginData.getWxUser() != null) {// 微信登录
            ForbiddenUserIdentifyCode identifyCode1 = forbiddenUserIdentifyCodeService.listByTypeAndIdentifyCode(
                    ForbiddenUserIdentifyCodeTypeEnum.wxUnionId, loginData.getWxUser().getUnionId());
            if (identifyCode1 != null && identifyCode1.getEffective() != null && identifyCode1.getEffective())
                throw new UserAccountException(Constant.CODE_FORBIDDEN_USER, Constant.FORBIDDEN_USER_REASON_DESC);
            UserInfo userInfo = userAccountService.getUserInfoByWXUnionId(loginData.getAppId(),
                    loginData.getWxUser().getUnionId());
            if (userInfo != null) {// 已存在的用户
                // 是否绑定了电话
                if (StringUtil.isNullOrEmpty(userInfo.getPhone())) {
                    return new WXMPLoginResult(WXMPLoginResult.CODE_BIND_PHONE, userInfo);
                }
                // 通过微信网页邀请关系进来的激活生效
                threeSaleSerivce.effective(userInfo);
                UserInfo boss = threeSaleSerivce.getBoss(userInfo.getId());
                if (boss == null) {// 需要绑定邀请码
                    // 提示客户端需要绑定邀请码
                    return new WXMPLoginResult(WXMPLoginResult.CODE_BIND_INVITE_CODE, userInfo);
                }
                // 登录成功
                return new WXMPLoginResult(WXMPLoginResult.CODE_SUCCESS, userInfo);
            } else {// 新用户
                userInfo = new UserInfo();
                userInfo.setAppId(loginData.getAppId());
                userInfo.setNickName(loginData.getWxUser().getNickName());
                userInfo.setPortrait(loginData.getWxUser().getAvatarUrl());
                userInfo.setWxUnionId(loginData.getWxUser().getUnionId());
                userInfo.setLoginType(2);
                // 提示绑定手机号
                return new WXMPLoginResult(WXMPLoginResult.CODE_BIND_PHONE, userInfo);
            }
        } else {
            if (loginData.getLastUser() != null && loginData.getBoss() != null) {// 邀请码绑定
                UserInfo userInfo = loginData.getLastUser();
                if (loginData.getLastUser().getId() == null) {// 新创建
                    addUser(userInfo);
                }
                return bindInviteCode(loginData.getBoss(), userInfo);
            } else {
                throw new UserAccountException(1, "数据不完整");
            }
        }
    }
    private void addUser(UserInfo userInfo) {
        userInfo.setPlatform("wxmp");
        userAccountService.addUser(userInfo);
    }
    private WXMPLoginResult bindInviteCode(UserInfo boss, UserInfo worker) throws UserAccountException {
        try {
            threeSaleSerivce.bind(worker, boss);
            return new WXMPLoginResult(WXMPLoginResult.CODE_SUCCESS, userInfoService.getUserById(worker.getId()));
        } catch (ThreeSaleException e) {
            throw new UserAccountException(201, "确定邀请关系失败");
        }
    }
}
fanli/src/main/java/com/yeshi/fanli/service/inter/config/BusinessSystemService.java
@@ -5,16 +5,16 @@
import com.yeshi.fanli.entity.system.BusinessSystem;
public interface BusinessSystemService {
    public BusinessSystem getBusinessSystem(String platform, String packages);
    public BusinessSystem getBusinessSystemCache(String platform, String packages);
    public List<BusinessSystem> getBusinessSystems();
    /**
     * 通过id查询
     *
     * @param id
     * @return
     */
fanli/src/main/java/com/yeshi/fanli/service/inter/user/UserAccountService.java
@@ -3,6 +3,8 @@
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import com.yeshi.fanli.dto.user.wx.WXMPLoginData;
import com.yeshi.fanli.dto.user.wx.WXMPLoginResult;
import com.yeshi.fanli.entity.accept.AcceptData;
import com.yeshi.fanli.entity.bus.user.LoginResult;
import com.yeshi.fanli.entity.bus.user.UserInfo;
@@ -26,8 +28,9 @@
     * @return
     * @throws UserAccountException
     */
    public LoginResult login(HttpServletRequest request,AcceptData acceptData,  Boolean first, String appId, String code, String phone,
            UserInfo tbUserInfo, boolean wxinstall, int loginType) throws UserAccountException;
    public LoginResult login(HttpServletRequest request, AcceptData acceptData, Boolean first, String appId,
            String code, String phone, UserInfo tbUserInfo, boolean wxinstall, int loginType)
            throws UserAccountException;
    /**
     * 没有安装微信时候的登录
@@ -40,8 +43,8 @@
     * @return
     * @throws UserAccountException
     */
    public LoginResult loginNoInstallWX(AcceptData acceptData, String appId, String code, String phone, UserInfo tbUserInfo, int loginType)
            throws UserAccountException;
    public LoginResult loginNoInstallWX(AcceptData acceptData, String appId, String code, String phone,
            UserInfo tbUserInfo, int loginType) throws UserAccountException;
    /**
     * 打通微信账号与其他类型的一个账号
@@ -153,7 +156,7 @@
     * @param uid
     * @param code
     */
    public void changeWXBind(AcceptData acceptData,Long uid, String code) throws UserAccountException;
    public void changeWXBind(AcceptData acceptData, Long uid, String code) throws UserAccountException;
    /**
     * 清理用户头像
@@ -171,6 +174,7 @@
    /**
     * 电话号码登录 1.5.3
     *
     * @param request
     * @param first
     * @param appId
@@ -178,11 +182,12 @@
     * @return
     * @throws UserAccountException
     */
    public UserInfo loginPhone(HttpServletRequest request, int loginType, String vcode, String phone,  String appId)
    public UserInfo loginPhone(HttpServletRequest request, int loginType, String vcode, String phone, String appId)
            throws UserAccountException;
    /**
     *微信登录 1.5.3
     * 微信登录 1.5.3
     *
     * @param request
     * @param first
     * @param appId
@@ -191,11 +196,12 @@
     * @return
     * @throws UserAccountException
     */
    public UserInfo loginWinXin(HttpServletRequest request,AcceptData acceptData,int loginType, String code, String appId)
            throws UserAccountException;
    public UserInfo loginWinXin(HttpServletRequest request, AcceptData acceptData, int loginType, String code,
            String appId) throws UserAccountException;
    /**
     *   绑定电话号码  V1.5.3
     * 绑定电话号码 V1.5.3
     *
     * @param uid
     * @param phone
     * @throws UserAccountException
@@ -203,15 +209,17 @@
    public void bindPhoneNew(Long uid, String phone) throws UserAccountException;
    /**
     *  绑定微信 V1.5.3
     * 绑定微信 V1.5.3
     *
     * @param uid
     * @param code
     * @throws UserAccountException
     */
    public void bindWeiXin(AcceptData acceptData,Long uid, String code) throws UserAccountException;
    public void bindWeiXin(AcceptData acceptData, Long uid, String code) throws UserAccountException;
    /**
     * 账户封禁
     *
     * @param uid
     * @param reason
     */
@@ -219,6 +227,7 @@
    /**
     * 封禁用户所有信息:手机号、微信、淘宝、支付宝
     *
     * @param uid
     * @param reason
     */
@@ -226,6 +235,7 @@
    /**
     * 删除账户
     *
     * @param uid
     * @param reason
     */
@@ -233,6 +243,7 @@
    /**
     * 长时间未登录账户删除
     *
     * @param uid
     * @param reason
     */
@@ -240,6 +251,7 @@
    /**
     * 2.0.1 新登录方式 -微信
     *
     * @param request
     * @param acceptData
     * @param loginType
@@ -248,10 +260,12 @@
     * @return
     * @throws UserAccountException
     */
    public UserInfo loginWeiXinNew(HttpServletRequest request, AcceptData acceptData, int loginType, String wxCode, String appId) throws UserAccountException;
    public UserInfo loginWeiXinNew(HttpServletRequest request, AcceptData acceptData, int loginType, String wxCode,
            String appId) throws UserAccountException;
    /**
     * 未注册之前绑定手机号
     *
     * @param phone
     * @param key
     * @param appId
@@ -261,4 +275,5 @@
     */
    public UserInfo bindPhoneToLogin(String phone, String key, String appId, HttpServletRequest request)
            throws UserAccountException;
}
fanli/src/main/java/com/yeshi/fanli/service/inter/user/invite/ThreeSaleSerivce.java
@@ -19,7 +19,7 @@
     */
    UserInfo getBoss(long uid);
    void bind(UserInfo invitee, UserInfo inviter) throws ThreeSaleException;
    void bind(UserInfo worker, UserInfo boss) throws ThreeSaleException;
    /**
     * 邀请关系生效
fanli/src/main/java/com/yeshi/fanli/service/inter/user/wx/WXMPUserLoginService.java
New file
@@ -0,0 +1,17 @@
package com.yeshi.fanli.service.inter.user.wx;
import com.yeshi.fanli.dto.user.wx.WXMPLoginData;
import com.yeshi.fanli.dto.user.wx.WXMPLoginResult;
import com.yeshi.fanli.exception.user.UserAccountException;
//小程序用户登录
public interface WXMPUserLoginService {
    /**
     * 微信小程序登录
     *
     * @param loginData
     * @return
     * @throws UserAccountException
     */
    public WXMPLoginResult wxmpLogin(WXMPLoginData loginData) throws UserAccountException;
}
fanli/src/main/java/com/yeshi/fanli/util/Constant.java
@@ -6,6 +6,7 @@
import java.util.Set;
import org.yeshi.utils.annotation.MapUtil;
import org.yeshi.utils.entity.wx.WXAPPInfo;
import com.yeshi.fanli.dto.wx.WXAccountInfoDTO;
import com.yeshi.fanli.entity.config.AlipayConfig;
@@ -24,8 +25,8 @@
    public static boolean IS_TEST = true;
    public static int PAGE_SIZE = 20;
    public static String YINGYONGBAO_LINK="https://a.app.qq.com/o/simple.jsp?pkgname=com.yeshi.ec.rebate";
    public static String YINGYONGBAO_LINK = "https://a.app.qq.com/o/simple.jsp?pkgname=com.yeshi.ec.rebate";
    public final static String UIDAESKEY = "WW782ss@8*px/%2v";
@@ -119,43 +120,42 @@
    public static final int GIVE_DAYS = 1;
    // 金币有效天数
    public static final int GOLD_COIN_VALID_DAYS = 30;
    // 微信自动提现金额
    public static final int AUTO_EXTRACT_MONEY = 1;
    // 微信自动提现最低余额
    public static final int AUTO_EXTRACT_MIN_SURPLUS = 2;
    // vip、红包、奖励券倒计时 2.1上线时间
    public static final String VIP_ONLINE_TIME = "2019-12-22";
    // 红包邀请奖励
    public static final String RED_PACK_ONLINE_TIME = "2019-12-14";
    // 一阶段:20天数限制
    // 一阶段:20天数限制
    public static final int ONE_STAGE_LIMIT_DAYS = 20;
    // 一阶段:立得现金3元
    // 一阶段:立得现金3元
    public static final BigDecimal ONE_STAGE_MONEY = new BigDecimal("3");
    // 二阶段:90天数限制
    // 二阶段:90天数限制
    public static final int TWO_STAGE_LIMIT_DAYS = 90;
    // 二阶段:-队友产生的订单中(自购+分享),邀请人累计产生≥1 元奖金
    // 二阶段:-队友产生的订单中(自购+分享),邀请人累计产生≥1 元奖金
    public static final BigDecimal TWO_STAGE_ORDER_REWARD_MIN = new BigDecimal("1");
    // 二阶段: 红包金额最少3元
    public static final BigDecimal TWO_STAGE_MONEY_MIN = new BigDecimal("3");
    // 二阶段:每次最多增加0.5
    // 二阶段:每次最多增加0.5
    public static final BigDecimal TWO_STAGE_MONEY_ADD = new BigDecimal("0.5");
    // 二阶段: 增加9次
    public static final int TWO_STAGE_MONEY_ADD_NUM = 9;
    public static final int TWO_STAGE_MONEY_ADD_NUM = 9;
    // 三阶段:连续奖励月数
    public static final int THREE_STAGE_REWARD_MONTH = 15;
    // 三阶段:-连续 15 个月好友每月“给你累计产生≥2 元奖 金”
    // 三阶段:-连续 15 个月好友每月“给你累计产生≥2 元奖 金”
    public static final BigDecimal THREE_STAGE_ORDER_REWARD_MIN = new BigDecimal("2");
    // 三阶段:红包奖励随机范围
    public static final double THREE_STAGE_RANDOM_MIN = 1.5;
    public static final double THREE_STAGE_RANDOM_MAX = 2;
    // 新人奖励连续天数
    public static final long TLJ_NEW_USER_DAYS = 7;
    // 新人奖励最高
@@ -168,21 +168,20 @@
    public static final int TLJ_NEW_USER_LIMIT = 10;
    // 新人定义: 自完成注册起10天内;
    public static final int TLJ_NEW_USER_DEFINE = 10;
    // vip奖励券券5张
    public static final int VIP_COUPON_REWARD_NUM = 30;
    // vip赠送免单券5张
    public static final int VIP_COUPON_GIVEFREE_NUM = 5;
    // vip赠送金币
    public static final int VIP_COLDCOIN_NUM = 1800;
    // 奖励券倒计时 - 天数
    public static final int COUPON_REWARD_LIMIT_DAY = 5;
    public static final int COUPON_REWARD_LIMIT_DAY = 5;
    // 专属邀请码申请直接粉丝限制
    public static final int INVITE_CODRE_TAILOR_LIMIT = 2;
    public static final int INVITE_CODRE_TAILOR_LIMIT = 2;
    public static WXGZConfig wxGZConfig;
    // 短信验证码配置
@@ -246,7 +245,15 @@
    public static final String WXHEADURL = "wx/headImg/";
    public static final String WEBPAGE_SIGN_KEY = "@?,223Hbb88lll";
    public static final String WXMP_SIGN_KEY="xyJBaNliK&*!uAIShEn8g@@";
    public static final String WXMP_USER_SIGN_KEY="xyJBaNliShEn8g@@";
    public static final WXAPPInfo WXMP_APP_INFO=new WXAPPInfo("wxc22f3bd53cb25012", "4c7b166fecb6d9f53837e993f2214673", "", "");
    // 新人抽奖-最大次数
    public static final int MAX_COUNT_LOTTERY_NEWBIES = 5;
@@ -329,8 +336,10 @@
            return 1;
        else if ("ios".equalsIgnoreCase(platform))
            return 2;
        else if ("wxmp".equalsIgnoreCase(platform))
            return 4;// 未知
        else
            return 0;// 未知
            return 0;
    }
    public static String getAppName(String platform, String version) {
fanli/src/main/java/com/yeshi/fanli/util/JumpDetailUtil.java
New file
@@ -0,0 +1,40 @@
package com.yeshi.fanli.util;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Iterator;
import com.yeshi.fanli.entity.common.JumpDetailV2;
import net.sf.json.JSONObject;
public class JumpDetailUtil {
    /**
     * 过滤小程序跳转参数
     *
     * @param detail
     * @param params
     * @return
     */
    public static JumpDetailV2 getWXMPJumDetail(JumpDetailV2 detail, JSONObject params) {
        String path = detail.getPath();
        if (params != null) {
            path += "?";
            for (Iterator<String> its = params.keys(); its.hasNext();) {
                String key = its.next();
                try {
                    path += (key + "=" + URLEncoder.encode(params.optString(key), "UTF-8") + "&");
                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                }
            }
        }
        if (path.endsWith("&"))
            path = path.substring(0, path.length() - 1);
        JumpDetailV2 v2 = new JumpDetailV2();
        v2.setPath(path);
        v2.setType(detail.getType());
        return v2;
    }
}
fanli/src/main/java/com/yeshi/fanli/util/RedisManager.java
@@ -568,7 +568,7 @@
     * @param key
     * @param seconds
     */
    public void saveObj(Class<?> clazz, String key, Integer seconds) {
    public void saveObj(Object clazz, String key, Integer seconds) {
        if (clazz == null)
            return;
        String value = new Gson().toJson(clazz);
fanli/src/test/java/org/fanli/elastic/Test_Query.java
@@ -49,7 +49,7 @@
    public void detele() {
        try {
            ESOrderDao dao = BeanUtil.getBean(ESOrderDao.class);
            dao.delete("1_102205518158-42030576999");
//            dao.delete("1_102205518158-42030576999");
            System.out.println("-------------结束-------------");
        } catch (Exception e) {
            e.printStackTrace();
pom.xml
@@ -1,6 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.yeshi</groupId>
@@ -334,7 +333,7 @@
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/javax.mail/mail -->
        <dependency>
@@ -551,29 +550,35 @@
        <!-- elasticsearch -->
        <dependency>
            <groupId>org.elasticsearch.client</groupId>
            <artifactId>transport</artifactId>
            <version>7.5.1</version>
        </dependency>
        <dependency>
            <groupId>org.elasticsearch.client</groupId>
            <artifactId >elasticsearch-rest-high-level-client</artifactId>
            <groupId>org.elasticsearch.client</groupId>
            <artifactId>transport</artifactId>
            <version>7.5.1</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-elasticsearch</artifactId>
            <version>3.2.3.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-api</artifactId>
            <version>2.11.2</version>
            <scope>compile</scope>
        </dependency>
            <groupId>org.elasticsearch.client</groupId>
            <artifactId>elasticsearch-rest-high-level-client</artifactId>
            <version>7.5.1</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-elasticsearch</artifactId>
            <version>3.2.3.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-api</artifactId>
            <version>2.11.2</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>org.bouncycastle</groupId>
            <artifactId>bcprov-jdk16</artifactId>
            <version>1.46</version>
        </dependency>
    </dependencies>
    <build>
utils/src/main/java/org/yeshi/utils/StringUtil.java
@@ -237,6 +237,7 @@
        Object retObj = mainMethod.invoke(null, new Object[] { input });
        return (String) retObj;
    }
    /**
     * BASE64解密
utils/src/main/java/org/yeshi/utils/entity/wx/WXMPSessionInfo.java
New file
@@ -0,0 +1,38 @@
package org.yeshi.utils.entity.wx;
public class WXMPSessionInfo {
    private String openId;
    private String sessionKey;
    private String unionId;
    public WXMPSessionInfo(String openId, String sessionKey, String unionId) {
        this.openId = openId;
        this.sessionKey = sessionKey;
        this.unionId = unionId;
    }
    public String getOpenId() {
        return openId;
    }
    public void setOpenId(String openId) {
        this.openId = openId;
    }
    public String getSessionKey() {
        return sessionKey;
    }
    public void setSessionKey(String sessionKey) {
        this.sessionKey = sessionKey;
    }
    public String getUnionId() {
        return unionId;
    }
    public void setUnionId(String unionId) {
        this.unionId = unionId;
    }
}
utils/src/main/java/org/yeshi/utils/entity/wx/WXMPUserInfo.java
New file
@@ -0,0 +1,92 @@
package org.yeshi.utils.entity.wx;
/**
 * 微信小程序用户信息
 *
 * @author Administrator
 *
 */
public class WXMPUserInfo {
    private String openId;
    private String unionId;
    private String nickName;// 昵称
    private Integer gender;// 性别
    private String language;
    private String city;
    private String province;
    private String country;
    private String avatarUrl;// 头像
    public String getOpenId() {
        return openId;
    }
    public void setOpenId(String openId) {
        this.openId = openId;
    }
    public String getUnionId() {
        return unionId;
    }
    public void setUnionId(String unionId) {
        this.unionId = unionId;
    }
    public String getNickName() {
        return nickName;
    }
    public void setNickName(String nickName) {
        this.nickName = nickName;
    }
    public Integer getGender() {
        return gender;
    }
    public void setGender(Integer gender) {
        this.gender = gender;
    }
    public String getLanguage() {
        return language;
    }
    public void setLanguage(String language) {
        this.language = language;
    }
    public String getCity() {
        return city;
    }
    public void setCity(String city) {
        this.city = city;
    }
    public String getProvince() {
        return province;
    }
    public void setProvince(String province) {
        this.province = province;
    }
    public String getCountry() {
        return country;
    }
    public void setCountry(String country) {
        this.country = country;
    }
    public String getAvatarUrl() {
        return avatarUrl;
    }
    public void setAvatarUrl(String avatarUrl) {
        this.avatarUrl = avatarUrl;
    }
}
utils/src/main/java/org/yeshi/utils/exception/WXMPException.java
New file
@@ -0,0 +1,33 @@
package org.yeshi.utils.exception;
/**
 * 微信小程序异常
 * @author Administrator
 *
 */
public class WXMPException extends Exception {
    private static final long serialVersionUID = 1L;
    private int code;
    private String msg;
    public int getCode() {
        return code;
    }
    public String getMsg() {
        return msg;
    }
    public WXMPException(int code, String msg) {
        this.code = code;
        this.msg = msg;
    }
    public WXMPException() {
    }
    @Override
    public String getMessage() {
        return this.msg;
    }
}
utils/src/main/java/org/yeshi/utils/wx/WXXCXUtil.java
@@ -1,8 +1,23 @@
package org.yeshi.utils.wx;
import java.io.InputStream;
import java.security.AlgorithmParameters;
import java.security.Security;
import java.util.Arrays;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Base64;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.yeshi.utils.HttpUtil;
import org.yeshi.utils.entity.wx.WXAPPInfo;
import org.yeshi.utils.entity.wx.WXMPSessionInfo;
import org.yeshi.utils.entity.wx.WXMPUserInfo;
import com.aliyun.openservices.shade.io.netty.util.internal.StringUtil;
import com.google.gson.Gson;
import net.sf.json.JSONObject;
@@ -34,4 +49,95 @@
        return HttpUtil.postForInputstream(url, data.toString());
    }
    public static WXMPSessionInfo getSessionInfo(WXAPPInfo app, String code) {
        try {
            String url = String.format(
                    "https://api.weixin.qq.com/sns/jscode2session?appid=%s&secret=%s&js_code=%s&grant_type=authorization_code",
                    app.getAppId(), app.getAppSecret(), code);
            String result = HttpUtil.get(url);
            System.out.println(result);
            JSONObject json = JSONObject.fromObject(result);
            WXMPSessionInfo info = new WXMPSessionInfo(json.optString("openid"), json.optString("session_key"),
                    json.optString("unionid"));
            if (org.yeshi.utils.StringUtil.isNullOrEmpty(info.getOpenId()))
                return null;
            return info;
        } catch (Exception e) {
        }
        return null;
    }
    /**
     * 通过解密信息获取电话号码
     *
     * @param sessionKey
     * @param encryptedData
     * @param iv
     * @return
     */
    public static String getPhoneNumber(String sessionKey, String encryptedData, String iv) {
        String result = decrpt(sessionKey, encryptedData, iv);
        if (!org.yeshi.utils.StringUtil.isNullOrEmpty(result)) {
            JSONObject data = JSONObject.fromObject(result);
            if (data.optString("countryCode").equalsIgnoreCase("86"))// 只能获取中国的手机号
                return data.optString("purePhoneNumber");
        }
        return null;
    }
    /**
     * 获取用户信息
     *
     * @param sessionKey
     * @param encryptedData
     * @param iv
     * @return
     */
    public static WXMPUserInfo getUserInfo(String sessionKey, String encryptedData, String iv) {
        String result = decrpt(sessionKey, encryptedData, iv);
        if (!org.yeshi.utils.StringUtil.isNullOrEmpty(result)) {
            WXMPUserInfo userInfo = new Gson().fromJson(result, WXMPUserInfo.class);
            return userInfo;
        }
        return null;
    }
    private static String decrpt(String sessionKey, String encryptedData, String iv) {
        try {
            final Base64 base64 = new Base64();
            // 被加密的数据
            byte[] dataByte = base64.decode(encryptedData.getBytes("UTF-8"));
            // 加密秘钥
            byte[] keyByte = base64.decode(sessionKey.getBytes("UTF-8"));
            // 偏移量
            byte[] ivByte = base64.decode(iv.getBytes("UTF-8"));
            // 如果密钥不足16位,那么就补足. 这个if 中的内容很重要
            int base = 16;
            if (keyByte.length % base != 0) {
                int groups = keyByte.length / base + (keyByte.length % base != 0 ? 1 : 0);
                byte[] temp = new byte[groups * base];
                Arrays.fill(temp, (byte) 0);
                System.arraycopy(keyByte, 0, temp, 0, keyByte.length);
                keyByte = temp;
            }
            // 初始化
            Security.addProvider(new BouncyCastleProvider());
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding", "BC");
            SecretKeySpec spec = new SecretKeySpec(keyByte, "AES");
            AlgorithmParameters parameters = AlgorithmParameters.getInstance("AES");
            parameters.init(new IvParameterSpec(ivByte));
            cipher.init(Cipher.DECRYPT_MODE, spec, parameters);// 初始化
            byte[] resultByte = cipher.doFinal(dataByte);
            if (null != resultByte && resultByte.length > 0) {
                String result = new String(resultByte, "UTF-8");
                return result;
            }
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
        return null;
    }
}