| @@ -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() { | |||
| @@ -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()); | |||
| } | |||
| } | |||
| } | |||
| @@ -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() { | |||
| @@ -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; | |||
| } | |||
| } | |||
| @@ -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); | |||
| } | |||
| @@ -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 | |||
| @@ -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); | |||
| @@ -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> | |||