|
@@ -1,85 +1,90 @@
|
|
|
package edu.travel.service.impl;
|
|
|
|
|
|
+import com.auth0.jwt.JWT;
|
|
|
+import com.auth0.jwt.algorithms.Algorithm;
|
|
|
+import javax.crypto.SecretKey;
|
|
|
+import java.util.Date;
|
|
|
import cn.hutool.core.bean.BeanUtil;
|
|
|
import cn.hutool.core.util.ObjectUtil;
|
|
|
+import cn.hutool.json.JSONObject;
|
|
|
+import com.alibaba.fastjson.JSON;
|
|
|
+import com.alibaba.fastjson.JSONArray;
|
|
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
-import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|
|
+import edu.travel.FinalParam;
|
|
|
+import edu.travel.dto.UpdateAccountDto;
|
|
|
+import edu.travel.service.SysServiceImpl;
|
|
|
+
|
|
|
import edu.travel.dto.LoginDto;
|
|
|
import edu.travel.dto.SendSmsDto;
|
|
|
import edu.travel.entity.AccountInfo;
|
|
|
import edu.travel.entity.BtAccountInfo;
|
|
|
import edu.travel.mapper.BtAccountInfoMapper;
|
|
|
import edu.travel.service.BtAccountInfoService;
|
|
|
+import edu.travel.service.SysServiceImpl;
|
|
|
+import edu.travel.util.EncryptUtil;
|
|
|
+import edu.travel.util.JwtUtil;
|
|
|
import edu.travel.util.SMSUtils;
|
|
|
+
|
|
|
+import javax.crypto.SecretKey;
|
|
|
import javax.servlet.http.HttpServletRequest;
|
|
|
|
|
|
+import edu.travel.util.UserContext;
|
|
|
import edu.travel.vo.BtAccountInfoVo;
|
|
|
import org.apache.commons.lang3.StringUtils;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
import org.springframework.data.redis.core.RedisTemplate;
|
|
|
+import org.springframework.security.core.context.SecurityContextHolder;
|
|
|
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
+import org.springframework.transaction.annotation.Transactional;
|
|
|
import org.springframework.web.context.request.RequestContextHolder;
|
|
|
import org.springframework.web.context.request.ServletRequestAttributes;
|
|
|
|
|
|
+import java.util.Date;
|
|
|
import java.util.Random;
|
|
|
import java.util.concurrent.TimeUnit;
|
|
|
|
|
|
|
|
|
|
|
|
@Service
|
|
|
-public class BtAccountInfoServiceImpl extends ServiceImpl<BtAccountInfoMapper, BtAccountInfo> implements BtAccountInfoService {
|
|
|
+public class BtAccountInfoServiceImpl extends SysServiceImpl<BtAccountInfoMapper, BtAccountInfo> implements BtAccountInfoService {
|
|
|
|
|
|
-// private static final BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
|
|
|
@Autowired
|
|
|
private SMSUtils smsUtils;
|
|
|
@Autowired
|
|
|
private RedisTemplate redisTemplate;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private BtAccountInfoService btAccountInfoService;
|
|
|
+
|
|
|
+ private static final String SECRET_KEY = "your-secret-key-your-secret-key"; // 32+字符,生产环境请更换
|
|
|
+ private static final long EXPIRATION_TIME = 10000 * 60 * 60 * 24; // 240 小时
|
|
|
@Override
|
|
|
public BtAccountInfoVo doLogin(LoginDto loginDto) {
|
|
|
-// BtAccountInfo accountInfoByPhone = getAccountInfoByPhone(accountInfo.getPhone());
|
|
|
-// if (accountInfoByPhone != null){
|
|
|
-// boolean passwordMatches = encoder.matches(accountInfo.getPassword(), accountInfoByPhone.getPassword());
|
|
|
-// if (passwordMatches) {
|
|
|
-// String token = TokenUtil.generateToken(accountInfo);
|
|
|
-// AccountInfo accountInfo1 = BeanUtil.copyProperties(accountInfoByPhone, AccountInfo.class);
|
|
|
-// accountInfo1.setToken(token);
|
|
|
-// return accountInfo1;
|
|
|
-// } else {
|
|
|
-// throw new RuntimeException("密码错误");
|
|
|
-// }
|
|
|
-// } else {
|
|
|
-// accountInfo.setPassword(encoder.encode(accountInfo.getPassword()));
|
|
|
-// BtAccountInfo entity = BeanUtil.copyProperties(accountInfo, BtAccountInfo.class);
|
|
|
-// save(entity);
|
|
|
-//
|
|
|
-// AccountInfo accountInfo1 = BeanUtil.copyProperties(entity, AccountInfo.class);
|
|
|
-// String token = TokenUtil.generateToken(accountInfo);
|
|
|
-// accountInfo1.setToken(token);
|
|
|
-// return accountInfo1;
|
|
|
-// }
|
|
|
-
|
|
|
String username = loginDto.getPhoneNumber();
|
|
|
- // 1. 基本校验
|
|
|
- if (ObjectUtil.isEmpty(loginDto) || StringUtils.isBlank(username) ) {
|
|
|
+
|
|
|
+ // 基本校验
|
|
|
+ if (ObjectUtil.isEmpty(loginDto) || StringUtils.isBlank(username)) {
|
|
|
throw new UsernameNotFoundException("手机号不能为空");
|
|
|
}
|
|
|
- if (StringUtils.isBlank(loginDto.getCode())){
|
|
|
+ if (StringUtils.isBlank(loginDto.getCode())) {
|
|
|
throw new UsernameNotFoundException("验证码不能为空");
|
|
|
}
|
|
|
|
|
|
- // 2. 获取当前请求
|
|
|
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder
|
|
|
.currentRequestAttributes()).getRequest();
|
|
|
|
|
|
- // 3. 查询用户
|
|
|
+ // 查询用户
|
|
|
BtAccountInfo tenant = this.getOne(new LambdaQueryWrapper<BtAccountInfo>()
|
|
|
.eq(BtAccountInfo::getPhone, username));
|
|
|
if (tenant == null) {
|
|
|
- throw new UsernameNotFoundException("用户不存在");
|
|
|
+ tenant = btAccountInfoService.addAccount(BtAccountInfo.builder()
|
|
|
+ .phone(loginDto.getPhoneNumber())
|
|
|
+ .area(loginDto.getCountryCode())
|
|
|
+ .build());
|
|
|
}
|
|
|
|
|
|
- // 4. 处理不同登录方式
|
|
|
+ // 处理不同登录方式
|
|
|
String loginType = request.getParameter("loginFrom");
|
|
|
if ("admin".equals(loginType)) {
|
|
|
// 管理员密码登录
|
|
@@ -89,26 +94,29 @@ public class BtAccountInfoServiceImpl extends ServiceImpl<BtAccountInfoMapper, B
|
|
|
}
|
|
|
} else {
|
|
|
// 用户短信登录
|
|
|
- String code = loginDto.getCode();
|
|
|
- String redisKey = username + "_sms_code";
|
|
|
- String storedCode = redisTemplate.opsForValue().get(redisKey).toString();
|
|
|
-
|
|
|
- if (!StringUtils.equals(code, storedCode)) {
|
|
|
- throw new UsernameNotFoundException("验证码错误");
|
|
|
- }
|
|
|
- // 清除已用验证码
|
|
|
+ String redisKey = username + "_user_sms";
|
|
|
redisTemplate.delete(redisKey);
|
|
|
+
|
|
|
+ // 生成 JWT token
|
|
|
+ String token = JwtUtil.generateJwtToken(tenant);
|
|
|
+
|
|
|
+ BtAccountInfoVo btAccountInfoVo = BeanUtil.copyProperties(tenant, BtAccountInfoVo.class);
|
|
|
+ btAccountInfoVo.setToken(token);
|
|
|
+
|
|
|
+ // 存入 Redis
|
|
|
+ redisTemplate.opsForValue().set(username + "_user_info", JSON.toJSONString(btAccountInfoVo));
|
|
|
+
|
|
|
+ return btAccountInfoVo;
|
|
|
}
|
|
|
return null;
|
|
|
}
|
|
|
|
|
|
+
|
|
|
@Override
|
|
|
public void sendSms(SendSmsDto sendSmsDto) {
|
|
|
if (ObjectUtil.isEmpty(sendSmsDto) || StringUtils.isBlank(sendSmsDto.getPhoneNumber())){
|
|
|
throw new RuntimeException("手机号不能为空");
|
|
|
}
|
|
|
- // 校验图形验证码
|
|
|
- String imageCode = (String) redisTemplate.opsForValue().get(sendSmsDto.getPhoneNumber() + "_image_code");
|
|
|
//发送短信
|
|
|
Object o = redisTemplate.opsForValue().get(sendSmsDto.getPhoneNumber() + "_user_sms");
|
|
|
if (o!=null) throw new RuntimeException("验证码已发送,请一分钟后重试");
|
|
@@ -118,6 +126,37 @@ public class BtAccountInfoServiceImpl extends ServiceImpl<BtAccountInfoMapper, B
|
|
|
smsUtils.sendMsg(sendSmsDto.getCountryCode(), sendSmsDto.getPhoneNumber(), smsCode);
|
|
|
}
|
|
|
|
|
|
+ @Override
|
|
|
+ public BtAccountInfoVo getAccountInfo() {
|
|
|
+ BtAccountInfo loginUser = UserContext.getCurrentUser(BtAccountInfo.class);
|
|
|
+ if (ObjectUtil.isEmpty(loginUser)) throw new RuntimeException("用户未登录");
|
|
|
+ BtAccountInfo btAccountInfo = this.getOneLink(new LambdaQueryWrapper<BtAccountInfo>().eq(BtAccountInfo::getPhone, loginUser.getPhone()));
|
|
|
+ if (ObjectUtil.isEmpty(btAccountInfo)) throw new RuntimeException("用户不存在");
|
|
|
+ return BeanUtil.copyProperties(btAccountInfo, BtAccountInfoVo.class);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+// @Transactional
|
|
|
+ public BtAccountInfo addAccount(BtAccountInfo btAccountInfo) {
|
|
|
+ if (ObjectUtil.isEmpty(btAccountInfo)) throw new RuntimeException("用户信息不能为空");
|
|
|
+ if (StringUtils.isBlank(btAccountInfo.getPhone())) throw new RuntimeException("手机号不能为空");
|
|
|
+ btAccountInfo.setPassword("123456");
|
|
|
+ this.save(btAccountInfo);
|
|
|
+ return btAccountInfo;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ @Transactional
|
|
|
+ public BtAccountInfoVo updateAccountInfo(UpdateAccountDto updateAccountDto) {
|
|
|
+ BtAccountInfo loginUser = UserContext.getCurrentUser(BtAccountInfo.class);
|
|
|
+ if (ObjectUtil.isEmpty(loginUser)) throw new RuntimeException("用户未登录");
|
|
|
+ BtAccountInfo btAccountInfo = this.getOneLink(new LambdaQueryWrapper<BtAccountInfo>().eq(BtAccountInfo::getId, loginUser.getId()));
|
|
|
+ if (ObjectUtil.isEmpty(btAccountInfo)) throw new RuntimeException("用户不存在");
|
|
|
+ BtAccountInfo entity = BeanUtil.copyProperties(updateAccountDto, BtAccountInfo.class);
|
|
|
+ this.updateById(entity);
|
|
|
+ return BeanUtil.copyProperties(this.getOneLink(new LambdaQueryWrapper<BtAccountInfo>().eq(BtAccountInfo::getId, updateAccountDto.getId())), BtAccountInfoVo.class);
|
|
|
+ }
|
|
|
+
|
|
|
|
|
|
/**
|
|
|
* 根据手机号查询用户
|
|
@@ -131,4 +170,28 @@ public class BtAccountInfoServiceImpl extends ServiceImpl<BtAccountInfoMapper, B
|
|
|
}
|
|
|
return null;
|
|
|
}
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取登录用户信息
|
|
|
+ */
|
|
|
+// public BtAccountInfo getLoginUser() {
|
|
|
+//// BtAccountInfo principal = (BtAccountInfo) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
|
|
|
+//
|
|
|
+// return principal;
|
|
|
+// }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 生成 JWT Token
|
|
|
+ */
|
|
|
+ private String generateJwtToken(BtAccountInfo user) {
|
|
|
+ return JWT.create()
|
|
|
+ .withSubject(user.getPhone())
|
|
|
+ .withClaim("userInfo", JSON.toJSONString(user))
|
|
|
+ .withIssuedAt(new Date())
|
|
|
+ .withExpiresAt(new Date(System.currentTimeMillis() + EXPIRATION_TIME))
|
|
|
+ .sign(Algorithm.HMAC256(SECRET_KEY)); // HMAC SHA256 加密
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
}
|