Browse Source

任务详情页UI优化

urbanu 1 month ago
parent
commit
951dba47b9
5 changed files with 184 additions and 68 deletions
  1. 7 1
      src/locales/en.json
  2. 9 1
      src/locales/id.json
  3. 9 1
      src/locales/vi.json
  4. 7 1
      src/locales/zh.json
  5. 152 64
      src/views/task/detail.vue

+ 7 - 1
src/locales/en.json

@@ -194,7 +194,13 @@
     "hoursAudit": "h Review",
     "clickCopyShare": "Click to Copy & Share",
     "stepNo": "Step ",
-    "stepSuffix": ""
+    "stepSuffix": "",
+    "beginnerGuide": "Guide",
+    "guideStep1": "Browse the task list and choose a task that suits you",
+    "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"
   },
   "taskStatus": {
     "all": "All",

+ 9 - 1
src/locales/id.json

@@ -169,7 +169,15 @@
     "abandonTask": "Batalkan tugas",
     "abandonConfirm": "Yakin ingin membatalkan tugas ini?",
     "submitSuccess": "Berhasil submit",
-    "claimSuccess": "Berhasil mengambil"
+    "claimSuccess": "Berhasil mengambil",
+    "stepNo": "Langkah ",
+    "stepSuffix": "",
+    "beginnerGuide": "Panduan",
+    "guideStep1": "Jelajahi daftar tugas, pilih tugas yang cocok",
+    "guideStep2": "Klik \"Ambil Tugas\" untuk memulai",
+    "guideStep3": "Ikuti langkah-langkah tugas dan ambil tangkapan layar",
+    "guideStep4": "Unggah tangkapan layar dan kirim untuk ditinjau",
+    "guideStep5": "Hadiah akan dikreditkan setelah disetujui"
   },
   "taskStatus": {
     "all": "Semua",

+ 9 - 1
src/locales/vi.json

@@ -169,7 +169,15 @@
     "abandonTask": "Từ bỏ nhiệm vụ",
     "abandonConfirm": "Bạn có chắc muốn từ bỏ nhiệm vụ này?",
     "submitSuccess": "Nộp thành công",
-    "claimSuccess": "Nhận thành công"
+    "claimSuccess": "Nhận thành công",
+    "stepNo": "Bước ",
+    "stepSuffix": "",
+    "beginnerGuide": "Hướng dẫn",
+    "guideStep1": "Duyệt danh sách nhiệm vụ, chọn nhiệm vụ phù hợp",
+    "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"
   },
   "taskStatus": {
     "all": "Tất cả",

+ 7 - 1
src/locales/zh.json

@@ -194,7 +194,13 @@
     "hoursAudit": "小时内审核",
     "clickCopyShare": "点击复制并分享",
     "stepNo": "第",
-    "stepSuffix": "步"
+    "stepSuffix": "步",
+    "beginnerGuide": "新手说明",
+    "guideStep1": "浏览任务列表,选择适合自己的任务",
+    "guideStep2": "点击【领取任务】按钮,开始执行任务",
+    "guideStep3": "按照任务步骤完成操作,并截图保存凭证",
+    "guideStep4": "上传截图提交审核,等待平台审核通过",
+    "guideStep5": "审核通过后奖励将自动发放到您的账户"
   },
   "taskStatus": {
     "all": "全部",

+ 152 - 64
src/views/task/detail.vue

@@ -4,11 +4,11 @@
     <div class="header">
       <van-icon name="arrow-left" @click="goBack" />
       <span>{{ $t('task.taskDetail') }}</span>
-      <span></span>
+      <span class="header-right-btn" @click="showGuide = true">{{ $t('task.beginnerGuide') }}</span>
     </div>
 
-    <!-- 任务基本信息卡片 - 参考图1布局 -->
-    <div class="task-card" v-if="taskInfo">
+    <!-- 任务基本信息卡片 - 紧凑布局 -->
+    <div class="task-card compact" v-if="taskInfo">
       <!-- 顶部提示标签 -->
       <div class="guarantee-tag">
         <van-icon name="shield-o" />
@@ -35,8 +35,8 @@
       </div>
     </div>
 
-    <!-- 审核标准(固定显示) -->
-    <div class="task-section" v-if="taskInfo">
+    <!-- 审核标准 -->
+    <div class="task-section compact" v-if="taskInfo">
       <div class="section-title">{{ $t('task.reviewStandards') }}</div>
       <div class="standard-list">
         <span class="standard-item">
@@ -55,7 +55,7 @@
     </div>
 
     <!-- 完成条件/认证标签 -->
-    <div class="task-section" v-if="hasAuthTags">
+    <div class="task-section compact" v-if="hasAuthTags">
       <div class="tag-list">
         <span class="auth-tag" v-if="taskInfo.requirePhone">
           {{ $t('task.phoneAuth') }}
@@ -102,6 +102,7 @@
               <span class="step-label">{{ $t('task.stepNo') }}{{ index + 1 }}{{ $t('task.stepSuffix') }}:</span>
               <span class="step-text">{{ step.title }}</span>
             </div>
+            <div class="step-desc" v-if="step.description">{{ step.description }}</div>
             <div class="step-image" v-if="step.image" @click="previewStepImage(step.image)">
               <img :src="step.image" alt="step" />
             </div>
@@ -216,6 +217,25 @@
         {{ applyInfo?.rejectReason || 'No reason provided' }}
       </div>
     </van-dialog>
+
+    <!-- 新手说明弹窗 -->
+    <van-popup
+      v-model:show="showGuide"
+      position="bottom"
+      round
+      :style="{ maxHeight: '80vh' }"
+      closeable
+    >
+      <div class="guide-popup">
+        <div class="guide-title">{{ $t('task.beginnerGuide') }}</div>
+        <div class="guide-content">
+          <div class="guide-step" v-for="(item, index) in guideSteps" :key="index">
+            <div class="guide-step-no">{{ index + 1 }}</div>
+            <div class="guide-step-text">{{ item }}</div>
+          </div>
+        </div>
+      </div>
+    </van-popup>
   </div>
 </template>
 
@@ -238,6 +258,7 @@ const exampleList = ref<any[]>([]);
 const applyInfo = ref<any>(null);
 const claiming = ref(false);
 const showReject = ref(false);
+const showGuide = ref(false);
 const activeTab = ref<'steps' | 'examples'>('steps');
 
 // 格式化奖励金额(后端返回的是分,需要转换为元)
@@ -257,6 +278,15 @@ const hasAuthTags = computed(() => {
   return taskInfo.value.requirePhone || taskInfo.value.requireRealname || taskInfo.value.requireIdcard;
 });
 
+// 新手说明步骤
+const guideSteps = computed(() => [
+  t('task.guideStep1'),
+  t('task.guideStep2'),
+  t('task.guideStep3'),
+  t('task.guideStep4'),
+  t('task.guideStep5'),
+]);
+
 const getTaskDetail = async () => {
   try {
     const res = await requestTaskDetail(taskId);
@@ -363,7 +393,7 @@ onMounted(() => {
   display: flex;
   align-items: center;
   justify-content: space-between;
-  padding: min(4.267vw, 20.48px);
+  padding: min(2.667vw, 12.8px) min(3.2vw, 15.36px);
   color: #fff;
   font-size: min(4.267vw, 20.48px);
   font-weight: 600;
@@ -371,70 +401,129 @@ onMounted(() => {
   .van-icon {
     font-size: min(5.333vw, 25.6px);
   }
+
+  .header-right-btn {
+    font-size: min(3.2vw, 15.36px);
+    font-weight: 400;
+    color: #ffc300;
+    cursor: pointer;
+    padding: min(1.067vw, 5.12px) min(2.133vw, 10.24px);
+    border: 1px solid rgba(255, 195, 0, 0.4);
+    border-radius: min(1.333vw, 6.4px);
+    white-space: nowrap;
+
+    &:active {
+      opacity: 0.7;
+    }
+  }
 }
 
-// 任务信息卡片 - 参考图1布局
-.task-card {
-  margin: min(4.267vw, 20.48px);
-  padding: min(4.267vw, 20.48px);
+// 新手说明弹窗
+.guide-popup {
+  padding: min(5.333vw, 25.6px) min(4.267vw, 20.48px) min(8vw, 38.4px);
+
+  .guide-title {
+    font-size: min(4.8vw, 23px);
+    font-weight: 600;
+    color: #333;
+    text-align: center;
+    margin-bottom: min(4.267vw, 20.48px);
+  }
+
+  .guide-content {
+    display: flex;
+    flex-direction: column;
+    gap: min(3.2vw, 15.36px);
+  }
+
+  .guide-step {
+    display: flex;
+    align-items: flex-start;
+    gap: min(2.667vw, 12.8px);
+
+    .guide-step-no {
+      flex-shrink: 0;
+      width: min(6.4vw, 30.72px);
+      height: min(6.4vw, 30.72px);
+      background: linear-gradient(135deg, #ffc300, #ff9800);
+      border-radius: 50%;
+      display: flex;
+      align-items: center;
+      justify-content: center;
+      font-size: min(3.467vw, 16.64px);
+      font-weight: 600;
+      color: #fff;
+    }
+
+    .guide-step-text {
+      flex: 1;
+      font-size: min(3.733vw, 17.92px);
+      color: #333;
+      line-height: 1.5;
+      padding-top: min(0.8vw, 3.84px);
+    }
+  }
+}
+
+// 任务信息卡片 - 紧凑布局
+.task-card.compact {
+  margin: min(1.6vw, 7.68px) min(3.2vw, 15.36px);
+  padding: min(2.667vw, 12.8px);
   background: rgba(255, 255, 255, 0.03);
-  border-radius: min(3.2vw, 15.36px);
+  border-radius: min(2.667vw, 12.8px);
 
-  // 顶部保障标签
   .guarantee-tag {
     display: inline-flex;
     align-items: center;
-    gap: min(1.333vw, 6.4px);
-    padding: min(1.6vw, 7.68px) min(2.667vw, 12.8px);
+    gap: min(1.067vw, 5.12px);
+    padding: min(1.067vw, 5.12px) min(2.133vw, 10.24px);
     background: rgba(76, 175, 80, 0.15);
     border: 1px solid rgba(76, 175, 80, 0.3);
-    border-radius: min(1.6vw, 7.68px);
+    border-radius: min(1.333vw, 6.4px);
     color: #4caf50;
-    font-size: min(3.2vw, 15.36px);
-    margin-bottom: min(3.2vw, 15.36px);
+    font-size: min(2.667vw, 12.8px);
+    margin-bottom: min(2.133vw, 10.24px);
 
     .van-icon {
-      font-size: min(4vw, 19.2px);
+      font-size: min(3.2vw, 15.36px);
     }
   }
 
-  // 任务标题和奖励
   .task-header {
     display: flex;
     justify-content: space-between;
     align-items: flex-start;
-    margin-bottom: min(4vw, 19.2px);
+    margin-bottom: min(2.667vw, 12.8px);
 
     .task-title {
       flex: 1;
-      font-size: min(4.8vw, 23px);
+      font-size: min(4vw, 19.2px);
       font-weight: 600;
       color: #fff;
-      line-height: 1.4;
-      margin-right: min(2.667vw, 12.8px);
+      line-height: 1.3;
+      margin-right: min(2.133vw, 10.24px);
     }
 
     .task-reward {
       flex-shrink: 0;
-      font-size: min(5.867vw, 28px);
+      font-size: min(4.8vw, 23px);
       font-weight: bold;
       color: #4caf50;
     }
   }
 
-  // 三个标签横排
   .task-tags {
     display: flex;
-    gap: min(2.133vw, 10.24px);
-    margin-bottom: min(4vw, 19.2px);
+    gap: min(1.6vw, 7.68px);
+    margin-bottom: min(2.667vw, 12.8px);
 
     .tag-item {
       flex: 1;
       text-align: center;
-      padding: min(2.667vw, 12.8px) min(2.133vw, 10.24px);
+      padding: min(1.6vw, 7.68px) min(1.333vw, 6.4px);
       background: rgba(255, 255, 255, 0.08);
-      border-radius: min(2.133vw, 10.24px);
-      font-size: min(3.2vw, 15.36px);
+      border-radius: min(1.6vw, 7.68px);
+      font-size: min(2.667vw, 12.8px);
       color: rgba(255, 255, 255, 0.7);
 
       &.highlight {
@@ -444,10 +533,9 @@ onMounted(() => {
     }
   }
 
-  // 任务简介
   .task-intro {
-    font-size: min(3.733vw, 17.92px);
-    line-height: 1.6;
+    font-size: min(3.2vw, 15.36px);
+    line-height: 1.4;
 
     .intro-label {
       color: #ff5722;
@@ -460,62 +548,52 @@ onMounted(() => {
   }
 }
 
-.task-section {
-  padding: 0 min(4.267vw, 20.48px) min(4.267vw, 20.48px);
+// 审核标准/认证标签区块 - 紧凑
+.task-section.compact {
+  padding: 0 min(3.2vw, 15.36px) min(1.6vw, 7.68px);
 
   .section-title {
-    font-size: min(4.267vw, 20.48px);
+    font-size: min(3.467vw, 16.64px);
     font-weight: 600;
     color: #fff;
-    margin-bottom: min(3.2vw, 15.36px);
+    margin-bottom: min(1.6vw, 7.68px);
     padding-left: min(2.133vw, 10.24px);
     border-left: 3px solid #ffc300;
   }
-
-  .section-content {
-    background: rgba(255, 255, 255, 0.03);
-    border-radius: min(3.2vw, 15.36px);
-    padding: min(4.267vw, 20.48px);
-    color: rgba(255, 255, 255, 0.8);
-    font-size: min(3.733vw, 17.92px);
-    line-height: 1.6;
-  }
 }
 
-// 审核标准
-.standard-list {
+.task-section.compact .standard-list {
   display: flex;
   flex-wrap: wrap;
-  gap: min(2.667vw, 12.8px);
+  gap: min(1.6vw, 7.68px);
 
   .standard-item {
     display: flex;
     align-items: center;
-    gap: min(1.333vw, 6.4px);
+    gap: min(1.067vw, 5.12px);
     color: rgba(255, 255, 255, 0.8);
-    font-size: min(3.467vw, 16.64px);
-    padding: min(2.133vw, 10.24px) min(3.2vw, 15.36px);
+    font-size: min(2.933vw, 14.08px);
+    padding: min(1.6vw, 7.68px) min(2.667vw, 12.8px);
     background: rgba(255, 255, 255, 0.05);
-    border-radius: min(1.6vw, 7.68px);
+    border-radius: min(1.333vw, 6.4px);
 
     .check-icon {
       color: #4caf50;
-      font-size: min(4vw, 19.2px);
+      font-size: min(3.467vw, 16.64px);
     }
   }
 }
 
-// 认证标签
-.tag-list {
+.task-section.compact .tag-list {
   display: flex;
   flex-wrap: wrap;
-  gap: min(2.667vw, 12.8px);
+  gap: min(1.6vw, 7.68px);
 
   .auth-tag {
-    padding: min(2.133vw, 10.24px) min(4vw, 19.2px);
+    padding: min(1.6vw, 7.68px) min(3.2vw, 15.36px);
     border: 1px solid #ffc300;
-    border-radius: min(1.6vw, 7.68px);
-    font-size: min(3.467vw, 16.64px);
+    border-radius: min(1.333vw, 6.4px);
+    font-size: min(2.933vw, 14.08px);
     color: #ffc300;
     background: rgba(255, 195, 0, 0.1);
   }
@@ -523,8 +601,8 @@ onMounted(() => {
 
 // 顶部复制按钮
 .copy-btn-top {
-  margin: min(4.267vw, 20.48px);
-  padding: min(4vw, 19.2px);
+  margin: min(1.6vw, 7.68px) min(3.2vw, 15.36px);
+  padding: min(2.667vw, 12.8px);
   background: linear-gradient(135deg, #ff9800 0%, #f57c00 100%);
   border-radius: min(2.133vw, 10.24px);
   text-align: center;
@@ -541,7 +619,7 @@ onMounted(() => {
 
 // 任务步骤和审核样例区块
 .steps-examples-section {
-  margin: min(4.267vw, 20.48px);
+  margin: min(1.6vw, 7.68px) min(3.2vw, 15.36px);
   background: rgba(255, 255, 255, 0.03);
   border-radius: min(3.2vw, 15.36px);
   overflow: hidden;
@@ -657,6 +735,16 @@ onMounted(() => {
       }
     }
 
+    .step-desc {
+      padding: 0 min(3.2vw, 15.36px);
+      margin-bottom: min(2.133vw, 10.24px);
+      color: rgba(255, 255, 255, 0.6);
+      font-size: min(3.2vw, 15.36px);
+      line-height: 1.5;
+      white-space: pre-wrap;
+      word-break: break-word;
+    }
+
     .step-image {
       border-radius: min(2.667vw, 12.8px);
       overflow: hidden;