children.vue 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. <template>
  2. <view class="container">
  3. <view class="children-list">
  4. <view class="child-item" v-for="child in children" :key="child.id">
  5. <view class="child-avatar">{{ child.nickname ? child.nickname[0] : '?' }}</view>
  6. <view class="child-info">
  7. <text class="child-name">{{ child.nickname }}</text>
  8. <text class="child-detail">年龄: {{ child.age }} | 积分: {{ child.totalPoints }}</text>
  9. <text class="child-dan" v-if="child.danLevel">DAN: {{ child.danLevel }}</text>
  10. <text class="child-dan" v-else>DAN: 未测评</text>
  11. </view>
  12. <view class="child-actions">
  13. <button class="btn-invite" open-type="share" @click="prepareInvite(child)">邀请</button>
  14. <text class="btn-edit" @click="editChild(child)">编辑</text>
  15. </view>
  16. </view>
  17. </view>
  18. <view class="empty" v-if="children.length === 0">
  19. <text>暂无孩子,请点击下方按钮添加</text>
  20. </view>
  21. <!-- 添加孩子按钮 -->
  22. <view class="add-btn-wrapper">
  23. <button class="btn-add" @click="addChild">
  24. <text class="add-icon">+</text>
  25. <text>添加孩子</text>
  26. </button>
  27. </view>
  28. </view>
  29. </template>
  30. <script>
  31. import { getChildren } from '../../utils/api.js'
  32. export default {
  33. data() {
  34. return {
  35. children: [],
  36. shareData: null
  37. }
  38. },
  39. onLoad() {
  40. },
  41. onShow() {
  42. this.loadChildren()
  43. },
  44. onShareAppMessage() {
  45. if (this.shareData) {
  46. return {
  47. title: this.shareData.title,
  48. path: this.shareData.path,
  49. imageUrl: '/static/invite-card.png'
  50. }
  51. }
  52. },
  53. methods: {
  54. async loadChildren() {
  55. try {
  56. const res = await getChildren()
  57. this.children = res.data || []
  58. } catch (e) {
  59. console.error(e)
  60. }
  61. },
  62. async prepareInvite(child) {
  63. try {
  64. const { generateInviteCard } = require('../../utils/api.js')
  65. const res = await generateInviteCard('child', child.id)
  66. const code = res.data.code
  67. this.shareData = {
  68. title: '邀请 ' + (child.nickname || '孩子') + ' 加入家庭',
  69. path: '/pages/login/login?invite_code=' + code
  70. }
  71. uni.showToast({ title: '点击右上角转发给TA', icon: 'none' })
  72. } catch (e) {
  73. uni.showToast({ title: e.message || '生成邀请失败', icon: 'none' })
  74. }
  75. },
  76. editChild(child) {
  77. uni.navigateTo({
  78. url: '/pages/profile/edit-child?childId=' + child.id
  79. })
  80. },
  81. addChild() {
  82. uni.navigateTo({
  83. url: '/pages/profile/create-child'
  84. })
  85. }
  86. }
  87. }
  88. </script>
  89. <style scoped>
  90. .container { padding: 30rpx; padding-bottom: 150rpx; }
  91. .children-list { background: #fff; border-radius: 20rpx; }
  92. .child-item { display: flex; align-items: center; padding: 30rpx; border-bottom: 1rpx solid #f0f0f0; }
  93. .child-avatar { width: 100rpx; height: 100rpx; border-radius: 50%; background: linear-gradient(135deg, #667eea, #764ba2); color: #fff; display: flex; align-items: center; justify-content: center; font-size: 40rpx; font-weight: bold; margin-right: 20rpx; }
  94. .child-info { flex: 1; }
  95. .child-name { font-size: 32rpx; font-weight: bold; color: #333; display: block; }
  96. .child-detail { font-size: 26rpx; color: #666; display: block; }
  97. .child-dan { font-size: 24rpx; color: #999; }
  98. .btn-edit { color: #F97316; font-size: 28rpx; }
  99. .btn-invite { background: #3B82F6; color: #fff; font-size: 24rpx; padding: 4rpx 16rpx; border-radius: 8rpx; margin-right: 10rpx; line-height: 1.8; display: inline-block; }
  100. .empty { text-align: center; padding: 100rpx; color: #999; }
  101. .add-btn-wrapper { position: fixed; bottom: 30rpx; left: 30rpx; right: 30rpx; }
  102. .btn-add {
  103. display: flex;
  104. align-items: center;
  105. justify-content: center;
  106. background: linear-gradient(135deg, #F97316, #FB923C);
  107. color: #fff;
  108. border-radius: 50rpx;
  109. padding: 24rpx 0;
  110. font-size: 32rpx;
  111. box-shadow: 0 4rpx 12rpx rgba(255, 107, 107, 0.3);
  112. }
  113. .add-icon { font-size: 40rpx; margin-right: 10rpx; font-weight: bold; }
  114. </style>