Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
飞
飞鹤小程序
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
FH
飞鹤小程序
Commits
19462a4a
Commit
19462a4a
authored
Jun 06, 2025
by
tao.huang
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat: 我的注册
parent
e6720212
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
933 additions
and
245 deletions
+933
-245
cfg.js
cfg.js
+82
-0
BabySwitcher.vue
components/BabySwitcher.vue
+107
-0
PickerCustom.vue
components/PickerCustom.vue
+107
-22
RegisterLayer.vue
components/RegisterLayer.vue
+129
-52
WheelSelector.vue
components/WheelSelector.vue
+167
-0
person.vue
pages/person/person.vue
+7
-0
user.js
stores/user.js
+116
-124
My.vue
views/My.vue
+218
-47
No files found.
cfg.js
View file @
19462a4a
export
const
PRIVACY_URL
=
"https://secret.feihe.com/secret.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
:
"胎儿发育完全成熟,即将出生"
},
];
components/BabySwitcher.vue
0 → 100644
View file @
19462a4a
<
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
components/PickerCustom.vue
View file @
19462a4a
...
...
@@ -27,24 +27,40 @@
>
<template
v-if=
"mode === 'date'"
>
<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
}}
年
</view>
</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
}}
月
</view>
</picker-view-column>
<picker-view-column>
<view
v-for=
"(item, idx) in days"
:key=
"idx"
class=
"picker-layer-item"
>
{{
item
===
'请选择'
?
item
:
`${item
}
日`
}}
<view
v-for=
"(item, idx) in days"
:key=
"idx"
class=
"picker-layer-item"
>
{{
item
===
"请选择"
?
item
:
`${item
}
日`
}}
<
/view
>
<
/picker-view-column
>
<
/template
>
<
template
v
-
else
>
<
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
}}
<
/view
>
<
/picker-view-column
>
...
...
@@ -60,7 +76,7 @@ import { ref, computed, watch } from "vue";
const
props
=
defineProps
({
mode
:
{
type
:
String
,
default
:
'custom'
,
// 'date' | 'custom'
default
:
"custom"
,
// 'date' | 'custom'
}
,
range
:
{
type
:
Array
,
...
...
@@ -78,33 +94,80 @@ const props = defineProps({
type
:
Function
,
default
:
()
=>
{
}
,
}
,
onStatusChange
:
{
type
:
Function
,
default
:
()
=>
{
}
,
}
,
disabled
:
{
type
:
Boolean
,
default
:
false
,
}
,
}
);
const
show
=
ref
(
false
);
// 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
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
);
}
return
arr
;
}
);
const
months
=
computed
(()
=>
{
const
[
yearIdx
]
=
pickerValue
.
value
;
const
selectedYear
=
years
.
value
[
yearIdx
];
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
);
}
return
arr
;
}
);
const
days
=
computed
(()
=>
{
const
[
yearIdx
,
monthIdx
]
=
pickerValue
.
value
;
const
year
=
years
.
value
[
yearIdx
]
||
years
.
value
[
0
];
const
month
=
months
.
value
[
monthIdx
]
||
months
.
value
[
0
];
const
dayCount
=
new
Date
(
year
,
month
,
0
).
getDate
();
const
arr
=
[
'请选择'
];
for
(
let
i
=
1
;
i
<=
dayCount
;
i
++
)
{
const
selectedYear
=
years
.
value
[
yearIdx
];
const
selectedMonth
=
months
.
value
[
monthIdx
];
const
dayCount
=
new
Date
(
selectedYear
,
selectedMonth
,
0
).
getDate
();
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
);
}
return
arr
;
...
...
@@ -120,7 +183,7 @@ const columns = computed(() => {
}
);
const
defaultValue
=
computed
(()
=>
{
if
(
props
.
mode
===
'date'
)
{
if
(
props
.
mode
===
"date"
)
{
// 默认选中今年1月1日
return
[
years
.
value
.
length
-
1
,
0
,
0
];
}
else
if
(
Array
.
isArray
(
props
.
value
))
{
...
...
@@ -135,7 +198,7 @@ const pickerValue = ref([...defaultValue.value]);
watch
(
()
=>
props
.
value
,
(
val
)
=>
{
if
(
props
.
mode
===
'date'
)
{
if
(
props
.
mode
===
"date"
)
{
pickerValue
.
value
=
[...
val
];
}
else
if
(
Array
.
isArray
(
val
))
{
pickerValue
.
value
=
[...
val
];
...
...
@@ -146,7 +209,9 @@ watch(
);
function
open
()
{
if
(
props
.
disabled
)
return
;
pickerValue
.
value
=
[...
defaultValue
.
value
];
show
.
value
=
true
;
props
.
onLayerVisibleChange
(
true
);
}
...
...
@@ -156,19 +221,35 @@ function close() {
}
function
confirm
()
{
close
();
if
(
props
.
mode
===
'date'
)
{
if
(
props
.
mode
===
"date"
)
{
const
[
yIdx
,
mIdx
,
dIdx
]
=
pickerValue
.
value
;
if
(
dIdx
===
0
)
{
props
.
onPickerChange
(
''
);
if
(
dIdx
===
0
)
{
props
.
onPickerChange
(
""
);
return
;
}
const
year
=
years
.
value
[
yIdx
];
const
month
=
months
.
value
[
mIdx
];
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
);
// 新增:判断状态并回调
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
{
// 单列时只返回索引,否则返回数组
if
(
columns
.
value
.
length
===
1
)
{
...
...
@@ -180,7 +261,7 @@ function confirm() {
}
function
onChange
(
e
)
{
let
val
=
e
.
detail
.
value
;
if
(
props
.
mode
===
'date'
)
{
if
(
props
.
mode
===
"date"
)
{
// 如果天数溢出,自动修正到最大天数
const
maxDay
=
days
.
value
.
length
;
if
(
val
[
2
]
>=
maxDay
)
val
[
2
]
=
maxDay
-
1
;
...
...
@@ -308,4 +389,8 @@ function onChange(e) {
pointer
-
events
:
none
;
}
.
picker
-
custom
[
disabled
]
{
opacity
:
0.5
;
pointer
-
events
:
none
;
}
<
/style>
\ No newline at end of file
components/RegisterLayer.vue
View file @
19462a4a
...
...
@@ -2,6 +2,7 @@
<Layer
v-model=
"visible"
:customHeader=
"true"
:maskClosable=
"false"
@
confirm=
"handleConfirm"
@
cancel=
"handleCancel"
>
...
...
@@ -13,16 +14,22 @@
<PickerCustom
mode=
"date"
:value=
"dateValue"
:disabled=
"status == 0"
:onPickerChange=
"onDateChange"
:onLayerVisibleChange=
"onLayerVisibleChange"
:onStatusChange=
"onStatusChange"
>
<view
class=
"register-baby-info-picker"
>
<view
class=
"register-baby-info-picker"
:style=
"status == 0 ? 'background: #e9edf1;' : ''"
>
<view
class=
"register-baby-info-picker-value"
:style=
"dateDisplay ? 'color: #1d1e25;' : ''"
>
{{
dateDisplay
||
"请选择宝宝的生日或预产期"
}}
</view
>
<image
v-if=
"status != 0"
class=
"register-baby-info-picker-arrow"
:src=
"$baseUrl + 'registerLayer/icon_arrow_yellow.png'"
mode=
"aspectFit"
...
...
@@ -31,18 +38,23 @@
</PickerCustom>
<PickerCustom
mode=
"selector"
:disabled=
"status == 0"
:range=
"genderOptions"
:value=
"genderIndex"
:onPickerChange=
"onGenderChange"
:onLayerVisibleChange=
"onLayerVisibleChange"
>
<view
class=
"register-baby-info-picker"
>
<view
class=
"register-baby-info-picker"
:style=
"status == 0 ? 'background: #e9edf1;' : ''"
>
<view
class=
"register-baby-info-picker-value"
:style=
"genderDisplay ? 'color: #1d1e25;' : ''"
>
{{
genderDisplay
||
"请选择宝宝的性别"
}}
</view
>
<image
v-if=
"status != 0"
class=
"register-baby-info-picker-arrow"
:src=
"$baseUrl + 'registerLayer/icon_arrow_yellow.png'"
mode=
"aspectFit"
...
...
@@ -51,24 +63,50 @@
</PickerCustom>
<PickerCustom
mode=
"selector"
:disabled=
"status == 0"
:range=
"fetusOptions"
:value=
"fetusIndex"
:onPickerChange=
"onFetusChange"
:onLayerVisibleChange=
"onLayerVisibleChange"
>
<view
class=
"register-baby-info-picker"
>
<view
class=
"register-baby-info-picker"
:style=
"status == 0 ? 'background: #e9edf1;' : ''"
>
<view
class=
"register-baby-info-picker-value"
:style=
"fetusDisplay ? 'color: #1d1e25;' : ''"
>
{{
fetusDisplay
||
"请选择胎数"
}}
</view
>
<image
v-if=
"status != 0"
class=
"register-baby-info-picker-arrow"
:src=
"$baseUrl + 'registerLayer/icon_arrow_yellow.png'"
mode=
"aspectFit"
/>
</view>
</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"
>
<image
class=
"register-baby-info-agreement-icon"
...
...
@@ -109,13 +147,16 @@
@
click=
"checked.option2 = !checked.option2"
/>
</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>
</Layer>
</
template
>
<
script
setup
>
import
{
ref
,
watch
,
computed
}
from
"vue"
;
import
Layer
from
"./Layer.vue"
;
...
...
@@ -132,7 +173,6 @@ const emit = defineEmits([
]);
const
visible
=
ref
(
props
.
modelValue
);
const
imageUrl
=
ref
(
props
.
value
);
watch
(
()
=>
props
.
modelValue
,
...
...
@@ -142,17 +182,8 @@ watch(
()
=>
visible
.
value
,
(
val
)
=>
emit
(
"update:modelValue"
,
val
)
);
watch
(
()
=>
props
.
value
,
(
val
)
=>
(
imageUrl
.
value
=
val
)
);
function
removeImage
()
{
imageUrl
.
value
=
""
;
emit
(
"update:value"
,
""
);
}
function
handleConfirm
()
{
emit
(
"confirm"
,
imageUrl
.
value
);
visible
.
value
=
false
;
}
function
handleCancel
()
{
...
...
@@ -169,9 +200,11 @@ const checked = ref({
const
date
=
ref
(
""
);
const
gender
=
ref
(
""
);
const
fetus
=
ref
(
""
);
// 0备孕 1孕中 2出生
const
status
=
ref
(
-
1
);
const
genderOptions
=
[
"男"
,
"女"
,
"
保密
"
];
const
fetusOptions
=
[
"
单胎"
,
"多
胎"
];
const
genderOptions
=
[
"男"
,
"女"
,
"
未知
"
];
const
fetusOptions
=
[
"
一胎"
,
"二胎"
,
"三
胎"
];
// date picker
const
dateValue
=
ref
([
50
,
0
,
0
]);
// 默认选中今年1月1日
...
...
@@ -194,48 +227,36 @@ function onFetusChange(idx) {
fetusIndex
.
value
=
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
)
{
uni
.
showToast
({
title
:
"请选择宝宝的生日或预产期"
,
icon
:
"none"
,
});
return
;
}
function
onLayerVisibleChange
()
{}
if
(
!
gender
.
value
)
{
uni
.
showToast
({
title
:
"请选择宝宝的性别"
,
icon
:
"none"
,
});
return
;
const
isBtnActive
=
computed
(()
=>
{
if
(
status
.
value
===
0
)
{
return
checked
.
value
.
option1
&&
checked
.
value
.
option2
;
}
else
{
return
(
checked
.
value
.
option1
&&
checked
.
value
.
option2
&&
!!
date
.
value
&&
!!
gender
.
value
&&
!!
fetus
.
value
);
}
});
if
(
!
fetus
.
value
)
{
uni
.
showToast
({
title
:
"请选择胎数"
,
icon
:
"none"
,
});
function
handleBabyInfoConfirm
()
{
if
(
!
isBtnActive
.
value
)
{
return
;
}
emit
(
"confirm"
,
{
date
:
date
.
value
,
gender
:
gender
.
value
,
fetus
:
fetus
.
value
,
status
:
status
.
value
,
});
visible
.
value
=
false
;
}
...
...
@@ -243,6 +264,22 @@ function openAgreement() {
// 跳转协议页面
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
>
<
style
lang=
"less"
scoped
>
...
...
@@ -273,7 +310,7 @@ function openAgreement() {
.register-baby-info-picker {
width: 654rpx;
background: #fff;
border-radius:
2
4rpx;
border-radius:
4
4rpx;
margin-bottom: 28rpx;
padding: 0 32rpx;
height: 94rpx;
...
...
@@ -282,10 +319,49 @@ function openAgreement() {
align-items: center;
box-shadow: 0 4rpx 24rpx 0 rgba(211, 163, 88, 0.04);
border: none;
margin-left: auto;
margin-right: auto;
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 {
font-size: 32rpx;
color: #bdbfc3;
...
...
@@ -366,4 +442,5 @@ function openAgreement() {
align-items: center;
justify-content: center;
}
</
style
>
\ No newline at end of file
</
style
>
components/WheelSelector.vue
0 → 100644
View file @
19462a4a
<
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
pages/person/person.vue
View file @
19462a4a
...
...
@@ -91,6 +91,7 @@
:value=
"getPickerIndex(item)"
:onPickerChange=
"(e) => onPickerChange(e, item.name)"
:onLayerVisibleChange=
"(e) => (pageStatus.btnStatus = !e)"
:onStatusChange=
"onDateStatusChange"
>
<view
class=
"form-input-box"
>
<view
class=
"form-input"
>
{{
...
...
@@ -373,6 +374,12 @@ watch(
}
}
);
function
onDateStatusChange
(
status
)
{
if
(
status
===
'已出生'
||
status
===
'孕中'
)
{
formData
.
value
.
currentBaby
=
status
;
}
}
</
script
>
<
style
lang=
"less"
scoped
>
...
...
stores/user.js
View file @
19462a4a
import
{
defineStore
}
from
"pinia"
;
import
{
defineStore
}
from
'pinia'
;
import
{
autoLoginByCode
,
fetchUserInfo
,
fetchBabyInfo
,
fetchAutoPhone
}
from
'../api/user.js'
;
import
{
useGlobalStore
}
from
'./global.js'
;
autoLoginByCode
,
fetchUserInfo
,
fetchBabyInfo
,
fetchAutoPhone
,
}
from
"../api/user.js"
;
import
{
useGlobalStore
}
from
"./global.js"
;
const
globalStore
=
useGlobalStore
();
export
const
useUserStore
=
defineStore
(
'userInfo'
,
{
state
:
()
=>
{
return
{
userInfo
:
null
,
babyInfo
:
null
,
};
},
actions
:
{
/**
* 更新用户信息
* @param {Object} userInfo
*/
setUserInfo
(
userInfo
)
{
this
.
userInfo
=
userInfo
;
},
/**
* 更新宝宝信息
* @param {Object} babyInfo
*/
setBabyInfo
(
babyInfo
)
{
this
.
babyInfo
=
babyInfo
;
},
export
const
useUserStore
=
defineStore
(
"userInfo"
,
{
state
:
()
=>
{
return
{
userInfo
:
{
// memberId: "12",
// memberName: "hzt",
},
babyInfo
:
null
,
};
},
actions
:
{
/**
* 更新用户信息
* @param {Object} userInfo
*/
setUserInfo
(
userInfo
)
{
this
.
userInfo
=
userInfo
;
},
/**
* 用户手机号验证的回调方法,用于获取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'
});
}
},
});
/**
* 更新宝宝信息
* @param {Object} babyInfo
*/
setBabyInfo
(
babyInfo
)
{
this
.
babyInfo
=
babyInfo
;
},
},
/**
* 用户手机号验证的回调方法,用于获取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
()
{
const
{
data
}
=
await
fetchUserInfo
();
console
.
log
(
'userInfo'
,
data
);
if
(
data
?.
memberId
!==
'not_login'
)
{
this
.
userInfo
=
data
;
}
},
/**
* 获取用户信息
*/
async
loadUserInfo
()
{
const
{
data
}
=
await
fetchUserInfo
();
console
.
log
(
"userInfo"
,
data
);
if
(
data
?.
memberId
!==
"not_login"
)
{
this
.
userInfo
=
data
;
}
},
/**
* 获取宝宝信息
*/
async
loadBabyInfo
()
{
const
{
data
}
=
await
fetchBabyInfo
();
console
.
log
(
'babyInfo'
,
data
);
if
(
data
?.
memberId
!==
'not_login'
)
{
this
.
babyInfo
=
data
;
}
},
/**
* 获取宝宝信息
*/
async
loadBabyInfo
()
{
const
{
data
}
=
await
fetchBabyInfo
();
console
.
log
(
"babyInfo"
,
data
);
if
(
data
?.
memberId
!==
"not_login"
)
{
this
.
babyInfo
=
data
;
}
},
/**
* wx.login 获取code后,调用此方法完成登录
* @param {String} code
*/
async
autoLoginByCode
(
code
)
{
const
{
data
}
=
await
autoLoginByCode
(
code
);
console
.
log
(
'autoLoginByCode'
,
data
);
// 如果登录成功,获取用户信息和宝宝信息,更新到state中,方便全局使用
if
(
data
&&
data
.
cuk
)
{
globalStore
.
setCuk
(
data
.
cuk
);
/**
* wx.login 获取code后,调用此方法完成登录
* @param {String} code
*/
async
autoLoginByCode
(
code
)
{
const
{
data
}
=
await
autoLoginByCode
(
code
);
console
.
log
(
"autoLoginByCode"
,
data
);
// 如果登录成功,获取用户信息和宝宝信息,更新到state中,方便全局使用
if
(
data
&&
data
.
cuk
)
{
globalStore
.
setCuk
(
data
.
cuk
);
this
.
loadUserInfo
();
this
.
loadBabyInfo
();
}
},
this
.
loadUserInfo
();
this
.
loadBabyInfo
();
}
},
/**
* 用户自动登录
*/
async
wxAutoLogin
()
{
uni
.
login
({
provider
:
'weixin'
,
success
:
(
res
)
=>
{
console
.
log
(
'wxAutoLogin'
,
res
);
if
(
res
.
errMsg
===
'login:ok'
)
{
this
.
autoLoginByCode
(
res
.
code
);
}
else
{
uni
.
showToast
({
title
:
res
.
errMsg
,
icon
:
'error'
});
}
},
});
},
},
});
\ No newline at end of file
/**
* 用户自动登录
*/
async
wxAutoLogin
()
{
uni
.
login
({
provider
:
"weixin"
,
success
:
(
res
)
=>
{
console
.
log
(
"wxAutoLogin"
,
res
);
if
(
res
.
errMsg
===
"login:ok"
)
{
this
.
autoLoginByCode
(
res
.
code
);
}
else
{
uni
.
showToast
({
title
:
res
.
errMsg
,
icon
:
"error"
,
});
}
},
});
},
},
});
views/My.vue
View file @
19462a4a
<
template
>
<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"
>
<image
class=
"bg-img"
...
...
@@ -10,47 +20,85 @@
bindload=
""
/>
</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=
"avatar-container"
>
<image
class=
"avatar"
:src=
"userInfo.avatar"
mode=
"aspectFill"
/>
<view
class=
"avatar-container"
@
click=
"handleEditProfile"
>
<image
class=
"avatar"
:src=
"babyInfo.babyAvatar || $baseUrl + 'common/default_avatar.png'"
mode=
"aspectFill"
/>
</view>
<image
class=
"avatar-modify"
:src=
"$baseUrl + 'my/icon_modify.png'"
mode=
"aspectFit"
lazy-load=
"false"
@
click=
"handleEditProfile"
/>
<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"
>
<text
class=
"integral-account-text"
>
积分账户:
</text>
<text
class=
"integral-account-value"
>
---
</text>
<text
class=
"integral-account-value"
>
{{
babyInfo
.
points
||
"---"
}}
</text
>
</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>
<!-- user desc -->
<view
class=
"user-desc"
>
<view
v-if=
"cfgStatus.showDetail"
class=
"user-desc"
>
<view
class=
"desc-top"
>
<text
class=
"desc-title"
>
宝宝变化
</text>
<text
class=
"desc-age"
>
{{
babyDetail
[
0
].
age
}}
{{
wheelOptions
[
wheelSelectedIndex
]?.
label
}}
</text>
</view>
<view
class=
"desc-content"
>
<text
class=
"desc-text"
>
{{
cfgStatus
.
openBabyCardDesc
?
babyDetail
[
0
].
desc
:
babyDetail
[
0
].
desc
.
slice
(
0
,
46
)
+
"..."
wheelOptions
[
wheelSelectedIndex
]?.
desc
.
length
>
46
?
cfgStatus
.
openBabyCardDesc
?
wheelOptions
[
wheelSelectedIndex
]?.
desc
:
wheelOptions
[
wheelSelectedIndex
]?.
desc
.
slice
(
0
,
46
)
+
"..."
:
wheelOptions
[
wheelSelectedIndex
]?.
desc
}}
</text>
<text
v-if=
"wheelOptions[wheelSelectedIndex]?.desc.length > 46"
class=
"desc-more"
@
click=
"cfgStatus.openBabyCardDesc = !cfgStatus.openBabyCardDesc"
>
{{
cfgStatus
.
openBabyCardDesc
?
"点击收起"
:
"点击展开"
}}
</text
...
...
@@ -74,32 +122,28 @@
<view
class=
"hot-member"
@
click=
"handleHot"
data-type=
"member"
></view>
<view
class=
"hot-privacy"
@
click=
"handleHot"
data-type=
"privacy"
></view>
</view>
<RegisterLayer
v-model=
"showRegisterLayer"
:value=
"registerImageUrl"
@
update:value=
"(val) => (registerImageUrl = val)"
@
confirm=
"onRegisterConfirm"
/>
<RegisterLayer
v-model=
"showRegisterLayer"
@
confirm=
"onRegisterConfirm"
/>
</view>
</
template
>
<
script
setup
>
import
{
ref
,
onMounted
,
getCurrentInstance
}
from
"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
$baseUrl
=
proxy
.
$baseUrl
;
const
cfgStatus
=
ref
({
openBabyCardDesc
:
false
,
showDetail
:
false
,
isRegister
:
false
,
});
const
babyDetail
=
ref
([
{
age
:
"2月龄"
,
desc
:
"宝宝开始对周围环境产生兴趣,喜欢看、听、摸,开始对玩具感兴趣,开始对妈妈的声音产生反应。宝宝开始对周围环境产生兴趣,喜欢看、听、摸,开始对玩具感兴趣,开始对妈妈的声音产生反应。宝宝开始对周围环境产生兴趣,喜欢看、听、摸,开始对玩具感兴趣,开始对妈妈的声音产生反应。"
,
},
]);
const
wheelOptions
=
ref
([]);
const
wheelSelectedIndex
=
ref
(
0
);
const
toolList
=
ref
([
{
...
...
@@ -129,11 +173,55 @@ const toolList = ref([
},
]);
// 用户信息
const
userInfo
=
ref
({});
const
babyInfo
=
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
registerImageUrl
=
ref
(
""
);
const
showBabySwitcher
=
ref
(
false
);
const
handleHot
=
(
e
)
=>
{
const
type
=
e
.
currentTarget
.
dataset
.
type
;
...
...
@@ -164,7 +252,8 @@ const navigateTo = (url) => {
// 编辑个人资料
const
handleEditProfile
=
()
=>
{
if
(
!
userInfo
.
value
||
JSON
.
stringify
(
userInfo
.
value
)
===
"{}"
)
{
const
userStore
=
useUserStore
();
if
(
!
userStore
.
userInfo
||
JSON
.
stringify
(
userStore
.
userInfo
)
===
"{}"
)
{
return
;
}
navigateTo
(
"/pages/person/person"
);
...
...
@@ -172,42 +261,86 @@ const handleEditProfile = () => {
const
handleRegister
=
()
=>
{
// 判断是否已注册
if
(
!
userInfo
.
value
||
JSON
.
stringify
(
userInfo
.
value
)
===
"{}"
)
{
showRegisterLayer
.
value
=
true
;
if
(
!
cfgStatus
.
value
.
isRegister
)
{
// 调用登录接口
// console.log("phoneButton", phoneButton.value);
// phoneButton.value.triggerEvent("tap");
}
return
;
};
function
onRegisterConfirm
(
data
)
{
const
onRegisterConfirm
=
async
(
data
)
=>
{
console
.
log
(
"onRegisterConfirm:"
,
data
);
showRegisterLayer
.
value
=
false
;
}
const
userStore
=
useUserStore
();
await
Promise
.
all
[(
userStore
.
loadUserInfo
(),
userStore
.
loadBabyInfo
())];
initData
();
};
// 获取用户信息
const
getUserInfo
=
async
()
=>
{
try
{
// TODO: 调用获取用户信息接口
const
res
=
await
uni
.
request
({
url
:
"/api/user/info"
,
method
:
"GET"
,
});
if
(
res
.
data
.
code
===
0
)
{
userInfo
.
value
=
res
.
data
.
data
;
}
}
catch
(
error
)
{
console
.
error
(
"获取用户信息失败:"
,
error
);
const
initData
=
async
()
=>
{
const
userStore
=
useUserStore
();
if
(
!
userStore
.
userInfo
||
JSON
.
stringify
(
userStore
.
userInfo
)
==
"{}"
)
{
cfgStatus
.
value
.
isRegister
=
false
;
cfgStatus
.
value
.
showDetail
=
false
;
return
;
}
const
__showDetail
=
[
1
,
2
].
includes
(
babyInfo
.
value
.
babyStage
);
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
({
title
:
"
获取用户信息失败
"
,
title
:
"
请授权使用手机号
"
,
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
(()
=>
{
// getUserInfo()
// getOrderCounts()
initData
();
});
// 定义页面配置
...
...
@@ -222,6 +355,26 @@ defineExpose({});
padding-bottom: 100rpx;
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 {
width: 750rpx;
height: 840rpx;
...
...
@@ -281,6 +434,7 @@ defineExpose({});
top: 84rpx;
z-index: 1;
display: block;
pointer-events: none;
}
.user-detail {
...
...
@@ -292,6 +446,19 @@ defineExpose({});
top: 48rpx;
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 {
font-size: 32rpx;
font-weight: 500;
...
...
@@ -395,6 +562,10 @@ defineExpose({});
}
}
.user-info-min {
min-height: 180rpx;
}
.tool-container {
margin: 0 auto;
margin-top: 48rpx;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment