hookehuyr

fix(家庭功能): 修复家庭相关功能并移除模拟数据

- 修复Dashboard页面获取家庭数据时未传递family_id的问题
- 更新家庭API文档,将member_user_id参数改为支持数组的user_ids
- 移除MyFamily页面的模拟数据,使用真实API数据
- 为成员头像添加默认头像处理
- 实现退出家庭和移除成员的实际API调用
/*
* @Date: 2024-01-01 00:00:00
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2025-09-03 11:25:11
* @LastEditTime: 2025-09-03 16:51:51
* @FilePath: /lls_program/src/api/family.js
* @Description: 家庭相关接口
*/
......@@ -168,7 +168,7 @@ export const switchCurrentFamilyAPI = (params) => fn(fetch.post(Api.SWITCH_CURRE
* @description: 退出或移出家庭成员
* @param {Object} params - 请求参数
* @param {number} params.family_id - 家庭ID
* @param {number} [params.member_user_id] - 成员用户ID(主动退出时不传,创建者移出时传递)
* @param {number|Array} [params.user_ids] - 成员用户ID(主动退出时不传,创建者移出时传递)
* @returns {Promise} 返回操作结果
* @returns {Object} response - 响应对象
* @returns {string} response.code - 响应状态码
......
......@@ -329,7 +329,7 @@ const family_id = ref('');
const totalFamilySteps = ref(0);
const initPageData = async () => {
const { code, data } = await getFamilyDashboardAPI({ family_id: family_id.value });
const { code, data } = await getFamilyDashboardAPI();
if (code) {
// 获取用户信息
console.warn(data);
......
<!--
* @Date: 2022-09-19 14:11:06
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2025-09-03 11:34:55
* @LastEditTime: 2025-09-03 16:18:16
* @FilePath: /lls_program/src/pages/MyFamily/index.vue
* @Description: 我的家庭页面 - 展示用户加入的家庭列表
-->
......@@ -56,7 +56,7 @@
<image
v-for="(member, index) in family?.users?.slice(0, 4) || []"
:key="member.id"
:src="member.avatar"
:src="member.avatar_url || defaultAvatar"
class="avatar-item w-8 h-8 rounded-full border-2 border-white object-cover"
:style="{ zIndex: 10 - index }"
/>
......@@ -165,7 +165,7 @@
<!-- 头像 -->
<image
:src="member.avatar"
:src="member.avatar_url || defaultAvatar"
class="w-10 h-10 rounded-full ml-3 object-cover flex-shrink-0"
/>
......@@ -221,9 +221,11 @@ import Taro, { useDidShow } from '@tarojs/taro';
import { Home } from '@nutui/icons-vue-taro';
import './index.less';
// 获取接口信息
import { getMyFamiliesAPI, switchCurrentFamilyAPI } from '@/api/family';
import { getMyFamiliesAPI, switchCurrentFamilyAPI, deleteFamilyMemberAPI } from '@/api/family';
//
const defaultFamilyCoverSvg = 'https://cdn.ipadbiz.cn/lls_prog/images/default-family-cover.png';
// 默认头像
const defaultAvatar = 'https://cdn.ipadbiz.cn/mlaj/images/icon_1.jpeg'
// 获取接口数据
// 响应式数据
......@@ -244,46 +246,6 @@ const initPageData = async () => {
familyList.value = data;
console.warn(data);
}
// 模拟家庭数据 - 添加is_my字段用于测试
familyList.value = [
{
id: 1,
name: '幸福之家',
created_by_nickname: '张明明',
avatar_url: 'https://images.unsplash.com/photo-1511895426328-dc8714191300?w=400&h=200&fit=crop',
is_current_family: true,
is_my: true, // 当前用户是家长,可以管理成员
users: [
{ 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: '欢乐之家',
created_by_nickname: '李志强',
avatar_url: 'https://images.unsplash.com/photo-1502086223501-7ea6ecd79368?w=400&h=200&fit=crop',
is_current_family: false,
is_my: false, // 当前用户不是家长
users: [
{ 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: '快乐之家',
created_by_nickname: '王芳',
avatar_url: 'https://images.unsplash.com/photo-1502086223501-7ea6ecd79368?w=400&h=200&fit=crop',
is_current_family: false,
is_my: true, // 当前用户是家长,但不在此家庭
users: [
{ 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' }
]
}
];
};
// 如果家庭列表存在时, 才显示加入新家庭的按钮
......@@ -304,7 +266,7 @@ const switchToFamily = async (familyId) => {
content: `确定要切换到「${family.name}」吗?`,
success: async (res) => {
if (res.confirm) {
const { code } = await switchCurrentFamilyAPI(familyId);
const { code } = await switchCurrentFamilyAPI({ family_id: familyId });
if (code) {
// 切换家庭逻辑 - 先清除所有当前标记,再设置新的当前家庭
familyList.value = familyList.value.map(f => ({
......@@ -327,7 +289,7 @@ const switchToFamily = async (familyId) => {
* 退出家庭
* @param {number} familyId - 家庭ID
*/
const exitFamily = (familyId) => {
const exitFamily = async (familyId) => {
const family = familyList.value.find(f => f.id === familyId);
if (!family) return;
......@@ -343,31 +305,45 @@ const exitFamily = (familyId) => {
Taro.showModal({
title: '退出家庭',
content: `确定要退出「${family.name}」吗?退出后将无法查看该家庭的相关信息。`,
success: (res) => {
success: async (res) => {
if (res.confirm) {
// 退出家庭逻辑
const exitingFamily = familyList.value.find(f => f.id === familyId);
if (exitingFamily?.is_current_family) {
// 如果退出的是当前家庭,需要返回我的页面
familyList.value = familyList.value.filter(f => f.id !== familyId);
Taro.showToast({
title: '已退出家庭',
icon: 'success'
try {
// 调用退出家庭API(主动退出时不传user_ids)
const { code } = await deleteFamilyMemberAPI({
family_id: familyId
});
// 延迟返回我的页面
setTimeout(() => {
Taro.navigateBack();
}, 1500);
} else {
// 退出非当前家庭
familyList.value = familyList.value.filter(f => f.id !== familyId);
if (code) {
const exitingFamily = familyList.value.find(f => f.id === familyId);
if (exitingFamily?.is_current_family) {
// 如果退出的是当前家庭,需要返回我的页面
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'
});
}
}
} catch (error) {
console.error('退出家庭失败:', error);
Taro.showToast({
title: '已退出家庭',
icon: 'success'
title: '退出失败,请重试',
icon: 'none'
});
}
}
......@@ -392,44 +368,12 @@ const joinNewFamily = () => {
*/
const showMemberManagement = (family) => {
currentFamily.value = family;
// 生成模拟成员数据
currentMembers.value = [
{
id: 1,
nickname: '张明明',
avatar: 'https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?w=100&h=100&fit=crop&crop=face',
role: '父亲',
is_my: true
},
{
id: 2,
nickname: '李美丽',
avatar: 'https://images.unsplash.com/photo-1438761681033-6461ffad8d80?w=100&h=100&fit=crop&crop=face',
role: '母亲',
is_my: false
},
{
id: 3,
nickname: '张小明',
avatar: 'https://images.unsplash.com/photo-1500648767791-00dcc994a43e?w=100&h=100&fit=crop&crop=face',
role: '儿子',
is_my: false
},
{
id: 4,
nickname: '张小花',
avatar: 'https://images.unsplash.com/photo-1494790108755-2616b612b786?w=100&h=100&fit=crop&crop=face',
role: '女儿',
is_my: false
},
{
id: 5,
nickname: '王奶奶',
avatar: 'https://images.unsplash.com/photo-1551836022-d5d88e9218df?w=100&h=100&fit=crop&crop=face',
role: '奶奶',
is_my: false
}
];
// 生成成员数据
currentMembers.value = family.users.map(user => ({
...user,
is_my: user.is_creator
}));
//
selectedMembers.value = [];
showMemberPopup.value = true;
};
......@@ -471,7 +415,7 @@ const toggleMemberSelection = (memberId) => {
/**
* 移除选中的成员
*/
const removeSelectedMembers = () => {
const removeSelectedMembers = async () => {
if (selectedMembers.value.length === 0) {
Taro.showToast({
title: '请选择要移除的成员',
......@@ -488,16 +432,41 @@ const removeSelectedMembers = () => {
Taro.showModal({
title: '移除成员',
content: `确定要移除「${selectedNames}」吗?移除后他们将无法访问家庭信息。`,
success: (res) => {
success: async (res) => {
if (res.confirm) {
// 从模拟数据中移除选中的成员
currentMembers.value = currentMembers.value.filter(m => !selectedMembers.value.includes(m.id));
selectedMembers.value = [];
Taro.showToast({
title: '移除成功',
icon: 'success'
});
try {
// 调用移除成员API(创建者移除时传递user_ids)
const { code } = await deleteFamilyMemberAPI({
family_id: currentFamily.value.id,
user_ids: selectedMembers.value
});
if (code) {
// 从当前成员列表中移除选中的成员
currentMembers.value = currentMembers.value.filter(m => !selectedMembers.value.includes(m.id));
// 同时更新家庭列表中对应家庭的成员数据
const familyIndex = familyList.value.findIndex(f => f.id === currentFamily.value.id);
if (familyIndex !== -1) {
familyList.value[familyIndex].users = familyList.value[familyIndex].users.filter(
user => !selectedMembers.value.includes(user.id)
);
}
selectedMembers.value = [];
Taro.showToast({
title: '移除成功',
icon: 'success'
});
}
} catch (error) {
console.error('移除成员失败:', error);
Taro.showToast({
title: '移除失败,请重试',
icon: 'none'
});
}
}
}
});
......