浏览代码

feat(task): 支持任务打回和重新提交

- 我的任务列表增加"已打回"状态Tab
- 任务详情页支持查看打回原因和重新提交
- 提交页显示打回/拒绝原因提示
- 已拒绝/已打回的任务可重新提交
- 多语言支持(zh/en/vi)
urbanu 1 月之前
父节点
当前提交
ae7f2ca70a
共有 6 个文件被更改,包括 111 次插入15 次删除
  1. 5 2
      src/locales/en.json
  2. 5 2
      src/locales/vi.json
  3. 5 2
      src/locales/zh.json
  4. 13 6
      src/views/my-task/index.vue
  5. 55 3
      src/views/task/detail.vue
  6. 28 0
      src/views/task/submit.vue

+ 5 - 2
src/locales/en.json

@@ -202,7 +202,9 @@
     "guideStep2": "Click \"Claim Task\" to start the task",
     "guideStep3": "Follow the task steps, take screenshots as proof",
     "guideStep4": "Upload screenshots and submit for review",
-    "guideStep5": "Rewards will be credited after approval"
+    "guideStep5": "Rewards will be credited after approval",
+    "viewReturnReason": "View Return Reason",
+    "reSubmit": "Re-Submit"
   },
   "taskStatus": {
     "all": "All",
@@ -210,7 +212,8 @@
     "pendingReview": "Pending Review",
     "completed": "Completed",
     "rejected": "Rejected",
-    "abandoned": "Abandoned"
+    "abandoned": "Abandoned",
+    "returnBack": "Returned"
   },
   "material": {
     "materialCenter": "Material Center",

+ 5 - 2
src/locales/vi.json

@@ -179,7 +179,9 @@
     "guideStep2": "Nhấn \"Nhận nhiệm vụ\" để bắt đầu",
     "guideStep3": "Hoàn thành các bước và chụp ảnh màn hình làm bằng chứng",
     "guideStep4": "Tải ảnh chụp lên và gửi xét duyệt",
-    "guideStep5": "Phần thưởng sẽ được cộng sau khi duyệt thành công"
+    "guideStep5": "Phần thưởng sẽ được cộng sau khi duyệt thành công",
+    "viewReturnReason": "Xem lý do trả lại",
+    "reSubmit": "Gửi lại"
   },
   "taskStatus": {
     "all": "Tất cả",
@@ -187,7 +189,8 @@
     "pendingReview": "Chờ duyệt",
     "completed": "Hoàn thành",
     "rejected": "Từ chối",
-    "abandoned": "Đã từ bỏ"
+    "abandoned": "Đã từ bỏ",
+    "returnBack": "Đã trả lại"
   },
   "material": {
     "materialCenter": "Trung tâm tài liệu",

+ 5 - 2
src/locales/zh.json

@@ -202,7 +202,9 @@
     "guideStep2": "点击【领取任务】按钮,开始执行任务",
     "guideStep3": "按照任务步骤完成操作,并截图保存凭证",
     "guideStep4": "上传截图提交审核,等待平台审核通过",
-    "guideStep5": "审核通过后奖励将自动发放到您的账户"
+    "guideStep5": "审核通过后奖励将自动发放到您的账户",
+    "viewReturnReason": "查看打回原因",
+    "reSubmit": "重新提交"
   },
   "taskStatus": {
     "all": "全部",
@@ -210,7 +212,8 @@
     "pendingReview": "待审核",
     "completed": "已完成",
     "rejected": "已驳回",
-    "abandoned": "已放弃"
+    "abandoned": "已放弃",
+    "returnBack": "已打回"
   },
   "material": {
     "materialCenter": "素材中心",

+ 13 - 6
src/views/my-task/index.vue

@@ -74,23 +74,25 @@ const refreshing = ref(false);
 const page = ref(1);
 const pageSize = 10;
 
-// 后端状态: -2=已放弃 -1=审核失败 0=进行中 1=待审核 2=已完成
+// 后端状态: -2=已放弃 -1=审核失败 0=进行中 1=待审核 2=已完成 5=已打回
 const statusTabs = computed(() => [
   { label: t('taskStatus.all'), value: -99 },
   { label: t('taskStatus.inProgress'), value: 0 },
   { label: t('taskStatus.pendingReview'), value: 1 },
   { label: t('taskStatus.completed'), value: 2 },
+  { label: t('taskStatus.returnBack'), value: 5 },
   { label: t('taskStatus.rejected'), value: -1 }
 ]);
 
-// 后端状态: -2=已放弃 -1=审核失败 0=进行中 1=待审核 2=已完成
+// 后端状态: -2=已放弃 -1=审核失败 0=进行中 1=待审核 2=已完成 5=已打回
 const getStatusClass = (s: number) => {
   const map: Record<number, string> = {
     [-2]: 'abandoned',
     [-1]: 'rejected',
     0: 'in-progress',
     1: 'pending',
-    2: 'completed'
+    2: 'completed',
+    5: 'return-back'
   };
   return map[s] || '';
 };
@@ -101,7 +103,8 @@ const getStatusText = (s: number) => {
     [-1]: t('taskStatus.rejected'),
     0: t('taskStatus.inProgress'),
     1: t('taskStatus.pendingReview'),
-    2: t('taskStatus.completed')
+    2: t('taskStatus.completed'),
+    5: t('taskStatus.returnBack')
   };
   return map[s] || '';
 };
@@ -179,8 +182,8 @@ const goBack = () => {
 };
 
 const goDetail = (item: TaskApplyInfo) => {
-  if (item.status === 0) {
-    // 进行中(status=0) - 跳转提交页
+  if (item.status === 0 || item.status === 5 || item.status === 3 || item.status === -1) {
+    // 进行中(0)、已拒绝(3/-1)或已打回(5) - 跳转提交页
     router.push(`/task/submit/${item.id}`);
   } else {
     // 其他状态 - 跳转详情页
@@ -319,6 +322,10 @@ onMounted(() => {
           background: rgba(158, 158, 158, 0.2);
           color: #9e9e9e;
         }
+        &.return-back {
+          background: rgba(255, 152, 0, 0.2);
+          color: #ff9800;
+        }
       }
     }
 

+ 55 - 3
src/views/task/detail.vue

@@ -194,7 +194,7 @@
         {{ $t('task.completed') }}
       </van-button>
 
-      <!-- 已驳回 -->
+      <!-- 已驳回 - 可重新提交 -->
       <div v-else-if="applyInfo?.status === 3" class="reject-actions">
         <van-button
           type="warning"
@@ -208,9 +208,29 @@
           type="primary"
           block
           round
-          @click="handleReClaim"
+          @click="goReSubmit"
         >
-          {{ $t('task.reClaim') }}
+          {{ $t('task.reSubmit') }}
+        </van-button>
+      </div>
+
+      <!-- 已打回 - 可重新提交 -->
+      <div v-else-if="applyInfo?.status === 5" class="return-back-actions">
+        <van-button
+          type="warning"
+          block
+          round
+          @click="showReturnBackReason"
+        >
+          {{ $t('task.viewReturnReason') }}
+        </van-button>
+        <van-button
+          type="primary"
+          block
+          round
+          @click="goReSubmit"
+        >
+          {{ $t('task.reSubmit') }}
         </van-button>
       </div>
     </div>
@@ -227,6 +247,18 @@
       </div>
     </van-dialog>
 
+    <!-- 打回原因弹窗 -->
+    <van-dialog
+      v-model:show="showReturnBack"
+      :title="$t('task.viewReturnReason')"
+      :show-cancel-button="false"
+      :confirm-button-text="$t('common.confirm')"
+    >
+      <div class="reject-content">
+        {{ applyInfo?.rejectReason || $t('task.noReasonProvided') }}
+      </div>
+    </van-dialog>
+
     <!-- 新手说明弹窗 -->
     <van-popup
       v-model:show="showGuide"
@@ -267,6 +299,7 @@ const exampleList = ref<any[]>([]);
 const applyInfo = ref<any>(null);
 const claiming = ref(false);
 const showReject = ref(false);
+const showReturnBack = ref(false);
 const showGuide = ref(false);
 const activeTab = ref<'steps' | 'intro' | 'examples'>('intro');
 
@@ -360,6 +393,16 @@ const showRejectReason = () => {
   showReject.value = true;
 };
 
+const showReturnBackReason = () => {
+  showReturnBack.value = true;
+};
+
+const goReSubmit = () => {
+  if (applyInfo.value) {
+    router.push(`/task/submit/${applyInfo.value.id}`);
+  }
+};
+
 const previewStepImage = (image: string) => {
   showImagePreview({
     images: [image],
@@ -872,6 +915,15 @@ onMounted(() => {
       flex: 1;
     }
   }
+
+  .return-back-actions {
+    display: flex;
+    gap: min(3.2vw, 15.36px);
+
+    .van-button {
+      flex: 1;
+    }
+  }
 }
 
 .reject-content {

+ 28 - 0
src/views/task/submit.vue

@@ -7,6 +7,12 @@
       <span></span>
     </div>
 
+    <!-- 打回/拒绝原因提示 -->
+    <div class="return-back-tips" v-if="(applyInfo?.status === 5 || applyInfo?.status === 3 || applyInfo?.status === -1) && (applyInfo?.rejectReason || applyInfo?.auditRemark)">
+      <div class="tips-title">⚠️ {{ applyInfo?.status === 5 ? '打回原因' : '拒绝原因' }}</div>
+      <div class="tips-content">{{ applyInfo.rejectReason || applyInfo.auditRemark }}</div>
+    </div>
+
     <!-- 温馨提示 -->
     <div class="warning-tips">
       温馨提示!请按任务需求提交相对应截图提交审核,否则一律审核不通过!
@@ -133,6 +139,7 @@ const getStatusText = (status: number | undefined) => {
     0: '未完成',
     1: '待审核',
     2: '已完成',
+    5: '已打回',
     [-1]: '审核失败',
     [-2]: '已放弃'
   };
@@ -292,6 +299,27 @@ onMounted(() => {
   }
 }
 
+.return-back-tips {
+  margin: 0 16px 16px;
+  padding: 12px;
+  background: rgba(255, 152, 0, 0.15);
+  border: 1px solid rgba(255, 152, 0, 0.3);
+  border-radius: 8px;
+
+  .tips-title {
+    font-size: 14px;
+    font-weight: 600;
+    color: #ff9800;
+    margin-bottom: 8px;
+  }
+
+  .tips-content {
+    font-size: 13px;
+    color: rgba(255, 255, 255, 0.85);
+    line-height: 1.5;
+  }
+}
+
 .warning-tips {
   margin: 0 16px 16px;
   padding: 12px;