Commit 19462a4a authored by tao.huang's avatar tao.huang

feat: 我的注册

parent e6720212
export const PRIVACY_URL = "https://secret.feihe.com/secret.html"; export const PRIVACY_URL = "https://secret.feihe.com/secret.html";
export const MEMBER_URL = "https://secret.feihe.com/index.html"; export const MEMBER_URL = "https://secret.feihe.com/index.html";
export const WHEEL_OPTIONS_YL = [
{ label: "1月龄", desc: "宝宝开始对外界产生兴趣,会追视物体" },
{ label: "2月龄", desc: "能发出咿咿呀呀的声音,会对妈妈微笑" },
{ label: "3月龄", desc: "抬头能力增强,喜欢玩自己的小手" },
{ label: "4月龄", desc: "会翻身了,对周围事物充满好奇" },
{ label: "5月龄", desc: "手眼协调能力提升,喜欢抓取玩具" },
{ label: "6月龄", desc: "可以独自坐立,开始尝试固体食物" },
{ label: "7月龄", desc: "会爬行了,语言能力逐渐发展" },
{ label: "8月龄", desc: "能扶物站立,认知能力显著提升" },
{ label: "9月龄", desc: "开始学步,能说简单的词语" },
{ label: "10月龄", desc: "独立行走能力增强,喜欢模仿大人" },
{ label: "11月龄", desc: "语言理解能力提高,会简单互动" },
{ label: "12月龄", desc: "基本能独立行走,表达欲望增强" },
{ label: "13月龄", desc: "动作更加协调,喜欢探索新事物" },
{ label: "14月龄", desc: "语言表达更丰富,独立意识增强" },
{ label: "15月龄", desc: "手部精细动作发展,创造力萌芽" },
{ label: "16月龄", desc: "记忆力提升,开始学习分类概念" },
{ label: "17月龄", desc: "想象力丰富,喜欢角色扮演游戏" },
{ label: "18月龄", desc: "语言交流更流畅,社交能力发展" },
{ label: "19月龄", desc: "运动技能全面发展,好奇心旺盛" },
{ label: "20月龄", desc: "逻辑思维初步形成,会简单推理" },
{ label: "21月龄", desc: "情感表达更丰富,记忆力增强" },
{ label: "22月龄", desc: "独立性增强,生活技能提升" },
{ label: "23月龄", desc: "语言组织能力提高,喜欢提问" },
{ label: "24月龄", desc: "社交圈子扩大,懂得分享" },
{ label: "25月龄", desc: "创造性思维发展,喜欢音乐" },
{ label: "26月龄", desc: "注意力更集中,会完成简单任务" },
{ label: "27月龄", desc: "空间认知能力提升,喜欢拼图" },
{ label: "28月龄", desc: "语言表达更准确,理解能力增强" },
{ label: "29月龄", desc: "自我意识增强,情绪管理提升" },
{ label: "30月龄", desc: "逻辑思维更成熟,会简单计数" },
{ label: "31月龄", desc: "艺术创造力发展,喜欢绘画" },
{ label: "32月龄", desc: "记忆力显著提升,会讲简单故事" },
{ label: "33月龄", desc: "运动协调性好,喜欢户外活动" },
{ label: "34月龄", desc: "社交技能成熟,懂得合作" },
{ label: "35月龄", desc: "思维更加灵活,解决问题能力增强" },
{ label: "36月龄", desc: "全面发展,准备进入幼儿园阶段" },
];
export const WHEEL_OPTIONS_YZ = [
{ label: "孕1周", desc: "胚胎开始着床,激素水平发生变化,胚胎开始着床,激素水平发生变化,胚胎开始着床,激素水平发生变化,胚胎开始着床,激素水平发生变化,胚胎开始着床,激素水平发生变化,胚胎开始着床,激素水平发生变化" },
{ label: "孕2周", desc: "胎盘开始形成,为胎儿提供营养" },
{ label: "孕3周", desc: "胎儿心脏开始跳动,神经系统发育" },
{ label: "孕4周", desc: "胎儿大小如花生,开始形成四肢" },
{ label: "孕5周", desc: "胎儿面部开始发育,可见眼睛雏形" },
{ label: "孕6周", desc: "胎儿开始运动,脊椎继续发育" },
{ label: "孕7周", desc: "胎儿手指脚趾形成,大脑发育加快" },
{ label: "孕8周", desc: "胎儿所有器官雏形完成,开始生长" },
{ label: "孕9周", desc: "胎儿开始吞咽羊水,肌肉发育" },
{ label: "孕10周", desc: "胎儿指甲开始生长,性别特征显现" },
{ label: "孕11周", desc: "胎儿可以做出简单动作,头部变圆" },
{ label: "孕12周", desc: "胎儿开始产生尿液,骨骼继续钙化" },
{ label: "孕13周", desc: "胎儿vocal cords形成,可发声" },
{ label: "孕14周", desc: "胎儿开始产生胎动,母体可感知" },
{ label: "孕15周", desc: "胎儿皮下脂肪开始形成,体型增大" },
{ label: "孕16周", desc: "胎儿听力开始发育,对声音敏感" },
{ label: "孕17周", desc: "胎儿免疫系统开始发育,产生抗体" },
{ label: "孕18周", desc: "胎儿睡眠周期形成,活动规律" },
{ label: "孕19周", desc: "胎儿肺部发育,为呼吸做准备" },
{ label: "孕20周", desc: "胎儿听力继续发育,对外界声音反应" },
{ label: "孕21周", desc: "胎儿眉毛睫毛生长,面部特征明显" },
{ label: "孕22周", desc: "胎儿皮肤变厚,开始长出胎毛" },
{ label: "孕23周", desc: "胎儿体重快速增长,运动更频繁" },
{ label: "孕24周", desc: "胎儿肺部继续发育,产生肺表面活性物质" },
{ label: "孕25周", desc: "胎儿脂肪积累加快,体型继续增大" },
{ label: "孕26周", desc: "胎儿眼睛可以睁开,对光有反应" },
{ label: "孕27周", desc: "胎儿大脑快速发育,神经系统成熟" },
{ label: "孕28周", desc: "胎儿各器官功能逐渐完善" },
{ label: "孕29周", desc: "胎儿骨骼继续钙化,头部下降" },
{ label: "孕30周", desc: "胎儿体重持续增加,活动空间减少" },
{ label: "孕31周", desc: "胎儿消化系统发育成熟,可消化羊水" },
{ label: "孕32周", desc: "胎儿皮下脂肪继续积累,体温调节能力增强" },
{ label: "孕33周", desc: "胎儿免疫系统继续发育,获得母体抗体" },
{ label: "孕34周", desc: "胎儿肺部发育接近成熟,准备独立呼吸" },
{ label: "孕35周", desc: "胎儿体重快速增加,为出生做准备" },
{ label: "孕36周", desc: "胎儿头部继续下降,为分娩做准备" },
{ label: "孕37周", desc: "胎儿各器官发育完善,可以安全出生" },
{ label: "孕38周", desc: "胎儿继续增重,准备出生" },
{ label: "孕39周", desc: "胎儿位置固定,随时可能出生" },
{ label: "孕40周", desc: "胎儿发育完全成熟,即将出生" },
];
<template>
<view class="baby-switcher-container">
<view class="baby-switcher-mask" @click.self="onClose"> </view>
<view class="baby-switcher-popup">
<view
v-for="baby in babyList"
:key="baby.id"
class="baby-item"
@click="selectBaby(baby)"
>
<text>{{ baby.babyName || "暂无昵称" }}</text>
<view
class="selected-icon"
:style="{ backgroundColor: baby.selected ? '#d3a358' : '#E8E8E8' }"
/>
</view>
<view v-if="babyList.length < 3" class="baby-item add-item" @click="onAdd">
<image :src="addIcon" class="add-icon" />
</view>
</view>
</view>
</template>
<script setup>
import { defineProps, defineEmits } from "vue";
const props = defineProps({
show: Boolean,
babyList: {
type: Array,
default: () => [],
},
addIcon: {
type: String,
default: "", // 传入新增icon路径
},
});
const emits = defineEmits(["close", "select", "add"]);
function onClose() {
emits("close");
}
function selectBaby(baby) {
emits("select", baby);
}
function onAdd() {
emits("add");
}
</script>
<style lang="less" scoped>
.baby-switcher-container {
touch-action: none;
}
.baby-switcher-mask {
position: fixed;
left: 0;
top: 0;
right: 0;
bottom: 0;
z-index: 1;
}
.baby-switcher-popup {
position: absolute;
left: 0;
top: 40rpx;
z-index: 2;
background: #fff;
border-radius: 16rpx;
padding: 10rpx 36rpx 22rpx 36rpx;
box-shadow: 0 0 30rpx rgba(204, 204, 204, 0.8);
box-sizing: border-box;
min-width: 247rpx;
}
.baby-item {
display: flex;
align-items: center;
justify-content: center;
padding: 20rpx 25rpx;
font-size: 26rpx;
font-weight: 500;
color: #1d1e25;
flex-wrap: nowrap;
border-bottom: 1px solid #eee;
&:nth-child(3) {
border-bottom: none;
}
}
.selected-icon {
width: 12rpx;
height: 12rpx;
margin-left: 17rpx;
background-color: #e8e8e8;
border-radius: 50%;
}
.add-item {
margin-top: 10rpx;
padding-top: 20rpx;
padding: 10rpx 0;
border-bottom: none;
}
.add-icon {
width: 96rpx;
height: 36rpx;
display: block;
}
</style>
\ No newline at end of file
...@@ -27,24 +27,40 @@ ...@@ -27,24 +27,40 @@
> >
<template v-if="mode === 'date'"> <template v-if="mode === 'date'">
<picker-view-column> <picker-view-column>
<view v-for="(item, idx) in years" :key="idx" class="picker-layer-item"> <view
v-for="(item, idx) in years"
:key="idx"
class="picker-layer-item"
>
{{ item }} {{ item }}
</view> </view>
</picker-view-column> </picker-view-column>
<picker-view-column> <picker-view-column>
<view v-for="(item, idx) in months" :key="idx" class="picker-layer-item"> <view
v-for="(item, idx) in months"
:key="idx"
class="picker-layer-item"
>
{{ item }} {{ item }}
</view> </view>
</picker-view-column> </picker-view-column>
<picker-view-column> <picker-view-column>
<view v-for="(item, idx) in days" :key="idx" class="picker-layer-item"> <view
{{ item === '请选择' ? item : `${item}日` }} v-for="(item, idx) in days"
:key="idx"
class="picker-layer-item"
>
{{ item === "请选择" ? item : `${item}日` }}
</view> </view>
</picker-view-column> </picker-view-column>
</template> </template>
<template v-else> <template v-else>
<picker-view-column v-for="(col, colIdx) in columns" :key="colIdx"> <picker-view-column v-for="(col, colIdx) in columns" :key="colIdx">
<view v-for="(item, idx) in col" :key="idx" class="picker-layer-item"> <view
v-for="(item, idx) in col"
:key="idx"
class="picker-layer-item"
>
{{ item }} {{ item }}
</view> </view>
</picker-view-column> </picker-view-column>
...@@ -60,7 +76,7 @@ import { ref, computed, watch } from "vue"; ...@@ -60,7 +76,7 @@ import { ref, computed, watch } from "vue";
const props = defineProps({ const props = defineProps({
mode: { mode: {
type: String, type: String,
default: 'custom', // 'date' | 'custom' default: "custom", // 'date' | 'custom'
}, },
range: { range: {
type: Array, type: Array,
...@@ -78,33 +94,80 @@ const props = defineProps({ ...@@ -78,33 +94,80 @@ const props = defineProps({
type: Function, type: Function,
default: () => {}, default: () => {},
}, },
onStatusChange: {
type: Function,
default: () => {},
},
disabled: {
type: Boolean,
default: false,
},
}); });
const show = ref(false); const show = ref(false);
// date模式相关 // date模式相关
const currentYear = new Date().getFullYear(); const today = new Date();
const currentYear = today.getFullYear();
const currentMonth = today.getMonth() + 1;
const currentDay = today.getDate();
// 计算未来280天的日期
const futureDate = new Date();
futureDate.setDate(futureDate.getDate() + 280);
const futureYear = futureDate.getFullYear();
const futureMonth = futureDate.getMonth() + 1;
const futureDay = futureDate.getDate();
const years = computed(() => { const years = computed(() => {
const arr = []; const arr = [];
for (let i = 1970; i <= currentYear; i++) { const startYear = currentYear - 3;
const endYear = futureYear;
for (let i = startYear; i <= endYear; i++) {
arr.push(i); arr.push(i);
} }
return arr; return arr;
}); });
const months = computed(() => { const months = computed(() => {
const [yearIdx] = pickerValue.value;
const selectedYear = years.value[yearIdx];
const arr = []; const arr = [];
for (let i = 1; i <= 12; i++) {
let startMonth = 1;
let endMonth = 12;
if (selectedYear === currentYear - 3) {
startMonth = currentMonth;
}
if (selectedYear === futureYear) {
endMonth = futureMonth;
}
for (let i = startMonth; i <= endMonth; i++) {
arr.push(i); arr.push(i);
} }
return arr; return arr;
}); });
const days = computed(() => { const days = computed(() => {
const [yearIdx, monthIdx] = pickerValue.value; const [yearIdx, monthIdx] = pickerValue.value;
const year = years.value[yearIdx] || years.value[0]; const selectedYear = years.value[yearIdx];
const month = months.value[monthIdx] || months.value[0]; const selectedMonth = months.value[monthIdx];
const dayCount = new Date(year, month, 0).getDate();
const arr = ['请选择']; const dayCount = new Date(selectedYear, selectedMonth, 0).getDate();
for (let i = 1; i <= dayCount; i++) { const arr = ["请选择"];
let startDay = 1;
let endDay = dayCount;
if (selectedYear === currentYear - 3 && selectedMonth === currentMonth) {
startDay = currentDay;
}
if (selectedYear === futureYear && selectedMonth === futureMonth) {
endDay = futureDay;
}
for (let i = startDay; i <= endDay; i++) {
arr.push(i); arr.push(i);
} }
return arr; return arr;
...@@ -120,7 +183,7 @@ const columns = computed(() => { ...@@ -120,7 +183,7 @@ const columns = computed(() => {
}); });
const defaultValue = computed(() => { const defaultValue = computed(() => {
if (props.mode === 'date') { if (props.mode === "date") {
// 默认选中今年1月1日 // 默认选中今年1月1日
return [years.value.length - 1, 0, 0]; return [years.value.length - 1, 0, 0];
} else if (Array.isArray(props.value)) { } else if (Array.isArray(props.value)) {
...@@ -135,7 +198,7 @@ const pickerValue = ref([...defaultValue.value]); ...@@ -135,7 +198,7 @@ const pickerValue = ref([...defaultValue.value]);
watch( watch(
() => props.value, () => props.value,
(val) => { (val) => {
if (props.mode === 'date') { if (props.mode === "date") {
pickerValue.value = [...val]; pickerValue.value = [...val];
} else if (Array.isArray(val)) { } else if (Array.isArray(val)) {
pickerValue.value = [...val]; pickerValue.value = [...val];
...@@ -146,7 +209,9 @@ watch( ...@@ -146,7 +209,9 @@ watch(
); );
function open() { function open() {
if (props.disabled) return;
pickerValue.value = [...defaultValue.value]; pickerValue.value = [...defaultValue.value];
show.value = true; show.value = true;
props.onLayerVisibleChange(true); props.onLayerVisibleChange(true);
} }
...@@ -156,19 +221,35 @@ function close() { ...@@ -156,19 +221,35 @@ function close() {
} }
function confirm() { function confirm() {
close(); close();
if (props.mode === 'date') { if (props.mode === "date") {
const [yIdx, mIdx, dIdx] = pickerValue.value; const [yIdx, mIdx, dIdx] = pickerValue.value;
if(dIdx === 0) { if (dIdx === 0) {
props.onPickerChange(''); props.onPickerChange("");
return; return;
} }
const year = years.value[yIdx]; const year = years.value[yIdx];
const month = months.value[mIdx]; const month = months.value[mIdx];
const day = days.value[dIdx]; const day = days.value[dIdx];
const dateStr = `${year}-${String(month).padStart(2, '0')}-${String(day).padStart(2, '0')}`; const dateStr = `${year}-${String(month).padStart(2, "0")}-${String(
day
).padStart(2, "0")}`;
props.onPickerChange(dateStr); props.onPickerChange(dateStr);
// 新增:判断状态并回调
const today = new Date();
const selectedDate = new Date(year, month - 1, day);
// 清除时分秒
today.setHours(0, 0, 0, 0);
selectedDate.setHours(0, 0, 0, 0);
let status = -1;
if (selectedDate.getTime() <= today.getTime()) {
status = 2;
} else {
status = 1;
}
props.onStatusChange(status);
} else { } else {
// 单列时只返回索引,否则返回数组 // 单列时只返回索引,否则返回数组
if (columns.value.length === 1) { if (columns.value.length === 1) {
...@@ -180,7 +261,7 @@ function confirm() { ...@@ -180,7 +261,7 @@ function confirm() {
} }
function onChange(e) { function onChange(e) {
let val = e.detail.value; let val = e.detail.value;
if (props.mode === 'date') { if (props.mode === "date") {
// 如果天数溢出,自动修正到最大天数 // 如果天数溢出,自动修正到最大天数
const maxDay = days.value.length; const maxDay = days.value.length;
if (val[2] >= maxDay) val[2] = maxDay - 1; if (val[2] >= maxDay) val[2] = maxDay - 1;
...@@ -308,4 +389,8 @@ function onChange(e) { ...@@ -308,4 +389,8 @@ function onChange(e) {
pointer-events: none; pointer-events: none;
} }
.picker-custom[disabled] {
opacity: 0.5;
pointer-events: none;
}
</style> </style>
\ No newline at end of file
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
<Layer <Layer
v-model="visible" v-model="visible"
:customHeader="true" :customHeader="true"
:maskClosable="false"
@confirm="handleConfirm" @confirm="handleConfirm"
@cancel="handleCancel" @cancel="handleCancel"
> >
...@@ -13,16 +14,22 @@ ...@@ -13,16 +14,22 @@
<PickerCustom <PickerCustom
mode="date" mode="date"
:value="dateValue" :value="dateValue"
:disabled="status == 0"
:onPickerChange="onDateChange" :onPickerChange="onDateChange"
:onLayerVisibleChange="onLayerVisibleChange" :onLayerVisibleChange="onLayerVisibleChange"
:onStatusChange="onStatusChange"
> >
<view class="register-baby-info-picker"> <view
class="register-baby-info-picker"
:style="status == 0 ? 'background: #e9edf1;' : ''"
>
<view <view
class="register-baby-info-picker-value" class="register-baby-info-picker-value"
:style="dateDisplay ? 'color: #1d1e25;' : ''" :style="dateDisplay ? 'color: #1d1e25;' : ''"
>{{ dateDisplay || "请选择宝宝的生日或预产期" }}</view >{{ dateDisplay || "请选择宝宝的生日或预产期" }}</view
> >
<image <image
v-if="status != 0"
class="register-baby-info-picker-arrow" class="register-baby-info-picker-arrow"
:src="$baseUrl + 'registerLayer/icon_arrow_yellow.png'" :src="$baseUrl + 'registerLayer/icon_arrow_yellow.png'"
mode="aspectFit" mode="aspectFit"
...@@ -31,18 +38,23 @@ ...@@ -31,18 +38,23 @@
</PickerCustom> </PickerCustom>
<PickerCustom <PickerCustom
mode="selector" mode="selector"
:disabled="status == 0"
:range="genderOptions" :range="genderOptions"
:value="genderIndex" :value="genderIndex"
:onPickerChange="onGenderChange" :onPickerChange="onGenderChange"
:onLayerVisibleChange="onLayerVisibleChange" :onLayerVisibleChange="onLayerVisibleChange"
> >
<view class="register-baby-info-picker"> <view
class="register-baby-info-picker"
:style="status == 0 ? 'background: #e9edf1;' : ''"
>
<view <view
class="register-baby-info-picker-value" class="register-baby-info-picker-value"
:style="genderDisplay ? 'color: #1d1e25;' : ''" :style="genderDisplay ? 'color: #1d1e25;' : ''"
>{{ genderDisplay || "请选择宝宝的性别" }}</view >{{ genderDisplay || "请选择宝宝的性别" }}</view
> >
<image <image
v-if="status != 0"
class="register-baby-info-picker-arrow" class="register-baby-info-picker-arrow"
:src="$baseUrl + 'registerLayer/icon_arrow_yellow.png'" :src="$baseUrl + 'registerLayer/icon_arrow_yellow.png'"
mode="aspectFit" mode="aspectFit"
...@@ -51,24 +63,50 @@ ...@@ -51,24 +63,50 @@
</PickerCustom> </PickerCustom>
<PickerCustom <PickerCustom
mode="selector" mode="selector"
:disabled="status == 0"
:range="fetusOptions" :range="fetusOptions"
:value="fetusIndex" :value="fetusIndex"
:onPickerChange="onFetusChange" :onPickerChange="onFetusChange"
:onLayerVisibleChange="onLayerVisibleChange" :onLayerVisibleChange="onLayerVisibleChange"
> >
<view class="register-baby-info-picker"> <view
class="register-baby-info-picker"
:style="status == 0 ? 'background: #e9edf1;' : ''"
>
<view <view
class="register-baby-info-picker-value" class="register-baby-info-picker-value"
:style="fetusDisplay ? 'color: #1d1e25;' : ''" :style="fetusDisplay ? 'color: #1d1e25;' : ''"
>{{ fetusDisplay || "请选择胎数" }}</view >{{ fetusDisplay || "请选择胎数" }}</view
> >
<image <image
v-if="status != 0"
class="register-baby-info-picker-arrow" class="register-baby-info-picker-arrow"
:src="$baseUrl + 'registerLayer/icon_arrow_yellow.png'" :src="$baseUrl + 'registerLayer/icon_arrow_yellow.png'"
mode="aspectFit" mode="aspectFit"
/> />
</view> </view>
</PickerCustom> </PickerCustom>
<view class="register-baby-info-status">
<view
class="register-baby-info-status-item"
:class="{ active: status === 0 }"
@click="toggleStatus(0)"
>
<view class="register-baby-info-status-item-icon">
<image
:src="
$baseUrl +
(status === 0
? 'registerLayer/circle_yes.png'
: 'registerLayer/circle_no.png')
"
mode="aspectFit"
/>
</view>
<view class="register-baby-info-status-item-text">备孕中</view>
</view>
</view>
<view class="register-baby-info-agreement"> <view class="register-baby-info-agreement">
<image <image
class="register-baby-info-agreement-icon" class="register-baby-info-agreement-icon"
...@@ -109,13 +147,16 @@ ...@@ -109,13 +147,16 @@
@click="checked.option2 = !checked.option2" @click="checked.option2 = !checked.option2"
/> />
</view> </view>
<view class="register-baby-info-btn" @click="handleBabyInfoConfirm"> <view
class="register-baby-info-btn"
:style="isBtnActive ? 'background: #d3a358;' : 'background: #e9edf1;'"
@click="handleBabyInfoConfirm"
>
完成 完成
</view> </view>
</view> </view>
</Layer> </Layer>
</template> </template>
<script setup> <script setup>
import { ref, watch, computed } from "vue"; import { ref, watch, computed } from "vue";
import Layer from "./Layer.vue"; import Layer from "./Layer.vue";
...@@ -132,7 +173,6 @@ const emit = defineEmits([ ...@@ -132,7 +173,6 @@ const emit = defineEmits([
]); ]);
const visible = ref(props.modelValue); const visible = ref(props.modelValue);
const imageUrl = ref(props.value);
watch( watch(
() => props.modelValue, () => props.modelValue,
...@@ -142,17 +182,8 @@ watch( ...@@ -142,17 +182,8 @@ watch(
() => visible.value, () => visible.value,
(val) => emit("update:modelValue", val) (val) => emit("update:modelValue", val)
); );
watch(
() => props.value,
(val) => (imageUrl.value = val)
);
function removeImage() {
imageUrl.value = "";
emit("update:value", "");
}
function handleConfirm() { function handleConfirm() {
emit("confirm", imageUrl.value);
visible.value = false; visible.value = false;
} }
function handleCancel() { function handleCancel() {
...@@ -169,9 +200,11 @@ const checked = ref({ ...@@ -169,9 +200,11 @@ const checked = ref({
const date = ref(""); const date = ref("");
const gender = ref(""); const gender = ref("");
const fetus = ref(""); const fetus = ref("");
// 0备孕 1孕中 2出生
const status = ref(-1);
const genderOptions = ["男", "女", "保密"]; const genderOptions = ["男", "女", "未知"];
const fetusOptions = ["单胎", "多胎"]; const fetusOptions = ["一胎", "二胎", "三胎"];
// date picker // date picker
const dateValue = ref([50, 0, 0]); // 默认选中今年1月1日 const dateValue = ref([50, 0, 0]); // 默认选中今年1月1日
...@@ -194,48 +227,36 @@ function onFetusChange(idx) { ...@@ -194,48 +227,36 @@ function onFetusChange(idx) {
fetusIndex.value = idx; fetusIndex.value = idx;
fetus.value = fetusOptions[idx]; fetus.value = fetusOptions[idx];
} }
function onLayerVisibleChange() {}
function handleBabyInfoConfirm() {
if (!checked.value.option1 || !checked.value.option2) {
uni.showToast({
title: "请先阅读并同意协议",
icon: "none",
});
return;
}
console.log(date.value, gender.value, fetus.value); function onStatusChange(v) {
status.value = v;
}
if(!date.value) { function onLayerVisibleChange() {}
uni.showToast({
title: "请选择宝宝的生日或预产期",
icon: "none",
});
return;
}
if(!gender.value) { const isBtnActive = computed(() => {
uni.showToast({ if (status.value === 0) {
title: "请选择宝宝的性别", return checked.value.option1 && checked.value.option2;
icon: "none", } else {
}); return (
return; checked.value.option1 &&
checked.value.option2 &&
!!date.value &&
!!gender.value &&
!!fetus.value
);
} }
});
if(!fetus.value) { function handleBabyInfoConfirm() {
uni.showToast({ if (!isBtnActive.value) {
title: "请选择胎数",
icon: "none",
});
return; return;
} }
emit("confirm", { emit("confirm", {
date: date.value, date: date.value,
gender: gender.value, gender: gender.value,
fetus: fetus.value, fetus: fetus.value,
status: status.value,
}); });
visible.value = false; visible.value = false;
} }
...@@ -243,6 +264,22 @@ function openAgreement() { ...@@ -243,6 +264,22 @@ function openAgreement() {
// 跳转协议页面 // 跳转协议页面
uni.navigateTo({ url: "/pages/agreement/index" }); uni.navigateTo({ url: "/pages/agreement/index" });
} }
function toggleStatus(val) {
if (status.value === val) {
status.value = -1; // 取消高亮
} else {
status.value = val; // 选中
if (val === 0) {
date.value = "";
dateDisplay.value = "";
gender.value = "";
genderIndex.value = 0;
fetus.value = "";
fetusIndex.value = 0;
}
}
}
</script> </script>
<style lang="less" scoped> <style lang="less" scoped>
...@@ -273,7 +310,7 @@ function openAgreement() { ...@@ -273,7 +310,7 @@ function openAgreement() {
.register-baby-info-picker { .register-baby-info-picker {
width: 654rpx; width: 654rpx;
background: #fff; background: #fff;
border-radius: 24rpx; border-radius: 44rpx;
margin-bottom: 28rpx; margin-bottom: 28rpx;
padding: 0 32rpx; padding: 0 32rpx;
height: 94rpx; height: 94rpx;
...@@ -282,10 +319,49 @@ function openAgreement() { ...@@ -282,10 +319,49 @@ function openAgreement() {
align-items: center; align-items: center;
box-shadow: 0 4rpx 24rpx 0 rgba(211, 163, 88, 0.04); box-shadow: 0 4rpx 24rpx 0 rgba(211, 163, 88, 0.04);
border: none; border: none;
margin-left: auto;
margin-right: auto;
position: relative; position: relative;
} }
.register-baby-info-status {
width: 654rpx;
margin-bottom: 28rpx;
display: flex;
justify-content: center;
}
.register-baby-info-status-item {
display: flex;
align-items: center;
justify-content: center;
width: 100%;
height: 94rpx;
background: #fff;
color: #bdbfc3;
border-radius: 44rpx;
cursor: pointer;
transition: background 0.2s, color 0.2s;
box-sizing: border-box;
.register-baby-info-status-item-icon {
width: 32rpx;
height: 32rpx;
image {
width: 100%;
height: 100%;
display: block;
}
}
.register-baby-info-status-item-text {
font-size: 32rpx;
color: #bdbfc3;
margin-left: 12rpx;
transition: color 0.2s;
}
}
.register-baby-info-status-item.active {
border: 2rpx solid #d3a358;
color: #d3a358;
.register-baby-info-status-item-text {
color: #d3a358;
}
}
.register-baby-info-picker-value { .register-baby-info-picker-value {
font-size: 32rpx; font-size: 32rpx;
color: #bdbfc3; color: #bdbfc3;
...@@ -366,4 +442,5 @@ function openAgreement() { ...@@ -366,4 +442,5 @@ function openAgreement() {
align-items: center; align-items: center;
justify-content: center; justify-content: center;
} }
</style> </style>
\ No newline at end of file
<template>
<view class="wheel-selector">
<image class="wheel-bg" :src="bgImg" mode="aspectFit" />
<view
class="wheel-options"
@touchstart="onTouchStart"
@touchmove.prevent="onTouchMove"
@touchend="onTouchEnd"
>
<view
v-for="opt in visibleOptions"
:key="opt.idx + '-' + opt.pos"
class="wheel-option"
:class="{ selected: opt.pos === 0 }"
:style="getOptionStyle(opt)"
>
<image
class="wheel-icon"
:class="{ 'wheel-icon-selected': opt.pos === 0 }"
:src="opt.pos === 0 ? iconSelected : iconNormal"
mode="aspectFit"
/>
<text class="wheel-label">{{ opt.item.label }}</text>
</view>
</view>
</view>
</template>
<script setup>
import { ref, watch, computed } from "vue";
const props = defineProps({
options: { type: Array, required: true }, // [{label: '七月龄'}, ...]
selectedIndex: { type: Number, default: 0 },
bgImg: { type: String, required: true },
iconNormal: { type: String, required: true },
iconSelected: { type: String, required: true },
});
const emits = defineEmits(["update:selectedIndex", "change"]);
const currentIndex = ref(props.selectedIndex);
// 计算最多展示三个 option
const visibleOptions = computed(() => {
const total = props.options.length;
const arr = [];
for (let i = 0; i < 3; i++) {
if (currentIndex.value + i < total) {
arr.push({
item: props.options[currentIndex.value + i],
idx: currentIndex.value + i,
pos: i,
});
}
}
return arr;
});
watch(
() => props.selectedIndex,
(val) => {
currentIndex.value = val;
}
);
let startY = 0;
function onTouchStart(e) {
startY = e.touches[0].clientY;
}
function onTouchMove(e) {
const deltaY = e.touches[0].clientY - startY;
if (Math.abs(deltaY) > 30) {
// 滑动阈值
if (deltaY > 0 && currentIndex.value > 0) {
currentIndex.value -= 1;
startY = e.touches[0].clientY;
} else if (
deltaY < 0 &&
currentIndex.value < props.options.length - 1
) {
currentIndex.value += 1;
startY = e.touches[0].clientY;
}
emits("update:selectedIndex", currentIndex.value);
emits("change", currentIndex.value);
}
}
function onTouchEnd() {
// nothing
}
function getOptionStyle(opt) {
const positions = [
{ x: 34, y: 94 },
{ x: 118, y: 278 },
{ x: 50, y: 446 },
];
const pos = positions[opt.pos] || positions[positions.length - 1];
const _oo = {
position: "absolute",
left: `${pos.x}rpx`,
top: `${pos.y}rpx`,
opacity: 1,
zIndex: 10 - opt.pos,
}
return _oo;
}
</script>
<style scoped lang="less">
.wheel-selector {
position: absolute;
top: 128rpx;
left: 0;
width: 340rpx;
height: 540rpx;
}
.wheel-bg {
position: absolute;
left: 0;
top: 94rpx;
width: 143rpx;
height: 436rpx;
z-index: 0;
display: block;
}
.wheel-options {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
z-index: 1;
display: flex;
flex-direction: column;
align-items: flex-start;
justify-content: center;
pointer-events: auto;
touch-action: none;
}
.wheel-option {
position: absolute;
width: 220rpx;
height: 60rpx;
display: flex;
align-items: center;
transition: all 0.7s, opacity 0.2s;
.wheel-icon {
width: 24rpx;
height: 24rpx;
display: block;
}
.wheel-icon-selected {
width: 56rpx;
height: 56rpx;
display: block;
}
.wheel-label {
font-size: 28rpx;
color: #FFFFFF;
text-shadow: 0 2rpx 8rpx #333333;
font-weight: bold;
}
}
</style>
\ No newline at end of file
...@@ -91,6 +91,7 @@ ...@@ -91,6 +91,7 @@
:value="getPickerIndex(item)" :value="getPickerIndex(item)"
:onPickerChange="(e) => onPickerChange(e, item.name)" :onPickerChange="(e) => onPickerChange(e, item.name)"
:onLayerVisibleChange="(e) => (pageStatus.btnStatus = !e)" :onLayerVisibleChange="(e) => (pageStatus.btnStatus = !e)"
:onStatusChange="onDateStatusChange"
> >
<view class="form-input-box"> <view class="form-input-box">
<view class="form-input">{{ <view class="form-input">{{
...@@ -373,6 +374,12 @@ watch( ...@@ -373,6 +374,12 @@ watch(
} }
} }
); );
function onDateStatusChange(status) {
if (status === '已出生' || status === '孕中') {
formData.value.currentBaby = status;
}
}
</script> </script>
<style lang="less" scoped> <style lang="less" scoped>
......
import { defineStore } from "pinia";
import { import {
defineStore autoLoginByCode,
} from 'pinia'; fetchUserInfo,
import { fetchBabyInfo,
autoLoginByCode, fetchAutoPhone,
fetchUserInfo, } from "../api/user.js";
fetchBabyInfo, import { useGlobalStore } from "./global.js";
fetchAutoPhone
} from '../api/user.js';
import {
useGlobalStore
} from './global.js';
const globalStore = useGlobalStore(); const globalStore = useGlobalStore();
export const useUserStore = defineStore('userInfo', { export const useUserStore = defineStore("userInfo", {
state: () => { state: () => {
return { return {
userInfo: null, userInfo: {
babyInfo: null, // memberId: "12",
}; // memberName: "hzt",
}, },
actions: { babyInfo: null,
/** };
* 更新用户信息 },
* @param {Object} userInfo actions: {
*/ /**
setUserInfo(userInfo) { * 更新用户信息
this.userInfo = userInfo; * @param {Object} userInfo
}, */
setUserInfo(userInfo) {
/** this.userInfo = userInfo;
* 更新宝宝信息 },
* @param {Object} babyInfo
*/
setBabyInfo(babyInfo) {
this.babyInfo = babyInfo;
},
/** /**
* 用户手机号验证的回调方法,用于获取encryptedData、iv、code,然后调用fetchAutoPhone接口完成手机号授权 * 更新宝宝信息
* @param {Object} data : {encryptedData, iv, code} * @param {Object} babyInfo
* @returns */
*/ setBabyInfo(babyInfo) {
async phoneCallback(data) { this.babyInfo = babyInfo;
uni.login({ },
provider: 'weixin',
success: async (res) => {
// console.log('wxAutoLogin', res);
if (res.errMsg === 'login:ok') {
// 用户手机授权
await fetchAutoPhone({
phoneEncryptedData: data.encryptedData,
phoneIv: data.iv,
code: data.code,
codeLogin: res.code
});
// 授权注册成功后做一次登录
this.wxAutoLogin();
} else {
uni.showToast({
title: res.errMsg,
icon: 'error'
});
}
},
});
}, /**
* 用户手机号验证的回调方法,用于获取encryptedData、iv、code,然后调用fetchAutoPhone接口完成手机号授权
* @param {Object} data : {encryptedData, iv, code}
* @returns
*/
async phoneCallback(data) {
uni.login({
provider: "weixin",
success: async (res) => {
// console.log('wxAutoLogin', res);
if (res.errMsg === "login:ok") {
// 用户手机授权
await fetchAutoPhone({
phoneEncryptedData: data.encryptedData,
phoneIv: data.iv,
code: data.code,
codeLogin: res.code,
});
// 授权注册成功后做一次登录
this.wxAutoLogin();
} else {
uni.showToast({
title: res.errMsg,
icon: "error",
});
}
},
});
},
/** /**
* 获取用户信息 * 获取用户信息
*/ */
async loadUserInfo() { async loadUserInfo() {
const { const { data } = await fetchUserInfo();
data console.log("userInfo", data);
} = await fetchUserInfo(); if (data?.memberId !== "not_login") {
console.log('userInfo', data); this.userInfo = data;
if (data?.memberId !== 'not_login') { }
this.userInfo = data; },
}
},
/** /**
* 获取宝宝信息 * 获取宝宝信息
*/ */
async loadBabyInfo() { async loadBabyInfo() {
const { const { data } = await fetchBabyInfo();
data console.log("babyInfo", data);
} = await fetchBabyInfo(); if (data?.memberId !== "not_login") {
console.log('babyInfo', data); this.babyInfo = data;
if (data?.memberId !== 'not_login') { }
this.babyInfo = data; },
}
},
/** /**
* wx.login 获取code后,调用此方法完成登录 * wx.login 获取code后,调用此方法完成登录
* @param {String} code * @param {String} code
*/ */
async autoLoginByCode(code) { async autoLoginByCode(code) {
const { const { data } = await autoLoginByCode(code);
data console.log("autoLoginByCode", data);
} = await autoLoginByCode(code); // 如果登录成功,获取用户信息和宝宝信息,更新到state中,方便全局使用
console.log('autoLoginByCode', data); if (data && data.cuk) {
// 如果登录成功,获取用户信息和宝宝信息,更新到state中,方便全局使用 globalStore.setCuk(data.cuk);
if (data && data.cuk) {
globalStore.setCuk(data.cuk);
this.loadUserInfo(); this.loadUserInfo();
this.loadBabyInfo(); this.loadBabyInfo();
} }
}, },
/** /**
* 用户自动登录 * 用户自动登录
*/ */
async wxAutoLogin() { async wxAutoLogin() {
uni.login({ uni.login({
provider: 'weixin', provider: "weixin",
success: (res) => { success: (res) => {
console.log('wxAutoLogin', res); console.log("wxAutoLogin", res);
if (res.errMsg === 'login:ok') { if (res.errMsg === "login:ok") {
this.autoLoginByCode(res.code); this.autoLoginByCode(res.code);
} else { } else {
uni.showToast({ uni.showToast({
title: res.errMsg, title: res.errMsg,
icon: 'error' icon: "error",
}); });
} }
}, },
}); });
}, },
}, },
}); });
\ No newline at end of file
<template> <template>
<view class="my-container"> <view class="my-container">
<view v-if="cfgStatus.showDetail" class="wheel-selector-fixed">
<WheelSelector
:options="wheelOptions"
:selectedIndex="wheelSelectedIndex"
:bgImg="$baseUrl + 'my/track/track.png'"
:iconNormal="$baseUrl + 'my/track/icon_stage_nor.png'"
:iconSelected="$baseUrl + 'my/track/icon_stage_sel.png'"
@update:selectedIndex="(val) => (wheelSelectedIndex = val)"
/>
</view>
<view class="bg-container"> <view class="bg-container">
<image <image
class="bg-img" class="bg-img"
...@@ -10,47 +20,85 @@ ...@@ -10,47 +20,85 @@
bindload="" bindload=""
/> />
</view> </view>
<button
v-if="!cfgStatus.isRegister"
type="primary"
class="phone-button"
open-type="getPhoneNumber"
@getphonenumber="getRealtimePhoneNumber"
/>
<!-- 用户信息区域 --> <!-- 用户信息区域 -->
<view class="user-info" @click="handleRegister"> <view
class="user-info"
:style="{ 'min-height': cfgStatus.showDetail ? '343rpx' : '180rpx' }"
@click="handleRegister"
>
<view class="user-header"> <view class="user-header">
<view class="avatar-container"> <view class="avatar-container" @click="handleEditProfile">
<image class="avatar" :src="userInfo.avatar" mode="aspectFill" /> <image
class="avatar"
:src="babyInfo.babyAvatar || $baseUrl + 'common/default_avatar.png'"
mode="aspectFill"
/>
</view> </view>
<image <image
class="avatar-modify" class="avatar-modify"
:src="$baseUrl + 'my/icon_modify.png'" :src="$baseUrl + 'my/icon_modify.png'"
mode="aspectFit" mode="aspectFit"
lazy-load="false" lazy-load="false"
@click="handleEditProfile"
/> />
<view class="user-detail"> <view class="user-detail">
<text class="nickname">{{ userInfo.nickname || "暂无昵称" }}</text> <view class="user-detail-nickname" @click="handleChangeBaby">
<text class="nickname">{{ babyInfo.babyName || "暂无昵称" }}</text>
<image
class="user-detail-nickname-icon"
:src="$baseUrl + 'registerLayer/icon_arrow_yellow.png'"
mode="aspectFit"
/>
</view>
<!-- 积分账户 --> <!-- 积分账户 -->
<view class="integral-account"> <view class="integral-account">
<text class="integral-account-text"> 积分账户: </text> <text class="integral-account-text"> 积分账户: </text>
<text class="integral-account-value"> --- </text> <text class="integral-account-value">
{{ babyInfo.points || "---" }}</text
>
</view> </view>
<BabySwitcher
v-if="showBabySwitcher"
:show="showBabySwitcher"
:babyList="babyInfo.allBabyBaseInfo"
:addIcon="$baseUrl + 'my/baby_add_btn.png'"
@close="showBabySwitcher = false"
@select="onSelectBaby"
@add="onAddBaby"
/>
</view> </view>
</view> </view>
<!-- user desc --> <!-- user desc -->
<view class="user-desc"> <view v-if="cfgStatus.showDetail" class="user-desc">
<view class="desc-top"> <view class="desc-top">
<text class="desc-title">宝宝变化</text> <text class="desc-title">宝宝变化</text>
<text class="desc-age"> <text class="desc-age">
{{ babyDetail[0].age }} {{ wheelOptions[wheelSelectedIndex]?.label }}
</text> </text>
</view> </view>
<view class="desc-content"> <view class="desc-content">
<text class="desc-text" <text class="desc-text"
>{{ >{{
cfgStatus.openBabyCardDesc wheelOptions[wheelSelectedIndex]?.desc.length > 46
? babyDetail[0].desc ? cfgStatus.openBabyCardDesc
: babyDetail[0].desc.slice(0, 46) + "..." ? wheelOptions[wheelSelectedIndex]?.desc
: wheelOptions[wheelSelectedIndex]?.desc.slice(0, 46) + "..."
: wheelOptions[wheelSelectedIndex]?.desc
}} }}
</text> </text>
<text <text
v-if="wheelOptions[wheelSelectedIndex]?.desc.length > 46"
class="desc-more" class="desc-more"
@click="cfgStatus.openBabyCardDesc = !cfgStatus.openBabyCardDesc" @click="cfgStatus.openBabyCardDesc = !cfgStatus.openBabyCardDesc"
>{{ cfgStatus.openBabyCardDesc ? "点击收起" : "点击展开" }}</text >{{ cfgStatus.openBabyCardDesc ? "点击收起" : "点击展开" }}</text
...@@ -74,32 +122,28 @@ ...@@ -74,32 +122,28 @@
<view class="hot-member" @click="handleHot" data-type="member"></view> <view class="hot-member" @click="handleHot" data-type="member"></view>
<view class="hot-privacy" @click="handleHot" data-type="privacy"></view> <view class="hot-privacy" @click="handleHot" data-type="privacy"></view>
</view> </view>
<RegisterLayer <RegisterLayer v-model="showRegisterLayer" @confirm="onRegisterConfirm" />
v-model="showRegisterLayer"
:value="registerImageUrl"
@update:value="(val) => (registerImageUrl = val)"
@confirm="onRegisterConfirm"
/>
</view> </view>
</template> </template>
<script setup> <script setup>
import { ref, onMounted, getCurrentInstance } from "vue"; import { ref, onMounted, getCurrentInstance } from "vue";
import RegisterLayer from "../components/RegisterLayer.vue"; import RegisterLayer from "../components/RegisterLayer.vue";
import BabySwitcher from "../components/BabySwitcher.vue";
import WheelSelector from "../components/WheelSelector.vue";
import { WHEEL_OPTIONS_YL, WHEEL_OPTIONS_YZ } from "@/cfg";
import { useUserStore } from "@/stores/user";
const { proxy } = getCurrentInstance(); const { proxy } = getCurrentInstance();
const $baseUrl = proxy.$baseUrl; const $baseUrl = proxy.$baseUrl;
const cfgStatus = ref({ const cfgStatus = ref({
openBabyCardDesc: false, openBabyCardDesc: false,
showDetail: false,
isRegister: false,
}); });
const babyDetail = ref([ const wheelOptions = ref([]);
{ const wheelSelectedIndex = ref(0);
age: "2月龄",
desc: "宝宝开始对周围环境产生兴趣,喜欢看、听、摸,开始对玩具感兴趣,开始对妈妈的声音产生反应。宝宝开始对周围环境产生兴趣,喜欢看、听、摸,开始对玩具感兴趣,开始对妈妈的声音产生反应。宝宝开始对周围环境产生兴趣,喜欢看、听、摸,开始对玩具感兴趣,开始对妈妈的声音产生反应。",
},
]);
const toolList = ref([ const toolList = ref([
{ {
...@@ -129,11 +173,55 @@ const toolList = ref([ ...@@ -129,11 +173,55 @@ const toolList = ref([
}, },
]); ]);
// 用户信息 const babyInfo = ref({
const userInfo = ref({}); babyName: "et",
babySkill: "occaecat",
babyAge: "2月龄",
babyAvatar: "sint ad sunt anim",
points: "23223",
babyStage: 1,
content: {
dueDate: "esse ea dolor id ipsum",
gestationalWeeks: "culpa",
babyType: "irure",
contentPreference: "occaecat commodo dolore",
followInfo: "est qui ea occaecat ad",
babyName: "Lorem",
babyBirthday: "est mollit do consectetur",
babyGender: "consectetur",
birthWeight: "dolore pariatur dolor",
birthHeight: "fugiat consectetur incididunt",
feedingType: "ipsum labore dolor in Lorem",
productPreference: "id voluptate",
purchaseChannel: "enim veniam in elit",
id: 2212796.2919538617,
memberBabyId: -77291739.14081913,
babyAvatar: "nisi Duis est",
backgroundImg: "laborum in esse ut deserunt",
},
allBabyBaseInfo: [
{
babyName: "",
babyType: 19188017.35935314,
babyStage: "veniam Ut sunt cupidatat",
id: "officia pariatur proident",
typeName: "eu",
selected: false,
},
{
babyName: "",
babyType: 34899428.44859558,
babyStage: "incididunt",
id: "non",
typeName: "dolor irure id cupidatat",
selected: true,
},
],
babyGender: "in voluptate ut",
});
const showRegisterLayer = ref(false); const showRegisterLayer = ref(false);
const registerImageUrl = ref(""); const showBabySwitcher = ref(false);
const handleHot = (e) => { const handleHot = (e) => {
const type = e.currentTarget.dataset.type; const type = e.currentTarget.dataset.type;
...@@ -164,7 +252,8 @@ const navigateTo = (url) => { ...@@ -164,7 +252,8 @@ const navigateTo = (url) => {
// 编辑个人资料 // 编辑个人资料
const handleEditProfile = () => { const handleEditProfile = () => {
if (!userInfo.value || JSON.stringify(userInfo.value) === "{}") { const userStore = useUserStore();
if (!userStore.userInfo || JSON.stringify(userStore.userInfo) === "{}") {
return; return;
} }
navigateTo("/pages/person/person"); navigateTo("/pages/person/person");
...@@ -172,42 +261,86 @@ const handleEditProfile = () => { ...@@ -172,42 +261,86 @@ const handleEditProfile = () => {
const handleRegister = () => { const handleRegister = () => {
// 判断是否已注册 // 判断是否已注册
if (!userInfo.value || JSON.stringify(userInfo.value) === "{}") { if (!cfgStatus.value.isRegister) {
showRegisterLayer.value = true; // 调用登录接口
// console.log("phoneButton", phoneButton.value);
// phoneButton.value.triggerEvent("tap");
} }
return; return;
}; };
function onRegisterConfirm(data) { const onRegisterConfirm = async (data) => {
console.log("onRegisterConfirm:", data); console.log("onRegisterConfirm:", data);
showRegisterLayer.value = false; showRegisterLayer.value = false;
} const userStore = useUserStore();
await Promise.all[(userStore.loadUserInfo(), userStore.loadBabyInfo())];
initData();
};
// 获取用户信息 // 获取用户信息
const getUserInfo = async () => { const initData = async () => {
try { const userStore = useUserStore();
// TODO: 调用获取用户信息接口
const res = await uni.request({ if (!userStore.userInfo || JSON.stringify(userStore.userInfo) == "{}") {
url: "/api/user/info", cfgStatus.value.isRegister = false;
method: "GET", cfgStatus.value.showDetail = false;
}); return;
if (res.data.code === 0) { }
userInfo.value = res.data.data;
} const __showDetail = [1, 2].includes(babyInfo.value.babyStage);
} catch (error) {
console.error("获取用户信息失败:", error); cfgStatus.value.isRegister = true;
// 已出生或孕中显示
cfgStatus.value.showDetail = __showDetail;
if (__showDetail) {
wheelOptions.value =
babyInfo.value.babyStage == 2 ? WHEEL_OPTIONS_YL : WHEEL_OPTIONS_YZ;
const index = wheelOptions.value.findIndex(
(item) => item.label == babyInfo.value.babyAge
);
wheelSelectedIndex.value = index > 0 ? index : 0;
}
};
const getRealtimePhoneNumber = async (e) => {
console.log("获取手机号码", e);
const userStore = useUserStore();
if (e.detail.errMsg !== "getPhoneNumber:ok") {
uni.showToast({ uni.showToast({
title: "获取用户信息失败", title: "请授权使用手机号",
icon: "none", icon: "none",
}); });
return;
} }
console.log("detail", e.detail);
await userStore.phoneCallback(e.detail);
showRegisterLayer.value = true;
}; };
const handleChangeBaby = () => {
if (!cfgStatus.value.isRegister) {
return;
}
showBabySwitcher.value = true;
};
function onSelectBaby(baby) {
// 处理宝宝切换逻辑
showBabySwitcher.value = false;
console.log("onSelectBaby", baby);
}
function onAddBaby() {
// 跳转到新增宝宝页面
showBabySwitcher.value = false;
navigateTo("/pages/person/person?type=add");
}
// 页面加载 // 页面加载
onMounted(() => { onMounted(() => {
// getUserInfo() initData();
// getOrderCounts()
}); });
// 定义页面配置 // 定义页面配置
...@@ -222,6 +355,26 @@ defineExpose({}); ...@@ -222,6 +355,26 @@ defineExpose({});
padding-bottom: 100rpx; padding-bottom: 100rpx;
overflow: hidden; overflow: hidden;
.wheel-selector-fixed {
position: absolute;
left: 0;
top: 0;
z-index: 10;
}
.phone-button {
position: absolute;
z-index: 3;
width: 686rpx;
height: 180rpx;
top: 676rpx;
left: 50%;
transform: translateX(-50%);
border: none;
background: transparent;
opacity: 0;
}
.bg-container { .bg-container {
width: 750rpx; width: 750rpx;
height: 840rpx; height: 840rpx;
...@@ -281,6 +434,7 @@ defineExpose({}); ...@@ -281,6 +434,7 @@ defineExpose({});
top: 84rpx; top: 84rpx;
z-index: 1; z-index: 1;
display: block; display: block;
pointer-events: none;
} }
.user-detail { .user-detail {
...@@ -292,6 +446,19 @@ defineExpose({}); ...@@ -292,6 +446,19 @@ defineExpose({});
top: 48rpx; top: 48rpx;
z-index: 1; z-index: 1;
.user-detail-nickname {
display: flex;
align-items: center;
}
.user-detail-nickname-icon {
width: 20rpx;
height: 12rpx;
display: block;
margin-left: 20rpx;
margin-top: -10rpx;
}
.nickname { .nickname {
font-size: 32rpx; font-size: 32rpx;
font-weight: 500; font-weight: 500;
...@@ -395,6 +562,10 @@ defineExpose({}); ...@@ -395,6 +562,10 @@ defineExpose({});
} }
} }
.user-info-min {
min-height: 180rpx;
}
.tool-container { .tool-container {
margin: 0 auto; margin: 0 auto;
margin-top: 48rpx; margin-top: 48rpx;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment