This commit is contained in:
张良(004796)
2024-05-11 12:25:08 +08:00
parent 978df0ea95
commit f6ab2c535a
13 changed files with 374 additions and 5 deletions

View File

@@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.test.RefreshArea;
import com.ruoyi.xq.domain.User;
import com.ruoyi.xq.job.JobManager;
import com.ruoyi.xq.service.CardAuthRecordService;
import com.ruoyi.xq.service.UserService;
import com.ruoyi.xq.util.AgeUtil;
import lombok.extern.slf4j.Slf4j;
@@ -23,6 +24,15 @@ public class RefreshTest {
private JobManager jobManager;
@Autowired
private UserService userService;
@Autowired
private CardAuthRecordService cardAuthRecordService;
@Test
public void test() throws InterruptedException {
Long recordId = 1788274531427102721L;
cardAuthRecordService.refreshUserCardByAdmin(recordId);
Thread.sleep(1000000);
}
@Test
public void refresh(){

View File

@@ -0,0 +1,21 @@
package com.ruoyi.oss.enums;
import cn.hutool.http.ContentType;
import lombok.Getter;
@Getter
public enum FileTypeEnums {
JPG("jpg", ContentType.OCTET_STREAM.getValue()),
MP4("mp4", ContentType.OCTET_STREAM.getValue());
private final String suffix;
private final String contentType;
FileTypeEnums(String suffix, String contentType) {
this.suffix = suffix;
this.contentType = contentType;
}
public String getSuffixV2(){
return "."+this.getSuffix();
}
}

View File

@@ -7,6 +7,7 @@ public class RedisHttpConstant {
public static final String RESET_PASSWORD_CHECK_REDIS = REDIS_P + "resetPasswordCheck:%s";
public static final String CODE_REDIS = REDIS_P + "codeIncs:%s:%s";
public static final String USER_UNREAD_REDIS = REDIS_P + "userUnread:%s:%s";
}

View File

@@ -0,0 +1,50 @@
package com.ruoyi.xq.controller.app;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.helper.LoginHelper;
import com.ruoyi.xq.dto.app.unread.UserUnreadAppVo;
import com.ruoyi.xq.manager.UserUnreadFlagManager;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/api/user/unread")
@Tag(name = "当前用户未读消息角标")
public class UserUnreadController {
@Autowired
private UserUnreadFlagManager userUnreadFlagManager;
@GetMapping("/messageNum")
@Operation(summary = "用户未读的数据")
public R<UserUnreadAppVo> messageNum(){
Long userId = LoginHelper.getUserId();
UserUnreadAppVo vo = new UserUnreadAppVo();
vo.setStar(userUnreadFlagManager.getStarFlag(userId));
vo.setStarDynamic(userUnreadFlagManager.getStarDynamicFlag(userId));
vo.setVisible(userUnreadFlagManager.getVisibleFlag(userId));
return R.ok(vo);
}
@GetMapping("/reset/message")
@Operation(summary = "将消息设置为全部已读")
public R<Void> resetMessage(@Parameter(name = "type", description = "类型 1-关注 2-关注动态 3-访问我的人") Integer type){
Long userId = LoginHelper.getUserId();
if(type == null){
return R.ok();
}
if(type == 1){
userUnreadFlagManager.resetStarKey(userId);
}else if(type == 2){
userUnreadFlagManager.resetStarDynamicKey(userId);
}else if(type == 3){
userUnreadFlagManager.resetVisibleKey(userId);
}
return R.ok();
}
}

View File

@@ -53,6 +53,10 @@ public class CardAuthRecord implements Serializable {
* 认证视频
*/
private String livenessVideo;
/**
*
*/
private String bestFrame;
/**
* 身份证正面
*/

View File

@@ -0,0 +1,15 @@
package com.ruoyi.xq.dto.app.unread;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data
public class UserUnreadAppVo {
@Schema(description = "关注未读")
private long star;
@Schema(description = "动态关注未读")
private long starDynamic;
@Schema(description = "查看我的人未读")
private long visible;
}

View File

@@ -0,0 +1,110 @@
package com.ruoyi.xq.manager;
import com.ruoyi.xq.constant.RedisHttpConstant;
import lombok.Data;
import org.redisson.api.RAtomicLong;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* 用户角标处理
*/
@Component
public class UserUnreadFlagManager {
private final static String UNREAD_STAR_FLAG = "star";
private final static String UNREAD_STAR_DYNAMIC_FLAG = "starDynamic";
private final static String UNREAD_VISIBLE_FLAG = "visible";
@Autowired
private RedissonClient redissonClient;
private String getStarKey(Long userId){
return String.format(RedisHttpConstant.USER_UNREAD_REDIS,UNREAD_STAR_FLAG,userId);
}
private String getStarDynamicKey(Long userId){
return String.format(RedisHttpConstant.USER_UNREAD_REDIS,UNREAD_STAR_DYNAMIC_FLAG,userId);
}
private String getVisibleKey(Long userId){
return String.format(RedisHttpConstant.USER_UNREAD_REDIS,UNREAD_VISIBLE_FLAG,userId);
}
public void resetStarKey(Long userId){
String key = getStarKey(userId);
RAtomicLong atomicLong = redissonClient.getAtomicLong(key);
atomicLong.set(0);
}
public void resetStarDynamicKey(Long userId){
String key = getStarDynamicKey(userId);
RAtomicLong atomicLong = redissonClient.getAtomicLong(key);
atomicLong.set(0);
}
public void resetVisibleKey(Long userId){
String key = getVisibleKey(userId);
RAtomicLong atomicLong = redissonClient.getAtomicLong(key);
atomicLong.set(0);
}
public Long getStarFlag(Long userId){
String key = getStarKey(userId);
RAtomicLong atomicLong = redissonClient.getAtomicLong(key);
long nn = atomicLong.get();
if(nn < 0){
return 0L;
}
return nn;
}
public Long getStarDynamicFlag(Long userId){
String key = getStarDynamicKey(userId);
RAtomicLong atomicLong = redissonClient.getAtomicLong(key);
long nn = atomicLong.get();
if(nn < 0){
return 0L;
}
return nn;
}
public Long getVisibleFlag(Long userId){
String key = getVisibleKey(userId);
RAtomicLong atomicLong = redissonClient.getAtomicLong(key);
long nn = atomicLong.get();
if(nn < 0){
return 0L;
}
return nn;
}
public void star(Long userId){
String key = getStarKey(userId);
RAtomicLong atomicLong = redissonClient.getAtomicLong(key);
atomicLong.incrementAndGet();
}
public void unstar(Long userId){
String key = getStarKey(userId);
RAtomicLong atomicLong = redissonClient.getAtomicLong(key);
atomicLong.decrementAndGet();
}
public void starDynamic(Long userId){
String key = getStarDynamicKey(userId);
RAtomicLong atomicLong = redissonClient.getAtomicLong(key);
atomicLong.incrementAndGet();
}
public void unStarDynamic(Long userId){
String key = getStarDynamicKey(userId);
RAtomicLong atomicLong = redissonClient.getAtomicLong(key);
atomicLong.incrementAndGet();
}
public void visible(Long userId){
String key = getVisibleKey(userId);
RAtomicLong atomicLong = redissonClient.getAtomicLong(key);
atomicLong.incrementAndGet();
}
}

View File

@@ -17,5 +17,9 @@ public interface CardAuthRecordService extends IService<CardAuthRecord> {
CommitAuthRecordResp commitAuthRecord(String bizToken);
boolean updateImage(CardAuthRecord cardAuthRecord, GetDetectInfoEnhancedResponse detectInfo);
boolean refreshUserCardByAdmin(Long authRecordId);
boolean updateCardRecordSuccess(CardAuthRecord cardAuthRecord, GetDetectInfoEnhancedResponse detectInfo);
}

View File

@@ -1,9 +1,16 @@
package com.ruoyi.xq.service.impl;
import cn.hutool.core.codec.Base64;
import cn.hutool.core.util.IdUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.spring.SpringUtils;
import com.ruoyi.oss.core.OssClient;
import com.ruoyi.oss.entity.UploadResult;
import com.ruoyi.oss.enums.FileTypeEnums;
import com.ruoyi.oss.factory.OssFactory;
import com.ruoyi.xq.domain.AuthOrder;
import com.ruoyi.xq.domain.CardAuthRecord;
import com.ruoyi.xq.domain.UserAuth;
@@ -12,12 +19,14 @@ import com.ruoyi.xq.dto.common.faceauth.CommitAuthRecordResp;
import com.ruoyi.xq.enums.common.AuditEnum;
import com.ruoyi.xq.enums.face.TokenStatusEnum;
import com.ruoyi.xq.enums.pay.PayStatusEnum;
import com.ruoyi.xq.executor.ExecutorConstant;
import com.ruoyi.xq.mapper.CardAuthRecordMapper;
import com.ruoyi.xq.service.*;
import com.ruoyi.xq.tencent.CreateAuthResp;
import com.ruoyi.xq.tencent.TencentAuthClient;
import com.tencentcloudapi.common.exception.TencentCloudSDKException;
import com.tencentcloudapi.faceid.v20180301.models.GetDetectInfoEnhancedResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -29,6 +38,7 @@ import org.springframework.transaction.annotation.Transactional;
* @date 2024-04-29
*/
@Service
@Slf4j
public class CardAuthRecordServiceImpl extends ServiceImpl<CardAuthRecordMapper,CardAuthRecord> implements CardAuthRecordService {
@Autowired
@@ -80,11 +90,123 @@ public class CardAuthRecordServiceImpl extends ServiceImpl<CardAuthRecordMapper,
}
CardAuthRecordService bean = SpringUtils.getBean(CardAuthRecordService.class);
boolean success = bean.updateCardRecordSuccess(cardAuthRecord, detectInfo);
ExecutorConstant.SYNC_EXECUTOR.execute(() -> {
bean.updateImage(cardAuthRecord,detectInfo);
});
CommitAuthRecordResp commitAuthRecordResp = new CommitAuthRecordResp();
commitAuthRecordResp.setFaceSuccess(success);
return commitAuthRecordResp;
}
private String getPath(String userCode,String token,String suffix){
String uuid = IdUtil.fastSimpleUUID();
return String.format("cardAuth/%s/%s/%s.%s", userCode, token, uuid, suffix);
}
@Override
public boolean updateImage(CardAuthRecord cardAuthRecord, GetDetectInfoEnhancedResponse detectInfo){
OssClient storage = OssFactory.instance();
String usercode = cardAuthRecord.getUsercode();
String bizToken = cardAuthRecord.getBizToken();
CardAuthRecord update = new CardAuthRecord();
update.setId(cardAuthRecord.getId());
boolean updateFlag = false;
// 保存身份证
if(detectInfo.getIdCardData() != null){
if(StringUtils.isNotBlank(detectInfo.getIdCardData().getOcrFront())){
try {
byte[] dataByte = Base64.decode(detectInfo.getIdCardData().getOcrFront());
String path = getPath(usercode, bizToken, FileTypeEnums.JPG.getSuffix());
UploadResult upload = storage.upload(dataByte, path, FileTypeEnums.JPG.getContentType());
update.setCardFront(upload.getUrl());
updateFlag = true;
}catch (Exception e){
log.error("上传 身份证失败recordId={}",cardAuthRecord.getId(),e);
}
}
if(StringUtils.isNotBlank(detectInfo.getIdCardData().getOcrBack())){
try {
byte[] dataByte = Base64.decode(detectInfo.getIdCardData().getOcrBack());
String path = getPath(usercode, bizToken, FileTypeEnums.JPG.getSuffix());
UploadResult upload = storage.upload(dataByte, path, FileTypeEnums.JPG.getContentType());
update.setCardBack(upload.getUrl());
updateFlag = true;
}catch (Exception e){
log.error("上传 身份证失败recordId={}",cardAuthRecord.getId(),e);
}
}
}
if(detectInfo.getBestFrame() != null){
if(StringUtils.isNotBlank(detectInfo.getBestFrame().getBestFrame())){
try {
byte[] dataByte = Base64.decode(detectInfo.getBestFrame().getBestFrame());
String path = getPath(usercode, bizToken, FileTypeEnums.JPG.getSuffix());
UploadResult upload = storage.upload(dataByte, path, FileTypeEnums.JPG.getContentType());
update.setBestFrame(upload.getUrl());
updateFlag = true;
}catch (Exception e){
log.error("上传 bestFrame 失败recordId={}",cardAuthRecord.getId(),e);
}
}
}
if(detectInfo.getVideoData() != null){
if(StringUtils.isNotBlank(detectInfo.getVideoData().getLivenessVideo())){
try {
byte[] dataByte = Base64.decode(detectInfo.getVideoData().getLivenessVideo());
String path = getPath(usercode, bizToken, FileTypeEnums.MP4.getSuffix());
UploadResult upload = storage.upload(dataByte, path, FileTypeEnums.MP4.getContentType());
update.setLivenessVideo(upload.getUrl());
updateFlag = true;
}catch (Exception e){
log.error("上传 视频认证失败recordId={}",cardAuthRecord.getId(),e);
}
}
}
if(!updateFlag){
return false;
}
this.updateById(update);
return true;
}
@Override
public boolean refreshUserCardByAdmin(Long authRecordId){
CardAuthRecord cardAuthRecord = this.getById(authRecordId);
if(cardAuthRecord == null){
throw new ServiceException("实名认证不存在!");
}
GetDetectInfoEnhancedResponse detectInfo = null;
try {
detectInfo = TencentAuthClient.getDetectInfo(cardAuthRecord.getBizToken());
} catch (TencentCloudSDKException e) {
log.error("查询实名认证异常",e);
throw new ServiceException("实名认证结果获取失败");
}
boolean pass = TencentAuthClient.faceDetectIsPass(detectInfo);
CardAuthRecord updateRecord = new CardAuthRecord();
updateRecord.setId(cardAuthRecord.getId());
if(!pass){
updateRecord.setTokenStatus(TokenStatusEnum.FAIL.getCode());
}else{
updateRecord.setTokenStatus(TokenStatusEnum.SUCCESS.getCode());
}
if(detectInfo.getText() != null){
updateRecord.setIdCard(detectInfo.getText().getIdCard());
updateRecord.setName(detectInfo.getText().getName());
if(detectInfo.getText().getOcrNation() != null){
updateRecord.setNation(detectInfo.getText().getOcrNation()+"");
}
}
this.updateById(updateRecord);
GetDetectInfoEnhancedResponse finalDetectInfo = detectInfo;
ExecutorConstant.SYNC_EXECUTOR.execute(() -> {
this.updateImage(cardAuthRecord, finalDetectInfo);
});
return pass;
}
@Override
@Transactional(rollbackFor = Exception.class)
public boolean updateCardRecordSuccess(CardAuthRecord cardAuthRecord, GetDetectInfoEnhancedResponse detectInfo){

View File

@@ -4,13 +4,16 @@ import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.core.domain.PageQuery;
import com.ruoyi.xq.domain.Dynamic;
import com.ruoyi.xq.domain.DynamicImage;
import com.ruoyi.xq.domain.DynamicStar;
import com.ruoyi.xq.dto.app.dynamic.MyStarDynamicListVO;
import com.ruoyi.xq.dto.app.dynamic.MyStarDynamicQuery;
import com.ruoyi.xq.dto.common.user.MinUser;
import com.ruoyi.xq.manager.UserUnreadFlagManager;
import com.ruoyi.xq.mapper.DynamicStarMapper;
import com.ruoyi.xq.service.DynamicImageService;
import com.ruoyi.xq.service.DynamicService;
import com.ruoyi.xq.service.DynamicStarService;
import com.ruoyi.xq.service.UserService;
import org.apache.commons.collections4.CollectionUtils;
@@ -36,6 +39,11 @@ public class DynamicStarServiceImpl extends ServiceImpl<DynamicStarMapper,Dynami
private UserService userService;
@Autowired
private DynamicImageService dynamicImageService;
@Autowired
private UserUnreadFlagManager userUnreadFlagManager;
@Autowired
private DynamicService dynamicService;
@Override
@Transactional(rollbackFor = Exception.class)
public void star(Long dynamicId, Long starUserId) {
@@ -43,6 +51,10 @@ public class DynamicStarServiceImpl extends ServiceImpl<DynamicStarMapper,Dynami
if(user == null){
return;
}
Dynamic dynamic = dynamicService.getById(dynamicId);
if(dynamic == null){
return;
}
this.remove(Wrappers.lambdaQuery(DynamicStar.class).eq(DynamicStar::getDynamicId, dynamicId)
.eq(DynamicStar::getStarUserId, starUserId));
DynamicStar dynamicStar = new DynamicStar();
@@ -50,12 +62,19 @@ public class DynamicStarServiceImpl extends ServiceImpl<DynamicStarMapper,Dynami
dynamicStar.setStarUsercode(user.getUsercode());
dynamicStar.setDynamicId(dynamicId);
this.save(dynamicStar);
userUnreadFlagManager.starDynamic(dynamic.getUserId());
}
@Override
public void unStar(Long dynamicId, Long starUserId) {
this.remove(Wrappers.lambdaQuery(DynamicStar.class).eq(DynamicStar::getDynamicId, dynamicId)
boolean remove = this.remove(Wrappers.lambdaQuery(DynamicStar.class).eq(DynamicStar::getDynamicId, dynamicId)
.eq(DynamicStar::getStarUserId, starUserId));
if(remove){
Dynamic dynamic = dynamicService.getById(dynamicId);
if(dynamic != null){
userUnreadFlagManager.unStarDynamic(dynamic.getUserId());
}
}
}
@Override

View File

@@ -11,6 +11,7 @@ import com.ruoyi.xq.domain.UserStar;
import com.ruoyi.xq.dto.app.userstar.UserStarQuery;
import com.ruoyi.xq.dto.app.userstar.UserStarReq;
import com.ruoyi.xq.dto.app.userstar.vo.UserStarListVo;
import com.ruoyi.xq.manager.UserUnreadFlagManager;
import com.ruoyi.xq.mapper.UserStarMapper;
import com.ruoyi.xq.service.UserService;
import com.ruoyi.xq.service.UserStarService;
@@ -30,6 +31,8 @@ import java.util.List;
public class UserStarServiceImpl extends ServiceImpl<UserStarMapper,UserStar> implements UserStarService {
@Autowired
private UserService userService;
@Autowired
private UserUnreadFlagManager userUnreadFlagManager;
/**
* @Schema(description = "1-关注 2-取消关注")
*/
@@ -54,10 +57,14 @@ public class UserStarServiceImpl extends ServiceImpl<UserStarMapper,UserStar> im
userStar.setStarUserId(starUser.getId());
userStar.setStarUserCode(starUser.getUsercode());
this.save(userStar);
userUnreadFlagManager.star(req.getStarUserId());
}else if(req.getStar().equals(2)){
this.remove(Wrappers.lambdaQuery(UserStar.class)
boolean flag = this.remove(Wrappers.lambdaQuery(UserStar.class)
.eq(UserStar::getUserId, req.getUserId())
.eq(UserStar::getStarUserId, req.getStarUserId()));
if(flag){
userUnreadFlagManager.unstar(req.getStarUserId());
}
}
}

View File

@@ -11,6 +11,7 @@ import com.ruoyi.xq.dto.app.userstar.vo.UserStarListVo;
import com.ruoyi.xq.dto.app.uservisitor.UserVisitorQuery;
import com.ruoyi.xq.dto.app.uservisitor.vo.UserVisitorListVo;
import com.ruoyi.xq.lock.LockKey;
import com.ruoyi.xq.manager.UserUnreadFlagManager;
import com.ruoyi.xq.mapper.UserVisitorMapper;
import com.ruoyi.xq.service.UserService;
import com.ruoyi.xq.service.UserVisitorService;
@@ -34,6 +35,8 @@ public class UserVisitorServiceImpl extends ServiceImpl<UserVisitorMapper,UserVi
private RedissonClient redissonClient;
@Autowired
private UserService userService;
@Autowired
private UserUnreadFlagManager userUnreadFlagManager;
@Override
public void visitor(Long userId, Long tarUserId) {
User user = userService.getById(userId);
@@ -62,6 +65,7 @@ public class UserVisitorServiceImpl extends ServiceImpl<UserVisitorMapper,UserVi
userVisitor.setTarUsercode(tarUser.getUsercode());
userVisitor.setVisitorNum(1);
this.save(userVisitor);
userUnreadFlagManager.visible(userVisitor.getTarId());
}finally {
lock.unlock();
}

View File

@@ -88,13 +88,15 @@ public class TencentAuthClient {
public static void main(String[] args) throws TencentCloudSDKException {
// createToken(null,null);
GetDetectInfoEnhancedResponse detectInfo = getDetectInfo("09792FA0-C269-401F-B8DB-E68B680E0728");
GetDetectInfoEnhancedResponse detectInfo = getDetectInfo("C454630F-0E21-4ABB-8575-3A4DA14B0BCF");
System.out.println(JSON.toJSONString(detectInfo));
base64ToVideo(detectInfo.getVideoData().getLivenessVideo(), "C:\\Users\\38320\\Desktop\\123\\123.mp4");
base64ToVideo(detectInfo.getIdCardData().getOcrFront(), "D:\\test\\front.jpg");
base64ToVideo(detectInfo.getIdCardData().getOcrBack(), "D:\\test\\back.jpg");
base64ToVideo(detectInfo.getBestFrame().getBestFrame(), "D:\\test\\best.jpg");
base64ToVideo(detectInfo.getVideoData().getLivenessVideo(), "D:\\test\\123.mp4");
}
public static void base64ToVideo(String base64, String targetPath) {
try {
//base解密