193 lines
4.2 KiB
Vue
193 lines
4.2 KiB
Vue
<template>
|
||
<view class="page">
|
||
<view class="header">
|
||
<view class="title-lg">选择孩子</view>
|
||
<view class="text-muted">点选孩子进入闯关地图</view>
|
||
</view>
|
||
|
||
<view v-for="c in children" :key="c.child_id" class="card child-card" @click="enter(c)">
|
||
<view class="avatar">{{ c.nickname.slice(0, 1) }}</view>
|
||
<view class="info">
|
||
<view class="name">{{ c.nickname }} <text class="age-tag">{{ c.age_group }}岁</text></view>
|
||
<view class="text-muted">
|
||
{{ c.level_title }} · {{ c.points }} 分 · 完美 {{ c.perfect_count }} 计
|
||
</view>
|
||
</view>
|
||
<view class="arrow">›</view>
|
||
</view>
|
||
|
||
<view v-if="children.length === 0" class="empty card">
|
||
<view class="empty-icon">🎈</view>
|
||
<view class="text-muted">还没有孩子档案,先添加一个吧</view>
|
||
</view>
|
||
|
||
<view v-if="showForm" class="card form-card">
|
||
<view class="form-title">新建孩子档案</view>
|
||
<input v-model="form.nickname" class="input" maxlength="32" placeholder="孩子昵称" />
|
||
<view class="age-row">
|
||
<view
|
||
v-for="g in ageGroups"
|
||
:key="g.value"
|
||
class="age-option"
|
||
:class="{ active: form.ageGroup === g.value }"
|
||
@click="form.ageGroup = g.value"
|
||
>{{ g.label }}</view>
|
||
</view>
|
||
<view class="btn-primary submit" @click="create">创建并进入</view>
|
||
</view>
|
||
|
||
<view class="btn-primary add" @click="showForm = !showForm">
|
||
{{ showForm ? '收起' : '+ 添加孩子' }}
|
||
</view>
|
||
</view>
|
||
</template>
|
||
|
||
<script>
|
||
import { api } from '../../api/index.js'
|
||
import { setChildId } from '../../store/user.js'
|
||
|
||
export default {
|
||
data() {
|
||
return {
|
||
children: [],
|
||
showForm: false,
|
||
form: { nickname: '', ageGroup: '4-6' },
|
||
ageGroups: [
|
||
{ label: '4-6 岁', value: '4-6' },
|
||
{ label: '6-8 岁', value: '6-8' }
|
||
]
|
||
}
|
||
},
|
||
onShow() {
|
||
this.load()
|
||
},
|
||
methods: {
|
||
async load() {
|
||
try {
|
||
const data = await api.childList()
|
||
this.children = data.list || []
|
||
} catch (e) {}
|
||
},
|
||
enter(c) {
|
||
setChildId(c.child_id)
|
||
uni.reLaunch({ url: '/pages/map/map' })
|
||
},
|
||
async create() {
|
||
if (!this.form.nickname.trim()) {
|
||
uni.showToast({ title: '请输入孩子昵称', icon: 'none' })
|
||
return
|
||
}
|
||
try {
|
||
const data = await api.childCreate({
|
||
nickname: this.form.nickname.trim(),
|
||
age_group: this.form.ageGroup
|
||
})
|
||
setChildId(data.child_id)
|
||
uni.reLaunch({ url: '/pages/map/map' })
|
||
} catch (e) {}
|
||
}
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<style scoped>
|
||
.page {
|
||
min-height: 100vh;
|
||
padding: 32rpx 32rpx 200rpx;
|
||
box-sizing: border-box;
|
||
}
|
||
.header {
|
||
padding: 32rpx 16rpx;
|
||
}
|
||
.child-card {
|
||
display: flex;
|
||
align-items: center;
|
||
padding: 32rpx;
|
||
margin-bottom: 24rpx;
|
||
}
|
||
.avatar {
|
||
width: 96rpx;
|
||
height: 96rpx;
|
||
border-radius: 50%;
|
||
background: linear-gradient(135deg, #ffd08a, #ff9a3d);
|
||
color: #ffffff;
|
||
font-size: 44rpx;
|
||
font-weight: 700;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
margin-right: 28rpx;
|
||
}
|
||
.info {
|
||
flex: 1;
|
||
}
|
||
.name {
|
||
font-size: 34rpx;
|
||
font-weight: 700;
|
||
margin-bottom: 8rpx;
|
||
}
|
||
.age-tag {
|
||
font-size: 22rpx;
|
||
color: #ff6b35;
|
||
background: #fff0e5;
|
||
border-radius: 20rpx;
|
||
padding: 4rpx 16rpx;
|
||
margin-left: 12rpx;
|
||
}
|
||
.arrow {
|
||
font-size: 48rpx;
|
||
color: #d5c4ae;
|
||
}
|
||
.empty {
|
||
padding: 80rpx 0;
|
||
text-align: center;
|
||
}
|
||
.empty-icon {
|
||
font-size: 72rpx;
|
||
margin-bottom: 20rpx;
|
||
}
|
||
.form-card {
|
||
padding: 40rpx;
|
||
margin-top: 24rpx;
|
||
}
|
||
.form-title {
|
||
font-size: 32rpx;
|
||
font-weight: 700;
|
||
margin-bottom: 28rpx;
|
||
}
|
||
.input {
|
||
background: #f8f2e8;
|
||
border-radius: 20rpx;
|
||
padding: 24rpx 28rpx;
|
||
margin-bottom: 24rpx;
|
||
font-size: 30rpx;
|
||
}
|
||
.age-row {
|
||
display: flex;
|
||
gap: 24rpx;
|
||
margin-bottom: 32rpx;
|
||
}
|
||
.age-option {
|
||
flex: 1;
|
||
text-align: center;
|
||
padding: 20rpx 0;
|
||
border-radius: 20rpx;
|
||
background: #f5ece0;
|
||
color: #a08c74;
|
||
font-weight: 600;
|
||
}
|
||
.age-option.active {
|
||
background: #ff9a3d;
|
||
color: #ffffff;
|
||
}
|
||
.submit {
|
||
margin-top: 8rpx;
|
||
}
|
||
.add {
|
||
position: fixed;
|
||
left: 32rpx;
|
||
right: 32rpx;
|
||
bottom: calc(48rpx + env(safe-area-inset-bottom));
|
||
}
|
||
</style>
|