feat 增加绑定手机

feat 增加修改手机号码
feat 增加收藏文章功能
This commit is contained in:
damonyuan 2024-10-19 22:44:50 +08:00
parent 9a99d79439
commit 26f965ff03
14 changed files with 190 additions and 76 deletions

View File

@ -0,0 +1,43 @@
package com.mdd.common.enums;
/**
* 相册枚举
*/
public enum LoginEnum {
ACCOUNT_PASSWORD(1, "账号/手机号密码登录"),
MOBILE_CAPTCHA(2, "手机验证码登录"),
THIRD_LOGIN(3, "第三方登录");
/**
* 构造方法
*/
private final int code;
private final String msg;
LoginEnum(int code, String msg) {
this.code = code;
this.msg = msg;
}
/**
* 获取状态码
*
* @author fzr
* @return Long
*/
public int getCode() {
return this.code;
}
/**
* 获取提示
*
* @author fzr
* @return String
*/
public String getMsg() {
return this.msg;
}
}

View File

@ -3,7 +3,12 @@ package com.mdd.common.plugin.notice;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.mdd.common.entity.notice.NoticeRecord;
import com.mdd.common.entity.server.Sys;
import com.mdd.common.entity.smsLog.SmsLog;
import com.mdd.common.enums.NoticeEnum;
import com.mdd.common.enums.SmsEnum;
import com.mdd.common.enums.YesNoEnum;
import com.mdd.common.mapper.notice.NoticeRecordMapper;
import com.mdd.common.mapper.smsLog.SmsLogMapper;
import com.mdd.common.util.SpringUtils;
import com.mdd.common.util.StringUtils;
@ -14,28 +19,40 @@ import javax.annotation.Resource;
*/
public class NoticeCheck {
public static Boolean verify(Integer scene, Object code) {
NoticeRecordMapper noticeRecordMapper = SpringUtils.getBean(NoticeRecordMapper.class);
public static Boolean verify(Integer sceneId, String code, String mobile) {
NoticeRecord noticeRecord = noticeRecordMapper.selectOne(new QueryWrapper<NoticeRecord>()
.eq("scene", scene)
.eq("status", 1)
.eq("is_read", 0)
.eq("is_captcha", 1)
.eq("is_delete", 0)
.eq("code", code.toString().toLowerCase())
.last("limit 1"));
SmsLogMapper smsLogMapper = SpringUtils.getBean(SmsLogMapper.class);
QueryWrapper queryWrapper = new QueryWrapper();
queryWrapper.eq("mobile", mobile);
queryWrapper.eq("send_status", SmsEnum.SEND_SUCCESS.getCode());
queryWrapper.in("scene_id", NoticeEnum.getSmsScene());
queryWrapper.eq("is_verify", YesNoEnum.NO.getCode());
if (sceneId.equals(0) == false) {
queryWrapper.eq("scene_id", sceneId);
}
queryWrapper.orderByDesc("send_time");
queryWrapper.last("limit 1");
SmsLog smsLog = smsLogMapper.selectOne(queryWrapper);
if (StringUtils.isNull(noticeRecord)) {
if (StringUtils.isNull(smsLog)) {
return false;
}
boolean result = noticeRecord.getCreateTime() > ((System.currentTimeMillis() / 1000) - (5 * 60)); //5分钟有效
// 没有验证码 最新验证码已校验 已过期(有效期5分钟)
if (smsLog.getIsVerify().equals(1) || smsLog.getSendTime() < System.currentTimeMillis() / 1000 - (5*60)) {
return false;
}
noticeRecord.setRead(1);
noticeRecord.setUpdateTime(System.currentTimeMillis() / 1000);
noticeRecordMapper.updateById(noticeRecord);
return result;
// 更新校验状态
smsLog.setCheckNum(smsLog.getCheckNum() + 1);
if (smsLog.getCode().equals(code)) {
smsLog.setIsVerify(YesNoEnum.YES.getCode());
smsLogMapper.updateById(smsLog);
return true;
} else {
smsLogMapper.updateById(smsLog);
return false;
}
}
}

View File

@ -58,7 +58,7 @@ public class ArticleController {
return AjaxResult.success(vo);
}
@GetMapping("/collectList")
@GetMapping("/collect")
@ApiOperation(value="收藏列表")
public AjaxResult<PageResult<ArticleCollectVo>> collect(@Validated PageValidate pageValidate) {
Integer userId = LikeFrontThreadLocal.getUserId();
@ -70,17 +70,17 @@ public class ArticleController {
@PostMapping("/addCollect")
@ApiOperation(value="收藏加入")
public AjaxResult<Object> addCollect(@Validated @RequestBody ArticleCollectValidate collectValidate) {
Integer articleId = collectValidate.getArticleId();
Integer articleId = collectValidate.getId();
Integer userId = LikeFrontThreadLocal.getUserId();
iArticleService.addCollect(articleId, userId);
return AjaxResult.success();
}
@PostMapping("/collectCancel")
@PostMapping("/cancelCollect")
@ApiOperation(value="收藏取消")
public AjaxResult<Object> cancelCollect(@Validated @RequestBody ArticleCollectValidate collectValidate) {
Integer articleId = collectValidate.getArticleId();
Integer articleId = collectValidate.getId();
Integer userId = LikeFrontThreadLocal.getUserId();
iArticleService.cancelCollect(articleId, userId);

View File

@ -44,25 +44,22 @@ public class LoginController {
@PostMapping("/account")
@ApiOperation(value="账号登录")
public AjaxResult<LoginTokenVo> account(@Validated @RequestBody LoginPwdValidate loginPwdValidate) {
Integer terminal = LikeFrontThreadLocal.getTerminal();
String account = loginPwdValidate.getAccount();
String password = loginPwdValidate.getPassword();
LoginTokenVo vo = iLoginService.accountLogin(account, password, terminal);
loginPwdValidate.setTerminal(LikeFrontThreadLocal.getTerminal());
LoginTokenVo vo = iLoginService.accountLogin(loginPwdValidate);
return AjaxResult.success(vo);
}
@NotLogin
@PostMapping("/mobileLogin")
@ApiOperation(value="手机登录")
public AjaxResult<LoginTokenVo> mobileLogin(@Validated @RequestBody LoginPhoneValidate loginPhoneValidate) {
Integer terminal = LikeFrontThreadLocal.getTerminal();
String mobile = loginPhoneValidate.getMobile();
String code = loginPhoneValidate.getCode();
LoginTokenVo vo = iLoginService.mobileLogin(mobile, code, terminal);
return AjaxResult.success(vo);
}
// @NotLogin
// @PostMapping("/mobileLogin")
// @ApiOperation(value="手机登录")
// public AjaxResult<LoginTokenVo> mobileLogin(@Validated @RequestBody LoginPhoneValidate loginPhoneValidate) {
// Integer terminal = LikeFrontThreadLocal.getTerminal();
// String mobile = loginPhoneValidate.getMobile();
// String code = loginPhoneValidate.getCode();
//
// LoginTokenVo vo = iLoginService.mobileLogin(mobile, code, terminal);
// return AjaxResult.success(vo);
// }
@NotLogin
@PostMapping("/mnpLogin")

View File

@ -2,6 +2,7 @@ package com.mdd.front.controller;
import com.mdd.common.aop.NotLogin;
import com.mdd.common.core.AjaxResult;
import com.mdd.common.exception.OperateException;
import com.mdd.front.LikeFrontThreadLocal;
import com.mdd.front.service.IUserService;
import com.mdd.front.validate.users.*;
@ -50,11 +51,14 @@ public class UserController {
return AjaxResult.success();
}
@PostMapping("/changePwd")
@PostMapping("/changePassword")
@ApiOperation(value="修改密码")
public AjaxResult<Object> changePwd(@Validated @RequestBody UserChangePwdValidate passwordValidate) {
public AjaxResult<Object> changePassword(@Validated @RequestBody UserChangePwdValidate passwordValidate) {
Integer userId = LikeFrontThreadLocal.getUserId();
if (passwordValidate.getPassword().equals(passwordValidate.getPasswordConfirm()) == false) {
throw new OperateException("两次输入的密码不一致");
}
iUserService.changePwd(passwordValidate.getPassword(), passwordValidate.getOldPassword(), userId);
return AjaxResult.success();
}

View File

@ -1,5 +1,6 @@
package com.mdd.front.service;
import com.mdd.front.validate.login.LoginPwdValidate;
import com.mdd.front.vo.login.LoginTokenVo;
import javax.servlet.http.HttpSession;
@ -28,7 +29,7 @@ public interface ILoginService {
* @param terminal 终端
* @return LoginTokenVo
*/
LoginTokenVo accountLogin(String account, String password, Integer terminal);
LoginTokenVo accountLogin(LoginPwdValidate loginPwdValidate);
/**
* 手机登录
@ -39,7 +40,7 @@ public interface ILoginService {
* @param terminal 终端
* @return LoginTokenVo
*/
LoginTokenVo mobileLogin(String mobile, String code, Integer terminal);
LoginTokenVo mobileLogin(String mobile, String code, Integer terminal, Integer sceneId);
/**
* 微信登录

View File

@ -201,24 +201,26 @@ public class ArticleServiceImpl implements IArticleService {
Integer pageNo = pageValidate.getPage_no();
Integer pageSize = pageValidate.getPage_size();
MPJQueryWrapper<ArticleCollect> mpjQueryWrapper = new MPJQueryWrapper<>();
mpjQueryWrapper.select("t.id,t.article_id,a.title,a.image,a.intro,a.visit,a.create_time")
.eq("t.user_id", userId)
.isNull("t.delete_time")
MPJQueryWrapper<Article> mpjQueryWrapper = new MPJQueryWrapper<>();
mpjQueryWrapper.setAlias("a").select("c.id,c.article_id,a.title,a.image,a.desc,a.is_show,a.click_virtual, a.click_actual,a.create_time, c.create_time as collect_time")
.eq("c.user_id", userId)
.isNull("c.delete_time")
.isNull("a.delete_time")
.orderByDesc("t.id")
.innerJoin("?_article a ON a.id=t.article_id".replace("?_", GlobalConfig.tablePrefix));
.eq("c.status", YesNoEnum.YES.getCode())
.eq("a.is_show", YesNoEnum.YES.getCode())
.orderByDesc("c.id")
.innerJoin("?_article_collect c ON c.article_id=a.id".replace("?_", GlobalConfig.tablePrefix));
IPage<ArticleCollectVo> iPage = articleCollectMapper.selectJoinPage(
IPage<ArticleCollectVo> iPage = articleMapper.selectJoinPage(
new Page<>(pageNo, pageSize),
ArticleCollectVo.class,
mpjQueryWrapper);
for (ArticleCollectVo vo : iPage.getRecords()) {
vo.setImage(UrlUtils.toAbsoluteUrl(vo.getImage()));
vo.setCreateTime(TimeUtils.timestampToDate(vo.getCreateTime()));
vo.setCreateTime(TimeUtils.timestampToDate(Long.valueOf(vo.getCreateTime().toString())));
vo.setCollectTime(TimeUtils.timestampToDate(Long.valueOf(vo.getCollectTime().toString())));
}
return PageResult.iPageHandle(iPage);
}
@ -240,7 +242,7 @@ public class ArticleServiceImpl implements IArticleService {
if (StringUtils.isNotNull(articleCollect)) {
articleCollect.setUpdateTime(System.currentTimeMillis() / 1000);
articleCollect.setStatus(YesNoEnum.NO.getCode());
articleCollect.setStatus(YesNoEnum.YES.getCode());
articleCollectMapper.updateById(articleCollect);
} else {
ArticleCollect model = new ArticleCollect();

View File

@ -3,10 +3,12 @@ package com.mdd.front.service.impl;
import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import cn.dev33.satoken.stp.StpUtil;
import com.alibaba.fastjson2.JSONArray;
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.LoginEnum;
import com.mdd.common.enums.NoticeEnum;
import com.mdd.common.exception.OperateException;
import com.mdd.common.mapper.user.UserAuthMapper;
@ -17,6 +19,7 @@ import com.mdd.common.util.*;
import com.mdd.front.cache.ScanLoginCache;
import com.mdd.front.cache.TokenLoginCache;
import com.mdd.front.service.ILoginService;
import com.mdd.front.validate.login.LoginPwdValidate;
import com.mdd.front.vo.login.LoginTokenVo;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.api.WxConsts;
@ -91,18 +94,36 @@ public class LoginServiceImpl implements ILoginService {
* @return LoginTokenVo
*/
@Override
public LoginTokenVo accountLogin(String account, String password, Integer terminal) {
User user = userMapper.selectOne(new QueryWrapper<User>()
.eq("account", account)
.isNull("delete_time")
.last("limit 1"));
public LoginTokenVo accountLogin(LoginPwdValidate loginPwdValidate) {
JSONArray config = JSONArray.parseArray(ConfigUtils.get("login", "login_way", "[]"));
if (config.contains(loginPwdValidate.getScene().toString()) == false) {
throw new OperateException("不支持的登录方式");
}
Assert.notNull(user, "账号不存在!");
String pwd = ToolUtils.makePassword(password);
Assert.isFalse(!pwd.equals(user.getPassword()), "账号或密码错误!");
Assert.isFalse(!user.getIsDisable().equals(0), "账号已被禁用!");
String account = loginPwdValidate.getAccount();
String password = loginPwdValidate.getPassword();
Integer terminal = loginPwdValidate.getTerminal();
String code = loginPwdValidate.getCode();
Integer sceneId = loginPwdValidate.getScene();
// 账号密码登录
if (loginPwdValidate.getScene().equals(LoginEnum.ACCOUNT_PASSWORD.getCode())) {
User user = userMapper.selectOne(new QueryWrapper<User>()
.nested(wq->wq
.like("account", account).or()
.like("mobile", account).or()
)
.isNull("delete_time")
.last("limit 1"));
return this.__loginToken(user.getId(), user.getMobile(), user.getIsNewUser(), terminal);
Assert.notNull(user, "账号不存在!");
String pwd = ToolUtils.makePassword(password);
Assert.isFalse(!pwd.equals(user.getPassword()), "账号或密码错误!");
Assert.isFalse(!user.getIsDisable().equals(0), "账号已被禁用!");
return this.__loginToken(user.getId(), user.getMobile(), user.getIsNewUser(), terminal);
} else {
return mobileLogin(account, code, terminal, sceneId);
}
}
/**
@ -114,18 +135,18 @@ public class LoginServiceImpl implements ILoginService {
* @return LoginTokenVo
*/
@Override
public LoginTokenVo mobileLogin(String mobile, String code, Integer terminal) {
public LoginTokenVo mobileLogin(String mobile, String code, Integer terminal, Integer sceneId) {
// 校验验证码
int sceneCode = NoticeEnum.LOGIN_CAPTCHA.getCode();
if (!NoticeCheck.verify(sceneCode, code)) {
if (!NoticeCheck.verify(sceneCode, code, mobile)) {
throw new OperateException("验证码错误!");
}
// 查询手机号
User user = userMapper.selectOne(new QueryWrapper<User>()
.select("id,username,mobile,is_disable,is_new")
.select("id,account,mobile,is_disable,is_new_user")
.eq("mobile", mobile)
.eq("is_delete", 0)
.isNull("delete_time")
.last("limit 1"));
Assert.notNull(user, "账号不存在!");
@ -328,7 +349,7 @@ public class LoginServiceImpl implements ILoginService {
User user = null;
if (StringUtils.isNotNull(userAuth)) {
user = userMapper.selectOne(new QueryWrapper<User>()
.eq("is_delete", 0)
.isNull("delete_time")
.eq("id", userAuth.getUserId())
.last("limit 1"));
}

View File

@ -192,7 +192,7 @@ public class UserServiceImpl implements IUserService {
@Override
public void changePwd(String password, String oldPassword, Integer userId) {
User user = userMapper.selectOne(new QueryWrapper<User>()
.select("id,password,salt")
.select("id,password")
.eq("id", userId)
.isNull("delete_time")
.last("limit 1"));
@ -228,7 +228,7 @@ public class UserServiceImpl implements IUserService {
public void forgotPwd(String password, String mobile, String code) {
// 校验验证码
int sceneCode = NoticeEnum.FIND_LOGIN_PASSWORD_CAPTCHA.getCode();
if (!NoticeCheck.verify(sceneCode, code)) {
if (!NoticeCheck.verify(sceneCode, code, mobile)) {
throw new OperateException("验证码错误!");
}
@ -266,7 +266,7 @@ public class UserServiceImpl implements IUserService {
// 校验验证码
int sceneCode = type.equals("bind") ? NoticeEnum.BIND_MOBILE_CAPTCHA.getCode() : NoticeEnum.CHANGE_MOBILE_CAPTCHA.getCode() ;
if (!NoticeCheck.verify(sceneCode, code)) {
if (!NoticeCheck.verify(sceneCode, code, mobile)) {
throw new OperateException("验证码错误!");
}

View File

@ -17,6 +17,6 @@ public class ArticleCollectValidate implements Serializable {
@NotNull(message = "articleId参数缺失")
@IDMust(message = "articleId参数必须大于0")
@ApiModelProperty(value = "文章ID", required = true)
private Integer articleId;
private Integer id;
}

View File

@ -16,9 +16,16 @@ public class LoginPwdValidate {
@ApiModelProperty(value = "登录账号", required = true)
private String account;
@NotNull(message = "password参数缺失")
@NotEmpty(message = "密码不能为空")
@ApiModelProperty(value = "登录密码", required = true)
@ApiModelProperty(value = "登录密码")
private String password;
@ApiModelProperty(value = "验证码登录")
private String code;
@ApiModelProperty(value = "终端")
private Integer scene;
@ApiModelProperty(value = "终端")
private Integer terminal;
}

View File

@ -19,6 +19,11 @@ public class UserChangePwdValidate implements Serializable {
@ApiModelProperty(value = "新密码", required = true)
private String password;
@NotNull(message = "请确认密码")
@Pattern(message = "确认密码密码必须是6-20字母+数字组合!", regexp="^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{6,20}$")
@ApiModelProperty(value = "确认密码", required = true)
private String passwordConfirm;
@NotNull(message = "oldPassword参数缺失")
@NotNull(message = "旧密码不能为空")
@ApiModelProperty(value = "旧密码", required = true)

View File

@ -1,5 +1,6 @@
package com.mdd.front.vo.article;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@ -25,12 +26,28 @@ public class ArticleCollectVo implements Serializable {
private String image;
@ApiModelProperty(value = "文章简介")
private String intro;
private String desc;
@ApiModelProperty(value = "浏览数量")
private Integer visit;
@ApiModelProperty(value = "是否显示:1-是.0-否")
private Integer isShow;
@ApiModelProperty(value = "虚拟浏览量")
private Integer clickVirtual;
@ApiModelProperty(value = "实际浏览量")
private Integer clickActual;
@ApiModelProperty(value = "创建时间")
private String createTime;
private Object createTime;
@ApiModelProperty(value = "收集时间")
private Object collectTime;
// @ApiModelProperty(value = "创建时间")
// @JsonProperty("create_time")
// private String createTimeStr;
//
// @ApiModelProperty(value = "收集时间")
// @JsonProperty("collect_time")
// private String collectTimeStr;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB