children.vue 3.8 KB

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