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.
595 lines
14 KiB
595 lines
14 KiB
<!--学员个人信息管理页面-->
|
|
<template>
|
|
<view class="main_box">
|
|
<!-- 自定义导航栏 -->
|
|
<view class="navbar_section">
|
|
<view class="navbar_back" @click="goBack">
|
|
<text class="back_icon">‹</text>
|
|
</view>
|
|
<view class="navbar_title">个人信息管理</view>
|
|
<view class="navbar_action"></view>
|
|
</view>
|
|
|
|
<!-- 学员头像区域 -->
|
|
<view class="avatar_section">
|
|
<view class="avatar_container">
|
|
<image
|
|
:src="studentInfo.headimg || '/static/default-avatar.png'"
|
|
class="avatar_image"
|
|
mode="aspectFill"
|
|
@click="uploadAvatar"
|
|
></image>
|
|
<view class="avatar_edit_icon" @click="uploadAvatar">
|
|
<text class="edit_text">✎</text>
|
|
</view>
|
|
</view>
|
|
<view class="student_name">{{ studentInfo.name || '学员姓名' }}</view>
|
|
<view class="student_basic_info">
|
|
<text class="info_tag">{{ studentInfo.gender_text }}</text>
|
|
<text class="info_tag">{{ studentInfo.ageText }}岁</text>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 基本信息表单 -->
|
|
<view class="form_section">
|
|
<view class="section_title">基本信息</view>
|
|
|
|
<view class="form_item">
|
|
<view class="form_label">姓名</view>
|
|
<fui-input
|
|
v-model="formData.name"
|
|
placeholder="请输入学员姓名"
|
|
borderColor="transparent"
|
|
backgroundColor="#f8f9fa"
|
|
:maxlength="20"
|
|
></fui-input>
|
|
</view>
|
|
|
|
<view class="form_item">
|
|
<view class="form_label">性别</view>
|
|
<fui-input
|
|
v-model="genderText"
|
|
placeholder="请选择性别"
|
|
borderColor="transparent"
|
|
backgroundColor="#f8f9fa"
|
|
readonly
|
|
@click="showGenderPicker = true"
|
|
>
|
|
<fui-icon name="arrowdown" color="#B2B2B2" :size="40"></fui-icon>
|
|
</fui-input>
|
|
<fui-picker
|
|
:options="genderOptions"
|
|
:show="showGenderPicker"
|
|
@change="changeGender"
|
|
@cancel="showGenderPicker = false"
|
|
></fui-picker>
|
|
</view>
|
|
|
|
<view class="form_item">
|
|
<view class="form_label">生日</view>
|
|
<fui-date-picker
|
|
:show="showDatePicker"
|
|
v-model="formData.birthday"
|
|
@change="changeBirthday"
|
|
@cancel="showDatePicker = false"
|
|
>
|
|
<fui-input
|
|
:value="birthdayText"
|
|
placeholder="请选择生日"
|
|
borderColor="transparent"
|
|
backgroundColor="#f8f9fa"
|
|
readonly
|
|
@click="showDatePicker = true"
|
|
>
|
|
<fui-icon name="arrowdown" color="#B2B2B2" :size="40"></fui-icon>
|
|
</fui-input>
|
|
</fui-date-picker>
|
|
</view>
|
|
|
|
<view class="form_item">
|
|
<view class="form_label">年龄</view>
|
|
<fui-input
|
|
:value="ageText"
|
|
placeholder="根据生日自动计算"
|
|
borderColor="transparent"
|
|
backgroundColor="#f0f0f0"
|
|
readonly
|
|
></fui-input>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 体测信息(只读展示) -->
|
|
<view class="form_section">
|
|
<view class="section_title">体测信息</view>
|
|
|
|
<view class="form_item">
|
|
<view class="form_label">身高 (cm)</view>
|
|
<fui-input
|
|
:value="physicalTestInfo.height || '暂无数据'"
|
|
placeholder="暂无体测数据"
|
|
borderColor="transparent"
|
|
backgroundColor="#f0f0f0"
|
|
readonly
|
|
></fui-input>
|
|
</view>
|
|
|
|
<view class="form_item">
|
|
<view class="form_label">体重 (kg)</view>
|
|
<fui-input
|
|
:value="physicalTestInfo.weight || '暂无数据'"
|
|
placeholder="暂无体测数据"
|
|
borderColor="transparent"
|
|
backgroundColor="#f0f0f0"
|
|
readonly
|
|
></fui-input>
|
|
</view>
|
|
|
|
<view class="form_item" v-if="physicalTestInfo.test_date">
|
|
<view class="form_label">体测日期</view>
|
|
<fui-input
|
|
:value="physicalTestInfo.test_date"
|
|
placeholder="暂无体测数据"
|
|
borderColor="transparent"
|
|
backgroundColor="#f0f0f0"
|
|
readonly
|
|
></fui-input>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 联系信息 -->
|
|
<view class="form_section">
|
|
<view class="section_title">紧急联系人</view>
|
|
|
|
<view class="form_item">
|
|
<view class="form_label">联系人姓名</view>
|
|
<fui-input
|
|
v-model="formData.emergency_contact"
|
|
placeholder="请输入紧急联系人姓名"
|
|
borderColor="transparent"
|
|
backgroundColor="#f8f9fa"
|
|
:maxlength="20"
|
|
></fui-input>
|
|
</view>
|
|
|
|
<view class="form_item">
|
|
<view class="form_label">联系电话</view>
|
|
<fui-input
|
|
v-model="formData.contact_phone"
|
|
placeholder="请输入联系电话"
|
|
borderColor="transparent"
|
|
backgroundColor="#f8f9fa"
|
|
type="number"
|
|
:maxlength="11"
|
|
></fui-input>
|
|
</view>
|
|
|
|
<view class="form_item">
|
|
<view class="form_label">备注信息</view>
|
|
<fui-textarea
|
|
v-model="formData.note"
|
|
placeholder="其他需要说明的信息"
|
|
backgroundColor="#f8f9fa"
|
|
:maxlength="500"
|
|
:rows="4"
|
|
></fui-textarea>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 保存按钮 -->
|
|
<view class="save_section">
|
|
<fui-button
|
|
background="#29d3b4"
|
|
radius="12rpx"
|
|
:loading="saving"
|
|
@click="saveStudentInfo"
|
|
>
|
|
{{ saving ? '保存中...' : '保存信息' }}
|
|
</fui-button>
|
|
</view>
|
|
</view>
|
|
</template>
|
|
|
|
<script>
|
|
import apiRoute from '@/api/member.js'
|
|
|
|
export default {
|
|
data() {
|
|
return {
|
|
studentId: 0,
|
|
studentInfo: {},
|
|
physicalTestInfo: {}, // 体测信息
|
|
formData: {
|
|
name: '',
|
|
gender: '',
|
|
birthday: '',
|
|
emergency_contact: '',
|
|
contact_phone: '',
|
|
note: ''
|
|
},
|
|
saving: false,
|
|
showGenderPicker: false,
|
|
showDatePicker: false,
|
|
genderOptions: [
|
|
{ value: '1', text: '男' },
|
|
{ value: '2', text: '女' }
|
|
]
|
|
}
|
|
},
|
|
computed: {
|
|
genderText() {
|
|
const gender = this.genderOptions.find(item => item.value === this.formData.gender)
|
|
return gender ? gender.text : ''
|
|
},
|
|
birthdayText() {
|
|
return this.formData.birthday || ''
|
|
},
|
|
ageText() {
|
|
if (!this.formData.birthday) return ''
|
|
|
|
const today = new Date()
|
|
const birthDate = new Date(this.formData.birthday)
|
|
let age = today.getFullYear() - birthDate.getFullYear()
|
|
let months = today.getMonth() - birthDate.getMonth()
|
|
|
|
if (months < 0 || (months === 0 && today.getDate() < birthDate.getDate())) {
|
|
age--
|
|
months += 12
|
|
}
|
|
|
|
if (months < 0) {
|
|
months = 0
|
|
}
|
|
|
|
return age > 0 ? `${age}.${months.toString().padStart(2, '0')}岁` : `${months}个月`
|
|
}
|
|
},
|
|
onLoad(options) {
|
|
this.studentId = parseInt(options.student_id) || 0
|
|
if (this.studentId) {
|
|
this.loadStudentInfo()
|
|
} else {
|
|
uni.showToast({
|
|
title: '参数错误',
|
|
icon: 'none'
|
|
})
|
|
}
|
|
},
|
|
|
|
methods: {
|
|
goBack() {
|
|
uni.navigateBack()
|
|
},
|
|
|
|
async loadStudentInfo() {
|
|
try {
|
|
console.log('加载学员信息:', this.studentId)
|
|
|
|
// 调用真实API
|
|
const response = await apiRoute.getStudentInfo(this.studentId)
|
|
console.log('学员信息API响应:', response)
|
|
|
|
if (response.code === 1) {
|
|
this.studentInfo = response.data.student_info
|
|
this.physicalTestInfo = response.data.physical_test_info || {}
|
|
|
|
// 填充表单数据
|
|
this.formData = {
|
|
name: this.studentInfo.name || '',
|
|
gender: String(this.studentInfo.gender || ''),
|
|
birthday: this.studentInfo.birthday || '',
|
|
emergency_contact: this.studentInfo.emergency_contact || '',
|
|
contact_phone: this.studentInfo.contact_phone || '',
|
|
note: this.studentInfo.note || ''
|
|
}
|
|
console.log('学员信息加载成功:', this.studentInfo)
|
|
console.log('体测信息加载成功:', this.physicalTestInfo)
|
|
} else {
|
|
uni.showToast({
|
|
title: response.msg || '获取学员信息失败',
|
|
icon: 'none'
|
|
})
|
|
}
|
|
} catch (error) {
|
|
console.error('获取学员信息失败:', error)
|
|
uni.showToast({
|
|
title: '获取学员信息失败',
|
|
icon: 'none'
|
|
})
|
|
}
|
|
},
|
|
|
|
changeGender(e) {
|
|
this.formData.gender = e.value
|
|
this.showGenderPicker = false
|
|
},
|
|
|
|
changeBirthday(e) {
|
|
this.formData.birthday = e.result
|
|
this.showDatePicker = false
|
|
},
|
|
|
|
async uploadAvatar() {
|
|
try {
|
|
uni.chooseImage({
|
|
count: 1,
|
|
sizeType: ['compressed'],
|
|
sourceType: ['album', 'camera'],
|
|
success: async (res) => {
|
|
const tempFilePath = res.tempFilePaths[0]
|
|
console.log('选择的图片:', tempFilePath)
|
|
|
|
// 显示上传中提示
|
|
uni.showLoading({
|
|
title: '上传中...'
|
|
})
|
|
|
|
try {
|
|
// 调用通用头像上传API
|
|
const response = await apiRoute.uploadAvatarForAdd(tempFilePath)
|
|
console.log('头像上传API响应:', response)
|
|
|
|
if (response.code === 1) {
|
|
// 更新头像URL并保存到数据库
|
|
this.studentInfo.headimg = response.data.url
|
|
this.formData.headimg = response.data.url
|
|
|
|
// 立即保存头像到数据库
|
|
await this.saveAvatarToDatabase(response.data.url)
|
|
|
|
uni.showToast({
|
|
title: '头像上传成功',
|
|
icon: 'success'
|
|
})
|
|
} else {
|
|
throw new Error(response.msg || '上传失败')
|
|
}
|
|
} catch (uploadError) {
|
|
console.error('头像上传失败:', uploadError)
|
|
uni.showToast({
|
|
title: '头像上传失败',
|
|
icon: 'none'
|
|
})
|
|
} finally {
|
|
uni.hideLoading()
|
|
}
|
|
},
|
|
fail: (error) => {
|
|
console.error('选择图片失败:', error)
|
|
}
|
|
})
|
|
} catch (error) {
|
|
console.error('选择头像失败:', error)
|
|
}
|
|
},
|
|
|
|
async saveAvatarToDatabase(avatarUrl) {
|
|
try {
|
|
const updateData = {
|
|
student_id: this.studentId,
|
|
headimg: avatarUrl
|
|
}
|
|
|
|
console.log('保存头像到数据库:', updateData)
|
|
|
|
// 调用更新学员信息API,只更新头像字段
|
|
const response = await apiRoute.updateStudentInfo(updateData)
|
|
console.log('保存头像API响应:', response)
|
|
|
|
if (response.code !== 1) {
|
|
throw new Error(response.msg || '保存头像失败')
|
|
}
|
|
} catch (error) {
|
|
console.error('保存头像到数据库失败:', error)
|
|
throw error
|
|
}
|
|
},
|
|
|
|
async saveStudentInfo() {
|
|
// 表单验证
|
|
if (!this.formData.name.trim()) {
|
|
uni.showToast({
|
|
title: '请输入学员姓名',
|
|
icon: 'none'
|
|
})
|
|
return
|
|
}
|
|
|
|
if (!this.formData.gender) {
|
|
uni.showToast({
|
|
title: '请选择性别',
|
|
icon: 'none'
|
|
})
|
|
return
|
|
}
|
|
|
|
// 手机号验证
|
|
if (this.formData.contact_phone && !/^1[3-9]\d{9}$/.test(this.formData.contact_phone)) {
|
|
uni.showToast({
|
|
title: '请输入正确的手机号',
|
|
icon: 'none'
|
|
})
|
|
return
|
|
}
|
|
|
|
this.saving = true
|
|
try {
|
|
const updateData = {
|
|
student_id: this.studentId,
|
|
...this.formData
|
|
}
|
|
|
|
console.log('保存学员信息:', updateData)
|
|
|
|
// 调用真实API
|
|
const response = await apiRoute.updateStudentInfo(updateData)
|
|
console.log('更新学员信息API响应:', response)
|
|
|
|
if (response.code === 1) {
|
|
// 更新本地学员信息
|
|
Object.assign(this.studentInfo, this.formData)
|
|
|
|
uni.showToast({
|
|
title: '保存成功',
|
|
icon: 'success'
|
|
})
|
|
|
|
// 延迟返回上一页
|
|
setTimeout(() => {
|
|
uni.navigateBack()
|
|
}, 1500)
|
|
} else {
|
|
uni.showToast({
|
|
title: response.message || '保存失败',
|
|
icon: 'none'
|
|
})
|
|
}
|
|
} catch (error) {
|
|
console.error('保存学员信息失败:', error)
|
|
uni.showToast({
|
|
title: '保存失败,请重试',
|
|
icon: 'none'
|
|
})
|
|
} finally {
|
|
this.saving = false
|
|
}
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style lang="less" scoped>
|
|
.main_box {
|
|
background: #f8f9fa;
|
|
min-height: 100vh;
|
|
}
|
|
|
|
// 自定义导航栏
|
|
.navbar_section {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
background: #29D3B4;
|
|
padding: 40rpx 32rpx 20rpx;
|
|
|
|
// 小程序端适配状态栏
|
|
// #ifdef MP-WEIXIN
|
|
padding-top: 80rpx;
|
|
// #endif
|
|
|
|
.navbar_back {
|
|
width: 60rpx;
|
|
|
|
.back_icon {
|
|
color: #fff;
|
|
font-size: 40rpx;
|
|
font-weight: 600;
|
|
}
|
|
}
|
|
|
|
.navbar_title {
|
|
color: #fff;
|
|
font-size: 32rpx;
|
|
font-weight: 600;
|
|
}
|
|
|
|
.navbar_action {
|
|
width: 60rpx;
|
|
}
|
|
}
|
|
|
|
// 头像区域
|
|
.avatar_section {
|
|
background: #fff;
|
|
padding: 40rpx 32rpx;
|
|
text-align: center;
|
|
|
|
.avatar_container {
|
|
position: relative;
|
|
display: inline-block;
|
|
margin-bottom: 24rpx;
|
|
|
|
.avatar_image {
|
|
width: 120rpx;
|
|
height: 120rpx;
|
|
border-radius: 50%;
|
|
border: 4rpx solid #f0f0f0;
|
|
}
|
|
|
|
.avatar_edit_icon {
|
|
position: absolute;
|
|
bottom: 0;
|
|
right: 0;
|
|
width: 40rpx;
|
|
height: 40rpx;
|
|
background: #29d3b4;
|
|
border-radius: 50%;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
border: 2rpx solid #fff;
|
|
|
|
.edit_text {
|
|
color: #fff;
|
|
font-size: 20rpx;
|
|
}
|
|
}
|
|
}
|
|
|
|
.student_name {
|
|
font-size: 32rpx;
|
|
font-weight: 600;
|
|
color: #333;
|
|
margin-bottom: 12rpx;
|
|
}
|
|
|
|
.student_basic_info {
|
|
.info_tag {
|
|
display: inline-block;
|
|
font-size: 22rpx;
|
|
color: #666;
|
|
background: #f0f0f0;
|
|
padding: 6rpx 16rpx;
|
|
border-radius: 16rpx;
|
|
margin: 0 8rpx;
|
|
}
|
|
}
|
|
}
|
|
|
|
// 表单区域
|
|
.form_section {
|
|
background: #fff;
|
|
margin: 20rpx;
|
|
border-radius: 16rpx;
|
|
padding: 32rpx;
|
|
|
|
.section_title {
|
|
font-size: 28rpx;
|
|
font-weight: 600;
|
|
color: #333;
|
|
margin-bottom: 32rpx;
|
|
padding-bottom: 16rpx;
|
|
border-bottom: 1px solid #f0f0f0;
|
|
}
|
|
|
|
.form_item {
|
|
margin-bottom: 32rpx;
|
|
|
|
&:last-child {
|
|
margin-bottom: 0;
|
|
}
|
|
|
|
.form_label {
|
|
font-size: 26rpx;
|
|
color: #333;
|
|
margin-bottom: 12rpx;
|
|
font-weight: 500;
|
|
}
|
|
}
|
|
}
|
|
|
|
// 保存按钮区域
|
|
.save_section {
|
|
padding: 40rpx 32rpx;
|
|
padding-bottom: 80rpx;
|
|
}
|
|
</style>
|