Files
yimo-resource-blog/pages/task/index.vue

97 lines
4.7 KiB
Vue
Raw Normal View History

2026-09-16 16:49:25 +08:00
<template>
<view class="page">
<view class="hero">
<view class="hero-title">积分任务中心</view>
<view class="hero-desc">完成任务上传截图,审核通过后积分自动到账</view>
</view>
<view v-if="tasks.length" class="task-list">
<view v-for="item in tasks" :key="item.id" class="task-card" @click="openTask(item)">
<image v-if="item.coverUrl" class="task-cover" :src="resolveUrl(item.coverUrl)" mode="aspectFill"></image>
<view v-else class="task-cover task-cover-default"><text class="cuIcon-formfill"></text></view>
<view class="task-main">
<view class="task-head">
<text class="task-name">{{ item.taskName }}</text>
<text class="cycle-tag" :class="item.cycleType === 'DAILY' ? 'daily' : 'once'">{{ item.cycleType === 'DAILY' ? '每日任务' : '单次任务' }}</text>
</view>
<view class="task-desc">{{ item.description || '完成任务并上传截图,等待平台审核' }}</view>
<view class="task-foot">
<view class="reward">+{{ item.rewardPoints }}<text> 积分</text></view>
<view class="task-status" :class="item.statusClassName">{{ item.statusLabel }} <text class="cuIcon-right"></text></view>
</view>
</view>
</view>
</view>
<view v-else-if="!loading" class="empty">
<text class="cuIcon-form empty-icon"></text>
<view>暂无进行中的积分任务</view>
</view>
</view>
</template>
<script>
import config from '@/config'
import { listPointTasks } from '@/api/app/index.js'
export default {
data() { return { tasks: [], loading: false } },
onShow() { this.loadTasks() },
onPullDownRefresh() { this.loadTasks() },
methods: {
loadTasks() {
this.loading = true
listPointTasks().then(res => {
this.tasks = (res.data || []).map(item => Object.assign({}, item, {
statusLabel: this.getStatusText(item),
statusClassName: this.getStatusClass(item)
}))
}).finally(() => { this.loading = false; uni.stopPullDownRefresh() })
},
openTask(item) { this.$tab.navigateTo('/pages/task/detail?id=' + item.id) },
resolveUrl(url) {
if (!url || /^(https?:)?\/\//i.test(url)) return url
return config.baseUrl + (url.charAt(0) === '/' ? url : '/' + url)
},
getStatusText(item) {
if (item.currentStatus === 0) return '审核中'
if (item.currentStatus === 1) return item.cycleType === 'DAILY' ? '今日已完成' : '已完成'
if (item.currentStatus === 2) return item.canSubmit ? '重新提交' : '未通过'
if (item.currentStatus === 3) return '奖励已撤销'
return '去完成'
},
getStatusClass(item) {
if (item.currentStatus === 1) return 'done'
if (item.currentStatus === 0) return 'pending'
if (item.currentStatus === 2 || item.currentStatus === 3) return 'rejected'
return 'available'
}
}
}
</script>
<style scoped>
.page { min-height: 100vh; background: #f5f7fb; padding: 28rpx; box-sizing: border-box; }
.hero { padding: 38rpx; border-radius: 24rpx; color: #fff; background: linear-gradient(135deg, #4c8dff, #725cff); box-shadow: 0 16rpx 36rpx rgba(76, 110, 255, .18); }
.hero-title { font-size: 40rpx; font-weight: 700; }
.hero-desc { margin-top: 14rpx; font-size: 25rpx; opacity: .9; }
.task-list { margin-top: 26rpx; }
.task-card { display: flex; padding: 24rpx; margin-bottom: 20rpx; background: #fff; border-radius: 22rpx; box-shadow: 0 8rpx 24rpx rgba(32, 47, 85, .06); }
.task-cover { width: 150rpx; height: 150rpx; flex-shrink: 0; border-radius: 18rpx; background: #eef3ff; }
.task-cover-default { display: flex; align-items: center; justify-content: center; color: #5f79f5; font-size: 60rpx; }
.task-main { flex: 1; min-width: 0; margin-left: 22rpx; }
.task-head { display: flex; align-items: center; }
.task-name { flex: 1; min-width: 0; font-size: 31rpx; font-weight: 600; color: #252a34; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cycle-tag { margin-left: 12rpx; padding: 5rpx 12rpx; border-radius: 15rpx; font-size: 20rpx; }
.cycle-tag.once { color: #2c9f6a; background: #eaf8f1; }
.cycle-tag.daily { color: #ed8a18; background: #fff4e5; }
.task-desc { height: 62rpx; margin-top: 13rpx; color: #8b929e; font-size: 24rpx; line-height: 31rpx; overflow: hidden; }
.task-foot { display: flex; align-items: center; margin-top: 10rpx; }
.reward { flex: 1; color: #ff8a22; font-size: 31rpx; font-weight: 700; }
.reward text { font-size: 23rpx; font-weight: 400; }
.task-status { font-size: 24rpx; }
.task-status.available { color: #4d72ee; }
.task-status.pending { color: #e69a24; }
.task-status.done { color: #36a66f; }
.task-status.rejected { color: #e45b5b; }
.empty { padding-top: 220rpx; color: #a9b0bc; text-align: center; font-size: 27rpx; }
.empty-icon { display: block; margin-bottom: 18rpx; font-size: 90rpx; color: #d7dce6; }
</style>