From f5d14f3b3f5b4888308f1da8e92f1db040b9f791 Mon Sep 17 00:00:00 2001 From: Helius <wangdoubleone@gmail.com> Date: Thu, 16 Sep 2021 17:08:44 +0800 Subject: [PATCH] add login interface --- src/main/java/cc/mrbird/febs/mall/controller/ApiLoginController.java | 15 + src/main/java/cc/mrbird/febs/mall/mapper/MallMemberMapper.java | 5 src/main/java/cc/mrbird/febs/mall/service/ICommonService.java | 9 + src/main/resources/mapper/modules/MallMemberMapper.xml | 11 + src/main/java/cc/mrbird/febs/mall/service/IApiMallMemberService.java | 14 ++ src/main/java/cc/mrbird/febs/mall/dto/RegisterDto.java | 2 src/main/java/cc/mrbird/febs/mall/service/impl/ApiMallMemberServiceImpl.java | 155 ++++++++++++++++++++++ src/main/java/cc/mrbird/febs/mall/dto/LoginDto.java | 24 +++ src/main/java/cc/mrbird/febs/mall/entity/MallMember.java | 19 ++ src/main/java/cc/mrbird/febs/common/utils/AppContants.java | 18 -- src/main/java/cc/mrbird/febs/mall/service/impl/CommonService.java | 6 src/main/java/cc/mrbird/febs/common/entity/BaseEntity.java | 4 src/main/java/cc/mrbird/febs/common/utils/ShareCodeUtil.java | 110 +++++++++++++++ 13 files changed, 364 insertions(+), 28 deletions(-) diff --git a/src/main/java/cc/mrbird/febs/common/entity/BaseEntity.java b/src/main/java/cc/mrbird/febs/common/entity/BaseEntity.java index 4a7e64a..fa87659 100644 --- a/src/main/java/cc/mrbird/febs/common/entity/BaseEntity.java +++ b/src/main/java/cc/mrbird/febs/common/entity/BaseEntity.java @@ -21,9 +21,9 @@ private String updatedBy = "system"; - private Date createdTime; + private Date createdTime = new Date(); - private Date updatedTime; + private Date updatedTime = new Date(); @TableId(value = "id",type = IdType.AUTO) private Long id; diff --git a/src/main/java/cc/mrbird/febs/common/utils/AppContants.java b/src/main/java/cc/mrbird/febs/common/utils/AppContants.java index 4ac326b..4d0dd5b 100644 --- a/src/main/java/cc/mrbird/febs/common/utils/AppContants.java +++ b/src/main/java/cc/mrbird/febs/common/utils/AppContants.java @@ -45,23 +45,6 @@ */ public static final String SYSTEM_REFERER = "rxadr3"; - /** - * 初始化金额 - */ - public static final BigDecimal INIT_MONEY = BigDecimal.ZERO; - - - public static final Integer INIT_SIMULATE_MONEY = 5000; - - /** - * homeSymbols 接口状态值 币币 - */ - public static final int HOME_SYMBOLS_COIN = 1; - - /** - * homeSymbols 接口状态值 合约 - */ - public static final int HOME_SYMBOLS_CONTRACT = 2; /** * 验证码前缀 手机 @@ -75,6 +58,5 @@ public static final String TIME_OUT = "time_out"; - public static final String CLOSING_ORDER_PREFIX = "closing_cnt_"; } diff --git a/src/main/java/cc/mrbird/febs/common/utils/ShareCodeUtil.java b/src/main/java/cc/mrbird/febs/common/utils/ShareCodeUtil.java new file mode 100644 index 0000000..c00834c --- /dev/null +++ b/src/main/java/cc/mrbird/febs/common/utils/ShareCodeUtil.java @@ -0,0 +1,110 @@ +package cc.mrbird.febs.common.utils; + +import java.util.Random; + +public class ShareCodeUtil { + + /** + * 自定义进制(0,1没有加入,容易与o,l混淆) + */ +// private static final char[] r=new char[]{'q', 'w', 'e', '8', 'a', 's', '2', 'd', 'z', 'x', '9', 'c', '7', 'p', '5', 'i', 'k', '3', 'm', 'j', 'u', 'f', 'r', '4', 'v', 'y', 'l', 't', 'n', '6', 'b', 'g', 'h'}; + private static final char[] r = new char[]{'1', '2', '3', '4', '5', '6', '7', '8', '9'}; + + /** + * (不能与自定义进制有重复) + */ + private static final char b = '0'; + + /** + * 进制长度 + */ + private static final int binLen = r.length; + + /** + * 序列最小长度 + */ + private static final int s = 8; + + /** + * 根据ID生成六位随机码 + * + * @param id ID + * @return 随机码 + */ + public static String toSerialCode(long id) { + char[] buf = new char[32]; + int charPos = 32; + + while ((id / binLen) > 0) { + int ind = (int) (id % binLen); + buf[--charPos] = r[ind]; + id /= binLen; + } + buf[--charPos] = r[(int) (id % binLen)]; + String str = new String(buf, charPos, (32 - charPos)); + // 不够长度的自动随机补全 + if (str.length() < s) { + StringBuilder sb = new StringBuilder(); + sb.append(b); + Random rnd = new Random(); + for (int i = 1; i < s - str.length(); i++) { + sb.append(r[rnd.nextInt(binLen)]); + } + str += sb.toString(); + } + return str; + } + + /** + * 根据ID生成六位随机码 + * + * @param id ID + * @return 随机码 + */ + public static String toSerialNumberCode(long id) { + char[] buf = new char[32]; + int charPos = 32; + + while ((id / binLen) > 0) { + int ind = (int) (id % binLen); + buf[--charPos] = r[ind]; + id /= binLen; + } + buf[--charPos] = r[(int) (id % binLen)]; + String str = new String(buf, charPos, (32 - charPos)); + // 不够长度的自动随机补全 + if (str.length() < s) { + StringBuilder sb = new StringBuilder(); + sb.append(b); + Random rnd = new Random(); + for (int i = 1; i < s - str.length(); i++) { + sb.append(r[rnd.nextInt(binLen)]); + } + str += sb.toString(); + } + return str; + } + + public static long codeToId(String code) { + char chs[] = code.toCharArray(); + long res = 0L; + for (int i = 0; i < chs.length; i++) { + int ind = 0; + for (int j = 0; j < binLen; j++) { + if (chs[i] == r[j]) { + ind = j; + break; + } + } + if (chs[i] == b) { + break; + } + if (i > 0) { + res = res * binLen + ind; + } else { + res = ind; + } + } + return res; + } +} diff --git a/src/main/java/cc/mrbird/febs/mall/controller/ApiLoginController.java b/src/main/java/cc/mrbird/febs/mall/controller/ApiLoginController.java index 496a308..3dc024f 100644 --- a/src/main/java/cc/mrbird/febs/mall/controller/ApiLoginController.java +++ b/src/main/java/cc/mrbird/febs/mall/controller/ApiLoginController.java @@ -1,8 +1,9 @@ package cc.mrbird.febs.mall.controller; import cc.mrbird.febs.common.entity.FebsResponse; +import cc.mrbird.febs.mall.dto.LoginDto; import cc.mrbird.febs.mall.dto.RegisterDto; -import cc.mrbird.febs.mall.service.MallMemberService; +import cc.mrbird.febs.mall.service.IApiMallMemberService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.RequiredArgsConstructor; @@ -23,15 +24,21 @@ @Validated @RequiredArgsConstructor @RestController -@RequestMapping(value = "/api/login/") +@RequestMapping(value = "/api/login") @Api(value = "ApiLoginController", tags = "登录注册类") public class ApiLoginController { - private final MallMemberService memberService; + private final IApiMallMemberService memberService; - @ApiOperation(value = "app注册接口", notes = "app注册接口,验证码必须输入可默认为123456") + @ApiOperation(value = "app注册接口", notes = "app注册接口") @PostMapping(value = "/register") public FebsResponse register(@RequestBody RegisterDto registerDto) { return memberService.register(registerDto); } + + @ApiOperation(value = "账号密码登录接口", notes = "账号密码登录接口") + @PostMapping(value = "/toLogin") + public FebsResponse login(@RequestBody LoginDto loginDto) { + return memberService.toLogin(loginDto); + } } diff --git a/src/main/java/cc/mrbird/febs/mall/dto/LoginDto.java b/src/main/java/cc/mrbird/febs/mall/dto/LoginDto.java new file mode 100644 index 0000000..2870467 --- /dev/null +++ b/src/main/java/cc/mrbird/febs/mall/dto/LoginDto.java @@ -0,0 +1,24 @@ +package cc.mrbird.febs.mall.dto; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotBlank; + +/** + * @author wzy + * @date 2021-09-16 + **/ +@Data +@ApiModel(value = "LoginDto", description = "登录接口参数接收类") +public class LoginDto { + + @NotBlank(message = "账号不能为空") + @ApiModelProperty(value = "账号", example = "15773001234") + private String account; + + @NotBlank(message = "密码不能为空") + @ApiModelProperty(value = "密码", example = "123456") + private String password; +} diff --git a/src/main/java/cc/mrbird/febs/mall/dto/RegisterDto.java b/src/main/java/cc/mrbird/febs/mall/dto/RegisterDto.java index 69a49f7..a8ef6af 100644 --- a/src/main/java/cc/mrbird/febs/mall/dto/RegisterDto.java +++ b/src/main/java/cc/mrbird/febs/mall/dto/RegisterDto.java @@ -23,7 +23,7 @@ private String password; @ApiModelProperty(value = "类型 1-手机号 2-邮箱", example = "1") - private Integer type = 1; + private String type = "1"; @NotBlank(message = "验证码不能为空") @ApiModelProperty(value = "验证码", example = "123456") diff --git a/src/main/java/cc/mrbird/febs/mall/entity/MallMember.java b/src/main/java/cc/mrbird/febs/mall/entity/MallMember.java index af98c35..14f5a20 100644 --- a/src/main/java/cc/mrbird/febs/mall/entity/MallMember.java +++ b/src/main/java/cc/mrbird/febs/mall/entity/MallMember.java @@ -1,6 +1,7 @@ package cc.mrbird.febs.mall.entity; import cc.mrbird.febs.common.controller.BaseController; +import cc.mrbird.febs.common.entity.BaseEntity; import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; @@ -10,7 +11,7 @@ **/ @Data @TableName("mall_member") -public class MallMember extends BaseController { +public class MallMember extends BaseEntity { private String name; @@ -31,7 +32,23 @@ private String level; private Integer accountStatus; + /** + * 启用 + */ + public static final Integer ACCOUNT_STATUS_ENABLE = 1; + /** + * 禁用 + */ + public static final Integer ACCOUNT_STATUS_DISABLED = 2; private Integer accountType; + /** + * 正常账号 + */ + public static final Integer ACCOUNT_TYPE_NORMAL = 1; + /** + * 测试账号 + */ + public static final Integer ACCOUNT_TYPE_TEST = 2; } diff --git a/src/main/java/cc/mrbird/febs/mall/mapper/MallMemberMapper.java b/src/main/java/cc/mrbird/febs/mall/mapper/MallMemberMapper.java index 4245646..490fe89 100644 --- a/src/main/java/cc/mrbird/febs/mall/mapper/MallMemberMapper.java +++ b/src/main/java/cc/mrbird/febs/mall/mapper/MallMemberMapper.java @@ -12,6 +12,11 @@ **/ public interface MallMemberMapper extends BaseMapper<MallMember> { + MallMember selectInfoByAccount(@Param("account") String account); + IPage<MallMember> selectMallMemberListInPage(Page<MallMember> page, @Param("record")MallMember mallMember); + MallMember selectInfoByInviteId(@Param("inviteId") String inviteId); + + MallMember selectInfoByAccountAndPwd(@Param("account") String account, @Param("password") String password); } diff --git a/src/main/java/cc/mrbird/febs/mall/service/IApiMallMemberService.java b/src/main/java/cc/mrbird/febs/mall/service/IApiMallMemberService.java new file mode 100644 index 0000000..f0d3815 --- /dev/null +++ b/src/main/java/cc/mrbird/febs/mall/service/IApiMallMemberService.java @@ -0,0 +1,14 @@ +package cc.mrbird.febs.mall.service; + +import cc.mrbird.febs.common.entity.FebsResponse; +import cc.mrbird.febs.mall.dto.LoginDto; +import cc.mrbird.febs.mall.dto.RegisterDto; +import cc.mrbird.febs.mall.entity.MallMember; +import com.baomidou.mybatisplus.extension.service.IService; + +public interface IApiMallMemberService extends IService<MallMember> { + FebsResponse register(RegisterDto registerDto); + + FebsResponse toLogin(LoginDto loginDto); + +} diff --git a/src/main/java/cc/mrbird/febs/mall/service/ICommonService.java b/src/main/java/cc/mrbird/febs/mall/service/ICommonService.java new file mode 100644 index 0000000..6508cb3 --- /dev/null +++ b/src/main/java/cc/mrbird/febs/mall/service/ICommonService.java @@ -0,0 +1,9 @@ +package cc.mrbird.febs.mall.service; + +/** + * @author wzy + * @date 2021-09-16 + **/ +public interface ICommonService { + boolean verifyCode(String account, String code); +} diff --git a/src/main/java/cc/mrbird/febs/mall/service/impl/ApiMallMemberServiceImpl.java b/src/main/java/cc/mrbird/febs/mall/service/impl/ApiMallMemberServiceImpl.java new file mode 100644 index 0000000..8b3273e --- /dev/null +++ b/src/main/java/cc/mrbird/febs/mall/service/impl/ApiMallMemberServiceImpl.java @@ -0,0 +1,155 @@ +package cc.mrbird.febs.mall.service.impl; + +import cc.mrbird.febs.common.entity.FebsResponse; +import cc.mrbird.febs.common.exception.FebsException; +import cc.mrbird.febs.common.utils.AppContants; +import cc.mrbird.febs.common.utils.RedisUtils; +import cc.mrbird.febs.common.utils.ShareCodeUtil; +import cc.mrbird.febs.mall.dto.LoginDto; +import cc.mrbird.febs.mall.dto.RegisterDto; +import cc.mrbird.febs.mall.entity.MallMember; +import cc.mrbird.febs.mall.mapper.MallMemberMapper; +import cc.mrbird.febs.mall.service.IApiMallMemberService; +import cc.mrbird.febs.mall.service.ICommonService; +import cn.hutool.core.util.IdUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import cn.hutool.crypto.SecureUtil; +import cn.hutool.crypto.asymmetric.KeyType; +import cn.hutool.crypto.asymmetric.RSA; +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @author wzy + * @date 2021-09-16 + **/ +@Slf4j +@Service +@RequiredArgsConstructor +public class ApiMallMemberServiceImpl extends ServiceImpl<MallMemberMapper, MallMember> implements IApiMallMemberService { + + private final ICommonService commonService; + private final RedisUtils redisUtils; + + @Value("${spring.profiles.active}") + private String active; + + @Override + public FebsResponse register(RegisterDto registerDto) { + MallMember mallMember = this.baseMapper.selectInfoByAccount(registerDto.getAccount()); + if (mallMember != null) { + throw new FebsException("该手机号/邮箱已被占用"); + } + + String account = registerDto.getAccount(); + String code = registerDto.getCode(); + boolean flags = commonService.verifyCode(account, code); + if(!flags) { + throw new FebsException("验证码错误"); + } + + mallMember = new MallMember(); + mallMember.setPassword(SecureUtil.md5(registerDto.getPassword())); + + // 判断账号类型 + if (AppContants.ACCOUNT_TYPE_MOBILE.equals(registerDto.getType())) { + mallMember.setPhone(registerDto.getAccount()); + } else { + mallMember.setEmail(registerDto.getAccount()); + } + + Integer count = this.baseMapper.selectCount(null); + if (count != null && count != 0) { + MallMember inviteMember = this.baseMapper.selectInfoByInviteId(registerDto.getInviteId()); + if (inviteMember == null) { + throw new FebsException("邀请码不存在"); + } + + mallMember.setReferrerId(registerDto.getInviteId()); + + } + mallMember.setName(registerDto.getAccount()); + mallMember.setAccountStatus(MallMember.ACCOUNT_STATUS_ENABLE); + mallMember.setAccountType(MallMember.ACCOUNT_TYPE_NORMAL); + mallMember.setLevel("1"); + mallMember.setSex("男"); + + this.baseMapper.insert(mallMember); + + String inviteId = ShareCodeUtil.toSerialCode(mallMember.getId()); + mallMember.setInviteId(inviteId); + + //推荐人和推荐人链 + boolean flag = false; + String parentId = mallMember.getReferrerId(); + String ids = ""; + while (!flag) { + if (StrUtil.isBlank(ids)) { + ids += parentId; + } else { + ids += ("," + parentId); + } + MallMember parentMember = this.baseMapper.selectInfoByInviteId(parentId); + if (parentMember == null) { + break; + } + parentId = parentMember.getReferrerId(); + if (parentMember.getReferrerId().equals(parentMember.getInviteId())) { + flag = true; + } + } + + if (StrUtil.isNotBlank(ids)) { + mallMember.setReferrerIds(ids); + } + this.baseMapper.updateById(mallMember); + return new FebsResponse().success().message("注册成功"); + } + + @Override + public FebsResponse toLogin(LoginDto loginDto) { + String md5Pwd = SecureUtil.md5(loginDto.getPassword()); + + MallMember mallMember = this.baseMapper.selectInfoByAccountAndPwd(loginDto.getAccount(), md5Pwd); + if (mallMember == null) { + throw new FebsException("用户不存在或账号密码错误"); + } + + if (MallMember.ACCOUNT_STATUS_DISABLED.equals(mallMember.getAccountStatus())) { + throw new FebsException("该账号存在异常, 暂限制登录"); + } + + String redisKey = AppContants.APP_LOGIN_PREFIX + mallMember.getId(); + String existToken = redisUtils.getString(redisKey); + if (StrUtil.isNotBlank(existToken)) { + Object o = redisUtils.get(existToken); + if (ObjectUtil.isNotEmpty(o)) { + redisUtils.del(existToken); + } + } + + String token = IdUtil.simpleUUID(); + redisUtils.set(token, JSONObject.toJSONString(mallMember), 360000); + redisUtils.set(redisKey, token, 360000); + Map<String, Object> authInfo = new HashMap<>(); + authInfo.put("token", token); + if ("dev".equals(active)) { + authInfo.put("rasToken", generateAsaToken(token)); + } + return new FebsResponse().success().data(authInfo); + } + + public String generateAsaToken(String token) { + RSA rsa = new RSA(null, AppContants.PUBLIC_KEY); + return rsa.encryptBase64(token + "_" + System.currentTimeMillis(), KeyType.PublicKey); + } +} diff --git a/src/main/java/cc/mrbird/febs/mall/service/CommonService.java b/src/main/java/cc/mrbird/febs/mall/service/impl/CommonService.java similarity index 83% rename from src/main/java/cc/mrbird/febs/mall/service/CommonService.java rename to src/main/java/cc/mrbird/febs/mall/service/impl/CommonService.java index 06e129d..443f40f 100644 --- a/src/main/java/cc/mrbird/febs/mall/service/CommonService.java +++ b/src/main/java/cc/mrbird/febs/mall/service/impl/CommonService.java @@ -1,7 +1,8 @@ -package cc.mrbird.febs.mall.service; +package cc.mrbird.febs.mall.service.impl; import cc.mrbird.febs.common.utils.AppContants; import cc.mrbird.febs.common.utils.RedisUtils; +import cc.mrbird.febs.mall.service.ICommonService; import cn.hutool.core.util.StrUtil; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -14,9 +15,10 @@ @Slf4j @Service @RequiredArgsConstructor -public class CommonService { +public class CommonService implements ICommonService { private final RedisUtils redisUtils; + @Override public boolean verifyCode(String account, String code) { String cacheCode = redisUtils.getString(AppContants.VERIFY_CODE_PREFIX + account); if (StrUtil.isBlank(cacheCode)) { diff --git a/src/main/resources/mapper/modules/MallMemberMapper.xml b/src/main/resources/mapper/modules/MallMemberMapper.xml index 3d724fb..f5cfcb7 100644 --- a/src/main/resources/mapper/modules/MallMemberMapper.xml +++ b/src/main/resources/mapper/modules/MallMemberMapper.xml @@ -23,4 +23,15 @@ order by m.CREATED_TIME desc </select> + <select id="selectInfoByAccount" resultType="cc.mrbird.febs.mall.entity.MallMember"> + select * from mall_member where phone=#{account} or email=#{account} + </select> + + <select id="selectInfoByInviteId" resultType="cc.mrbird.febs.mall.entity.MallMember"> + select * from mall_member where invite_id=#{inviteId} + </select> + + <select id="selectInfoByAccountAndPwd" resultType="cc.mrbird.febs.mall.entity.MallMember"> + select * from mall_member where (phone=#{account} or email=#{account}) and password=#{password} + </select> </mapper> \ No newline at end of file -- Gitblit v1.9.1