add sms code
This commit is contained in:
7
DockerFile
Normal file
7
DockerFile
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
FROM eclipse-temurin:21-jdk-jammy
|
||||||
|
MAINTAINER TongTongStudio <tongtongstudios@gmail.com>
|
||||||
|
RUN mv /etc/apt/sources.list /etc/apt/sources.list.bak
|
||||||
|
VOLUME /tmp
|
||||||
|
ADD target/*.jar app.jar
|
||||||
|
EXPOSE 8088
|
||||||
|
ENTRYPOINT ["java", "-jar", "/app.jar"]
|
||||||
36
pom.xml
36
pom.xml
@@ -1,6 +1,13 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<repositories>
|
||||||
|
<repository>
|
||||||
|
<id>nexus-tencentyun</id>
|
||||||
|
<url>http://mirrors.cloud.tencent.com/nexus/repository/maven-public/</url>
|
||||||
|
</repository>
|
||||||
|
<!-- 添加其他镜像源 -->
|
||||||
|
</repositories>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
@@ -38,6 +45,15 @@
|
|||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-web</artifactId>
|
<artifactId>spring-boot-starter-web</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-jdbc</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springdoc</groupId>
|
||||||
|
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
|
||||||
|
<version>2.1.0</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.projectlombok</groupId>
|
<groupId>org.projectlombok</groupId>
|
||||||
@@ -54,6 +70,26 @@
|
|||||||
<artifactId>reactor-test</artifactId>
|
<artifactId>reactor-test</artifactId>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>mysql</groupId>
|
||||||
|
<artifactId>mysql-connector-java</artifactId>
|
||||||
|
<scope>runtime</scope>
|
||||||
|
<version>8.0.33</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!--异步处理-->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.aliyun</groupId>
|
||||||
|
<artifactId>alibabacloud-dysmsapi20170525</artifactId>
|
||||||
|
<version>3.0.2</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!--同步-->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.aliyun</groupId>
|
||||||
|
<artifactId>dysmsapi20170525</artifactId>
|
||||||
|
<version>3.1.1</version>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
|||||||
@@ -0,0 +1,45 @@
|
|||||||
|
package com.ttstd.videotablet.controller;
|
||||||
|
|
||||||
|
import com.ttstd.videotablet.result.Result;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
public class HelloController {
|
||||||
|
//引入 redis
|
||||||
|
@Autowired
|
||||||
|
private StringRedisTemplate stringRedisTemplate;
|
||||||
|
|
||||||
|
@GetMapping("/")
|
||||||
|
public Result getMethodName() {
|
||||||
|
return Result.ok().message("Welcome to Yijiantong");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 存储
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@PostMapping("/set")
|
||||||
|
public Result setRedis(@RequestParam(value = "username") String username) {
|
||||||
|
//存储 key-value 键值对: "username"-"jaychou"
|
||||||
|
stringRedisTemplate.opsForValue().set("username", username);
|
||||||
|
return Result.ok().message("redis 存储成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 读取
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@GetMapping("/get")
|
||||||
|
public Result getRedis(@RequestParam(value = "username") String username) {
|
||||||
|
//通过 key 值读取 value
|
||||||
|
String result = stringRedisTemplate.opsForValue().get(username);
|
||||||
|
return Result.ok().data("username", result);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,105 @@
|
|||||||
|
package com.ttstd.videotablet.controller;
|
||||||
|
|
||||||
|
import com.aliyun.dysmsapi20170525.models.SendSmsResponse;
|
||||||
|
import com.aliyun.tea.TeaException;
|
||||||
|
import com.ttstd.videotablet.result.Result;
|
||||||
|
import com.ttstd.videotablet.sms.SendSms;
|
||||||
|
import com.ttstd.videotablet.utils.TextUtils;
|
||||||
|
import org.apache.commons.lang3.RandomStringUtils;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
public class SmsController {
|
||||||
|
private static final int LOGIN_CODE_TTL = 5;
|
||||||
|
|
||||||
|
//引入 redis
|
||||||
|
@Autowired
|
||||||
|
private StringRedisTemplate stringRedisTemplate;
|
||||||
|
|
||||||
|
@GetMapping("/verify_code")
|
||||||
|
public Result getMethodName(@RequestParam("number") String number) {
|
||||||
|
if (TextUtils.isEmpty(number)) {
|
||||||
|
return Result.error().message("phone number is empty");
|
||||||
|
}
|
||||||
|
String oldCode = stringRedisTemplate.opsForValue().get(number);
|
||||||
|
if (TextUtils.isEmpty(oldCode)) {
|
||||||
|
String code = SendSms.generatedcode(6);
|
||||||
|
return sendCode(number, code);
|
||||||
|
} else {
|
||||||
|
return sendCode(number, oldCode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Result sendCode(String number, String code) {
|
||||||
|
try {
|
||||||
|
com.aliyun.dysmsapi20170525.Client client = createClient();
|
||||||
|
com.aliyun.dysmsapi20170525.models.SendSmsRequest sendSmsRequest = new com.aliyun.dysmsapi20170525.models.SendSmsRequest()
|
||||||
|
.setSignName("同同的小站")
|
||||||
|
.setTemplateCode("SMS_468370574")
|
||||||
|
.setPhoneNumbers(number)
|
||||||
|
.setTemplateParam("{\"code\":\"" + code + "\"}");
|
||||||
|
com.aliyun.teautil.models.RuntimeOptions runtime = new com.aliyun.teautil.models.RuntimeOptions();
|
||||||
|
// 复制代码运行请自行打印 API 的返回值
|
||||||
|
SendSmsResponse sendSmsResponse = client.sendSmsWithOptions(sendSmsRequest, runtime);
|
||||||
|
// System.out.println(sendSmsResponse.body.toMap());
|
||||||
|
// System.out.println(sendSmsResponse.getBody().getMessage());
|
||||||
|
// System.out.println(sendSmsResponse.getBody().getCode());
|
||||||
|
if ("OK".equals(sendSmsResponse.getBody().getCode())) {
|
||||||
|
String randomString = RandomStringUtils.randomAlphanumeric(32);
|
||||||
|
Map<String, Object> map = new HashMap<>();
|
||||||
|
map.put("verify_key", randomString);
|
||||||
|
map.put("sms", sendSmsResponse.getBody().getMessage());
|
||||||
|
//4.保存验证码到Redis,并且设置有效期5分钟
|
||||||
|
stringRedisTemplate.opsForValue().set(number, code, LOGIN_CODE_TTL, TimeUnit.MINUTES);
|
||||||
|
return Result.ok().data(map);
|
||||||
|
} else {
|
||||||
|
return Result.error().message(sendSmsResponse.getBody().getMessage());
|
||||||
|
}
|
||||||
|
} catch (TeaException error) {
|
||||||
|
// 此处仅做打印展示,请谨慎对待异常处理,在工程项目中切勿直接忽略异常。
|
||||||
|
// 错误 message
|
||||||
|
System.out.println(error.getMessage());
|
||||||
|
// 诊断地址
|
||||||
|
System.out.println(error.getData().get("Recommend"));
|
||||||
|
com.aliyun.teautil.Common.assertAsString(error.message);
|
||||||
|
return Result.error().data("sms", error.message);
|
||||||
|
} catch (Exception _error) {
|
||||||
|
TeaException error = new TeaException(_error.getMessage(), _error);
|
||||||
|
// 此处仅做打印展示,请谨慎对待异常处理,在工程项目中切勿直接忽略异常。
|
||||||
|
// 错误 message
|
||||||
|
System.out.println(error.getMessage());
|
||||||
|
// 诊断地址
|
||||||
|
System.out.println(error.getData().get("Recommend"));
|
||||||
|
com.aliyun.teautil.Common.assertAsString(error.message);
|
||||||
|
return Result.error().data("sms", error.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 使用AK&SK初始化账号Client
|
||||||
|
*
|
||||||
|
* @return Client
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public com.aliyun.dysmsapi20170525.Client createClient() throws Exception {
|
||||||
|
// 工程代码泄露可能会导致 AccessKey 泄露,并威胁账号下所有资源的安全性。以下代码示例仅供参考。
|
||||||
|
// 建议使用更安全的 STS 方式,更多鉴权访问方式请参见:https://help.aliyun.com/document_detail/378657.html。
|
||||||
|
com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config()
|
||||||
|
// 必填,请确保代码运行环境设置了环境变量 ALIBABA_CLOUD_ACCESS_KEY_ID。
|
||||||
|
.setAccessKeyId("LTAI5tEVYLeg7U3bP58n3Xkj")
|
||||||
|
// 必填,请确保代码运行环境设置了环境变量 ALIBABA_CLOUD_ACCESS_KEY_SECRET。
|
||||||
|
.setAccessKeySecret("bbPSlxkaGgkhUPaCOP7CANaNNY1b2p");
|
||||||
|
// Endpoint 请参考 https://api.aliyun.com/product/Dysmsapi
|
||||||
|
config.endpoint = "dysmsapi.aliyuncs.com";
|
||||||
|
return new com.aliyun.dysmsapi20170525.Client(config);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,90 @@
|
|||||||
|
package com.ttstd.videotablet.handler;
|
||||||
|
|
||||||
|
import com.ttstd.videotablet.result.Result;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.validation.FieldError;
|
||||||
|
import org.springframework.web.bind.MethodArgumentNotValidException;
|
||||||
|
import org.springframework.web.bind.MissingServletRequestParameterException;
|
||||||
|
import org.springframework.web.bind.annotation.ControllerAdvice;
|
||||||
|
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||||
|
import org.springframework.web.bind.annotation.ResponseBody;
|
||||||
|
import org.springframework.web.bind.annotation.ResponseStatus;
|
||||||
|
import org.springframework.web.servlet.resource.NoResourceFoundException;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 统一异常处理
|
||||||
|
*
|
||||||
|
* @author 爷爷的茶七里香
|
||||||
|
* @date 2022/05/30 ControllerAdvice注解的含义是当异常抛到controller层时会拦截下来
|
||||||
|
*/
|
||||||
|
@ControllerAdvice
|
||||||
|
public class GlobalExceptionHandler {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 使用ExceptionHandler注解声明处理Exception异常
|
||||||
|
*
|
||||||
|
* @param e e
|
||||||
|
* @return {@link Result}
|
||||||
|
*/
|
||||||
|
@ResponseBody
|
||||||
|
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
|
||||||
|
@ExceptionHandler(Exception.class)
|
||||||
|
public Result handlerException(Exception e) {
|
||||||
|
// 控制台打印异常
|
||||||
|
e.printStackTrace();
|
||||||
|
// 返回错误格式信息
|
||||||
|
return Result.error().message(e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
@ResponseBody
|
||||||
|
@ResponseStatus(HttpStatus.BAD_REQUEST)
|
||||||
|
@ExceptionHandler(MissingServletRequestParameterException.class)
|
||||||
|
public Result handlerMissingServletRequestParameterException(MissingServletRequestParameterException e) {
|
||||||
|
// 控制台打印异常
|
||||||
|
e.printStackTrace();
|
||||||
|
return Result.error().message("缺少参数");
|
||||||
|
}
|
||||||
|
|
||||||
|
@ResponseBody
|
||||||
|
@ResponseStatus(HttpStatus.NOT_FOUND)
|
||||||
|
@ExceptionHandler(NoResourceFoundException.class)
|
||||||
|
public Result handleNoResourceFoundException(NoResourceFoundException ex) {
|
||||||
|
ex.printStackTrace();
|
||||||
|
// 新版本 Spring(推荐)我没有这个方法
|
||||||
|
// return ResponseEntity.notFound().body(error);
|
||||||
|
// 旧版本 Spring(兼容写法)
|
||||||
|
return Result.notFound().message("检查网址是否正确");
|
||||||
|
}
|
||||||
|
|
||||||
|
@ResponseBody
|
||||||
|
@ResponseStatus(HttpStatus.BAD_REQUEST)
|
||||||
|
@ExceptionHandler(MethodArgumentNotValidException.class)
|
||||||
|
public Result handleValidationExceptions(MethodArgumentNotValidException ex) {
|
||||||
|
ex.printStackTrace();
|
||||||
|
Map<String, Object> errors = new HashMap<>();
|
||||||
|
ex.getBindingResult().getAllErrors().forEach(error -> {
|
||||||
|
String fieldName = ((FieldError) error).getField();
|
||||||
|
String errorMessage = error.getDefaultMessage();
|
||||||
|
errors.put(fieldName, errorMessage);
|
||||||
|
});
|
||||||
|
return Result.error().message("参数不能为空").data(errors);
|
||||||
|
}
|
||||||
|
|
||||||
|
// @ResponseStatus(HttpStatus.BAD_REQUEST)
|
||||||
|
// @ExceptionHandler({MethodArgumentNotValidException.class, BindException.class})
|
||||||
|
// @ResponseBody
|
||||||
|
// public Map<String, String> handleValidationException(Exception ex) {
|
||||||
|
// BindingResult result = ex instanceof MethodArgumentNotValidException
|
||||||
|
// ? ((MethodArgumentNotValidException) ex).getBindingResult()
|
||||||
|
// : ((BindException) ex).getBindingResult();
|
||||||
|
//
|
||||||
|
// Map<String, String> errors = new HashMap<>();
|
||||||
|
// result.getFieldErrors().forEach(error -> {
|
||||||
|
// errors.put(error.getField(), error.getDefaultMessage());
|
||||||
|
// });
|
||||||
|
// return errors;
|
||||||
|
// }
|
||||||
|
}
|
||||||
60
src/main/java/com/ttstd/videotablet/result/JsonData.java
Normal file
60
src/main/java/com/ttstd/videotablet/result/JsonData.java
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
package com.ttstd.videotablet.result;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 接口返回工具类
|
||||||
|
*/
|
||||||
|
public class JsonData {
|
||||||
|
private int code;
|
||||||
|
private Object data;
|
||||||
|
private String msg;
|
||||||
|
|
||||||
|
public JsonData() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public JsonData(int code, Object data) {
|
||||||
|
this.code = code;
|
||||||
|
this.data = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public JsonData(int code, Object data, String msg) {
|
||||||
|
this.code = code;
|
||||||
|
this.data = data;
|
||||||
|
this.msg = msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static JsonData buildSuccess(Object data) {
|
||||||
|
return new JsonData(0, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static JsonData buildError(String msg) {
|
||||||
|
return new JsonData(-1, "", msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static JsonData buildError(int code, String msg) {
|
||||||
|
return new JsonData(code, "", msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getCode() {
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCode(int code) {
|
||||||
|
this.code = code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object getData() {
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setData(Object data) {
|
||||||
|
this.data = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMsg() {
|
||||||
|
return msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMsg(String msg) {
|
||||||
|
this.msg = msg;
|
||||||
|
}
|
||||||
|
}
|
||||||
129
src/main/java/com/ttstd/videotablet/result/Result.java
Normal file
129
src/main/java/com/ttstd/videotablet/result/Result.java
Normal file
@@ -0,0 +1,129 @@
|
|||||||
|
package com.ttstd.videotablet.result;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 统一返回格式类
|
||||||
|
*
|
||||||
|
* @author 爷爷的茶七里香
|
||||||
|
* @date 2022/05/30
|
||||||
|
*/
|
||||||
|
public class Result {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否成功
|
||||||
|
*/
|
||||||
|
private Boolean success;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 状态码
|
||||||
|
*/
|
||||||
|
private Integer code;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 返回的消息
|
||||||
|
*/
|
||||||
|
private String message;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 放置响应的数据
|
||||||
|
*/
|
||||||
|
private Map<String, Object> data = new HashMap<>();
|
||||||
|
|
||||||
|
public Result() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 以下是定义一些常用到的格式,可以看到调用了我们创建的枚举类 */
|
||||||
|
|
||||||
|
public static Result ok() {
|
||||||
|
Result r = new Result();
|
||||||
|
r.setSuccess(ResultCodeEnum.SUCCESS.getSuccess());
|
||||||
|
r.setCode(ResultCodeEnum.SUCCESS.getCode());
|
||||||
|
r.setMessage(ResultCodeEnum.SUCCESS.getMessage());
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Result error() {
|
||||||
|
Result r = new Result();
|
||||||
|
r.setSuccess(ResultCodeEnum.UNKNOWN_REASON.getSuccess());
|
||||||
|
r.setCode(ResultCodeEnum.UNKNOWN_REASON.getCode());
|
||||||
|
r.setMessage(ResultCodeEnum.UNKNOWN_REASON.getMessage());
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Result notFound() {
|
||||||
|
Result r = new Result();
|
||||||
|
r.setSuccess(ResultCodeEnum.NOT_FOUND.getSuccess());
|
||||||
|
r.setCode(ResultCodeEnum.NOT_FOUND.getCode());
|
||||||
|
r.setMessage(ResultCodeEnum.NOT_FOUND.getMessage());
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Result setResult(ResultCodeEnum resultCodeEnum) {
|
||||||
|
Result r = new Result();
|
||||||
|
r.setSuccess(resultCodeEnum.getSuccess());
|
||||||
|
r.setCode(resultCodeEnum.getCode());
|
||||||
|
r.setMessage(resultCodeEnum.getMessage());
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Result success(Boolean success) {
|
||||||
|
this.setSuccess(success);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Result message(String message) {
|
||||||
|
this.setMessage(message);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Result code(Integer code) {
|
||||||
|
this.setCode(code);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Result data(String key, Object value) {
|
||||||
|
this.data.put(key, value);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Result data(Map<String, Object> map) {
|
||||||
|
this.setData(map);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 以下是get/set方法,如果项目有集成lombok可以使用@Data注解代替 */
|
||||||
|
|
||||||
|
public Boolean getSuccess() {
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSuccess(Boolean success) {
|
||||||
|
this.success = success;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getCode() {
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCode(Integer code) {
|
||||||
|
this.code = code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMessage() {
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMessage(String message) {
|
||||||
|
this.message = message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, Object> getData() {
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setData(Map<String, Object> data) {
|
||||||
|
this.data = data;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
package com.ttstd.videotablet.result;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 状态码
|
||||||
|
*
|
||||||
|
* @author 爷爷的茶七里香
|
||||||
|
* @date 2022/05/30
|
||||||
|
*/
|
||||||
|
public enum ResultCodeEnum {
|
||||||
|
|
||||||
|
SUCCESS(true, 20000, "成功"),
|
||||||
|
|
||||||
|
UNKNOWN_REASON(false, 20001, "未知错误"),
|
||||||
|
NOT_FOUND(true, 20004, "没有数据");
|
||||||
|
|
||||||
|
|
||||||
|
private final Boolean success;
|
||||||
|
|
||||||
|
private final Integer code;
|
||||||
|
|
||||||
|
private final String message;
|
||||||
|
|
||||||
|
ResultCodeEnum(Boolean success, Integer code, String message) {
|
||||||
|
this.success = success;
|
||||||
|
this.code = code;
|
||||||
|
this.message = message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean getSuccess() {
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getCode() {
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMessage() {
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "ResultCodeEnum{" + "success=" + success + ", code=" + code + ", message='" + message + '\'' + '}';
|
||||||
|
}
|
||||||
|
}
|
||||||
95
src/main/java/com/ttstd/videotablet/sms/SendSms.java
Normal file
95
src/main/java/com/ttstd/videotablet/sms/SendSms.java
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
package com.ttstd.videotablet.sms;
|
||||||
|
|
||||||
|
// This file is auto-generated, don't edit it. Thanks.
|
||||||
|
|
||||||
|
import com.aliyun.auth.credentials.Credential;
|
||||||
|
import com.aliyun.auth.credentials.provider.StaticCredentialProvider;
|
||||||
|
import com.aliyun.sdk.service.dysmsapi20170525.AsyncClient;
|
||||||
|
import com.aliyun.sdk.service.dysmsapi20170525.models.SendSmsRequest;
|
||||||
|
import com.aliyun.sdk.service.dysmsapi20170525.models.SendSmsResponse;
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import darabonba.core.client.ClientOverrideConfiguration;
|
||||||
|
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
|
public class SendSms {
|
||||||
|
public static void sendTest(String number) throws Exception {
|
||||||
|
|
||||||
|
// HttpClient Configuration
|
||||||
|
/*HttpClient httpClient = new ApacheAsyncHttpClientBuilder()
|
||||||
|
.connectionTimeout(Duration.ofSeconds(10)) // Set the connection timeout time, the default is 10 seconds
|
||||||
|
.responseTimeout(Duration.ofSeconds(10)) // Set the response timeout time, the default is 20 seconds
|
||||||
|
.maxConnections(128) // Set the connection pool size
|
||||||
|
.maxIdleTimeOut(Duration.ofSeconds(50)) // Set the connection pool timeout, the default is 30 seconds
|
||||||
|
// Configure the proxy
|
||||||
|
.proxy(new ProxyOptions(ProxyOptions.Type.HTTP, new InetSocketAddress("<your-proxy-hostname>", 9001))
|
||||||
|
.setCredentials("<your-proxy-username>", "<your-proxy-password>"))
|
||||||
|
// If it is an https connection, you need to configure the certificate, or ignore the certificate(.ignoreSSL(true))
|
||||||
|
.x509TrustManagers(new X509TrustManager[]{})
|
||||||
|
.keyManagers(new KeyManager[]{})
|
||||||
|
.ignoreSSL(false)
|
||||||
|
.build();*/
|
||||||
|
|
||||||
|
// Configure Credentials authentication information, including ak, secret, token
|
||||||
|
StaticCredentialProvider provider = StaticCredentialProvider.create(Credential.builder()
|
||||||
|
// Please ensure that the environment variables ALIBABA_CLOUD_ACCESS_KEY_ID and ALIBABA_CLOUD_ACCESS_KEY_SECRET are set.
|
||||||
|
.accessKeyId("LTAI5tEVYLeg7U3bP58n3Xkj")
|
||||||
|
.accessKeySecret("bbPSlxkaGgkhUPaCOP7CANaNNY1b2p")
|
||||||
|
//.securityToken(System.getenv("ALIBABA_CLOUD_SECURITY_TOKEN")) // use STS token
|
||||||
|
.build());
|
||||||
|
|
||||||
|
// Configure the Client
|
||||||
|
AsyncClient client = AsyncClient.builder()
|
||||||
|
.region("cn-shenzhen") // Region ID
|
||||||
|
//.httpClient(httpClient) // Use the configured HttpClient, otherwise use the default HttpClient (Apache HttpClient)
|
||||||
|
.credentialsProvider(provider)
|
||||||
|
//.serviceConfiguration(Configuration.create()) // Service-level configuration
|
||||||
|
// Client-level configuration rewrite, can set Endpoint, Http request parameters, etc.
|
||||||
|
.overrideConfiguration(
|
||||||
|
ClientOverrideConfiguration.create()
|
||||||
|
// Endpoint 请参考 https://api.aliyun.com/product/Dysmsapi
|
||||||
|
.setEndpointOverride("dysmsapi.aliyuncs.com")
|
||||||
|
//.setConnectTimeout(Duration.ofSeconds(30))
|
||||||
|
)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// Parameter settings for API request
|
||||||
|
SendSmsRequest sendSmsRequest = SendSmsRequest.builder()
|
||||||
|
.signName("同同的小站")
|
||||||
|
.templateCode("SMS_467570437")
|
||||||
|
.phoneNumbers(number)
|
||||||
|
.templateParam("{\"code\":\"" + generatedcode(4) + "\"}")
|
||||||
|
// Request-level configuration rewrite, can set Http request parameters, etc.
|
||||||
|
// .requestConfiguration(RequestConfiguration.create().setHttpHeaders(new HttpHeaders()))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// Asynchronously get the return value of the API request
|
||||||
|
CompletableFuture<SendSmsResponse> response = client.sendSms(sendSmsRequest);
|
||||||
|
// Synchronously get the return value of the API request
|
||||||
|
SendSmsResponse resp = response.get();
|
||||||
|
System.out.println(new Gson().toJson(resp));
|
||||||
|
// Asynchronous processing of return values
|
||||||
|
/*response.thenAccept(resp -> {
|
||||||
|
System.out.println(new Gson().toJson(resp));
|
||||||
|
}).exceptionally(throwable -> { // Handling exceptions
|
||||||
|
System.out.println(throwable.getMessage());
|
||||||
|
return null;
|
||||||
|
});*/
|
||||||
|
|
||||||
|
// Finally, close the client
|
||||||
|
client.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成?位的数字类型的短信验证码
|
||||||
|
*
|
||||||
|
* @param count
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static String generatedcode(int count) {
|
||||||
|
String code = String.valueOf((int) ((Math.random() * 9 + 1) * Math.pow(10, count - 1)));
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
79
src/main/java/com/ttstd/videotablet/utils/HashUtils.java
Normal file
79
src/main/java/com/ttstd/videotablet/utils/HashUtils.java
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
package com.ttstd.videotablet.utils;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.security.MessageDigest;
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
|
||||||
|
public class HashUtils {
|
||||||
|
public static String getFileMD5(File file) throws NoSuchAlgorithmException, IOException {
|
||||||
|
MessageDigest md = MessageDigest.getInstance("MD5");
|
||||||
|
FileInputStream fis = new FileInputStream(file);
|
||||||
|
byte[] dataBytes = new byte[1024];
|
||||||
|
|
||||||
|
int bytesRead;
|
||||||
|
while ((bytesRead = fis.read(dataBytes)) != -1) {
|
||||||
|
md.update(dataBytes, 0, bytesRead);
|
||||||
|
}
|
||||||
|
|
||||||
|
byte[] mdBytes = md.digest();
|
||||||
|
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
for (byte mdByte : mdBytes) {
|
||||||
|
sb.append(Integer.toString((mdByte & 0xff) + 0x100, 16).substring(1));
|
||||||
|
}
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String calculateSHA1(File file) throws NoSuchAlgorithmException, IOException {
|
||||||
|
InputStream inputStream = new FileInputStream(file);
|
||||||
|
return calculateSHA1(inputStream);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String calculateSHA1(InputStream inputStream) throws NoSuchAlgorithmException, IOException {
|
||||||
|
MessageDigest digest = MessageDigest.getInstance("SHA-1");
|
||||||
|
byte[] buffer = new byte[4096];
|
||||||
|
int bytesRead;
|
||||||
|
while ((bytesRead = inputStream.read(buffer)) != -1) {
|
||||||
|
digest.update(buffer, 0, bytesRead);
|
||||||
|
}
|
||||||
|
byte[] hashBytes = digest.digest();
|
||||||
|
return bytesToHex(hashBytes, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String calculateSHA256(File file) throws NoSuchAlgorithmException, IOException {
|
||||||
|
MessageDigest digest = MessageDigest.getInstance("SHA-256");
|
||||||
|
try (InputStream inputStream = new FileInputStream(file)) {
|
||||||
|
byte[] buffer = new byte[4096];
|
||||||
|
int bytesRead;
|
||||||
|
while ((bytesRead = inputStream.read(buffer)) != -1) {
|
||||||
|
digest.update(buffer, 0, bytesRead);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
byte[] hashBytes = digest.digest();
|
||||||
|
return bytesToHex(hashBytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String bytesToHex(byte[] bytes) {
|
||||||
|
StringBuilder hexString = new StringBuilder();
|
||||||
|
for (byte b : bytes) {
|
||||||
|
String hex = String.format("%02x", b & 0xFF);
|
||||||
|
/*大写*/
|
||||||
|
// String hex = String.format("%02X", b & 0xFF);
|
||||||
|
hexString.append(hex);
|
||||||
|
}
|
||||||
|
return hexString.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String bytesToHex(byte[] bytes, boolean upcase) {
|
||||||
|
String format = upcase ? "%02X" : "%02x";
|
||||||
|
StringBuilder hexString = new StringBuilder();
|
||||||
|
for (byte b : bytes) {
|
||||||
|
String hex = String.format(format, b & 0xFF);
|
||||||
|
hexString.append(hex);
|
||||||
|
}
|
||||||
|
return hexString.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
7
src/main/java/com/ttstd/videotablet/utils/TextUtils.java
Normal file
7
src/main/java/com/ttstd/videotablet/utils/TextUtils.java
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
package com.ttstd.videotablet.utils;
|
||||||
|
|
||||||
|
public class TextUtils {
|
||||||
|
public static boolean isEmpty(CharSequence str) {
|
||||||
|
return str == null || str.length() == 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
24
src/main/resources/application-debug.properties
Normal file
24
src/main/resources/application-debug.properties
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
spring.application.name=VideoTablet
|
||||||
|
server.port=8088
|
||||||
|
|
||||||
|
## mysql ??????
|
||||||
|
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
|
||||||
|
#spring.datasource.url=jdbc:mysql://139.199.77.221:3306/spring_boot?useUnicode=true&characterEncoding=utf8&useSSL=false
|
||||||
|
spring.datasource.url=jdbc:mysql://127.0.0.1:3305/video_tablet_db?useUnicode=true&characterEncoding=utf8&useSSL=false&allowPublicKeyRetrieval=true
|
||||||
|
spring.datasource.username=tt
|
||||||
|
spring.datasource.password=fanhuitong
|
||||||
|
|
||||||
|
# redis????
|
||||||
|
# 0????????????? Redis ???????
|
||||||
|
spring.data.redis.database=0
|
||||||
|
# 6379???????? Redis ??
|
||||||
|
spring.data.redis.port=6379
|
||||||
|
# ???????????
|
||||||
|
spring.data.redis.host=127.0.0.1
|
||||||
|
spring.data.redis.password=fanhuitong
|
||||||
|
# ???
|
||||||
|
spring.data.redis.lettuce.pool.min-idle=5
|
||||||
|
spring.data.redis.lettuce.pool.max-idle=10
|
||||||
|
spring.data.redis.lettuce.pool.max-active=8
|
||||||
|
spring.data.redis.lettuce.pool.max-wait=1ms
|
||||||
|
spring.data.redis.lettuce.shutdown-timeout=100ms
|
||||||
2
src/main/resources/application-prod.properties
Normal file
2
src/main/resources/application-prod.properties
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
spring.application.name=VideoTablet
|
||||||
|
|
||||||
2
src/main/resources/application-test.properties
Normal file
2
src/main/resources/application-test.properties
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
spring.application.name=VideoTablet
|
||||||
|
|
||||||
@@ -1 +1,3 @@
|
|||||||
spring.application.name=VideoTablet
|
# application.properties
|
||||||
|
# ????????
|
||||||
|
spring.profiles.active=debug
|
||||||
|
|||||||
Reference in New Issue
Block a user