Forráskód Böngészése

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

徐滕 1 napja
szülő
commit
e00357f543

+ 9 - 0
src/main/java/com/jeeplus/modules/WorkKnowledgeBase/entity/WorkKnowledgeBasePoint.java

@@ -28,6 +28,7 @@ public class WorkKnowledgeBasePoint extends DataEntity<WorkKnowledgeBasePoint> {
 	private String endDate;		// 结束日期
 	private String submitterId;	// 经办人ID(查询用)
 	private String submitterName;	// 经办人名称(查询用)
+	private String isAdmin;		//是否为管理员
 
 	/** 手机号 */
 	private String mobile;
@@ -173,4 +174,12 @@ public class WorkKnowledgeBasePoint extends DataEntity<WorkKnowledgeBasePoint> {
 	public void setTotalPoint(Integer totalPoint) {
 		this.totalPoint = totalPoint;
 	}
+
+	public String getIsAdmin() {
+		return isAdmin;
+	}
+
+	public void setIsAdmin(String isAdmin) {
+		this.isAdmin = isAdmin;
+	}
 }

+ 10 - 0
src/main/java/com/jeeplus/modules/WorkKnowledgeBase/entity/WorkKnowledgeBaseShareInfo.java

@@ -64,6 +64,8 @@ public class WorkKnowledgeBaseShareInfo extends DataEntity<WorkKnowledgeBaseShar
     private String answerId;
     /** 确认答案时间(问答答疑专用) */
     private Date confirmDate;
+    /** 问题说明(问答答疑专用,富文本) */
+    private String questionDescription;
 
     public String getTreeNodeId() {
         return treeNodeId;
@@ -232,4 +234,12 @@ public class WorkKnowledgeBaseShareInfo extends DataEntity<WorkKnowledgeBaseShar
     public void setConfirmDate(Date confirmDate) {
         this.confirmDate = confirmDate;
     }
+
+    public String getQuestionDescription() {
+        return questionDescription;
+    }
+
+    public void setQuestionDescription(String questionDescription) {
+        this.questionDescription = questionDescription;
+    }
 }

+ 23 - 15
src/main/java/com/jeeplus/modules/WorkKnowledgeBase/service/WorkKnowledgeBaseShareService.java

@@ -776,22 +776,30 @@ public class WorkKnowledgeBaseShareService extends CrudService<WorkKnowledgeBase
         
         // 4. 给问题发起人发放积分(使用固定分值)
         WorkKnowledgeBaseShareInfo question = dao.get(questionId);
-        if (question != null && StringUtils.isNotBlank(question.getSubmitAuditUserId())) {
-            if (questionRule != null && StringUtils.isNotBlank(questionRule.getPointValue())) {
-                try {
-                    Integer questionPoint = Integer.parseInt(questionRule.getPointValue());
-                    if (questionPoint > 0) {
-                        insertPointDetail(
-                            question.getSubmitAuditUserId(),  // 问题发起人ID
-                            questionId,                        // 问题ID
-                            POINT_CHANGE_CREATE,              // 变动类型:创建加分
-                            categoryId,                       // 分类ID
-                            questionRule.getId(),             // 规则ID
-                            questionPoint                     // 积分值
-                        );
+        if (question != null) {
+            // 优先使用submitAuditUserId,如果为空则使用创建人ID
+            String questionCreatorId = question.getSubmitAuditUserId();
+            if (StringUtils.isBlank(questionCreatorId) && question.getCreateBy() != null) {
+                questionCreatorId = question.getCreateBy().getId();
+            }
+            
+            if (StringUtils.isNotBlank(questionCreatorId)) {
+                if (questionRule != null && StringUtils.isNotBlank(questionRule.getPointValue())) {
+                    try {
+                        Integer questionPoint = Integer.parseInt(questionRule.getPointValue());
+                        if (questionPoint > 0) {
+                            insertPointDetail(
+                                questionCreatorId,                     // 问题发起人ID
+                                questionId,                            // 问题ID
+                                POINT_CHANGE_CREATE,                   // 变动类型:创建加分
+                                categoryId,                            // 分类ID
+                                questionRule.getId(),                  // 规则ID
+                                questionPoint                          // 积分值
+                            );
+                        }
+                    } catch (NumberFormatException e) {
+                        // 积分值格式错误,跳过
                     }
-                } catch (NumberFormatException e) {
-                    // 积分值格式错误,跳过
                 }
             }
         }

+ 15 - 0
src/main/java/com/jeeplus/modules/WorkKnowledgeBase/web/WorkKnowledgeBasePointController.java

@@ -11,9 +11,13 @@ import com.jeeplus.modules.WorkKnowledgeBase.entity.UserPointDetail;
 import com.jeeplus.modules.WorkKnowledgeBase.entity.WorkKnowledgeBasePoint;
 import com.jeeplus.modules.WorkKnowledgeBase.service.WorkKnowledgeBasePointDetailService;
 import com.jeeplus.modules.WorkKnowledgeBase.service.WorkKnowledgeBasePointService;
+import com.jeeplus.modules.sys.entity.User;
 import com.jeeplus.modules.sys.service.OfficeService;
+import com.jeeplus.modules.sys.utils.UserUtils;
+import org.apache.shiro.SecurityUtils;
 import org.apache.shiro.authz.annotation.Logical;
 import org.apache.shiro.authz.annotation.RequiresPermissions;
+import org.apache.shiro.subject.Subject;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Controller;
 import org.springframework.ui.Model;
@@ -85,6 +89,17 @@ public class WorkKnowledgeBasePointController extends BaseController {
             }
         }
 
+        User user = UserUtils.getUser();
+        Subject subject = SecurityUtils.getSubject();
+        if(user.isAdmin()  || subject.isPermitted("workKnowledgeBase:point:listAll")){
+            workKnowledgeBasePoint.setIsAdmin("admin");
+        }else{
+            workKnowledgeBasePoint.setIsAdmin("user");
+            // 普通用户只能查看自己的积分,设置当前用户ID
+            workKnowledgeBasePoint.setUserId(user.getId());
+        }
+
+
         Page<WorkKnowledgeBasePoint> page = workKnowledgeBasePointDetailService.findUserPointSummaryPage(new Page<>(request, response), workKnowledgeBasePoint);
         model.addAttribute("page", page);
         model.addAttribute("workKnowledgeBasePoint", workKnowledgeBasePoint);

+ 14 - 1
src/main/java/com/jeeplus/modules/WorkKnowledgeBase/web/WorkKnowledgeBaseShareController.java

@@ -164,7 +164,8 @@ public class WorkKnowledgeBaseShareController extends BaseController {
      */
     @RequiresPermissions(value = {"workKnowledgeBase:share:view", "workKnowledgeBase:share:edit"}, logical = org.apache.shiro.authz.annotation.Logical.OR)
     @RequestMapping(value = "detail")
-    public String detail(WorkKnowledgeBaseShareInfo shareInfo, Model model) {
+    public String detail(@RequestParam(required = false) Boolean readOnly,
+                        WorkKnowledgeBaseShareInfo shareInfo, Model model) {
         String rootId = shareInfo.getRootId();
         String treeNodeId = shareInfo.getTreeNodeId();
 
@@ -200,6 +201,8 @@ public class WorkKnowledgeBaseShareController extends BaseController {
         model.addAttribute("dynamicFields", dynamicFields);
         model.addAttribute("rootId", rootId);
         model.addAttribute("dynValues", dynValues);
+        // 传递只读标识
+        model.addAttribute("readOnly", readOnly != null && readOnly);
 
         // 获取阅读量和点赞量
         if (StringUtils.isNotBlank(shareInfo.getId())) {
@@ -284,10 +287,20 @@ public class WorkKnowledgeBaseShareController extends BaseController {
             shareInfo.setWorkAttachments(shareService.findAttachmentsByFileId(shareInfo.getId()));
         }
 
+        // 判断是否为问答答疑分类
+        boolean isQaCategory = false;
+        if (StringUtils.isNotBlank(treeNodeId)) {
+            WorkKnowledgeBaseTreeInfo treeInfo = shareService.getTreeInfoById(treeNodeId);
+            if (treeInfo != null && "问答答疑".equals(treeInfo.getTreeName())) {
+                isQaCategory = true;
+            }
+        }
+
         model.addAttribute("entity", shareInfo);
         model.addAttribute("dynamicFields", dynamicFields);
         model.addAttribute("rootId", rootId);
         model.addAttribute("dynValues", dynValues);
+        model.addAttribute("isQaCategory", isQaCategory);
         return "modules/WorkKnowledgeBase/workKnowledgeBaseShareForm";
     }
 

+ 35 - 5
src/main/resources/mappings/modules/WorkKnowledgeBase/WorkKnowledgeBasePointDetailDao.xml

@@ -105,11 +105,22 @@
             o.name      AS "officeName",
             COALESCE(SUM(d.point), 0) AS "totalPoint"
         FROM sys_user u
-        INNER JOIN work_knowledge_base_point_detail d ON d.user_id = u.id AND d.del_flag = '0'
+        LEFT JOIN work_knowledge_base_point_detail d ON d.user_id = u.id AND d.del_flag = '0'
         LEFT JOIN sys_office o ON o.id = u.office_id
         <where>
             u.del_flag = '0'
-            <if test="userId != null and userId != ''">
+            <!-- 管理员权限:默认只查看有积分记录的用户 -->
+            <if test="isAdmin != null and isAdmin == 'admin'">
+                AND d.id IS NOT NULL
+            </if>
+            <!-- 普通用户权限:只能查看自己(包括积分为0的情况) -->
+            <if test="isAdmin == null or isAdmin == 'user'">
+                <if test="userId != null and userId != ''">
+                    AND u.id = #{userId}
+                </if>
+            </if>
+            <!-- 如果指定了userId查询条件(精确查询),优先使用 -->
+            <if test="userId != null and userId != '' and (isAdmin == null or isAdmin == 'user')">
                 AND u.id = #{userId}
             </if>
             <if test="userName != null and userName != ''">
@@ -126,12 +137,16 @@
             </if>
         </where>
         GROUP BY u.id, u.name, u.mobile, u.phone, o.name
+        <!-- 管理员模式下,过滤掉积分为0的记录 -->
+        <if test="isAdmin != null and isAdmin == 'admin'">
+            HAVING totalPoint > 0
+        </if>
         <choose>
             <when test="page !=null and page.orderBy != null and page.orderBy != ''">
                 ORDER BY ${page.orderBy}
             </when>
             <otherwise>
-                ORDER BY d.create_date DESC
+                ORDER BY MAX(d.create_date) DESC
             </otherwise>
         </choose>
     </select>
@@ -140,11 +155,22 @@
         SELECT COUNT(1) FROM (
             SELECT u.id
             FROM sys_user u
-            INNER JOIN work_knowledge_base_point_detail d ON d.user_id = u.id AND d.del_flag = '0'
+            LEFT JOIN work_knowledge_base_point_detail d ON d.user_id = u.id AND d.del_flag = '0'
             LEFT JOIN sys_office o ON o.id = u.office_id
             <where>
                 u.del_flag = '0'
-                <if test="userId != null and userId != ''">
+                <!-- 管理员权限:默认只查看有积分记录的用户 -->
+                <if test="isAdmin != null and isAdmin == 'admin'">
+                    AND d.id IS NOT NULL
+                </if>
+                <!-- 普通用户权限:只能查看自己(包括积分为0的情况) -->
+                <if test="isAdmin == null or isAdmin == 'user'">
+                    <if test="userId != null and userId != ''">
+                        AND u.id = #{userId}
+                    </if>
+                </if>
+                <!-- 如果指定了userId查询条件(精确查询),优先使用 -->
+                <if test="userId != null and userId != '' and (isAdmin == null or isAdmin == 'user')">
                     AND u.id = #{userId}
                 </if>
                 <if test="userName != null and userName != ''">
@@ -162,6 +188,10 @@
                 </if>
             </where>
             GROUP BY u.id
+            <!-- 管理员模式下,过滤掉积分为0的记录 -->
+            <if test="isAdmin != null and isAdmin == 'admin'">
+                HAVING COALESCE(SUM(d.point), 0) > 0
+            </if>
         ) t
     </select>
 

+ 14 - 4
src/main/resources/mappings/modules/WorkKnowledgeBase/WorkKnowledgeBaseShareInfoDao.xml

@@ -20,6 +20,9 @@
         a.submit_audit_user_id AS "submitAuditUserId",
         a.audit_start_date AS "auditStartDate",
         a.content_attribute AS "contentAttribute",
+        a.answer_id        AS "answerId",
+        a.confirm_date     AS "confirmDate",
+        a.question_description AS "questionDescription",
         a.del_flag         AS "delFlag"
     </sql>
 
@@ -81,6 +84,9 @@
             a.audit_reject_count                                  AS "auditRejectCount",
             a.audit_start_date                                    AS "auditStartDate",
             a.content_attribute AS "contentAttribute",
+            a.answer_id                                           AS "answerId",
+            a.confirm_date                                        AS "confirmDate",
+            a.question_description                                AS "questionDescription",
             su.name                                               AS "createBy.name"
             <!-- 动态列:CASE WHEN + MAX + GROUP BY -->
             <if test="dynamicFields != null and dynamicFields.size() > 0">
@@ -139,7 +145,8 @@
             </if>
         </where>
         GROUP BY a.id, a.tree_node_id, a.file_name, a.file_url, a.name, a.create_time,
-                 a.create_by, a.create_date, a.remarks, a.audit_status, a.audit_pass_count, a.audit_reject_count, a.submit_audit_user_id, a.audit_start_date
+                 a.create_by, a.create_date, a.remarks, a.audit_status, a.audit_pass_count, a.audit_reject_count, a.submit_audit_user_id, a.audit_start_date,
+                 a.content_attribute, a.answer_id, a.confirm_date, a.question_description
         ORDER BY a.update_date DESC
         <if test="offset != null and limit != null">
             LIMIT #{offset}, #{limit}
@@ -232,11 +239,13 @@
         INSERT INTO work_knowledge_base_share_info (
             id, tree_node_id, file_name, file_url, name, create_time,content_attribute,
             create_by, create_date, update_by, update_date, remarks,
-            audit_status, audit_pass_count, audit_reject_count, submit_audit_user_id, audit_start_date, del_flag
+            audit_status, audit_pass_count, audit_reject_count, submit_audit_user_id, audit_start_date,
+            answer_id, confirm_date, question_description, del_flag
         ) VALUES (
             #{id}, #{treeNodeId}, #{fileName}, #{fileUrl}, #{name}, NOW(),#{contentAttribute},
             #{createBy.id}, #{createDate}, #{updateBy.id}, #{updateDate}, #{remarks},
-            #{auditStatus}, #{auditPassCount}, #{auditRejectCount}, #{submitAuditUserId}, #{auditStartDate}, #{delFlag}
+            #{auditStatus}, #{auditPassCount}, #{auditRejectCount}, #{submitAuditUserId}, #{auditStartDate},
+            #{answerId}, #{confirmDate}, #{questionDescription}, #{delFlag}
         )
     </insert>
 
@@ -256,7 +265,8 @@
             content_attribute = #{contentAttribute},
             audit_start_date   = #{auditStartDate},
             answer_id          = #{answerId},
-            confirm_date       = #{confirmDate}
+            confirm_date       = #{confirmDate},
+            question_description = #{questionDescription}
         WHERE id = #{id}
     </update>
 

+ 36 - 7
src/main/webapp/webpage/modules/WorkKnowledgeBase/workKnowledgeBaseShareDetail.jsp

@@ -184,7 +184,14 @@
         <form:form id="inputForm" modelAttribute="entity" action="" method="post" class="layui-form">
         <div class="form-group layui-row">
             <div class="form-group-label">
-                <h2 style="display:inline-block;">知识库文件信息</h2>
+                <c:choose>
+                    <c:when test="${isQaCategory}">
+                        <h2 style="display:inline-block;">问答答疑信息</h2>
+                    </c:when>
+                    <c:otherwise>
+                        <h2 style="display:inline-block;">知识库文件信息</h2>
+                    </c:otherwise>
+                </c:choose>
                 <span style="float:right; margin-right:10px; font-size:14px; color:#666;">
                     <a href="javascript:void(0)" onclick="showReadDetail('${entity.id}')" 
                        style="color:#1e9fff; text-decoration:none; margin-right:20px;">
@@ -197,9 +204,14 @@
                 </span>
             </div>
 
-            <!-- 文件名称 -->
+            <!-- 文件名称/问题概述 -->
             <div class="layui-item layui-col-sm6 lw6">
-                <label class="layui-form-label detail-label">文件名称:</label>
+                <label class="layui-form-label detail-label">
+                    <c:choose>
+                        <c:when test="${isQaCategory}">问题概述:</c:when>
+                        <c:otherwise>文件名称:</c:otherwise>
+                    </c:choose>
+                </label>
                 <div class="layui-input-block">
                     <input type="text" class="form-control layui-input" value="${entity.name}" readonly="readonly"/>
                 </div>
@@ -244,6 +256,20 @@
                 </div>
             </div>
             </c:if>
+
+
+            <!-- 说明(富文本,所有类型通用) -->
+            <div class="layui-item layui-col-sm12 lw6" style="padding-bottom: 20px;">
+                <label class="layui-form-label detail-label">说明:</label>
+                <div class="layui-input-block">
+                    <div class="wrapForm">
+                        <div class="mask">
+                            <form:textarea path="questionDescription" disabled="true" htmlEscape="false" colspan="3" rows="6" class="form-control"/>
+                            <sys:ckeditorView replace="questionDescription" uploadPath="/workKnowledgeBase/share"/>
+                        </div>
+                    </div>
+                </div>
+            </div>
         </div>
 
         <!-- 审核状态 -->
@@ -454,7 +480,8 @@
 <c:if test="${isQaCategory}">
 <div class="single-form" style="margin-top:10px;">
     <div class="container">
-        <!-- 提交回答区域 -->
+        <!-- 提交回答区域(只读模式不显示) -->
+        <c:if test="${!readOnly}">
         <div class="form-group layui-row">
             <div class="form-group-label"><h2>发表回答</h2></div>
             <div class="layui-item layui-col-xs12 with-textarea">
@@ -468,6 +495,7 @@
                 </div>
             </div>
         </div>
+        </c:if>
 
         <!-- 回答列表区域 -->
         <div class="form-group layui-row">
@@ -483,6 +511,7 @@
 <script>
     // 问答相关变量
     var isQaCategory = ${isQaCategory != null ? isQaCategory : false};
+    var readOnly = ${readOnly != null ? readOnly : false};
     var questionId = '${entity.id}';
     var currentUserId = '${fns:getUser().id}';
     var questionCreatorId = '${entity.createBy.id}';
@@ -630,12 +659,12 @@
         html += '<span>' + (ans.createDate || '') + '</span>';
         
         // 删除按钮(仅回答人可看到,最佳答案不能删除)
-        if (!isBest && canDelete) {
+        if (!isBest && canDelete && !readOnly) {
             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 && !hasBestAnswer) {
+        // 确认按钮(仅发起人且未确认答案时显示,只读模式不显示
+        if (!isBest && currentUserId == questionCreatorId && !hasBestAnswer && !readOnly) {
             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>';
         }
         

+ 46 - 13
src/main/webapp/webpage/modules/WorkKnowledgeBase/workKnowledgeBaseShareForm.jsp

@@ -120,22 +120,55 @@
             <input type="hidden" id="dynamicValuesJson" name="dynamicValuesJson"/>
 
             <div class="form-group layui-row">
-                <div class="form-group-label"><h2>知识库文件信息</h2></div>
+                <c:choose>
+                    <c:when test="${isQaCategory}">
+                        <div class="form-group-label"><h2>问答答疑信息</h2></div>
 
-                <!-- 文件名(必填) -->
-                <div class="layui-item layui-col-sm6 lw6">
-                    <label class="layui-form-label"><span class="require-item">*</span>文件名称:</label>
-                    <div class="layui-input-block">
-                        <form:input path="name" placeholder="请输入文件名称" htmlEscape="false"
-                                    maxlength="200" class="form-control layui-input required"/>
-                    </div>
-                </div>
+                        <!-- 问题概述(必填) -->
+                        <div class="layui-item layui-col-sm6 lw6">
+                            <label class="layui-form-label"><span class="require-item">*</span>问题概述:</label>
+                            <div class="layui-input-block">
+                                <form:input path="name" placeholder="请输入问题概述" htmlEscape="false"
+                                            maxlength="200" class="form-control layui-input required"/>
+                            </div>
+                        </div>
+
+                        <div class="layui-item layui-col-sm6 lw6">
+                            <label class="layui-form-label"><span class="require-item">*</span>内容属性:</label>
+                            <div class="layui-input-block">
+                                <input type="radio" name="contentAttribute" lay-filter="contentAttributeRadio" title="原创" value="0" class="required">
+                                <input type="radio" name="contentAttribute" lay-filter="contentAttributeRadio" title="转载" value="1" class="required">
+                            </div>
+                        </div>
+                    </c:when>
+                    <c:otherwise>
+                        <div class="form-group-label"><h2>知识库文件信息</h2></div>
+
+                        <!-- 文件名称(必填) -->
+                        <div class="layui-item layui-col-sm6 lw6">
+                            <label class="layui-form-label"><span class="require-item">*</span>文件名称:</label>
+                            <div class="layui-input-block">
+                                <form:input path="name" placeholder="请输入文件名称" htmlEscape="false"
+                                            maxlength="200" class="form-control layui-input required"/>
+                            </div>
+                        </div>
+
+                        <div class="layui-item layui-col-sm6 lw6">
+                            <label class="layui-form-label"><span class="require-item">*</span>内容属性:</label>
+                            <div class="layui-input-block">
+                                <input type="radio" name="contentAttribute" lay-filter="contentAttributeRadio" title="原创" value="0" class="required">
+                                <input type="radio" name="contentAttribute" lay-filter="contentAttributeRadio" title="转载" value="1" class="required">
+                            </div>
+                        </div>
+                    </c:otherwise>
+                </c:choose>
 
-                <div class="layui-item layui-col-sm6 lw6">
-                    <label class="layui-form-label"><span class="require-item">*</span>内容属性:</label>
+                <!-- 说明(富文本,非必填) -->
+                <div class="layui-item layui-col-sm12" style="padding-bottom: 20px;">
+                    <label class="layui-form-label">说明:</label>
                     <div class="layui-input-block">
-                        <input type="radio" name="contentAttribute" lay-filter="contentAttributeRadio" title="原创" value="0" class="required">
-                        <input type="radio" name="contentAttribute" lay-filter="contentAttributeRadio" title="转载" value="1" class="required">
+                        <form:textarea path="questionDescription" htmlEscape="false" colspan="3" rows="6" maxlength="5000" class="form-control"/>
+                        <sys:ckeditor replace="questionDescription" uploadPath="/workKnowledgeBase/share"/>
                     </div>
                 </div>
             </div>

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

@@ -85,6 +85,19 @@
             });
         }
         
+        /** 查看问答答疑详情(只读模式) */
+        function openQaDetailDialog(id) {
+            top.layer.open({
+                type: 2,
+                area: ['80%', '80%'],
+                title: '问答详情',
+                maxmin: true,
+                content: '${ctx}/workKnowledgeBase/share/detail?readOnly=true&id=' + id + '&treeNodeId=${treeNodeId}&rootId=${rootId}',
+                btn: ['关闭'],
+                btn1: function(index) { top.layer.close(index); }
+            });
+        }
+        
         /** 查看详情(带阅读记录) */
         function openDetailDialogWithRead(id) {
             // 先记录阅读行为
@@ -107,6 +120,28 @@
             });
         }
         
+        /** 查看问答答疑详情(只读模式,带阅读记录) */
+        function openQaDetailDialogWithRead(id) {
+            // 先记录阅读行为
+            $.ajax({
+                type: 'POST',
+                url: '${ctx}/workKnowledgeBase/readLike/recordRead',
+                data: { fileId: id },
+                success: function(result) {
+                    // 打开只读模式的详情弹窗
+                    openQaDetailDialog(id);
+                    // 刷新列表,更新阅读量
+                    setTimeout(function() {
+                        search();
+                    }, 500);
+                },
+                error: function() {
+                    // 即使记录失败也打开详情
+                    openQaDetailDialog(id);
+                }
+            });
+        }
+        
         /** 预览文件(带阅读记录) */
         function openPreviewWithRead(url, type, fileId) {
             // 先记录阅读行为
@@ -580,7 +615,12 @@
         var cols = [
             {field: 'index', align: 'center', width: 50, title: '序号'},
             {field: 'name', align: 'center', title: '文件名称', minWidth: 200, templet: function(d) {
-                return '<a href="javascript:void(0)" class="attention-info" onclick="openDetailDialogWithRead(\'' + d.id + '\')">' + (d.name || '') + '</a>';
+                // 问答答疑分类使用只读模式,其他分类使用普通模式
+                if (d.isQaCategory) {
+                    return '<a href="javascript:void(0)" class="attention-info" onclick="openQaDetailDialogWithRead(\'' + d.id + '\')">' + (d.name || '') + '</a>';
+                } else {
+                    return '<a href="javascript:void(0)" class="attention-info" onclick="openDetailDialogWithRead(\'' + d.id + '\')">' + (d.name || '') + '</a>';
+                }
             }},
             {field: 'fileUrl', align: 'center', title: '文件地址', minWidth: 200, templet: function(d) {
                 if(2 == d.uploadMode){