leon 1 år sedan
förälder
incheckning
66be4f66f7

+ 2 - 0
src/_health/components/choose_date_time.tsx

@@ -31,12 +31,14 @@ export default function ChooseDateTime(props: {
     timeChange?: any,
     dateChange?: any,
     change?: any,
+
     enterTimestamp?: number,
     targetTimestamp?: number
 }) {
     const [chooseDate, setChooseDate] = useState(false)
     const { t } = useTranslation()
     const [count, setCount] = useState(0)
+    const health = 
 
     useEffect(() => {
         console.log('sss')

+ 4 - 2
src/_health/components/fast_sleep_popup_content.tsx

@@ -13,6 +13,7 @@ export default function FastSleepPopupContent(props: {
     sleepStatus: StatusType,
     afterStatus: StatusType,
     showStep: boolean,
+    isFixed?:boolean,
     total: string,
     total1?: any,
     total2?: any,
@@ -91,9 +92,10 @@ export default function FastSleepPopupContent(props: {
             }
         </StatusIndicator>
     }
-    return <View className="popup_container1" style={{
+    return <View className="popup_container1" catchMove style={{
         top:props.top,
-        height:'100vh'
+        height:'100vh',
+        position:props.isFixed?'fixed':'absolute'
     }}>
         <View className="fast_sleep_content">
             <View className="h34 bold">{props.title ?? t('health.three_stages')}</View>

+ 2 - 2
src/_health/pages/fast_sleep.tsx

@@ -59,7 +59,7 @@ export default function FastSleep() {
                 setCurrent(3)
                 break;
         }
-
+        Taro.showLoading()
         getDatas()
 
         return () => {
@@ -73,7 +73,7 @@ export default function FastSleep() {
 
 
     function getDatas() {
-        Taro.showLoading()
+        // 
         fastWithSleep().then(res => {
             setLoaded(true)
             setData(res)

+ 2 - 2
src/_health/pages/log_time.tsx

@@ -947,7 +947,7 @@ export default function LogTime() {
             disable={array[index].disable}
             showError={showError}
             showLine={showLine}
-            targetTimestamp={timeline.target.timestamp}
+            targetTimestamp={router.params.longfast?health.long_fast.timeline[1].target.timestamp:timeline.target.timestamp}
             enterTimestamp={enterTime}
             color={iFast ? MainColorType.fast : MainColorType.sleep}
             minTimestamp={min}
@@ -1162,7 +1162,7 @@ export default function LogTime() {
                         <View className="error_icon_bg" style={{ backgroundColor: MainColorType.success }}>
                             <Image src={require('@assets/_health/tip_check.png')} style={{ width: rpxToPx(26), height: rpxToPx(26) }} />
                         </View>
-                        <Text className="h24" style={{ lineHeight: rpxToPx(36) + 'px' }}>{t('health.auto_save')}</Text>
+                        <Text className="h24" style={{ lineHeight: rpxToPx(36) + 'px' }}>{t('health.conflict_resolve')}</Text>
                     </View>
                 }
                 {

+ 1 - 1
src/_health/pages/timeline_detail.config.ts

@@ -3,7 +3,7 @@ export default definePageConfig({
         // 'ec-canvas': '../../lib/ec-canvas/ec-canvas',
         // 'demo':'../../components/demo'
     },
-    "navigationBarTitleText": "详情",
+    "navigationBarTitleText": "",
     // "disableScroll":true,
     "navigationBarBackgroundColor":"#f5f5f5"
 })

+ 6 - 1
src/_health/pages/timeline_detail.tsx

@@ -178,6 +178,10 @@ export default function TimelineDetail() {
         if (!window_id && ((health.mode != 'ACTIVE' && health.mode != 'EAT') || fast_type == 'LF') && autoPost == '1') {
             setShowPop(true)
         }
+
+        return ()=>{
+            console.log('page dealloc')
+        }
     }, [])
 
     useEffect(() => {
@@ -278,7 +282,7 @@ export default function TimelineDetail() {
 
     function uploadFile(path, source) {
         Taro.showLoading({
-            title: '加载中'
+            title: t('health.loading')
         })
         var dot = path.lastIndexOf('.')
         var fileExt = dot > 0 ? path.substring(dot) : ''
@@ -566,6 +570,7 @@ export default function TimelineDetail() {
                 sleepStatus={StatusType.normal}
                 afterStatus={StatusType.normal}
                 title={t('health.my_fast_journal')}
+                isFixed
                 showStep={true}
                 total={''}
                 // total1={total1()}

+ 1 - 0
src/context/locales/en.js

@@ -1202,5 +1202,6 @@ export default {
         hit_steps2:'Hit {{steps}} steps',
         hour_step_goal:'Hourly Step Goal',
         avg_total_steps:'Average {{avg}} steps, Total {{total}} steps',
+        conflict_resolve:'Time Conflict Resolved',
     }
 }

+ 1 - 0
src/context/locales/zh.js

@@ -1203,5 +1203,6 @@ export default {
         hit_steps2:'走够{{steps}}步',
         hour_step_goal:'每小时步数目标',
         avg_total_steps:'平均 {{avg}} 步,全天 {{total}} 步',
+        conflict_resolve:'时间冲突已解决',
     }
 }

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

@@ -51,6 +51,7 @@ export default forwardRef((props: { type?: string, fast_type?: string, updateDat
     const [hideFastTip, setHideFastTip] = useState(false)
     const [hideSleepTip, setHideSleepTip] = useState(false)
     const [pageTop, setPageTop] = useState(0)
+    const query = Taro.createSelectorQuery()
 
     const dispatch = useDispatch()
     const { t } = useTranslation()
@@ -142,7 +143,7 @@ export default forwardRef((props: { type?: string, fast_type?: string, updateDat
     }, [health.mode])
 
     function measureItemLayouts() {
-        const query = Taro.createSelectorQuery()
+        
         list.forEach((item, index) => {
             query.select(`#history-${index}`).boundingClientRect()
         });

+ 713 - 0
src/features/health/MainHistory2 copy.tsx

@@ -0,0 +1,713 @@
+import { View, Text, Image } from "@tarojs/components";
+import { forwardRef, useEffect, useImperativeHandle, useRef, useState } from "react";
+import { getLatestJournal, records } from "@/services/health";
+import './History.scss'
+import Calendar from "./calendar";
+import { useDispatch, useSelector } from "react-redux";
+import HistoryItem from "./HistoryItem";
+import { rpxToPx } from "@/utils/tools";
+import { jumpPage } from "../trackTimeDuration/hooks/Common";
+import Taro, { useReady } from "@tarojs/taro";
+import { getScenario, getThemeColor } from "./hooks/health_hooks";
+import { TimeFormatter } from "@/utils/time_format";
+import dayjs from "dayjs";
+import { MainColorType } from "@/context/themes/color";
+import { IconArrow, IconCellArrow } from "@/components/basic/Icons";
+import NoRecord from "@/_health/components/no_record";
+import ListFooter from "@/_health/components/list_footer";
+import { useTranslation } from "react-i18next";
+import { setActiveTip, setEatTip, setFirstActiveId, setFirstEatId } from "@/store/health";
+import RightArrowRow from "@/_health/components/right_arrow_row";
+import TimelineDate from "@/_health/components/timeline_date";
+
+let lastMode = ''
+let myScrollTop = 0
+export default forwardRef((props: { type?: string, fast_type?: string, updateDate?: any, refreshSuccess?: any }, ref) => {
+    const [itemLayouts, setItemLayouts] = useState<any>([])
+    const [itemHeights, setItemHeights] = useState<any>([])
+    const [list, setList] = useState<any>([])
+    const [page, setPage] = useState(1)
+    const [total, setTotal] = useState(0)
+    const [loaded, setLoaded] = useState(false)
+    const health = useSelector((state: any) => state.health);
+    const user = useSelector((state: any) => state.user);
+    const [loading, setLoading] = useState(false)
+    const [showEatArchive, setShowEatArchive] = useState(true)
+    const [showActiveArchive, setShowActiveArchive] = useState(true)
+    const [onlyMe, setOnlyMe] = useState(true)
+
+    const [fastList, setFastList] = useState<any>([])
+    const [eatList, setEatList] = useState<any>([])
+    const [activeList, setActiveList] = useState<any>([])
+    const [sleepList, setSleepList] = useState<any>([])
+    const query = Taro.createSelectorQuery()
+    const [pageTop, setPageTop] = useState(0)
+
+    const dispatch = useDispatch()
+    const { t } = useTranslation()
+
+    useImperativeHandle(ref, () => ({
+        onScroll: onScroll,
+        refresh: refresh,
+        more: more
+    }))
+
+    useEffect(() => {
+        if (list.length > 0) {
+            setTimeout(() => {
+                measureItemLayouts()
+            }, 300)
+        }
+    }, [list])
+
+    useEffect(() => {
+        refresh()
+    }, [onlyMe])
+
+    useEffect(() => {
+        return () => {
+            myScrollTop = 0
+        }
+    }, [])
+
+
+    useEffect(() => {
+        if (!user.isLogin) {
+            setList([])
+        }
+    }, [user.isLogin])
+
+    global.refreshOtherHistory = () => {
+        refresh()
+    }
+
+    useEffect(() => {
+        // if (props.type == 'FAST,SLEEP' || (props.fast_type && props.fast_type == 'LF')) {
+
+        // }
+        // else {
+        //     global.refreshHistory = () => {
+        //         refresh()
+        //         // refreshFast()
+        //         // refreshSleep()
+        //         // refreshEat()
+        //         // refreshActive()
+        //         refreshItem('FAST')
+        //         refreshItem('SLEEP')
+        //         refreshItem('EAT')
+        //         refreshItem('ACTIVE')
+        //     }
+        // }
+    }, [])
+
+    useEffect(() => {
+        if (props.type) {
+            loadData(1)
+        }
+    }, [props.type])
+
+
+    useEffect(() => {
+        if (lastMode != health.mode) {
+            lastMode = health.mode
+            // loadData(1)
+            setPage(1)
+            switch (health.mode) {
+                case 'DAY':
+                case 'NIGHT':
+                    debugger
+                    setList([])
+                    return
+                case 'FAST':
+                    if (fastList.length > 0) {
+                        setList(fastList)
+                        return;
+                    }
+                    break
+                case 'EAT':
+                    if (eatList.length > 0) {
+                        setList(eatList)
+                        return;
+                    }
+                    break
+                case 'SLEEP':
+                    if (sleepList.length > 0) {
+                        setList(sleepList)
+                        return;
+                    }
+                    break
+                case 'ACTIVE':
+                    if (activeList.length > 0) {
+                        setList(activeList)
+                        return;
+                    }
+                    break
+            }
+            loadData(1)
+        }
+
+    }, [health.mode])
+
+    function measureItemLayouts() {
+        console.log('开始计算位置', new Date().getTime(), list.length)
+        if (list.length <= 10) {
+            list.forEach((item, index) => {
+                query.select(`#history-${index}`).boundingClientRect()
+            });
+            query.exec((res) => {
+                var layouts: any = []
+                var heights: any = []
+                res.forEach((rect, index) => {
+                    if (rect) {
+                        layouts[index] = rect.top + myScrollTop
+                        heights[index] = rect.height
+                    }
+                });
+                setItemLayouts(layouts)
+                setItemHeights(heights)
+                console.log('结束计算位置', new Date().getTime())
+            })
+        }
+        else {
+            list.forEach((item, index) => {
+                if (index >= itemLayouts.length) {
+                    query.select(`#history-${index}`).boundingClientRect()
+                }
+            });
+            query.exec((res) => {
+                var layouts: any = []
+                var heights: any = []
+                // console.log(res)
+                res.forEach((rect, index) => {
+                    
+                    if (rect) {
+                        layouts[index] = rect.top + myScrollTop
+                        heights[index] = rect.height
+                    }
+                });
+                setItemLayouts([...itemLayouts,...layouts])
+                setItemHeights([...itemHeights,...heights])
+                console.log('结束计算位置', new Date().getTime())
+            })
+
+        }
+
+
+    }
+
+    function onScroll(e) {
+        // var top = e.detail.scrollTop
+        // myScrollTop = top
+        var top = e.detail.scrollTop - e.detail.deltaY
+        myScrollTop = e.detail.scrollTop
+        setPageTop(top)
+        if (itemLayouts.length > 0) {
+            var i = -1
+            var date = ''
+            list.forEach((item, index) => {
+                if (top >= itemLayouts[index] - 50) {
+                    i = index
+                    if (TimeFormatter.isTimestampInThisWeek(item.window_range.start_timestamp)) {
+                        date = t('health.this_week')
+                    }
+                    else if (dayjs(item.window_range.start_timestamp).format('YYYY') == dayjs().format('YYYY')) {
+                        date = global.language == 'en' ? dayjs(item.window_range.start_timestamp).format('MMMM') : dayjs(item.window_range.start_timestamp).format('MMMM')
+                    }
+                    else {
+                        date = global.language == 'en' ? dayjs(item.window_range.start_timestamp).format('MMMM YYYY') : dayjs(item.window_range.start_timestamp).format('YYYY年M月')
+                    }
+                }
+            })
+            if (props.updateDate) {
+                props.updateDate({
+                    show: i != -1,
+                    date: date
+                })
+            }
+        }
+        else {
+            if (props.updateDate) {
+                props.updateDate({
+                    show: false,
+                    date: ''
+                })
+            }
+
+        }
+    }
+
+    function refresh() {
+        loadData(1)
+        setPage(1)
+    }
+
+    function more() {
+        if (loading) return;
+        if (total == list.length) return;
+        var index = page;
+        index++;
+        setPage(index)
+        loadData(index)
+    }
+
+    function refreshItem(type) {
+        setPage(1)
+        var params: any = {
+            window: type,
+            limit: 10,
+            page: 1
+        }
+
+        records(params).then(res => {
+            var array = (res as any).data
+
+            array.map(item => {
+                var temps: any = []
+                var lastType = ''
+                var lastTextArray: any = []
+                var lastImageArray: any = []
+                item.events.map(event => {
+                    event.moments && event.moments.map(moment => {
+                        switch (moment.type) {
+                            case 'TEXT':
+                                {
+                                    lastTextArray.push({
+                                        title: moment.title,
+                                        description: moment.description,
+                                        event_id: event.id
+                                    })
+                                    if (lastType == 'PIC') {
+                                        temps.push({
+                                            type: 'PIC',
+                                            data: JSON.parse(JSON.stringify(lastImageArray))
+                                        })
+                                        lastImageArray = []
+                                    }
+                                    lastType = 'TEXT'
+                                }
+                                break;
+                            case 'PIC':
+                                {
+                                    lastImageArray.push(moment.media[0].url)
+                                    if (lastType == 'TEXT') {
+                                        temps.push({
+                                            type: 'TEXT',
+                                            data: JSON.parse(JSON.stringify(lastTextArray))
+                                        })
+                                        lastTextArray = []
+                                    }
+                                    lastType = 'PIC'
+                                }
+                                break;
+                            case 'PIC_TEXT':
+                                if (lastType == 'PIC') {
+                                    temps.push({
+                                        type: 'PIC',
+                                        data: JSON.parse(JSON.stringify(lastImageArray))
+                                    })
+                                    lastImageArray = []
+                                }
+                                if (lastType == 'TEXT') {
+                                    temps.push({
+                                        type: 'TEXT',
+                                        data: JSON.parse(JSON.stringify(lastTextArray))
+                                    })
+                                    lastTextArray = []
+                                }
+                                temps.push({
+                                    type: 'PIC_TEXT',
+                                    data: [
+                                        {
+                                            title: moment.title,
+                                            description: moment.description,
+                                            url: moment.media[0].url,
+                                            event_id: event.id
+                                        }
+                                    ]
+                                })
+                                lastType = 'PIC_TEXT'
+                                break;
+                        }
+                    })
+                })
+
+                if (lastType == 'PIC') {
+                    temps.push({
+                        type: 'PIC',
+                        data: JSON.parse(JSON.stringify(lastImageArray))
+                    })
+                    lastImageArray = []
+                }
+                if (lastType == 'TEXT') {
+                    temps.push({
+                        type: 'TEXT',
+                        data: JSON.parse(JSON.stringify(lastTextArray))
+                    })
+                    lastTextArray = []
+                }
+
+                item.dataArray = temps;
+            })
+            switch (type) {
+                case 'FAST':
+                    setFastList(array)
+                    break
+                case 'SLEEP':
+                    setSleepList(array)
+                    break
+                case 'EAT':
+                    setEatList(array)
+                    break
+                case 'ACTIVE':
+                    setActiveList(array)
+                    break
+            }
+        })
+    }
+
+
+    function loadData(index: number) {
+        var params: any = {
+            window: props.type ? props.type : health.mode,
+            limit: 10,
+            page: index
+        }
+        if (props.fast_type) {
+            params.fast_type = props.fast_type
+        }
+        params.show_all_user = onlyMe ? false : true
+        setPage(index)
+        setLoading(true)
+        records(params).then(res => {
+            var array = (res as any).data
+
+            array.map(item => {
+                var temps: any = []
+                var lastType = ''
+                var lastTextArray: any = []
+                var lastImageArray: any = []
+                item.events.map(event => {
+                    event.moments && event.moments.map(moment => {
+                        switch (moment.type) {
+                            case 'TEXT':
+                                {
+                                    lastTextArray.push({
+                                        title: moment.title,
+                                        description: moment.description,
+                                        event_id: event.id
+                                    })
+                                    if (lastType == 'PIC') {
+                                        temps.push({
+                                            type: 'PIC',
+                                            data: JSON.parse(JSON.stringify(lastImageArray))
+                                        })
+                                        lastImageArray = []
+                                    }
+                                    lastType = 'TEXT'
+                                }
+                                break;
+                            case 'PIC':
+                                {
+                                    lastImageArray.push(moment.media[0].url)
+                                    if (lastType == 'TEXT') {
+                                        temps.push({
+                                            type: 'TEXT',
+                                            data: JSON.parse(JSON.stringify(lastTextArray))
+                                        })
+                                        lastTextArray = []
+                                    }
+                                    lastType = 'PIC'
+                                }
+                                break;
+                            case 'PIC_TEXT':
+                                if (lastType == 'PIC') {
+                                    temps.push({
+                                        type: 'PIC',
+                                        data: JSON.parse(JSON.stringify(lastImageArray))
+                                    })
+                                    lastImageArray = []
+                                }
+                                if (lastType == 'TEXT') {
+                                    temps.push({
+                                        type: 'TEXT',
+                                        data: JSON.parse(JSON.stringify(lastTextArray))
+                                    })
+                                    lastTextArray = []
+                                }
+                                temps.push({
+                                    type: 'PIC_TEXT',
+                                    data: [
+                                        {
+                                            title: moment.title,
+                                            description: moment.description,
+                                            url: moment.media[0].url,
+                                            event_id: event.id
+                                        }
+                                    ]
+                                })
+                                lastType = 'PIC_TEXT'
+                                break;
+                        }
+                    })
+                })
+
+                if (lastType == 'PIC') {
+                    temps.push({
+                        type: 'PIC',
+                        data: JSON.parse(JSON.stringify(lastImageArray))
+                    })
+                    lastImageArray = []
+                }
+                if (lastType == 'TEXT') {
+                    temps.push({
+                        type: 'TEXT',
+                        data: JSON.parse(JSON.stringify(lastTextArray))
+                    })
+                    lastTextArray = []
+                }
+
+                item.dataArray = temps;
+            })
+
+
+            setLoading(false)
+            setLoaded(true)
+            if (index == 1) {
+                // console.log(props.type,health.mode)
+                if (!props.type && array.length > 0) {
+                    if (health.mode == 'EAT') {
+                        setEatList(array)
+                        // dispatch(setFirstEatId(array[0].window_id))
+                        // if (health.first_eat_id.length > 0 && health.first_eat_id != array[0].window_id) {
+                        //     dispatch(setEatTip(true))
+                        // }
+                    }
+                    else if (health.mode == 'ACTIVE') {
+                        setActiveList(array)
+                        // dispatch(setFirstActiveId(array[0].window_id))
+                        // if (health.first_active_id.length > 0 && health.first_active_id != array[0].window_id) {
+                        //     dispatch(setActiveTip(true))
+                        // }
+                    }
+                    else if (health.mode == 'FAST') {
+                        setFastList(array)
+                    }
+                    else if (health.mode == 'SLEEP') {
+                        setSleepList(array)
+                    }
+                }
+                setList(array)
+                setTotal((res as any).total)
+                if (props.refreshSuccess) {
+                    props.refreshSuccess()
+                }
+            }
+            else {
+                setList([...list, ...array])
+            }
+
+            // 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.selectAll('#history_id_0').boundingClientRect((rect) => {
+            //             console.log(rect)
+            //         }).exec();
+            //     }, 1000)
+            // }
+
+        }).catch(e => {
+            setLoading(false)
+        })
+    }
+
+    function historyMonth(index) {
+        var showDate = false;
+        var dateStr = ''
+        if (index == 0) {
+            var currentDate = global.language == 'en' ? dayjs(list[index].window_range.start_timestamp).format('YYYY') : dayjs(list[index].window_range.start_timestamp).format('YYYY年')
+            var now = global.language == 'en' ? dayjs().format('YYYY') : dayjs().format('YYYY年')
+
+            if (currentDate != now) {
+                showDate = true
+                dateStr = currentDate
+            }
+
+
+        }
+        else {
+            var currentDate = global.language == 'en' ? dayjs(list[index].window_range.start_timestamp).format('YYYY') : dayjs(list[index].window_range.start_timestamp).format('YYYY年')
+            var now = global.language == 'en' ? dayjs(list[index - 1].window_range.start_timestamp).format('YYYY') : dayjs(list[index - 1].window_range.start_timestamp).format('YYYY年')
+            if (currentDate != now) {
+                showDate = true
+                dateStr = currentDate
+            }
+        }
+        if (showDate) {
+            return <View className="history_year_month h42 bold" style={{ marginBottom: rpxToPx(60) }}>{dateStr}</View>
+        }
+        return <View />
+    }
+
+
+    function hideLine(index) {
+        var currentDate = dayjs(list[index].window_range.start_timestamp).format('YYYY年M月D日')
+        if (list.length > index + 1) {
+            var nextDate = dayjs(list[index + 1].window_range.start_timestamp).format('YYYY年M月D日')
+            if (currentDate == nextDate) return true
+        }
+        return false
+    }
+
+    function archiveContent() {
+        if (health.mode != 'EAT' && health.mode != 'ACTIVE') {
+            return
+        }
+
+        if (health.mode == 'EAT') {
+            if (!showEatArchive || !health.eatArchived || !health.eatArchived.archived) {
+                return
+            }
+        }
+
+        if (health.mode == 'ACTIVE') {
+            if (!showActiveArchive || !health.activeArchived || !health.activeArchived.archived) {
+                return
+            }
+        }
+
+        return <View style={{
+            display: 'flex',
+            flexDirection: 'column',
+            alignItems: 'center',
+            paddingTop: rpxToPx(82),
+            paddingBottom: rpxToPx(82),
+            backgroundColor: '#fff',
+            position: 'relative'
+        }}>
+            <View className="archived_bg" onClick={() => {
+                jumpPage('/_health/pages/archive')
+                setTimeout(() => {
+                    health.mode == 'EAT' ? setShowEatArchive(false) : setShowActiveArchive(false)
+                }, 1000)
+
+            }}>
+                <Text className="archived_text bold" style={{ color: getThemeColor(health.mode) }}>[{health.eatArchived.real_count}/{health.eatArchived.target_count} Meals] Archived {TimeFormatter.dateDescription(new Date(health.eatArchived.timestamp).getTime(), true, false)}</Text>
+                {
+                    health.eatArchived.images.map((item, index) => {
+                        return <Image src={item} key={index} className="archived_img" mode="aspectFill" />
+                    })
+                }
+                <IconArrow color={MainColorType.g02} width={rpxToPx(34)} />
+            </View>
+            <View className="border_footer_line" />
+        </View>
+    }
+
+    if (!loaded || health.mode == 'DAY' || health.mode == 'NIGHT')
+        return <View />
+
+    if (!user.isLogin) return <View />
+
+    function showTipF() {
+        var showTip = false
+        if (getScenario(health.windows, health.mode).status == 'OG') {
+            if (health.mode == 'EAT') {
+                showTip = !global.hideEatArchiveTip
+            }
+            else if (health.mode == 'ACTIVE') {
+                showTip = !global.hideActiveArchiveTip
+            }
+        }
+        return showTip
+    }
+
+    return <View style={{ width: rpxToPx(750), marginTop: rpxToPx(60) }}>
+
+        {
+            <View className="new_header_bg" style={{ position: 'relative' }}>
+                <Text className="h50 bold">{t('health.recents')}</Text>
+                {
+                    user.test_user && <View style={{ position: 'absolute', right: 30, top: 20 }} onClick={() => {
+                        setOnlyMe(!onlyMe)
+
+                    }}>{onlyMe ? '仅自己' : '全部用户'}</View>
+                }
+                {
+                    false && (health.mode == 'EAT' || health.mode == 'ACTIVE') && <View onClick={() => {
+                        jumpPage('/pages/account/Journal?type=' + health.mode + `&show_tip=${showTipF() ? '1' : '0'}`)
+                        setTimeout(() => {
+                            health.mode == 'EAT' ? setShowEatArchive(false) : setShowActiveArchive(false)
+                        }, 1000)
+                    }} className="archive_bg" style={{ position: 'relative' }}>
+                        <Image className="archive_bg" src={require('@assets/_health/journal.png')} />
+
+                    </View>
+                }
+            </View>
+        }
+        {
+            list.length == 0 && <NoRecord />
+        }
+        {
+            list.length > 0 && <View style={{ minHeight: rpxToPx(464), backgroundColor: '#fff', paddingTop: rpxToPx(60) }}>
+                {
+                    list.map((item, index) => {
+                        if (itemLayouts.length >= index + 1 && pageTop > 0) {
+                            if (Math.abs(itemLayouts[index] - pageTop) > 3000) {
+                                return <View style={{ height: itemHeights[index] }} id={`history-${index}`}>
+                                </View>
+                            }
+                            if (Math.abs(itemLayouts[index] - pageTop) > 1500) {
+                                return <View style={{
+                                    height: itemHeights[index], display: 'flex',
+                                    paddingLeft: rpxToPx(40),
+                                    paddingRight: rpxToPx(40),
+                                    boxSizing: 'border-box',
+                                    flexDirection: 'row'
+                                }} id={`history-${index}`}>
+                                    <TimelineDate timestamp={item.window_range.start_timestamp}
+                                        pre_timestamp={index > 0 ? list[index - 1].window_range.start_timestamp : null}
+                                    />
+                                    <View style={{
+                                        display: 'flex', flexDirection: 'column', flex: 1,
+                                        width: rpxToPx(552), height: itemHeights[index] - rpxToPx(60), backgroundColor: '#fafafa'
+                                    }}>
+                                    </View>
+                                </View>
+                            }
+
+                        }
+                        return <View id={`history-${index}`} key={index}>
+                            {
+                                historyMonth(index)
+                            }
+                            <HistoryItem
+                                data={item}
+                                preData={index > 0 ? list[index - 1] : null}
+                                index={index}
+                                mode={props.type ?? health.mode}
+                                fast_type={props.fast_type}
+                                type={props.type}
+                                hideLine={hideLine(index)}
+                                onClick={() => {
+
+                                }} />
+
+                        </View>
+                    })
+                }
+            </View>
+        }
+
+
+        {/* <View style={{ height: rpxToPx(40), flexShrink: 0, backgroundColor: '#fff' }} /> */}
+        <ListFooter noMore={(list.length > 0) && (total == list.length)} loading={loading} />
+    </View>
+})

+ 87 - 26
src/features/health/MainHistory2.tsx

@@ -19,6 +19,7 @@ import { useTranslation } from "react-i18next";
 import { setActiveTip, setEatTip, setFirstActiveId, setFirstEatId } from "@/store/health";
 import RightArrowRow from "@/_health/components/right_arrow_row";
 import TimelineDate from "@/_health/components/timeline_date";
+import VirtualList from "@tarojs/components/virtual-list";
 
 let lastMode = ''
 let myScrollTop = 0
@@ -34,13 +35,13 @@ export default forwardRef((props: { type?: string, fast_type?: string, updateDat
     const [loading, setLoading] = useState(false)
     const [showEatArchive, setShowEatArchive] = useState(true)
     const [showActiveArchive, setShowActiveArchive] = useState(true)
-    const [onlyMe,setOnlyMe] = useState(true)
+    const [onlyMe, setOnlyMe] = useState(true)
 
     const [fastList, setFastList] = useState<any>([])
     const [eatList, setEatList] = useState<any>([])
     const [activeList, setActiveList] = useState<any>([])
     const [sleepList, setSleepList] = useState<any>([])
-
+    const query = Taro.createSelectorQuery()
     const [pageTop, setPageTop] = useState(0)
 
     const dispatch = useDispatch()
@@ -60,15 +61,15 @@ export default forwardRef((props: { type?: string, fast_type?: string, updateDat
         }
     }, [list])
 
-    useEffect(()=>{
+    useEffect(() => {
         refresh()
-    },[onlyMe])
+    }, [onlyMe])
 
-    useEffect(()=>{
-        return ()=>{
+    useEffect(() => {
+        return () => {
             myScrollTop = 0
         }
-    },[])
+    }, [])
 
 
     useEffect(() => {
@@ -149,22 +150,50 @@ export default forwardRef((props: { type?: string, fast_type?: string, updateDat
     }, [health.mode])
 
     function measureItemLayouts() {
-        const query = Taro.createSelectorQuery()
-        list.forEach((item, index) => {
-            query.select(`#history-${index}`).boundingClientRect()
-        });
-        query.exec((res) => {
-            var layouts: any = []
-            var heights: any = []
-            res.forEach((rect, index) => {
-                if (rect) {
-                    layouts[index] = rect.top + myScrollTop
-                    heights[index] = rect.height
+        console.log('开始计算位置', new Date().getTime(), list.length)
+        if (list.length <= 10) {
+            list.forEach((item, index) => {
+                query.select(`#history-${index}`).boundingClientRect()
+            });
+            query.exec((res) => {
+                var layouts: any = []
+                var heights: any = []
+                res.forEach((rect, index) => {
+                    if (rect) {
+                        layouts[index] = rect.top + myScrollTop
+                        heights[index] = rect.height
+                    }
+                });
+                setItemLayouts(layouts)
+                setItemHeights(heights)
+                console.log('结束计算位置', new Date().getTime())
+            })
+        }
+        else {
+            list.forEach((item, index) => {
+                if (index >= itemLayouts.length) {
+                    query.select(`#history-${index}`).boundingClientRect()
                 }
             });
-            setItemLayouts(layouts)
-            setItemHeights(heights)
-        })
+            query.exec((res) => {
+                var layouts: any = []
+                var heights: any = []
+                // console.log(res)
+                res.forEach((rect, index) => {
+                    
+                    if (rect) {
+                        layouts[index] = rect.top + myScrollTop
+                        heights[index] = rect.height
+                    }
+                });
+                setItemLayouts([...itemLayouts,...layouts])
+                setItemHeights([...itemHeights,...heights])
+                console.log('结束计算位置', new Date().getTime())
+            })
+
+        }
+
+
     }
 
     function onScroll(e) {
@@ -347,7 +376,7 @@ export default forwardRef((props: { type?: string, fast_type?: string, updateDat
         if (props.fast_type) {
             params.fast_type = props.fast_type
         }
-        params.show_all_user = onlyMe?false:true
+        params.show_all_user = onlyMe ? false : true
         setPage(index)
         setLoading(true)
         records(params).then(res => {
@@ -603,13 +632,13 @@ export default forwardRef((props: { type?: string, fast_type?: string, updateDat
     return <View style={{ width: rpxToPx(750), marginTop: rpxToPx(60) }}>
 
         {
-            <View className="new_header_bg" style={{position:'relative'}}>
+            <View className="new_header_bg" style={{ position: 'relative' }}>
                 <Text className="h50 bold">{t('health.recents')}</Text>
                 {
-                    user.test_user && <View style={{position:'absolute',right:30,top:20}} onClick={()=>{
+                    user.test_user && <View style={{ position: 'absolute', right: 30, top: 20 }} onClick={() => {
                         setOnlyMe(!onlyMe)
 
-                    }}>{onlyMe?'仅自己':'全部用户'}</View>
+                    }}>{onlyMe ? '仅自己' : '全部用户'}</View>
                 }
                 {
                     false && (health.mode == 'EAT' || health.mode == 'ACTIVE') && <View onClick={() => {
@@ -627,6 +656,39 @@ export default forwardRef((props: { type?: string, fast_type?: string, updateDat
         {
             list.length == 0 && <NoRecord />
         }
+        {/* {
+            list.length > 0 && <VirtualList 
+                height={800}
+                item={
+                    (data)=>{
+                        const index = data.index
+                        const item = list[index]
+                        return <View id={`history-${index}`} key={index}>
+                        {
+                            historyMonth(index)
+                        }
+                        <HistoryItem
+                            data={item}
+                            preData={index > 0 ? list[index - 1] : null}
+                            index={index}
+                            mode={props.type ?? health.mode}
+                            fast_type={props.fast_type}
+                            type={props.type}
+                            hideLine={hideLine(index)}
+                            onClick={() => {
+
+                            }} />
+
+                    </View>
+                    }
+                }
+                itemData={list}
+                itemCount={list.length}
+                itemSize={150}
+                width='100%'
+
+            />
+        } */}
         {
             list.length > 0 && <View style={{ minHeight: rpxToPx(464), backgroundColor: '#fff', paddingTop: rpxToPx(60) }}>
                 {
@@ -634,7 +696,6 @@ export default forwardRef((props: { type?: string, fast_type?: string, updateDat
                         if (itemLayouts.length >= index + 1 && pageTop > 0) {
                             if (Math.abs(itemLayouts[index] - pageTop) > 3000) {
                                 return <View style={{ height: itemHeights[index] }} id={`history-${index}`}>
-                                    {/* {index} */}
                                 </View>
                             }
                             if (Math.abs(itemLayouts[index] - pageTop) > 1500) {