Просмотр исходного кода

[微信第三方登录][修改]:微信绑定及手机号登录

release_toaliyun_real
Stormeye Wu 7 лет назад
Родитель
Сommit
e766d90aa3
8 измененных файлов: 314 добавлений и 38 удалений
  1. +134
    -11
      mallinkAdmin/src/main/java/com/iformall/controller/HomeController.java
  2. +34
    -24
      mallinkAdmin/src/main/java/com/iformall/controller/WechatLoginController.java
  3. +1
    -1
      mallinkService/src/main/java/com/iformall/domain/po/MallUserInfo.java
  4. +46
    -0
      mallinkService/src/main/java/com/iformall/domain/vo/MallUserInfoVo.java
  5. +4
    -0
      mallinkService/src/main/java/com/iformall/mapper/MallUserInfoMapper.java
  6. +16
    -1
      mallinkService/src/main/java/com/iformall/service/MallUserInfoService.java
  7. +39
    -1
      mallinkService/src/main/java/com/iformall/service/impl/MallUserInfoServiceImpl.java
  8. +40
    -0
      mallinkService/src/main/resources/mapper/MallUserInfoMapper.xml

+ 134
- 11
mallinkAdmin/src/main/java/com/iformall/controller/HomeController.java Просмотреть файл

@@ -1,25 +1,20 @@
package com.iformall.controller;

import com.github.pagehelper.PageInfo;
import com.google.code.kaptcha.Constants;
import com.google.code.kaptcha.Producer;
import com.iformall.common.ErrorCode;
import com.iformall.common.Result;
import com.iformall.common.ResultData;
import com.iformall.domain.po.MallRolePermission;
import com.iformall.domain.po.MallUserInfo;
import com.iformall.domain.po.MallUserRole;
import com.iformall.domain.po.WxAppinfo;
import com.iformall.enums.EnumMenuType;
import com.iformall.enums.EnumUserAdmin;
import com.iformall.domain.po.*;
import com.iformall.domain.vo.MallUserInfoVo;
import com.iformall.exception.MallinkException;
import com.iformall.service.MallRolePermissionService;
import com.iformall.service.MallUserInfoService;
import com.iformall.service.MallUserRoleService;
import com.iformall.service.WxAppinfoService;
import com.iformall.service.*;
import com.iformall.shiro.UserSession;
import com.iformall.shiro.UseriFormallToken;
import com.iformall.utils.ShiroUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
@@ -39,6 +34,7 @@ import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.List;
import java.util.Map;


@RestController
@@ -61,6 +57,9 @@ public class HomeController extends BaseController {
@Autowired
private WxAppinfoService appinfoService;

@Autowired
private WxMsgValidationcodeService wxMsgValidationcodeService;

@GetMapping("/captcha.jpg")
public void captcha(HttpServletResponse response)throws ServletException, IOException {
logger.debug("[" + getIpAddr() + "] HomeController::captcha");
@@ -198,6 +197,130 @@ public class HomeController extends BaseController {
return data;
}

@GetMapping("sendLoginCode")
@ApiImplicitParams({
@ApiImplicitParam(name = "phone", value = "手机号", dataType = "String", paramType = "query", required = true),
@ApiImplicitParam(name = "type", value = "场景(1:登录)", dataType = "Integer", paramType = "query", required = true)})
public ResultData sendlogincode(String phone, Integer type) {
logger.debug("[" + getIpAddr() + "] HomeController::sendlogincode");
// 1. 检查手机号是否在用户列表里
// 2. 发送手机验证码
// 2.1 如果只找到一个手机号 直接发
// 2.2 如果找到多个,用富茂的发
WxMsgValidationcode wxMsgValidationcode = new WxMsgValidationcode();
wxMsgValidationcode.setPhone(phone);
wxMsgValidationcode.setType(type);
// TODO 登录时不知道哪个tenantId
return wxMsgValidationcodeService.sendvalidationcode(wxMsgValidationcode);
}

@ApiOperation(value = "手机验证码登录", notes = "{\"phone\",\"string\",\"code\",\"string\"}")
@PostMapping("/doLoginByPhone")
public ResultData doLoginByPhone(@RequestBody Map<String, String> params) {
logger.debug("[" + getIpAddr() + "] HomeController::doLoginByPhone");
// String phone,String code,String pwd
String phone = params.get("phone");
String code = params.get("code");

if (StringUtils.isBlank(phone)) {
return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), "userName不能为空");
}
if (StringUtils.isBlank(code)) {
return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), "验证码不能为空");
}

// check 验证码正确
// TODO
// try {
// return userInfoService.updatepwd(user, code);
// } catch (Exception e) {
// return new ResultData(Result.ERROR, e.getMessage());
// }

// 获取用户信息列表
List<MallUserInfoVo> userList = mallUserInfoService.getUserByPhone(phone);
if(userList.size() == 1) {
// 唯一用户,直接登录即可
MallUserInfoVo user = userList.get(0);
try {
Subject subject = SecurityUtils.getSubject();
UseriFormallToken token = new UseriFormallToken(user.getUsername());
subject.login(token);
MallUserInfo info = (MallUserInfo) SecurityUtils.getSubject().getSession().getAttribute(UserSession.userInfo);
info.setPassword("保密");
if(StringUtils.isNotBlank(info.getBopenId()))
info.setBopenId("保密");
if(StringUtils.isNotBlank(info.getWebOpenId()))
info.setWebOpenId("保密");
// System.out.println("id:"+ SecurityUtils.getSubject().getSession().getId());
String menus = mallUserRoleService.getPermissionsByUser(info);
if(menus != null) {
info.setMenus(menus);
}
return new ResultData(info);
} catch (Exception e) {
return new ResultData(ResultData.ERROR, "用户名或者密码错误");
}
} else {
// TODO 多个租户,前端界面做选择
return new ResultData();
}
}

@ApiOperation(value = "手机验证码租户登录", notes = "{\"tenantId\",\"string\", \"phone\",\"string\",\"code\",\"string\"}")
@PostMapping("/doLoginByTenantPhone")
public ResultData doLoginByTenantPhone(@RequestBody Map<String, String> params) {
logger.debug("[" + getIpAddr() + "] HomeController::doLoginByTenantPhone");
String tenantId = params.get("tenantId");
String phone = params.get("phone");
String code = params.get("code");

if (StringUtils.isBlank(tenantId)) {
return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), "tenantId不能为空");
}
if (StringUtils.isBlank(phone)) {
return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), "phone不能为空");
}
if (StringUtils.isBlank(code)) {
return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), "验证码不能为空");
}

MallUserInfo user = mallUserInfoService.getByPhone(phone, tenantId);
if(user == null) {
return new ResultData(ErrorCode.USER_IS_EMPTY);
}

// check 验证码正确
ResultData r = null;
try {
r = mallUserInfoService.checkCodeValid(user, code);
if(r.code != Result.SUCCESS) {
return r;
}
} catch (Exception e) {
return new ResultData(Result.ERROR, e.getMessage());
}

try {
Subject subject = SecurityUtils.getSubject();
UseriFormallToken token = new UseriFormallToken(user.getUsername());
subject.login(token);
MallUserInfo info = (MallUserInfo) SecurityUtils.getSubject().getSession().getAttribute(UserSession.userInfo);
info.setPassword("保密");
if(StringUtils.isNotBlank(info.getBopenId()))
info.setBopenId("保密");
if(StringUtils.isNotBlank(info.getWebOpenId()))
info.setWebOpenId("保密");
String menus = mallUserRoleService.getPermissionsByUser(info);
if(menus != null) {
info.setMenus(menus);
}
return new ResultData(info);
} catch (Exception e) {
return new ResultData(ResultData.ERROR, "用户名或者密码错误");
}
}

@ApiOperation("登出")
@GetMapping("/logout")
public ResultData logout() {


+ 34
- 24
mallinkAdmin/src/main/java/com/iformall/controller/WechatLoginController.java Просмотреть файл

@@ -1,6 +1,5 @@
package com.iformall.controller;

import com.iformall.common.ResultData;
import com.iformall.domain.po.MallUserInfo;
import com.iformall.service.MallUserInfoService;
import com.iformall.service.MallUserRoleService;
@@ -20,9 +19,8 @@ import org.springframework.web.bind.annotation.*;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.io.IOException;
import java.util.List;
import java.util.Map;


@Controller
@@ -45,7 +43,6 @@ public class WechatLoginController extends BaseController {
log.debug("[" + getIpAddr() + "] WechatLoginController::getAccessToken");
String host = request.getHeader("host");
log.debug("code: " + code);
//ResultData r = new ResultData();
try {
WxMpOAuth2AccessToken accessToken = wxMpService.oauth2getAccessToken(code);
log.debug("accessToken: " + accessToken.getAccessToken() + ", openId: " + accessToken.getOpenId() + ", unionId: " + accessToken.getUnionId());
@@ -76,50 +73,63 @@ public class WechatLoginController extends BaseController {
unameCookie.setMaxAge(60);
response.addCookie(openIdCookie);
log.debug("https://" + host + "/#/");
//r.data = info;
response.sendRedirect("https://" + host + "/#/layout");
} catch (Exception e) {
log.error(e.getMessage());
//return new ResultData(ResultData.ERROR, "用户名或者密码错误");
}
} else {
// 跳转选择界面
//response.sendRedirect(request.getContextPath() + "/student/html/index.min.html#/app/home?open_id=" + openId);
// 跳转登录选择页面
try {
response.sendRedirect("https://" + host + "/#/loginselect?openId=" + accessToken.getOpenId());
} catch (Exception e) {
log.error(e.getMessage());
}
}

} else {
// 跳转登录页面
try {
response.sendRedirect("https://" + host + "/#/");
//return new ResultData(ResultData.ERROR, "用户名或者密码错误");
response.sendRedirect("https://" + host + "/#/login");
} catch (Exception e) {
log.error(e.getMessage());
//return new ResultData(ResultData.ERROR, "用户名或者密码错误");
}

}
//return r;
} catch (WxErrorException e) {
log.error(e.getMessage());
//return new ResultData();
}
}

@ApiOperation(value = "微信第三方登录设置", notes = "请配置此callback到网页redirect_uri")
@ApiOperation(value = "微信第三方登录绑定", notes = "请配置此callback到网页redirect_uri")
@GetMapping("bindWebOpenId")
public ResultData userBindWebOpenId(String code) {
MallUserInfo user = getUser();
ResultData r = new ResultData();
public void userBindWebOpenId(String code, String state, HttpServletRequest request, HttpServletResponse response) {
log.debug("[" + getIpAddr() + "] WechatLoginController::bindWebOpenId");
String host = request.getHeader("host");
try {
WxMpOAuth2AccessToken accessToken = wxMpService.oauth2getAccessToken(code);
MallUserInfo updateUser = new MallUserInfo();
updateUser.setId(user.getId());
updateUser.setWebOpenId(accessToken.getOpenId());
mallUserInfoService.saveOrUpdate(updateUser);
return r;
log.debug("accessToken: " + accessToken.getAccessToken() + ", openId: " + accessToken.getOpenId() + ", unionId: " + accessToken.getUnionId());

// 保存 openId 到 cookie,一小时过期
Cookie openIdCookie = new Cookie("openId", accessToken.getOpenId());
openIdCookie.setMaxAge(60);
response.addCookie(openIdCookie);

String uname = state;
MallUserInfo user = mallUserInfoService.getByUsername(uname);
if(user != null) {
user.setWebOpenId(accessToken.getOpenId());
mallUserInfoService.updateWebOpenId(user);
// TODO 绑定成功
log.debug("https://" + host + "/#/layout");
response.sendRedirect("https://" + host + "/#/layout");
} else {
// 返回首页
log.debug("https://" + host + "/#/");
response.sendRedirect("https://" + host + "/#/layout");
}
} catch (WxErrorException e) {
log.error(e.getMessage());
return new ResultData();
} catch (IOException e) {
log.error(e.getMessage());
}
}
}

+ 1
- 1
mallinkService/src/main/java/com/iformall/domain/po/MallUserInfo.java Просмотреть файл

@@ -100,7 +100,7 @@ public class MallUserInfo implements Serializable {
private String captcha;

/**1合同审批 2账单审批**/
@io.swagger.annotations.ApiModelProperty(value="",name="flowPermission")
@io.swagger.annotations.ApiModelProperty(value="1合同审批 2账单审批",name="flowPermission")
private String flowPermission;

public String getFlowPermission() {


+ 46
- 0
mallinkService/src/main/java/com/iformall/domain/vo/MallUserInfoVo.java Просмотреть файл

@@ -0,0 +1,46 @@
package com.iformall.domain.vo;

import com.iformall.domain.po.MallUserInfo;

public class MallUserInfoVo extends MallUserInfo {
@io.swagger.annotations.ApiModelProperty(value="商场名",name="mallName")
private String mallName;
@io.swagger.annotations.ApiModelProperty(value="集团",name="mallGroup")
private String mallGroup;
@io.swagger.annotations.ApiModelProperty(value="商场图标",name="imgUrl")
private String imgUrl;
@io.swagger.annotations.ApiModelProperty(value="商场图标",name="imgUrlH")
private String imgUrlH;

public String getMallName() {
return mallName;
}

public void setMallName(String mallName) {
this.mallName = mallName;
}

public String getMallGroup() {
return mallGroup;
}

public void setMallGroup(String mallGroup) {
this.mallGroup = mallGroup;
}

public String getImgUrl() {
return imgUrl;
}

public void setImgUrl(String _imgUrl) {
this.imgUrl = _imgUrl;
}

public String getImgUrlH() {
return imgUrlH;
}

public void setImgUrlH(String imgUrlH) {
this.imgUrlH = imgUrlH;
}
}

+ 4
- 0
mallinkService/src/main/java/com/iformall/mapper/MallUserInfoMapper.java Просмотреть файл

@@ -2,6 +2,7 @@ package com.iformall.mapper;

import com.iformall.common.CommonMapper;
import com.iformall.domain.po.MallUserInfo;
import com.iformall.domain.vo.MallUserInfoVo;
import org.apache.ibatis.annotations.Param;

import java.util.List;
@@ -23,4 +24,7 @@ public interface MallUserInfoMapper extends CommonMapper<MallUserInfo, String> {

long cntByUserName(Map<String,Object> params);


List<MallUserInfoVo> selectUsersByPhone(@Param("phone") String phone);

}

+ 16
- 1
mallinkService/src/main/java/com/iformall/service/MallUserInfoService.java Просмотреть файл

@@ -3,7 +3,7 @@ package com.iformall.service;
import com.github.pagehelper.PageInfo;
import com.iformall.common.ResultData;
import com.iformall.domain.po.MallUserInfo;
import com.iformall.domain.po.WxAppinfo;
import com.iformall.domain.vo.MallUserInfoVo;

import java.util.List;

@@ -82,6 +82,8 @@ public interface MallUserInfoService {

ResultData updatepwd(MallUserInfo user, String code);

ResultData checkCodeValid(MallUserInfo user, String code);

/**
* 根据phone获得实体
*
@@ -89,6 +91,15 @@ public interface MallUserInfoService {
* @return
*/
MallUserInfo getByPhone(String phone, String tenantId);

/**
* 根据phone获得实体列表
*
* @param phone
* @return
*/
List<MallUserInfoVo> getUserByPhone(String phone);

/**
* 根据B端OpenId获得实体
*
@@ -97,6 +108,8 @@ public interface MallUserInfoService {
*/
MallUserInfo getByBOpenId(String openId, String tenantId);

void updateBOpenId(MallUserInfo user);

/**
* 根据web端OpenId获得实体
*
@@ -105,6 +118,8 @@ public interface MallUserInfoService {
*/
List<MallUserInfo> getByWebOpenId(String openId);

void updateWebOpenId(MallUserInfo user);

/**
* 根据条件用户列表
* @return


+ 39
- 1
mallinkService/src/main/java/com/iformall/service/impl/MallUserInfoServiceImpl.java Просмотреть файл

@@ -8,8 +8,8 @@ import com.iformall.common.Result;
import com.iformall.common.ResultData;
import com.iformall.domain.po.MallUserInfo;
import com.iformall.domain.po.MallUserRole;
import com.iformall.domain.po.WxAppinfo;
import com.iformall.domain.po.WxMsgValidationcode;
import com.iformall.domain.vo.MallUserInfoVo;
import com.iformall.exception.MallinkException;
import com.iformall.mapper.MallUserInfoMapper;
import com.iformall.mapper.MallUserRoleMapper;
@@ -62,16 +62,37 @@ public class MallUserInfoServiceImpl implements MallUserInfoService {
return mallUserInfoMapper.selectByBOpenId(openId, tenantId);
}

@Override
public void updateBOpenId(MallUserInfo user) {
MallUserInfo updateUser = new MallUserInfo();
updateUser.setId(user.getId());
updateUser.setBopenId(user.getBopenId());
mallUserInfoMapper.updateByPrimaryKeySelective(user);
}

@Override
public MallUserInfo getByPhone(String phone, String tenantId) {
return mallUserInfoMapper.selectByPhone(phone, tenantId);
}

@Override
public List<MallUserInfoVo> getUserByPhone(String phone) {
return mallUserInfoMapper.selectUsersByPhone(phone);
}

@Override
public List<MallUserInfo> getByWebOpenId(String openId) {
return mallUserInfoMapper.selectByWebOpenId(openId);
}

@Override
public void updateWebOpenId(MallUserInfo user) {
MallUserInfo updateUser = new MallUserInfo();
updateUser.setId(user.getId());
updateUser.setWebOpenId(user.getWebOpenId());
mallUserInfoMapper.updateByPrimaryKeySelective(user);
}

@Override
public void saveOrUpdate(MallUserInfo record) {
if (record.getId() == null) {
@@ -157,6 +178,23 @@ public class MallUserInfoServiceImpl implements MallUserInfoService {
return new ResultData();
}

@Override
public ResultData checkCodeValid(MallUserInfo user, String code) {
WxMsgValidationcode wxMsgValidationcode = new WxMsgValidationcode();
/// wxMsgValidationcode.setTenantId(user.getTenantId());
wxMsgValidationcode.setPhone(user.getPhone());
wxMsgValidationcode.setCode(code);
List<WxMsgValidationcode> wxmsgvalidationcodelist = wxMsgValidationcodeMapper.findList(wxMsgValidationcode);
Date currentdate = new Date();
wxmsgvalidationcodelist = wxmsgvalidationcodelist.stream().filter(validationcode ->
validationcode.getExpiretime().after(currentdate)).collect(Collectors.toList());
if (wxmsgvalidationcodelist.size() > 0) {
return new ResultData();
} else {
return new ResultData(Result.ERROR,"验证码不存在或过期",false);
}
}

@Override
public List<MallUserInfo> findList(MallUserInfo record){
return mallUserInfoMapper.findList(record);


+ 40
- 0
mallinkService/src/main/resources/mapper/MallUserInfoMapper.xml Просмотреть файл

@@ -161,4 +161,44 @@
</if>
</select>


<resultMap id="VBaseResultMap" type="com.iformall.domain.vo.MallUserInfoVo">
<id column="id" jdbcType="BIGINT" property="id"/>
<result column="tenant_id" jdbcType="VARCHAR" property="tenantId"/>
<result column="username" jdbcType="VARCHAR" property="username"/>
<result column="name" jdbcType="VARCHAR" property="name"/>
<result column="password" jdbcType="VARCHAR" property="password"/>
<result column="create_time" jdbcType="TIMESTAMP" property="createTime"/>
<result column="last_login_time" jdbcType="TIMESTAMP" property="lastLoginTime"/>
<result column="status" jdbcType="INTEGER" property="status"/>
<result column="is_admin" jdbcType="INTEGER" property="isAdmin"/>
<result column="nick_name" jdbcType="VARCHAR" property="nickName"/>
<result column="phone" jdbcType="VARCHAR" property="phone"/>
<result column="bopen_id" jdbcType="VARCHAR" property="bopenId"/>
<result column="web_open_id" jdbcType="VARCHAR" property="webOpenId"/>
<result column="flow_permission" property="flowPermission"/>

<result column="mall_name" jdbcType="VARCHAR" property="mallName"/>
<result column="mall_group" jdbcType="VARCHAR" property="mallGroup"/>
<result column="img_url" jdbcType="VARCHAR" property="imgUrl"/>
<result column="img_url_h" jdbcType="VARCHAR" property="imgUrlH"/>
</resultMap>

<sql id="allVColumns">
u.`id`,u.`tenant_id`,u.`username`,u.`name`,u.`password`,u.`create_time`,u.`last_login_time`,u.`status`,u.`is_admin`,u.`nick_name`,u.`phone`,u.`bopen_id`,u.`web_open_id`,u.`flow_permission`,
m.`name` as mall_name, m.`group` as mall_group, m.`img_url`, m.`img_url_h`
</sql>


<select id="selectUsersByPhone" resultMap="VBaseResultMap">
select
<include refid="allVColumns"/>
from mall_user_info u
left join wx_mall m where m.`tenant_id` = u.`tenant_id`
where 1=1
<if test=" null != phone ">
and u.`phone` = #{phone}
</if>
</select>

</mapper>

Загрузка…
Отмена
Сохранить