Commit 821b80a8 authored by spc's avatar spc

Merge branch 'master' into 20250901_915Act

parents 426127d7 21692b07
......@@ -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
......@@ -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
......@@ -6,7 +6,7 @@ const init = (SENSORS_URL) => {
sensors.setPara({
name: "sensors",
server_url: SENSORS_URL,
show_log: true,
show_log: false,
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
};
......@@ -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": {
......
{
"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
......@@ -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
......@@ -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()
}
})
// 定义分享函数
......
......@@ -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
<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;
......
......@@ -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>
......
......@@ -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 = {
......
<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;
}
......
......@@ -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>
......
......@@ -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);
......
......@@ -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);
......
......@@ -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>
......
......@@ -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
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment