admin
2019-12-30 3f7bcb1fb68b78a2cd2a87b44098f1de70378d92
完成微信小程序登录流程
14个文件已修改
7个文件已添加
1066 ■■■■■ 已修改文件
fanli/src/main/java/com/yeshi/fanli/controller/wxmp/ConfigController.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/main/java/com/yeshi/fanli/controller/wxmp/UserAccountController.java 273 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/main/java/com/yeshi/fanli/controller/wxmp/UserController.java 27 ●●●● 补丁 | 查看 | 原始文档 | 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/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/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 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/main/java/com/yeshi/fanli/util/RedisManager.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/wx/WXXCXUtil.java 97 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/main/java/com/yeshi/fanli/controller/wxmp/ConfigController.java
@@ -24,7 +24,7 @@
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
@Controller
@Controller("WXMPConfigController")
@RequestMapping("/wxmp/api/v1/config")
public class ConfigController {
fanli/src/main/java/com/yeshi/fanli/controller/wxmp/UserAccountController.java
New file
@@ -0,0 +1,273 @@
package com.yeshi.fanli.controller.wxmp;
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/UserController.java
@@ -2,12 +2,17 @@
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;
@@ -17,20 +22,34 @@
@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, PrintWriter out) {
    public void getOpenId(WXMPAcceptData acceptData, String code, HttpSession session, PrintWriter out) {
        if (StringUtil.isNullOrEmpty(code)) {
            out.print(JsonUtil.loadFalseResult("code为空"));
            return;
        }
        String openId = WXXCXUtil.getOpenId(Constant.WXMP_APP_INFO, code);
        if (!StringUtil.isNullOrEmpty(openId)) {
        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", openId);
            data.put("openId", info.getOpenId());
            out.print(JsonUtil.loadTrueResult(data));
        } else {
            out.print(JsonUtil.loadFalseResult("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/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/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
@@ -247,6 +247,8 @@
    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", "", "");
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);
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/wx/WXXCXUtil.java
@@ -1,11 +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;
@@ -37,20 +49,95 @@
        return HttpUtil.postForInputstream(url, data.toString());
    }
    public static String getOpenId(WXAPPInfo app, String code) {
    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);
            String openId = json.optString("openid");
            if (!StringUtil.isNullOrEmpty(openId)) {
                return openId;
            }
            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;
    }
}