更新宝贝监护功能

This commit is contained in:
扫地僧 2026-02-04 23:45:55 +08:00
parent 649da2a6fd
commit eec987041c
6 changed files with 621 additions and 218 deletions

3
.env development Normal file
View File

@ -0,0 +1,3 @@
# 开发环境接口
# VITE_API_BASE_URL='https://backend.yunzer.cn'
VITE_API_BASE_URL = 'http://localhost:8000'

View File

@ -20,7 +20,7 @@ export function getBabyList() {
* @param {number} id 宝贝ID
* @returns {Promise}
*/
export function getDetail(id) {
export function getBabyDetail(id) {
return request({
url: `/admin/babys/${id}`,
method: "get",
@ -32,7 +32,7 @@ export function getDetail(id) {
* @param {Object} data 宝贝数据
* @returns {Promise}
*/
export function create(data) {
export function createBaby(data) {
return request({
url: "/admin/babys",
method: "post",
@ -49,14 +49,11 @@ export function create(data) {
* @param {Object} data 更新的数据
* @returns {Promise}
*/
export function update(id, data) {
export function editBaby(id, data) {
return request({
url: `/admin/babys/${id}`,
method: "put",
data: data,
headers: {
"Content-Type": "multipart/form-data"
}
method: "post",
data: { ...data, _method: 'PUT' }
});
}
@ -65,13 +62,39 @@ export function update(id, data) {
* @param {number} id 宝贝ID
* @returns {Promise}
*/
export function del(id) {
export function deleteBaby(id) {
return request({
url: `/admin/babys/${id}`,
method: "delete",
});
}
/**
* 绑定父母
* @param {number} id 宝贝ID
* @param {Object} data 绑定数据
* @returns {Promise}
*/
export function bindParent(id, data) {
return request({
url: `/admin/babys/bindparents/${id}`,
method: "post",
data: data,
});
}
/**
* 获取父母
* @param {number} id 宝贝ID
* @returns {Promise}
*/
export function getParents(id) {
return request({
url: `/admin/babys/getParents/${id}`,
method: "get",
});
}
/*************************************************
****************** 用户相关接口 ******************
*************************************************/
@ -124,7 +147,7 @@ export function createUser(data) {
export function updateUser(id, data) {
return request({
url: `/admin/babyhealthUser/${id}`,
method: "put",
method: "post",
data: data,
headers: {
"Content-Type": "multipart/form-data"

View File

@ -1,42 +0,0 @@
import request from '@/utils/request';
/**
* 上传头像
* @param {FormData} data 表单数据
* @param {Object} params 查询参数
* @returns {Promise} Promise对象
*/
export function uploadAvatar(data, params) {
return request({
url: '/admin/uploadavatar',
method: 'post',
data,
params,
headers: {
'Content-Type': 'multipart/form-data',
},
});
}
/**
* 上传文件
* @param {FormData} data 表单数据
* @param {Object} params 查询参数
* @returns {Promise} Promise对象
*/
export function uploadFile(data, params) {
return request({
url: '/admin/upload',
method: 'post',
data,
params,
headers: {
'Content-Type': 'multipart/form-data',
},
});
}
export default {
uploadAvatar,
uploadFile
};

View File

@ -0,0 +1,369 @@
<template>
<el-dialog
v-model="dialogVisible"
title="绑定父母"
width="500px"
:close-on-click-modal="false"
@close="handleClose"
>
<el-form ref="formRef" :model="formData" :rules="formRules" label-width="80px">
<el-form-item label="父亲">
<div class="parent-selector">
<el-select
v-model="formData.father_id"
placeholder="请输入手机号或者账号"
clearable
filterable
remote
reserve-keyword
:remote-method="(query) => handleSearchUser(query, 1)"
:loading="searchLoading"
style="width: 100%"
>
<template #default>
<div class="search-tip">支持账号/手机号搜索</div>
<el-option
v-for="user in maleUsers"
:key="user.id"
:label="user.name || user.account"
:value="user.id"
>
<div class="user-option">
<span class="user-name">{{ user.name || user.account }}</span>
<span class="user-phone">{{ user.phone }}</span>
</div>
</el-option>
</template>
</el-select>
<el-button link type="primary" @click="handleSearchUser('', 1)">
<i class="fa-solid fa-refresh"></i> 刷新列表
</el-button>
</div>
</el-form-item>
<el-form-item label="母亲">
<div class="parent-selector">
<el-select
v-model="formData.mother_id"
placeholder="请输入手机号或者账号"
clearable
filterable
remote
reserve-keyword
:remote-method="(query) => handleSearchUser(query, 2)"
:loading="searchLoading"
style="width: 100%"
>
<template #default>
<div class="search-tip">支持账号/手机号搜索</div>
<el-option
v-for="user in femaleUsers"
:key="user.id"
:label="user.name || user.account"
:value="user.id"
>
<div class="user-option">
<span class="user-name">{{ user.name || user.account }}</span>
<span class="user-phone">{{ user.phone }}</span>
</div>
</el-option>
</template>
</el-select>
<el-button link type="primary" @click="handleSearchUser('', 2)">
<i class="fa-solid fa-refresh"></i> 刷新列表
</el-button>
</div>
</el-form-item>
</el-form>
<template #footer>
<el-button @click="handleClose">取消</el-button>
<el-button type="primary" :loading="loading" @click="handleSubmit">确定</el-button>
</template>
</el-dialog>
</template>
<script setup lang="ts">
import { ref, reactive, watch, computed } from 'vue';
import { ElMessage, type FormInstance, type FormRules } from 'element-plus';
import { bindParent, getParents, getUserList } from '@/api/babyhealth';
interface Baby {
id: number;
name: string;
nickname: string;
avatar: string;
}
interface User {
id: number;
name: string;
account: string;
phone: string;
sex: number;
}
const props = defineProps<{
visible: boolean;
babyData?: Baby | null;
}>();
const emit = defineEmits<{
'update:visible': [value: boolean];
success: [];
}>();
const dialogVisible = ref(false);
const loading = ref(false);
const searchLoading = ref(false);
const formRef = ref<FormInstance>();
const users = ref<User[]>([]);
const allUsers = ref<User[]>([]);
const parents = ref<User[]>([]);
const formData = reactive<{
father_id: number | null;
mother_id: number | null;
}>({
father_id: null,
mother_id: null,
});
const formRules: FormRules = {};
//
const maleUsers = computed(() => {
return users.value.filter(user => user.sex === 1);
});
//
const femaleUsers = computed(() => {
return users.value.filter(user => user.sex === 2);
});
//
const getEnvUrl = (path: string) => {
const API_BASE_URL = import.meta.env.VITE_API_BASE_URL;
return `${API_BASE_URL}${path}`;
};
//
const resetForm = () => {
formData.father_id = null;
formData.mother_id = null;
};
//
const handleClose = () => {
dialogVisible.value = false;
resetForm();
};
// visible
watch(() => props.visible, (val) => {
dialogVisible.value = val;
if (val) {
fetchUsers();
}
});
//
watch(dialogVisible, (val) => {
if (!val) {
users.value = parents.value;
}
});
// dialogVisible
watch(dialogVisible, (val) => {
emit('update:visible', val);
});
//
const fetchUsers = async () => {
try {
//
const res = await getUserList();
if (res.code === 200) {
allUsers.value = res.data || [];
users.value = res.data || [];
}
//
if (props.babyData?.id) {
const parentsRes = await getParents(props.babyData.id);
if (parentsRes.code === 200 && parentsRes.data) {
formData.father_id = parentsRes.data.father_id || null;
formData.mother_id = parentsRes.data.mother_id || null;
// 便
if (parentsRes.data.father_id && parentsRes.data.father) {
const fatherExists = allUsers.value.some(u => u.id === parentsRes.data.father_id);
if (!fatherExists) {
allUsers.value.push({
id: parentsRes.data.father_id,
name: parentsRes.data.father,
account: '',
phone: '',
sex: 1
});
}
}
// 便
if (parentsRes.data.mother_id && parentsRes.data.mother) {
const motherExists = allUsers.value.some(u => u.id === parentsRes.data.mother_id);
if (!motherExists) {
allUsers.value.push({
id: parentsRes.data.mother_id,
name: parentsRes.data.mother,
account: '',
phone: '',
sex: 2
});
}
}
//
users.value = allUsers.value;
}
}
} catch (error) {
console.error('获取数据失败:', error);
ElMessage.error('获取数据失败');
}
};
//
const handleSearchUser = async (query: string, sex: number) => {
searchLoading.value = true;
try {
if (!query) {
//
users.value = allUsers.value.filter(user => user.sex === sex);
} else {
//
const filteredUsers = allUsers.value.filter(user => {
const isTargetSex = user.sex === sex;
const matchAccount = user.account?.toLowerCase().includes(query.toLowerCase());
const matchPhone = user.phone?.includes(query);
const matchName = user.name?.toLowerCase().includes(query.toLowerCase());
return isTargetSex && (matchAccount || matchPhone || matchName);
});
users.value = filteredUsers;
}
} catch (error) {
console.error('搜索用户失败:', error);
ElMessage.error('搜索用户失败');
} finally {
searchLoading.value = false;
}
};
//
const handleSubmit = async () => {
if (!formRef.value) return;
if (!props.babyData?.id) {
ElMessage.error('宝贝信息不存在');
return;
}
loading.value = true;
try {
const submitData: Record<string, any> = {};
if (formData.father_id) {
submitData.father_id = formData.father_id;
}
if (formData.mother_id) {
submitData.mother_id = formData.mother_id;
}
const res = await bindParent(props.babyData.id, submitData);
if (res.code === 200) {
ElMessage.success('绑定成功');
dialogVisible.value = false;
resetForm();
emit('success');
} else {
ElMessage.error(res.msg || '绑定失败');
}
} catch (error) {
console.error('绑定失败:', error);
ElMessage.error('绑定失败');
} finally {
loading.value = false;
}
};
</script>
<style scoped lang="scss">
.baby-info-display {
display: flex;
align-items: center;
gap: 12px;
padding: 12px;
background: var(--el-fill-color-light);
border-radius: 8px;
.baby-avatar-mini {
width: 50px;
height: 50px;
border-radius: 50%;
object-fit: cover;
}
.baby-info-text {
flex: 1;
.baby-name {
font-size: 16px;
font-weight: 600;
color: var(--el-text-color-primary);
margin-bottom: 4px;
}
.baby-nickname {
font-size: 14px;
color: var(--el-text-color-regular);
}
}
}
.parent-selector {
display: flex;
gap: 8px;
align-items: center;
width: 100%;
.el-select {
flex: 1;
}
}
.search-tip {
padding: 8px 12px;
font-size: 12px;
color: var(--el-text-color-secondary);
border-bottom: 1px solid var(--el-border-color-lighter);
background: var(--el-fill-color-lighter);
}
.user-option {
display: flex;
justify-content: space-between;
align-items: center;
width: 100%;
.user-name {
flex: 1;
}
.user-phone {
margin-left: 12px;
color: var(--el-text-color-secondary);
font-size: 12px;
}
}
</style>

View File

@ -6,90 +6,99 @@
:close-on-click-modal="false"
@close="handleClose"
>
<el-form ref="editFormRef" :model="formData" :rules="formRules" label-width="100px">
<el-form-item label="姓名" prop="name">
<el-input v-model="formData.name" placeholder="请输入姓名" clearable />
</el-form-item>
<el-form-item label="昵称" prop="nickname">
<el-input v-model="formData.nickname" placeholder="请输入昵称" clearable />
</el-form-item>
<el-form-item label="性别" prop="sex">
<el-radio-group v-model="formData.sex">
<el-radio :value="1"></el-radio>
<el-radio :value="2"></el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="出生日期" prop="birth">
<el-date-picker
v-model="formData.birth"
type="date"
placeholder="选择出生日期"
style="width: 100%"
format="YYYY-MM-DD"
value-format="YYYY-MM-DD"
/>
</el-form-item>
<el-form-item label="身高" prop="height">
<el-input-number
v-model="formData.height"
:min="0"
:max="200"
:precision="1"
:step="0.5"
controls-position="right"
style="width: 100%"
/>
<span style="margin-left: 8px; color: var(--el-text-color-regular)">cm</span>
</el-form-item>
<el-form-item label="体重" prop="weight">
<el-input-number
v-model="formData.weight"
:min="0"
:max="50"
:precision="2"
:step="0.01"
controls-position="right"
style="width: 100%"
/>
<span style="margin-left: 8px; color: var(--el-text-color-regular)">kg</span>
</el-form-item>
<el-form-item label="头像">
<div class="dialog-content">
<!-- 头像上传区域 -->
<div class="avatar-section">
<el-upload
:action="uploadUrl"
:show-file-list="false"
:on-success="handleAvatarSuccess"
:before-upload="beforeAvatarUpload"
:http-request="uploadFile"
:headers="uploadHeaders"
class="avatar-uploader"
>
<img v-if="formData.avatar" :src="getEnvUrl(formData.avatar)" class="avatar-preview" />
<el-icon v-else class="avatar-uploader-icon"><Plus /></el-icon>
<el-image
v-if="formData.avatar"
:src="getEnvUrl(formData.avatar)"
class="avatar-preview"
fit="cover"
:preview-src-list="[getEnvUrl(formData.avatar)]"
:initial-index="0"
/>
<div v-else class="avatar-placeholder">
<el-icon class="avatar-uploader-icon"><Plus /></el-icon>
<span class="avatar-tip">点击上传头像</span>
</div>
</el-upload>
</div>
<!-- 表单区域 -->
<el-form ref="editFormRef" :model="formData" :rules="formRules" label-width="100px">
<el-form-item label="姓名" prop="name">
<el-input v-model="formData.name" placeholder="请输入姓名" clearable />
</el-form-item>
<el-form-item label="小名" prop="nickname">
<el-input v-model="formData.nickname" placeholder="请输入小名" clearable />
</el-form-item>
<el-form-item label="性别" prop="sex">
<el-radio-group v-model="formData.sex">
<el-radio :value="1"></el-radio>
<el-radio :value="2"></el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="出生日期" prop="birth">
<el-date-picker
v-model="formData.birth"
type="date"
placeholder="选择出生日期"
style="width: 100%"
format="YYYY-MM-DD"
value-format="YYYY-MM-DD"
/>
</el-form-item>
<el-form-item label="身高" prop="height">
<el-input
v-model="formData.height"
:min="0"
:max="200"
:precision="1"
:step="0.5"
controls-position="right"
style="width: 100%"
>
<template #append>CM</template>
</el-input>
</el-form-item>
<el-form-item label="体重" prop="weight">
<el-input
v-model="formData.weight"
:min="0"
:max="50"
:precision="2"
:step="0.01"
controls-position="right"
style="width: 100%"
>
<template #append>KG</template>
</el-input>
</el-form-item>
<el-form-item label="状态" prop="status">
<el-radio-group v-model="formData.status">
<el-radio :value="1">正常</el-radio>
<el-radio :value="0">禁用</el-radio>
</el-radio-group>
</el-form-item>
</el-form>
<el-form-item label="状态" prop="status">
<el-radio-group v-model="formData.status">
<el-radio :value="1">正常</el-radio>
<el-radio :value="0">禁用</el-radio>
</el-radio-group>
</el-form-item>
</el-form>
</div>
<template #footer>
<el-button @click="handleClose">取消</el-button>
<el-button type="primary" :loading="loading" @click="handleSubmit">确定</el-button>
</template>
<!-- 预览对话框 -->
<el-dialog v-model="previewVisible" title="头像预览" width="500px">
<img w-full :src="getEnvUrl(previewImageUrl)" alt="Preview Image" style="width: 100%" />
</el-dialog>
</el-dialog>
</template>
@ -97,8 +106,8 @@
import { ref, reactive, watch } from 'vue';
import { ElMessage, type FormInstance, type FormRules } from 'element-plus';
import { Plus } from '@element-plus/icons-vue';
import { createBaby, updateBaby } from '@/api/babyhealth';
import { uploadAvatar } from '@/api/upload';
import { createBaby, editBaby } from '@/api/babyhealth';
import { uploadAvatar } from '@/api/file';
interface BabyFormData {
id: number;
@ -119,12 +128,10 @@ const props = defineProps<{
const emit = defineEmits<{
'update:visible': [value: boolean];
submit: [data: BabyFormData];
success: [];
}>();
const dialogVisible = ref(false);
const previewVisible = ref(false);
const previewImageUrl = ref('');
const loading = ref(false);
const editFormRef = ref<FormInstance>();
const fileList = ref<any[]>([]);
@ -208,45 +215,44 @@ watch(() => props.editData, (data) => {
}
}, { immediate: true });
//
const uploadUrl = import.meta.env.VITE_API_BASE_URL + "/admin/uploadavatar";
const uploadHeaders = {
'Content-Type': 'multipart/form-data'
};
//
const beforeAvatarUpload = (file: any) => {
const isImage = file.type.startsWith('image/');
const isLt5M = file.size / 1024 / 1024 < 5;
if (!isImage) {
ElMessage.error('仅支持图片格式');
return false;
}
return false;
if (!isLt5M) {
ElMessage.error('图片大小不能超过5MB');
return false;
}
return true;
};
//
const uploadFile = async (options: any) => {
const { file } = options;
const formData = new FormData();
formData.append('file', file);
const uploadFormData = new FormData();
uploadFormData.append('file', file);
try {
// 使uploadAvatar
const response = await uploadAvatar(formData, { cate: 'baby_avatar' });
if (response.code === 200) {
const response = await uploadAvatar(uploadFormData, { cate: 'baby_avatar' });
if (response.code === 200 || response.code === 201) {
//
const avatarUrl = response.data.url || response.data.path || '';
formData.avatar = avatarUrl;
//
if (formData.id) {
await updateBaby(formData.id, { avatar: avatarUrl });
if (response.code === 201) {
ElMessage.info("文件已存在,使用已有图片");
} else {
ElMessage.success("头像上传成功");
}
ElMessage.success("头像上传成功");
} else {
ElMessage.error(response.msg || "上传失败");
}
@ -256,23 +262,6 @@ const uploadFile = async (options: any) => {
}
};
//
const handleAvatarSuccess = (response: any) => {
if (response.code === 200) {
const avatarUrl = response.data.url || response.data.path || '';
formData.avatar = avatarUrl;
//
if (formData.id) {
updateBaby(formData.id, { avatar: avatarUrl });
}
ElMessage.success("头像上传成功");
} else {
ElMessage.error(response.msg || "上传失败");
}
};
//
const handleUploadChange = (file: any) => {
if (file.raw) {
@ -291,11 +280,6 @@ const handleRemove = (file: any) => {
formData.avatar = '';
};
const handlePictureCardPreview = (file: any) => {
previewImageUrl.value = file.url;
previewVisible.value = true;
};
//
const handleSubmit = async () => {
if (!editFormRef.value) return;
@ -311,7 +295,7 @@ const handleSubmit = async () => {
uploadFormData.append('cate', 'baby');
const uploadRes = await uploadAvatar(uploadFormData);
if (uploadRes.code === 200 && uploadRes.data?.url) {
if ((uploadRes.code === 200 || uploadRes.code === 201) && uploadRes.data?.url) {
formData.avatar = uploadRes.data.url;
} else {
ElMessage.error('图片上传失败');
@ -319,10 +303,35 @@ const handleSubmit = async () => {
}
}
//
emit('submit', { ...formData });
dialogVisible.value = false;
resetForm();
let res;
if (formData.id) {
// - 使PUT
const submitData: Record<string, any> = {};
Object.keys(formData).forEach(key => {
if (key !== 'id' && formData[key as keyof BabyFormData] !== undefined && formData[key as keyof BabyFormData] !== null) {
submitData[key] = formData[key as keyof BabyFormData];
}
});
res = await editBaby(formData.id, submitData);
} else {
// - 使 FormData
const submitData = new FormData();
Object.keys(formData).forEach(key => {
if (key !== 'id' && formData[key as keyof BabyFormData] !== undefined && formData[key as keyof BabyFormData] !== null) {
submitData.append(key, String(formData[key as keyof BabyFormData]));
}
});
res = await createBaby(submitData);
}
if (res.code === 200) {
ElMessage.success(formData.id ? '编辑成功' : '添加成功');
dialogVisible.value = false;
resetForm();
emit('success'); //
} else {
ElMessage.error(res.msg || (formData.id ? '编辑失败' : '添加失败'));
}
} catch (error) {
console.error('提交失败:', error);
ElMessage.error('提交失败');
@ -335,39 +344,80 @@ const handleSubmit = async () => {
</script>
<style scoped lang="scss">
.dialog-content {
display: flex;
flex-direction: column;
}
.avatar-section {
display: flex;
justify-content: center;
align-items: center;
margin-bottom: 24px;
padding-bottom: 24px;
border-bottom: 1px solid var(--el-border-color-lighter);
}
.avatar-preview {
width: 100px;
height: 100px;
border-radius: 6px;
width: 120px;
height: 120px;
border-radius: 8px;
object-fit: cover;
display: block;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
:deep(img) {
width: 100%;
height: 100%;
border-radius: 8px;
}
}
.avatar-uploader {
:deep(.el-upload) {
border: 1px dashed var(--el-border-color);
border-radius: 6px;
border: 2px dashed var(--el-border-color);
border-radius: 8px;
cursor: pointer;
position: relative;
overflow: hidden;
transition: var(--el-transition-duration-fast);
width: 100px;
height: 100px;
transition: all 0.3s;
width: 120px;
height: 120px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
background: var(--el-fill-color-light);
&:hover {
border-color: var(--el-color-primary);
transform: scale(1.05);
box-shadow: 0 4px 12px rgba(64, 158, 255, 0.2);
}
}
}
.avatar-placeholder {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100%;
padding: 16px;
text-align: center;
.avatar-uploader-icon {
font-size: 28px;
color: #8c939d;
width: 100px;
height: 100px;
text-align: center;
line-height: 100px;
font-size: 32px;
color: var(--el-text-color-placeholder);
margin-bottom: 8px;
}
.avatar-tip {
font-size: 12px;
color: var(--el-text-color-placeholder);
}
}
:deep(.el-upload-list__item-thumbnail) {
width: 100%;
height: 100%;

View File

@ -59,6 +59,9 @@
{{ baby.status === 1 ? '正常' : '禁用' }}
</el-tag>
<div class="baby-actions">
<el-button size="small" type="primary" link @click="handleBindParents(baby)">
<i class="fa-solid fa-link"></i>
</el-button>
<el-button size="small" type="primary" link @click="handleView(baby)">
<i class="fa-solid fa-eye"></i>
</el-button>
@ -82,7 +85,14 @@
<BabyEdit
v-model:visible="editDialogVisible"
:editData="currentBaby"
@submit="handleSubmit"
@success="handleEditSuccess"
/>
<!-- 绑定父母对话框 -->
<BindParents
v-model:visible="bindParentsVisible"
:babyData="currentBaby"
@success="handleBindParentsSuccess"
/>
</div>
</template>
@ -91,7 +101,8 @@
import { ref, onMounted } from 'vue';
import { ElMessage, ElMessageBox } from 'element-plus';
import BabyEdit from './components/edit.vue';
import { getBabyList, getDetail, create, update, del } from '@/api/babyhealth';
import BindParents from './components/bindParents.vue';
import { getBabyList, deleteBaby } from '@/api/babyhealth';
interface Baby {
id: number;
@ -109,6 +120,7 @@ interface Baby {
const loading = ref(false);
const babyList = ref<Baby[]>([]);
const editDialogVisible = ref(false);
const bindParentsVisible = ref(false);
const currentBaby = ref<Baby | null>(null);
//
@ -162,7 +174,7 @@ const handleDelete = (row: Baby) => {
.then(async () => {
try {
loading.value = true;
const res = await del(row.id);
const res = await deleteBaby(row.id);
if (res.code === 200) {
ElMessage.success('删除成功');
fetchBabyList();
@ -179,32 +191,20 @@ const handleDelete = (row: Baby) => {
.catch(() => {});
};
//
const handleSubmit = async (data: any) => {
try {
if (data.id) {
//
const res = await update(data.id, data);
if (res.code === 200) {
ElMessage.success('编辑成功');
fetchBabyList();
} else {
ElMessage.error(res.msg || '编辑失败');
}
} else {
//
const res = await create(data);
if (res.code === 200) {
ElMessage.success('添加成功');
fetchBabyList();
} else {
ElMessage.error(res.msg || '添加失败');
}
}
} catch (error) {
console.error(data.id ? '编辑失败:' : '添加失败:', error);
ElMessage.error(data.id ? '编辑失败' : '添加失败');
}
//
const handleBindParents = (row: Baby) => {
currentBaby.value = row;
bindParentsVisible.value = true;
};
// /
const handleEditSuccess = () => {
fetchBabyList();
};
//
const handleBindParentsSuccess = () => {
fetchBabyList();
};
//
@ -212,7 +212,7 @@ const fetchBabyList = async () => {
loading.value = true;
try {
const res = await getBabyList();
console.log('获取宝贝列表响应:', res);
// console.log(':', res);
if (res.code === 200) {
babyList.value = res.data || [];
} else {