Kaynağa Gözat

知识库积分部分功能提交,问答答疑部分功能提交

徐滕 2 gün önce
ebeveyn
işleme
ae0c6c9a21

+ 7 - 0
src/main/java/com/jeeplus/modules/WorkKnowledgeBase/dao/WorkKnowledgeBaseQaAnswerDao.java

@@ -34,4 +34,11 @@ public interface WorkKnowledgeBaseQaAnswerDao extends CrudDao<WorkKnowledgeBaseQ
      * @return 影响行数
      */
     int insertAnswer(WorkKnowledgeBaseQaAnswer answer);
+    
+    /**
+     * 删除回答(物理删除)
+     * @param answerId 回答ID
+     * @return 影响行数
+     */
+    int deleteAnswer(String answerId);
 }

+ 30 - 14
src/main/java/com/jeeplus/modules/WorkKnowledgeBase/service/WorkKnowledgeBaseReadLikeService.java

@@ -3,6 +3,7 @@ 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.common.utils.StringUtils;
 import com.jeeplus.modules.WorkKnowledgeBase.dao.*;
 import com.jeeplus.modules.WorkKnowledgeBase.entity.WorkKnowledgeBaseLikeRecord;
 import com.jeeplus.modules.WorkKnowledgeBase.entity.WorkKnowledgeBasePointDetail;
@@ -222,15 +223,21 @@ public class WorkKnowledgeBaseReadLikeService extends CrudService<WorkKnowledgeB
      */
     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)) {
-                // 自己阅读自己的文件,不给积分
+            // 判断阅读人是否是记录所有者(与前端isCreator逻辑一致)
+            // 如果submitAuditUserId有值,则判定是否是最后修改人
+            // 如果submitAuditUserId为空,则判定是否是创建人
+            String ownerUserId = (StringUtils.isNotBlank(shareInfo.getSubmitAuditUserId()))
+                ? shareInfo.getSubmitAuditUserId() 
+                : shareInfo.getCreateBy().getId();
+            
+            if (ownerUserId.equals(readerUserId)) {
+                // 记录所有者阅读自己的文件,不给积分
                 return;
             }
 
@@ -252,7 +259,7 @@ public class WorkKnowledgeBaseReadLikeService extends CrudService<WorkKnowledgeB
                 int pointValue = Integer.parseInt(rule.getPointValue());
                 if (pointValue > 0) {
                     // 插入积分明细(change_type=3 表示阅读积分)
-                    insertPointDetail(creatorUserId, fileId, 3, categoryId, rule.getId(), pointValue);
+                    insertPointDetail(ownerUserId, fileId, 3, categoryId, rule.getId(), pointValue);
                 }
             }
         } catch (Exception e) {
@@ -266,15 +273,21 @@ public class WorkKnowledgeBaseReadLikeService extends CrudService<WorkKnowledgeB
      */
     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)) {
-                // 自己点赞自己的文件,不给积分
+            // 判断点赞人是否是记录所有者(与前端isCreator逻辑一致)
+            // 如果submitAuditUserId有值,则判定是否是最后修改人
+            // 如果submitAuditUserId为空,则判定是否是创建人
+            String ownerUserId = (StringUtils.isNotBlank(shareInfo.getSubmitAuditUserId()))
+                ? shareInfo.getSubmitAuditUserId() 
+                : shareInfo.getCreateBy().getId();
+            
+            if (ownerUserId.equals(likerUserId)) {
+                // 记录所有者点赞自己的文件,不给积分
                 return;
             }
 
@@ -296,7 +309,7 @@ public class WorkKnowledgeBaseReadLikeService extends CrudService<WorkKnowledgeB
                 int pointValue = Integer.parseInt(rule.getPointValue());
                 if (pointValue > 0) {
                     // 插入积分明细(change_type=4 表示点赞积分)
-                    insertPointDetail(creatorUserId, fileId, 4, categoryId, rule.getId(), pointValue);
+                    insertPointDetail(ownerUserId, fileId, 4, categoryId, rule.getId(), pointValue);
                 }
             }
         } catch (Exception e) {
@@ -327,16 +340,19 @@ public class WorkKnowledgeBaseReadLikeService extends CrudService<WorkKnowledgeB
      */
     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();
+            // 判断记录所有者(与grantPointsForFirstLike逻辑一致)
+            String ownerUserId = (StringUtils.isNotBlank(shareInfo.getSubmitAuditUserId())) 
+                ? shareInfo.getSubmitAuditUserId() 
+                : shareInfo.getCreateBy().getId();
             
-            // 物理删除创建人的点赞积分记录(change_type=4表示点赞积分)
-            pointDetailDao.deleteByUserIdAndShareIdAndChangeType(creatorUserId, fileId, 4);
+            // 物理删除记录所有者的点赞积分记录(change_type=4表示点赞积分)
+            pointDetailDao.deleteByUserIdAndShareIdAndChangeType(ownerUserId, fileId, 4);
         } catch (Exception e) {
             // 删除失败不影响取消点赞操作,记录日志即可
             e.printStackTrace();

+ 29 - 0
src/main/java/com/jeeplus/modules/WorkKnowledgeBase/service/WorkKnowledgeBaseShareService.java

@@ -819,6 +819,35 @@ public class WorkKnowledgeBaseShareService extends CrudService<WorkKnowledgeBase
     }
 
     /**
+     * 删除回答(物理删除)
+     * @param answerId 回答ID
+     * @param currentUserId 当前用户ID
+     * @throws Exception 如果无权删除则抛出异常
+     */
+    @Transactional(readOnly = false)
+    public void deleteAnswer(String answerId, String currentUserId) throws Exception {
+        // 1. 查询回答信息
+        WorkKnowledgeBaseQaAnswer answer = qaAnswerDao.get(answerId);
+        if (answer == null) {
+            throw new Exception("回答不存在");
+        }
+        
+        // 2. 验证权限:只有回答的创建人可以删除
+        if (!currentUserId.equals(answer.getCreateBy().getId())) {
+            throw new Exception("只有回答的创建人可以删除此回答");
+        }
+        
+        // 3. 检查该回答是否已被确认为最佳答案
+        WorkKnowledgeBaseShareInfo question = dao.get(answer.getQuestionId());
+        if (question != null && answerId.equals(question.getAnswerId())) {
+            throw new Exception("最佳答案不能删除");
+        }
+        
+        // 4. 执行物理删除
+        qaAnswerDao.deleteAnswer(answerId);
+    }
+
+    /**
      * 逻辑删除文件(含动态字段值)
      */
     @Transactional(readOnly = false)

+ 20 - 0
src/main/java/com/jeeplus/modules/WorkKnowledgeBase/web/WorkKnowledgeBaseShareController.java

@@ -596,4 +596,24 @@ public class WorkKnowledgeBaseShareController extends BaseController {
         }
         return result;
     }
+
+    /**
+     * 删除回答(Ajax)
+     */
+    @RequiresPermissions("workKnowledgeBase:share:list")
+    @RequestMapping(value = "deleteAnswer")
+    @ResponseBody
+    public Map<String, Object> deleteAnswer(@RequestParam String answerId) {
+        Map<String, Object> result = new HashMap<>();
+        try {
+            String currentUserId = UserUtils.getUser().getId();
+            shareService.deleteAnswer(answerId, currentUserId);
+            result.put("success", true);
+            result.put("message", "删除成功");
+        } catch (Exception e) {
+            result.put("success", false);
+            result.put("message", e.getMessage());
+        }
+        return result;
+    }
 }

+ 7 - 0
src/main/resources/mappings/modules/WorkKnowledgeBase/WorkKnowledgeBaseQaAnswerDao.xml

@@ -12,6 +12,7 @@
         a.update_date AS "updateDate",
         a.remarks AS "remarks",
         a.del_flag AS "delFlag",
+        u.id AS "answerUser.id",  <!-- 回答人ID -->
         u.name AS "answerUserName",
         q.name AS "questionTitle",
         CASE WHEN q.answer_id = a.id THEN 1 ELSE 0 END AS "isBestAnswer"
@@ -76,4 +77,10 @@
         )
     </insert>
     
+    <!-- 删除回答(物理删除) -->
+    <delete id="deleteAnswer">
+        DELETE FROM work_knowledge_base_qa_answer
+        WHERE id = #{answerId}
+    </delete>
+    
 </mapper>

+ 89 - 30
src/main/webapp/webpage/modules/WorkKnowledgeBase/workKnowledgeBaseShareDetail.jsp

@@ -213,6 +213,8 @@
                 </div>
             </div>
 
+            <!-- 审核状态(问答答疑分类不显示) -->
+            <c:if test="${!isQaCategory}">
             <div class="layui-item layui-col-sm6 lw6">
                 <label class="layui-form-label detail-label">审核状态:</label>
                 <div class="layui-input-block">
@@ -241,6 +243,7 @@
                            style="color:${auditStatusColor};font-weight:bold;"/>
                 </div>
             </div>
+            </c:if>
         </div>
 
         <!-- 审核状态 -->
@@ -515,30 +518,37 @@
     /** 加载回答列表 */
     function loadAnswers() {
         if (!isQaCategory) return;
-        
+            
         $.ajax({
             type: 'GET',
             url: '${ctx}/workKnowledgeBase/share/getAnswers',
             data: { questionId: questionId },
             success: function(data) {
+                console.log('回答数据:', data); // 调试信息
                 if (data.success) {
                     renderAnswers(data.answers);
                     $('#answerTotalCount').text(data.answerCount);
-                    
-                    // 如果已确认答案,隐藏发表回答框和所有"确认最佳答案"按钮
+                        
+                    // 如果已确认答案,隐藏发表回答框和所有“确认最佳答案”按钮
                     if (!data.canAnswer) {
                         // 隐藏整个发表回答区域
                         $('.form-group-label:has(h2)').filter(function() {
                             return $(this).text().indexOf('发表回答') !== -1;
                         }).parent().hide();
                     }
+                } else {
+                    console.error('加载回答失败:', data.message);
                 }
+            },
+            error: function(xhr, status, error) {
+                console.error('请求失败:', status, error);
             }
         });
     }
 
     /** 渲染回答列表 */
     function renderAnswers(answers) {
+        console.log('开始渲染回答,数量:', answers ? answers.length : 0); // 调试信息
         var html = '';
         if (answers && answers.length > 0) {
             // 分离最佳答案和其他答案
@@ -554,64 +564,85 @@
                 }
             }
             
+            // 判断是否已有最佳答案
+            var hasBestAnswer = (bestAnswer != null);
+            
             // 如果有最佳答案,先渲染最佳答案(置顶)
             if (bestAnswer) {
-                html += renderAnswerItem(bestAnswer, true);
+                html += renderAnswerItem(bestAnswer, true, hasBestAnswer);
             }
             
             // 渲染其他答案
             for (var i = 0; i < otherAnswers.length; i++) {
-                html += renderAnswerItem(otherAnswers[i], false);
+                html += renderAnswerItem(otherAnswers[i], false, hasBestAnswer);
             }
         } else {
-            html = '<div style="text-align:center;color:#999;padding:20px;">暂无回答</div>';
+            html = '<div style="padding:20px;text-align:center;color:#999;">暂无回答</div>';
         }
         $('#answerListContainer').html(html);
+        console.log('渲染完成,HTML长度:', html.length); // 调试信息
     }
     
     /** 渲染单个回答项 */
-    function renderAnswerItem(ans, isBest) {
+    function renderAnswerItem(ans, isBest, hasBestAnswer) {
         var isCreator = ans.createBy && ans.createBy.id == questionCreatorId;
+        // 获取回答人ID:优先使用answerUser.id(从数据库查询),其次使用createBy.id
+        var answerUserId = (ans.answerUser && ans.answerUser.id) || (ans.createBy && ans.createBy.id) || '';
+        var canDelete = currentUserId == answerUserId; // 只有回答人可以删除自己的回答
+        
+        // 调试日志:打印回答信息
+        console.log('回答ID:', ans.id);
+        console.log('  - answerUser:', ans.answerUser);
+        console.log('  - createBy:', ans.createBy);
+        console.log('  - answerUserId:', answerUserId);
+        console.log('  - currentUserId:', currentUserId);
+        console.log('  - canDelete:', canDelete);
+        console.log('  - isBest:', isBest);
+        console.log('  - hasBestAnswer:', hasBestAnswer);
+        
         var html = '';
         
         // 最佳答案使用特殊背景色突出显示
         if (isBest) {
-            html += '<div class="media" style="padding:15px;border:2px solid #52c41a;background-color:#f6ffed;margin-bottom:15px;border-radius:5px;">';
+            html += '<div class="layui-item layui-col-xs12" id="answer' + ans.id + '" style="padding:10px 0;background-color:#f6ffed;border-radius:5px;margin-bottom:10px;">';
         } else {
-            html += '<div class="media" style="padding:15px;border-bottom:1px solid #eee;">';
+            html += '<div class="layui-item layui-col-xs12" id="answer' + ans.id + '" style="padding:10px 0;">';
         }
-        html += '  <div class="media-body">';
         
-        // 最佳答案标识
-        if (isBest) {
-            html += '    <div style="color:#52c41a;font-weight:bold;font-size:16px;margin-bottom:8px;">✓ 最佳答案</div>';
-        }
+        // 用户名:淡蓝色、字体放大
+        html += '<span class="comment_name" style="color:#1E9FFF;font-size:16px;font-weight:500;">' + (ans.answerUserName || '未知') + '</span>';
         
-        // 回答人信息
-        html += '    <div style="color:#666;margin-bottom:8px;">';
-        html += '      <span style="font-weight:bold;color:' + (isBest ? '#52c41a' : '#333') + ';">' + (ans.answerUserName || '未知') + '</span>';
-        html += '      <span style="margin-left:10px;color:#999;">' + (ans.createDate || '') + '</span>';
+        // 如果是提问者,添加标识
         if (isCreator) {
-            html += '      <span style="margin-left:10px;color:#1890ff;">(提问者)</span>';
+            html += ' <span style="color:#1890ff;font-size:14px;">(提问者)</span>';
         }
-        html += '    </div>';
         
-        // 回答内容(最佳答案字体颜色更深)
+        // 最佳答案标识
         if (isBest) {
-            html += '    <div style="color:#333;line-height:1.8;font-size:15px;">' + (ans.answerContent || '') + '</div>';
-        } else {
-            html += '    <div style="color:#333;line-height:1.8;">' + (ans.answerContent || '') + '</div>';
+            html += ' <span style="color:#52c41a;font-weight:bold;font-size:14px;">✓ 最佳答案</span>';
+        }
+        
+        // 回答内容:缩进、行高加大
+        html += '<div class="comment_content" style="margin-left:25px;margin-top:8px;font-size:14px;line-height:1.8;color:' + (isBest ? '#333' : '#333') + ';">' + (ans.answerContent || '') + '</div>';
+        
+        // 底部信息:时间和删除按钮
+        html += '<div class="del" style="color:#999;font-size:12px;margin-top:5px;">';
+        html += '<span>' + (ans.createDate || '') + '</span>';
+        
+        // 删除按钮(仅回答人可看到,最佳答案不能删除)
+        if (!isBest && canDelete) {
+            html += '<a href="javascript:void(0)" onclick="deleteAnswer(\'' + ans.id + '\')" style="float:right;margin-right:20px;color:#666;font-size:14px;font-weight:500;">删除</a>';
         }
         
         // 确认按钮(仅发起人且未确认答案时显示)
-        if (!isBest && currentUserId == questionCreatorId) {
-            html += '    <div style="margin-top:10px;">';
-            html += '      <a href="javascript:void(0)" onclick="confirmAnswer(\'' + ans.id + '\')" class="layui-btn layui-btn-xs layui-bg-green">确认为最佳答案</a>';
-            html += '    </div>';
+        if (!isBest && currentUserId == questionCreatorId && !hasBestAnswer) {
+            html += '<a href="javascript:void(0)" onclick="confirmAnswer(\'' + ans.id + '\')" style="float:right;margin-right:10px;color:#52c41a;font-size:14px;font-weight:500;">确认为最佳答案</a>';
         }
         
-        html += '  </div>';
-        html += '</div>';
+        html += '</div>';  // 闭合 .del
+        html += '<hr style="margin:15px 0;border:none;border-top:1px solid #eee;">';
+        html += '</div>';  // 闭合 .layui-item
+        
         return html;
     }
 
@@ -679,6 +710,34 @@
         });
     }
 
+    /** 删除回答 */
+    function deleteAnswer(answerId) {
+        layer.confirm('确认删除此回答吗?', {
+            icon: 3,
+            title: '删除提示'
+        }, function(index){
+            $.ajax({
+                type: 'POST',
+                url: '${ctx}/workKnowledgeBase/share/deleteAnswer',
+                data: {
+                    answerId: answerId
+                },
+                success: function(data) {
+                    if (data.success) {
+                        layer.msg('删除成功', {icon: 1});
+                        layer.close(index);
+                        loadAnswers(); // 刷新列表
+                    } else {
+                        layer.msg(data.message || '删除失败', {icon: 2});
+                    }
+                },
+                error: function() {
+                    layer.msg('请求失败,请重试', {icon: 2});
+                }
+            });
+        });
+    }
+
     // 页面加载完成后,如果是问答分类,则加载回答列表
     $(document).ready(function() {
         if (isQaCategory) {

+ 2 - 2
src/main/webapp/webpage/modules/WorkKnowledgeBase/workKnowledgeBaseShareList.jsp

@@ -698,8 +698,8 @@
                     }
                 }
                 
-                // 点赞/取消点赞按钮(仅审核通过的文件显示,问答分类不需要)
-                if (!d.isQaCategory && status === 5) {
+                // 点赞/取消点赞按钮(仅审核通过的文件显示,问答分类不需要,创建人不能给自己点赞
+                if (!d.isQaCategory && status === 5 && !isCreator) {
                     if (d.liked) {
                         xml += '<a href="javascript:void(0)" onclick="cancelLikeFile(\'' + d.id + '\')" class="layui-btn layui-btn-xs layui-bg-orange"><i class="fa fa-heart"></i> 已赞</a>';
                     } else {