| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130 |
- <template>
- <view class="container">
- <view class="header">
- <text class="title">我的计划</text>
- </view>
- <!-- 计划列表 -->
- <view class="plan-list" v-if="plans.length > 0">
- <view
- class="plan-card"
- v-for="plan in plans"
- :key="plan.id"
- @click="goToDetail(plan.id)"
- >
- <view class="plan-header">
- <text class="plan-name">{{ plan.name }}</text>
- <text class="plan-status" :class="plan.status">{{ getStatusText(plan.status) }}</text>
- </view>
- <view class="plan-progress">
- <progress :percent="getProgress(plan)" :stroke-width="8" backgroundColor="#e0e0e0" activeColor="#4CAF50" />
- <text class="progress-text">{{ plan.completedDays }} / {{ plan.totalDays }} 天</text>
- </view>
- <view class="plan-dates">
- <text>{{ formatDate(plan.startDate) }} - {{ formatDate(plan.endDate) }}</text>
- </view>
- <view class="plan-actions" v-if="plan.status === 'active'">
- <button class="btn-cancel" @click.stop="cancelPlan(plan.id)">取消</button>
- </view>
- </view>
- </view>
- <!-- 空状态 -->
- <view class="empty" v-else>
- <text class="empty-text">暂无计划,快去应用任务模板吧</text>
- <button class="btn-go" @click="goToMarket">去市场</button>
- </view>
- </view>
- </template>
- <script>
- import { getMyPlans, cancelPlan as cancelPlanApi } from '@/utils/api.js'
- export default {
- data() {
- return {
- plans: []
- }
- },
- onShow() {
- this.loadPlans()
- },
- methods: {
- async loadPlans() {
- try {
- const res = await getMyPlans()
- this.plans = res.data || []
- } catch (e) {
- console.error(e)
- }
- },
- getStatusText(status) {
- const map = { 'active': '进行中', 'completed': '已完成', 'cancelled': '已取消' }
- return map[status] || status
- },
- getProgress(plan) {
- if (!plan.totalDays) return 0
- return Math.round(plan.completedDays / plan.totalDays * 100)
- },
- formatDate(date) {
- if (!date) return ''
- const d = new Date(date)
- return `${d.getMonth() + 1}-${d.getDate()}`
- },
- goToDetail(id) {
- uni.navigateTo({
- url: `/pages/parent/plans/detail?id=${id}`
- })
- },
- goToMarket() {
- uni.navigateTo({
- url: '/pages/parent/market/index'
- })
- },
- async cancelPlan(id) {
- uni.showModal({
- title: '确认取消',
- content: '确定要取消这个计划吗?',
- success: async (res) => {
- if (res.confirm) {
- try {
- await cancelPlanApi(id)
- uni.showToast({ title: '已取消' })
- this.loadPlans()
- } catch (e) {
- uni.showToast({ title: '取消失败', icon: 'none' })
- }
- }
- }
- })
- }
- }
- }
- </script>
- <style scoped>
- .container { min-height: 100vh; background: #f5f5f5; padding: 30rpx; }
- .header { margin-bottom: 30rpx; }
- .title { font-size: 36rpx; font-weight: bold; color: #333; }
- .plan-list { display: flex; flex-direction: column; gap: 20rpx; }
- .plan-card { background: #fff; border-radius: 16rpx; padding: 30rpx; box-shadow: 0 2rpx 10rpx rgba(0,0,0,0.05); }
- .plan-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 20rpx; }
- .plan-name { font-size: 32rpx; font-weight: bold; color: #333; }
- .plan-status { font-size: 24rpx; padding: 8rpx 16rpx; border-radius: 20rpx; }
- .plan-status.active { background: #e8f5e9; color: #4CAF50; }
- .plan-status.completed { background: #e3f2fd; color: #2196F3; }
- .plan-status.cancelled { background: #f5f5f5; color: #999; }
- .plan-progress { display: flex; align-items: center; gap: 16rpx; margin-bottom: 16rpx; }
- .plan-progress progress { flex: 1; }
- .progress-text { font-size: 24rpx; color: #666; }
- .plan-dates { font-size: 24rpx; color: #999; margin-bottom: 16rpx; }
- .plan-actions { display: flex; justify-content: flex-end; }
- .btn-cancel { background: #f5f5f5; color: #666; font-size: 24rpx; padding: 12rpx 24rpx; border-radius: 24rpx; }
- .empty { display: flex; flex-direction: column; align-items: center; padding: 100rpx; }
- .empty-text { color: #999; font-size: 28rpx; margin-bottom: 30rpx; }
- .btn-go { background: #4CAF50; color: #fff; }
- </style>
|