From 21868ae523335917faa20ea32470d5283aeb6569 Mon Sep 17 00:00:00 2001 From: amypeng Date: Fri, 29 May 2026 17:44:20 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=87=E7=AB=A0=E7=A7=AF=E5=88=86=E7=9B=B8?= =?UTF-8?q?=E5=85=B3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 文章积分相关 --- .../cms/doc/domain/CmsDocSearchVo.java | 6 + .../cms/doc/service/ICmsAsyncService.java | 32 +++++ .../doc/service/impl/CmsAsyncServiceImpl.java | 126 ++++++++++++++++++ .../doc/service/impl/CmsDocServiceImpl.java | 11 ++ .../microservices/cms/utils/CmsConstants.java | 20 +++ .../resources/mapper/cms/CmsDocMapper.xml | 1 + 6 files changed, 196 insertions(+) diff --git a/microservices-modules/microservices-modules-cms/src/main/java/com/microservices/cms/doc/domain/CmsDocSearchVo.java b/microservices-modules/microservices-modules-cms/src/main/java/com/microservices/cms/doc/domain/CmsDocSearchVo.java index 655de8514..82465ae55 100644 --- a/microservices-modules/microservices-modules-cms/src/main/java/com/microservices/cms/doc/domain/CmsDocSearchVo.java +++ b/microservices-modules/microservices-modules-cms/src/main/java/com/microservices/cms/doc/domain/CmsDocSearchVo.java @@ -83,4 +83,10 @@ public class CmsDocSearchVo { */ @ApiModelProperty("关键词") private String keywords; + + /** + * 排除文章Id + */ + @ApiModelProperty(value = "排除文章Id", hidden = true) + private Long excludeId; } diff --git a/microservices-modules/microservices-modules-cms/src/main/java/com/microservices/cms/doc/service/ICmsAsyncService.java b/microservices-modules/microservices-modules-cms/src/main/java/com/microservices/cms/doc/service/ICmsAsyncService.java index 4261b6464..77d99a23f 100644 --- a/microservices-modules/microservices-modules-cms/src/main/java/com/microservices/cms/doc/service/ICmsAsyncService.java +++ b/microservices-modules/microservices-modules-cms/src/main/java/com/microservices/cms/doc/service/ICmsAsyncService.java @@ -101,4 +101,36 @@ public interface ICmsAsyncService { void pushDocDataSearchEngine(CmsDoc cmsDoc); void clearTmpDoc(CmsProject cmsProject,List tmpDocList); + + /** + * 异步增加文章发布积分 + * + * @param deptId 组织ID + * @param createBy 创建人用户名 + * @param docId 文章ID + * @param subjectDesc 文章标题 + */ + void addPublishDocPointsAsync(Long deptId, String createBy, Long docId, String subjectDesc); + + /** + * 异步增加文章浏览积分(每满100次+2,上限50) + * + * @param deptId 组织ID + * @param createBy 创建人用户名 + * @param docId 文章ID + * @param docName 文章名称 + * @param totalVisits 累计阅读次数 + * @param pointsTriggerCount 当前第几次增加积分 + */ + void addVisitsDocPointsAsync(Long deptId, String createBy, Long docId, String docName, Long totalVisits); + + /** + * 异步增加文章被设为精选的积分 + * + * @param deptId 组织ID + * @param createBy 创建人用户名 + * @param docId 文章ID + * @param subjectDesc 文章标题 + */ + void addFeaturedDocPointsAsync(Long deptId, String createBy, Long docId, String subjectDesc); } diff --git a/microservices-modules/microservices-modules-cms/src/main/java/com/microservices/cms/doc/service/impl/CmsAsyncServiceImpl.java b/microservices-modules/microservices-modules-cms/src/main/java/com/microservices/cms/doc/service/impl/CmsAsyncServiceImpl.java index 857bc8ad1..47303349e 100644 --- a/microservices-modules/microservices-modules-cms/src/main/java/com/microservices/cms/doc/service/impl/CmsAsyncServiceImpl.java +++ b/microservices-modules/microservices-modules-cms/src/main/java/com/microservices/cms/doc/service/impl/CmsAsyncServiceImpl.java @@ -35,6 +35,7 @@ import com.microservices.common.httpClient.util.GitLinkRequestHelper; import com.microservices.common.redis.service.RedisService; import com.microservices.common.security.utils.SecurityUtils; import com.microservices.system.api.RemoteDeptService; +import com.microservices.system.api.RemoteUserService; import com.microservices.system.api.RemoteZoneService; import com.microservices.system.api.utils.FeignUtils; import org.apache.http.client.config.RequestConfig; @@ -97,6 +98,8 @@ public class CmsAsyncServiceImpl implements ICmsAsyncService { @Autowired private RemoteZoneService remoteZoneService; @Autowired + private RemoteUserService remoteUserService; + @Autowired private RequestConfig config; /** @@ -1084,4 +1087,127 @@ public class CmsAsyncServiceImpl implements ICmsAsyncService { } } + /** + * 检查是否为积分部门 + * + * @param deptId 部门ID + * @return 是否为积分部门 + */ + private boolean isPointsDept(Long deptId) { + Long cachedPointsDeptId = redisService.getCacheObject(CacheConstants.ZONE_POINTS_DEPT_ID_KEY); + return cachedPointsDeptId != null && cachedPointsDeptId > 0 && cachedPointsDeptId.equals(deptId); + } + + @Async + @Override + public void addPublishDocPointsAsync(Long deptId, String createBy, Long docId, String subjectDesc) { + try { + if (deptId == null || createBy == null) { + logger.warn("文章审核通过增加积分失败,deptId或createBy为空,docId={}", docId); + return; + } + // 检查是否为积分部门 + if (!isPointsDept(deptId)) { + logger.info("文章审核通过增加积分跳过,非积分部门,deptId={},docId={}", deptId, docId); + return; + } + // 获取用户ID + com.microservices.system.api.domain.SysUser sysUser = FeignUtils.getReturnData( + remoteUserService.getSysUserByUserName(createBy, SecurityConstants.INNER)); + if (sysUser == null || sysUser.getUserId() == null) { + logger.warn("文章审核通过增加积分失败,未找到用户信息,createBy={},docId={}", createBy, docId); + return; + } + + // 直接写入 Redis 积分队列,由 Zone 模块定时任务消费 + JSONObject task = new JSONObject(); + task.put("sourceType", CmsConstants.PUBLISH_DOC); + task.put("userId", sysUser.getUserId()); + task.put("deptId", deptId); + task.put("sourceId", docId); + task.put("subjectDesc", subjectDesc); + task.put("operatorId", sysUser.getUserId()); + redisService.leftPush(CmsConstants.ZONE_POINTS_ASYNC_QUEUE_KEY, task.toJSONString()); + logger.info("文章审核通过增加积分任务已写入队列,docId={},userId={},deptId={}", docId, sysUser.getUserId(), deptId); + } catch (Throwable e) { + // 捕获所有异常,确保不影响主事务 + logger.error("文章审核通过增加积分异常,docId={}", docId, e); + } + } + + @Async + @Override + public void addVisitsDocPointsAsync(Long deptId, String createBy, Long docId, String docName, Long totalVisits) { + try { + if (deptId == null || createBy == null) { + logger.warn("文章浏览增加积分失败,参数不合法,deptId={},createBy={}", deptId, createBy); + return; + } + // 检查是否为积分部门 + if (!isPointsDept(deptId)) { + logger.info("文章浏览增加积分跳过,非积分部门,deptId={},docId={}", deptId, docId); + return; + } + // 获取用户ID + com.microservices.system.api.domain.SysUser sysUser = FeignUtils.getReturnData( + remoteUserService.getSysUserByUserName(createBy, SecurityConstants.INNER)); + if (sysUser == null || sysUser.getUserId() == null) { + logger.warn("文章浏览增加积分失败,未找到用户信息,createBy={},docId={}", createBy, docId); + return; + } + // 直接写入 Redis 积分队列,由 Zone 模块定时任务消费 + JSONObject task = new JSONObject(); + task.put("sourceType", CmsConstants.VISITS_DOC); + task.put("userId", sysUser.getUserId()); + task.put("deptId", deptId); + task.put("sourceId", docId); +// JSONObject sourceData = new JSONObject(); +// sourceData.put("totalVisits", totalVisits); +// sourceData.put("currentIncrement", pointsTriggerCount); + task.put("sourceData", totalVisits); + task.put("subjectDesc", docName); + task.put("operatorId", SecurityUtils.getUserId()); + redisService.leftPush(CmsConstants.ZONE_POINTS_ASYNC_QUEUE_KEY, task.toJSONString()); + logger.info("文章浏览增加积分任务已写入队列,docId={},userId={},deptId={},totalVisits={}", docId, sysUser.getUserId(), deptId, totalVisits); + } catch (Throwable e) { + // 捕获所有异常,确保不影响主事务 + logger.error("文章浏览增加积分异常,docId={}", docId, e); + } + } + + @Async + @Override + public void addFeaturedDocPointsAsync(Long deptId, String createBy, Long docId, String subjectDesc) { + try { + if (deptId == null || createBy == null) { + logger.warn("积分-文章精选:参数不合法,deptId={},createBy={}", deptId, createBy); + return; + } + // 检查是否为积分部门 + if (!isPointsDept(deptId)) { + logger.info("积分-文章精选:非积分部门,deptId={},docId={}", deptId, docId); + return; + } + // 获取用户ID + com.microservices.system.api.domain.SysUser sysUser = FeignUtils.getReturnData( + remoteUserService.getSysUserByUserName(createBy, SecurityConstants.INNER)); + if (sysUser == null || sysUser.getUserId() == null) { + logger.warn("积分-文章精选:未找到用户信息,createBy={},docId={}", createBy, docId); + return; + } + // 直接写入 Redis 积分队列,由 Zone 模块定时任务消费 + JSONObject task = new JSONObject(); + task.put("sourceType", CmsConstants.FEATURED_DOC); + task.put("userId", sysUser.getUserId()); + task.put("deptId", deptId); + task.put("sourceId", docId); + task.put("subjectDesc", "《" + subjectDesc + "》管理员标记"); + task.put("operatorId", SecurityUtils.getUserId()); + redisService.leftPush(CmsConstants.ZONE_POINTS_ASYNC_QUEUE_KEY, task.toJSONString()); + logger.info("文章被设为精选增加积分任务已写入队列,docId={},userId={},deptId={}", docId, sysUser.getUserId(), deptId); + } catch (Throwable e) { + // 捕获所有异常,确保不影响主事务 + logger.error("文章被设为精选增加积分异常,docId={}", docId, e); + } + } } diff --git a/microservices-modules/microservices-modules-cms/src/main/java/com/microservices/cms/doc/service/impl/CmsDocServiceImpl.java b/microservices-modules/microservices-modules-cms/src/main/java/com/microservices/cms/doc/service/impl/CmsDocServiceImpl.java index 72a02f7ba..52b72aca8 100644 --- a/microservices-modules/microservices-modules-cms/src/main/java/com/microservices/cms/doc/service/impl/CmsDocServiceImpl.java +++ b/microservices-modules/microservices-modules-cms/src/main/java/com/microservices/cms/doc/service/impl/CmsDocServiceImpl.java @@ -382,6 +382,10 @@ public class CmsDocServiceImpl implements ICmsDocService { boolean success = insertCommonCmsDoc(cmsDoc, "创建文章:" + StringUtils.truncateStringAndConcatenatingSpecifiedString(cmsDoc.getName(), 100, "..."), cmsDocInputDto.getContent()); + if (success) { + // 自动审核通过时也需要增加积分 + cmsAsyncService.addPublishDocPointsAsync(cmsDoc.getDeptId(), cmsDoc.getCreateBy(), cmsDoc.getId(), cmsDoc.getName()); + } return success ? cmsDoc.getId().intValue() : null; } else { //创建临时分支,创建文件,创建PR @@ -572,6 +576,8 @@ public class CmsDocServiceImpl implements ICmsDocService { // 推送文章地址到搜索引擎 cmsAsyncService.pushDocDataSearchEngine(cmsDoc); + // 文章审核通过后,给作者增加积分(异步执行,不影响主事务) + cmsAsyncService.addPublishDocPointsAsync(cmsDoc.getDeptId(), cmsDoc.getCreateBy(), cmsDoc.getId(), cmsDoc.getName()); } private JSONObject mergePullRequestByGitLink(CmsProject cmsProject, CmsDoc cmsDoc) { @@ -1044,6 +1050,8 @@ public class CmsDocServiceImpl implements ICmsDocService { visits = visits + cmsDoc.getVisits(); } cmsDoc.setVisits(visits); + cmsAsyncService.addVisitsDocPointsAsync(cmsDoc.getDeptId(), cmsDoc.getCreateBy(), + cmsDoc.getId(), cmsDoc.getName(), cmsDoc.getVisits()); return cmsDocMapper.updateCmsDoc(cmsDoc) > 0; } @@ -1168,6 +1176,9 @@ public class CmsDocServiceImpl implements ICmsDocService { //首页推荐时,需将顺序设置为1 setCmsSort(1, cmsDoc, false, null); cmsDoc.setIsHomepage(CmsConstants.TRUE); + // 文章被设为精选,异步增加作者积分 + cmsAsyncService.addFeaturedDocPointsAsync(cmsDoc.getDeptId(), cmsDoc.getCreateBy(), + cmsDoc.getId(), cmsDoc.getName()); } return cmsDocMapper.updateCmsDoc(cmsDoc); } diff --git a/microservices-modules/microservices-modules-cms/src/main/java/com/microservices/cms/utils/CmsConstants.java b/microservices-modules/microservices-modules-cms/src/main/java/com/microservices/cms/utils/CmsConstants.java index 8fcbe1322..2f8aab3de 100644 --- a/microservices-modules/microservices-modules-cms/src/main/java/com/microservices/cms/utils/CmsConstants.java +++ b/microservices-modules/microservices-modules-cms/src/main/java/com/microservices/cms/utils/CmsConstants.java @@ -25,4 +25,24 @@ public class CmsConstants { * 是 */ public final static String TRUE = "1"; + + /** + * 专区积分异步队列 Redis Key(与 Zone 模块保持一致) + */ + public final static String ZONE_POINTS_ASYNC_QUEUE_KEY = "zone:points:async:queue"; + + /** + * 发布文章积分类型 + */ + public final static String PUBLISH_DOC = "publishDoc"; + + /** + * 浏览文章积分类型 + */ + public final static String VISITS_DOC = "visitsDoc"; + + /** + * 精选文章积分类型 + */ + public final static String FEATURED_DOC = "featuredDoc"; } diff --git a/microservices-modules/microservices-modules-cms/src/main/resources/mapper/cms/CmsDocMapper.xml b/microservices-modules/microservices-modules-cms/src/main/resources/mapper/cms/CmsDocMapper.xml index 2dcdc953e..6e9bdd750 100644 --- a/microservices-modules/microservices-modules-cms/src/main/resources/mapper/cms/CmsDocMapper.xml +++ b/microservices-modules/microservices-modules-cms/src/main/resources/mapper/cms/CmsDocMapper.xml @@ -264,6 +264,7 @@ and audit_status = #{auditStatus} and audit_status = '1' and create_by = #{createBy} + and id != #{excludeId}