|
|
@@ -0,0 +1,345 @@
|
|
|
+package com.jeeplus.modules.WorkKnowledgeBase.service;
|
|
|
+
|
|
|
+import com.jeeplus.common.persistence.Page;
|
|
|
+import com.jeeplus.common.service.CrudService;
|
|
|
+import com.jeeplus.common.utils.IdGen;
|
|
|
+import com.jeeplus.modules.WorkKnowledgeBase.dao.*;
|
|
|
+import com.jeeplus.modules.WorkKnowledgeBase.entity.WorkKnowledgeBaseLikeRecord;
|
|
|
+import com.jeeplus.modules.WorkKnowledgeBase.entity.WorkKnowledgeBasePointDetail;
|
|
|
+import com.jeeplus.modules.WorkKnowledgeBase.entity.WorkKnowledgeBasePointRule;
|
|
|
+import com.jeeplus.modules.WorkKnowledgeBase.entity.WorkKnowledgeBaseReadRecord;
|
|
|
+import com.jeeplus.modules.WorkKnowledgeBase.entity.WorkKnowledgeBaseShareInfo;
|
|
|
+import com.jeeplus.modules.WorkKnowledgeBase.entity.WorkKnowledgePointCategory;
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
+import org.springframework.transaction.annotation.Transactional;
|
|
|
+
|
|
|
+import java.util.Date;
|
|
|
+import java.util.List;
|
|
|
+import java.util.Map;
|
|
|
+
|
|
|
+/**
|
|
|
+ * 知识库阅读和点赞Service
|
|
|
+ */
|
|
|
+@Service
|
|
|
+@Transactional(readOnly = true)
|
|
|
+public class WorkKnowledgeBaseReadLikeService extends CrudService<WorkKnowledgeBaseReadRecordDao, WorkKnowledgeBaseReadRecord> {
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private WorkKnowledgeBaseReadRecordDao readRecordDao;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private WorkKnowledgeBaseLikeRecordDao likeRecordDao;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private WorkKnowledgeBasePointRuleDao pointRuleDao;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private WorkKnowledgeBaseShareInfoDao shareInfoDao;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private WorkKnowledgePointCategoryDao categoryDao;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private WorkKnowledgeBasePointDetailDao pointDetailDao;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 记录阅读行为(首次阅读给创建人加分)
|
|
|
+ * @param fileId 文件ID
|
|
|
+ * @param userId 访问人ID
|
|
|
+ * @return 是否首次阅读
|
|
|
+ */
|
|
|
+ @Transactional(readOnly = false)
|
|
|
+ public boolean recordRead(String fileId, String userId) {
|
|
|
+ if (fileId == null || userId == null) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 查询是否已有阅读记录
|
|
|
+ WorkKnowledgeBaseReadRecord existingRecord = readRecordDao.findByFileIdAndUserId(fileId, userId);
|
|
|
+
|
|
|
+ if (existingRecord != null) {
|
|
|
+ // 已存在记录,更新访问次数和最近访问时间
|
|
|
+ existingRecord.setLastReadTime(new Date());
|
|
|
+ existingRecord.setReadCount(existingRecord.getReadCount() + 1);
|
|
|
+ existingRecord.preUpdate();
|
|
|
+ readRecordDao.updateReadRecord(existingRecord);
|
|
|
+ return false; // 非首次阅读
|
|
|
+ } else {
|
|
|
+ // 首次阅读,创建新记录
|
|
|
+ WorkKnowledgeBaseReadRecord newRecord = new WorkKnowledgeBaseReadRecord();
|
|
|
+ newRecord.setFileId(fileId);
|
|
|
+ newRecord.setUserId(userId);
|
|
|
+ Date now = new Date();
|
|
|
+ newRecord.setFirstReadTime(now);
|
|
|
+ newRecord.setLastReadTime(now);
|
|
|
+ newRecord.setReadCount(1);
|
|
|
+ newRecord.preInsert();
|
|
|
+ readRecordDao.insert(newRecord);
|
|
|
+
|
|
|
+ // 首次阅读:给创建人发放积分
|
|
|
+ grantPointsForFirstRead(fileId, userId);
|
|
|
+ return true; // 首次阅读
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 点赞操作
|
|
|
+ * @param fileId 文件ID
|
|
|
+ * @param userId 点赞人ID
|
|
|
+ * @return 是否首次点赞(用于前端提示)
|
|
|
+ */
|
|
|
+ @Transactional(readOnly = false)
|
|
|
+ public boolean likeFile(String fileId, String userId) {
|
|
|
+ if (fileId == null || userId == null) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 查询是否有点赞记录
|
|
|
+ WorkKnowledgeBaseLikeRecord existingRecord = likeRecordDao.findByFileIdAndUserId(fileId, userId);
|
|
|
+
|
|
|
+ if (existingRecord != null) {
|
|
|
+ if (existingRecord.getStatus() == 1) {
|
|
|
+ // 已经点赞过了,不需要重复操作
|
|
|
+ return false;
|
|
|
+ } else {
|
|
|
+ // 之前取消过点赞,现在重新点赞
|
|
|
+ existingRecord.setStatus(1);
|
|
|
+ existingRecord.setLikeTime(new Date());
|
|
|
+ existingRecord.setCancelTime(null);
|
|
|
+ existingRecord.preUpdate();
|
|
|
+ likeRecordDao.updateLikeStatus(existingRecord);
|
|
|
+
|
|
|
+ // 重新点赞也给创建人发放积分(仅一次)
|
|
|
+ grantPointsForFirstLike(fileId, userId);
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ // 首次点赞,创建新记录
|
|
|
+ WorkKnowledgeBaseLikeRecord newRecord = new WorkKnowledgeBaseLikeRecord();
|
|
|
+ newRecord.setFileId(fileId);
|
|
|
+ newRecord.setUserId(userId);
|
|
|
+ newRecord.setLikeTime(new Date());
|
|
|
+ newRecord.setStatus(1);
|
|
|
+ newRecord.preInsert();
|
|
|
+ likeRecordDao.insert(newRecord);
|
|
|
+
|
|
|
+ // 首次点赞:给创建人发放积分
|
|
|
+ grantPointsForFirstLike(fileId, userId);
|
|
|
+ return true; // 首次点赞
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 取消点赞操作(同时删除对应的积分记录)
|
|
|
+ * @param fileId 文件ID
|
|
|
+ * @param userId 点赞人ID
|
|
|
+ */
|
|
|
+ @Transactional(readOnly = false)
|
|
|
+ public void cancelLike(String fileId, String userId) {
|
|
|
+ if (fileId == null || userId == null) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ WorkKnowledgeBaseLikeRecord record = likeRecordDao.findByFileIdAndUserId(fileId, userId);
|
|
|
+ if (record != null && record.getStatus() == 1) {
|
|
|
+ // 更新点赞状态为已取消
|
|
|
+ record.setStatus(0);
|
|
|
+ record.setCancelTime(new Date());
|
|
|
+ record.preUpdate();
|
|
|
+ likeRecordDao.updateLikeStatus(record);
|
|
|
+
|
|
|
+ // 删除对应的点赞积分记录(避免重复刷分)
|
|
|
+ deletePointDetailForCancelLike(fileId, userId);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 统计文件的阅读量(去重后的用户数量,每人每文件只计1次)
|
|
|
+ */
|
|
|
+ public Integer getReadCount(String fileId) {
|
|
|
+ if (fileId == null) {
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ Integer count = readRecordDao.countReadersByFileId(fileId);
|
|
|
+ return count != null ? count : 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 统计文件的点赞量
|
|
|
+ */
|
|
|
+ public Integer getLikeCount(String fileId) {
|
|
|
+ if (fileId == null) {
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ Integer count = likeRecordDao.countLikesByFileId(fileId);
|
|
|
+ return count != null ? count : 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 查询文件的阅读详情列表(不分页)
|
|
|
+ */
|
|
|
+ public List<WorkKnowledgeBaseReadRecord> getReadDetailList(String fileId) {
|
|
|
+ return readRecordDao.findReadDetailList(fileId);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 查询文件的阅读详情列表(分页)
|
|
|
+ */
|
|
|
+ public Page<WorkKnowledgeBaseReadRecord> findReadDetailPage(Page<WorkKnowledgeBaseReadRecord> page, String fileId) {
|
|
|
+ page.setList(readRecordDao.findReadDetailPage(page, fileId));
|
|
|
+ return page;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 查询文件的点赞详情列表(不分页)
|
|
|
+ */
|
|
|
+ public List<WorkKnowledgeBaseLikeRecord> getLikeDetailList(String fileId) {
|
|
|
+ return likeRecordDao.findLikeDetailList(fileId);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 查询文件的点赞详情列表(分页)
|
|
|
+ */
|
|
|
+ public Page<WorkKnowledgeBaseLikeRecord> findLikeDetailPage(Page<WorkKnowledgeBaseLikeRecord> page, String fileId) {
|
|
|
+ page.setList(likeRecordDao.findLikeDetailPage(page, fileId));
|
|
|
+ return page;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 检查用户是否已点赞
|
|
|
+ */
|
|
|
+ public boolean isLiked(String fileId, String userId) {
|
|
|
+ if (fileId == null || userId == null) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ WorkKnowledgeBaseLikeRecord record = likeRecordDao.findByFileIdAndUserId(fileId, userId);
|
|
|
+ return record != null && record.getStatus() == 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 首次阅读时给创建人发放积分
|
|
|
+ */
|
|
|
+ private void grantPointsForFirstRead(String fileId, String readerUserId) {
|
|
|
+ try {
|
|
|
+ // 查询文件信息获取创建人
|
|
|
+ WorkKnowledgeBaseShareInfo shareInfo = shareInfoDao.get(fileId);
|
|
|
+ if (shareInfo == null || shareInfo.getCreateBy() == null) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ String creatorUserId = shareInfo.getCreateBy().getId();
|
|
|
+ if (creatorUserId.equals(readerUserId)) {
|
|
|
+ // 自己阅读自己的文件,不给积分
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 查询"基础积分"分类的积分规则
|
|
|
+ List<WorkKnowledgePointCategory> categories = categoryDao.findList(
|
|
|
+ new WorkKnowledgePointCategory() {{ setCategoryName("基础积分"); }}
|
|
|
+ );
|
|
|
+
|
|
|
+ if (categories == null || categories.isEmpty()) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ String categoryId = categories.get(0).getId();
|
|
|
+
|
|
|
+ // 使用新方法精确查询:category_id + rule_type=10 + point_name="阅读"
|
|
|
+ WorkKnowledgeBasePointRule rule = pointRuleDao.findByCategoryIdAndRuleTypeAndPointName(categoryId, "10", "阅读");
|
|
|
+
|
|
|
+ if (rule != null && rule.getPointValue() != null) {
|
|
|
+ int pointValue = Integer.parseInt(rule.getPointValue());
|
|
|
+ if (pointValue > 0) {
|
|
|
+ // 插入积分明细(change_type=3 表示阅读积分)
|
|
|
+ insertPointDetail(creatorUserId, fileId, 3, pointValue);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ // 积分发放失败不影响阅读记录,记录日志即可
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 首次点赞时给创建人发放积分
|
|
|
+ */
|
|
|
+ private void grantPointsForFirstLike(String fileId, String likerUserId) {
|
|
|
+ try {
|
|
|
+ // 查询文件信息获取创建人
|
|
|
+ WorkKnowledgeBaseShareInfo shareInfo = shareInfoDao.get(fileId);
|
|
|
+ if (shareInfo == null || shareInfo.getCreateBy() == null) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ String creatorUserId = shareInfo.getCreateBy().getId();
|
|
|
+ if (creatorUserId.equals(likerUserId)) {
|
|
|
+ // 自己点赞自己的文件,不给积分
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 查询"基础积分"分类的积分规则
|
|
|
+ List<WorkKnowledgePointCategory> categories = categoryDao.findList(
|
|
|
+ new WorkKnowledgePointCategory() {{ setCategoryName("基础积分"); }}
|
|
|
+ );
|
|
|
+
|
|
|
+ if (categories == null || categories.isEmpty()) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ String categoryId = categories.get(0).getId();
|
|
|
+
|
|
|
+ // 使用新方法精确查询:category_id + rule_type=10 + point_name="点赞"
|
|
|
+ WorkKnowledgeBasePointRule rule = pointRuleDao.findByCategoryIdAndRuleTypeAndPointName(
|
|
|
+ categoryId, "10", "点赞"
|
|
|
+ );
|
|
|
+
|
|
|
+ if (rule != null && rule.getPointValue() != null) {
|
|
|
+ int pointValue = Integer.parseInt(rule.getPointValue());
|
|
|
+ if (pointValue > 0) {
|
|
|
+ // 插入积分明细(change_type=4 表示点赞积分)
|
|
|
+ insertPointDetail(creatorUserId, fileId, 4, pointValue);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ // 积分发放失败不影响点赞记录,记录日志即可
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 插入积分明细记录
|
|
|
+ */
|
|
|
+ private void insertPointDetail(String userId, String shareId, Integer changeType, Integer point) {
|
|
|
+ WorkKnowledgeBasePointDetail detail = new WorkKnowledgeBasePointDetail();
|
|
|
+ detail.setUserId(userId);
|
|
|
+ detail.setShareId(shareId);
|
|
|
+ detail.setChangeType(changeType);
|
|
|
+ detail.setPoint(point);
|
|
|
+ detail.preInsert();
|
|
|
+ pointDetailDao.insert(detail);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 取消点赞时删除对应的点赞积分记录(物理删除)
|
|
|
+ * @param fileId 文件ID
|
|
|
+ * @param likerUserId 点赞人ID
|
|
|
+ */
|
|
|
+ private void deletePointDetailForCancelLike(String fileId, String likerUserId) {
|
|
|
+ try {
|
|
|
+ // 查询文件信息获取创建人
|
|
|
+ WorkKnowledgeBaseShareInfo shareInfo = shareInfoDao.get(fileId);
|
|
|
+ if (shareInfo == null || shareInfo.getCreateBy() == null) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ String creatorUserId = shareInfo.getCreateBy().getId();
|
|
|
+
|
|
|
+ // 物理删除创建人的点赞积分记录(change_type=4表示点赞积分)
|
|
|
+ pointDetailDao.deleteByUserIdAndShareIdAndChangeType(creatorUserId, fileId, 4);
|
|
|
+ } catch (Exception e) {
|
|
|
+ // 删除失败不影响取消点赞操作,记录日志即可
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|