文章积分相关

文章积分相关
This commit is contained in:
amypeng 2026-05-29 17:44:20 +08:00
parent 1ac64877f8
commit 21868ae523
6 changed files with 196 additions and 0 deletions

View File

@ -83,4 +83,10 @@ public class CmsDocSearchVo {
*/
@ApiModelProperty("关键词")
private String keywords;
/**
* 排除文章Id
*/
@ApiModelProperty(value = "排除文章Id", hidden = true)
private Long excludeId;
}

View File

@ -101,4 +101,36 @@ public interface ICmsAsyncService {
void pushDocDataSearchEngine(CmsDoc cmsDoc);
void clearTmpDoc(CmsProject cmsProject,List<CmsDoc> 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);
}

View File

@ -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);
}
}
}

View File

@ -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);
}

View File

@ -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";
}

View File

@ -264,6 +264,7 @@
<if test="auditStatus != null and auditStatus != '-1' ">and audit_status = #{auditStatus}</if>
<if test="auditStatus == null ">and audit_status = '1'</if>
<if test="createBy != null and createBy != '' ">and create_by = #{createBy}</if>
<if test="excludeId != null ">and id != #{excludeId}</if>
</where>
</sql>