Merge branch 'dev/dev_xp' into dev/3.1_release_merge
This commit is contained in:
@@ -33,7 +33,11 @@ public enum AuthenticationOperationTypeEnum {
|
|||||||
*/
|
*/
|
||||||
UPDATE_USERINFO,
|
UPDATE_USERINFO,
|
||||||
|
|
||||||
REGISTER;
|
REGISTER,
|
||||||
|
/**
|
||||||
|
* Global_Award 活动验证
|
||||||
|
*/
|
||||||
|
GLOBAL_AWARD;
|
||||||
|
|
||||||
public static AuthenticationOperationTypeEnum of(String name) {
|
public static AuthenticationOperationTypeEnum of(String name) {
|
||||||
return Stream.of(AuthenticationOperationTypeEnum.values()).filter(v -> v.name().equals(name)).findFirst().orElse(null);
|
return Stream.of(AuthenticationOperationTypeEnum.values()).filter(v -> v.name().equals(name)).findFirst().orElse(null);
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package com.ai.da.controller;
|
|||||||
|
|
||||||
import com.ai.da.common.response.Response;
|
import com.ai.da.common.response.Response;
|
||||||
import com.ai.da.model.dto.ContestantDTO;
|
import com.ai.da.model.dto.ContestantDTO;
|
||||||
|
import com.ai.da.model.vo.CheckOTPVO;
|
||||||
import com.ai.da.service.GlobalAwardService;
|
import com.ai.da.service.GlobalAwardService;
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
@@ -38,6 +39,18 @@ public class GlobalAwardController {
|
|||||||
ContestantDTO dto = globalAwardService.getContestantByEmail(email);
|
ContestantDTO dto = globalAwardService.getContestantByEmail(email);
|
||||||
return Response.success(dto);
|
return Response.success(dto);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@GetMapping("/checkEmail")
|
||||||
|
public Response<String> checkEmail(@RequestParam("email") String email) {
|
||||||
|
globalAwardService.checkEmail(email);
|
||||||
|
return Response.success();
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/checkCode")
|
||||||
|
public Response<CheckOTPVO> checkOTP(@RequestParam("email") String email, @RequestParam("code") String code) {
|
||||||
|
return Response.success(globalAwardService.checkOTP(email, code));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package com.ai.da.model.dto;
|
package com.ai.da.model.dto;
|
||||||
|
|
||||||
|
import jakarta.validation.constraints.NotBlank;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -24,6 +25,9 @@ public class ContestantDTO {
|
|||||||
* 是否确认覆盖已存在记录(false 表示发现已有记录时仅返回 existingRecord,不覆盖)
|
* 是否确认覆盖已存在记录(false 表示发现已有记录时仅返回 existingRecord,不覆盖)
|
||||||
*/
|
*/
|
||||||
private Boolean confirm = false;
|
private Boolean confirm = false;
|
||||||
|
|
||||||
|
@NotBlank
|
||||||
|
private String secureToken;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
16
src/main/java/com/ai/da/model/vo/CheckOTPVO.java
Normal file
16
src/main/java/com/ai/da/model/vo/CheckOTPVO.java
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
package com.ai.da.model.vo;
|
||||||
|
|
||||||
|
import com.ai.da.model.dto.ContestantDTO;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class CheckOTPVO {
|
||||||
|
|
||||||
|
private String secureToken;
|
||||||
|
|
||||||
|
private ContestantDTO contestantDTO;
|
||||||
|
}
|
||||||
@@ -1,15 +1,23 @@
|
|||||||
package com.ai.da.service;
|
package com.ai.da.service;
|
||||||
|
|
||||||
import com.ai.da.model.dto.ContestantDTO;
|
import com.ai.da.model.dto.ContestantDTO;
|
||||||
|
import com.ai.da.model.vo.CheckOTPVO;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
public interface GlobalAwardService {
|
public interface GlobalAwardService {
|
||||||
String uploadPdf(MultipartFile file, String email) throws Exception;
|
String uploadPdf(MultipartFile file, String email) throws Exception;
|
||||||
|
|
||||||
String uploadVideo(MultipartFile file, String email) throws Exception;
|
String uploadVideo(MultipartFile file, String email) throws Exception;
|
||||||
|
|
||||||
Map<String, Object> saveContestant(ContestantDTO request);
|
Map<String, Object> saveContestant(ContestantDTO request);
|
||||||
|
|
||||||
com.ai.da.model.dto.ContestantDTO getContestantByEmail(String email);
|
com.ai.da.model.dto.ContestantDTO getContestantByEmail(String email);
|
||||||
|
|
||||||
|
void checkEmail(String email);
|
||||||
|
|
||||||
|
CheckOTPVO checkOTP(String email, String otp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,41 +1,64 @@
|
|||||||
package com.ai.da.service.impl;
|
package com.ai.da.service.impl;
|
||||||
|
|
||||||
import com.ai.da.common.config.exception.BusinessException;
|
import com.ai.da.common.config.exception.BusinessException;
|
||||||
|
import com.ai.da.common.enums.AuthenticationOperationTypeEnum;
|
||||||
|
import com.ai.da.common.utils.*;
|
||||||
|
import com.ai.da.mapper.primary.AccountMapper;
|
||||||
import com.ai.da.mapper.primary.ContestantMapper;
|
import com.ai.da.mapper.primary.ContestantMapper;
|
||||||
|
import com.ai.da.mapper.primary.NotificationMapper;
|
||||||
|
import com.ai.da.mapper.primary.entity.Account;
|
||||||
import com.ai.da.mapper.primary.entity.Contestant;
|
import com.ai.da.mapper.primary.entity.Contestant;
|
||||||
|
import com.ai.da.mapper.primary.entity.Notification;
|
||||||
import com.ai.da.model.dto.ContestantDTO;
|
import com.ai.da.model.dto.ContestantDTO;
|
||||||
|
import com.ai.da.model.dto.PublishSysNotificationDTO;
|
||||||
|
import com.ai.da.model.vo.CheckOTPVO;
|
||||||
import com.ai.da.service.GlobalAwardService;
|
import com.ai.da.service.GlobalAwardService;
|
||||||
|
import com.ai.da.service.MessageCenterService;
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
import com.ai.da.common.utils.MinioUtil;
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.file.Files;
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
import java.util.HashMap;
|
import java.util.*;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
@Slf4j
|
@Slf4j
|
||||||
|
@RequiredArgsConstructor
|
||||||
public class GlobalAwardServiceImpl implements GlobalAwardService {
|
public class GlobalAwardServiceImpl implements GlobalAwardService {
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private ContestantMapper contestantMapper;
|
private ContestantMapper contestantMapper;
|
||||||
|
|
||||||
|
private final AccountMapper accountMapper;
|
||||||
|
|
||||||
|
private final MessageCenterService messageCenterService;
|
||||||
|
|
||||||
|
private final NotificationMapper notificationMapper;
|
||||||
|
|
||||||
|
private final RedisUtil redisUtil;
|
||||||
|
|
||||||
@Value("${file.upload.dir:uploads}")
|
@Value("${file.upload.dir:uploads}")
|
||||||
private String uploadDir;
|
private String uploadDir;
|
||||||
|
|
||||||
private static final DateTimeFormatter YYYY_MM_DD = DateTimeFormatter.ofPattern("yyyy/MM");
|
private static final DateTimeFormatter YYYY_MM_DD = DateTimeFormatter.ofPattern("yyyy/MM");
|
||||||
|
|
||||||
|
private static final String tokenCacheKey = AuthenticationOperationTypeEnum.GLOBAL_AWARD.name() + ":";
|
||||||
|
|
||||||
@Value("${minio.bucket:contestants}")
|
@Value("${minio.bucket:contestants}")
|
||||||
private String minioBucket;
|
private String minioBucket;
|
||||||
|
|
||||||
|
@Value("${global.award.link}")
|
||||||
|
private String link;
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private MinioUtil minioUtil;
|
private MinioUtil minioUtil;
|
||||||
|
|
||||||
@@ -111,6 +134,14 @@ public class GlobalAwardServiceImpl implements GlobalAwardService {
|
|||||||
throw new IllegalArgumentException("email required");
|
throw new IllegalArgumentException("email required");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String key = tokenCacheKey + request.getEmail();
|
||||||
|
String tokenCache = redisUtil.getFromString(key);
|
||||||
|
if (StringUtils.isBlank(tokenCache)) {
|
||||||
|
throw new BusinessException("请先完成邮箱认证");
|
||||||
|
} else if (!tokenCache.equals(request.getSecureToken())){
|
||||||
|
throw new BusinessException("身份认证失败,请先完成邮箱认证");
|
||||||
|
}
|
||||||
|
|
||||||
QueryWrapper<Contestant> qw = new QueryWrapper<>();
|
QueryWrapper<Contestant> qw = new QueryWrapper<>();
|
||||||
qw.eq("email", request.getEmail());
|
qw.eq("email", request.getEmail());
|
||||||
Contestant existing = contestantMapper.selectOne(qw);
|
Contestant existing = contestantMapper.selectOne(qw);
|
||||||
@@ -185,6 +216,59 @@ public class GlobalAwardServiceImpl implements GlobalAwardService {
|
|||||||
dto.setVideoPath(existing.getVideoPath());
|
dto.setVideoPath(existing.getVideoPath());
|
||||||
return dto;
|
return dto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void checkEmail(String email) {
|
||||||
|
List<Integer> validRole = Arrays.asList(1, 2, 7, 8);
|
||||||
|
// 1. 验证邮箱在aida中有无账号
|
||||||
|
QueryWrapper<Account> queryWrapper = new QueryWrapper<>();
|
||||||
|
queryWrapper.lambda().eq(Account::getUserEmail, email);
|
||||||
|
List<Account> accounts = accountMapper.selectList(queryWrapper);
|
||||||
|
if (accounts.isEmpty()) {
|
||||||
|
throw new BusinessException("请注册并订阅AiDA,再重新提交申请");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 验证账号是否是付费用户(如果首次提交是,但是修改的时候已经不是了,how?不允许修改吗)
|
||||||
|
if (validRole.contains(accounts.getFirst().getSystemUser())) {
|
||||||
|
String randomVerifyCode = RandomsUtil.generateVerifyCode(100000L, 999999L);
|
||||||
|
LocalCacheUtils.setVerifyCodeCache(
|
||||||
|
AuthenticationOperationTypeEnum.GLOBAL_AWARD.name() + "_" + email, randomVerifyCode);
|
||||||
|
SendEmailUtil.send(email, null,
|
||||||
|
SendEmailUtil.LOGIN_TEMPLATE_ID, randomVerifyCode);
|
||||||
|
} else {
|
||||||
|
throw new BusinessException("请订阅AiDA,再重新提交申请");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public CheckOTPVO checkOTP(String email, String otp) {
|
||||||
|
String otpCache = LocalCacheUtils.getVerifyCodeCache(AuthenticationOperationTypeEnum.GLOBAL_AWARD.name() + "_" + email);
|
||||||
|
assert otpCache != null;
|
||||||
|
if (otpCache.equals(otp)) {
|
||||||
|
// 1. 生成唯一token
|
||||||
|
String secureToken = UUID.randomUUID().toString().replace("-", "");
|
||||||
|
redisUtil.addToString(tokenCacheKey + email, secureToken, 3 * 24 * 60 * 60L);
|
||||||
|
|
||||||
|
return new CheckOTPVO(secureToken, getContestantByEmail(email));
|
||||||
|
} else {
|
||||||
|
throw new BusinessException("验证码错误,请重试");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 发送站内信
|
||||||
|
public void sendSiteMsg(String applicationId, Long userId) {
|
||||||
|
PublishSysNotificationDTO sysNotificationDTO = new PublishSysNotificationDTO();
|
||||||
|
Notification notification = new Notification();
|
||||||
|
notification.setType("system");
|
||||||
|
notification.setReceiverId(userId);
|
||||||
|
sysNotificationDTO.setTitle("System Notification 系统通知");
|
||||||
|
// todo
|
||||||
|
sysNotificationDTO.setContent(link + applicationId);
|
||||||
|
notification.setContent(JSON.toJSONString(sysNotificationDTO));
|
||||||
|
notification.setIsRead(0);
|
||||||
|
notification.setCreateTime(LocalDateTime.now());
|
||||||
|
notificationMapper.insert(notification);
|
||||||
|
// 这里推送消息是在接受到视频生成结束后发生的,所以UserContext中没有用户信息
|
||||||
|
messageCenterService.pushMessage("system", userId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -158,4 +158,5 @@ google.client.id=157095842121-kdd1fdf8m8nudvj9sprstb2k2prnf9e4.apps.googleuserco
|
|||||||
#google.client.secret=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
|
#google.client.secret=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
|
||||||
google.client.secret=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
|
google.client.secret=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
|
||||||
google.redirect.uri=https://develop.api.aida.com.hk/api/third/party/auth/google_callback
|
google.redirect.uri=https://develop.api.aida.com.hk/api/third/party/auth/google_callback
|
||||||
design.callback.url=https://develop.api.aida.com.hk/api/third/party/receiveDesignResults
|
design.callback.url=https://develop.api.aida.com.hk/api/third/party/receiveDesignResults
|
||||||
|
global.award.link=https://develop.aida.com.hk/
|
||||||
@@ -156,4 +156,5 @@ FREEPIK_API_KEY=FPSX94e5917d376a4facb87dabbaa0319c72
|
|||||||
google.client.id=29310152396-nnsd3h533fld665oguu8ovrt1nukmt46.apps.googleusercontent.com
|
google.client.id=29310152396-nnsd3h533fld665oguu8ovrt1nukmt46.apps.googleusercontent.com
|
||||||
google.client.secret=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
|
google.client.secret=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
|
||||||
google.redirect.uri=https://www.api.aida.com.hk/api/third/party/auth/google_callback
|
google.redirect.uri=https://www.api.aida.com.hk/api/third/party/auth/google_callback
|
||||||
design.callback.url=https://api.aida.com.hk/api/third/party/receiveDesignResults
|
design.callback.url=https://api.aida.com.hk/api/third/party/receiveDesignResults
|
||||||
|
global.award.link=https://www.aida.com.hk/
|
||||||
Reference in New Issue
Block a user