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
821b80a8
Commit
821b80a8
authored
Sep 10, 2025
by
spc
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'master' into 20250901_915Act
parents
426127d7
21692b07
Changes
17
Show whitespace changes
Inline
Side-by-side
Showing
17 changed files
with
6108 additions
and
5083 deletions
+6108
-5083
BabySwitchPopup.vue
components/BabySwitchPopup.vue
+45
-63
popup-tip.vue
components/popup-tip/popup-tip.vue
+68
-19
md.js
md.js
+11
-1
home.json
mock/home.json
+6
-0
integral.json
mock/integral.json
+815
-0
my.json
mock/my.json
+437
-446
XingmaLabDetailPage.vue
pages/XingmaLabDetailPage/XingmaLabDetailPage.vue
+24
-8
feedingIndex.vue
pages/feedingIndex/feedingIndex.vue
+4145
-3995
person.vue
pages/person/person.vue
+75
-153
postnatalCheckUp.vue
pages/postnatalCheckUp/postnatalCheckUp.vue
+47
-7
shengzhangTestResult.vue
pages/shengzhangTestResult/shengzhangTestResult.vue
+18
-6
shengzhangTools.vue
pages/shengzhangTools/shengzhangTools.vue
+304
-288
xingmaLab.vue
pages/xingmaLab/xingmaLab.vue
+100
-91
user.js
stores/user.js
+6
-2
index.js
utils/index.js
+1
-1
Home.vue
views/Home.vue
+1
-1
My.vue
views/My.vue
+5
-2
No files found.
components/BabySwitchPopup.vue
View file @
821b80a8
...
...
@@ -4,68 +4,45 @@
<!-- 弹窗头部 -->
<view
class=
"popup-header"
>
<text
class=
"popup-title"
>
切换宝宝
</text>
<image
class=
"close-btn"
:src=
"`$
{$baseUrl}shengzhangTool/1001/changeBaby/closeBtn.png`"
mode="aspectFit"
@click="closePopup"
/>
<image
class=
"close-btn"
:src=
"`$
{$baseUrl}shengzhangTool/1001/changeBaby/closeBtn.png`"
mode="aspectFit" @click="closePopup" />
</view>
<!-- 宝宝列表 -->
<view
class=
"baby-list"
>
<view
v-for=
"(baby, index) in babyList"
:key=
"index"
class=
"baby-item"
:class=
"
{ selected: selectIndex === index }"
@click="selectBaby(index)"
>
<view
v-for=
"(baby, index) in babyList"
:key=
"index"
class=
"baby-item"
:class=
"
{ selected: selectIndex === index }" @click="selectBaby(index)">
<!-- 选中背景 -->
<image
v-if=
"selectIndex === index"
class=
"baby-item-bg"
:src=
"`$
{$baseUrl}shengzhangTool/1001/changeBaby/babyItemBg.png`"
mode="aspectFit"
/>
<image
v-if=
"selectIndex === index"
class=
"baby-item-bg"
:src=
"`$
{$baseUrl}shengzhangTool/1001/changeBaby/babyItemBg.png`" mode="aspectFit" />
<!-- 宝宝头像 -->
<image
class=
"baby-avatar"
<image
class=
"baby-avatar"
:src=
"baby.babyAvatar || `https://course.feihe.com/momclub-picture/common/default_avatar.png`"
mode=
"aspectFill"
/>
mode=
"aspectFill"
/>
<!-- 宝宝信息 -->
<view
class=
"baby-info"
>
<view
class=
"baby-name-row"
>
<text
class=
"baby-name"
>
{{
baby
.
babyName
}}
</text>
<image
class=
"gender-icon"
<image
class=
"gender-icon"
:src=
"baby.babyGender === 'M' ? `$
{$baseUrl}shengzhangTool/1001/sex1.png` : `${$baseUrl}shengzhangTool/1001/sex0.png`"
mode="aspectFit"
/>
mode="aspectFit" />
</view>
<text
class=
"baby-birthday"
>
宝宝生日:
{{
baby
.
babyBirthday
}}
</text>
</view>
</view>
</view>
<image
class=
"ok-btn"
:class=
"
{'ok-btn-active': isOkPressed}"
:src="`${$baseUrl}shengzhangTool/1001/changeBaby/okBtn.png`"
@touchstart="handleOkTouchStart"
@touchend="handleOkTouchEnd"
mode="aspectFit"
>
</image>
<image
class=
"ok-btn"
:class=
"
{ 'ok-btn-active': isOkPressed }"
:src="`${$baseUrl}shengzhangTool/1001/changeBaby/okBtn.png`" @touchstart="handleOkTouchStart"
@touchend="handleOkTouchEnd" mode="aspectFit">
</image>
</view>
</view>
</
template
>
<
script
setup
>
import
{
ref
,
defineEmits
,
defineProps
,
onMounted
}
from
'vue'
import
{
ref
,
defineEmits
,
defineProps
,
onMounted
,
watch
}
from
'vue'
import
{
useUserStore
}
from
"@/stores/user"
;
import
md
from
'../md.js'
...
...
@@ -91,6 +68,7 @@ const props = defineProps({
}
})
const
userStore
=
useUserStore
();
const
emit
=
defineEmits
([
'update:visible'
,
'update:selectedIndex'
,
'change'
])
...
...
@@ -145,9 +123,10 @@ const selectBaby = (index) => {
}
const
babyList
=
ref
([]);
onMounted
(()
=>
{
const
initListData
=
()
=>
{
babyList
.
value
=
(
userStore
.
babyInfo
?.
allBabyBaseInfo
||
[]).
filter
(
tem
=>
tem
.
babyStage
===
2
);
if
(
babyList
.
value
===
null
)
{
if
(
babyList
.
value
===
null
)
{
babyList
.
value
=
[];
}
...
...
@@ -159,6 +138,16 @@ onMounted(() => {
toolName
:
"生长曲线"
,
popName
:
"切换宝宝弹窗"
});
}
watch
(()
=>
props
.
visible
,
(
val
,
oldVal
)
=>
{
if
(
val
&&
!
oldVal
)
{
// 打开的时候更新数据
initListData
();
}
},
{
immediate
:
true
})
onMounted
(()
=>
{
initListData
();
})
...
...
@@ -285,6 +274,7 @@ onMounted(() => {
height: 98rpx;
margin-left: 35rpx;
margin-top: 0rpx;
&.ok-btn-active {
transform: scale(0.95);
}
...
...
@@ -292,12 +282,4 @@ onMounted(() => {
}
}
</
style
>
\ No newline at end of file
components/popup-tip/popup-tip.vue
View file @
821b80a8
...
...
@@ -35,6 +35,7 @@
</
template
>
</view>
<view
class=
"form-btn"
@
click=
"onAdd"
>
<image
v-if=
"isType == '0' || isType == '2'"
:src=
"`${$baseUrl}chanjianTool/1001/icon23.png`"
></image>
<
template
v-if=
"type == '1'"
>
...
...
@@ -43,6 +44,8 @@
<
template
v-if=
"type == '2'"
>
{{
isType
==
'0'
?
'添加状态'
:
isType
==
'3'
?
'我知道了'
:
isType
==
'1'
?
'切换状态'
:
'修改状态'
}}
</
template
>
<button
v-if=
"isNotLogin"
type=
"primary"
class=
"phone-button"
open-type=
"getPhoneNumber"
@
getphonenumber=
"getRealtimePhoneNumber"
/>
</view>
</view>
</view>
...
...
@@ -53,7 +56,8 @@ import {
ref
,
onMounted
,
computed
,
defineEmits
defineEmits
,
watch
}
from
'vue'
import
{
useUserStore
}
from
"@/stores/user"
;
// 接受父组件参数
...
...
@@ -61,6 +65,10 @@ const props = defineProps({
type
:
{
type
:
String
,
default
:
'1'
,
// 1 非宝宝状态 2 非孕中状态
},
isNotLogin
:
{
type
:
Boolean
,
default
:
false
//是否未登录
}
})
// 用户信息
...
...
@@ -68,7 +76,7 @@ const userStore = useUserStore();
const
babyInfo
=
ref
(
userStore
.
babyInfo
)
// 回调函数
const
emit
=
defineEmits
([
'statusChange'
,
'close'
])
const
emit
=
defineEmits
([
'statusChange'
,
'close'
])
const
isType
=
ref
(
'0'
)
// 0 添加状态或者宝宝 1 切换状态 2 修改状态 3 宝宝已达上限
...
...
@@ -98,7 +106,25 @@ const navigateToFn = () => {
url
:
`/pages/person/person?type=
${
type
}
`
})
}
const
getRealtimePhoneNumber
=
async
(
e
)
=>
{
console
.
log
(
"获取手机号码"
,
e
);
if
(
e
.
detail
.
errMsg
!==
"getPhoneNumber:ok"
)
{
uni
.
showToast
({
title
:
"请授权使用手机号"
,
icon
:
"none"
,
});
return
;
}
await
userStore
.
phoneCallback
(
e
.
detail
,
()
=>
{
},
()
=>
{
emit
(
'afterPhone'
)
//如果没有宝宝信息,页面中处理宝宝注册信息
});
console
.
log
(
"closeclosecloseclose"
);
emit
(
'close'
)
emit
(
'statusChange'
)
//借用这个事件,刷新下页面数据
};
// 切换状态 需要对应的宝宝id 直接请求接口
const
switchState
=
async
()
=>
{
console
.
log
(
'切换状态'
,
babyBaseId
.
value
)
...
...
@@ -117,8 +143,12 @@ const modifyState = async () => {
url
:
`/pages/person/person?type=
${
type
}
&id=
${
babyBaseId
.
value
}
`
})
}
//这里新增一下未登录的情况,点击事件直接去拉起手机号授权
// 跳转新增产检页面
const
onAdd
=
()
=>
{
if
(
props
.
isNotLogin
==
true
)
{
return
;
}
// 0 添加状态或者宝宝 1 切换状态 2 修改状态 3 宝宝已达上限
switch
(
isType
.
value
)
{
case
'0'
:
...
...
@@ -131,17 +161,28 @@ const onAdd = () => {
modifyState
()
break
;
case
'3'
:
if
(
getCurrentPages
().
length
>
1
)
{
uni
.
navigateBack
()
}
else
{
uni
.
reLaunch
({
url
:
'/pages/index/index'
})
}
break
;
default
:
break
;
}
}
onMounted
(()
=>
{
onMounted
(
async
()
=>
{
if
(
props
.
isNotLogin
)
{
await
userStore
.
wxAutoLogin
();
}
// 宝宝生长测试和喂养记录
console
.
log
(
'babyInfo-获取宝宝'
,
babyInfo
.
value
)
const
babyBaseInfo
=
babyInfo
.
value
.
allBabyBaseInfo
const
babyBaseInfo
=
babyInfo
?.
value
?
.
allBabyBaseInfo
console
.
log
(
"🚀 ~ babyBaseInfo:"
,
babyBaseInfo
)
// 有宝宝状态
if
(
babyBaseInfo
)
{
...
...
@@ -319,11 +360,19 @@ onMounted(() => {
align-items
:
center
;
justify-content
:
center
;
margin-top
:
55rpx
;
position
:
relative
;
image
{
width
:
42rpx
;
height
:
42rpx
;
margin-right
:
12rpx
;
}
.phone-button
{
width
:
100%
;
height
:
100%
;
position
:
absolute
;
opacity
:
0
;
}
}
</
style
>
\ No newline at end of file
md.js
View file @
821b80a8
...
...
@@ -6,7 +6,7 @@ const init = (SENSORS_URL) => {
sensors
.
setPara
({
name
:
"sensors"
,
server_url
:
SENSORS_URL
,
show_log
:
tru
e
,
show_log
:
fals
e
,
autoTrack
:
{
appLaunch
:
true
,
// 默认为 true,false 则关闭 $MPLaunch 事件采集
appShow
:
true
,
// 默认为 true,false 则关闭 $MPShow 事件采集
...
...
@@ -178,6 +178,15 @@ const sensorPopLogTake = (logObj) => {
sensorPopLog
(
evt
);
};
const
sensorUserLogTake
=
(
logObj
)
=>
{
if
(
!
logObj
)
{
return
;
}
sensors
.
track
(
"xcxUserStatus"
,
{
...
logObj
,
});
};
export
default
{
init
,
sensors
,
...
...
@@ -188,4 +197,5 @@ export default {
sensorComponentLogTake
,
sensorPopLog
,
sensorPopLogTake
,
sensorUserLogTake
};
mock/home.json
View file @
821b80a8
...
...
@@ -120,6 +120,12 @@
},
"channelTabListMianTitle"
:
"有声频道"
,
"swiperList"
:
[
{
"videoUrl"
:
"homepage/homeSwiper/V1/9_1.mp4"
,
"link"
:
{},
"title"
:
"教师节banner"
,
"url"
:
"homepage/homeSwiper/V1/9.gif"
},
{
"img"
:
"homepage/homeSwiper/V1/7.jpg"
,
"link"
:
{
...
...
mock/integral.json
0 → 100644
View file @
821b80a8
{
"clickMore"
:
{
"extra"
:
{
"envVersion"
:
"release"
,
"appId"
:
"wx4205ec55b793245e"
},
"type"
:
2
,
"url"
:
"subPackages/xmhMainProcess/member/index?entrySource=xmh_wechatmp_points_recgoodsbot"
},
"tupianBanben"
:
"1022"
,
"swiper"
:
[],
"goodsListData"
:
{
"listCommon"
:
{
"listItemImgBg"
:
"integral/1022/listItemImgBg.png"
},
"tabInfo"
:
{
"tabBg"
:
"tapSelectBg.png"
,
"tabTexts"
:
[
{
"line2"
:
""
,
"line1"
:
"星品榜单"
},
{
"line2"
:
""
,
"line1"
:
"0元爆款"
},
{
"line2"
:
""
,
"line1"
:
"北纬专场"
}
]
},
"goodsData"
:
[
{
"titles"
:
[
"星飞帆4段儿童成长配..."
,
"星飞帆卓睿4段儿童配..."
,
"飞鹤臻贵儿童成长配方..."
,
"茁然 茁护儿童配方奶..."
,
"经典爱本乳铁蛋白配方..."
,
"飞鹤茁然高钙奶酪泡芙..."
,
"金装1962-中老年高钙..."
,
"经典爱本膳骨配方奶粉..."
,
"经典爱本清澄配方奶粉..."
,
"金装1962-高钙高蛋白..."
,
"德佑纯水湿巾80抽/包"
,
"婴儿专护除菌除螨洗衣..."
,
"DHA深海鳕鱼肠80g*4袋"
,
"云朵软软绵柔巾洗脸巾..."
],
"prices"
:
[
"低至730积分+¥115"
,
"低至865积分+¥195"
,
"低至1000积分+¥228"
,
"低至715积分+¥125"
,
"低至3160积分+¥126.4"
,
"低至1400积分+¥55.8"
,
"低至1780积分+¥71.2"
,
"低至3160积分+¥126.4"
,
"低至3960积分+¥158.4"
,
"低至1780积分+¥71.2"
,
"低至65积分+¥36.5"
,
"低至440积分+¥17.5"
,
"低至520积分+¥20.8"
,
"低至460积分+¥18.3"
],
"goodsImgs"
:
[
"listItemImgJx0.png"
,
"listItemImgJx1.png"
,
"listItemImgJx2.png"
,
"listItemImgJx3.png"
,
"listItemImgJx4.png"
,
"listItemImgJx5.png"
,
"listItemImgJx6.png"
,
"listItemImgJx7.png"
,
"listItemImgJx8.png"
,
"listItemImgJx9.png"
,
"listItemImgJx10.png"
,
"listItemImgJx11.png"
,
"listItemImgJx13.png"
,
"listItemImgJx14.png"
]
},
{
"titles"
:
[
"星飞帆4段儿童成长配..."
,
"飞鹤茁然儿童配方奶升..."
,
"茁然 茁护儿童配方奶..."
,
"宝宝钙维生素D软胶囊..."
,
"公牛 新国标插座/插线..."
,
"九阳煮蛋器多功能智能..."
,
"荣事达电煮锅家用多功..."
,
"babygo进口户外防水..."
,
"苏泊尔(SUPOR)真..."
,
"超级飞侠儿童绘画笔套..."
],
"prices"
:
[
11500
,
8900
,
12000
,
5450
,
5980
,
5900
,
5900
,
3800
,
9900
,
7900
],
"goodsImgs"
:
[
"listItemImgXL0.png"
,
"listItemImgXL1.png"
,
"listItemImgXL2.png"
,
"listItemImgXL3.png"
,
"listItemImgXL5.png"
,
"listItemImgXL7.png"
,
"listItemImgXL9.png"
,
"listItemImgXL11.png"
,
"listItemImgXL12.png"
,
"listItemImgXL13.png"
]
},
{
"titles"
:
[
"北纬47度水果玉米"
,
"北纬47度黄糯鲜玉米"
,
"北纬47度白甜糯玉米"
,
"北纬47度东北烧烤..."
,
"北纬47度花甜糯玉米"
,
"北纬47度黑珍珠玉米"
,
"N47°植物酵素乳245..."
,
"N47°水果玉米汁245..."
],
"prices"
:
[
4740
,
3900
,
4600
,
5990
,
4600
,
5200
,
9990
,
7990
],
"goodsImgs"
:
[
"listItemImgPzh0.png"
,
"listItemImgPzh1.png"
,
"listItemImgPzh2.png"
,
"listItemImgPzh3.png"
,
"listItemImgPzh4.png"
,
"listItemImgPzh5.png"
,
"listItemImgPzh6.png"
,
"listItemImgPzh7.png"
]
}
],
"productIdUrl"
:
{
"lingyuan"
:
[
{
"productId"
:
"643301938280182989"
,
"extra"
:
{
"envVersion"
:
"release"
,
"appId"
:
"wx4205ec55b793245e"
},
"type"
:
2
,
"url"
:
"subPackages/shopMainProcess/product/index?productId={productId}&skuId={skuId}&entrySource=xmh_wechatmp_points_star"
,
"skuId"
:
"643301938280182990"
},
{
"productId"
:
"570770855028876907"
,
"extra"
:
{
"envVersion"
:
"release"
,
"appId"
:
"wx4205ec55b793245e"
},
"type"
:
2
,
"url"
:
"subPackages/shopMainProcess/product/index?productId={productId}&skuId={skuId}&entrySource=xmh_wechatmp_points_star"
,
"skuId"
:
"570770855028876908"
},
{
"productId"
:
"643302772176787321"
,
"extra"
:
{
"envVersion"
:
"release"
,
"appId"
:
"wx4205ec55b793245e"
},
"type"
:
2
,
"url"
:
"subPackages/shopMainProcess/product/index?productId={productId}&skuId={skuId}&entrySource=xmh_wechatmp_points_star"
,
"skuId"
:
"643302772176787322"
},
{
"productId"
:
"650261586675438161"
,
"extra"
:
{
"envVersion"
:
"release"
,
"appId"
:
"wx4205ec55b793245e"
},
"type"
:
2
,
"url"
:
"subPackages/shopMainProcess/product/index?productId={productId}&skuId={skuId}&entrySource=xmh_wechatmp_points_star"
,
"skuId"
:
"650261761758111604"
},
{
"productId"
:
"637462885116453461"
,
"extra"
:
{
"envVersion"
:
"release"
,
"appId"
:
"wx4205ec55b793245e"
},
"type"
:
2
,
"url"
:
"subPackages/shopMainProcess/product/index?productId={productId}&skuId={skuId}&entrySource=xmh_wechatmp_points_star"
,
"skuId"
:
"637462885116453462"
},
{
"productId"
:
"664995106239801237"
,
"extra"
:
{
"envVersion"
:
"release"
,
"appId"
:
"wx4205ec55b793245e"
},
"type"
:
2
,
"url"
:
"subPackages/shopMainProcess/product/index?productId={productId}&skuId={skuId}&entrySource=xmh_wechatmp_points_star"
,
"skuId"
:
"664995106239801238"
},
{
"productId"
:
"664992929630904330"
,
"extra"
:
{
"envVersion"
:
"release"
,
"appId"
:
"wx4205ec55b793245e"
},
"type"
:
2
,
"url"
:
"subPackages/shopMainProcess/product/index?productId={productId}&skuId={skuId}&entrySource=xmh_wechatmp_points_star"
,
"skuId"
:
"702706680618457075"
},
{
"productId"
:
"477231839213998660"
,
"extra"
:
{
"envVersion"
:
"release"
,
"appId"
:
"wx4205ec55b793245e"
},
"type"
:
2
,
"url"
:
"subPackages/shopMainProcess/product/index?productId={productId}&skuId={skuId}&entrySource=xmh_wechatmp_points_star"
,
"skuId"
:
"477231839213998661"
},
{
"productId"
:
"710238004623156187"
,
"extra"
:
{
"envVersion"
:
"release"
,
"appId"
:
"wx4205ec55b793245e"
},
"type"
:
2
,
"url"
:
"subPackages/shopMainProcess/product/index?productId={productId}&skuId={skuId}&entrySource=xmh_wechatmp_points_star"
,
"skuId"
:
"710238148411278894"
},
{
"productId"
:
"637105594356118250"
,
"extra"
:
{
"envVersion"
:
"release"
,
"appId"
:
"wx4205ec55b793245e"
},
"type"
:
2
,
"url"
:
"subPackages/shopMainProcess/product/index?productId={productId}&skuId={skuId}&entrySource=xmh_wechatmp_points_star"
,
"skuId"
:
"637105594356118251"
}
],
"xingpin"
:
[
{
"productId"
:
"632366292935447153"
,
"extra"
:
{
"envVersion"
:
"release"
,
"appId"
:
"wx4205ec55b793245e"
},
"type"
:
2
,
"url"
:
"subPackages/shopMainProcess/product/index?productId={productId}&skuId={skuId}&entrySource=xmh_wechatmp_points_star"
,
"skuId"
:
"632366292935447154"
},
{
"productId"
:
"434526218612696157"
,
"extra"
:
{
"envVersion"
:
"release"
,
"appId"
:
"wx4205ec55b793245e"
},
"type"
:
2
,
"url"
:
"subPackages/shopMainProcess/product/index?productId={productId}&skuId={skuId}&entrySource=xmh_wechatmp_points_star"
,
"skuId"
:
"434526218612696158"
},
{
"productId"
:
"779457178234291713"
,
"extra"
:
{
"envVersion"
:
"release"
,
"appId"
:
"wx4205ec55b793245e"
},
"type"
:
2
,
"url"
:
"subPackages/shopMainProcess/product/index?productId={productId}&skuId={skuId}&entrySource=xmh_wechatmp_points_star"
,
"skuId"
:
"779457178234291714"
},
{
"productId"
:
"632368902459430553"
,
"extra"
:
{
"envVersion"
:
"release"
,
"appId"
:
"wx4205ec55b793245e"
},
"type"
:
2
,
"url"
:
"subPackages/shopMainProcess/product/index?productId={productId}&skuId={skuId}&entrySource=xmh_wechatmp_points_star"
,
"skuId"
:
"632368902459430554"
},
{
"productId"
:
"748373470406312440"
,
"extra"
:
{
"envVersion"
:
"release"
,
"appId"
:
"wx4205ec55b793245e"
},
"type"
:
2
,
"url"
:
"subPackages/shopMainProcess/product/index?productId={productId}&skuId={skuId}&entrySource=xmh_wechatmp_points_star"
,
"skuId"
:
"748373470406312441"
},
{
"productId"
:
"700209063828145600"
,
"extra"
:
{
"envVersion"
:
"release"
,
"appId"
:
"wx4205ec55b793245e"
},
"type"
:
2
,
"url"
:
"subPackages/shopMainProcess/product/index?productId={productId}&skuId={skuId}&entrySource=xmh_wechatmp_points_star"
,
"skuId"
:
"700209063828145601"
},
{
"productId"
:
"444612538255511698"
,
"extra"
:
{
"envVersion"
:
"release"
,
"appId"
:
"wx4205ec55b793245e"
},
"type"
:
2
,
"url"
:
"subPackages/shopMainProcess/product/index?productId={productId}&skuId={skuId}&entrySource=xmh_wechatmp_points_star"
,
"skuId"
:
"444612538255511699"
},
{
"productId"
:
"748374838109458955"
,
"extra"
:
{
"envVersion"
:
"release"
,
"appId"
:
"wx4205ec55b793245e"
},
"type"
:
2
,
"url"
:
"subPackages/shopMainProcess/product/index?productId={productId}&skuId={skuId}&entrySource=xmh_wechatmp_points_star"
,
"skuId"
:
"748374838109458956"
},
{
"productId"
:
"748376191670080756"
,
"extra"
:
{
"envVersion"
:
"release"
,
"appId"
:
"wx4205ec55b793245e"
},
"type"
:
2
,
"url"
:
"subPackages/shopMainProcess/product/index?productId={productId}&skuId={skuId}&entrySource=xmh_wechatmp_points_star"
,
"skuId"
:
"748376191670080757"
},
{
"productId"
:
"444614841574228087"
,
"extra"
:
{
"envVersion"
:
"release"
,
"appId"
:
"wx4205ec55b793245e"
},
"type"
:
2
,
"url"
:
"subPackages/shopMainProcess/product/index?productId={productId}&skuId={skuId}&entrySource=xmh_wechatmp_points_star"
,
"skuId"
:
"444614841574228088"
},
{
"productId"
:
"642944987112793104"
,
"extra"
:
{
"envVersion"
:
"release"
,
"appId"
:
"wx4205ec55b793245e"
},
"type"
:
2
,
"url"
:
"subPackages/shopMainProcess/product/index?productId={productId}&skuId={skuId}&entrySource=xmh_wechatmp_points_star"
,
"skuId"
:
"642944987112793105"
},
{
"productId"
:
"660577242594873852"
,
"extra"
:
{
"envVersion"
:
"release"
,
"appId"
:
"wx4205ec55b793245e"
},
"type"
:
2
,
"url"
:
"subPackages/shopMainProcess/product/index?productId={productId}&skuId={skuId}&entrySource=xmh_wechatmp_points_star"
,
"skuId"
:
"660577242594873853"
},
{
"productId"
:
"670068445908034706"
,
"extra"
:
{
"envVersion"
:
"release"
,
"appId"
:
"wx4205ec55b793245e"
},
"type"
:
2
,
"url"
:
"subPackages/shopMainProcess/product/index?productId={productId}&skuId={skuId}&entrySource=xmh_wechatmp_points_star"
,
"skuId"
:
"670072178498381183"
},
{
"productId"
:
"660575857729992191"
,
"extra"
:
{
"envVersion"
:
"release"
,
"appId"
:
"wx4205ec55b793245e"
},
"type"
:
2
,
"url"
:
"subPackages/shopMainProcess/product/index?productId={productId}&skuId={skuId}&entrySource=xmh_wechatmp_points_star"
,
"skuId"
:
"660575857729992192"
}
],
"beiwei"
:
[
{
"productId"
:
"694019044167238066"
,
"extra"
:
{
"envVersion"
:
"release"
,
"appId"
:
"wx4205ec55b793245e"
},
"type"
:
2
,
"url"
:
"subPackages/shopMainProcess/product/index?productId={productId}&skuId={skuId}&entrySource=xmh_wechatmp_points_star"
,
"skuId"
:
"694019044167238067"
},
{
"productId"
:
"548984197069284758"
,
"extra"
:
{
"envVersion"
:
"release"
,
"appId"
:
"wx4205ec55b793245e"
},
"type"
:
2
,
"url"
:
"subPackages/shopMainProcess/product/index?productId={productId}&skuId={skuId}&entrySource=xmh_wechatmp_points_star"
,
"skuId"
:
"548984197069284759"
},
{
"productId"
:
"548991402553569325"
,
"extra"
:
{
"envVersion"
:
"release"
,
"appId"
:
"wx4205ec55b793245e"
},
"type"
:
2
,
"url"
:
"subPackages/shopMainProcess/product/index?productId={productId}&skuId={skuId}&entrySource=xmh_wechatmp_points_star"
,
"skuId"
:
"548991402553569326"
},
{
"productId"
:
"757045038059549612"
,
"extra"
:
{
"envVersion"
:
"release"
,
"appId"
:
"wx4205ec55b793245e"
},
"type"
:
2
,
"url"
:
"subPackages/shopMainProcess/product/index?productId={productId}&skuId={skuId}&entrySource=xmh_wechatmp_points_star"
,
"skuId"
:
"757045038059549613"
},
{
"productId"
:
"555507401709887582"
,
"extra"
:
{
"envVersion"
:
"release"
,
"appId"
:
"wx4205ec55b793245e"
},
"type"
:
2
,
"url"
:
"subPackages/shopMainProcess/product/index?productId={productId}&skuId={skuId}&entrySource=xmh_wechatmp_points_star"
,
"skuId"
:
"555507401709887583"
},
{
"productId"
:
"555151404052796950"
,
"extra"
:
{
"envVersion"
:
"release"
,
"appId"
:
"wx4205ec55b793245e"
},
"type"
:
2
,
"url"
:
"subPackages/shopMainProcess/product/index?productId={productId}&skuId={skuId}&entrySource=xmh_wechatmp_points_star"
,
"skuId"
:
"555151404052796951"
},
{
"productId"
:
"704050114989893289"
,
"extra"
:
{
"envVersion"
:
"release"
,
"appId"
:
"wx4205ec55b793245e"
},
"type"
:
2
,
"url"
:
"subPackages/shopMainProcess/product/index?productId={productId}&skuId={skuId}&entrySource=xmh_wechatmp_points_star"
,
"skuId"
:
"704050114989893290"
},
{
"productId"
:
"710290587034550507"
,
"extra"
:
{
"envVersion"
:
"release"
,
"appId"
:
"wx4205ec55b793245e"
},
"type"
:
2
,
"url"
:
"subPackages/shopMainProcess/product/index?productId={productId}&skuId={skuId}&entrySource=xmh_wechatmp_points_star"
,
"skuId"
:
"710290587034550508"
}
]
}
},
"quanyitiaozhuanInfo"
:
{
"shengrili"
:
{
"qushiyong"
:
{
"extra"
:
{
"envVersion"
:
"release"
,
"appId"
:
"wx4205ec55b793245e"
},
"type"
:
2
,
"url"
:
"subPackages/shopMainProcess/coupons/couponList"
}
},
"suyuanyou"
:
{
"qubaoming"
:
{
"type"
:
3
,
"url"
:
"https://member.feihe.com/memberH5/#/SyySignupInfo?activityCode=syy20250806&sceneCode=WXG01"
}
}
},
"vipIntegral"
:
{
"gonglue"
:
{
"img"
:
"strategyBtn.png"
,
"type"
:
3
,
"url"
:
"https://mom.feihe.com/member/mine/pointStrategy"
},
"jifenmingxi"
:
{
"type"
:
3
,
"url"
:
"https://mom.feihe.com/member/mine/newPointDetail?crmId={crmid}&appCode=XMH"
},
"progressBar"
:
{
"barBgImg"
:
"progressBarBgIntegral.png"
,
"barImg"
:
"progressBarIntegral.png"
},
"vipCardInfo"
:
{
"extra"
:
{
"envVersion"
:
"release"
,
"appId"
:
"wx4205ec55b793245e"
},
"type"
:
2
,
"url"
:
"subPackages/xmhMainProcess/member/index?entrySource=xmh_wechatmp_points_recgoodsbot"
},
"excharge"
:
{
"img"
:
"integralExchargeBtn.png"
,
"extra"
:
{
"envVersion"
:
"release"
,
"appId"
:
"wx4205ec55b793245e"
},
"type"
:
2
,
"url"
:
"subPackages/shopMainList/topicNew/index?id=1000187"
}
},
"viplv"
:
{
"imgs"
:
[
"imgPlatinum0.png"
,
"imgPlatinum1.png"
,
"imgPlatinum2.png"
,
"imgPlatinum3.png"
,
"imgPlatinum4.png"
],
"upLvTxts"
:
[
"扫罐内码或下单有机会提升至/V2铂金会员"
,
"扫罐内码或下单有机会提升至/V3钻石会员"
,
"扫罐内码或下单有机会提升至/V4星光会员"
,
"扫罐内码或下单有机会提升至/V5星耀会员"
,
"已提升至最高等级/V5星耀会员"
],
"vipLvIcon"
:
[
"imgPlatinumIcon0.png"
,
"imgPlatinumIcon1.png"
,
"imgPlatinumIcon2.png"
,
"imgPlatinumIcon3.png"
,
"imgPlatinumIcon4.png"
],
"nickNameColors"
:
[
"#1d1e25"
,
"#1d1e25"
,
"#ffffff"
],
"imgBgs"
:
[
"imgPlatinumBg0.png"
,
"imgPlatinumBg1.png"
,
"imgPlatinumBg2.png"
,
"imgPlatinumBg3.png"
,
"imgPlatinumBg4.png"
],
"dangqianColors"
:
[
"#b27c1e"
,
"#447ab0"
,
"#332288"
,
"#674513"
,
"#674513"
],
"vipNameImgs"
:
[
"imgPlatinumName0.png"
,
"imgPlatinumName1.png"
,
"imgPlatinumName2.png"
,
"imgPlatinumName3.png"
,
"imgPlatinumName4.png"
]
},
"vipActive"
:
[
{
"img"
:
"vipAct250910001.png"
,
"extra"
:
{
"envVersion"
:
"release"
,
"appId"
:
"wx4205ec55b793245e"
},
"type"
:
2
,
"url"
:
"/subPackages/shopMainProcess/product/index?productId=543558664688883066&skuId=543560605494007100"
,
"title"
:
"黄糯玉米"
},
{
"img"
:
"vipAct2.png"
,
"extra"
:
{
"envVersion"
:
"release"
,
"appId"
:
"wx4205ec55b793245e"
},
"type"
:
2
,
"url"
:
"/subPackages/shopMainProcess/lottery/index?utm_campaign=%E6%BA%AF%E6%BA%90%E6%8A%BD%E5%A5%96&_channel_track_key=ngSppZAj"
}
],
"vipLvInfo"
:
[
{
"vipLvIcon"
:
"vipLvIcon0.png"
,
"vipLvBg"
:
"vipLvBg0.png"
,
"currentLvTip"
:
"currentLvTip0.png"
,
"barVip"
:
"barVip0.png"
,
"barBgVip"
:
"barBgVip0.png"
},
{
"vipLvIcon"
:
"vipLvIcon1.png"
,
"vipLvBg"
:
"vipLvBg1.png"
,
"currentLvTip"
:
"currentLvTip1.png"
,
"barVip"
:
"barVip1.png"
,
"barBgVip"
:
"barBgVip1.png"
},
{
"vipLvIcon"
:
"vipLvIcon2.png"
,
"vipLvBg"
:
"vipLvBg2.png"
,
"currentLvTip"
:
"currentLvTip2.png"
,
"barVip"
:
"barVip2.png"
,
"barBgVip"
:
"barBgVip2.png"
},
{
"vipLvIcon"
:
"vipLvIcon3.png"
,
"vipLvBg"
:
"vipLvBg3.png"
,
"currentLvTip"
:
"currentLvTip3.png"
,
"barVip"
:
"barVip3.png"
,
"barBgVip"
:
"barBgVip3.png"
},
{
"vipLvIcon"
:
"vipLvIcon4.png"
,
"vipLvBg"
:
"vipLvBg4.png"
,
"currentLvTip"
:
"currentLvTip4.png"
,
"barVip"
:
"barVip4.png"
,
"barBgVip"
:
"barBgVip4.png"
}
],
"qunyiInfo"
:
{
"vipRule"
:
{
"type"
:
3
,
"url"
:
"https://mom.feihe.com/member/mine/pointStrategy"
},
"quanyiBgs"
:
[
{
"selectImg"
:
"quanyiSelectBg0.png"
,
"lockImg"
:
"quanyiLockBg0.png"
,
"unlockImg"
:
"quanyiunLockBg0.png"
,
"quanyiNum"
:
3
},
{
"selectImg"
:
"quanyiSelectBg1.png"
,
"lockImg"
:
"quanyiLockBg1.png"
,
"unlockImg"
:
"quanyiunLockBg1.png"
,
"quanyiNum"
:
5
},
{
"selectImg"
:
"quanyiSelectBg2.png"
,
"lockImg"
:
"quanyiLockBg2.png"
,
"unlockImg"
:
"quanyiunLockBg2.png"
,
"quanyiNum"
:
8
},
{
"selectImg"
:
"quanyiSelectBg3.png"
,
"lockImg"
:
"quanyiLockBg3.png"
,
"unlockImg"
:
"quanyiunLockBg3.png"
,
"quanyiNum"
:
9
},
{
"selectImg"
:
"quanyiSelectBg4.png"
,
"lockImg"
:
"quanyiLockBg4.png"
,
"unlockImg"
:
"quanyiunLockBg4.png"
,
"quanyiNum"
:
9
}
],
"rule"
:
{
"type"
:
3
,
"url"
:
"https://mom.feihe.com/member/mine/pointStrategy"
},
"imgInfos"
:
[
{
"img"
:
"yueyueliIcon0.png"
,
"name"
:
"月月礼"
,
"width"
:
"99rpx"
,
"height"
:
"99rpx"
},
{
"img"
:
"yuerIcon0.png"
,
"name"
:
"育儿课程"
,
"width"
:
"99rpx"
,
"height"
:
"99rpx"
},
{
"img"
:
"mainfeiIcon0.png"
,
"name"
:
"免费问诊"
,
"width"
:
"99rpx"
,
"height"
:
"99rpx"
},
{
"img"
:
"aibenxinrenliIcon0.png"
,
"name"
:
"爱本新人礼"
,
"width"
:
"99rpx"
,
"height"
:
"99rpx"
},
{
"img"
:
"zhuanduanliIcon0.png"
,
"name"
:
"转段礼"
,
"width"
:
"99rpx"
,
"height"
:
"99rpx"
},
{
"img"
:
"zhousuiliIcon0.png"
,
"name"
:
"周岁礼"
,
"width"
:
"99rpx"
,
"height"
:
"99rpx"
},
{
"img"
:
"shengriliIcon0.png"
,
"name"
:
"生日礼"
,
"width"
:
"99rpx"
,
"height"
:
"99rpx"
},
{
"img"
:
"jinjiliIcon0.png"
,
"name"
:
"晋级礼"
,
"width"
:
"99rpx"
,
"height"
:
"99rpx"
},
{
"img"
:
"suyuanyouIcon0.png"
,
"name"
:
"溯源游"
,
"width"
:
"99rpx"
,
"height"
:
"99rpx"
}
],
"vipQuanyiUrl"
:
{
"extra"
:
{
"envVersion"
:
"release"
,
"appId"
:
"wx4205ec55b793245e"
},
"type"
:
2
,
"url"
:
"subPackages/xmhMainProcess/member/index?entrySource=xmh_wechatmp_points_recgoodsbot"
},
"vipLvsQuanyi"
:
[
{
"isNewArr"
:
[],
"qunyiList"
:
[
0
,
2
,
5
]
},
{
"isNewArr"
:
[
6
,
7
],
"qunyiList"
:
[
6
,
7
,
0
,
2
,
5
]
},
{
"isNewArr"
:
[
8
,
1
],
"qunyiList"
:
[
8
,
1
,
6
,
7
,
0
,
2
,
5
]
},
{
"isNewArr"
:
[
9
],
"qunyiList"
:
[
9
,
8
,
1
,
6
,
7
,
0
,
2
,
5
]
},
{
"isNewArr"
:
[
9
],
"qunyiList"
:
[
9
,
8
,
1
,
6
,
7
,
0
,
2
,
5
]
}
]
}
}
\ No newline at end of file
mock/my.json
View file @
821b80a8
...
...
@@ -323,16 +323,6 @@
"desc"
:
"星妈会Lab"
,
"bgUrl"
:
"my/icon_xingma_lab1.png"
},
{
"link"
:
{
"extra"
:
{},
"type"
:
1
,
"url"
:
"/pages/naming/naming"
},
"title"
:
"星妈起名"
,
"desc"
:
"星妈起名"
,
"bgUrl"
:
"my/naming.png"
},
{
"link"
:
{
"extra"
:
{},
...
...
@@ -446,13 +436,14 @@
],
"activeInfo"
:
[
{
"img"
:
"https://course.feihe.com/momclub-picture/my/vipAct090201
.png"
,
"img"
:
"https://course.feihe.com/momclub-picture/my/vipAct250910002
.png"
,
"extra"
:
{
"envVersion"
:
"release"
,
"appId"
:
"wx4205ec55b793245e"
},
"type"
:
2
,
"url"
:
"/subPackages/shopMainProcess/product/index?productId=739634042657637394&skuId=739635029460743612"
"url"
:
"/subPackages/shopMainProcess/product/index?productId=543558664688883066&skuId=543560605494007100"
,
"title"
:
"黄糯玉米"
},
{
"img"
:
"https://course.feihe.com/momclub-picture/my/activeImg0823.png"
,
...
...
@@ -470,4 +461,4 @@
"母婴店"
]
}
}
\ No newline at end of file
}
\ No newline at end of file
pages/XingmaLabDetailPage/XingmaLabDetailPage.vue
View file @
821b80a8
...
...
@@ -52,7 +52,9 @@
<button
open-type=
"getPhoneNumber"
@
getphonenumber=
"(e) => onGetPhoneNumber(e, 'like')"
class=
"auth-like-btn phone-auth-btn-cover"
></button>
<!-- 分享按钮授权覆盖 - 移除这个,让分享按钮正常工作 -->
<!-- 分享按钮授权覆盖 -->
<button
open-type=
"getPhoneNumber"
@
getphonenumber=
"(e) => onGetPhoneNumber(e, 'share')"
class=
"auth-share-btn phone-auth-btn-cover"
></button>
</div>
</div>
</view>
...
...
@@ -72,7 +74,7 @@ defineOptions({
})
// 响应式数据
const
collectionNumber
=
ref
(
'
123456789
'
)
const
collectionNumber
=
ref
(
''
)
const
recordId
=
ref
(
''
)
// 添加记录ID的响应式变量
const
detailData
=
ref
({
content
:
''
,
...
...
@@ -267,8 +269,8 @@ const handleGoBack = () => {
}
}
//
生命周期
onMounted
(
async
(
options
)
=>
{
//
页面初始化逻辑
const
initPage
=
async
(
)
=>
{
md
.
sensorComponentLogTake
({
xcxComponentExposure
:
"true"
,
...
...
@@ -284,7 +286,6 @@ onMounted(async (options) => {
componentContent
:
"分享"
});
// 调用 home 接口获取登录状态
await
homeStore
.
loadHomeInfo
()
...
...
@@ -297,7 +298,6 @@ onMounted(async (options) => {
recordId
.
value
=
id
// 立即保存ID,确保分享时能获取到
await
fetchDetailData
(
id
)
md
.
sensorComponentLogTake
({
xcxComponentExposure
:
"true"
,
pageName
:
"星妈lab-藏品详情页"
,
...
...
@@ -305,7 +305,7 @@ onMounted(async (options) => {
componentContent
:
"藏品详情页+"
+
detailData
.
value
.
content
});
}
else
{
console
.
warn
(
'⚠️ 未获取到页面参数 id'
,
options
,
currentPage
.
options
)
console
.
warn
(
'⚠️ 未获取到页面参数 id'
,
currentPage
.
options
)
// uni.showToast({
// title: '参数错误',
// icon: 'none'
...
...
@@ -323,6 +323,22 @@ onMounted(async (options) => {
withShareTicket
:
true
,
menus
:
[
'shareAppMessage'
]
})
}
// 生命周期
onMounted
(
async
(
options
)
=>
{
console
.
log
(
'星妈lab详情页面已加载'
)
// 先进行自动登录获取基础信息,登录成功后执行页面初始化
try
{
console
.
log
(
'开始执行 normalAutoLogin...'
)
await
userStore
.
normalAutoLogin
(
initPage
)
console
.
log
(
'normalAutoLogin 完成'
)
}
catch
(
error
)
{
console
.
error
(
'normalAutoLogin 失败:'
,
error
)
// 即使登录失败也执行页面初始化
await
initPage
()
}
})
// 定义分享函数
...
...
pages/feedingIndex/feedingIndex.vue
View file @
821b80a8
...
...
@@ -417,33 +417,68 @@
</view>
</uni-popup>
<popupTip
v-if=
"isTip"
type=
"1"
@
statusChange=
"onPopupTipBabyChange"
@
close=
"isTip = false"
></popupTip>
<popupTip
v-if=
"isTip"
type=
"1"
@
statusChange=
"onPopupTipBabyChange"
@
afterPhone=
"isShowRegisterLayer = true"
:isNotLogin=
"isNotLogin"
@
close=
"isTip = false"
></popupTip>
<RegisterLayer
v-model=
"isShowRegisterLayer"
@
confirm=
"onRegisterConfirm"
/>
</
template
>
<
script
setup
>
import
{
ref
,
computed
,
onMounted
,
onUnmounted
,
getCurrentInstance
}
from
'vue'
import
{
onShow
,
onLoad
,
onHide
}
from
'@dcloudio/uni-app'
import
BabySwitchPopup
from
'@/components/BabySwitchPopup.vue'
import
popupTip
from
'../../components/popup-tip/popup-tip.vue'
import
{
fetchFeedingJSON
,
feedingHome
,
feedingRecords
,
feedingFoodsCustom
,
feedingFoodsCustomAdd
,
feedingFoodsCustomDelete
,
feedingTimerStart
,
feedingTimerStop
,
feedingVoiceUpload
,
feedingVoiceResult
}
from
'@/api/feeding.js'
import
{
useUserStore
}
from
'@/stores/user.js'
import
{
jump
,
JumpType
,
showLoading
}
from
'../../utils'
import
{
getHealthField
}
from
"@/api/common"
;
import
md
from
'../../md'
// 弹窗引用
const
addFoodPopup
=
ref
(
null
)
const
successPopup
=
ref
(
null
)
const
{
proxy
}
=
getCurrentInstance
();
const
$baseUrl
=
proxy
.
$baseUrl
;
const
version
=
'v1'
// 计时器上限时间(秒)
const
TIMER_MAX_DURATION
=
3600
const
feedingIndexRes
=
{
import
{
ref
,
computed
,
onMounted
,
onUnmounted
,
getCurrentInstance
}
from
'vue'
import
{
onShow
,
onLoad
,
onHide
,
onShareAppMessage
,
onShareTimeline
}
from
'@dcloudio/uni-app'
import
BabySwitchPopup
from
'@/components/BabySwitchPopup.vue'
import
RegisterLayer
from
'@/components/RegisterLayer.vue'
import
popupTip
from
'../../components/popup-tip/popup-tip.vue'
import
{
fetchFeedingJSON
,
feedingHome
,
feedingRecords
,
feedingFoodsCustom
,
feedingFoodsCustomAdd
,
feedingFoodsCustomDelete
,
feedingTimerStart
,
feedingTimerStop
,
feedingVoiceUpload
,
feedingVoiceResult
}
from
'@/api/feeding.js'
import
{
useUserStore
}
from
'@/stores/user.js'
import
{
jump
,
JumpType
,
showLoading
}
from
'../../utils'
import
{
getHealthField
}
from
"@/api/common"
;
import
md
from
'../../md'
// 弹窗引用
const
addFoodPopup
=
ref
(
null
)
const
successPopup
=
ref
(
null
)
const
{
proxy
}
=
getCurrentInstance
();
const
$baseUrl
=
proxy
.
$baseUrl
;
const
version
=
'v1'
// 计时器上限时间(秒)
const
TIMER_MAX_DURATION
=
3600
const
feedingIndexRes
=
{
// 轮播图
banner
:
$baseUrl
+
`feedingIndex/
${
version
}
/banner.png`
,
...
...
@@ -512,26 +547,26 @@ const feedingIndexRes = {
// 识别成功弹窗
icon_btn_confirm
:
$baseUrl
+
`feedingIndex/
${
version
}
/icon_btn_confirm.png`
,
icon_btn_cancel
:
$baseUrl
+
`feedingIndex/
${
version
}
/icon_btn_cancel.png`
,
}
}
const
swiperData
=
ref
([
const
swiperData
=
ref
([
]);
const
indicatorStyle
=
`height: 40px; border: none;`
]);
const
indicatorStyle
=
`height: 40px; border: none;`
// 当前时间,使用 home 接口的 timestamp
const
currentTime
=
ref
(
null
)
// 当前时间,使用 home 接口的 timestamp
const
currentTime
=
ref
(
null
)
// 日期范围限制
const
earliestDateString
=
ref
(
'2020-01-01'
)
const
latestDateString
=
ref
(
'2030-12-31'
)
// 日期范围限制
const
earliestDateString
=
ref
(
'2020-01-01'
)
const
latestDateString
=
ref
(
'2030-12-31'
)
// 时间选择器引用
const
timePickerRef
=
ref
(
null
)
const
voiceTimePickerRef
=
ref
(
null
)
// 时间选择器引用
const
timePickerRef
=
ref
(
null
)
const
voiceTimePickerRef
=
ref
(
null
)
// 接口返回的数据
const
homeData
=
ref
({
// 接口返回的数据
const
homeData
=
ref
({
timestamp
:
null
,
lastRecordType
:
0
,
lastBreastMilkVolume
:
0
,
...
...
@@ -540,12 +575,12 @@ const homeData = ref({
leftTimerDuration
:
0
,
rightTimerRunning
:
false
,
rightTimerDuration
:
0
})
})
// 记录相关数据
const
currentRecordId
=
ref
(
null
)
// 当前记录ID,用于区分新增和修改
const
isSubmitting
=
ref
(
false
)
// 提交状态
const
bannerHandler
=
(
item
)
=>
{
// 记录相关数据
const
currentRecordId
=
ref
(
null
)
// 当前记录ID,用于区分新增和修改
const
isSubmitting
=
ref
(
false
)
// 提交状态
const
bannerHandler
=
(
item
)
=>
{
// 检查是否正在录音
if
(
recordingState
.
value
.
isRecording
||
voiceRecognitionState
.
value
.
isRecording
)
{
uni
.
showToast
({
...
...
@@ -562,41 +597,60 @@ const bannerHandler = (item) => {
});
console
.
log
(
item
);
jump
({
type
:
item
.
jumpType
,
url
:
item
.
url
,
extra
:
item
.
extra
})
}
jump
({
type
:
item
.
jumpType
,
url
:
item
.
url
,
extra
:
item
.
extra
})
}
const
showTimePicker
=
()
=>
{
const
showTimePicker
=
()
=>
{
md
.
sensorLogTake
({
xcxClick
:
"小程序页面点击事件"
,
pageName
:
"喂养工具首页"
,
buttonName
:
"选择喂养时间"
,
});
}
}
const
feedingTypes
=
ref
([
{
value
:
'breastfeeding'
,
label
:
'母乳亲喂'
,
icon
:
feedingIndexRes
.
icon_muruqinwei
},
{
value
:
'bottle'
,
label
:
'母乳瓶喂'
,
icon
:
feedingIndexRes
.
icon_murupinwei
},
{
value
:
'formula'
,
label
:
'奶粉喂养'
,
icon
:
feedingIndexRes
.
icon_naifen
},
{
value
:
'food'
,
label
:
'辅食'
,
icon
:
feedingIndexRes
.
icon_fushi
}
])
const
feedingTypes
=
ref
([{
value
:
'breastfeeding'
,
label
:
'母乳亲喂'
,
icon
:
feedingIndexRes
.
icon_muruqinwei
},
{
value
:
'bottle'
,
label
:
'母乳瓶喂'
,
icon
:
feedingIndexRes
.
icon_murupinwei
},
{
value
:
'formula'
,
label
:
'奶粉喂养'
,
icon
:
feedingIndexRes
.
icon_naifen
},
{
value
:
'food'
,
label
:
'辅食'
,
icon
:
feedingIndexRes
.
icon_fushi
}
])
// 根据接口数据初始化选中的喂养类型
const
selectedType
=
ref
(
'breastfeeding'
)
// 根据接口数据初始化选中的喂养类型
const
selectedType
=
ref
(
'breastfeeding'
)
// 为每种喂养方式设置独立的记录方法
const
recordMethods
=
ref
({
// 为每种喂养方式设置独立的记录方法
const
recordMethods
=
ref
({
breastfeeding
:
'manual'
,
bottle
:
'manual'
,
formula
:
'manual'
,
food
:
'manual'
})
const
isRecording
=
ref
(
false
)
const
isLeftTimerRunning
=
ref
(
false
)
const
isRightTimerRunning
=
ref
(
false
)
})
const
isRecording
=
ref
(
false
)
const
isLeftTimerRunning
=
ref
(
false
)
const
isRightTimerRunning
=
ref
(
false
)
// 辅食数据结构 - 使用接口数据
const
foodCategories
=
ref
({
// 辅食数据结构 - 使用接口数据
const
foodCategories
=
ref
({
主食
:
{
items
:
[],
customItems
:
[],
...
...
@@ -617,21 +671,21 @@ const foodCategories = ref({
customItems
:
[],
expanded
:
false
}
})
})
// 辅食ID映射,用于删除操作
const
foodIdMap
=
ref
(
new
Map
())
// 辅食ID映射,用于删除操作
const
foodIdMap
=
ref
(
new
Map
())
// 辅食类型映射
const
foodTypeMap
=
{
// 辅食类型映射
const
foodTypeMap
=
{
1
:
'主食'
,
2
:
'蔬菜'
,
3
:
'水果'
,
4
:
'其他'
}
}
// 辅食选择状态
const
foodSelectionState
=
ref
({
// 辅食选择状态
const
foodSelectionState
=
ref
({
isEditMode
:
false
,
// 是否处于编辑模式
showAddPopup
:
false
,
// 是否显示添加弹窗
currentCategory
:
''
,
// 当前添加的分类
...
...
@@ -640,12 +694,12 @@ const foodSelectionState = ref({
originalFoodData
:
null
,
// 保存原始辅食数据,用于恢复
isAddingFood
:
false
,
// 添加辅食防连点状态
isDeletingFood
:
false
// 删除辅食防连点状态
})
})
// 记录成功弹窗状态 - 已移除,改用 .open() 和 .close() 方法
// 记录成功弹窗状态 - 已移除,改用 .open() 和 .close() 方法
// 语音识别状态
const
voiceRecognitionState
=
ref
({
// 语音识别状态
const
voiceRecognitionState
=
ref
({
isRecording
:
false
,
// 是否正在录音
showResultPage
:
false
,
// 是否显示识别结果页面
recognizedText
:
''
,
// 识别结果文本
...
...
@@ -660,22 +714,23 @@ const voiceRecognitionState = ref({
recordDate
:
''
,
// 记录日期
recordTime
:
''
,
// 记录时间
voiceDateTime
:
''
// 完整的日期时间字符串
})
// 录音管理器
const
recorderManager
=
uni
.
getRecorderManager
()
})
// 全局状态管理
const
userStore
=
useUserStore
()
const
babyId
=
computed
(()
=>
userStore
.
babyInfo
?.
content
?.
id
)
// 录音管理器
const
recorderManager
=
uni
.
getRecorderManager
()
// 宝宝切换相关状态
const
showBabySwitchPopup
=
ref
(
false
)
// 全局状态管理
const
userStore
=
useUserStore
()
const
babyId
=
computed
(()
=>
userStore
.
babyInfo
?.
content
?.
id
)
const
isTip
=
ref
(
true
)
// 宝宝切换相关状态
const
showBabySwitchPopup
=
ref
(
false
)
// 为每种喂养方式设置独立的数据 - 根据接口数据初始化
const
feedingData
=
ref
({
const
isTip
=
ref
(
true
)
const
isNotLogin
=
ref
(
false
)
const
isShowRegisterLayer
=
ref
(
false
)
// 为每种喂养方式设置独立的数据 - 根据接口数据初始化
const
feedingData
=
ref
({
breastfeeding
:
{
leftDuration
:
5
,
rightDuration
:
5
...
...
@@ -689,37 +744,42 @@ const feedingData = ref({
food
:
{
selectedItems
:
[]
}
})
})
// 刻度标记数组 (0-500ml,每5ml一个刻度)
const
scaleMarks
=
ref
([
0
,
50
,
100
,
150
,
200
,
250
,
300
,
350
,
400
,
450
,
500
])
// 刻度标记数组 (0-500ml,每5ml一个刻度)
const
scaleMarks
=
ref
([
0
,
50
,
100
,
150
,
200
,
250
,
300
,
350
,
400
,
450
,
500
])
// picker-view相关数据
const
pickerAmounts
=
ref
([
0
,
5
,
10
,
15
,
20
,
25
,
30
,
35
,
40
,
45
,
50
,
55
,
60
,
65
,
70
,
75
,
80
,
85
,
90
,
95
,
100
,
105
,
110
,
115
,
120
,
125
,
130
,
135
,
140
,
145
,
150
,
155
,
160
,
165
,
170
,
175
,
180
,
185
,
190
,
195
,
200
,
205
,
210
,
215
,
220
,
225
,
230
,
235
,
240
,
245
,
250
,
255
,
260
,
265
,
270
,
275
,
280
,
285
,
290
,
295
,
300
,
305
,
310
,
315
,
320
,
325
,
330
,
335
,
340
,
345
,
350
,
355
,
360
,
365
,
370
,
375
,
380
,
385
,
390
,
395
,
400
,
405
,
410
,
415
,
420
,
425
,
430
,
435
,
440
,
445
,
450
,
455
,
460
,
465
,
470
,
475
,
480
,
485
,
490
,
495
,
500
])
// picker-view相关数据
const
pickerAmounts
=
ref
([
0
,
5
,
10
,
15
,
20
,
25
,
30
,
35
,
40
,
45
,
50
,
55
,
60
,
65
,
70
,
75
,
80
,
85
,
90
,
95
,
100
,
105
,
110
,
115
,
120
,
125
,
130
,
135
,
140
,
145
,
150
,
155
,
160
,
165
,
170
,
175
,
180
,
185
,
190
,
195
,
200
,
205
,
210
,
215
,
220
,
225
,
230
,
235
,
240
,
245
,
250
,
255
,
260
,
265
,
270
,
275
,
280
,
285
,
290
,
295
,
300
,
305
,
310
,
315
,
320
,
325
,
330
,
335
,
340
,
345
,
350
,
355
,
360
,
365
,
370
,
375
,
380
,
385
,
390
,
395
,
400
,
405
,
410
,
415
,
420
,
425
,
430
,
435
,
440
,
445
,
450
,
455
,
460
,
465
,
470
,
475
,
480
,
485
,
490
,
495
,
500
])
// 滑动相关状态
const
isDragging
=
ref
(
false
)
const
startY
=
ref
(
0
)
const
startAmount
=
ref
(
0
)
// 滑动相关状态
const
isDragging
=
ref
(
false
)
const
startY
=
ref
(
0
)
const
startAmount
=
ref
(
0
)
// 计时器数据 - 根据接口数据初始化
const
timerData
=
ref
({
// 计时器数据 - 根据接口数据初始化
const
timerData
=
ref
({
leftDuration
:
0
,
rightDuration
:
0
})
})
// 计时器间隔ID
let
leftTimerInterval
=
null
let
rightTimerInterval
=
null
// 计时器间隔ID
let
leftTimerInterval
=
null
let
rightTimerInterval
=
null
// 计算属性 - 判断是否显示表单
const
shouldShowForm
=
computed
(()
=>
{
// 计算属性 - 判断是否显示表单
const
shouldShowForm
=
computed
(()
=>
{
const
currentMethod
=
recordMethods
.
value
[
selectedType
.
value
]
return
currentMethod
===
'manual'
// 只有手动模式显示表单
})
})
// 计算属性 - 同步picker-view的值
const
pickerValue
=
computed
({
// 计算属性 - 同步picker-view的值
const
pickerValue
=
computed
({
get
()
{
const
currentAmount
=
feedingData
.
value
[
selectedType
.
value
].
amount
const
index
=
pickerAmounts
.
value
.
indexOf
(
currentAmount
)
...
...
@@ -728,28 +788,28 @@ const pickerValue = computed({
set
(
value
)
{
// 这个setter不会被直接调用,但需要保持响应式
}
})
})
// 计算属性 - 判断是否为语音模式(辅食除外)
const
isVoiceMode
=
computed
(()
=>
{
// 计算属性 - 判断是否为语音模式(辅食除外)
const
isVoiceMode
=
computed
(()
=>
{
return
recordMethods
.
value
[
selectedType
.
value
]
===
'voice'
&&
selectedType
.
value
!==
'food'
})
})
// 计算属性 - 获取宝宝信息(只显示已出生的宝宝)
const
babyList
=
computed
(()
=>
{
// 计算属性 - 获取宝宝信息(只显示已出生的宝宝)
const
babyList
=
computed
(()
=>
{
const
allBabies
=
userStore
.
babyInfo
?.
allBabyBaseInfo
||
[]
// 只返回已出生的宝宝(babyStage === 2)
return
allBabies
.
filter
(
baby
=>
baby
.
babyStage
===
2
)
})
const
currentBabyIndex
=
computed
(()
=>
{
})
const
currentBabyIndex
=
computed
(()
=>
{
if
(
!
babyList
.
value
||
!
currentBaby
.
value
)
return
0
return
babyList
.
value
.
findIndex
(
baby
=>
baby
.
id
===
currentBaby
.
value
.
id
)
})
const
currentBaby
=
computed
(()
=>
userStore
.
babyInfo
?.
content
)
const
currentBabyId
=
computed
(()
=>
userStore
.
babyInfo
?.
content
?.
id
)
})
const
currentBaby
=
computed
(()
=>
userStore
.
babyInfo
?.
content
)
const
currentBabyId
=
computed
(()
=>
userStore
.
babyInfo
?.
content
?.
id
)
// 页面加载时获取数据
onMounted
(
async
()
=>
{
// 页面加载时获取数据
onMounted
(
async
()
=>
{
md
.
sensorLogTake
({
xcxPage
:
"小程序页面浏览事件"
,
pageName
:
"喂养工具首页"
,
...
...
@@ -760,18 +820,26 @@ onMounted(async () => {
// 初始化录音管理器
initializeRecorderManager
()
})
})
const
onRegisterConfirm
=
async
()
=>
{
isShowRegisterLayer
.
value
=
false
;
await
loadBabyInfo
()
loadFoodsData
()
const
onPopupTipBabyChange
=
async
()
=>
{
// 初始化录音管理器
initializeRecorderManager
()
}
const
onPopupTipBabyChange
=
async
()
=>
{
isTip
.
value
=
false
console
.
log
(
'onPopupTipBabyChange'
,
isTip
.
value
)
// showBabySwitchPopup.value = true
await
loadBabyInfo
()
loadHomeData
()
}
}
// 页面显示时刷新数据
onShow
(
async
()
=>
{
// 页面显示时刷新数据
onShow
(
async
()
=>
{
console
.
log
(
'页面显示,刷新数据...'
)
if
(
!
babyId
.
value
)
{
...
...
@@ -807,10 +875,10 @@ onShow(async () => {
restoreUnfinishedEdit
()
},
500
)
}
})
})
// 页面隐藏时同步计时器状态
onHide
(()
=>
{
// 页面隐藏时同步计时器状态
onHide
(()
=>
{
console
.
log
(
'页面隐藏,处理录音状态...'
)
// 如果正在录音,停止录音并重置状态
...
...
@@ -829,10 +897,10 @@ onHide(() => {
console
.
log
(
'页面隐藏时同步右侧计时器状态'
)
// 这里可以选择是否调用后端接口同步状态
}
})
})
// 页面卸载时清理计时器
onUnmounted
(()
=>
{
// 页面卸载时清理计时器
onUnmounted
(()
=>
{
console
.
log
(
'页面卸载,清理资源...'
)
// 清理左侧计时器
...
...
@@ -866,10 +934,10 @@ onUnmounted(() => {
}
catch
(
error
)
{
console
.
warn
(
'页面卸载时清理录音管理器回调出错:'
,
error
)
}
})
})
// 页面参数接收
onLoad
(
async
(
options
)
=>
{
// 页面参数接收
onLoad
(
async
(
options
)
=>
{
console
.
log
(
'页面参数:'
,
options
)
// 如果是修改记录,接收记录ID
...
...
@@ -894,18 +962,18 @@ onLoad(async (options) => {
}
selectedType
.
value
=
typeMap
[
options
.
feedingType
]
||
'breastfeeding'
}
})
})
function
getCurrentTime
()
{
function
getCurrentTime
()
{
const
now
=
new
Date
()
const
hours
=
String
(
now
.
getHours
()).
padStart
(
2
,
'0'
)
const
minutes
=
String
(
now
.
getMinutes
()).
padStart
(
2
,
'0'
)
return
`
${
hours
}
:
${
minutes
}
`
}
}
// 根据记录数据设置表单
function
setFormDataFromRecord
(
recordData
)
{
// 根据记录数据设置表单
function
setFormDataFromRecord
(
recordData
)
{
// 设置喂养类型
const
typeMap
=
{
1
:
'breastfeeding'
,
...
...
@@ -937,11 +1005,19 @@ function setFormDataFromRecord(recordData) {
}
// 不清除记录方法,保持用户的选择
}
}
// 获取宝宝信息
async
function
loadBabyInfo
()
{
// 获取宝宝信息
async
function
loadBabyInfo
()
{
try
{
isNotLogin
.
value
=
false
;
await
userStore
.
loadUserInfo
()
if
(
userStore
?.
userInfo
?.
memberId
&&
userStore
?.
userInfo
?.
memberId
==
"not_login"
||
!
userStore
.
userInfo
)
{
isNotLogin
.
value
=
true
;
}
console
.
log
(
'开始加载宝宝信息...'
)
if
(
userStore
.
babyInfo
?.
babyStage
!=
2
)
{
isTip
.
value
=
true
...
...
@@ -977,10 +1053,10 @@ async function loadBabyInfo() {
icon
:
'none'
})
}
}
}
// 获取首页数据
async
function
loadHomeData
()
{
// 获取首页数据
async
function
loadHomeData
()
{
if
(
!
babyId
.
value
)
{
isTip
.
value
=
true
return
...
...
@@ -1035,7 +1111,8 @@ async function loadHomeData() {
const
feedingResponse
=
await
fetchFeedingJSON
()
console
.
log
(
'轮播图数据:'
,
feedingResponse
)
if
(
feedingResponse
&&
feedingResponse
.
data
&&
feedingResponse
.
data
.
swiperData
&&
feedingResponse
.
data
.
swiperData
.
length
>
0
)
{
if
(
feedingResponse
&&
feedingResponse
.
data
&&
feedingResponse
.
data
.
swiperData
&&
feedingResponse
.
data
.
swiperData
.
length
>
0
)
{
swiperData
.
value
=
feedingResponse
.
data
.
swiperData
}
}
catch
(
error
)
{
...
...
@@ -1043,10 +1120,10 @@ async function loadHomeData() {
// 使用默认的轮播图数据作为fallback
swiperData
.
value
=
[]
}
}
}
// 根据接口数据初始化页面状态
function
initializePageData
()
{
// 根据接口数据初始化页面状态
function
initializePageData
()
{
const
data
=
homeData
.
value
// 设置当前时间,优先使用 home 接口的 timestamp
...
...
@@ -1112,10 +1189,10 @@ function initializePageData() {
// 重置计时器状态,确保状态和实际运行状态保持一致
resetTimerStatus
()
}
}
// 重置计时器状态
function
resetTimerStatus
()
{
// 重置计时器状态
function
resetTimerStatus
()
{
// 如果状态显示计时器在运行,但实际没有定时器在运行,则重置状态
if
(
isLeftTimerRunning
.
value
&&
!
leftTimerInterval
)
{
console
.
log
(
'重置左侧计时器状态:状态为运行但实际已停止'
)
...
...
@@ -1125,10 +1202,10 @@ function resetTimerStatus() {
console
.
log
(
'重置右侧计时器状态:状态为运行但实际已停止'
)
isRightTimerRunning
.
value
=
false
}
}
}
// 方法
function
selectType
(
type
)
{
// 方法
function
selectType
(
type
)
{
// 检查是否正在录音
if
(
recordingState
.
value
.
isRecording
||
voiceRecognitionState
.
value
.
isRecording
)
{
uni
.
showToast
({
...
...
@@ -1198,12 +1275,12 @@ function selectType(type) {
});
}
selectedType
.
value
=
type
}
}
// 清空之前的状态
function
clearPreviousState
()
{
// 清空之前的状态
function
clearPreviousState
()
{
// 清理轮询定时器
clearPollingInterval
()
...
...
@@ -1246,10 +1323,10 @@ function clearPreviousState() {
isDragging
.
value
=
false
startY
.
value
=
0
startAmount
.
value
=
0
}
}
// 清空喂养数据(保存成功后调用)
function
clearFeedingData
()
{
// 清空喂养数据(保存成功后调用)
function
clearFeedingData
()
{
// 清空所有喂养方式的数据
feedingData
.
value
.
breastfeeding
.
leftDuration
=
5
feedingData
.
value
.
breastfeeding
.
rightDuration
=
5
...
...
@@ -1316,9 +1393,9 @@ function clearFeedingData() {
}
console
.
log
(
'喂养数据已清空'
)
}
}
function
adjustDuration
(
side
,
value
)
{
function
adjustDuration
(
side
,
value
)
{
const
currentData
=
feedingData
.
value
.
breastfeeding
if
(
side
===
'left'
)
{
...
...
@@ -1365,26 +1442,26 @@ function adjustDuration(side, value) {
currentData
.
rightDuration
=
newValue
}
}
}
}
function
adjustAmount
(
value
)
{
function
adjustAmount
(
value
)
{
const
currentType
=
selectedType
.
value
if
(
currentType
===
'bottle'
||
currentType
===
'formula'
)
{
const
currentData
=
feedingData
.
value
[
currentType
]
currentData
.
amount
=
Math
.
max
(
0
,
Math
.
min
(
500
,
currentData
.
amount
+
value
))
}
}
}
// 滑动选择相关方法
function
onTouchStart
(
e
)
{
// 滑动选择相关方法
function
onTouchStart
(
e
)
{
isDragging
.
value
=
true
startY
.
value
=
e
.
touches
[
0
].
clientY
startAmount
.
value
=
feedingData
.
value
[
selectedType
.
value
].
amount
}
}
function
onTouchMove
(
e
)
{
function
onTouchMove
(
e
)
{
if
(
!
isDragging
.
value
)
return
const
currentY
=
e
.
touches
[
0
].
clientY
...
...
@@ -1398,26 +1475,26 @@ function onTouchMove(e) {
const
adjustedAmount
=
Math
.
round
(
newAmount
/
5
)
*
5
feedingData
.
value
[
selectedType
.
value
].
amount
=
adjustedAmount
}
}
function
onTouchEnd
()
{
function
onTouchEnd
()
{
isDragging
.
value
=
false
}
}
function
getSliderPosition
()
{
function
getSliderPosition
()
{
const
currentAmount
=
feedingData
.
value
[
selectedType
.
value
].
amount
// 将0-500ml映射到0-100%的位置
return
100
-
(
currentAmount
/
500
)
*
100
}
}
// picker-view选择事件
function
onPickerChange
(
e
)
{
// picker-view选择事件
function
onPickerChange
(
e
)
{
const
index
=
e
.
detail
.
value
[
0
]
const
selectedAmount
=
pickerAmounts
.
value
[
index
]
feedingData
.
value
[
selectedType
.
value
].
amount
=
selectedAmount
}
}
function
setRecordMethod
(
method
)
{
function
setRecordMethod
(
method
)
{
// 手动记录、计时器记录、语音记录
...
...
@@ -1489,7 +1566,8 @@ function setRecordMethod(method) {
}
// 母乳亲喂计时器运行时阻止切换记录方式
if
(
selectedType
.
value
===
'breastfeeding'
&&
((
isLeftTimerRunning
.
value
&&
leftTimerInterval
)
||
(
isRightTimerRunning
.
value
&&
rightTimerInterval
)))
{
if
(
selectedType
.
value
===
'breastfeeding'
&&
((
isLeftTimerRunning
.
value
&&
leftTimerInterval
)
||
(
isRightTimerRunning
.
value
&&
rightTimerInterval
)))
{
uni
.
showToast
({
title
:
'计时器正在运行,请先停止计时'
,
icon
:
'none'
...
...
@@ -1522,15 +1600,15 @@ function setRecordMethod(method) {
if
(
method
===
'voice'
)
{
checkVoicePermission
()
}
}
}
function
toggleRecording
()
{
function
toggleRecording
()
{
isRecording
.
value
=
!
isRecording
.
value
}
}
async
function
toggleTimer
(
side
)
{
async
function
toggleTimer
(
side
)
{
const
currentBabyId
=
babyId
.
value
if
(
side
===
'left'
)
{
...
...
@@ -1646,9 +1724,9 @@ async function toggleTimer(side) {
}
}
}
}
}
function
startLeftTimer
()
{
function
startLeftTimer
()
{
// 开始左侧计时
console
.
log
(
'开始左侧计时'
)
// 如果已经有计时器在运行,先停止
...
...
@@ -1667,18 +1745,18 @@ function startLeftTimer() {
autoStopLeftTimer
()
}
},
1000
)
// 每秒增加1秒
}
}
function
stopLeftTimer
()
{
function
stopLeftTimer
()
{
// 停止左侧计时
console
.
log
(
'停止左侧计时'
)
if
(
leftTimerInterval
)
{
clearInterval
(
leftTimerInterval
)
leftTimerInterval
=
null
}
}
}
function
startRightTimer
()
{
function
startRightTimer
()
{
// 开始右侧计时
console
.
log
(
'开始右侧计时'
)
// 如果已经有计时器在运行,先停止
...
...
@@ -1697,19 +1775,19 @@ function startRightTimer() {
autoStopRightTimer
()
}
},
1000
)
// 每秒增加1秒
}
}
function
stopRightTimer
()
{
function
stopRightTimer
()
{
// 停止右侧计时
console
.
log
(
'停止右侧计时'
)
if
(
rightTimerInterval
)
{
clearInterval
(
rightTimerInterval
)
rightTimerInterval
=
null
}
}
}
// 自动停止左侧计时器(调用后端接口)
async
function
autoStopLeftTimer
()
{
// 自动停止左侧计时器(调用后端接口)
async
function
autoStopLeftTimer
()
{
const
currentBabyId
=
babyId
.
value
if
(
!
currentBabyId
)
{
console
.
warn
(
'没有选择宝宝,无法停止计时器'
)
...
...
@@ -1727,10 +1805,10 @@ async function autoStopLeftTimer() {
console
.
error
(
'自动停止左侧计时器失败:'
,
error
)
// 不显示错误提示,因为这是自动停止
}
}
}
// 自动停止右侧计时器(调用后端接口)
async
function
autoStopRightTimer
()
{
// 自动停止右侧计时器(调用后端接口)
async
function
autoStopRightTimer
()
{
const
currentBabyId
=
babyId
.
value
if
(
!
currentBabyId
)
{
console
.
warn
(
'没有选择宝宝,无法停止计时器'
)
...
...
@@ -1748,10 +1826,10 @@ async function autoStopRightTimer() {
console
.
error
(
'自动停止右侧计时器失败:'
,
error
)
// 不显示错误提示,因为这是自动停止
}
}
}
// 停止所有计时器
async
function
stopAllTimers
()
{
// 停止所有计时器
async
function
stopAllTimers
()
{
const
currentBabyId
=
babyId
.
value
if
(
!
currentBabyId
)
{
console
.
warn
(
'没有选择宝宝,无法停止计时器'
)
...
...
@@ -1787,10 +1865,10 @@ async function stopAllTimers() {
// 不显示错误提示,因为这是正常的保存流程
// 即使计时器停止失败,也要继续保存记录
}
}
}
// 完成记录
async
function
completeRecord
()
{
// 完成记录
async
function
completeRecord
()
{
// 防止重复提交
...
...
@@ -1907,20 +1985,26 @@ async function completeRecord() {
isSubmitting
.
value
=
false
},
2000
)
}
}
}
// 验证记录数据
function
validateRecordData
()
{
// 验证记录数据
function
validateRecordData
()
{
const
currentBaby
=
userStore
.
babyInfo
?.
content
// 验证宝宝信息
if
(
!
currentBaby
||
!
currentBaby
.
id
)
{
return
{
valid
:
false
,
message
:
'请选择宝宝'
}
return
{
valid
:
false
,
message
:
'请选择宝宝'
}
}
// 验证喂养时间
if
(
!
currentTime
.
value
)
{
return
{
valid
:
false
,
message
:
'请选择喂养时间'
}
return
{
valid
:
false
,
message
:
'请选择喂养时间'
}
}
// 根据喂养类型和记录方式验证具体数据
...
...
@@ -1933,19 +2017,28 @@ function validateRecordData() {
const
leftDuration
=
feedingData
.
value
.
breastfeeding
.
leftDuration
const
rightDuration
=
feedingData
.
value
.
breastfeeding
.
rightDuration
if
(
leftDuration
===
0
&&
rightDuration
===
0
)
{
return
{
valid
:
false
,
message
:
'还没有输入喂养信息哦~'
}
return
{
valid
:
false
,
message
:
'还没有输入喂养信息哦~'
}
}
}
else
if
(
currentMethod
===
'timer'
)
{
// 计时器模式:验证计时器状态
const
leftDuration
=
timerData
.
value
.
leftDuration
const
rightDuration
=
timerData
.
value
.
rightDuration
if
(
leftDuration
===
0
&&
rightDuration
===
0
)
{
return
{
valid
:
false
,
message
:
'还没有输入喂养信息哦~'
}
return
{
valid
:
false
,
message
:
'还没有输入喂养信息哦~'
}
}
}
else
if
(
currentMethod
===
'voice'
)
{
// 语音模式:验证语音识别结果
if
(
!
voiceRecognitionState
.
value
.
recognizedText
.
trim
())
{
return
{
valid
:
false
,
message
:
'还没有输入喂养信息哦~'
}
return
{
valid
:
false
,
message
:
'还没有输入喂养信息哦~'
}
}
}
break
...
...
@@ -1958,12 +2051,18 @@ function validateRecordData() {
// 手动模式:验证喂养量
const
amount
=
feedingData
.
value
[
selectedType
.
value
].
amount
if
(
amount
===
0
)
{
return
{
valid
:
false
,
message
:
'还没有输入喂养信息哦~'
}
return
{
valid
:
false
,
message
:
'还没有输入喂养信息哦~'
}
}
}
else
if
(
currentMethod2
===
'voice'
)
{
// 语音模式:验证语音识别结果
if
(
!
voiceRecognitionState
.
value
.
recognizedText
.
trim
())
{
return
{
valid
:
false
,
message
:
'还没有输入喂养信息哦~'
}
return
{
valid
:
false
,
message
:
'还没有输入喂养信息哦~'
}
}
}
break
...
...
@@ -1972,16 +2071,21 @@ function validateRecordData() {
// 辅食只有手动选择模式
const
selectedItems
=
feedingData
.
value
.
food
.
selectedItems
if
(
selectedItems
.
length
===
0
)
{
return
{
valid
:
false
,
message
:
'还没有输入喂养信息哦~'
}
return
{
valid
:
false
,
message
:
'还没有输入喂养信息哦~'
}
}
break
}
return
{
valid
:
true
}
}
return
{
valid
:
true
}
}
// 构建记录数据
function
buildRecordData
()
{
// 构建记录数据
function
buildRecordData
()
{
const
currentBaby
=
userStore
.
babyInfo
?.
content
// 判断是否为语音模式,如果是则使用弹窗中的日期和时间
...
...
@@ -2020,7 +2124,8 @@ function buildRecordData() {
feedingType
:
1
,
// 母乳亲喂
durationLeftSeconds
:
feedingData
.
value
.
breastfeeding
.
leftDuration
*
60
,
// 转换为秒
durationRightSeconds
:
feedingData
.
value
.
breastfeeding
.
rightDuration
*
60
,
totalDurationSeconds
:
(
feedingData
.
value
.
breastfeeding
.
leftDuration
+
feedingData
.
value
.
breastfeeding
.
rightDuration
)
*
60
totalDurationSeconds
:
(
feedingData
.
value
.
breastfeeding
.
leftDuration
+
feedingData
.
value
.
breastfeeding
.
rightDuration
)
*
60
}
}
else
if
(
currentMethod
===
'timer'
)
{
// 计时器模式:使用计时器的实际时长
...
...
@@ -2091,13 +2196,13 @@ function buildRecordData() {
}
return
baseData
}
}
function
goBack
()
{
function
goBack
()
{
uni
.
navigateBack
()
}
}
function
goToFeedingRecord
()
{
function
goToFeedingRecord
()
{
// 检查是否正在录音
if
(
recordingState
.
value
.
isRecording
||
voiceRecognitionState
.
value
.
isRecording
)
{
uni
.
showToast
({
...
...
@@ -2116,15 +2221,15 @@ function goToFeedingRecord() {
uni
.
navigateTo
({
url
:
'/pages/feedingRecord/feedingRecord'
})
}
}
// 时间选择器相关方法
function
onTimeChange
(
value
)
{
// 时间选择器相关方法
function
onTimeChange
(
value
)
{
currentTime
.
value
=
value
}
}
// 语音识别时间选择器显示
function
showVoiceTimePicker
()
{
// 语音识别时间选择器显示
function
showVoiceTimePicker
()
{
// 使用与 formatCurrentTime() 一致的默认时间
if
(
!
voiceRecognitionState
.
value
.
voiceDateTime
)
{
const
defaultTimeString
=
formatCurrentTime
()
...
...
@@ -2136,10 +2241,10 @@ function showVoiceTimePicker() {
}
}
voiceTimePickerRef
.
value
.
show
()
}
}
// 语音识别时间选择
function
onVoiceTimeChange
(
value
)
{
// 语音识别时间选择
function
onVoiceTimeChange
(
value
)
{
// 设置完整的日期时间字符串
voiceRecognitionState
.
value
.
voiceDateTime
=
value
...
...
@@ -2154,10 +2259,10 @@ function onVoiceTimeChange(value) {
// 设置分离的日期和时间
voiceRecognitionState
.
value
.
recordDate
=
`
${
year
}
-
${
month
}
-
${
day
}
`
voiceRecognitionState
.
value
.
recordTime
=
`
${
hours
}
:
${
minutes
}
`
}
}
// 格式化语音识别时间显示
function
formatVoiceDateTime
()
{
// 格式化语音识别时间显示
function
formatVoiceDateTime
()
{
if
(
voiceRecognitionState
.
value
.
voiceDateTime
)
{
const
date
=
new
Date
(
voiceRecognitionState
.
value
.
voiceDateTime
)
const
year
=
date
.
getFullYear
()
...
...
@@ -2169,10 +2274,10 @@ function formatVoiceDateTime() {
return
`
${
year
}
-
${
month
}
-
${
day
}
${
hours
}
:
${
minutes
}
`
}
return
''
}
}
// 关闭语音识别结果弹窗
function
closeVoiceResult
()
{
// 关闭语音识别结果弹窗
function
closeVoiceResult
()
{
voiceRecognitionState
.
value
.
showResultPage
=
false
voiceRecognitionState
.
value
.
recognizedText
=
''
voiceRecognitionState
.
value
.
recordDate
=
''
...
...
@@ -2181,9 +2286,9 @@ function closeVoiceResult() {
// 重置防连点状态,确保用户可以重新录音
resetRecordingCooldown
()
}
}
function
formatCurrentTime
()
{
function
formatCurrentTime
()
{
if
(
!
currentTime
.
value
)
{
// 如果当前时间未设置,返回当前时间
const
now
=
new
Date
()
...
...
@@ -2202,9 +2307,9 @@ function formatCurrentTime() {
const
hours
=
String
(
date
.
getHours
()).
padStart
(
2
,
'0'
)
const
minutes
=
String
(
date
.
getMinutes
()).
padStart
(
2
,
'0'
)
return
`
${
year
}
-
${
month
}
-
${
day
}
${
hours
}
:
${
minutes
}
`
}
}
function
getTabImage
()
{
function
getTabImage
()
{
const
currentMethod
=
recordMethods
.
value
[
selectedType
.
value
]
if
(
currentMethod
===
'manual'
)
{
return
feedingIndexRes
.
Tab_bottom_write
...
...
@@ -2213,35 +2318,35 @@ function getTabImage() {
}
else
{
return
feedingIndexRes
.
Tab_bottom_voice
}
}
}
function
getTabImage2
()
{
function
getTabImage2
()
{
const
currentMethod
=
recordMethods
.
value
[
selectedType
.
value
]
if
(
currentMethod
===
'manual'
)
{
return
feedingIndexRes
.
Tab_bottom_muruandnaifen_write
}
else
{
return
feedingIndexRes
.
Tab_bottom_muruandnaifen_voice
}
}
}
// 格式化时间显示 (MM:SS)
function
formatTime
(
seconds
)
{
// 格式化时间显示 (MM:SS)
function
formatTime
(
seconds
)
{
const
minutes
=
Math
.
floor
(
seconds
/
60
)
const
remainingSeconds
=
seconds
%
60
return
`
${
minutes
.
toString
().
padStart
(
2
,
'0'
)}
:
${
remainingSeconds
.
toString
().
padStart
(
2
,
'0'
)}
`
}
}
// 格式化总时长显示 (HH:MM:SS)
function
formatTotalDuration
()
{
// 格式化总时长显示 (HH:MM:SS)
function
formatTotalDuration
()
{
const
totalSeconds
=
timerData
.
value
.
leftDuration
+
timerData
.
value
.
rightDuration
const
hours
=
Math
.
floor
(
totalSeconds
/
3600
)
const
minutes
=
Math
.
floor
((
totalSeconds
%
3600
)
/
60
)
const
seconds
=
totalSeconds
%
60
return
`
${
hours
.
toString
().
padStart
(
2
,
'0'
)}
:
${
minutes
.
toString
().
padStart
(
2
,
'0'
)}
:
${
seconds
.
toString
().
padStart
(
2
,
'0'
)}
`
}
}
// 辅食选择相关方法
function
toggleFoodSelection
(
item
)
{
// 辅食选择相关方法
function
toggleFoodSelection
(
item
)
{
// 在编辑模式时不允许选择
if
(
foodSelectionState
.
value
.
isEditMode
)
{
return
...
...
@@ -2257,9 +2362,9 @@ function toggleFoodSelection(item) {
// 如果未选中,则添加选中
selectedItems
.
push
(
item
)
}
}
}
function
enterEditMode
()
{
function
enterEditMode
()
{
if
(
foodSelectionState
.
value
.
isEditMode
)
{
// 如果已经在编辑模式,则取消编辑
cancelEditMode
()
...
...
@@ -2287,9 +2392,9 @@ function enterEditMode() {
// 清空待删除列表
foodSelectionState
.
value
.
pendingDeletes
=
[]
}
}
}
function
cancelEditMode
()
{
function
cancelEditMode
()
{
// 恢复原始辅食数据,保持原有顺序
if
(
foodSelectionState
.
value
.
originalFoodData
)
{
feedingData
.
value
.
food
.
selectedItems
=
[...
foodSelectionState
.
value
.
originalFoodData
.
selectedItems
]
...
...
@@ -2329,9 +2434,9 @@ function cancelEditMode() {
foodSelectionState
.
value
.
isEditMode
=
false
// 清理原始数据
foodSelectionState
.
value
.
originalFoodData
=
null
}
}
async
function
exitEditMode
()
{
async
function
exitEditMode
()
{
md
.
sensorLogTake
({
xcxClick
:
"小程序页面点击事件"
,
pageName
:
"喂养工具首页"
,
...
...
@@ -2381,7 +2486,8 @@ async function exitEditMode() {
if
(
foodSelectionState
.
value
.
originalFoodData
)
{
// 恢复原始辅食数据
Object
.
keys
(
foodCategories
.
value
).
forEach
(
categoryName
=>
{
const
originalCategory
=
foodSelectionState
.
value
.
originalFoodData
.
categories
[
categoryName
]
const
originalCategory
=
foodSelectionState
.
value
.
originalFoodData
.
categories
[
categoryName
]
if
(
originalCategory
)
{
foodCategories
.
value
[
categoryName
].
items
=
[...
originalCategory
.
items
]
foodCategories
.
value
[
categoryName
].
customItems
=
[...
originalCategory
.
customItems
]
...
...
@@ -2404,9 +2510,9 @@ async function exitEditMode() {
// 立即重置防连点状态
foodSelectionState
.
value
.
isDeletingFood
=
false
console
.
log
(
'防连点:重置删除完成状态为false'
)
}
}
function
showAddFoodPopup
(
categoryName
)
{
function
showAddFoodPopup
(
categoryName
)
{
md
.
sensorLogTake
({
xcxClick
:
"小程序页面点击事件"
,
pageName
:
"喂养工具首页"
,
...
...
@@ -2456,17 +2562,17 @@ function showAddFoodPopup(categoryName) {
foodSelectionState
.
value
.
isAddingFood
=
false
console
.
log
(
'防连点:重置添加辅食状态为false'
)
},
100
)
}
}
// 切换分类展开/缩起状态
function
toggleCategoryExpansion
(
categoryName
)
{
// 切换分类展开/缩起状态
function
toggleCategoryExpansion
(
categoryName
)
{
const
category
=
foodCategories
.
value
[
categoryName
]
if
(
category
)
{
category
.
expanded
=
!
category
.
expanded
}
}
}
function
cancelAddFood
()
{
function
cancelAddFood
()
{
addFoodPopup
.
value
.
close
()
foodSelectionState
.
value
.
newFoodItem
=
''
md
.
sensorPopLogTake
({
...
...
@@ -2475,9 +2581,9 @@ function cancelAddFood() {
popName
:
"新增辅食弹窗"
,
buttonName
:
"取消"
});
}
}
function
confirmAddFood
()
{
function
confirmAddFood
()
{
if
(
foodSelectionState
.
value
.
isAddingFood
)
{
console
.
log
(
'防连点:添加辅食按钮被阻止'
)
return
...
...
@@ -2511,9 +2617,9 @@ function confirmAddFood() {
foodSelectionState
.
value
.
isAddingFood
=
false
console
.
log
(
'防连点:重置添加辅食状态为false'
)
},
2000
)
}
}
async
function
addCustomFoodItem
(
categoryName
,
itemName
)
{
async
function
addCustomFoodItem
(
categoryName
,
itemName
)
{
// 检查字数限制
if
(
itemName
.
length
>
10
)
{
uni
.
showToast
({
...
...
@@ -2583,9 +2689,9 @@ async function addCustomFoodItem(categoryName, itemName) {
// 失败时重置防连点状态
foodSelectionState
.
value
.
isAddingFood
=
false
}
}
}
function
removeFoodItem
(
categoryName
,
itemName
)
{
function
removeFoodItem
(
categoryName
,
itemName
)
{
// 获取foodId
const
foodId
=
foodIdMap
.
value
.
get
(
itemName
)
...
...
@@ -2632,10 +2738,10 @@ function removeFoodItem(categoryName, itemName) {
})
console
.
log
(
'添加到待删除列表:'
,
itemName
,
'原始位置:'
,
originalIndex
,
'当前待删除:'
,
foodSelectionState
.
value
.
pendingDeletes
)
}
}
// 语音识别相关方法
function
checkVoicePermission
()
{
// 语音识别相关方法
function
checkVoicePermission
()
{
// 检查录音权限
uni
.
getSetting
({
success
:
(
res
)
=>
{
...
...
@@ -2662,13 +2768,16 @@ function checkVoicePermission() {
// 打开设置页面
uni
.
openSetting
({
success
:
(
settingRes
)
=>
{
console
.
log
(
'设置页面结果:'
,
settingRes
)
if
(
settingRes
.
authSetting
[
'scope.record'
])
{
console
.
log
(
'设置页面结果:'
,
settingRes
)
if
(
settingRes
.
authSetting
[
'scope.record'
])
{
console
.
log
(
'录音权限已开启'
)
}
},
fail
:
(
err
)
=>
{
console
.
error
(
'打开设置页面失败:'
,
err
)
console
.
error
(
'打开设置页面失败:'
,
err
)
}
})
}
...
...
@@ -2688,10 +2797,10 @@ function checkVoicePermission() {
})
}
})
}
}
// 录音状态管理
const
recordingState
=
ref
({
// 录音状态管理
const
recordingState
=
ref
({
isInitialized
:
false
,
// 是否已初始化录音管理器
isRecording
:
false
,
// 是否正在录音
recordingStartTime
:
null
,
// 录音开始时间
...
...
@@ -2699,10 +2808,10 @@ const recordingState = ref({
recordingTimer
:
null
,
// 录音时长定时器
lastStopTime
:
0
,
// 上次停止录音的时间戳
canStartRecording
:
true
// 是否可以开始录音(防连点)
})
})
// 初始化录音管理器(只初始化一次)
function
initializeRecorderManager
()
{
// 初始化录音管理器(只初始化一次)
function
initializeRecorderManager
()
{
if
(
recordingState
.
value
.
isInitialized
)
{
console
.
log
(
'录音管理器已初始化,跳过'
)
return
...
...
@@ -2745,7 +2854,8 @@ function initializeRecorderManager() {
// 启动录音时长定时器
recordingState
.
value
.
recordingTimer
=
setInterval
(()
=>
{
if
(
recordingState
.
value
.
isRecording
&&
recordingState
.
value
.
recordingStartTime
)
{
const
duration
=
Math
.
floor
((
Date
.
now
()
-
recordingState
.
value
.
recordingStartTime
)
/
1000
)
const
duration
=
Math
.
floor
((
Date
.
now
()
-
recordingState
.
value
.
recordingStartTime
)
/
1000
)
recordingState
.
value
.
recordingDuration
=
duration
voiceRecognitionState
.
value
.
recordingDuration
=
duration
}
...
...
@@ -2830,10 +2940,10 @@ function initializeRecorderManager() {
recordingState
.
value
.
isInitialized
=
true
console
.
log
(
'录音管理器初始化完成'
)
}
}
// 重置录音状态
function
resetRecordingState
()
{
// 重置录音状态
function
resetRecordingState
()
{
console
.
log
(
'重置录音状态'
)
// 清理录音定时器
...
...
@@ -2855,26 +2965,26 @@ function resetRecordingState() {
// 注意:这里不调用 recorderManager.stop(),因为调用方会处理
// 避免重复调用导致的问题
}
}
// 重置防连点状态(立即恢复)
function
resetRecordingCooldown
()
{
// 重置防连点状态(立即恢复)
function
resetRecordingCooldown
()
{
recordingState
.
value
.
canStartRecording
=
true
console
.
log
(
'立即重置录音冷却状态'
)
}
}
// 检查录音管理器状态
function
checkRecorderStatus
()
{
// 检查录音管理器状态
function
checkRecorderStatus
()
{
console
.
log
(
'检查录音管理器状态:'
,
{
isRecording
:
recordingState
.
value
.
isRecording
,
voiceIsRecording
:
voiceRecognitionState
.
value
.
isRecording
,
recognitionStatus
:
voiceRecognitionState
.
value
.
recognitionStatus
,
canStartRecording
:
recordingState
.
value
.
canStartRecording
})
}
}
// 强制重置录音管理器状态
function
forceResetRecorderManager
()
{
// 强制重置录音管理器状态
function
forceResetRecorderManager
()
{
console
.
log
(
'强制重置录音管理器状态'
)
// 重置录音状态
...
...
@@ -2902,10 +3012,10 @@ function forceResetRecorderManager() {
// 检查重置后的状态
checkRecorderStatus
()
},
300
)
}
}
// 开始录音
async
function
startRecording
()
{
// 开始录音
async
function
startRecording
()
{
if
(
!
recordingState
.
value
.
isRecording
)
{
md
.
sensorLogTake
({
xcxClick
:
"小程序页面点击事件"
,
...
...
@@ -3008,10 +3118,10 @@ async function startRecording() {
})
}
})
}
}
// 停止录音
async
function
stopRecording
()
{
// 停止录音
async
function
stopRecording
()
{
console
.
log
(
'停止录音请求...'
)
...
...
@@ -3076,10 +3186,10 @@ async function stopRecording() {
// 即使停止失败,也要强制重置录音管理器状态
forceResetRecorderManager
()
}
}
}
// 处理语音文件
async
function
processVoiceFile
(
tempFilePath
)
{
// 处理语音文件
async
function
processVoiceFile
(
tempFilePath
)
{
try
{
// 显示加载提示
uni
.
showLoading
({
...
...
@@ -3097,10 +3207,10 @@ async function processVoiceFile(tempFilePath) {
}
catch
(
error
)
{
handleVoiceRecognitionError
(
error
)
}
}
}
// 上传语音文件
async
function
uploadVoiceFile
(
tempFilePath
)
{
// 上传语音文件
async
function
uploadVoiceFile
(
tempFilePath
)
{
return
new
Promise
((
resolve
,
reject
)
=>
{
// 检查文件路径
if
(
!
tempFilePath
||
typeof
tempFilePath
!==
'string'
)
{
...
...
@@ -3144,38 +3254,50 @@ async function uploadVoiceFile(tempFilePath) {
encoding
:
'base64'
,
success
:
async
(
res
)
=>
{
try
{
console
.
log
(
'语音文件读取成功,base64长度:'
,
res
.
data
.
length
,
'字符'
)
console
.
log
(
'语音文件读取成功,base64长度:'
,
res
.
data
.
length
,
'字符'
)
// 检查base64数据是否有效
if
(
!
res
.
data
||
res
.
data
.
length
<
100
)
{
console
.
error
(
'base64数据无效,长度:'
,
res
.
data
?.
length
)
reject
(
new
Error
(
'语音文件数据无效,请重新录音'
))
if
(
!
res
.
data
||
res
.
data
.
length
<
100
)
{
console
.
error
(
'base64数据无效,长度:'
,
res
.
data
?.
length
)
reject
(
new
Error
(
'语音文件数据无效,请重新录音'
))
return
}
// 验证base64格式
if
(
!
/^
[
A-Za-z0-9+
/]
*=
{0,2}
$/
.
test
(
res
.
data
))
{
if
(
!
/^
[
A-Za-z0-9+
/]
*=
{0,2}
$/
.
test
(
res
.
data
))
{
console
.
error
(
'base64格式无效'
)
reject
(
new
Error
(
'语音文件格式无效,请重新录音'
))
reject
(
new
Error
(
'语音文件格式无效,请重新录音'
))
return
}
console
.
log
(
'base64数据验证通过,开始上传'
)
// 添加base64格式头
const
base64WithHeader
=
`data:audio/mp3;base64,
${
res
.
data
}
`
const
base64WithHeader
=
`data:audio/mp3;base64,
${
res
.
data
}
`
// 调用上传接口,传递带格式头的base64数据
const
response
=
await
feedingVoiceUpload
({
const
response
=
await
feedingVoiceUpload
({
audioData
:
base64WithHeader
})
console
.
log
(
'上传接口返回:'
,
response
)
if
(
response
&&
response
.
data
&&
response
.
data
.
taskId
)
{
if
(
response
&&
response
.
data
&&
response
.
data
.
taskId
)
{
resolve
(
response
.
data
)
}
else
{
reject
(
new
Error
(
'上传失败:未获取到taskId,返回数据:'
+
JSON
.
stringify
(
response
)))
reject
(
new
Error
(
'上传失败:未获取到taskId,返回数据:'
+
JSON
.
stringify
(
response
)))
}
}
catch
(
error
)
{
console
.
error
(
'上传过程中发生错误:'
,
error
)
...
...
@@ -3184,7 +3306,8 @@ async function uploadVoiceFile(tempFilePath) {
},
fail
:
(
err
)
=>
{
console
.
error
(
'读取语音文件失败:'
,
err
)
reject
(
new
Error
(
'读取语音文件失败:'
+
err
.
errMsg
))
reject
(
new
Error
(
'读取语音文件失败:'
+
err
.
errMsg
))
}
})
},
...
...
@@ -3200,10 +3323,10 @@ async function uploadVoiceFile(tempFilePath) {
}
})
})
}
}
// 开始轮询识别结果
async
function
startPollingRecognitionResult
(
taskId
)
{
// 开始轮询识别结果
async
function
startPollingRecognitionResult
(
taskId
)
{
console
.
log
(
'开始轮询识别结果,taskId:'
,
taskId
)
voiceRecognitionState
.
value
.
taskId
=
taskId
...
...
@@ -3266,7 +3389,8 @@ async function startPollingRecognitionResult(taskId) {
voiceRecognitionState
.
value
.
recordDate
=
`
${
year
}
-
${
month
}
-
${
day
}
`
voiceRecognitionState
.
value
.
recordTime
=
`
${
hours
}
:
${
minutes
}
`
voiceRecognitionState
.
value
.
voiceDateTime
=
`
${
year
}
-
${
month
}
-
${
day
}
${
hours
}
:
${
minutes
}
:00`
voiceRecognitionState
.
value
.
voiceDateTime
=
`
${
year
}
-
${
month
}
-
${
day
}
${
hours
}
:
${
minutes
}
:00`
}
voiceRecognitionState
.
value
.
showResultPage
=
true
md
.
sensorPopLogTake
({
...
...
@@ -3340,10 +3464,10 @@ async function startPollingRecognitionResult(taskId) {
})
}
},
30000
)
}
}
// 清理轮询定时器
function
clearPollingInterval
()
{
// 清理轮询定时器
function
clearPollingInterval
()
{
console
.
log
(
'清理轮询定时器'
)
if
(
voiceRecognitionState
.
value
.
pollingInterval
)
{
...
...
@@ -3369,10 +3493,10 @@ function clearPollingInterval() {
// 重置防连点状态,确保用户可以重新录音
resetRecordingCooldown
()
}
}
// 处理语音识别错误
function
handleVoiceRecognitionError
(
error
)
{
// 处理语音识别错误
function
handleVoiceRecognitionError
(
error
)
{
console
.
error
(
'语音识别错误:'
,
error
)
clearPollingInterval
()
uni
.
hideLoading
()
...
...
@@ -3401,9 +3525,9 @@ function handleVoiceRecognitionError(error) {
title
:
errorMessage
,
icon
:
'none'
})
}
}
function
getFeedingTypeLabel
()
{
function
getFeedingTypeLabel
()
{
const
typeMap
=
{
breastfeeding
:
'母乳亲喂'
,
bottle
:
'母乳瓶喂'
,
...
...
@@ -3411,10 +3535,10 @@ function getFeedingTypeLabel() {
food
:
'辅食'
}
return
typeMap
[
selectedType
.
value
]
||
'未知'
}
}
// 格式化录音时长显示
function
formatRecordingDuration
(
seconds
)
{
// 格式化录音时长显示
function
formatRecordingDuration
(
seconds
)
{
if
(
!
seconds
||
seconds
<=
0
)
return
'0秒'
const
minutes
=
Math
.
floor
(
seconds
/
60
)
...
...
@@ -3425,9 +3549,9 @@ function formatRecordingDuration(seconds) {
}
else
{
return
`
${
remainingSeconds
}
秒`
}
}
}
function
reRecognize
()
{
function
reRecognize
()
{
console
.
log
(
'重新识别...'
)
md
.
sensorPopLogTake
({
xcxPopClick
:
"true"
,
...
...
@@ -3454,9 +3578,9 @@ function reRecognize() {
voiceRecognitionState
.
value
.
recordDate
=
''
voiceRecognitionState
.
value
.
recordTime
=
''
voiceRecognitionState
.
value
.
voiceDateTime
=
''
}
}
async
function
completeVoiceRecord
()
{
async
function
completeVoiceRecord
()
{
// 防止重复提交
if
(
isSubmitting
.
value
)
{
return
...
...
@@ -3542,12 +3666,12 @@ async function completeVoiceRecord() {
isSubmitting
.
value
=
false
},
2000
)
}
}
}
// 记录成功弹窗相关方法
async
function
onSuccessJump
()
{
// 记录成功弹窗相关方法
async
function
onSuccessJump
()
{
// 检查是否正在录音
if
(
recordingState
.
value
.
isRecording
||
voiceRecognitionState
.
value
.
isRecording
)
{
uni
.
showToast
({
...
...
@@ -3567,7 +3691,13 @@ async function onSuccessJump() {
return
;
}
const
{
sign
,
timestamp
,
appId
,
partnerUserId
,
env
}
=
res
.
data
;
const
{
sign
,
timestamp
,
appId
,
partnerUserId
,
env
}
=
res
.
data
;
jump
({
type
:
JumpType
.
MINI
,
...
...
@@ -3580,8 +3710,7 @@ async function onSuccessJump() {
timestamp
,
// 参考 4.请求参数
appId
,
// 参考 4.请求参数
partnerUserId
,
// 参考 4.请求参数
targetApp
:
"/h5/partner/shining-like-a-start/landing-free-consult?sysType=CRF"
,
targetApp
:
"/h5/partner/shining-like-a-start/landing-free-consult?sysType=CRF"
,
},
},
});
// 关闭弹窗
...
...
@@ -3592,9 +3721,9 @@ async function onSuccessJump() {
popName
:
"添加成功弹窗"
,
buttonName
:
"咨询专家"
});
}
}
function
onSuccessClose
()
{
function
onSuccessClose
()
{
// 关闭弹窗
successPopup
.
value
.
close
()
md
.
sensorPopLogTake
({
...
...
@@ -3607,15 +3736,15 @@ function onSuccessClose() {
uni
.
navigateTo
({
url
:
'/pages/feedingRecord/feedingRecord'
})
}
}
// 检查是否有未完成的编辑操作
function
hasUnfinishedEdit
()
{
// 检查是否有未完成的编辑操作
function
hasUnfinishedEdit
()
{
return
foodSelectionState
.
value
.
isEditMode
&&
foodSelectionState
.
value
.
pendingDeletes
.
length
>
0
}
}
// 恢复未完成的编辑操作
function
restoreUnfinishedEdit
()
{
// 恢复未完成的编辑操作
function
restoreUnfinishedEdit
()
{
if
(
hasUnfinishedEdit
())
{
console
.
log
(
'恢复未完成的辅食删除操作'
)
// 显示提示
...
...
@@ -3636,10 +3765,10 @@ function restoreUnfinishedEdit() {
}
})
}
}
}
// 宝宝切换相关方法
function
showBabySwitch
()
{
// 宝宝切换相关方法
function
showBabySwitch
()
{
// 检查是否正在录音
if
(
recordingState
.
value
.
isRecording
||
voiceRecognitionState
.
value
.
isRecording
)
{
uni
.
showToast
({
...
...
@@ -3658,9 +3787,9 @@ function showBabySwitch() {
});
showBabySwitchPopup
.
value
=
true
}
}
}
async
function
onBabyChange
(
baby
,
index
)
{
async
function
onBabyChange
(
baby
,
index
)
{
// 切换宝宝
await
userStore
.
changeBabySelected
(
baby
.
id
)
console
.
log
(
'切换到宝宝:'
,
baby
.
babyName
,
'索引:'
,
index
)
...
...
@@ -3670,17 +3799,23 @@ async function onBabyChange(baby, index) {
// 清空当前状态,避免数据混乱
clearPreviousState
()
}
}
// 获取辅食列表数据
async
function
loadFoodsData
()
{
// 获取辅食列表数据
async
function
loadFoodsData
()
{
try
{
const
response
=
await
feedingFoodsCustom
()
console
.
log
(
'辅食列表数据:'
,
response
)
if
(
response
&&
response
.
data
)
{
const
foodsList
=
response
.
data
//未登录情况下这里是个object{error_msg:'404 Route Not Found'}
if
(
foodsList
instanceof
Array
)
{
processFoodsData
(
foodsList
)
}
else
{
processFoodsData
([])
}
}
else
{
// 如果没有数据,使用默认数据
loadDefaultFoodsData
()
...
...
@@ -3691,10 +3826,10 @@ async function loadFoodsData() {
// 使用默认数据作为fallback
loadDefaultFoodsData
()
}
}
}
// 处理辅食数据
function
processFoodsData
(
foodsList
)
{
// 处理辅食数据
function
processFoodsData
(
foodsList
)
{
// 清空现有数据
Object
.
keys
(
foodCategories
.
value
).
forEach
(
category
=>
{
foodCategories
.
value
[
category
].
items
=
[]
...
...
@@ -3719,10 +3854,10 @@ function processFoodsData(foodsList) {
console
.
log
(
'处理后的辅食数据:'
,
foodCategories
.
value
)
console
.
log
(
'辅食ID映射:'
,
foodIdMap
.
value
)
}
}
// 加载默认辅食数据(fallback)
function
loadDefaultFoodsData
()
{
// 加载默认辅食数据(fallback)
function
loadDefaultFoodsData
()
{
foodCategories
.
value
=
{
主食
:
{
items
:
[],
...
...
@@ -3745,33 +3880,48 @@ function loadDefaultFoodsData() {
expanded
:
false
}
}
}
}
onShareAppMessage
(()
=>
{
return
{
title
:
"喂养记录:喂奶辅食轻松记录,喂养数据一目了然"
,
path
:
"/pages/feedingIndex/feedingIndex"
,
imageUrl
:
$baseUrl
+
"share/weiyang.png"
,
}
});
onShareTimeline
(()
=>
{
return
{
title
:
"喂养记录:喂奶辅食轻松记录,喂养数据一目了然"
,
path
:
"/pages/feedingIndex/feedingIndex"
,
imageUrl
:
$baseUrl
+
"share/weiyang.png"
,
}
});
</
script
>
<
style
lang=
"scss"
scoped
>
/* ===== 页面整体布局 ===== */
.feeding-record-add-page
{
/* ===== 页面整体布局 ===== */
.feeding-record-add-page
{
background
:
#ffffff
;
min-height
:
100vh
;
padding
:
0
;
position
:
relative
;
}
/* ===== 可滚动内容区域 ===== */
// .scrollable-content {
// height: calc(100vh);
// // height: 100vh;
// background-color: #FFF8F1;
// /* 减去底部按钮的高度 */
// z-index: 200;
// position: absolute;
// width: 100vw;
// }
/* ===== 底部完成按钮 ===== */
.bottom_complete-btn
{
}
/* ===== 可滚动内容区域 ===== */
// .scrollable-content {
// height: calc(100vh);
// // height: 100vh;
// background-color: #FFF8F1;
// /* 减去底部按钮的高度 */
// z-index: 200;
// position: absolute;
// width: 100vw;
// }
/* ===== 底部完成按钮 ===== */
.bottom_complete-btn
{
// padding-top: 20rpx;
position
:
fixed
;
bottom
:
0rpx
;
...
...
@@ -3790,10 +3940,10 @@ function loadDefaultFoodsData() {
height
:
94rpx
;
display
:
block
;
}
}
}
/* ===== 广告横幅 ===== */
.banner-swiper
{
/* ===== 广告横幅 ===== */
.banner-swiper
{
position
:
relative
;
top
:
0
;
left
:
16rpx
;
...
...
@@ -3805,10 +3955,10 @@ function loadDefaultFoodsData() {
height
:
100%
;
border-radius
:
16rpx
;
}
}
}
/* ===== 喂养时间区域 ===== */
.feeding-time
{
/* ===== 喂养时间区域 ===== */
.feeding-time
{
position
:
relative
;
// margin-top: 174rpx;
left
:
0
;
...
...
@@ -3893,10 +4043,10 @@ function loadDefaultFoodsData() {
margin-top
:
10rpx
;
}
}
}
}
/* ===== 喂养记录链接 ===== */
.feeding-records
{
/* ===== 喂养记录链接 ===== */
.feeding-records
{
position
:
relative
;
// margin-top: 270rpx;
left
:
0
;
...
...
@@ -3922,12 +4072,12 @@ function loadDefaultFoodsData() {
width
:
11rpx
;
height
:
19rpx
;
}
}
}
/* ===== 喂养类型选择 ===== */
.feeding-types
{
/* ===== 喂养类型选择 ===== */
.feeding-types
{
position
:
relative
;
// margin-top: 320rpx;
left
:
0
;
...
...
@@ -3992,10 +4142,10 @@ function loadDefaultFoodsData() {
}
}
}
}
}
/* ===== 温馨提示 ===== */
.warm-tip
{
/* ===== 温馨提示 ===== */
.warm-tip
{
position
:
relative
;
// margin-top: 20rpx;
left
:
0
;
...
...
@@ -4008,10 +4158,10 @@ function loadDefaultFoodsData() {
font-size
:
24rpx
;
color
:
#000
;
}
}
}
/* ===== 表单区域 ===== */
.form-section
{
/* ===== 表单区域 ===== */
.form-section
{
position
:
absolute
;
top
:
80rpx
;
left
:
0
;
...
...
@@ -4021,10 +4171,10 @@ function loadDefaultFoodsData() {
background-color
:
#fff
;
// height: 300rpx;
z-index
:
2
;
}
}
/* ===== 母乳亲喂表单 ===== */
.breastfeeding-form
{
/* ===== 母乳亲喂表单 ===== */
.breastfeeding-form
{
.duration-controls
{
display
:
flex
;
...
...
@@ -4109,10 +4259,10 @@ function loadDefaultFoodsData() {
}
}
}
}
}
/* ===== 母乳瓶喂/奶粉喂养表单 ===== */
.bottle-form
{
/* ===== 母乳瓶喂/奶粉喂养表单 ===== */
.bottle-form
{
.bottle-graphic
{
width
:
100%
;
height
:
574rpx
;
...
...
@@ -4219,10 +4369,10 @@ function loadDefaultFoodsData() {
}
}
}
}
/* ===== 辅食表单 ===== */
.food-form
{
/* ===== 辅食表单 ===== */
.food-form
{
margin-top
:
-80rpx
;
.selected-items
{
...
...
@@ -4436,14 +4586,14 @@ function loadDefaultFoodsData() {
}
}
}
}
}
/* ===== 添加辅食弹窗 ===== */
.add-food-popup-container
{
/* ===== 添加辅食弹窗 ===== */
.add-food-popup-container
{
z-index
:
10003
!
important
;
}
}
.add-food-popup
{
.add-food-popup
{
background
:
white
;
border-radius
:
40rpx
;
width
:
654rpx
;
...
...
@@ -4516,12 +4666,12 @@ function loadDefaultFoodsData() {
}
}
}
}
}
/* ===== 记录成功弹窗 ===== */
.success-popup
{
/* ===== 记录成功弹窗 ===== */
.success-popup
{
position
:
relative
;
width
:
654rpx
;
height
:
436rpx
;
...
...
@@ -4573,10 +4723,10 @@ function loadDefaultFoodsData() {
}
}
}
}
/* ===== 记录方式选择 ===== */
.record-methods1
{
/* ===== 记录方式选择 ===== */
.record-methods1
{
position
:
absolute
;
top
:
570rpx
;
left
:
0
;
...
...
@@ -4610,10 +4760,10 @@ function loadDefaultFoodsData() {
.right
{
left
:
calc
(
50%
+
78rpx
);
}
}
}
/* ===== 记录方式选择 - 母乳瓶喂/奶粉喂养 ===== */
.record-methods2
{
/* ===== 记录方式选择 - 母乳瓶喂/奶粉喂养 ===== */
.record-methods2
{
position
:
absolute
;
top
:
570rpx
;
left
:
0
;
...
...
@@ -4665,10 +4815,10 @@ function loadDefaultFoodsData() {
font-weight
:
bold
;
}
}
}
}
/* ===== 语音控制区域 ===== */
.voice-controls
{
/* ===== 语音控制区域 ===== */
.voice-controls
{
position
:
absolute
;
left
:
0
;
right
:
0
;
...
...
@@ -4726,10 +4876,10 @@ function loadDefaultFoodsData() {
color
:
#6f6d67
;
}
}
}
}
/* ===== 计时器控制区域 ===== */
.timer-controls
{
/* ===== 计时器控制区域 ===== */
.timer-controls
{
position
:
absolute
;
left
:
0
;
right
:
0
;
...
...
@@ -4793,13 +4943,13 @@ function loadDefaultFoodsData() {
}
}
}
}
}
/* ===== 下半部分背景区域 ===== */
.bottom-section
{
/* ===== 下半部分背景区域 ===== */
.bottom-section
{
position
:
relative
;
left
:
0
;
right
:
0
;
...
...
@@ -4819,37 +4969,37 @@ function loadDefaultFoodsData() {
}
}
// uni-datetime-picker样式覆盖(与feedingRecord页面保持一致)
::v-deep
.uni-datetime-picker--btn
{
// uni-datetime-picker样式覆盖(与feedingRecord页面保持一致)
::v-deep
.uni-datetime-picker--btn
{
background-color
:
#D4A574
!
important
;
}
}
::v-deep
.uni-calendar-item--checked
{
::v-deep
.uni-calendar-item--checked
{
background-color
:
#D4A574
!
important
;
}
}
::v-deep
.uni-datetime-picker-btn-text
{
::v-deep
.uni-datetime-picker-btn-text
{
color
:
#D4A574
!
important
;
}
}
/* 全局时间选择器层级修复 */
::v-deep
.uni-datetime-picker
{
/* 全局时间选择器层级修复 */
::v-deep
.uni-datetime-picker
{
z-index
:
999999
!
important
;
}
}
::v-deep
.uni-datetime-picker__mask
{
::v-deep
.uni-datetime-picker__mask
{
z-index
:
999998
!
important
;
position
:
fixed
!
important
;
top
:
0
!
important
;
left
:
0
!
important
;
right
:
0
!
important
;
bottom
:
0
!
important
;
}
}
::v-deep
.uni-datetime-picker__popup
{
::v-deep
.uni-datetime-picker__popup
{
z-index
:
999999
!
important
;
position
:
fixed
!
important
;
bottom
:
218rpx
!
important
;
...
...
@@ -4859,66 +5009,66 @@ function loadDefaultFoodsData() {
padding
:
30px
!
important
;
width
:
270px
!
important
;
background-color
:
#fff
!
important
;
}
}
::v-deep
.uni-datetime-picker__content
{
::v-deep
.uni-datetime-picker__content
{
z-index
:
999999
!
important
;
position
:
relative
!
important
;
}
}
/* 确保时间选择器内部元素也有正确的层级 */
::v-deep
.uni-datetime-picker__container
{
/* 确保时间选择器内部元素也有正确的层级 */
::v-deep
.uni-datetime-picker__container
{
z-index
:
999999
!
important
;
position
:
relative
!
important
;
}
}
::v-deep
.uni-datetime-picker__timebox
{
::v-deep
.uni-datetime-picker__timebox
{
z-index
:
999999
!
important
;
position
:
relative
!
important
;
}
}
::v-deep
.uni-datetime-picker__date
{
::v-deep
.uni-datetime-picker__date
{
z-index
:
999999
!
important
;
position
:
relative
!
important
;
}
}
::v-deep
.uni-datetime-picker__time
{
::v-deep
.uni-datetime-picker__time
{
z-index
:
999999
!
important
;
position
:
relative
!
important
;
}
}
/* 修复时间选择器文本显示位置 */
::v-deep
.uni-datetime-picker-text
{
/* 修复时间选择器文本显示位置 */
::v-deep
.uni-datetime-picker-text
{
position
:
relative
!
important
;
display
:
inline-block
!
important
;
line-height
:
50px
!
important
;
font-size
:
14px
!
important
;
text-align
:
center
!
important
;
vertical-align
:
middle
!
important
;
}
}
/* 修复时间选择器内部布局 */
::v-deep
.uni-datetime-picker__container-box
{
/* 修复时间选择器内部布局 */
::v-deep
.uni-datetime-picker__container-box
{
position
:
relative
!
important
;
display
:
flex
!
important
;
align-items
:
center
!
important
;
justify-content
:
center
!
important
;
margin-top
:
40px
!
important
;
}
}
::v-deep
.uni-datetime-picker-item
{
::v-deep
.uni-datetime-picker-item
{
display
:
flex
!
important
;
align-items
:
center
!
important
;
justify-content
:
center
!
important
;
height
:
50px
!
important
;
}
}
::v-deep
.uni-datetime-picker-view
{
::v-deep
.uni-datetime-picker-view
{
height
:
150px
!
important
;
}
}
/* ===== 语音识别结果弹窗 ===== */
.popup-mask
{
/* ===== 语音识别结果弹窗 ===== */
.popup-mask
{
position
:
fixed
;
top
:
0
;
left
:
0
;
...
...
@@ -4932,11 +5082,11 @@ function loadDefaultFoodsData() {
overflow
:
hidden
;
touch-action
:
none
;
/* 为固定按钮留出空间 */
}
}
.popup-content
{
.popup-content
{
background
:
#f6f8fa
;
width
:
750rpx
;
max-height
:
80vh
;
...
...
@@ -5141,9 +5291,9 @@ function loadDefaultFoodsData() {
padding-top
:
20rpx
!
important
;
border-top
:
1rpx
solid
#e5e5e5
!
important
;
}
}
}
@keyframes
slideUp
{
@keyframes
slideUp
{
from
{
transform
:
translateY
(
100%
);
}
...
...
@@ -5151,10 +5301,10 @@ function loadDefaultFoodsData() {
to
{
transform
:
translateY
(
0
);
}
}
}
// 语音模式提示样式
.voice-mode-tip
{
// 语音模式提示样式
.voice-mode-tip
{
position
:
absolute
;
top
:
-60rpx
;
left
:
50%
;
...
...
@@ -5166,15 +5316,15 @@ function loadDefaultFoodsData() {
font-size
:
24rpx
;
white-space
:
nowrap
;
z-index
:
10
;
}
}
.
food-input
:
:
placeholder
{
.
food-input
:
:
placeholder
{
color
:
#bbb
;
line-height
:
70rpx
;
/* 或 110rpx,和上面保持一致 */
}
}
.uni-date
{
.uni-date
{
z-index
:
999999
!
important
;
}
}
</
style
>
\ No newline at end of file
pages/person/person.vue
View file @
821b80a8
<
template
>
<view
class=
"person-page"
>
<image
class=
"icon-return"
:src=
"$baseUrl + 'person/icon_return.png'"
mode=
"aspectFit"
@
click=
"handleReturn"
/>
<image
class=
"banner_upload"
:src=
"$baseUrl + 'person/customer.png'"
mode=
"aspectFit"
:data-log=
"
{
<image
class=
"icon-return"
:src=
"$baseUrl + 'person/icon_return.png'"
mode=
"aspectFit"
@
click=
"handleReturn"
/>
<image
class=
"banner_upload"
:src=
"$baseUrl + 'person/customer.png'"
mode=
"aspectFit"
:data-log=
"
{
xcxClick: '我的页面-信息修改页点击',
pageName: '我的页面-信息修改页',
buttonName: '上传背景',
}"
@click="handleUploadBackground"
/>
}" @click="handleUploadBackground" />
<view
class=
"person-header"
>
<image
class=
"banner_bg"
:src=
"formData.backgroundImg || $baseUrl + 'person/banner.png'"
mode=
"aspectFill"
/>
<image
class=
"banner_cover"
:src=
"$baseUrl + 'person/cover_white.png'"
mode=
"aspectFill"
/>
<image
class=
"banner_bg"
:src=
"formData.backgroundImg || $baseUrl + 'person/banner.png'"
mode=
"aspectFill"
/>
<image
class=
"banner_cover"
:src=
"$baseUrl + 'person/cover_white.png'"
mode=
"aspectFill"
/>
</view>
<!-- 头像 -->
<view
class=
"person-avatar"
>
<view
class=
"person-avatar-box"
>
<button
class=
"avatar-wrapper"
open-type=
"chooseAvatar"
@
chooseavatar=
"onChooseAvatar"
>
<image
class=
"person-avatar-img"
mode=
"aspectFill"
:src=
"formData.babyAvatar || $baseUrl + 'common/default_avatar.png'"
></image>
<button
class=
"avatar-wrapper"
open-type=
"chooseAvatar"
@
chooseavatar=
"onChooseAvatar"
>
<image
class=
"person-avatar-img"
mode=
"aspectFill"
:src=
"formData.babyAvatar || $baseUrl + 'common/default_avatar.png'"
></image>
</button>
</view>
<image
class=
"avatar-edit"
:src=
"$baseUrl + 'person/icon_modify.png'"
mode=
"widthFix"
lazy-load=
"false"
binderror=
""
bindload=
""
/>
<image
class=
"avatar-edit"
:src=
"$baseUrl + 'person/icon_modify.png'"
mode=
"widthFix"
lazy-load=
"false"
binderror=
""
bindload=
""
/>
</view>
<form
@
submit=
"onSubmit"
>
<view
class=
"person-info"
>
<block
v-for=
"(item, index) in formItems
<block
v-for=
"(item, index) in formItems
.filter(formItemFilter)
.slice(
0,
formData.babyStage == 2 && pageStatus.formStatus == 2
? 6
: formItems.length
)"
:key=
"item.name"
>
<view
class=
"form-row"
:style=
"
{
)"
:key=
"item.name"
>
<view
class=
"form-row"
:style=
"
{
'border-bottom':
pageStatus.formStatus == 0
&&
index == formItems.filter(formItemFilter).length - 1
? 'none'
: '1rpx solid #f2f2f2',
}"
>
}">
<text
class=
"form-label"
>
{{
getlabelFn
(
item
)
}}
<!--
{{
item
.
label
}}
-->
<text
v-if=
"item.required"
class=
"required"
>
*
</text>
</text>
<!-- 输入框类型 -->
<input
v-if=
"item.type === 'input'"
class=
"form-input"
:name=
"item.name"
:placeholder=
"item.placeholder"
v-model=
"formData[item.name]"
:maxlength=
"item.maxLength"
/>
<input
v-if=
"item.type === 'input'"
class=
"form-input"
:name=
"item.name"
:placeholder=
"item.placeholder"
v-model=
"formData[item.name]"
:maxlength=
"item.maxLength"
/>
<!-- 只读展示类型 -->
<view
v-else-if=
"item.type === 'display'"
class=
"form-input-box"
>
<view
class=
"form-input"
style=
"color: #222"
>
{{
formData
[
item
.
name
]
||
item
.
placeholder
}}
</view>
</view>
<view
v-else-if=
"item.type === 'display-obj'"
class=
"form-input-box"
>
<view
v-else-if=
"item.type === 'display-obj'"
class=
"form-input-box"
>
<view
class=
"form-input"
style=
"color: #222"
>
{{
getLabelByValue
(
item
,
formData
[
item
.
name
])
}}
</view>
</view>
<!-- 选择器类型 -->
<picker-custom
v-else-if=
"item.type === 'picker'"
:mode=
"item.mode"
:range=
"item.range"
:value=
"
item.mode === 'date'
<picker-custom
v-else-if=
"item.type === 'picker'"
:mode=
"item.mode"
:range=
"item.range"
:value=
"item.mode === 'date'
? formData[item.name]
: getPickerIndex(item)
"
:onPickerChange=
"(e) => onPickerChange(e, item.name)"
:onLayerVisibleChange=
"(e) => (pageStatus.btnStatus = !e)"
:onStatusChange=
"onDateStatusChange"
>
"
:onPickerChange=
"(e) => onPickerChange(e, item.name)"
:onLayerVisibleChange=
"(e) => (pageStatus.btnStatus = !e)"
:onStatusChange=
"onDateStatusChange"
>
<view
class=
"form-input-box"
>
<view
class=
"form-input"
>
{{
getLabelByValue
(
item
,
formData
[
item
.
name
])
||
item
.
placeholder
}}
</view>
<image
class=
"form-input-icon"
:src=
"$baseUrl + 'person/icon_arrow_yellow_right.png'"
/>
<image
class=
"form-input-icon"
:src=
"$baseUrl + 'person/icon_arrow_yellow_right.png'"
/>
</view>
</picker-custom>
<!-- 多选弹窗类型 -->
<view
v-else-if=
"item.type === 'multi-picker'"
@
click=
"handleMultiPickerOpen(item)"
>
<view
v-else-if=
"item.type === 'multi-picker'"
@
click=
"handleMultiPickerOpen(item)"
>
<view
class=
"form-input-box"
>
<view
class=
"form-input"
>
{{
...
...
@@ -151,52 +90,27 @@
item
.
placeholder
}}
</view>
<image
class=
"form-input-icon"
:src=
"$baseUrl + 'person/icon_arrow_yellow_right.png'"
/>
<image
class=
"form-input-icon"
:src=
"$baseUrl + 'person/icon_arrow_yellow_right.png'"
/>
</view>
</view>
<!-- 单选类型 -->
<radio-group
v-else-if=
"item.type === 'radio'"
@
change=
"(e) => onRadioChange(e, item.name)"
>
<label
v-for=
"opt in item.options"
:key=
"opt.value"
class=
"form-radio"
>
<radio
:value=
"opt.value"
:checked=
"formData[item.name] === opt.value"
/>
<radio-group
v-else-if=
"item.type === 'radio'"
@
change=
"(e) => onRadioChange(e, item.name)"
>
<label
v-for=
"opt in item.options"
:key=
"opt.value"
class=
"form-radio"
>
<radio
:value=
"opt.value"
:checked=
"formData[item.name] === opt.value"
/>
{{
opt
.
label
}}
</label>
</radio-group>
</view>
</block>
<view
v-if=
"formData.babyStage == 2"
class=
"form-bottom-btn"
@
click=
"handleFormBottomBtn"
>
<view
v-if=
"formData.babyStage == 2"
class=
"form-bottom-btn"
@
click=
"handleFormBottomBtn"
>
<text
class=
"form-bottom-text"
>
{{
pageStatus
.
formStatus
==
1
?
"收起"
:
"展开"
}}
</text>
<image
v-if=
"pageStatus.formStatus == 1"
class=
"form-bottom-icon"
:src=
"$baseUrl + 'person/icon_arrow_yellow_up.png'"
mode=
"aspectFit"
/>
<image
v-else
class=
"form-bottom-icon"
:src=
"$baseUrl + 'person/icon_arrow_yellow_down.png'"
mode=
"aspectFit"
/>
<image
v-if=
"pageStatus.formStatus == 1"
class=
"form-bottom-icon"
:src=
"$baseUrl + 'person/icon_arrow_yellow_up.png'"
mode=
"aspectFit"
/>
<image
v-else
class=
"form-bottom-icon"
:src=
"$baseUrl + 'person/icon_arrow_yellow_down.png'"
mode=
"aspectFit"
/>
</view>
</view>
<view
class=
"form-bottom"
></view>
...
...
@@ -206,18 +120,11 @@
</button>
</form>
<MultiSelectLayer
v-if=
"multiPickerStatus && currentMultiPickerName"
v-model=
"multiPickerStatus"
:title=
"
formItems.find((i) => i.name === currentMultiPickerName)?.label +
<MultiSelectLayer
v-if=
"multiPickerStatus && currentMultiPickerName"
v-model=
"multiPickerStatus"
:title=
"formItems.find((i) => i.name === currentMultiPickerName)?.label +
'(多选)'
"
:options=
"formItems.find((i) => i.name === currentMultiPickerName)?.range"
:modelSelected=
"multiPickerSelected[currentMultiPickerName]"
@
confirm=
"handleMultiPickerConfirm"
@
cancel=
"handleMultiPickerCancel"
/>
"
:options=
"formItems.find((i) => i.name === currentMultiPickerName)?.range"
:modelSelected=
"multiPickerSelected[currentMultiPickerName]"
@
confirm=
"handleMultiPickerConfirm"
@
cancel=
"handleMultiPickerCancel"
/>
</view>
</
template
>
...
...
@@ -579,6 +486,13 @@ const onSubmit = async (e) => {
console
.
log
(
"提交数据"
,
data
);
const
pregnancyStatus
=
babyStageMap
.
find
((
i
)
=>
i
.
value
===
formData
.
value
.
babyStage
)?.
label
||
""
;
md
.
sensorUserLogTake
({
memberid
:
uni
.
getStorageSync
(
'memberId'
),
pregnancyStatus
:
pregnancyStatus
,
})
showLoading
();
const
res
=
await
updateBabyInfo
(
data
);
...
...
@@ -846,9 +760,11 @@ watch(
<
style
lang=
"less"
scoped
>
@import "@/common.less";
.person-page {
background-color: #f6f8fa;
min-height: 100vh;
.icon-return {
width: 20rpx;
height: 32rpx;
...
...
@@ -870,6 +786,7 @@ watch(
.person-header {
position: relative;
height: 463rpx;
.banner_bg {
width: 100%;
height: 100%;
...
...
@@ -942,6 +859,7 @@ watch(
position: relative;
z-index: 2;
box-sizing: border-box;
.form-row {
display: flex;
align-items: center;
...
...
@@ -958,11 +876,13 @@ watch(
width: 250rpx;
color: #222;
font-size: 28rpx;
.required {
color: #b88a3a;
margin-left: -4rpx;
}
}
.form-input {
flex: 1;
color: #6f6d67;
...
...
@@ -998,6 +918,7 @@ watch(
justify-content: center;
width: 100%;
height: 80rpx;
.form-bottom-text {
font-size: 28rpx;
color: #6f6d67;
...
...
@@ -1015,6 +936,7 @@ watch(
height: 300rpx;
width: 100%;
}
.form-btn {
width: 686rpx;
height: 94rpx;
...
...
pages/postnatalCheckUp/postnatalCheckUp.vue
View file @
821b80a8
...
...
@@ -114,11 +114,12 @@
</view>
<!-- 提示弹窗 -->
<popup-tip
v-if=
"isTip"
type=
"2"
@
statusChange=
"onBabyChange"
@
close=
"isTip = false"
></popup-tip>
<popup-tip
v-if=
"isTip"
type=
"2"
@
statusChange=
"onBabyChange"
@
afterPhone=
"isShowRegisterLayer = true"
:isNotLogin=
"isNotLogin"
@
close=
"isTip = false"
></popup-tip>
<RegisterLayer
v-model=
"isShowRegisterLayer"
@
confirm=
"onRegisterConfirm"
/>
<!-- 使用封装后的日期选择器组件 -->
<DatePicker
v-model:visible=
"visible"
:default-date=
"time"
@
confirm=
"handleDateConfirm"
/>
<DatePicker
v-model:visible=
"visible"
:default-date=
"time"
@
confirm=
"handleDateConfirm"
/>
</view>
</view>
</template>
...
...
@@ -133,7 +134,9 @@ import {
}
from
'vue'
import
{
onLoad
,
onShow
onShow
,
onShareAppMessage
,
onShareTimeline
}
from
'@dcloudio/uni-app'
import
{
jump
,
...
...
@@ -150,6 +153,7 @@ import {
}
from
'../../api/obstetric.js'
;
// 导入日期选择器组件
import
DatePicker
from
'@/components/DatePicker.vue'
import
RegisterLayer
from
'@/components/RegisterLayer.vue'
const
{
proxy
}
=
getCurrentInstance
();
...
...
@@ -168,6 +172,8 @@ const isWxNotification = ref(true)
// 提示弹窗
const
isTip
=
ref
(
false
)
const
isNotLogin
=
ref
(
false
);
const
isShowRegisterLayer
=
ref
(
false
)
// 弹窗控制
const
showPicker
=
ref
(
false
)
...
...
@@ -562,8 +568,19 @@ const onBabyChange = () => {
publicFn
()
}
// 公共函数
const
publicFn
=
()
=>
{
console
.
log
(
"🚀 ~ onShow ~ userStore:"
,
userStore
.
babyInfo
)
const
publicFn
=
async
()
=>
{
await
userStore
.
loadUserInfo
()
console
.
log
(
"🚀 ~ onShow ~ userStore:"
,
userStore
.
userInfo
)
isNotLogin
.
value
=
false
;
if
(
userStore
?.
userInfo
?.
memberId
&&
userStore
?.
userInfo
?.
memberId
==
"not_login"
||
!
userStore
.
userInfo
)
{
isNotLogin
.
value
=
true
;
}
const
babyInfo
=
userStore
.
babyInfo
if
(
babyInfo
&&
babyInfo
.
babyStage
==
1
)
{
isTip
.
value
=
false
...
...
@@ -577,6 +594,11 @@ const publicFn = () => {
isTip
.
value
=
true
}
}
const
onRegisterConfirm
=
async
()
=>
{
isShowRegisterLayer
.
value
=
false
;
await
userStore
.
loadBabyInfo
()
publicFn
()
}
onShow
(
async
()
=>
{
await
userStore
.
loadBabyInfo
()
console
.
log
(
'宝宝信息加载完成:'
,
userStore
.
babyInfo
)
...
...
@@ -589,6 +611,24 @@ onMounted(() => {
pageName
:
"产检提醒首页"
});
})
onShareAppMessage
(()
=>
{
return
{
title
:
"产检工具:孕检项目全掌握,产检日程不错过"
,
path
:
"/pages/postnatalCheckUp/postnatalCheckUp"
,
imageUrl
:
$baseUrl
+
"share/chanjian.png"
,
}
});
onShareTimeline
(()
=>
{
return
{
title
:
"产检工具:孕检项目全掌握,产检日程不错过"
,
path
:
"/pages/postnatalCheckUp/postnatalCheckUp"
,
imageUrl
:
$baseUrl
+
"share/chanjian.png"
,
}
});
</
script
>
<
style
lang=
"less"
scoped
>
...
...
pages/shengzhangTestResult/shengzhangTestResult.vue
View file @
821b80a8
...
...
@@ -307,7 +307,7 @@
</
template
>
<
script
setup
>
import
{
ref
,
onMounted
}
from
'vue'
import
{
ref
,
onMounted
,
getCurrentInstance
}
from
'vue'
import
{
onLoad
,
onShareAppMessage
}
from
"@dcloudio/uni-app"
;
import
{
useShengzhangStore
}
from
'../../stores/shengzhangResult.js'
;
import
{
formatDate
,
jump
,
JumpType
}
from
'../../utils/index.js'
;
...
...
@@ -320,7 +320,8 @@ import md from '../../md';
const
isRecords
=
ref
(
false
);
const
shareText
=
ref
(
''
)
const
{
proxy
}
=
getCurrentInstance
();
const
$baseUrl
=
proxy
.
$baseUrl
;
onLoad
((
options
)
=>
{
isRecords
.
value
=
options
.
isRecords
;
// activeTab.value = isRecords.value ? 'history' : 'latest';
...
...
@@ -699,9 +700,9 @@ const backFailHandler = () => {
onShareAppMessage
(()
=>
{
return
{
title
:
shareText
.
value
,
title
:
shareText
.
value
||
"生长测评:精准评估宝宝发育水平"
,
path
:
`/pages/shengzhangTestResult/shengzhangTestResult`
,
imageUrl
:
''
imageUrl
:
$baseUrl
+
"share/shengzhang.png"
,
}
})
...
...
@@ -713,10 +714,21 @@ onMounted(async () => {
xcxPage
:
"测评结果页"
,
pageName
:
"测评结果页"
});
const
userStore
=
useUserStore
();
//获取历史记录
const
historyListData
=
await
getGrowthHistoryList
();
console
.
log
(
userStore
.
babyInfo
?.
content
?.
id
+
'--------------------'
,
shengzhangStore
?.
getGrowthCurveDataInfoHeight
?.
userDataPoints
)
if
(
!
userStore
.
babyInfo
?.
content
?.
id
){
jump
({
type
:
JumpType
.
INNER
,
url
:
"/pages/shengzhangTools/shengzhangTools"
})
return
;
}
if
(
!
historyListData
.
success
||
(
!
historyListData
.
data
||
historyListData
.
data
.
length
==
0
)){
showNoValBg
.
value
=
true
;
return
;
...
...
@@ -761,7 +773,7 @@ onMounted(async () => {
}
}
const
userStore
=
useUserStore
();
const
babyId
=
userStore
.
babyInfo
?.
content
?.
id
;
const
babyDataHeight
=
{
...
...
pages/shengzhangTools/shengzhangTools.vue
View file @
821b80a8
<
template
>
<view
class=
"shengzhang-tools-container"
>
<swiper
class=
"banner-swiper"
:indicator-dots=
"swiperData?.length > 1"
:autoplay=
"swiperData?.length > 1"
:circular=
"swiperData?.length > 1"
indicator-color=
"#dfddd9"
indicator-active-color=
"#b27c1e"
:indicator-top=
"596"
v-if=
"swiperData && swiperData?.length > 0"
>
<swiper
class=
"banner-swiper"
:indicator-dots=
"swiperData?.length > 1"
:autoplay=
"swiperData?.length > 1"
:circular=
"swiperData?.length > 1"
indicator-color=
"#dfddd9"
indicator-active-color=
"#b27c1e"
:indicator-top=
"596"
v-if=
"swiperData && swiperData?.length > 0"
>
<swiper-item
v-for=
"(item, index) in swiperData"
:key=
"index"
>
<image
class=
"banner-img"
:src=
"`$
{$baseUrl}${item?.img}`"
mode="aspectFill"
@click="bannerHandler(item, index)"
/>
<image
class=
"banner-img"
:src=
"`$
{$baseUrl}${item?.img}`" mode="aspectFill"
@click="bannerHandler(item, index)" />
</swiper-item>
</swiper>
...
...
@@ -26,16 +15,21 @@
<!-- 顶部宝宝信息区域 -->
<view
class=
"baby-info-section"
>
<view
class=
"baby-avatar"
>
<image
class=
"avatar-img"
:src=
"babyAvatar ? babyAvatar : `https://course.feihe.com/momclub-picture/common/default_avatar.png`"
mode=
"aspectFill"
></image>
<image
class=
"avatar-img"
:src=
"babyAvatar ? babyAvatar : `https://course.feihe.com/momclub-picture/common/default_avatar.png`"
mode=
"aspectFill"
></image>
</view>
<view
class=
"baby-details"
>
<view
class=
"baby-name-row"
>
<text
class=
"baby-name"
>
{{
babyName
}}
</text>
<image
class=
"change-baby-btn"
@
click=
"changeBaby"
:src=
"`$
{$baseUrl}shengzhangTool/1001/changeBaby.png`" mode="aspectFit">
</image>
<image
class=
"change-baby-btn"
@
click=
"changeBaby"
:src=
"`$
{$baseUrl}shengzhangTool/1001/changeBaby.png`" mode="aspectFit">
</image>
</view>
<view
class=
"baby-info-row"
>
<view
class=
"gender-age"
>
<image
class=
"gender-icon"
:src=
"babyGender == 'M' ? `$
{$baseUrl}shengzhangTool/1001/sex1.png` : `${$baseUrl}shengzhangTool/1001/sex0.png`" mode="aspectFit">
</image>
<image
class=
"gender-icon"
:src=
"babyGender == 'M' ? `$
{$baseUrl}shengzhangTool/1001/sex1.png` : `${$baseUrl}shengzhangTool/1001/sex0.png`"
mode="aspectFit">
</image>
<text
class=
"age-text"
>
{{
babyAge
}}
</text>
</view>
<text
class=
"birth-date"
>
{{
formatDate
(
babyBirthday
)
}}
</text>
...
...
@@ -43,7 +37,8 @@
</view>
<view
class=
"record-btn"
@
click=
"viewRecords"
>
<text
class=
"record-text"
>
测评记录
</text>
<image
class=
"arrow-icon"
:src=
"`$
{$baseUrl}shengzhangTool/1001/close.png`" mode="aspectFit">
</image>
<image
class=
"arrow-icon"
:src=
"`$
{$baseUrl}shengzhangTool/1001/close.png`" mode="aspectFit">
</image>
</view>
</view>
...
...
@@ -56,7 +51,8 @@
<text
class=
"label"
>
本次测评日期
</text>
<view
class=
"date-container"
@
click=
"showDatePicker"
>
<text
class=
"date-value"
>
{{
selectedDate
}}
</text>
<image
class=
"edit-icon"
:src=
"`$
{$baseUrl}shengzhangTool/1001/editIcon.png`" mode="aspectFit">
</image>
<image
class=
"edit-icon"
:src=
"`$
{$baseUrl}shengzhangTool/1001/editIcon.png`" mode="aspectFit">
</image>
</view>
</view>
<!-- 分割线 -->
...
...
@@ -66,7 +62,8 @@
<text
class=
"label"
>
宝宝喂养方式
</text>
<view
class=
"feeding-select"
@
click=
"showFeedingPopup"
>
<text
class=
"feeding-value"
>
{{
selectedFeedText
}}
</text>
<image
class=
"dropdown-icon"
:src=
"`$
{$baseUrl}shengzhangTool/1001/close.png`" mode="aspectFit">
</image>
<image
class=
"dropdown-icon"
:src=
"`$
{$baseUrl}shengzhangTool/1001/close.png`" mode="aspectFit">
</image>
</view>
</view>
</view>
...
...
@@ -89,15 +86,12 @@
<view
class=
"input-section"
>
<view
class=
"input-item"
>
<view
class=
"input-container"
>
<image
class=
"input-bg"
:src=
"`$
{$baseUrl}shengzhangTool/1001/numBg.png`" mode="aspectFit">
</image>
<picker-view
class=
"measurement-picker"
:class=
"
{ 'measurement-picker-disabled': isHeightTipActive }"
:value="heightPickerValue"
@change="onHeightChange"
:indicator-style="indicatorStyle"
indicator-class="date-picker"
>
<image
class=
"input-bg"
:src=
"`$
{$baseUrl}shengzhangTool/1001/numBg.png`" mode="aspectFit">
</image>
<picker-view
class=
"measurement-picker"
:class=
"
{ 'measurement-picker-disabled': isHeightTipActive }" :value="heightPickerValue"
@change="onHeightChange" :indicator-style="indicatorStyle"
indicator-class="date-picker">
<picker-view-column>
<view
v-for=
"(item, index) in heightRange"
:key=
"index"
class=
"picker-item"
>
{{
item
}}
...
...
@@ -105,30 +99,20 @@
</picker-view-column>
</picker-view>
<!-- 身高输入框 -->
<input
class=
"measurement-input"
type=
"number"
:value=
"height"
@
input=
"onHeightInput"
@
blur=
"onHeightBlur"
@
focus=
"onHeightFocus"
:disabled=
"isHeightTipActive"
:style=
"`background-image: url($
{$baseUrl}shengzhangTool/1001/numBg.png); background-size: 100% 100%; background-repeat: no-repeat;`"
/>
<input
class=
"measurement-input"
type=
"number"
:value=
"height"
@
input=
"onHeightInput"
@
blur=
"onHeightBlur"
@
focus=
"onHeightFocus"
:disabled=
"isHeightTipActive"
:style=
"`background-image: url($
{$baseUrl}shengzhangTool/1001/numBg.png); background-size: 100% 100%; background-repeat: no-repeat;`" />
<text
class=
"unit"
>
cm
</text>
</view>
</view>
<view
class=
"input-item"
>
<view
class=
"input-container"
>
<image
class=
"input-bg"
:src=
"`$
{$baseUrl}shengzhangTool/1001/numBg.png`" mode="aspectFit">
</image>
<picker-view
class=
"measurement-picker"
:class=
"
{ 'measurement-picker-disabled': isWeightTipActive }"
:value="weightPickerValue"
@change="onWeightChange"
:indicator-style="indicatorStyle"
indicator-class="date-picker"
>
<image
class=
"input-bg"
:src=
"`$
{$baseUrl}shengzhangTool/1001/numBg.png`" mode="aspectFit">
</image>
<picker-view
class=
"measurement-picker"
:class=
"
{ 'measurement-picker-disabled': isWeightTipActive }" :value="weightPickerValue"
@change="onWeightChange" :indicator-style="indicatorStyle"
indicator-class="date-picker">
<picker-view-column>
<view
v-for=
"(item, index) in weightRange"
:key=
"index"
class=
"picker-item"
>
{{
item
}}
...
...
@@ -136,30 +120,19 @@
</picker-view-column>
</picker-view>
<!-- 体重输入框 -->
<input
class=
"measurement-input"
type=
"number"
:value=
"weight"
@
input=
"onWeightInput"
@
blur=
"onWeightBlur"
@
focus=
"onWeightFocus"
:disabled=
"isWeightTipActive"
:style=
"`background-image: url($
{$baseUrl}shengzhangTool/1001/numBg.png); background-size: 100% 100%; background-repeat: no-repeat;`"
/>
<input
class=
"measurement-input"
type=
"number"
:value=
"weight"
@
input=
"onWeightInput"
@
blur=
"onWeightBlur"
@
focus=
"onWeightFocus"
:disabled=
"isWeightTipActive"
:style=
"`background-image: url($
{$baseUrl}shengzhangTool/1001/numBg.png); background-size: 100% 100%; background-repeat: no-repeat;`" />
<text
class=
"unit"
>
kg
</text>
</view>
</view>
<view
class=
"input-item"
>
<view
class=
"input-container"
>
<image
class=
"input-bg"
:src=
"`$
{$baseUrl}shengzhangTool/1001/numBg.png`" mode="aspectFit">
</image>
<picker-view
class=
"measurement-picker"
:class=
"
{ 'measurement-picker-disabled': isHeadTipActive }"
:value="headPickerValue"
@change="onHeadChange"
:indicator-style="indicatorStyle"
indicator-class="date-picker"
>
<image
class=
"input-bg"
:src=
"`$
{$baseUrl}shengzhangTool/1001/numBg.png`" mode="aspectFit">
</image>
<picker-view
class=
"measurement-picker"
:class=
"
{ 'measurement-picker-disabled': isHeadTipActive }" :value="headPickerValue"
@change="onHeadChange" :indicator-style="indicatorStyle" indicator-class="date-picker">
<picker-view-column>
<view
v-for=
"(item, index) in headRange"
:key=
"index"
class=
"picker-item"
>
{{
item
}}
...
...
@@ -167,16 +140,9 @@
</picker-view-column>
</picker-view>
<!-- 头围输入框 -->
<input
class=
"measurement-input"
type=
"number"
:value=
"headCircumference"
@
input=
"onHeadInput"
@
blur=
"onHeadBlur"
@
focus=
"onHeadFocus"
:disabled=
"isHeadTipActive"
:style=
"`background-image: url($
{$baseUrl}shengzhangTool/1001/numBg.png); background-size: 100% 100%; background-repeat: no-repeat;`"
/>
<input
class=
"measurement-input"
type=
"number"
:value=
"headCircumference"
@
input=
"onHeadInput"
@
blur=
"onHeadBlur"
@
focus=
"onHeadFocus"
:disabled=
"isHeadTipActive"
:style=
"`background-image: url($
{$baseUrl}shengzhangTool/1001/numBg.png); background-size: 100% 100%; background-repeat: no-repeat;`" />
<text
class=
"unit"
>
cm
</text>
</view>
</view>
...
...
@@ -199,7 +165,8 @@
<!-- 提交按钮 -->
<view
class=
"submit-section"
>
<view
class=
"submit-btn"
@
click=
"submitData"
>
<image
class=
"submit-bg"
:src=
"`$
{$baseUrl}shengzhangTool/1001/submitBtn.png`" mode="aspectFit">
</image>
<image
class=
"submit-bg"
:src=
"`$
{$baseUrl}shengzhangTool/1001/submitBtn.png`" mode="aspectFit">
</image>
<!--
<text
class=
"submit-text"
>
确认提交
</text>
-->
</view>
<view
class=
"bottom-tip"
@
click=
"onClickTips"
>
...
...
@@ -209,14 +176,18 @@
</view>
</view>
<view
class=
"guide-container"
v-if=
"guideIndex != -1"
@
click=
"guideHandler"
>
<image
v-if=
"guideIndex == 0"
class=
"guide-img0"
:src=
"`$
{$baseUrl}shengzhangTool/1001/guide0.png`" mode="aspectFit">
</image>
<image
v-if=
"guideIndex == 1"
class=
"guide-img1"
:src=
"`$
{$baseUrl}shengzhangTool/1001/guide1-2.png`" mode="aspectFit">
</image>
<image
v-if=
"guideIndex == 2"
class=
"guide-img2"
:src=
"`$
{$baseUrl}shengzhangTool/1001/guide2.png`" mode="aspectFit">
</image>
<image
v-if=
"guideIndex == 0"
class=
"guide-img0"
:src=
"`$
{$baseUrl}shengzhangTool/1001/guide0.png`"
mode="aspectFit">
</image>
<image
v-if=
"guideIndex == 1"
class=
"guide-img1"
:src=
"`$
{$baseUrl}shengzhangTool/1001/guide1-2.png`"
mode="aspectFit">
</image>
<image
v-if=
"guideIndex == 2"
class=
"guide-img2"
:src=
"`$
{$baseUrl}shengzhangTool/1001/guide2.png`"
mode="aspectFit">
</image>
</view>
<view
class=
"loading-container"
v-if=
"showLoading"
>
<view
class=
"loading-content"
>
<view
class=
"star-container"
>
<image
class=
"loading-star"
:src=
"`$
{$baseUrl}shengzhangTool/1001/loadingActImg.png`" mode="aspectFit">
</image>
<image
class=
"loading-star"
:src=
"`$
{$baseUrl}shengzhangTool/1001/loadingActImg.png`"
mode="aspectFit">
</image>
</view>
<view
class=
"loading-text"
>
<text
class=
"loading-title"
>
正在计算宝宝的生长测评得分
</text>
...
...
@@ -227,49 +198,42 @@
</view>
<!-- 在页面底部添加弹窗组件 -->
<BabySwitchPopup
v-model:visible=
"showBabySwitchPopup"
:babyList=
"babyList"
v-model:selectedIndex=
"currentBabyIndex"
@
change=
"onBabyChange"
/>
<BabySwitchPopup
v-model:visible=
"showBabySwitchPopup"
:babyList=
"babyList"
v-model:selectedIndex=
"currentBabyIndex"
@
change=
"onBabyChange"
/>
<!-- 喂养方式弹窗 -->
<BabyFeedSwitchPopup
v-model:visible=
"showFeedSwitchPopup"
v-model:selectedIndex=
"currentFeedIndex"
@
change=
"onFeedChange"
/>
<BabyFeedSwitchPopup
v-model:visible=
"showFeedSwitchPopup"
v-model:selectedIndex=
"currentFeedIndex"
@
change=
"onFeedChange"
/>
<!-- 日期选择弹窗 -->
<DatePickerPopup
v-model:visible=
"showDatePickerPopup"
v-model:selectedDate=
"selectedDate"
v-model:babyBirthday=
"babyBirthday"
@
change=
"onDateChange"
/>
<DatePickerPopup
v-model:visible=
"showDatePickerPopup"
v-model:selectedDate=
"selectedDate"
v-model:babyBirthday=
"babyBirthday"
@
change=
"onDateChange"
/>
<!-- 宝宝测评提示弹窗 -->
<BabyTestTipsPopup
v-model:visible=
"showBabyTestTipsPopup
"
/
>
<
popup-tip
v-if=
"isTip"
type=
"1"
@
statusChange=
"onBabyChange1"
@
close=
"isTip = false"
></popup-tip
>
<BabyTestTipsPopup
v-model:visible=
"showBabyTestTipsPopup"
/>
<popup-tip
v-if=
"isTip"
type=
"1"
@
statusChange=
"onBabyChange1"
@
afterPhone=
"isShowRegisterLayer = true
"
@
close=
"isTip = false"
:isNotLogin=
"isNotLogin"
></popup-tip
>
<
RegisterLayer
v-model=
"isShowRegisterLayer"
@
confirm=
"onRegisterConfirm"
/
>
</
template
>
<
script
setup
>
import
{
onMounted
,
ref
}
from
'vue'
import
{
onMounted
,
ref
,
getCurrentInstance
,
watch
}
from
'vue'
import
BabySwitchPopup
from
'@/components/BabySwitchPopup.vue'
import
BabyFeedSwitchPopup
from
'@/components/BabyFeedSwitchPopup.vue'
import
DatePickerPopup
from
'@/components/DatePickerPopup.vue'
import
BabyTestTipsPopup
from
'@/components/BabyTestTipsPopup.vue'
import
{
growthHome
,
guideCompleted
,
getGrowthCurveData
,
fetchShengzhangToolsJSON
}
from
'../../api/shengzhangTools'
import
{
onLoad
,
onShow
}
from
"@dcloudio/uni-app"
;
import
{
throttleTap
,
jump
,
JumpType
,
formatDate
}
from
'../../utils/index.js'
;
import
{
growthHome
,
guideCompleted
,
getGrowthCurveData
,
fetchShengzhangToolsJSON
}
from
'../../api/shengzhangTools'
import
{
onLoad
,
onShow
,
onShareAppMessage
,
onShareTimeline
}
from
"@dcloudio/uni-app"
;
import
{
throttleTap
,
jump
,
JumpType
,
formatDate
}
from
'../../utils/index.js'
;
import
{
useShengzhangStore
}
from
'../../stores/shengzhangResult.js'
;
import
{
useUserStore
}
from
"@/stores/user"
;
import
md
from
'../../md'
;
import
{
RegisterLayer
}
from
'@/components/RegisterLayer.vue'
;
import
{
storeToRefs
}
from
'pinia'
const
isTip
=
ref
(
false
);
const
isNotLogin
=
ref
(
false
);
const
isShowRegisterLayer
=
ref
(
false
);
const
babyName
=
ref
(
'宝宝名称'
)
const
babyAge
=
ref
(
'8月龄'
)
...
...
@@ -282,12 +246,13 @@ const shengzhangStore = useShengzhangStore();
const
guideFlag
=
ref
(
false
);
const
showLoading
=
ref
(
false
);
const
{
proxy
}
=
getCurrentInstance
();
const
$baseUrl
=
proxy
.
$baseUrl
;
const
bannerHandler
=
(
item
,
index
)
=>
{
console
.
log
(
item
)
let
buttonName
=
''
;
switch
(
index
)
{
switch
(
index
)
{
case
0
:
buttonName
=
'第一张焦点图'
;
break
;
...
...
@@ -308,7 +273,7 @@ const bannerHandler = (item, index) => {
buttonName
:
buttonName
,
});
if
(
item
?.
url
!=
""
)
{
if
(
item
?.
url
!=
""
)
{
jump
({
type
:
item
.
type
,
url
:
item
.
url
,
...
...
@@ -559,15 +524,15 @@ const viewRecords = () => {
}
const
convertFeedingType
=
(
type
)
=>
{
if
(
type
==
'纯母乳'
)
{
if
(
type
==
'纯母乳'
)
{
return
'BREAST_MILK'
}
else
if
(
type
==
'母乳+奶粉混合喂养'
)
{
}
else
if
(
type
==
'母乳+奶粉混合喂养'
)
{
return
'MIXED'
}
else
if
(
type
==
'奶粉'
)
{
}
else
if
(
type
==
'奶粉'
)
{
return
'FORMULA'
}
else
if
(
type
==
'母乳+辅食'
)
{
}
else
if
(
type
==
'母乳+辅食'
)
{
return
'BREAST_MILK_CF'
}
else
if
(
type
==
'奶粉+辅食'
)
{
}
else
if
(
type
==
'奶粉+辅食'
)
{
return
'FORMULA_CF'
}
}
...
...
@@ -580,7 +545,7 @@ const submitData = throttleTap(async () => {
showLoading
.
value
=
true
;
if
(
headCircumference
.
value
==
0
)
{
if
(
headCircumference
.
value
==
0
)
{
headCircumference
.
value
=
null
;
}
const
submitData
=
{
...
...
@@ -595,9 +560,9 @@ const submitData = throttleTap(async () => {
await
shengzhangStore
.
assessmentSave
(
submitData
);
if
(
shengzhangStore
.
shengzhangInfo
.
success
)
{
if
(
shengzhangStore
.
shengzhangInfo
.
success
)
{
babyId
.
value
=
shengzhangStore
.
shengzhangInfo
.
babyId
;
}
else
{
}
else
{
showLoading
.
value
=
false
;
return
;
}
...
...
@@ -629,7 +594,7 @@ const submitData = throttleTap(async () => {
//跳转测评结果页
if
(
shengzhangStore
.
shengzhangInfo
.
success
)
{
if
(
shengzhangStore
.
shengzhangInfo
.
success
)
{
jump
({
type
:
JumpType
.
INNER
,
url
:
"/pages/shengzhangTestResult/shengzhangTestResult"
...
...
@@ -704,11 +669,11 @@ const toggleHeadTip = () => {
pushCount
(
2
)
isHeadTipActive
.
value
=
!
isHeadTipActive
.
value
if
(
isHeadTipActive
.
value
)
{
if
(
isHeadTipActive
.
value
)
{
// 不改变输入框的值,只标记为暂无数据状态
tempHeadCircumference
.
value
=
headCircumference
.
value
;
headCircumference
.
value
=
0
;
}
else
{
}
else
{
// 恢复原来的值
headCircumference
.
value
=
tempHeadCircumference
.
value
;
}
...
...
@@ -758,22 +723,33 @@ const guideHandler = async () => {
if
(
guideIndex
.
value
>
2
)
{
const
data
=
await
guideCompleted
();
if
(
data
.
success
)
{
if
(
data
.
success
)
{
guideFlag
.
value
=
true
;
guideIndex
.
value
=
-
1
;
}
else
{
}
else
{
//引导页完成失败,提示用户
}
}
}
const
userStore
=
useUserStore
();
const
{
babyInfo
}
=
storeToRefs
(
userStore
)
// 获取页面参数
onLoad
((
options
)
=>
{
if
(
options
.
babyId
)
{
babyId
.
value
=
parseInt
(
options
.
babyId
)
console
.
log
(
'获取到的babyId:'
,
babyId
.
value
)
}
})
watch
(
babyInfo
,
async
(
newVal
,
oldVal
)
=>
{
console
.
log
(
oldVal
,
'-----babyId发生变化,重新获取数据'
,
newVal
)
if
((
!
oldVal
||
!
oldVal
?.
content
?.
id
)
&&
newVal
?.
content
?.
id
){
console
.
log
(
'start重新获取数据'
,
newVal
)
await
babyRefresh
();
}
})
onShow
(
async
()
=>
{
...
...
@@ -781,54 +757,15 @@ onShow(async () => {
})
// 提示弹窗回调
const
onBabyChange1
=
async
()
=>
{
const
onRegisterConfirm
=
async
()
=>
{
isShowRegisterLayer
.
value
=
false
;
await
babyRefresh
();
}
const
babyRefresh
=
async
()
=>
{
const
userStore
=
useUserStore
();
const
babyInfo
=
userStore
.
babyInfo
;
if
(
babyInfo
&&
babyInfo
.
babyStage
==
2
){
isTip
.
value
=
false
await
refreshBabyInfo
();
}
else
{
isTip
.
value
=
true
;
}
// 提示弹窗回调
const
onBabyChange1
=
async
()
=>
{
await
babyRefresh
();
}
const
shengzhangToolsData
=
ref
({
activeInfo
:[
{
"img"
:
"shengzhangTool/1001/banner1.png"
,
"url"
:
"subPackages/shopMainList/topicNew/index?id=1000911"
,
"type"
:
2
,
"extra"
:
{
"appId"
:
"wx4205ec55b793245e"
,
"envVersion"
:
"release"
}
}
]
});
const
swiperData
=
ref
([]);
onMounted
(
async
()
=>
{
md
.
sensorLogTake
({
xcxPage
:
"生长曲线首页"
,
pageName
:
"生长曲线首页"
});
const
{
data
}
=
await
fetchShengzhangToolsJSON
();
if
(
data
){
shengzhangToolsData
.
value
=
{...
data
};
}
else
{
shengzhangToolsData
.
value
=
{
activeInfo
:[]};
}
swiperData
.
value
=
shengzhangToolsData
?.
value
?.
activeInfo
||
[];
})
const
refreshBabyInfo
=
async
()
=>
{
const
userStore
=
useUserStore
();
babyId
.
value
=
userStore
.
babyInfo
?.
content
?.
id
;
...
...
@@ -844,7 +781,7 @@ const refreshBabyInfo = async () => {
// (item) => item.selected
// );
const
{
data
}
=
await
growthHome
(
babyId
.
value
);
const
{
data
}
=
await
growthHome
(
babyId
.
value
);
selectedDate
.
value
=
formatDate
(
new
Date
());
// const data = {"babyId":1234,"babyName":"小强","gender":"M","monthAge":3,"avatar":"https://momclub.feihe.com/pmall/momclub-picture/integral/1009/yuerBtn.png","birthDate":"2018-10-28 14:06:45","guideFlag":false};
...
...
@@ -869,6 +806,80 @@ const refreshBabyInfo = async () => {
// }
}
const
babyRefresh
=
async
()
=>
{
const
userStore
=
useUserStore
();
await
userStore
.
loadBabyInfo
();
const
babyInfo
=
userStore
.
babyInfo
;
isNotLogin
.
value
=
false
;
isTip
.
value
=
false
if
(
userStore
?.
userInfo
?.
memberId
&&
userStore
?.
userInfo
?.
memberId
==
"not_login"
||
!
userStore
.
userInfo
)
{
isNotLogin
.
value
=
true
;
}
console
.
log
(
babyInfo
?.
babyStage
+
'--------------------'
,
babyInfo
)
if
(
babyInfo
&&
babyInfo
.
babyStage
==
2
)
{
isTip
.
value
=
false
await
refreshBabyInfo
();
}
else
{
isTip
.
value
=
true
;
}
}
const
shengzhangToolsData
=
ref
({
activeInfo
:
[
{
"img"
:
"shengzhangTool/1001/banner1.png"
,
"url"
:
"subPackages/shopMainList/topicNew/index?id=1000911"
,
"type"
:
2
,
"extra"
:
{
"appId"
:
"wx4205ec55b793245e"
,
"envVersion"
:
"release"
}
}
]
});
const
swiperData
=
ref
([]);
onMounted
(
async
()
=>
{
md
.
sensorLogTake
({
xcxPage
:
"生长曲线首页"
,
pageName
:
"生长曲线首页"
});
const
{
data
}
=
await
fetchShengzhangToolsJSON
();
if
(
data
)
{
shengzhangToolsData
.
value
=
{
...
data
};
}
else
{
shengzhangToolsData
.
value
=
{
activeInfo
:
[]
};
}
swiperData
.
value
=
shengzhangToolsData
?.
value
?.
activeInfo
||
[];
})
onShareAppMessage
(()
=>
{
return
{
title
:
"生长测评:精准评估宝宝发育水平"
,
path
:
"/pages/shengzhangTools/shengzhangTools"
,
imageUrl
:
$baseUrl
+
"share/shengzhang.png"
,
}
});
onShareTimeline
(()
=>
{
return
{
title
:
"生长测评:精准评估宝宝发育水平"
,
path
:
"/pages/shengzhangTools/shengzhangTools"
,
imageUrl
:
$baseUrl
+
"share/shengzhang.png"
,
}
});
</
script
>
...
...
@@ -1292,28 +1303,31 @@ const refreshBabyInfo = async () => {
}
}
.guide-container{
.guide-container
{
position: absolute;
top: 0;
bottom: 0;
width: 100%;
height: 100%;
z-index: 1000;
.guide-img0{
.guide-img0 {
width: 100%;
height: 1624rpx;
position: absolute;
top: 0;
left: 0;
}
.guide-img1{
.guide-img1 {
width: 100%;
height: 1624rpx;
position: absolute;
top: 0;
left: 0;
}
.guide-img2{
.guide-img2 {
width: 100%;
height: 1624rpx;
position: absolute;
...
...
@@ -1383,9 +1397,11 @@ const refreshBabyInfo = async () => {
0% {
opacity: 0.6;
}
50% {
opacity: 1;
}
100% {
opacity: 0.6;
}
...
...
pages/xingmaLab/xingmaLab.vue
View file @
821b80a8
...
...
@@ -29,8 +29,11 @@
<view
class=
"item_cangguan_img1"
:style=
"`background-image: url($
{item.imgUrl}); background-size: 707rpx auto; background-repeat: no-repeat;`"
mode="widthFix">
<image
class=
"item_cangguan_img"
:src=
"`$
{item.imgUrl}`" mode="widthFix" @load="(e) => handleImageLoad(e, item, index)">
</image>
<image
class=
"item_cangguan_img_up"
:src=
"`$
{item.imgUrl}`" mode="aspectFill" :style="`width: ${item.targetWidth - 30}rpx; height: ${item.targetHeight - 120}rpx;`">
</image>
<image
class=
"item_cangguan_img"
:src=
"`$
{item.imgUrl}`" mode="widthFix"
@load="(e) => handleImageLoad(e, item, index)">
</image>
<image
class=
"item_cangguan_img_up"
:src=
"`$
{item.imgUrl}`" mode="aspectFill"
:style="`width: ${item.targetWidth - 30}rpx; height: ${item.targetHeight - 120}rpx;`">
</image>
</view>
<view
class=
"item_cangguan_bottom"
>
...
...
@@ -357,19 +360,19 @@ onShow(async () => {
console
.
log
(
'currentPage='
,
currentPage
);
// console.log('onshow')
//1收藏,-1取消收藏,不存在刷新页面
if
(
!
isFavorite
)
{
if
(
!
isFavorite
)
{
await
xingmaLabStore
.
loadXingmaInfo
();
await
reloadCangguanList
();
await
reloadCangpinList
();
await
reloadShoucangList
();
}
else
{
if
(
isFavorite
==
1
)
{
}
else
{
if
(
isFavorite
==
1
)
{
currentItem
.
value
.
collection
=
true
;
}
else
{
if
(
currentItemType
.
value
==
'cangguan'
)
{
}
else
{
if
(
currentItemType
.
value
==
'cangguan'
)
{
currentItem
.
value
.
collection
=
false
;
}
else
{
}
else
{
shoucangList
.
value
.
splice
(
currentItem
.
value
,
1
)
}
}
...
...
@@ -477,9 +480,15 @@ const convertDobuleList = (list) => {
// 方法
const
handleBack
=
()
=>
{
if
(
getCurrentPages
().
length
>
1
)
{
uni
.
navigateBack
({
delta
:
1
})
}
else
{
uni
.
redirectTo
({
url
:
'/pages/index/index?pageType=my'
})
}
}
const
switchTab
=
(
tab
)
=>
{
...
...
@@ -491,8 +500,8 @@ const switchTab = (tab) => {
//我的藏品/我的收藏tab
const
switchSubTab
=
async
(
subTab
)
=>
{
if
(
subTab
==
'collections'
)
{
if
(
currentFrontNavType
!=
'collections'
)
{
if
(
subTab
==
'collections'
)
{
if
(
currentFrontNavType
!=
'collections'
)
{
currentFrontNavType
=
'collections'
md
.
sensorComponentLogTake
({
...
...
@@ -506,8 +515,8 @@ const switchSubTab = async (subTab) => {
}
}
else
if
(
subTab
==
'favorites'
)
{
if
(
currentFrontNavType
!=
'favorites'
)
{
}
else
if
(
subTab
==
'favorites'
)
{
if
(
currentFrontNavType
!=
'favorites'
)
{
md
.
sensorComponentLogTake
({
xcxComponentClick
:
"true"
,
pageName
:
"星妈lab首页"
,
...
...
@@ -570,7 +579,7 @@ const handleBottomNavClick = async (navType) => {
// 点击"星妈会藏馆"时,切换到藏馆tab,展示单列列表
activeTab
.
value
=
'cangguan'
if
(
currentButtomNavType
!=
'cangguan'
)
{
if
(
currentButtomNavType
!=
'cangguan'
)
{
md
.
sensorComponentLogTake
({
xcxComponentExposure
:
"true"
,
pageName
:
"星妈lab首页"
,
...
...
@@ -600,10 +609,10 @@ const handleBottomNavClick = async (navType) => {
// 点击"我的藏品"时,切换到我的藏馆tab,默认展示我的藏品
activeTab
.
value
=
'wodecangguan'
if
(
currentButtomNavType
!=
'wodecangguan'
)
{
if
(
currentButtomNavType
!=
'wodecangguan'
)
{
currentButtomNavType
=
'wodecangguan'
;
if
(
currentFrontNavType
==
''
)
{
if
(
!
(
cangpinList
.
value
&&
cangpinList
.
value
.
length
>
0
))
{
if
(
currentFrontNavType
==
''
)
{
if
(
!
(
cangpinList
.
value
&&
cangpinList
.
value
.
length
>
0
))
{
md
.
sensorComponentLogTake
({
xcxComponentExposure
:
"true"
,
pageName
:
"星妈lab-我的藏品页"
,
...
...
@@ -625,10 +634,10 @@ const handleBottomNavClick = async (navType) => {
currentFrontNavType
=
'collections'
// await reloadCangpinList();
}
else
{
}
else
{
currentFrontNavType
=
activeSubTab
.
value
;
if
(
activeSubTab
.
value
==
'collections'
)
{
if
(
!
(
cangpinList
.
value
&&
cangpinList
.
value
.
length
>
0
))
{
if
(
activeSubTab
.
value
==
'collections'
)
{
if
(
!
(
cangpinList
.
value
&&
cangpinList
.
value
.
length
>
0
))
{
md
.
sensorComponentLogTake
({
xcxComponentExposure
:
"true"
,
...
...
@@ -648,7 +657,7 @@ const handleBottomNavClick = async (navType) => {
// }
// await reloadCangpinList();
//走onshow刷新,因为去发布按钮埋点
}
else
{
}
else
{
// md.sensorComponentLogTake({
// xcxComponentExposure: "true",
// pageName: "星妈lab-我的藏品页",
...
...
@@ -729,12 +738,12 @@ const handlePublish = () => {
const
handleNoTimeButtonClick
=
()
=>
{
showNoTimePopup
.
value
=
false
// // 显示更详细的发布次数信息
// const { currentMonthPublishCount, maxPublishCount, remainingPublishCount } = xingmaLabStore.xingmaInfo
// uni.showToast({
// title: `本月已发布${currentMonthPublishCount}次,剩余${remainingPublishCount}次`,
// icon: 'none',
// duration: 3000
// // 显示更详细的发布次数信息
// const { currentMonthPublishCount, maxPublishCount, remainingPublishCount } = xingmaLabStore.xingmaInfo
// uni.showToast({
// title: `本月已发布${currentMonthPublishCount}次,剩余${remainingPublishCount}次`,
// icon: 'none',
// duration: 3000
// })
}
</
script
>
...
...
stores/user.js
View file @
821b80a8
...
...
@@ -71,7 +71,7 @@ export const useUserStore = defineStore("userInfo", {
* @param {Object} data : {encryptedData, iv, code}
* @returns
*/
async
phoneCallback
(
data
,
onOpenRegisterFn
=
()
=>
{
})
{
async
phoneCallback
(
data
,
onOpenRegisterFn
=
()
=>
{
}
,
cb
)
{
uni
.
login
({
provider
:
"weixin"
,
success
:
async
(
res
)
=>
{
...
...
@@ -86,7 +86,11 @@ export const useUserStore = defineStore("userInfo", {
code
:
data
.
code
,
codeLogin
:
res
.
code
,
});
!
babyExistence
&&
onOpenRegisterFn
&&
onOpenRegisterFn
();
if
(
!
babyExistence
.
value
&&
cb
)
{
cb
();
}
const
homeStore
=
useHomeStore
();
await
homeStore
.
setBabyExistence
(
babyExistence
);
...
...
utils/index.js
View file @
821b80a8
...
...
@@ -36,7 +36,7 @@ export function jump({ type, url, extra = {} }) {
console
.
log
(
"jumpParams:"
,
jumpParams
);
if
(
extra
.
embedded
){
if
(
extra
.
embedded
||
jumpParams
.
appId
===
'wx4205ec55b793245e'
){
// 星妈优选的小程序都为半屏拉起
uni
.
openEmbeddedMiniProgram
(
jumpParams
);
}
else
{
uni
.
navigateToMiniProgram
(
jumpParams
);
...
...
views/Home.vue
View file @
821b80a8
...
...
@@ -58,7 +58,7 @@
<swiper-item
v-for=
"(item, index) in toolList.tools"
:key=
"index"
:class=
"['swiperItem',
{ 'active': currentIndex === index }]">
<view
class=
"tool"
>
<button
v-if=
"homeStore && !homeStore.isLogin && item.title!='星妈起名' && item.title!='体质测试'"
<button
v-if=
"homeStore && !homeStore.isLogin && item.title!='星妈起名'
&& item.title!='喂养工具' && item.title!='产检提醒' && item.title!='宝宝生长测评'
&& item.title!='体质测试'"
open-type=
"getPhoneNumber"
@
getphonenumber=
"onGetPhoneNumber"
class=
"sq_btn"
></button>
<image
class=
"tool_bg"
:src=
"$baseUrl + item.icon"
@
tap=
"handleToolClick(item)"
>
</image>
...
...
views/My.vue
View file @
821b80a8
...
...
@@ -100,8 +100,9 @@
<view
class=
"tool-list"
>
<view
class=
"tool-item"
v-for=
"item in toolList"
:key=
"item.title"
@
click=
"handleToolClick(item)"
>
<image
class=
"tool-icon"
:src=
"$baseUrl + item.bgUrl"
mode=
"aspectFit"
/>
<!-- || item.title == '产检提醒' || item.title == '喂养记录' || item.title == '生长测评' -->
<button
v-if=
"(item.title == '医生问诊'
|| item.title == '产检提醒' || item.title == '喂养记录' || item.title == '生长测评'
) && !cfgStatus.isRegister"
v-if=
"(item.title == '医生问诊') && !cfgStatus.isRegister"
class=
"tool-btn-register"
type=
"primary"
open-type=
"getPhoneNumber"
@
getphonenumber=
"getRealtimePhoneNumber"
/>
</view>
...
...
@@ -268,7 +269,7 @@ const handleToolClick = async (item) => {
}
// 三个工具校验是否授权
else
if
(
item
.
title
===
"生长测评"
||
item
.
title
===
"喂养记录"
||
item
.
title
===
"产检提醒"
)
{
if
(
!
cfgStatus
.
value
.
isRegister
)
return
;
//
if (!cfgStatus.value.isRegister) return;
jump
({
type
:
item
.
link
.
type
,
url
:
item
.
link
.
url
});
}
else
{
...
...
@@ -404,6 +405,8 @@ const initData = async () => {
// 已出生或孕中显示
cfgStatus
.
value
.
showDetail
=
__showDetail
;
if
(
__showDetail
)
{
wheelOptions
.
value
=
babyInfo
.
value
.
babyStage
==
2
...
...
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