智慧教务系统
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

501 lines
10 KiB

<!--添加孩子页面-->
<template>
<view class="add_child_container">
<!-- 自定义导航栏 -->
<view class="navbar_section">
<view class="navbar_content">
<view class="back_button" @click="goBack">
<image src="/static/icon-img/back.png" class="back_icon"></image>
</view>
<view class="navbar_title">添加孩子</view>
<view class="navbar_placeholder"></view>
</view>
</view>
<!-- 表单区域 -->
<view class="form_section">
<view class="form_card">
<view class="form_title">孩子基本信息</view>
<!-- 头像选择 -->
<view class="form_item">
<view class="item_label">头像</view>
<view class="avatar_selector" @click="selectAvatar">
<image
:src="formData.headimg || '/static/default-avatar.png'"
class="avatar_preview"
mode="aspectFill"
></image>
<view class="avatar_text">点击选择头像</view>
</view>
</view>
<!-- 姓名输入 -->
<view class="form_item">
<view class="item_label required">姓名</view>
<input
v-model="formData.name"
placeholder="请输入孩子姓名"
class="form_input"
maxlength="20"
/>
</view>
<!-- 性别选择 -->
<view class="form_item">
<view class="item_label required">性别</view>
<view class="gender_selector">
<view
:class="['gender_option', formData.gender === '1' ? 'active' : '']"
@click="selectGender('1')"
>
<image src="/static/icon-img/male.png" class="gender_icon"></image>
<text>男孩</text>
</view>
<view
:class="['gender_option', formData.gender === '2' ? 'active' : '']"
@click="selectGender('2')"
>
<image src="/static/icon-img/female.png" class="gender_icon"></image>
<text>女孩</text>
</view>
</view>
</view>
<!-- 出生日期 -->
<view class="form_item">
<view class="item_label required">出生日期</view>
<picker
mode="date"
:value="formData.birthday"
@change="onBirthdayChange"
class="date_picker"
>
<view class="picker_display">
{{ formData.birthday || '请选择出生日期' }}
</view>
</picker>
</view>
<!-- 紧急联系人 -->
<view class="form_item">
<view class="item_label">紧急联系人</view>
<input
v-model="formData.emergency_contact"
placeholder="请输入紧急联系人姓名"
class="form_input"
maxlength="20"
/>
</view>
<!-- 联系电话 -->
<view class="form_item">
<view class="item_label">联系电话</view>
<input
v-model="formData.contact_phone"
placeholder="请输入联系电话"
class="form_input"
type="number"
maxlength="11"
/>
</view>
<!-- 备注信息 -->
<view class="form_item">
<view class="item_label">备注</view>
<textarea
v-model="formData.note"
placeholder="请输入备注信息(选填)"
class="form_textarea"
maxlength="500"
></textarea>
</view>
</view>
</view>
<!-- 提交按钮 -->
<view class="submit_section">
<button
class="submit_button"
@click="submitForm"
:disabled="submitting"
>
{{ submitting ? '提交中...' : '添加孩子' }}
</button>
</view>
</view>
</template>
<script>
import apiRoute from '@/api/member.js'
export default {
data() {
return {
formData: {
name: '',
gender: '1', // '1':男 '2':女
birthday: '',
headimg: '',
emergency_contact: '',
contact_phone: '',
note: ''
},
submitting: false,
uploadingAvatar: false
}
},
methods: {
goBack() {
uni.navigateBack()
},
selectAvatar() {
uni.chooseImage({
count: 1,
sizeType: ['original', 'compressed'],
sourceType: ['album', 'camera'],
success: (res) => {
const tempFilePath = res.tempFilePaths[0]
this.formData.headimg = tempFilePath
// 这里可以上传图片到服务器
this.uploadAvatar(tempFilePath)
},
fail: (err) => {
console.error('选择图片失败:', err)
}
})
},
async uploadAvatar(filePath) {
this.uploadingAvatar = true
uni.showLoading({
title: '上传中...'
})
try {
// 调用头像上传API(暂时不需要student_id,因为是新增孩子)
const response = await apiRoute.uploadAvatarForAdd(filePath)
console.log('头像上传响应:', response)
if (response.code === 1) {
// 更新表单中的头像字段
this.formData.headimg = response.data.url
uni.showToast({
title: '头像上传成功',
icon: 'success'
})
} else {
throw new Error(response.msg || '上传失败')
}
} catch (error) {
console.error('头像上传失败:', error)
uni.showToast({
title: error.message || '头像上传失败',
icon: 'none'
})
// 恢复本地预览图片
this.formData.headimg = filePath
} finally {
uni.hideLoading()
this.uploadingAvatar = false
}
},
selectGender(gender) {
this.formData.gender = gender
},
onBirthdayChange(e) {
this.formData.birthday = e.detail.value
},
validateForm() {
if (!this.formData.name.trim()) {
uni.showToast({
title: '请输入孩子姓名',
icon: 'none'
})
return false
}
if (!this.formData.gender) {
uni.showToast({
title: '请选择性别',
icon: 'none'
})
return false
}
if (!this.formData.birthday) {
uni.showToast({
title: '请选择出生日期',
icon: 'none'
})
return false
}
// 手机号验证
if (this.formData.contact_phone && !/^1[3-9]\d{9}$/.test(this.formData.contact_phone)) {
uni.showToast({
title: '请输入正确的手机号',
icon: 'none'
})
return false
}
return true
},
async submitForm() {
if (!this.validateForm()) {
return
}
this.submitting = true
try {
console.log('提交表单数据:', this.formData)
// 调用真实API
const response = await apiRoute.addChild(this.formData)
console.log('添加孩子API响应:', response)
if (response.code === 1) {
uni.showToast({
title: '添加成功',
icon: 'success'
})
// 延迟跳转,让用户看到成功提示
setTimeout(() => {
uni.navigateBack()
}, 1500)
} else {
uni.showToast({
title: response.msg || '添加失败',
icon: 'none'
})
}
} catch (error) {
console.error('添加孩子失败:', error)
uni.showToast({
title: error.message || '添加失败',
icon: 'none'
})
} finally {
this.submitting = false
}
}
}
}
</script>
<style lang="less" scoped>
.add_child_container {
background: #f8f9fa;
min-height: 100vh;
}
// 自定义导航栏
.navbar_section {
background: linear-gradient(135deg, #29D3B4 0%, #1BA297 100%);
padding: 40rpx 32rpx 32rpx;
// 小程序端适配状态栏
// #ifdef MP-WEIXIN
padding-top: 80rpx;
// #endif
.navbar_content {
display: flex;
align-items: center;
justify-content: space-between;
.back_button {
width: 40rpx;
height: 40rpx;
display: flex;
align-items: center;
justify-content: center;
.back_icon {
width: 24rpx;
height: 24rpx;
}
}
.navbar_title {
color: #fff;
font-size: 36rpx;
font-weight: 600;
}
.navbar_placeholder {
width: 40rpx;
}
}
}
// 表单区域
.form_section {
padding: 32rpx 20rpx;
.form_card {
background: #fff;
border-radius: 16rpx;
padding: 32rpx;
.form_title {
font-size: 32rpx;
font-weight: 600;
color: #333;
margin-bottom: 32rpx;
text-align: center;
}
.form_item {
margin-bottom: 32rpx;
.item_label {
font-size: 28rpx;
color: #333;
margin-bottom: 16rpx;
font-weight: 500;
&.required::after {
content: '*';
color: #ff4757;
margin-left: 4rpx;
}
}
.form_input {
width: 100%;
padding: 24rpx;
background: #f8f9fa;
border-radius: 12rpx;
border: 1px solid #e9ecef;
font-size: 28rpx;
color: #333;
&:focus {
border-color: #29d3b4;
}
}
.form_textarea {
width: 100%;
min-height: 120rpx;
padding: 24rpx;
background: #f8f9fa;
border-radius: 12rpx;
border: 1px solid #e9ecef;
font-size: 28rpx;
color: #333;
resize: none;
}
// 头像选择器
.avatar_selector {
display: flex;
align-items: center;
gap: 24rpx;
padding: 24rpx;
background: #f8f9fa;
border-radius: 12rpx;
border: 1px solid #e9ecef;
.avatar_preview {
width: 100rpx;
height: 100rpx;
border-radius: 50%;
border: 2px solid #29d3b4;
}
.avatar_text {
font-size: 28rpx;
color: #666;
}
}
// 性别选择器
.gender_selector {
display: flex;
gap: 32rpx;
.gender_option {
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
gap: 12rpx;
padding: 32rpx 20rpx;
background: #f8f9fa;
border-radius: 12rpx;
border: 2px solid #e9ecef;
&.active {
border-color: #29d3b4;
background: rgba(41, 211, 180, 0.1);
text {
color: #29d3b4;
font-weight: 600;
}
}
.gender_icon {
width: 48rpx;
height: 48rpx;
}
text {
font-size: 26rpx;
color: #666;
}
}
}
// 日期选择器
.date_picker {
.picker_display {
width: 100%;
padding: 24rpx;
background: #f8f9fa;
border-radius: 12rpx;
border: 1px solid #e9ecef;
font-size: 28rpx;
color: #333;
}
}
}
}
}
// 提交按钮
.submit_section {
padding: 32rpx 20rpx 60rpx;
.submit_button {
width: 100%;
background: linear-gradient(135deg, #29D3B4 0%, #1BA297 100%);
color: #fff;
border: none;
border-radius: 16rpx;
padding: 28rpx 0;
font-size: 32rpx;
font-weight: 600;
&:disabled {
opacity: 0.6;
}
&:active:not(:disabled) {
opacity: 0.8;
}
}
}
</style>