leon hai 1 ano
pai
achega
b63494f889

+ 10 - 2
src/_health/pages/add_moment.tsx

@@ -12,8 +12,9 @@ import dayjs from "dayjs";
 import TimePicker from "@/features/common/TimePicker";
 import { MainColorType } from "@/context/themes/color";
 import { createMoment } from "@/services/health";
-import { useSelector } from "react-redux";
+import { useDispatch, useSelector } from "react-redux";
 import { getThemeColor } from "@/features/health/hooks/health_hooks";
+import { setShowActionTip } from "@/store/health";
 
 
 let useRoute;
@@ -33,7 +34,7 @@ export default function AddMoment() {
     const [endTime, setEndTime] = useState(0)
     const [showPicker, setShowPicker] = useState(false)
     const [durationPicker, setDurationPicker] = useState(false)
-
+    const dispatch = useDispatch()
     const health = useSelector((state: any) => state.health);
 
 
@@ -163,6 +164,13 @@ export default function AddMoment() {
                 Taro.navigateBack();
             }
 
+            if (health.mode == 'EAT') {
+                dispatch(setShowActionTip({
+                    isShow: true,
+                    isCompleted: false
+                }))
+            }
+
             global.refreshWindow()
             global.refreshHistory()
         })

+ 4 - 1
src/_health/pages/move.tsx

@@ -11,6 +11,7 @@ import { useTranslation } from "react-i18next";
 import { getActiveMoves, getActiveMovesCurrent, uploadActiveMoves } from "@/services/health";
 import dayjs from "dayjs";
 import { TimeFormatter } from "@/utils/time_format";
+import { jumpPage } from "@/features/trackTimeDuration/hooks/Common";
 
 let timer
 export default function Move() {
@@ -250,7 +251,9 @@ export default function Move() {
             </View>
             <View className="current_footer">
                 <Text>{currentFootDesc()}</Text>
-                <Text>Show More</Text>
+                <Text onClick={()=>{
+                    jumpPage(`/_health/pages/move_schedule?hours=${JSON.stringify(data.hours)}`)
+                }}>Show More</Text>
             </View>
 
         </View>

+ 1 - 0
src/_health/pages/move_schedule.config.ts

@@ -0,0 +1 @@
+

+ 54 - 0
src/_health/pages/move_schedule.scss

@@ -0,0 +1,54 @@
+.schedule_item{
+    position: relative;
+    height: 140px;
+    background-color: #fff;
+    display: flex;
+    flex-direction: row;
+    align-items: center;
+    padding-left: 52px;
+    box-sizing: border-box;
+    padding-right: 40px;
+}
+
+.schedule_item_left{
+    display: flex;
+    flex-direction: column;
+}
+
+.schedule_item_line{
+    background-color: #B2B2B2;
+    opacity: 0.1;
+    position: absolute;
+    right: 0;
+    bottom: 0;
+    left: 52px;
+    height: 2px;
+    transform: scaleY(0.5);
+}
+
+.schedule_item_time{
+    font-size: 24px;
+    color: #B2B2B2;
+
+}
+
+.schedule_item_target{
+    color: #000;
+    font-size: 28px;
+    margin-top: 8px;
+}
+
+.schedule_item_open{
+    color: 26px;
+    color: #FF2E66;
+}
+
+.no_more{
+    color: #B2B2B2;
+    background-color: #f5f5f5;
+    width: 750px;
+    height: 128px;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+}

+ 57 - 0
src/_health/pages/move_schedule.tsx

@@ -0,0 +1,57 @@
+import { View, Text } from "@tarojs/components";
+import './move_schedule.scss'
+import { useRouter } from "@tarojs/taro";
+
+let useRoute;
+let useNavigation;
+let scenario = '';
+if (process.env.TARO_ENV == 'rn') {
+    useRoute = require("@react-navigation/native").useRoute
+    useNavigation = require("@react-navigation/native").useNavigation
+}
+/*
+https://fast-dev.oss-cn-beijing.aliyuncs.com/users/b13170f6916a27713c118a5ce75ea74a/food-journal/2024/88620d96-c898-472f-8783-d425bb91333a_20240910114628_698.png
+https://fast-dev.oss-cn-beijing.aliyuncs.com/users/b13170f6916a27713c118a5ce75ea74a/food-journal/2024/88620d96-c898-472f-8783-d425bb91333a_20240910114628_698.png?x-oss-process=image/resize,w_50,limit_0
+*/
+
+export default function MoveSchedule() {
+    let router
+    let navigation;
+    if (useNavigation) {
+        navigation = useNavigation()
+    }
+
+    if (process.env.TARO_ENV == 'rn') {
+        router = useRoute()
+    }
+    else {
+        router = useRouter()
+    }
+
+    const hours = JSON.parse(router.params.hours)
+
+    // console.log(JSON.parse(router.params.hours))
+
+    return <View style={{ display: 'flex', flexDirection: 'column' }}>
+        {
+            hours.map((item, index) => {
+                var start = item.hour
+                var end = start + 1
+                start = (start + '').padStart(2, '0')
+                end = (end + '').padStart(2, '0')
+                return <View key={index} className="schedule_item">
+                    <View className="schedule_item_left">
+                        <View className="schedule_item_time">{start}:00-{end}:00</View>
+                        <Text className="schedule_item_target">{item.real_steps}/{item.target_steps} steps</Text>
+                    </View>
+                    <View style={{flex:1}}/>
+                    <Text className="schedule_item_open">{start}:00开放</Text>
+                    {
+                        index < hours.length - 1 && <View className="schedule_item_line" />
+                    }
+                </View>
+            })
+        }
+        <Text className="no_more">没有更多了</Text>
+    </View>
+}

+ 5 - 0
src/_health/pages/move_setting.tsx

@@ -0,0 +1,5 @@
+import { View } from "@tarojs/components";
+
+export default function MoveSetting(){
+    return <View></View>
+}

+ 3 - 1
src/app.config.ts

@@ -58,7 +58,9 @@ const appConfig = defineAppConfig({
         'pages/setting_reminder',
         'pages/moment_detail',
         'pages/archive',
-        'pages/move'
+        'pages/move',
+        'pages/move_schedule',
+        'pages/move_setting'
       ]
     }
   ],

BIN=BIN
src/assets/_health/active.png


BIN=BIN
src/assets/_health/eat.png


BIN=BIN
src/assets/_health/fast.png


BIN=BIN
src/assets/_health/moon.png


BIN=BIN
src/assets/_health/sleep.png


BIN=BIN
src/assets/_health/sun.png


+ 35 - 0
src/features/health/HeaderCircadian.scss

@@ -0,0 +1,35 @@
+.circadian_bg {
+    height: 88px;
+    display: flex;
+    flex-direction: row;
+    border-radius: 44px;
+    background-color: #000;
+    padding-left: 26px;
+    padding-right: 60px;
+    align-items: center;
+}
+
+.circadian_icon {
+    width: 36px;
+    height: 36px;
+    margin-right: 30px;
+}
+
+.circadian_content {
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    justify-content: center;
+}
+
+.circadian_name {
+    color: #fff;
+    font-weight: bold;
+    font-size: 28px;
+}
+
+.circadian_status {
+    color: #999999;
+    font-weight: bold;
+    font-size: 20px;
+}

+ 232 - 0
src/features/health/HeaderCircadian.tsx

@@ -0,0 +1,232 @@
+import { View, Image, Text } from '@tarojs/components'
+import './HeaderCircadian.scss'
+import { useDispatch, useSelector } from 'react-redux';
+import { useEffect, useState } from 'react';
+import { setShowActionTip } from '@/store/health';
+import { getScenario } from './hooks/health_hooks';
+import dayjs from 'dayjs';
+
+let lauchShow = false
+let timer;
+export default function HeaderCircadian() {
+    const health = useSelector((state: any) => state.health);
+    const dispatch = useDispatch()
+    const [showTip, setShowTip] = useState(false)
+
+    const [icon, setIcon] = useState(require('@assets/_health/sun.png'))
+    const [title, setTitle] = useState('')
+    const [desc, setDesc] = useState('')
+    const [lowLight, setLowLight] = useState(false)
+
+    useEffect(() => {
+        if (health && health.windows && !lauchShow) {
+            lauchShow = true
+            checkTip()
+        }
+    }, [health])
+
+    useEffect(() => {
+        checkTip()
+    }, [health.mode])
+
+    function checkTip() {
+        //启动时toast
+        if (health && health.windows) {
+            // lauchShow = true
+            const scenario = getScenario(health.windows, health.mode)
+            if (scenario.real) {
+                dispatch(setShowActionTip({
+                    isShow: true,
+                    isCompleted: false
+                }))
+                return;
+            }
+            else {
+                if (new Date().getTime() >= scenario.target.start_timestamp && new Date().getTime() < scenario.target.end_timestamp) {
+                    setDesc('ON')
+                    setLowLight(false)
+                }
+                else {
+                    setDesc('UPCOMING')
+                    setLowLight(true)
+                }
+            }
+            switch (health.mode) {
+                case 'FAST':
+                    {
+                        setIcon(require('@assets/_health/fast.png'))
+                        setTitle('Fast time')
+                        // setDesc(health.isCompleted ? 'COMPLETED' : 'IN PROGRESS')
+                    }
+                    break;
+                case 'EAT':
+                    {
+                        setIcon(require('@assets/_health/eat.png'))
+                        setTitle('Eat time')
+                        // setDesc(health.isCompleted ? 'COMPLETED' : 'IN PROGRESS')
+                    }
+                    break;
+                case 'SLEEP':
+                    {
+                        setIcon(require('@assets/_health/sleep.png'))
+                        setTitle('Sleep time')
+                        // setDesc(health.isCompleted ? 'COMPLETED' : 'IN PROGRESS')
+                    }
+                    break;
+                case 'ACTIVE':
+                    {
+                        setIcon(require('@assets/_health/active.png'))
+                        setTitle('Active time')
+                        // setDesc(health.isCompleted ? 'COMPLETED' : 'IN PROGRESS')
+                    }
+                    break;
+                case 'DAY':
+                    {
+                        setIcon(require('@assets/_health/sun.png'))
+                        setTitle('Daytime')
+                        // setDesc(health.isCompleted ? 'COMPLETED' : 'IN PROGRESS')
+                    }
+                    break;
+                case 'NIGHT':
+                    {
+                        setIcon(require('@assets/_health/moon.png'))
+                        setTitle('Nighttime')
+                        // setDesc(health.isCompleted ? 'COMPLETED' : 'IN PROGRESS')
+                    }
+                    break;
+            }
+
+            setShowTip(true)
+            if (timer) {
+                clearTimeout(timer)
+                timer = null
+            }
+            timer = setTimeout(() => {
+                setShowTip(false)
+            }, 3000)
+        }
+    }
+
+    useEffect(() => {
+        if (health.showActionCircadian) {
+            setLowLight(false)
+            switch (health.mode) {
+                case 'FAST':
+                    {
+                        setIcon(require('@assets/_health/fast.png'))
+                        setTitle('Fast logging')
+                        setDesc(health.isCompleted ? 'COMPLETED' : 'IN PROGRESS')
+                    }
+                    break;
+                case 'EAT':
+                    {
+                        setIcon(require('@assets/_health/eat.png'))
+                        setTitle('Meal logging')
+                        setDesc(health.isCompleted ? 'COMPLETED' : 'IN PROGRESS')
+                    }
+                    break;
+                case 'SLEEP':
+                    {
+                        setIcon(require('@assets/_health/sleep.png'))
+                        setTitle('Sleep logging')
+                        setDesc(health.isCompleted ? 'COMPLETED' : 'IN PROGRESS')
+                    }
+                    break;
+                case 'ACTIVE':
+                    {
+                        setIcon(require('@assets/_health/active.png'))
+                        setTitle('Activity logging')
+                        setDesc(health.isCompleted ? 'COMPLETED' : 'IN PROGRESS')
+                    }
+                    break;
+            }
+
+            setShowTip(true)
+            if (timer) {
+                clearTimeout(timer)
+                timer = null
+            }
+            timer = setTimeout(() => {
+                setShowTip(false)
+                dispatch(setShowActionTip({
+                    isShow: false,
+                    isCompleted: false
+                }))
+            }, 3000)
+        }
+
+    }, [health.showActionCircadian])
+
+    useEffect(() => {
+        setInterval(() => {
+            if (health.windows) {
+                const now = dayjs().format('YYYY-MM-DD HH:mm:ss')
+                const day = getScenario(health.windows, 'DAY')
+                const night = getScenario(health.windows, 'NIGHT')
+                const fast = getScenario(health.windows, 'FAST')
+                const eat = getScenario(health.windows, 'EAT')
+                const sleep = getScenario(health.windows, 'SLEEP')
+                const active = getScenario(health.windows, 'ACTIVE')
+                var isShow = false
+                if (dayjs(day.target.start_timestamp).format('YYYY-MM-DD HH:mm:ss') == now) {
+                    isShow = true;
+                    setIcon(require('@assets/_health/sun.png'))
+                    setTitle('Daytime')
+                }
+                else if (dayjs(night.target.start_timestamp).format('YYYY-MM-DD HH:mm:ss') == now) {
+                    isShow = true;
+                    setIcon(require('@assets/_health/moon.png'))
+                    setTitle('Nighttime')
+                }
+                else if (dayjs(fast.target.start_timestamp).format('YYYY-MM-DD HH:mm:ss') == now) {
+                    isShow = true;
+                    setIcon(require('@assets/_health/fast.png'))
+                    setTitle('Fast time')
+                }
+                else if (dayjs(eat.target.start_timestamp).format('YYYY-MM-DD HH:mm:ss') == now) {
+                    isShow = true;
+                    setIcon(require('@assets/_health/eat.png'))
+                    setTitle('Eat time')
+                }
+                else if (dayjs(sleep.target.start_timestamp).format('YYYY-MM-DD HH:mm:ss') == now) {
+                    isShow = true;
+                    setIcon(require('@assets/_health/sleep.png'))
+                    setTitle('Sleep time')
+                }
+                else if (dayjs(active.target.start_timestamp).format('YYYY-MM-DD HH:mm:ss') == now) {
+                    isShow = true;
+                    setIcon(require('@assets/_health/active.png'))
+                    setTitle('Active time')
+                }
+                if (isShow) {
+                    setDesc('ON')
+                    setLowLight(false)
+                    setShowTip(true)
+                    if (timer) {
+                        clearTimeout(timer)
+                        timer = null
+                    }
+                    timer = setTimeout(() => {
+                        setShowTip(false)
+                        dispatch(setShowActionTip({
+                            isShow: false,
+                            isCompleted: false
+                        }))
+                    }, 3000)
+                }
+
+            }
+
+
+
+        }, 1000)
+    }, [])
+
+    return <View className='circadian_bg' style={{ opacity: showTip ? 1 : 0 }}>
+        <Image src={icon} className='circadian_icon' style={{ opacity: lowLight ? 0.7 : 1.0 }} />
+        <View className='circadian_content'>
+            <View className='circadian_name'>{title}</View>
+            <View className='circadian_status'>{desc}</View>
+        </View>
+    </View>
+}

+ 54 - 5
src/features/health/MainConsole.tsx

@@ -12,10 +12,13 @@ import { clockTimes, makeDone, updateEventDuration, updateSchedule, updateTarget
 import TimePicker from "../common/TimePicker";
 import showActionSheet from "@/components/basic/ActionSheet";
 import { rpxToPx } from "@/utils/tools";
-import { setMode } from "@/store/health";
+import { setMode, setShowActionTip } from "@/store/health";
 import { getCountownTime, getDuration, getScenario, getThemeColor, getWindowStatus } from "./hooks/health_hooks";
 import { IconMore } from "@/components/basic/Icons";
 import DurationPicker from "@/_health/components/duration_picker";
+import Taro from "@tarojs/taro";
+import { systemLocation } from "@/services/common";
+import { TimeFormatter } from "@/utils/time_format";
 
 let useNavigation;
 let min = 0
@@ -147,7 +150,7 @@ export default function MainConsole(props: { type: WindowType }) {
                 }
 
             </View>
-            <View style={{flex:1}}/>
+            <View style={{ flex: 1 }} />
             {
                 !item.reminder && <Image src={require('@assets/images/notification_off.png')} className='notification_icon' />
             }
@@ -323,6 +326,10 @@ export default function MainConsole(props: { type: WindowType }) {
                 timestamp: t1
             }]
         }).then(res => {
+            dispatch(setShowActionTip({
+                isShow: true,
+                isCompleted: (selItem.event == 'FAST_END' || selItem.event == 'SLEEP_WAKE_UP')
+            }))
             setBtnDisable(false)
             setShowTimePicker(false)
             global.refreshWindow()
@@ -559,6 +566,45 @@ export default function MainConsole(props: { type: WindowType }) {
         return ''
     }
 
+    function chooseLocation() {
+        Taro.chooseLocation({
+            // latitude: authInfo && authInfo.lat ? authInfo.lat : undefined,
+            // longitude: authInfo && authInfo.lat ? authInfo.lng : undefined,
+            success: function (res) {
+                uploadLocation(res)
+            },
+            fail(res) {
+                Taro.showToast({
+                    title: '位置修改失败!\n请重新选择就近位置',
+                    icon: 'none'
+                })
+            },
+            complete(res) {
+
+            }
+        })
+    }
+
+    function uploadLocation(res) {
+        var today = new Date()
+        var yesterday = new Date(today.getTime() - 24 * 3600 * 1000)
+        var tomorrow = new Date(today.getTime() + 24 * 3600 * 1000 * 5)
+        var strYesterday = `${yesterday.getFullYear()}-${TimeFormatter.padZero(yesterday.getMonth() + 1)}-${TimeFormatter.padZero(yesterday.getDate())}`
+        var strTomorrow = `${tomorrow.getFullYear()}-${TimeFormatter.padZero(tomorrow.getMonth() + 1)}-${TimeFormatter.padZero(tomorrow.getDate())}`
+
+        systemLocation({
+            lat: res.latitude,
+            lng: res.longitude,
+            name: res.name,
+            address: res.address,
+            date_start: strYesterday,
+            date_end: strTomorrow,
+            coordinate_system_standard: process.env.TARO_ENV == 'weapp' ? 'GCJ-02' : 'WGS-84'
+        }).then(data => {
+            global.refreshWindow()
+        })
+    }
+
     function updateDuration(duration) {
         setDurationPicker(false)
         const scenario = getScenario(health.windows, health.mode)
@@ -584,19 +630,22 @@ export default function MainConsole(props: { type: WindowType }) {
             {/* {
                 (health.mode == 'EAT' || health.mode == 'ACTIVE') && <Text style={{ display: 'flex', alignItems: 'center', justifyContent: 'center' }} onClick={more}>更多</Text>
             } */}
+            {
+                (health.mode == 'DAY' || health.mode == 'NIGHT') && <Text onClick={chooseLocation}>选择位置</Text>
+            }
             <View className="main_footer_more" onClick={more}>
                 <IconMore color="#b2b2b2" width={17} />
             </View>
 
         </View>
         {
-            health.mode == 'ACTIVE' && <View className="console_active_bg" onClick={()=>{
+            health.mode == 'ACTIVE' && <View className="console_active_bg" onClick={() => {
                 jumpPage('/_health/pages/move')
             }}>
                 <View className="console_active">
-                    <Image className="active_icon" src={require('@assets/_health/walk.png')}/>
+                    <Image className="active_icon" src={require('@assets/_health/walk.png')} />
                     <Text className="active_text">Move More</Text>
-                    <Image className="cell_arrow" src={require('@assets/_health/cell_arrow.png')}/>
+                    <Image className="cell_arrow" src={require('@assets/_health/cell_arrow.png')} />
                 </View>
 
             </View>

+ 9 - 2
src/features/health/MainHistory.tsx

@@ -68,8 +68,15 @@ export default function MainHistory(props: { type: string }) {
 
             if ((res as any).data.length > 0) {
                 setTimeout(() => {
+                    // var array:any = [];
+                    // (res as any).data.map((item,index)=>{
+                    //     array.push('#history_id_'+index)
+                    // })
+                    // var ids = array.join(',')
+                    // console.log(array)
+                    // console.log(ids)
                     const query = Taro.createSelectorQuery();
-                    query.select(('#demo1')).boundingClientRect((rect) => {
+                    query.selectAll('#history_id_0').boundingClientRect((rect) => {
                         console.log(rect)
                     }).exec();
                 }, 1000)
@@ -121,7 +128,7 @@ export default function MainHistory(props: { type: string }) {
         }
         {
             list.map((item, index) => {
-                return <View ref={refDemo} id="demo1" key={index}>
+                return <View ref={refDemo} id={'history_id_0'} key={index}>
                     <HistoryItem
                         data={item}
                         preData={index > 0 ? list[index - 1] : null}

+ 1 - 3
src/features/journal/components/journal_cover.tsx

@@ -17,9 +17,7 @@ export default function JournalCover(props: { count: number }) {
             </View>
         case 3:
             return <View className='double'>
-                <View style={{ display: 'flex', flexDirection: 'column' }}>
-                    <View className='half_img' />
-                </View>
+                <View className='half_img' />
                 <View className='journal_space' />
                 <View className='half_top_down'>
                     <View className='quarter_img' />

+ 2 - 2
src/features/trackTimeDuration/components/Rings.weapp.tsx

@@ -176,9 +176,9 @@ export default function Rings(props: {
         // 设置画布尺寸
         ctx.scale(dpr, dpr)
 
-        ctx.translate(center, center)
+        ctx.translate(center, 2*center)
         ctx.scale(scale, scale);
-        ctx.translate(-center, -center);
+        ctx.translate(-center, -2*center);
 
 
 

+ 15 - 1
src/pages/clock/Clock.tsx

@@ -11,6 +11,7 @@ import { IconStreak } from "@/components/basic/Icons";
 import { getScenario, getThemeColor } from "@/features/health/hooks/health_hooks";
 import Streak from "@/features/health/Streak";
 import Calendar from "@/features/health/calendar";
+import HeaderCircadian from "@/features/health/HeaderCircadian";
 
 let useNavigation;
 
@@ -122,7 +123,7 @@ export default function Clock() {
                 marginTop: systemInfo.statusBarHeight,
                 alignItems: 'center',
                 justifyContent: 'center',
-                paddingLeft:0
+                paddingLeft: 0
             }} >{health.title}</View>
 
             {
@@ -144,6 +145,19 @@ export default function Clock() {
                 </View>
             }
 
+            <View style={{
+                position: 'absolute',
+                left: 60,
+                right: 60,
+                bottom: 0,
+                height: 44,
+                display:'flex',
+                alignItems:'center',
+                justifyContent:'center'
+            }}>
+                <HeaderCircadian />
+            </View>
+
 
         </View>
         <ClockNew />

+ 13 - 4
src/store/health.tsx

@@ -6,7 +6,9 @@ interface HealthState {
     selTab: number;
     refreshs: any; //刷新数据时间点
     title: string;
-    eatArchived:any;
+    eatArchived: any;
+    showActionCircadian: boolean;
+    isCompleted: boolean;
 }
 
 const initialState: HealthState = {
@@ -15,7 +17,9 @@ const initialState: HealthState = {
     selTab: 0,
     refreshs: [],
     title: '',
-    eatArchived:null,
+    eatArchived: null,
+    showActionCircadian: false,
+    isCompleted: false,
 }
 
 const healthSlice = createSlice({
@@ -38,8 +42,13 @@ const healthSlice = createSlice({
         setTitle(state, action) {
             state.title = action.payload
         },
-        setEatArchived(state,action){
+        setEatArchived(state, action) {
             state.eatArchived = action.payload
+        },
+        setShowActionTip(state, action) {
+            const { isShow, isCompleted } = action.payload
+            state.showActionCircadian = isShow
+            state.isCompleted = isCompleted
         }
 
     }
@@ -48,5 +57,5 @@ const healthSlice = createSlice({
 
 
 
-export const { setWindows, setMode, setTab, setRefreshs,setTitle,setEatArchived } = healthSlice.actions;
+export const { setWindows, setMode, setTab, setRefreshs, setTitle, setEatArchived, setShowActionTip } = healthSlice.actions;
 export default healthSlice.reducer;