index.vue
8.43 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
<!--
* @Date: 2022-09-19 14:11:06
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2025-09-02 21:45:14
* @FilePath: /lls_program/src/pages/MyFamily/index.vue
* @Description: 我的家庭页面 - 展示用户加入的家庭列表
-->
<template>
<view class="min-h-screen bg-gray-50 pb-20">
<!-- 家庭列表 -->
<view class="px-4 py-4 space-y-4">
<view
v-for="family in familyList"
:key="family.id"
class="bg-white rounded-lg overflow-hidden shadow-sm border border-gray-100"
>
<!-- 家庭封面图和基本信息 -->
<view class="relative">
<!-- 当前家庭标记 -->
<view
v-if="family.is_in"
class="absolute top-2 right-2 bg-blue-500 text-white text-xs px-2 py-1 rounded-sm z-10"
>
当前家庭
</view>
<!-- 封面图 -->
<image
:src="family.avatar_url || defaultFamilyCoverSvg"
class="w-full h-44 object-cover"
mode="aspectFill"
/>
<!-- 家庭名称和大家长信息覆盖层 -->
<view class="absolute bottom-0 left-0 right-0 bg-gradient-to-t from-black/60 to-transparent p-4">
<view class="text-white font-bold text-lg mb-1">{{ family.name }}</view>
<view class="text-white/90 text-sm">大家长:{{ family.ownerName }}</view>
</view>
</view>
<!-- 成员信息和操作按钮 -->
<view class="p-4">
<!-- 成员头像和数量 -->
<view class="flex items-center justify-between mb-4">
<view class="flex items-center">
<!-- 成员头像叠加效果 -->
<view class="avatar-overlap">
<image
v-for="(member, index) in family?.members?.slice(0, 4) || []"
:key="member.id"
:src="member.avatar"
class="avatar-item w-8 h-8 rounded-full border-2 border-white object-cover"
:style="{ zIndex: 10 - index }"
/>
<!-- 更多成员数量显示 -->
<view
v-if="family?.members?.length > 4"
class="w-8 h-8 rounded-full bg-gray-300 border-2 border-white flex items-center justify-center text-xs text-gray-600"
:style="{ zIndex: 6 }"
>
+{{ family?.members?.length - 4 }}
</view>
</view>
<!-- 总成员数 -->
<view class="ml-3 text-sm text-gray-600">
{{ family?.members?.length || 0 }} 位家庭成员
</view>
</view>
</view>
<!-- 操作按钮 -->
<view class="flex gap-3 justify-end">
<view
v-if="!family.is_in"
@tap="switchToFamily(family.id)"
class="px-4 py-2 bg-blue-500 text-white text-sm rounded-lg"
>
切换到此家庭
</view>
<view
@tap="exitFamily(family.id)"
class="px-4 py-2 bg-red-500 text-white text-sm rounded-lg"
>
退出家庭
</view>
</view>
</view>
</view>
<!-- 空状态 -->
<view v-if="familyList.length === 0" class="text-center py-12">
<view class="text-gray-400 mb-4">
<Home size="48" />
</view>
<view class="text-gray-500 mb-2">您还没有加入任何家庭</view>
</view>
</view>
<!-- 底部固定按钮 -->
<view v-if="isShowBtn" class="fixed bottom-0 left-0 right-0 bg-white border-t border-gray-100 p-4 z-10">
<view
@tap="joinNewFamily"
class="w-full bg-blue-500 text-white text-center py-3 rounded-lg font-medium"
>
加入新家庭
</view>
</view>
<!-- 确认弹窗已替换为Taro.showModal -->
</view>
</template>
<script setup>
import { ref, onMounted, computed } from 'vue';
import Taro, { useDidShow } from '@tarojs/taro';
import { Home } from '@nutui/icons-vue-taro';
import './index.less';
import { getMyFamiliesAPI } from '@/api/family';
//
const defaultFamilyCoverSvg = 'https://cdn.ipadbiz.cn/lls_prog/images/default-family-cover.png';
// 获取接口数据
// 响应式数据
const familyList = ref([]);
/**
* 初始化页面数据
*/
const initPageData = async () => {
const { code, data } = await getMyFamiliesAPI();
if (code) {
familyList.value = data;
console.warn(data);
}
// 模拟家庭数据
// familyList.value = [
// {
// id: 1,
// name: '幸福之家',
// ownerName: '张明明',
// avatar_url: 'https://images.unsplash.com/photo-1511895426328-dc8714191300?w=400&h=200&fit=crop',
// is_in: true,
// members: [
// { id: 1, avatar: 'https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?w=100&h=100&fit=crop&crop=face' },
// { id: 2, avatar: 'https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?w=100&h=100&fit=crop&crop=face' },
// { id: 3, avatar: 'https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?w=100&h=100&fit=crop&crop=face' }
// ]
// },
// {
// id: 2,
// name: '欢乐之家',
// ownerName: '李志强',
// avatar_url: 'https://images.unsplash.com/photo-1502086223501-7ea6ecd79368?w=400&h=200&fit=crop',
// is_in: false,
// members: [
// { id: 4, avatar: 'https://images.unsplash.com/photo-1500648767791-00dcc994a43e?w=100&h=100&fit=crop&crop=face' },
// { id: 5, avatar: 'https://images.unsplash.com/photo-1438761681033-6461ffad8d80?w=100&h=100&fit=crop&crop=face' }
// ]
// },
// {
// id: 3,
// name: '快乐之家',
// ownerName: '王芳',
// avatar_url: 'https://images.unsplash.com/photo-1502086223501-7ea6ecd79368?w=400&h=200&fit=crop',
// is_in: false,
// members: [
// { id: 6, avatar: 'https://images.unsplash.com/photo-1500648767791-00dcc994a43e?w=100&h=100&fit=crop&crop=face' },
// { id: 7, avatar: 'https://images.unsplash.com/photo-1438761681033-6461ffad8d80?w=100&h=100&fit=crop&crop=face' }
// ]
// },
// ];
};
// 如果家庭列表存在时, 才显示加入新家庭的按钮
const isShowBtn = computed(() => {
return familyList.value.length > 0;
})
/**
* 切换到指定家庭
* @param {number} familyId - 家庭ID
*/
const switchToFamily = (familyId) => {
const family = familyList.value.find(f => f.id === familyId);
if (!family) return;
Taro.showModal({
title: '切换家庭',
content: `确定要切换到「${family.name}」吗?`,
success: (res) => {
if (res.confirm) {
// 切换家庭逻辑 - 先清除所有当前标记,再设置新的当前家庭
familyList.value = familyList.value.map(f => ({
...f,
is_in: f.id === familyId
}));
console.log('切换家庭后的列表:', familyList.value);
Taro.showToast({
title: '切换成功',
icon: 'success'
});
}
}
});
};
/**
* 退出家庭
* @param {number} familyId - 家庭ID
*/
const exitFamily = (familyId) => {
const family = familyList.value.find(f => f.id === familyId);
if (!family) return;
Taro.showModal({
title: '退出家庭',
content: `确定要退出「${family.name}」吗?退出后将无法查看该家庭的相关信息。`,
success: (res) => {
if (res.confirm) {
// 退出家庭逻辑
const exitingFamily = familyList.value.find(f => f.id === familyId);
if (exitingFamily?.is_in) {
// 如果退出的是当前家庭,需要返回我的页面
familyList.value = familyList.value.filter(f => f.id !== familyId);
Taro.showToast({
title: '已退出家庭',
icon: 'success'
});
// 延迟返回我的页面
setTimeout(() => {
Taro.navigateBack();
}, 1500);
} else {
// 退出非当前家庭
familyList.value = familyList.value.filter(f => f.id !== familyId);
Taro.showToast({
title: '已退出家庭',
icon: 'success'
});
}
}
}
});
};
/**
* 加入新家庭
*/
const joinNewFamily = () => {
Taro.navigateTo({
url: '/pages/JoinFamily/index'
});
};
// 页面加载时初始化数据
useDidShow(() => {
initPageData();
});
</script>
<script>
export default {
name: 'MyFamily',
};
</script>