登录与注册
This commit is contained in:
parent
1768127ea0
commit
006978a484
|
|
@ -145,6 +145,12 @@
|
|||
<groupId>com.github.oshi</groupId>
|
||||
<artifactId>oshi-core</artifactId>
|
||||
</dependency>
|
||||
<!-- 微信小程序 -->
|
||||
<dependency>
|
||||
<groupId>com.github.binarywang</groupId>
|
||||
<artifactId>weixin-java-miniapp</artifactId>
|
||||
<version>4.4.0</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
|
|
@ -16,13 +16,14 @@ public class User implements Serializable {
|
|||
|
||||
@TableId(value="id", type= IdType.AUTO)
|
||||
private Integer id; // 主键
|
||||
private String sn; // 编号
|
||||
private Integer sn; // 编号
|
||||
private String avatar; // 用户头像
|
||||
private String realName; // 真实姓名
|
||||
private String nickname; // 用户昵称
|
||||
private String username; // 用户账号
|
||||
private String password; // 用户密码
|
||||
private String mobile; // 用户电话
|
||||
private Integer channel; // 注册渠道
|
||||
private String salt; // 加密盐巴
|
||||
private Integer sex; // 用户性别: [1=男, 2=女]
|
||||
private Integer is_delete; // 是否删除: [0=否, 1=是]
|
||||
|
|
|
|||
|
|
@ -0,0 +1,26 @@
|
|||
package com.mdd.common.entity.user;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 用户授权实体
|
||||
*/
|
||||
@Data
|
||||
public class UserAuth implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@TableId(value="id", type= IdType.AUTO)
|
||||
private Integer id; // 主键
|
||||
private Integer userId; // 用户Id
|
||||
private String openid; // Openid
|
||||
private String unionid; // Unionid
|
||||
private Integer client; // 客户端类型: [1=微信小程序, 2=微信公众号, 3=手机H5;4=电脑PC, 5=苹果APP, 6=安卓APP]
|
||||
private Long createTime; // 创建时间
|
||||
private Long updateTime; // 更新时间
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,79 @@
|
|||
package com.mdd.common.enums;
|
||||
|
||||
/**
|
||||
* 客户端枚举类
|
||||
*/
|
||||
public enum ClientEnum {
|
||||
|
||||
MNP(1, "微信小程序"),
|
||||
OA(2, "微信公众号"),
|
||||
H5(3, "手机H5"),
|
||||
PC(4, "电脑PC"),
|
||||
IOS(5, "苹果APP"),
|
||||
APK(5, "安卓APP");
|
||||
|
||||
/**
|
||||
* 构造方法
|
||||
*/
|
||||
private final int code;
|
||||
private final String msg;
|
||||
ClientEnum(int code, String msg) {
|
||||
this.code = code;
|
||||
this.msg = msg;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据类型获取Code
|
||||
*
|
||||
* @author fzr
|
||||
* @param type 类型
|
||||
* @return Integer
|
||||
*/
|
||||
public static Integer getCodeByType(String type){
|
||||
for(ClientEnum enumItem: ClientEnum.values()) {
|
||||
if (enumItem.toString().equals(type.toUpperCase())) {
|
||||
return enumItem.getCode();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据类型获取Msg
|
||||
*
|
||||
* @author fzr
|
||||
* @param type 类型
|
||||
* @return String
|
||||
*/
|
||||
public static String getMsgByType(String type){
|
||||
for(ClientEnum enumItem: ClientEnum.values()) {
|
||||
if (enumItem.toString().equals(type)) {
|
||||
return enumItem.getMsg();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 获取状态码
|
||||
*
|
||||
* @author fzr
|
||||
* @return Long
|
||||
*/
|
||||
public int getCode() {
|
||||
return this.code;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取提示
|
||||
*
|
||||
* @author fzr
|
||||
* @return String
|
||||
*/
|
||||
public String getMsg() {
|
||||
return this.msg;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
package com.mdd.common.mapper.user;
|
||||
|
||||
import com.mdd.common.core.basics.IBaseMapper;
|
||||
import com.mdd.common.entity.user.UserAuth;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
/**
|
||||
* 用户授权Mapper
|
||||
*/
|
||||
@Mapper
|
||||
public interface UserAuthMapper extends IBaseMapper<UserAuth> {
|
||||
}
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
package com.mdd.common.plugin.wechat;
|
||||
|
||||
public class WechatDriver {
|
||||
}
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
package com.mdd.front.controller;
|
||||
|
||||
import com.baomidou.mybatisplus.core.toolkit.Assert;
|
||||
import com.mdd.common.core.AjaxResult;
|
||||
import com.mdd.common.enums.ClientEnum;
|
||||
import com.mdd.front.service.ILoginService;
|
||||
import com.mdd.front.validate.RegisterParam;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/api/login")
|
||||
public class LoginController {
|
||||
|
||||
@Resource
|
||||
ILoginService iLoginService;
|
||||
|
||||
/**
|
||||
* 注册账号
|
||||
*
|
||||
* @author fzr
|
||||
* @param registerParam 参数
|
||||
* @return Object
|
||||
*/
|
||||
@PostMapping("/register")
|
||||
public Object register(@Validated @RequestBody RegisterParam registerParam) {
|
||||
iLoginService.register(registerParam);
|
||||
return AjaxResult.success();
|
||||
}
|
||||
|
||||
@PostMapping("/check")
|
||||
public Object check(@RequestBody Map<String, String> params) {
|
||||
Assert.notNull(params.get("scene"), "scene参数缺失!");
|
||||
|
||||
Map<String, Object> map = new LinkedHashMap<>();
|
||||
switch (params.get("scene")) {
|
||||
case "mnp":
|
||||
map = iLoginService.mnpLogin(params);
|
||||
break;
|
||||
case "sms":
|
||||
Assert.isNull(params.get("code"), "code参数缺失!");
|
||||
iLoginService.smsLogin(params);
|
||||
break;
|
||||
case "account":
|
||||
iLoginService.accountLogin(params);
|
||||
break;
|
||||
}
|
||||
|
||||
return AjaxResult.success(map);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
package com.mdd.front.service;
|
||||
|
||||
import com.mdd.front.validate.RegisterParam;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 登录服务接口类
|
||||
*/
|
||||
public interface ILoginService {
|
||||
|
||||
/**
|
||||
* 账号注册
|
||||
*
|
||||
* @author fzr
|
||||
* @param registerParam 参数
|
||||
*/
|
||||
void register(RegisterParam registerParam);
|
||||
|
||||
/**
|
||||
* 微信小程序登录
|
||||
*
|
||||
* @author fzr
|
||||
* @param scene 场景
|
||||
* @param code 编码
|
||||
*/
|
||||
Map<String, Object> mnpLogin(Map<String, String> params);
|
||||
|
||||
void smsLogin(Map<String, String> params);
|
||||
|
||||
void accountLogin(Map<String, String> params);
|
||||
|
||||
void forgotPassword(Map<String, String> params);
|
||||
}
|
||||
|
|
@ -0,0 +1,210 @@
|
|||
package com.mdd.front.service.impl;
|
||||
|
||||
import cn.binarywang.wx.miniapp.api.WxMaService;
|
||||
import cn.binarywang.wx.miniapp.api.impl.WxMaServiceImpl;
|
||||
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
|
||||
import cn.binarywang.wx.miniapp.config.impl.WxMaDefaultConfigImpl;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Assert;
|
||||
import com.mdd.common.entity.user.User;
|
||||
import com.mdd.common.entity.user.UserAuth;
|
||||
import com.mdd.common.enums.ClientEnum;
|
||||
import com.mdd.common.exception.OperateException;
|
||||
import com.mdd.common.mapper.user.UserAuthMapper;
|
||||
import com.mdd.common.mapper.user.UserMapper;
|
||||
import com.mdd.common.utils.ConfigUtil;
|
||||
import com.mdd.common.utils.IpUtil;
|
||||
import com.mdd.common.utils.StringUtil;
|
||||
import com.mdd.common.utils.ToolsUtil;
|
||||
import com.mdd.front.service.ILoginService;
|
||||
import com.mdd.front.validate.RegisterParam;
|
||||
import me.chanjar.weixin.common.error.WxErrorException;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 登录服务实现类
|
||||
*/
|
||||
@Service
|
||||
public class LoginServiceImpl implements ILoginService {
|
||||
|
||||
@Resource
|
||||
UserMapper userMapper;
|
||||
|
||||
@Resource
|
||||
UserAuthMapper userAuthMapper;
|
||||
|
||||
|
||||
/**
|
||||
* 注册账号
|
||||
*
|
||||
* @author fzr
|
||||
* @param registerParam 参数
|
||||
*/
|
||||
@Override
|
||||
public void register(RegisterParam registerParam) {
|
||||
User model = userMapper.selectOne(new QueryWrapper<User>()
|
||||
.select("id,sn,username")
|
||||
.eq("username", registerParam.getUsername())
|
||||
.eq("is_delete", 0)
|
||||
.last("limit 1"));
|
||||
|
||||
Assert.isNull(model, "账号已存在,换一个吧!");
|
||||
|
||||
Integer sn = this.randMakeSn();
|
||||
String salt = ToolsUtil.randomString(5);
|
||||
String pwd = ToolsUtil.makeMd5(registerParam.getPassword()+salt);
|
||||
|
||||
User user = new User();
|
||||
user.setSn(sn);
|
||||
user.setNickname("用户"+sn);
|
||||
user.setUsername(registerParam.getUsername());
|
||||
user.setPassword(pwd);
|
||||
user.setSalt(salt);
|
||||
user.setChannel(0);
|
||||
user.setCreateTime(System.currentTimeMillis() / 1000);
|
||||
user.setUpdateTime(System.currentTimeMillis() / 1000);
|
||||
userMapper.insert(user);
|
||||
}
|
||||
|
||||
/**
|
||||
* 微信小程序登录
|
||||
*
|
||||
* @author fzr
|
||||
* @param params 参数
|
||||
* @return Map<String, Object>
|
||||
*/
|
||||
@Override
|
||||
@Transactional
|
||||
public Map<String, Object> mnpLogin(Map<String, String> params) {
|
||||
Assert.notNull(params.get("code"), "code参数缺失!");
|
||||
String scene = params.get("scene");
|
||||
String code = params.get("code");
|
||||
String avatarUrl = params.getOrDefault("avatarUrl", "");
|
||||
String nickName = params.getOrDefault("nickName", "");
|
||||
String gender = params.getOrDefault("gender", "0");
|
||||
Integer client = ClientEnum.getCodeByType(scene);
|
||||
|
||||
Map<String, String> config = ConfigUtil.get("mp_channel");
|
||||
WxMaService wxMaService = new WxMaServiceImpl();
|
||||
WxMaDefaultConfigImpl wxConfig = new WxMaDefaultConfigImpl();
|
||||
wxConfig.setAppid(config.getOrDefault("appId", ""));
|
||||
wxConfig.setSecret(config.getOrDefault("appSecret", ""));
|
||||
wxMaService.setWxMaConfig(wxConfig);
|
||||
|
||||
try {
|
||||
WxMaJscode2SessionResult sessionResult = wxMaService.getUserService().getSessionInfo(code);
|
||||
String openId = sessionResult.getOpenid();
|
||||
String unionId = sessionResult.getUnionid();
|
||||
|
||||
UserAuth userAuth = userAuthMapper.selectOne(new QueryWrapper<UserAuth>()
|
||||
.eq("client", client)
|
||||
.nested(wq->wq
|
||||
.eq("openid", openId).or()
|
||||
.eq("unionid", unionId)
|
||||
).last("limit 1"));
|
||||
|
||||
User user = null;
|
||||
Integer userId;
|
||||
if (StringUtil.isNotNull(userAuth)) {
|
||||
user = userMapper.selectOne(new QueryWrapper<User>()
|
||||
.eq("id", userAuth.getUserId())
|
||||
.eq("is_delete", 0)
|
||||
.last("limit 1"));
|
||||
}
|
||||
|
||||
if (StringUtil.isNull(user)) {
|
||||
Integer sn = this.randMakeSn();
|
||||
User model = new User();
|
||||
model.setSn(sn);
|
||||
model.setAvatar(avatarUrl);
|
||||
model.setNickname(nickName.equals("")?"用户"+sn:nickName);
|
||||
model.setUsername("u"+sn);
|
||||
model.setSex(Integer.parseInt(gender));
|
||||
model.setChannel(client);
|
||||
model.setLastLoginIp(IpUtil.getHostIp());
|
||||
model.setLastLoginTime(System.currentTimeMillis() / 1000);
|
||||
model.setCreateTime(System.currentTimeMillis() / 1000);
|
||||
model.setUpdateTime(System.currentTimeMillis() / 1000);
|
||||
userMapper.insert(model);
|
||||
userId = model.getId();
|
||||
|
||||
UserAuth auth = new UserAuth();
|
||||
auth.setUserId(model.getId());
|
||||
auth.setOpenid(openId);
|
||||
auth.setUnionid(unionId);
|
||||
auth.setClient(client);
|
||||
auth.setCreateTime(System.currentTimeMillis() / 1000);
|
||||
auth.setUpdateTime(System.currentTimeMillis() / 1000);
|
||||
userAuthMapper.insert(auth);
|
||||
} else {
|
||||
// 更新微信标识
|
||||
userId = user.getId();
|
||||
if (StringUtil.isEmpty(userAuth.getUnionid()) && StringUtil.isNotEmpty(sessionResult.getUnionid())) {
|
||||
userAuth.setUnionid(sessionResult.getUnionid());
|
||||
userAuthMapper.updateById(userAuth);
|
||||
}
|
||||
|
||||
// 更新用户信息
|
||||
if (StringUtil.isEmpty(user.getAvatar()) && StringUtil.isNotEmpty(avatarUrl)) {
|
||||
user.setAvatar(avatarUrl);
|
||||
user.setNickname(nickName);
|
||||
user.setSex(Integer.parseInt(gender));
|
||||
}
|
||||
|
||||
// 更新登录信息
|
||||
user.setLastLoginIp(IpUtil.getHostIp());
|
||||
user.setLastLoginTime(System.currentTimeMillis() / 1000);
|
||||
userMapper.updateById(user);
|
||||
}
|
||||
|
||||
String token = ToolsUtil.makeToken();
|
||||
Map<String, Object> response = new LinkedHashMap<>();
|
||||
response.put("id", userId);
|
||||
response.put("token", token);
|
||||
return response;
|
||||
} catch (WxErrorException e) {
|
||||
throw new OperateException(e.getError().getErrorCode() + ", " + e.getError().getErrorMsg());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void smsLogin(Map<String, String> params) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accountLogin(Map<String, String> params) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void forgotPassword(Map<String, String> params) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成用户编号
|
||||
*
|
||||
* @author fzr
|
||||
* @return Integer
|
||||
*/
|
||||
private Integer randMakeSn() {
|
||||
Integer sn;
|
||||
while (true) {
|
||||
sn = Integer.parseInt(ToolsUtil.randomInt(8));
|
||||
User snModel = userMapper.selectOne(new QueryWrapper<User>()
|
||||
.select("id,sn,username")
|
||||
.eq("sn", sn)
|
||||
.last("limit 1"));
|
||||
if (snModel == null) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return sn;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
package com.mdd.front.validate;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
import org.hibernate.validator.constraints.Length;
|
||||
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import javax.validation.constraints.Pattern;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 注册参数类
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
@Accessors(chain = true)
|
||||
public class RegisterParam implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@NotNull(message = "username参数缺失")
|
||||
@NotEmpty(message = "账号不能为空")
|
||||
@Length(min = 3, max = 12, message = "账号必须在3~12个字符内")
|
||||
@Pattern(message = "账号只允许是字母和数字", regexp="^[A-Za-z0-9]+$")
|
||||
@Pattern(message = "账号应该为3-12位字母、数字组合", regexp="^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{3,12}$")
|
||||
private String username;
|
||||
|
||||
@NotNull(message = "password参数缺失")
|
||||
@NotEmpty(message = "密码不能为空")
|
||||
@Length(min = 6, max = 12, message = "密码必须在6~12个字符内")
|
||||
private String password;
|
||||
|
||||
}
|
||||
Loading…
Reference in New Issue