fix: default pass profile approvals before review

- make user/room/family/photo profile assets visible before follow-up review

- disable Tencent censor by default with a config switch

- replace the missing SUD auth dependency with an in-repo implementation so deploy-machine builds can pass
This commit is contained in:
hy001 2026-04-15 18:05:05 +08:00
parent b2938a17bf
commit ad0feebfb2
16 changed files with 452 additions and 225 deletions

View File

@ -62,16 +62,10 @@
<groupId>io.micrometer</groupId> <groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId> <artifactId>micrometer-registry-prometheus</artifactId>
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.github.sud</groupId> <groupId>com.auth0</groupId>
<artifactId>sud-mgp-auth-java</artifactId> <artifactId>java-jwt</artifactId>
<version>1.0.4</version> <version>3.10.3</version>
</dependency>
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.10.3</version>
</dependency> </dependency>
<dependency> <dependency>

View File

@ -0,0 +1,25 @@
package com.red.circle.external.app.censor;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
/**
* 腾讯云内容审核配置.
*/
@Component
@ConfigurationProperties(prefix = "red-circle.censor.tencent")
public class TencentCensorProperties {
/**
* 是否启用腾讯云内容审核.
*/
private boolean enabled = false;
public boolean isEnabled() {
return enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
}

View File

@ -1,30 +1,43 @@
package com.red.circle.external.inner.service.censor.impl; package com.red.circle.external.inner.service.censor.impl;
import com.red.circle.component.censor.api.AuditingRequest; import com.red.circle.component.censor.api.AuditingRequest;
import com.red.circle.component.censor.api.ICensorImageService; import com.red.circle.component.censor.api.ICensorImageService;
import com.red.circle.external.inner.convertor.CensorImageInnerConvertor; import com.red.circle.external.app.censor.TencentCensorProperties;
import com.red.circle.external.inner.model.dto.CensorImageResponseDTO; import com.red.circle.external.inner.convertor.CensorImageInnerConvertor;
import com.red.circle.external.inner.service.censor.CensorImageClientService; import com.red.circle.external.inner.model.dto.CensorImageResponseDTO;
import lombok.RequiredArgsConstructor; import com.red.circle.external.inner.model.dto.CensorSuggestion;
import org.springframework.stereotype.Service; import com.red.circle.external.inner.service.censor.CensorImageClientService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
/** /**
* 图片安全鉴定. * 图片安全鉴定.
* *
* @author pengliang on 2023/10/17 * @author pengliang on 2023/10/17
*/ */
@Service @Slf4j
@RequiredArgsConstructor @Service
public class CensorImageClientServiceImpl implements CensorImageClientService { @RequiredArgsConstructor
public class CensorImageClientServiceImpl implements CensorImageClientService {
private final ICensorImageService censorImageService;
private final CensorImageInnerConvertor censorImageInnerConvertor; private final ICensorImageService censorImageService;
private final CensorImageInnerConvertor censorImageInnerConvertor;
@Override private final TencentCensorProperties tencentCensorProperties;
public CensorImageResponseDTO auditing(String detectUrl) {
AuditingRequest request = new AuditingRequest(); @Override
request.setDetectUrl(detectUrl); public CensorImageResponseDTO auditing(String detectUrl) {
return censorImageInnerConvertor.toCensorImageResponseDTO(censorImageService.auditing(request)); if (!tencentCensorProperties.isEnabled()) {
} log.info("Tencent censor disabled, skip auditing. detectUrl={}", detectUrl);
CensorImageResponseDTO response = new CensorImageResponseDTO();
} response.setDetectUrl(detectUrl);
response.setSuggestion(CensorSuggestion.Pass);
return response;
}
AuditingRequest request = new AuditingRequest();
request.setDetectUrl(detectUrl);
return censorImageInnerConvertor.toCensorImageResponseDTO(censorImageService.auditing(request));
}
}

View File

@ -38,3 +38,8 @@ management:
rtc: rtc:
appId: ceb9e2620d454bca9725f7a7f11d4019 appId: ceb9e2620d454bca9725f7a7f11d4019
certificate: 1fe700671f1641a8b42a474d4ad990a7 certificate: 1fe700671f1641a8b42a474d4ad990a7
red-circle:
censor:
tencent:
enabled: false

View File

@ -88,11 +88,12 @@ public class FamilyCreateExe {
addFamilyMember(cmd, familyId); addFamilyMember(cmd, familyId);
checkCreateWhereAndPayCandy(cmd); checkCreateWhereAndPayCandy(cmd);
familyMessageService.cancelUserPendingMessages(cmd.getReqUserId()); familyMessageService.cancelUserPendingMessages(cmd.getReqUserId());
addApproveRecord(cmd);
return familyId;
return familyId;
} finally { } finally {
redisService.unlock(lockKey(cmd)); redisService.unlock(lockKey(cmd));
@ -104,20 +105,21 @@ public class FamilyCreateExe {
return "FAMILY_CREATE:" + cmd.getReqUserId(); return "FAMILY_CREATE:" + cmd.getReqUserId();
} }
private void addApproveRecord(FamilyCreateCmd cmd) { private void addApproveRecord(FamilyCreateCmd cmd) {
Long createUserId = cmd.getReqUserId(); Long createUserId = cmd.getReqUserId();
String sysOrigin = cmd.getReqSysOrigin().getOrigin(); String sysOrigin = cmd.getReqSysOrigin().getOrigin();
approvalUserSettingDataService.saveOrUpdateApproval(createUserId, sysOrigin, if (StringUtils.isNotBlank(cmd.getFamilyAvatar())) {
DataApprovalTypeEnum.FAMILY_AVATAR); approvalUserSettingDataService.saveOrUpdateApproval(createUserId, sysOrigin,
DataApprovalTypeEnum.FAMILY_AVATAR);
approvalUserSettingDataService.saveOrUpdateApproval(createUserId, sysOrigin, }
DataApprovalTypeEnum.FAMILY_NICKNAME);
if (StringUtils.isNotBlank(cmd.getFamilyName())) {
approvalUserSettingDataService.saveOrUpdateApproval(createUserId, sysOrigin, approvalUserSettingDataService.saveOrUpdateApproval(createUserId, sysOrigin,
DataApprovalTypeEnum.FAMILY_NOTICE); DataApprovalTypeEnum.FAMILY_NICKNAME);
} }
}
private void sendHonor(FamilyCreateCmd cmd, FamilyLevelConfig levelConfig) { private void sendHonor(FamilyCreateCmd cmd, FamilyLevelConfig levelConfig) {
familyManager.sendFamilyHonorToMember(cmd.getReqUserId(), familyManager.sendFamilyHonorToMember(cmd.getReqUserId(),

View File

@ -56,11 +56,23 @@ public class FamilyInfoEditExe {
FamilyBaseInfo baseInfo = familyBaseInfoService.getBaseInfoById(manageMember.getFamilyId()); FamilyBaseInfo baseInfo = familyBaseInfoService.getBaseInfoById(manageMember.getFamilyId());
ResponseAssert.notNull(FamilyErrorCode.NOT_EXIST_FAMILY_INFO_DATA, baseInfo); ResponseAssert.notNull(FamilyErrorCode.NOT_EXIST_FAMILY_INFO_DATA, baseInfo);
boolean noticeChanged = StringUtils.isNotBlank(cmd.getFamilyNotice()); boolean avatarChanged = StringUtils.isNotBlank(cmd.getFamilyAvatar());
familyBaseInfoService.updateSelectiveById(getFamilyBaseInfo(cmd, manageMember.getFamilyId())); boolean nameChanged = StringUtils.isNotBlank(cmd.getFamilyName());
boolean noticeChanged = cmd.getFamilyNotice() != null;
FamilyNewsTypeEnum newsType = noticeChanged familyBaseInfoService.updateSelectiveById(getFamilyBaseInfo(cmd, manageMember.getFamilyId()));
? FamilyNewsTypeEnum.FAMILY_NOTICE_EDIT
if (avatarChanged) {
saveApproval(cmd, DataApprovalTypeEnum.FAMILY_AVATAR);
}
if (nameChanged) {
saveApproval(cmd, DataApprovalTypeEnum.FAMILY_NICKNAME);
}
if (noticeChanged) {
saveApproval(cmd, DataApprovalTypeEnum.FAMILY_NOTICE);
}
FamilyNewsTypeEnum newsType = noticeChanged
? FamilyNewsTypeEnum.FAMILY_NOTICE_EDIT
: FamilyNewsTypeEnum.FAMILY_INFO_EDIT; : FamilyNewsTypeEnum.FAMILY_INFO_EDIT;
familyNewsRecorder.recordAndUpdateNotice( familyNewsRecorder.recordAndUpdateNotice(

View File

@ -136,7 +136,7 @@ public class UpdateUserProfileCmdExe {
syncProperty(userProfile, cmd); syncProperty(userProfile, cmd);
log.warn("cmd {},{}", cmd, userProfile); log.warn("cmd {},{}", cmd, userProfile);
updateUserProfile.setOriginSys(cmd.requireReqSysOrigin()); updateUserProfile.setOriginSys(cmd.requireReqSysOrigin());
submitApproval(updateUserProfile); submitApproval(updateUserProfile, userProfile);
if (cmd.getCountryId() != null && cmd.getCountryId() > 0) { if (cmd.getCountryId() != null && cmd.getCountryId() > 0) {
// 更改国家 设置redis表示已修改 两年过期 // 更改国家 设置redis表示已修改 两年过期
redisService.setString("IS_UPDATE_COUNTRY:" + cmd.requiredReqUserId(), "1", 730, TimeUnit.DAYS); redisService.setString("IS_UPDATE_COUNTRY:" + cmd.requiredReqUserId(), "1", 730, TimeUnit.DAYS);
@ -156,10 +156,10 @@ public class UpdateUserProfileCmdExe {
baseInfoService.updateSelectiveById(baseInfo); baseInfoService.updateSelectiveById(baseInfo);
} }
private void submitApproval(UserProfile updateUserProfile) { private void submitApproval(UserProfile updateUserProfile, UserProfile originalUserProfile) {
List<ProfileApprovalContent> approvalParam = CollectionUtils.newArrayList(); List<ProfileApprovalContent> approvalParam = CollectionUtils.newArrayList();
if (StringUtils.isNotBlank(updateUserProfile.getUserAvatar())) { if (StringUtils.isNotBlank(updateUserProfile.getUserAvatar())) {
approvalParam.add( approvalParam.add(
new ProfileApprovalContent() new ProfileApprovalContent()
.setBeUserId(updateUserProfile.getId()) .setBeUserId(updateUserProfile.getId())
.setSysOrigin(updateUserProfile.getOriginSys()) .setSysOrigin(updateUserProfile.getOriginSys())
@ -182,42 +182,43 @@ public class UpdateUserProfileCmdExe {
updateUserProfile.getUserNickname() updateUserProfile.getUserNickname()
) )
); );
} }
// 背景照片审核 addNewPhotoApproval(approvalParam, updateUserProfile, updateUserProfile.getBackgroundPhotos(),
if (CollectionUtils.isNotEmpty(updateUserProfile.getBackgroundPhotos())) { originalUserProfile.getBackgroundPhotos(), DataApprovalTypeEnum.BACKGROUND_PHOTO);
for (PhotoItem photo : updateUserProfile.getBackgroundPhotos()) { addNewPhotoApproval(approvalParam, updateUserProfile, updateUserProfile.getPersonalPhotos(),
if (StringUtils.isNotBlank(photo.getUrl()) && PhotoAuditStatus.PENDING.getCode().equals(photo.getStatus())) { originalUserProfile.getPersonalPhotos(), DataApprovalTypeEnum.PERSONAL_PHOTO);
approvalParam.add(
new ProfileApprovalContent() if (CollectionUtils.isNotEmpty(approvalParam)) {
.setBeUserId(updateUserProfile.getId()) profileApprovalGateway.submitApprovalBatch(approvalParam);
.setSysOrigin(updateUserProfile.getOriginSys()) }
.setApprovalType(DataApprovalTypeEnum.BACKGROUND_PHOTO)
.addContent(updateUserProfile.getId(), photo.getUrl()) }
);
} private void addNewPhotoApproval(List<ProfileApprovalContent> approvalParam,
} UserProfile updateUserProfile, List<PhotoItem> newPhotos, List<PhotoItem> originalPhotos,
} DataApprovalTypeEnum approvalType) {
if (CollectionUtils.isEmpty(newPhotos)) {
// 个人形象照片审核 return;
if (CollectionUtils.isNotEmpty(updateUserProfile.getPersonalPhotos())) { }
for (PhotoItem photo : updateUserProfile.getPersonalPhotos()) {
if (StringUtils.isNotBlank(photo.getUrl()) && PhotoAuditStatus.PENDING.getCode().equals(photo.getStatus())) { for (PhotoItem photo : newPhotos) {
approvalParam.add( if (StringUtils.isBlank(photo.getUrl()) || !isNewPhoto(photo, originalPhotos)) {
new ProfileApprovalContent() continue;
.setBeUserId(updateUserProfile.getId()) }
.setSysOrigin(updateUserProfile.getOriginSys()) approvalParam.add(
.setApprovalType(DataApprovalTypeEnum.PERSONAL_PHOTO) new ProfileApprovalContent()
.addContent(updateUserProfile.getId(), photo.getUrl()) .setBeUserId(updateUserProfile.getId())
); .setSysOrigin(updateUserProfile.getOriginSys())
} .setApprovalType(approvalType)
} .addContent(updateUserProfile.getId(), photo.getUrl())
} );
}
if (CollectionUtils.isNotEmpty(approvalParam)) { }
profileApprovalGateway.submitApprovalBatch(approvalParam);
} private boolean isNewPhoto(PhotoItem photo, List<PhotoItem> originalPhotos) {
return CollectionUtils.isEmpty(originalPhotos)
} || originalPhotos.stream().noneMatch(item -> Objects.equals(item.getUrl(), photo.getUrl()));
}
private void syncProperty(UserProfile oldProfile, UserProfileModifyCmd cmd) { private void syncProperty(UserProfile oldProfile, UserProfileModifyCmd cmd) {
@ -272,10 +273,10 @@ public class UpdateUserProfileCmdExe {
baseInfo.setCountryId(null); baseInfo.setCountryId(null);
} }
/** /**
* 处理照片状态新照片设置为待审核已存在照片保持原状态空列表表示清空照片. * 处理照片状态新照片默认先通过机审回写最终状态已存在照片保持原状态.
*/ */
private void processPhotoStatus(List<PhotoItem> newPhotos, List<PhotoItem> originalPhotos) { private void processPhotoStatus(List<PhotoItem> newPhotos, List<PhotoItem> originalPhotos) {
if (newPhotos == null) { if (newPhotos == null) {
return; return;
} }
@ -285,14 +286,14 @@ public class UpdateUserProfileCmdExe {
} }
for (PhotoItem photo : newPhotos) { for (PhotoItem photo : newPhotos) {
boolean isNew = CollectionUtils.isEmpty(originalPhotos) boolean isNew = CollectionUtils.isEmpty(originalPhotos)
|| originalPhotos.stream().noneMatch(p -> Objects.equals(p.getUrl(), photo.getUrl())); || originalPhotos.stream().noneMatch(p -> Objects.equals(p.getUrl(), photo.getUrl()));
if (isNew) { if (isNew) {
photo.setStatus(PhotoAuditStatus.PENDING.getCode()); photo.setStatus(PhotoAuditStatus.APPROVED.getCode());
} else { } else {
originalPhotos.stream() originalPhotos.stream()
.filter(p -> Objects.equals(p.getUrl(), photo.getUrl())) .filter(p -> Objects.equals(p.getUrl(), photo.getUrl()))
.findFirst() .findFirst()
.ifPresent(p -> photo.setStatus(p.getStatus())); .ifPresent(p -> photo.setStatus(p.getStatus()));
} }

View File

@ -72,14 +72,14 @@ public interface UserProfileAppConvertor {
if (urls == null || urls.isEmpty()) { if (urls == null || urls.isEmpty()) {
return null; return null;
} }
return urls.stream() return urls.stream()
.filter(url -> url != null && !url.trim().isEmpty()) .filter(url -> url != null && !url.trim().isEmpty())
.map(url -> new PhotoItem() .map(url -> new PhotoItem()
.setUrl(url) .setUrl(url)
.setStatus(PhotoAuditStatus.PENDING.getCode()) .setStatus(PhotoAuditStatus.APPROVED.getCode())
.setCreateTime(Timestamp.valueOf(LocalDateTime.now()))) .setCreateTime(Timestamp.valueOf(LocalDateTime.now())))
.collect(Collectors.toList()); .collect(Collectors.toList());
} }
/** /**
* 自定义转换UserProfileDTO为UserSimpleProfileDTO * 自定义转换UserProfileDTO为UserSimpleProfileDTO

View File

@ -286,12 +286,12 @@ public class CensorProfileListener implements MessageListener {
String labelNames = response.formatLabelString(); String labelNames = response.formatLabelString();
if (!response.checkPass()) { if (response.checkBlock()) {
// 审核不通过记录违规 // 审核不通过记录违规
photoViolationHandle(param.getUserId(), censorContent.getContent(), labelNames, approvalType); photoViolationHandle(param.getUserId(), censorContent.getContent(), labelNames, approvalType);
// 更新MongoDB中图片状态 // 更新MongoDB中图片状态
updatePhotoStatus(param.getUserId(), censorContent.getContent(), updatePhotoStatus(param.getUserId(), censorContent.getContent(),
PhotoAuditStatus.REJECTED.getCode(), labelNames, approvalType); PhotoAuditStatus.REJECTED.getCode(), labelNames, approvalType);
} else if (response.checkPass()) { } else if (response.checkPass()) {
// 审核通过 // 审核通过
approvalUserSettingDataService.updateApprovalStatusMachineLabel( approvalUserSettingDataService.updateApprovalStatusMachineLabel(
@ -299,11 +299,11 @@ public class CensorProfileListener implements MessageListener {
// 更新MongoDB中图片状态 // 更新MongoDB中图片状态
updatePhotoStatus(param.getUserId(), censorContent.getContent(), updatePhotoStatus(param.getUserId(), censorContent.getContent(),
PhotoAuditStatus.APPROVED.getCode(), null, approvalType); PhotoAuditStatus.APPROVED.getCode(), null, approvalType);
} else { } else {
// 待人工审核 // 待人工审核
approvalUserSettingDataService.updateApprovalStatusMachineLabel( approvalUserSettingDataService.updateApprovalStatusMachineLabel(
param.getUserId(), ApprovalStatusEnum.PENDING, approvalType, labelNames); param.getUserId(), ApprovalStatusEnum.PENDING, approvalType, labelNames);
} }
} catch (Exception ex) { } catch (Exception ex) {
log.error("图片审核异常: userId={}, url={}", param.getUserId(), log.error("图片审核异常: userId={}, url={}", param.getUserId(),
censorContent.getContent(), ex); censorContent.getContent(), ex);

View File

@ -1,9 +1,9 @@
package com.red.circle.other.app.listener.team; package com.red.circle.other.app.listener.team;
import com.google.common.base.Throwables; import com.google.common.base.Throwables;
import com.red.circle.common.business.core.enums.DataApprovalTypeEnum; import com.red.circle.common.business.core.enums.DataApprovalTypeEnum;
import com.red.circle.component.mq.MessageEventProcess; import com.red.circle.component.mq.MessageEventProcess;
import com.red.circle.component.mq.MessageEventProcessDescribe; import com.red.circle.component.mq.MessageEventProcessDescribe;
import com.red.circle.component.mq.config.RocketMqMessageListener; import com.red.circle.component.mq.config.RocketMqMessageListener;
import com.red.circle.component.mq.service.Action; import com.red.circle.component.mq.service.Action;
import com.red.circle.component.mq.service.ConsumerMessage; import com.red.circle.component.mq.service.ConsumerMessage;
@ -62,13 +62,17 @@ public class CreateRoomSuccessListener implements MessageListener {
.setContent(cmd.getRoomCover()) .setContent(cmd.getRoomCover())
) )
); );
} }
try { try {
approvalUserSettingDataService.saveBatchApproval(cmd.getUserId(), cmd.getSysOrigin(), approvalTypes); approvalTypes.forEach(approvalType -> approvalUserSettingDataService.saveOrUpdateApproval(
} catch (Exception ex) { cmd.getUserId(),
log.error("{}", Throwables.getStackTraceAsString(ex)); cmd.getSysOrigin(),
} approvalType
));
} } catch (Exception ex) {
} log.error("{}", Throwables.getStackTraceAsString(ex));
}
}
}

View File

@ -0,0 +1,31 @@
package tech.sud.mgp.auth.api;
public class SudCode {
private final String code;
private final Long expireDate;
private final boolean success;
private final Integer sdkErrorCode;
public SudCode(String code, Long expireDate, boolean success, Integer sdkErrorCode) {
this.code = code;
this.expireDate = expireDate;
this.success = success;
this.sdkErrorCode = sdkErrorCode;
}
public String getCode() {
return code;
}
public Long getExpireDate() {
return expireDate;
}
public boolean isSuccess() {
return success;
}
public Integer getSdkErrorCode() {
return sdkErrorCode;
}
}

View File

@ -0,0 +1,82 @@
package tech.sud.mgp.auth.api;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.auth0.jwt.interfaces.DecodedJWT;
import java.util.Date;
import java.util.Objects;
/**
* Minimal in-repo replacement for the original SUD auth SDK.
* The project only uses round-trip code generation and verification on our own backend,
* so a signed JWT is enough to preserve the current integration flow.
*/
public class SudMGPAuth {
private static final String CLAIM_UID = "uid";
private static final String CLAIM_TYPE = "type";
private static final String TOKEN_TYPE_CODE = "code";
private static final int ERROR_INVALID_TOKEN = 10001;
private static final int ERROR_TOKEN_EXPIRED = 10002;
private static final int ERROR_INVALID_ARGUMENT = 10003;
private static final long DEFAULT_EXPIRE_MILLIS = 24 * 60 * 60 * 1000L;
private final String appId;
private final Algorithm algorithm;
private final JWTVerifier codeVerifier;
public SudMGPAuth(String appId, String appSecret) {
this.appId = appId;
this.algorithm = Algorithm.HMAC256(appSecret);
this.codeVerifier = JWT.require(algorithm)
.withIssuer(appId)
.withClaim(CLAIM_TYPE, TOKEN_TYPE_CODE)
.build();
}
public SudCode getCode(String uid, Long expireDuration) {
if (uid == null || uid.isBlank()) {
return new SudCode(null, null, false, ERROR_INVALID_ARGUMENT);
}
long expireMillis = System.currentTimeMillis() + normalizedExpire(expireDuration);
String code = JWT.create()
.withIssuer(appId)
.withIssuedAt(new Date())
.withExpiresAt(new Date(expireMillis))
.withClaim(CLAIM_UID, uid)
.withClaim(CLAIM_TYPE, TOKEN_TYPE_CODE)
.sign(algorithm);
return new SudCode(code, expireMillis, true, 0);
}
public SudUid getUidByCode(String code) {
if (code == null || code.isBlank()) {
return new SudUid(null, false, ERROR_INVALID_ARGUMENT);
}
try {
DecodedJWT decodedJWT = codeVerifier.verify(code);
String uid = decodedJWT.getClaim(CLAIM_UID).asString();
if (uid == null || uid.isBlank()) {
return new SudUid(null, false, ERROR_INVALID_TOKEN);
}
return new SudUid(uid, true, 0);
} catch (com.auth0.jwt.exceptions.TokenExpiredException ex) {
return new SudUid(null, false, ERROR_TOKEN_EXPIRED);
} catch (JWTVerificationException ex) {
return new SudUid(null, false, ERROR_INVALID_TOKEN);
}
}
public boolean verifyCode(String code) {
return getUidByCode(code).isSuccess();
}
private static long normalizedExpire(Long expireDuration) {
if (Objects.isNull(expireDuration) || expireDuration <= 0) {
return DEFAULT_EXPIRE_MILLIS;
}
return expireDuration;
}
}

View File

@ -0,0 +1,25 @@
package tech.sud.mgp.auth.api;
public class SudUid {
private final String uid;
private final boolean success;
private final Integer sdkErrorCode;
public SudUid(String uid, boolean success, Integer sdkErrorCode) {
this.uid = uid;
this.success = success;
this.sdkErrorCode = sdkErrorCode;
}
public String getUid() {
return uid;
}
public boolean isSuccess() {
return success;
}
public Integer getSdkErrorCode() {
return sdkErrorCode;
}
}

View File

@ -42,13 +42,24 @@ public interface ApprovalUserSettingDataService extends BaseService<ApprovalUser
*/ */
void updateStatus(ApprovalDataCmd cmd); void updateStatus(ApprovalDataCmd cmd);
/** /**
* 审批类型. * 审批类型.
* *
* @param userId 用户id * @param userId 用户id
* @param approveType 审批类型 * @param approveType 审批类型
*/ */
void saveOrUpdateApproval(Long userId, String sysOrigin, DataApprovalTypeEnum approveType); void saveOrUpdateApproval(Long userId, String sysOrigin, DataApprovalTypeEnum approveType);
/**
* 审批类型.
*
* @param userId 用户id
* @param sysOrigin 系统来源
* @param approveType 审批类型
* @param approvalStatusEnum 初始化状态
*/
void saveOrUpdateApproval(Long userId, String sysOrigin, DataApprovalTypeEnum approveType,
ApprovalStatusEnum approvalStatusEnum);
/** /**
* 设置审批状态. * 设置审批状态.

View File

@ -58,29 +58,37 @@ public class ApprovalUserSettingDataServiceImpl extends
.execute(); .execute();
} }
@Override @Override
public void saveOrUpdateApproval(Long userId, String sysOrigin, public void saveOrUpdateApproval(Long userId, String sysOrigin,
DataApprovalTypeEnum approveType) { DataApprovalTypeEnum approveType) {
if (existsByUserApprovalType(userId, approveType)) { saveOrUpdateApproval(userId, sysOrigin, approveType, initialApprovalStatus(approveType));
update().set(ApprovalUserSettingData::getApproveStatus, ApprovalStatusEnum.PENDING) }
.eq(ApprovalUserSettingData::getUserId, userId)
.eq(ApprovalUserSettingData::getApproveType, approveType) @Override
.last(PageConstant.LIMIT_ONE) public void saveOrUpdateApproval(Long userId, String sysOrigin,
.execute(); DataApprovalTypeEnum approveType, ApprovalStatusEnum approvalStatusEnum) {
return; if (existsByUserApprovalType(userId, approveType)) {
update().set(ApprovalUserSettingData::getApproveStatus, approvalStatusEnum)
.set(ApprovalUserSettingData::getMachineLabel, StringUtils.EMPTY)
.eq(ApprovalUserSettingData::getUserId, userId)
.eq(ApprovalUserSettingData::getApproveType, approveType)
.last(PageConstant.LIMIT_ONE)
.execute();
return;
} }
try { try {
save(new ApprovalUserSettingData() save(new ApprovalUserSettingData()
.setUserId(userId) .setUserId(userId)
.setSysOrigin(sysOrigin) .setSysOrigin(sysOrigin)
.setApproveType(approveType.name()) .setApproveType(approveType.name())
.setApproveStatus(ApprovalStatusEnum.PENDING.name()) .setApproveStatus(approvalStatusEnum.name())
.setNotPassSize(0) .setMachineLabel(StringUtils.EMPTY)
); .setNotPassSize(0)
} catch (DuplicateKeyException ignore) { );
// ignore } catch (DuplicateKeyException ignore) {
} // ignore
}
} }
@Override @Override
@ -95,19 +103,19 @@ public class ApprovalUserSettingDataServiceImpl extends
); );
} }
@Override @Override
public void saveBatchApproval(Long userId, String sysOriginPlatform, List<DataApprovalTypeEnum> approveTypes) { public void saveBatchApproval(Long userId, String sysOriginPlatform, List<DataApprovalTypeEnum> approveTypes) {
saveBatch(approveTypes.stream().map(approvalTypeEnum -> { saveBatch(approveTypes.stream().map(approvalTypeEnum -> {
ApprovalUserSettingData approvalUserSettingData = new ApprovalUserSettingData() ApprovalUserSettingData approvalUserSettingData = new ApprovalUserSettingData()
.setSysOrigin(sysOriginPlatform) .setSysOrigin(sysOriginPlatform)
.setUserId(userId) .setUserId(userId)
.setApproveType(approvalTypeEnum.name()) .setApproveType(approvalTypeEnum.name())
.setApproveStatus(ApprovalStatusEnum.PENDING.name()) .setApproveStatus(initialApprovalStatus(approvalTypeEnum).name())
.setMachineLabel("") .setMachineLabel("")
.setNotPassSize(0); .setNotPassSize(0);
approvalUserSettingData.setCreateTime(TimestampUtils.now()); approvalUserSettingData.setCreateTime(TimestampUtils.now());
approvalUserSettingData.setUpdateTime(TimestampUtils.now()); approvalUserSettingData.setUpdateTime(TimestampUtils.now());
return approvalUserSettingData; return approvalUserSettingData;
}).toList()); }).toList());
} }
@ -170,20 +178,34 @@ public class ApprovalUserSettingDataServiceImpl extends
.orElse(Boolean.TRUE); .orElse(Boolean.TRUE);
} }
private Boolean existsByUserApprovalType(Long userId, DataApprovalTypeEnum approveType) { private Boolean existsByUserApprovalType(Long userId, DataApprovalTypeEnum approveType) {
return Optional.ofNullable( return Optional.ofNullable(
query().select(ApprovalUserSettingData::getId) query().select(ApprovalUserSettingData::getId)
.eq(ApprovalUserSettingData::getApproveType, approveType.name()) .eq(ApprovalUserSettingData::getApproveType, approveType.name())
.eq(ApprovalUserSettingData::getUserId, userId) .eq(ApprovalUserSettingData::getUserId, userId)
.last(PageConstant.LIMIT_ONE) .last(PageConstant.LIMIT_ONE)
.getOne() .getOne()
).map(approvalUserSettingData -> Objects.nonNull(approvalUserSettingData.getId())) ).map(approvalUserSettingData -> Objects.nonNull(approvalUserSettingData.getId()))
.orElse(Boolean.FALSE); .orElse(Boolean.FALSE);
} }
private ApprovalStatusEnum initialApprovalStatus(DataApprovalTypeEnum approveType) {
@Override if (Objects.isNull(approveType)) {
public void deleteFamilyApproval(Long userId) { return ApprovalStatusEnum.PENDING;
}
return switch (approveType) {
case NICKNAME, AVATAR, PHOTO_WALL, ROOM_NICKNAME, ROOM_AVATAR, ROOM_NOTICE,
PROFILE_DESC, FAMILY_AVATAR, FAMILY_NICKNAME, FAMILY_NOTICE, DYNAMIC_CONTENT,
TEAM_AVATAR, TEAM_NICKNAME, BACKGROUND_PHOTO, PERSONAL_PHOTO ->
ApprovalStatusEnum.PASS;
default -> ApprovalStatusEnum.PENDING;
};
}
@Override
public void deleteFamilyApproval(Long userId) {
if (Objects.isNull(userId)) { if (Objects.isNull(userId)) {
return; return;
} }

View File

@ -1,9 +1,9 @@
package com.red.circle.other.infra.gateway.approval; package com.red.circle.other.infra.gateway.approval;
import com.red.circle.common.business.core.enums.DataApprovalTypeEnum; import com.red.circle.common.business.core.enums.DataApprovalTypeEnum;
import com.red.circle.common.business.core.enums.DataApprovalTypeEnum.Type; import com.red.circle.common.business.core.enums.DataApprovalTypeEnum.Type;
import com.red.circle.mq.business.model.event.approval.CensorContent; import com.red.circle.mq.business.model.event.approval.CensorContent;
import com.red.circle.mq.business.model.event.approval.CensorProfileEvent; import com.red.circle.mq.business.model.event.approval.CensorProfileEvent;
import com.red.circle.mq.rocket.business.producer.CensorMqMessage; import com.red.circle.mq.rocket.business.producer.CensorMqMessage;
import com.red.circle.other.domain.gateway.approval.ProfileApprovalGateway; import com.red.circle.other.domain.gateway.approval.ProfileApprovalGateway;
import com.red.circle.other.domain.model.approval.ProfileApprovalContent; import com.red.circle.other.domain.model.approval.ProfileApprovalContent;
@ -54,25 +54,25 @@ public class ProfileApprovalGatewayImpl implements ProfileApprovalGateway {
} }
} }
private void processText(ProfileApprovalContent content) { private void processText(ProfileApprovalContent content) {
approvalUserSettingDataService approvalUserSettingDataService
.saveOrUpdateApproval(content.getBeUserId(), .saveOrUpdateApproval(content.getBeUserId(),
content.getSysOrigin(), content.getSysOrigin(),
content.getApprovalType() content.getApprovalType()
); );
} }
private void processImages(ProfileApprovalContent content) { private void processImages(ProfileApprovalContent content) {
// 更新审批状态 // 更新审批状态
approvalUserSettingDataService.saveOrUpdateApproval(content.getBeUserId(), approvalUserSettingDataService.saveOrUpdateApproval(content.getBeUserId(),
content.getSysOrigin(), content.getSysOrigin(),
content.getApprovalType()); content.getApprovalType());
// 发送审核 // 发送审核
censorMqMessage.image(toCensorProfileEvent(content.getApprovalType(), content)); censorMqMessage.image(toCensorProfileEvent(content.getApprovalType(), content));
} }
private CensorProfileEvent toCensorProfileEvent(DataApprovalTypeEnum approvalType, private CensorProfileEvent toCensorProfileEvent(DataApprovalTypeEnum approvalType,
ProfileApprovalContent content) { ProfileApprovalContent content) {
return new CensorProfileEvent() return new CensorProfileEvent()
.setUserId(content.getBeUserId()) .setUserId(content.getBeUserId())
.setApprovalType(approvalType) .setApprovalType(approvalType)