index.vue 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. <template>
  2. <view class="container">
  3. <view v-if="hasFamily">
  4. <view class="header">
  5. <text class="title">我的计划</text>
  6. <text class="subtitle">查看和管理家庭成长计划</text>
  7. </view>
  8. <!-- 加载中 -->
  9. <view class="loading" v-if="loading">
  10. <text>加载中...</text>
  11. </view>
  12. <!-- 空状态 -->
  13. <view class="empty" v-else-if="plans.length === 0">
  14. <text class="empty-icon">📋</text>
  15. <text class="empty-text">暂无计划</text>
  16. <text class="empty-hint">规划师可为您创建专属成长计划</text>
  17. </view>
  18. <!-- 计划列表 -->
  19. <view class="plan-list" v-else>
  20. <view class="plan-card" v-for="plan in plans" :key="plan.id" @click="goDetail(plan.id)">
  21. <view class="card-top">
  22. <text class="plan-title">{{ plan.title }}</text>
  23. <view class="plan-status" :class="'status-' + (plan.status || 0)">
  24. <text>{{ statusText(plan.status) }}</text>
  25. </view>
  26. </view>
  27. <text class="plan-desc" v-if="plan.description">{{ plan.description }}</text>
  28. <view class="card-meta">
  29. <text class="meta-item">孩子:{{ plan.childName || '--' }}</text>
  30. <text class="meta-item">创建时间:{{ plan.createTime || '--' }}</text>
  31. </view>
  32. </view>
  33. </view>
  34. </view>
  35. <view v-else>
  36. <FamilyEmptyState type="card" />
  37. </view>
  38. </view>
  39. </template>
  40. <script>
  41. import { listFamilyPlans } from '../../../utils/api.js'
  42. export default {
  43. data() {
  44. return {
  45. loading: false,
  46. plans: []
  47. }
  48. },
  49. computed: {
  50. hasFamily: function() {
  51. return this.$store.getters.hasFamily
  52. }
  53. },
  54. onShow() {
  55. this.loadPlans()
  56. },
  57. methods: {
  58. loadPlans: function() {
  59. this.loading = true
  60. var self = this
  61. listFamilyPlans({}).then(function(res) {
  62. self.loading = false
  63. if (res.code === 200 && Array.isArray(res.data)) {
  64. self.plans = res.data
  65. } else if (res.code === 200 && res.data && res.data.records) {
  66. self.plans = res.data.records
  67. }
  68. }).catch(function() {
  69. self.loading = false
  70. self.plans = []
  71. })
  72. },
  73. goDetail: function(id) {
  74. uni.navigateTo({ url: './detail?planId=' + id })
  75. },
  76. statusText: function(status) {
  77. var map = { 0: '待审核', 1: '进行中', 2: '已完成', 3: '已取消' }
  78. return map[status] || '未知'
  79. }
  80. }
  81. }
  82. </script>
  83. <style scoped>
  84. .container { min-height: 100vh; background: #f8f8f8; padding-bottom: 30rpx; }
  85. .header { padding: 40rpx 30rpx 20rpx; }
  86. .title { font-size: 36rpx; font-weight: bold; color: #333; display: block; }
  87. .subtitle { font-size: 26rpx; color: #999; margin-top: 8rpx; display: block; }
  88. .loading, .empty { display: flex; flex-direction: column; align-items: center; padding: 100rpx 0; }
  89. .empty-icon { font-size: 80rpx; }
  90. .empty-text { font-size: 30rpx; color: #666; margin-top: 20rpx; }
  91. .empty-hint { font-size: 26rpx; color: #bbb; margin-top: 10rpx; }
  92. .plan-list { padding: 0 30rpx; }
  93. .plan-card { background: #fff; border-radius: 16rpx; padding: 30rpx; margin-bottom: 20rpx; box-shadow: 0 2rpx 12rpx rgba(0,0,0,0.06); }
  94. .card-top { display: flex; justify-content: space-between; align-items: center; }
  95. .plan-title { font-size: 30rpx; font-weight: bold; color: #333; flex: 1; }
  96. .plan-status { font-size: 22rpx; padding: 4rpx 16rpx; border-radius: 20rpx; }
  97. .status-0 { background: #FFF3E0; color: #F97316; }
  98. .status-1 { background: #E8F5E9; color: #4CAF50; }
  99. .status-2 { background: #E3F2FD; color: #2196F3; }
  100. .status-3 { background: #F5F5F5; color: #999; }
  101. .plan-desc { font-size: 26rpx; color: #666; margin-top: 12rpx; display: block; line-height: 1.5; }
  102. .card-meta { display: flex; flex-direction: column; margin-top: 16rpx; gap: 6rpx; }
  103. .meta-item { font-size: 24rpx; color: #bbb; }
  104. </style>