Browse Source

小程序登录

pengcheng 1 month ago
parent
commit
ecfdde0089

+ 14 - 4
ruoyi-api/src/main/java/com/ruoyi/api/controller/user/ApiUserLoginController.java

@@ -2,22 +2,21 @@ package com.ruoyi.api.controller.user;
 
 import cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo;
 import com.ruoyi.api.controller.common.AbstractApiController;
+import com.ruoyi.clock.domain.vo.EmployeeVo;
 import com.ruoyi.common.core.domain.R;
 import com.ruoyi.framework.web.service.ApiTokenService;
 import com.ruoyi.user.domain.User;
 import com.ruoyi.user.service.IUserService;
+import com.ruoyi.weixin.domain.WxEmployeeDto;
 import com.ruoyi.weixin.domain.WxUserDto;
 import com.ruoyi.weixin.service.WxUserService;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import lombok.RequiredArgsConstructor;
-import org.apache.commons.lang.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
-
 import java.util.HashMap;
-import java.util.Map;
 
 /**
  * 小程序用户管理Controller
@@ -38,6 +37,18 @@ public class ApiUserLoginController extends AbstractApiController {
     private ApiTokenService apiTokenService;
 
     private final WxUserService wxUserService;
+
+    /**
+     * 小程序登录
+     */
+    @ApiOperation("小程序登录")
+    @PostMapping("/wx/login")
+    public R login(@RequestBody @Validated WxEmployeeDto wxEmployeeDto) {
+        EmployeeVo user = userService.login(wxEmployeeDto);
+        String token = apiTokenService.generateEmployeeToken(user);
+        return R.ok(token);
+    }
+
     /**
      * 小程序授权登录
      */
@@ -50,7 +61,6 @@ public class ApiUserLoginController extends AbstractApiController {
         return R.ok(token);
     }
 
-
     /**
      * 小程序获取手机号
      */

+ 8 - 0
ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/ApiTokenService.java

@@ -1,6 +1,7 @@
 package com.ruoyi.framework.web.service;
 
 import cn.hutool.core.date.DateUtil;
+import com.ruoyi.clock.domain.vo.EmployeeVo;
 import com.ruoyi.common.constant.Constants;
 import com.ruoyi.common.utils.DateUtils;
 import com.ruoyi.user.domain.User;
@@ -42,6 +43,13 @@ public class ApiTokenService {
         return doGenerateToken(claims, user.getNickname());
     }
 
+    public String generateEmployeeToken(EmployeeVo user) {
+        Map<String, Object> claims = new HashMap<>();
+        // 自定义参数,把需要存入token的参数都可以自定义到这里,比如 角色 部门类的关键参数
+        claims.put(Constants.USER_ID, user.getEmployeeId());
+        return doGenerateToken(claims, user.getEmployeeName());
+    }
+
     /**
      * 生成小程序token
      *

+ 7 - 0
ruoyi-system/src/main/java/com/ruoyi/clock/domain/Employee.java

@@ -2,6 +2,7 @@ package com.ruoyi.clock.domain;
 
 import com.baomidou.mybatisplus.annotation.*;
 import com.ruoyi.common.core.domain.BaseEntity;
+import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 import lombok.NoArgsConstructor;
 import java.io.Serializable;
@@ -39,6 +40,12 @@ public class Employee extends BaseEntity {
      * 店铺id
      */
     private Long shopId;
+
+    /**
+     * 用户头像
+     */
+    private String avatar;
+
     /**
      * 手机号码
      */

+ 6 - 0
ruoyi-system/src/main/java/com/ruoyi/clock/domain/bo/EmployeeBo.java

@@ -52,6 +52,12 @@ public class EmployeeBo extends BaseEntity {
     @NotNull(message = "店铺id不能为空", groups = { AddGroup.class, EditGroup.class })
     private Long shopId;
 
+    /**
+     * 用户头像
+     */
+    @ApiModelProperty(value = "用户头像")
+    private String avatar;
+
     /**
      * 手机号码
      */

+ 9 - 1
ruoyi-system/src/main/java/com/ruoyi/clock/domain/vo/EmployeeVo.java

@@ -67,6 +67,12 @@ public class EmployeeVo {
     @ApiModelProperty("店铺名称")
     private String shopName;
 
+    /**
+     * 用户头像
+     */
+    @ApiModelProperty(value = "用户头像")
+    private String avatar;
+
     /**
      * 手机号码
      */
@@ -89,6 +95,9 @@ public class EmployeeVo {
     @ApiModelProperty("密码")
     private String password;
 
+    @ApiModelProperty("删除标志(0代表存在 2代表删除)")
+    private String delFlag;
+
     @ApiModelProperty("代理商信息")
     private AgentVo agent;
 
@@ -116,5 +125,4 @@ public class EmployeeVo {
         }
         return this.shop;
     }
-
 }

+ 3 - 0
ruoyi-system/src/main/java/com/ruoyi/clock/mapper/EmployeeMapper.java

@@ -2,6 +2,7 @@ package com.ruoyi.clock.mapper;
 
 import com.ruoyi.clock.domain.Employee;
 import com.ruoyi.clock.domain.vo.EmployeeVo;
+import com.ruoyi.common.core.domain.entity.SysUser;
 import com.ruoyi.common.core.mapper.BaseMapperPlus;
 
 /**
@@ -12,4 +13,6 @@ import com.ruoyi.common.core.mapper.BaseMapperPlus;
  */
 public interface EmployeeMapper extends BaseMapperPlus<EmployeeMapper, Employee, EmployeeVo> {
 
+    EmployeeVo selectUserByUserName(String userName);
+
 }

+ 9 - 0
ruoyi-system/src/main/java/com/ruoyi/clock/service/IEmployeeService.java

@@ -4,6 +4,7 @@ import com.ruoyi.clock.domain.Employee;
 import com.ruoyi.clock.domain.bo.EmployeeStatusBo;
 import com.ruoyi.clock.domain.vo.EmployeeVo;
 import com.ruoyi.clock.domain.bo.EmployeeBo;
+import com.ruoyi.common.core.domain.entity.SysUser;
 import com.ruoyi.common.core.page.TableDataInfo;
 import com.ruoyi.common.core.domain.PageQuery;
 
@@ -42,6 +43,14 @@ public interface IEmployeeService {
      */
     EmployeeVo queryById(Long employeeId);
 
+    /**
+     * 通过用户名查询用户
+     *
+     * @param userName 用户名
+     * @return 用户对象信息
+     */
+    EmployeeVo selectUserByUserName(String userName);
+
     /**
      * 详情店员信息
      *

+ 5 - 0
ruoyi-system/src/main/java/com/ruoyi/clock/service/impl/EmployeeServiceImpl.java

@@ -88,6 +88,11 @@ public class EmployeeServiceImpl implements IEmployeeService {
         return baseMapper.selectVoById(employeeId);
     }
 
+    @Override
+    public EmployeeVo selectUserByUserName(String userName) {
+        return baseMapper.selectUserByUserName(userName);
+    }
+
     /**
      * 详情店员信息
      *

+ 5 - 0
ruoyi-system/src/main/resources/mapper/clock/EmployeeMapper.xml

@@ -19,4 +19,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
     </resultMap>
 
 
+    <select id="selectUserByUserName" resultType="com.ruoyi.clock.domain.vo.EmployeeVo">
+        select * from tb_employee e where e.del_flag = '0' and e.phonenumber = #{userName}
+    </select>
+
+
 </mapper>

+ 4 - 0
ruoyi-user/pom.xml

@@ -23,5 +23,9 @@
             <groupId>com.ruoyi</groupId>
             <artifactId>ruoyi-weixin-miniapp</artifactId>
         </dependency>
+        <dependency>
+            <groupId>com.ruoyi</groupId>
+            <artifactId>ruoyi-system</artifactId>
+        </dependency>
     </dependencies>
 </project>

+ 5 - 0
ruoyi-user/src/main/java/com/ruoyi/user/service/IUserService.java

@@ -1,10 +1,12 @@
 package com.ruoyi.user.service;
 
+import com.ruoyi.clock.domain.vo.EmployeeVo;
 import com.ruoyi.user.domain.User;
 import com.ruoyi.user.domain.vo.UserVo;
 import com.ruoyi.user.domain.bo.UserBo;
 import com.ruoyi.common.core.page.TableDataInfo;
 import com.ruoyi.common.core.domain.PageQuery;
+import com.ruoyi.weixin.domain.WxEmployeeDto;
 import com.ruoyi.weixin.domain.WxUserDto;
 
 import java.util.Collection;
@@ -71,4 +73,7 @@ public interface IUserService {
     User authorization(WxUserDto wxUserDto);
 
     User getById(Long userId, boolean isThrow);
+
+    EmployeeVo login(WxEmployeeDto wxEmployeeDto);
+
 }

+ 53 - 0
ruoyi-user/src/main/java/com/ruoyi/user/service/impl/UserServiceImpl.java

@@ -1,24 +1,35 @@
 package com.ruoyi.user.service.impl;
 
 import cn.binarywang.wx.miniapp.bean.WxMaUserInfo;
+import cn.dev33.satoken.secure.BCrypt;
 import cn.hutool.core.bean.BeanUtil;
 import cn.hutool.core.util.ObjectUtil;
+import com.ruoyi.clock.domain.vo.EmployeeVo;
+import com.ruoyi.clock.service.IEmployeeService;
+import com.ruoyi.common.constant.Constants;
+import com.ruoyi.common.core.domain.entity.SysUser;
 import com.ruoyi.common.enums.ExceptionEnum;
+import com.ruoyi.common.enums.UserStatus;
 import com.ruoyi.common.exception.ServiceException;
+import com.ruoyi.common.exception.user.UserException;
+import com.ruoyi.common.utils.MessageUtils;
 import com.ruoyi.common.utils.StringUtils;
 import com.ruoyi.common.core.page.TableDataInfo;
 import com.ruoyi.common.core.domain.PageQuery;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.ruoyi.common.utils.redis.RedisUtils;
 import com.ruoyi.user.domain.UserThirdIdentity;
 import com.ruoyi.user.domain.bo.UserThirdIdentityBo;
 import com.ruoyi.user.mapper.UserThirdIdentityMapper;
 import com.ruoyi.user.service.IUserThirdIdentityService;
+import com.ruoyi.weixin.domain.WxEmployeeDto;
 import com.ruoyi.weixin.domain.WxUserDto;
 import com.ruoyi.weixin.service.WxMsgService;
 import com.ruoyi.weixin.service.WxUserService;
 import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import com.ruoyi.user.domain.bo.UserBo;
@@ -32,6 +43,7 @@ import java.util.Date;
 import java.util.List;
 import java.util.Map;
 import java.util.Collection;
+import java.util.concurrent.TimeUnit;
 
 /**
  * 小程序用户管理Service业务层处理
@@ -41,12 +53,15 @@ import java.util.Collection;
  */
 @RequiredArgsConstructor
 @Service
+@Slf4j
 public class UserServiceImpl implements IUserService {
 
     private final UserMapper baseMapper;
 
     private final WxUserService wxUserService;
 
+    private final IEmployeeService employeeService;
+
     private final UserThirdIdentityMapper userThirdIdentityMapper;
 
     /**
@@ -232,4 +247,42 @@ public class UserServiceImpl implements IUserService {
         }
         return obj;
     }
+
+    @Override
+    public EmployeeVo login(WxEmployeeDto wxEmployeeDto) {
+        String username = wxEmployeeDto.getUsername();
+        String password = wxEmployeeDto.getPassword();
+        EmployeeVo user = loadUserByUsername(username);
+        Integer errorNumber = RedisUtils.getCacheObject(Constants.LOGIN_ERROR + username);
+        if (!BCrypt.checkpw(password, user.getPassword())) {
+            // 是否第一次
+            errorNumber = ObjectUtil.isNull(errorNumber) ? 1 : errorNumber + 1;
+            // 达到规定错误次数 则锁定登录
+            if (errorNumber.equals(Constants.LOGIN_ERROR_NUMBER)) {
+                RedisUtils.setCacheObject(Constants.LOGIN_ERROR + username, errorNumber, Constants.LOGIN_ERROR_LIMIT_TIME, TimeUnit.MINUTES);
+                throw new UserException("user.password.retry.limit.exceed", Constants.LOGIN_ERROR_LIMIT_TIME);
+            } else {
+                // 未达到规定错误次数 则递增
+                RedisUtils.setCacheObject(Constants.LOGIN_ERROR + username, errorNumber);
+                throw new UserException("user.password.retry.limit.count", errorNumber);
+            }
+        }
+        return user;
+    }
+
+    private EmployeeVo loadUserByUsername(String username) {
+        EmployeeVo user = employeeService.selectUserByUserName(username);
+        if (ObjectUtil.isNull(user)) {
+            log.info("登录用户:{} 不存在.", username);
+            throw new UserException("user.not.exists", username);
+        } else if (UserStatus.DELETED.getCode().equals(user.getDelFlag())) {
+            log.info("登录用户:{} 已被删除.", username);
+            throw new UserException("user.password.delete", username);
+        } else if (UserStatus.DISABLE.getCode().equals(user.getStatus())) {
+            log.info("登录用户:{} 已被停用.", username);
+            throw new UserException("user.blocked", username);
+        }
+        return user;
+    }
+
 }

+ 27 - 0
ruoyi-weixin/ruoyi-weixin-miniapp/src/main/java/com/ruoyi/weixin/domain/WxEmployeeDto.java

@@ -0,0 +1,27 @@
+package com.ruoyi.weixin.domain;
+
+import com.ruoyi.common.constant.UserConstants;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import org.hibernate.validator.constraints.Length;
+
+import javax.validation.constraints.NotBlank;
+import java.io.Serializable;
+
+/**
+ * 店员用户
+ */
+@Data
+public class WxEmployeeDto implements Serializable {
+
+    @NotBlank(message = "{user.username.not.blank}")
+    @Length(min = UserConstants.USERNAME_MIN_LENGTH, max = UserConstants.USERNAME_MAX_LENGTH, message = "{user.username.length.valid}")
+    @ApiModelProperty(value = "用户名")
+    private String username;
+
+    @NotBlank(message = "{user.password.not.blank}")
+    @Length(min = UserConstants.PASSWORD_MIN_LENGTH, max = UserConstants.PASSWORD_MAX_LENGTH, message = "{user.password.length.valid}")
+    @ApiModelProperty(value = "用户密码")
+    private String password;
+
+}