Jelajahi Sumber

fix(article): 已撤回文章支持重新编辑流程(状态机+前台按钮)

- ArticleService.reDraft(): 允许 withdrawn → draft(原仅 rejected),对齐 ActivityAdminService 既有先例
- AdminArticleController.update(): 放开 withdrawn 编辑限制(原仅 draft/published)
- ArticleManage.vue: 已撤回行下拉菜单新增「重新编辑」操作
- ArticleEdit.vue: 编辑页标题模板扩展匹配 withdrawn(显示「保存到草稿箱重新编辑」)
- getUpdatedSince(): status 缺省时默认 published,堵住 RAG 增量接口内容泄漏
- generateQuiz(): 增加 status=published 检查,禁止对撤回文章生成 AI 题目
Xiaogang Liao 1 Minggu lalu
induk
melakukan
b959ca4eb7

+ 3 - 2
cfc-backend/src/main/java/com/etotem/cfc/controller/admin/AdminArticleController.java

@@ -174,8 +174,9 @@ public class AdminArticleController {
         if (articleId != null) {
             Article existing = articleService.getById(articleId);
             if (existing != null && !"draft".equals(existing.getStatus())
-                    && !"published".equals(existing.getStatus())) {
-                return Result.error("仅草稿或已上架状态可编辑");
+                    && !"published".equals(existing.getStatus())
+                    && !"withdrawn".equals(existing.getStatus())) {
+                return Result.error("仅草稿、已上架或已撤回状态可编辑");
             }
         }
         Article article = new Article();

+ 1 - 1
cfc-backend/src/main/java/com/etotem/cfc/controller/content/ArticleCommentController.java

@@ -109,7 +109,7 @@ public class ArticleCommentController {
         Long articleId = ParamUtils.getLong(params.get("articleId"));
         Long memberId = ParamUtils.getLong(params.get("memberId"), currentMemberId);
         Article article = articleMapper.selectById(articleId);
-        if (article == null) return Result.error("文章不存在");
+        if (article == null || !"published".equals(article.getStatus())) return Result.error("文章不存在");
 
         String content = article.getContent();
         if (content != null && content.length() > 2000) content = content.substring(0, 2000);

+ 4 - 5
cfc-backend/src/main/java/com/etotem/cfc/service/ArticleService.java

@@ -988,9 +988,8 @@ public class ArticleService {
         LambdaQueryWrapper<Article> wrapper = new LambdaQueryWrapper<Article>()
                 .ge(Article::getUpdatedAt, since)
                 .orderByDesc(Article::getUpdatedAt);
-        if (status != null && !status.trim().isEmpty()) {
-            wrapper.eq(Article::getStatus, status.trim());
-        }
+        String s = (status != null && !status.trim().isEmpty()) ? status.trim() : "published";
+        wrapper.eq(Article::getStatus, s);
         return articleMapper.selectList(wrapper);
     }
 
@@ -1146,8 +1145,8 @@ public class ArticleService {
         if (article == null) {
             throw new RuntimeException("文章不存在");
         }
-        if (!"rejected".equals(article.getStatus())) {
-            throw new RuntimeException("仅已驳回的文章可重新编辑");
+        if (!"rejected".equals(article.getStatus()) && !"withdrawn".equals(article.getStatus())) {
+            throw new RuntimeException("仅已驳回或已撤回的文章可重新编辑");
         }
         article.setStatus("draft");
         article.setAuditStatus(null);

+ 1 - 1
cfc-web/src/views/admin/ArticleEdit.vue

@@ -10,7 +10,7 @@
             <el-button type="success" @click="handleSubmitReview" :loading="reviewLoading" v-if="isEdit && articleStatus === 'draft' && !articleWasPublished">提交审核</el-button>
             <el-button type="success" @click="handleSave(true)" :loading="publishing" v-if="!isEdit || articleStatus === 'draft'">直接发布</el-button>
           </template>
-          <template v-if="articleStatus === 'rejected'">
+          <template v-if="articleStatus === 'rejected' || articleStatus === 'withdrawn'">
             <el-button type="primary" @click="handleReDraft" :loading="reDraftLoading">保存到草稿箱重新编辑</el-button>
           </template>
           <template v-if="readonly && articleStatus !== 'rejected'">

+ 2 - 1
cfc-web/src/views/admin/ArticleManage.vue

@@ -224,7 +224,7 @@
                 </el-dropdown-menu>
               </el-dropdown>
             </template>
-            <!-- 已撤回:查看 + 重新发布 -->
+            <!-- 已撤回:查看 + 重新发布 + 重新编辑 -->
             <template v-else-if="row.status === 'withdrawn'">
               <el-button size="mini" type="primary" @click="$router.push('/article-edit?id=' + row.id + '&readonly=1')">查看</el-button>
               <el-button size="mini" @click="openReadRecords(row)">阅读记录</el-button>
@@ -234,6 +234,7 @@
                 </el-button>
                 <el-dropdown-menu slot="dropdown">
                   <el-dropdown-item command="rePublish" icon="el-icon-s-promotion">重新发布</el-dropdown-item>
+                  <el-dropdown-item command="reDraft" icon="el-icon-edit-outline">重新编辑</el-dropdown-item>
                   <el-dropdown-item command="copy" icon="el-icon-document-copy">复制</el-dropdown-item>
                 </el-dropdown-menu>
               </el-dropdown>