登录与注册
This commit is contained in:
parent
1768127ea0
commit
006978a484
|
|
@ -145,6 +145,12 @@
|
||||||
<groupId>com.github.oshi</groupId>
|
<groupId>com.github.oshi</groupId>
|
||||||
<artifactId>oshi-core</artifactId>
|
<artifactId>oshi-core</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<!-- 微信小程序 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.github.binarywang</groupId>
|
||||||
|
<artifactId>weixin-java-miniapp</artifactId>
|
||||||
|
<version>4.4.0</version>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
|
@ -16,13 +16,14 @@ public class User implements Serializable {
|
||||||
|
|
||||||
@TableId(value="id", type= IdType.AUTO)
|
@TableId(value="id", type= IdType.AUTO)
|
||||||
private Integer id; // 主键
|
private Integer id; // 主键
|
||||||
private String sn; // 编号
|
private Integer sn; // 编号
|
||||||
private String avatar; // 用户头像
|
private String avatar; // 用户头像
|
||||||
private String realName; // 真实姓名
|
private String realName; // 真实姓名
|
||||||
private String nickname; // 用户昵称
|
private String nickname; // 用户昵称
|
||||||
private String username; // 用户账号
|
private String username; // 用户账号
|
||||||
private String password; // 用户密码
|
private String password; // 用户密码
|
||||||
private String mobile; // 用户电话
|
private String mobile; // 用户电话
|
||||||
|
private Integer channel; // 注册渠道
|
||||||
private String salt; // 加密盐巴
|
private String salt; // 加密盐巴
|
||||||
private Integer sex; // 用户性别: [1=男, 2=女]
|
private Integer sex; // 用户性别: [1=男, 2=女]
|
||||||
private Integer is_delete; // 是否删除: [0=否, 1=是]
|
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