今日完成

乘客用户中心服务
验证码发送
首先我们需要开发用户注册和登录功能,其中重点是乘客发送验证码,以下是发送验证码的时序图

REST ful 风格
在设计rest fuk 风格的时候,我们需要考虑以下的事情:
- 协议(http,https)
- 域名 (www.xxx.com/aoi/courses,api.xxx.com/courses)
- 路径
- 版本(v1,v2等)
- 动作(post,put,patch, delete, get)
nacos下载和配置
下载地址:https://github.com/alibaba/nacos/releases/tag/2.0.3
添加maven依赖
<!-- nacos-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
<version>2021.1</version>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<version>2021.1</version>
</dependency>
# 启动Nacos Server:
定位到bin目录,然后执行启动命令:
## cmd窗口
startup.cmd -m standalone
## powershell窗口
.\startup.cmd -m standalone
这将以单机模式启动Nacos服务器。

获取随机验证码
@RestController
public class NumberCodeController {
@GetMapping("/numberCode/{size}")
public String numberCode(@PathVariable("size") int size) {
System.out.println("生成验证码,验证码长度:" + size);
JSONObject result = new JSONObject();
result.put("code", 1);
result.put("message", "success");
JSONObject data = new JSONObject();
//获取随机数
String number = "0123456789";
StringBuilder numberCode = new StringBuilder();
for (int i = 0; i < size; i++) {
int index = (int) (Math.random() * number.length());
char c = number.charAt(index);
numberCode.append(c);
}
System.out.println(numberCode.toString());
data.put("numberCode", numberCode);
result.put("data", data);
return result.toString();
}
}
统一返回类型
public enum CommonStatusEnum {
SUCCESS(1, "success"),
FAIL(0, "fail");
@Getter
private int code;
@Getter
private String value;
private CommonStatusEnum(int code, String value) {
this.code = code;
this.value = value;
}
}
@Data
@Accessors(chain = true)
public class ResponseResult<T> {
private int code;
private String message;
private T data;
/**
* 成功返回结果
*/
public static <T> ResponseResult<T> success(T data) {
return new ResponseResult<T>().setCode(CommonStatusEnum.SUCCESS.getCode())
.setMessage(CommonStatusEnum.SUCCESS.getValue())
.setData(data);
}
/**
* 失败返回结果
*/
public static <T> ResponseResult<T> fail(int code , String message) {
return new ResponseResult<T>().setCode(code)
.setMessage(message);
}
/**
* 失败返回结果,自定义失败
*/
public static <T> ResponseResult<T> fail(int code, String message,T data) {
return new ResponseResult<T>().setCode(code)
.setMessage(message)
.setData(data);
}
/**
* 失败:统一失败
*/
public static <T> ResponseResult<T> fail(T data) {
return new ResponseResult<T>().setData(data);
}
}
改造后的为:
@RestController
public class NumberCodeController {
@GetMapping("/numberCode/{size}")
public ResponseResult numberCode(@PathVariable("size") int size) {
System.out.println("生成验证码,验证码长度:" + size);
//获取随机数
String number = "0123456789";
StringBuilder numberCode = new StringBuilder();
for (int i = 0; i < size; i++) {
int index = (int) (Math.random() * number.length());
char c = number.charAt(index);
numberCode.append(c);
}
//定义返回值
NumberCodeResponse numberCodeResponse = new NumberCodeResponse();
numberCodeResponse.setNumberCode(Integer.parseInt(numberCode.toString()));
return ResponseResult.success(numberCodeResponse);
}
}
api-passenger和service-verificationCode之间的调用
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
@FeignClient("service-verificationcode")
public interface ServiceVerificationCodeClient {
@GetMapping("/numberCode/{size}")
ResponseResult<NumberCodeResponse> numberCode(@PathVariable("size") int size);
}
验证码redis使用
maven依赖
<!--redis使用-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
yml编写
server:
port: 8081
spring:
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
application:
name: api-passenger
redis:
host: 127.0.0.1
port: 6379
代码编写
@Service
public class VerificationCodeService {
// 验证码前缀
private String verificationCodePrefix = "passenger-verification-code-";
@Autowired
private StringRedisTemplate stringRedisTemplate;
@Autowired
private ServiceVerificationCodeClient serviceVerificationCodeClient;
public ResponseResult generateCode(String passengerPhone){
// 调用验证码服务
System.out.println("调用生成验证码服务");
ResponseResult<NumberCodeResponse> numberCode = serviceVerificationCodeClient.numberCode(6);
System.out.println("获取验证码为:" + numberCode.getData().getNumberCode());
//存入redis
System.out.println("将验证码存入redis");
String key = verificationCodePrefix + passengerPhone;
stringRedisTemplate.opsForValue().set(key, numberCode.getData().toString(),1, TimeUnit.MINUTES);
//通过第三发短信商务发送验证码 TODO
//返回值
return ResponseResult.success(numberCode);
}
}
校验验证码

骨架
@PostMapping("/verification-code-check")
public ResponseResult verificationCodeCheck(@RequestBody VerificationCodeDTO verificationCodeDTO){
String passengerPhone = verificationCodeDTO.getPassengerPhone();
String verificationCode = verificationCodeDTO.getVerificationCode();
return verificationCodeService.checkCode(passengerPhone, verificationCode);
}
/**
* 校验验证码
* @param passengerPhone
* @param verificationCode
* @return
*/
public ResponseResult checkCode(String passengerPhone, String verificationCode){
//1.根据手机号获取redis中的验证码
//2.校验验证码
//3.判断原来是否存在用户,如果不存在,则创建用户
//4.颁发令牌
TokenResponse tokenResponse = new TokenResponse();
tokenResponse.setToken("token value");
//5.返回结果
return ResponseResult.success(tokenResponse);
}
校验redis验证码
/**
* 校验验证码
* @param passengerPhone
* @param verificationCode
* @return
*/
public ResponseResult checkCode(String passengerPhone, String verificationCode){
//1.根据手机号获取redis中的验证码
String key = generatorKeyByPhone(passengerPhone);
String codeRedis = stringRedisTemplate.opsForValue().get(key);
System.out.println("redis中的key:"+codeRedis);
if (codeRedis == null){
return ResponseResult.fail(CommonStatusEnum.VERIFICATION_CODE_ERROR.getCode(), CommonStatusEnum.VERIFICATION_CODE_ERROR.getValue());
}
if (!codeRedis.equals(verificationCode)){
return ResponseResult.fail(CommonStatusEnum.VERIFICATION_CODE_ERROR.getCode(), CommonStatusEnum.VERIFICATION_CODE_ERROR.getValue());
}
stringRedisTemplate.delete(key);
//2.校验验证码
//3.判断原来是否存在用户,如果不存在,则创建用户
//4.颁发令牌
TokenResponse tokenResponse = new TokenResponse();
tokenResponse.setToken("token value");
//5.返回结果
return ResponseResult.success(tokenResponse);
}
private String generatorKeyByPhone(String phone){
return verificationCodePrefix + phone;
}
}
乘客用户服务
骨架
@RestController
public class UserController {
@Autowired
private UserService userService;
@PostMapping("/user")
public ResponseResult loginOrRegister(@RequestBody VerificationCodeDTO verificationCodeDTO){
String passengerPhone = verificationCodeDTO.getPassengerPhone();
return userService.loginOrRegister(passengerPhone);
}
}
@Service
public class UserService {
public ResponseResult loginOrRegister(String passengerPhone){
System.out.println("注册手机号被调用,手机号为:"+passengerPhone);
//根据手机号查询用户
//判断用户是否存在
return ResponseResult.success(passengerPhone);
}
}