Leon 1 ano atrás
pai
commit
a8292f069d

+ 20 - 11
src/app.scss

@@ -59,7 +59,7 @@ page {
 
 .fast_bg_color {}
 
-.metric_tag_bg{
+.metric_tag_bg {
     height: 32px;
     padding-left: 6px;
     padding-right: 6px;
@@ -74,7 +74,7 @@ page {
     top: 1px;
 }
 
-.metric_tag_text{
+.metric_tag_text {
     height: 32px;
     line-height: 32px;
     font-size: 20px;
@@ -249,15 +249,26 @@ page {
     margin-top: 20px;
 }
 
-.cell_full {
+.cell_bg {
     background-color: #1C1C1C;
     display: flex;
-    flex-direction: row;
-    height: 96px;
+    flex-direction: column;
+    border-radius: 24px;
     margin-left: 46px;
     margin-right: 46px;
     padding-left: 40px;
     padding-right: 40px;
+}
+
+.cell_full {
+    background-color: #1C1C1C;
+    display: flex;
+    flex-direction: row;
+    height: 96px;
+    // margin-left: 46px;
+    // margin-right: 46px;
+    // padding-left: 40px;
+    // padding-right: 40px;
     align-items: center;
     border-radius: 24px;
 }
@@ -277,12 +288,9 @@ page {
     position: relative;
 }
 
-.cell_line{
-    position: absolute;
-    right: 0;
-    bottom: 0;
-    left: 40px;
-    
+.cell_line {
+    margin-left: 0px;
+    height: 1px;
     background-color: #323232;
 }
 
@@ -299,6 +307,7 @@ page {
     border-bottom-left-radius: 24px;
     border-bottom-right-radius: 24px;
 }
+
 .cell_center {
     position: relative;
     background-color: #1C1C1C;

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

@@ -189,7 +189,8 @@ export default {
                 start_sleep: 'Start sleeping',
                 started_sleeping: 'Started sleeping',
                 end_sleep: 'End sleeping',
-                ended_sleeping: 'Ended sleeping'
+                ended_sleeping: 'Ended sleeping',
+                start_fasting_first:'Start fasting first.',
             },
             change_tz_alert: {
                 title: 'New Time Zone Detected',
@@ -247,6 +248,7 @@ export default {
                 duration_goals_by_stage: 'View fasting stage goals',
                 current_stage: 'View current fasting stage',
                 timeline: 'Schedule',
+                total_time:'Total time',
                 stage: 'Stages',
 
             },
@@ -267,6 +269,11 @@ export default {
             action_sheet: {
                 change_schedule: 'Adjust schedule',
                 switch_scenario: 'Select circadian clock',
+                set_new_goals:'Set New Goals',
+                set_fast_goal:'Set Fast Goal (for this time)',
+                set_sleep_goal:'Set Sleep Goal (for this time) ',
+                edit_fasting_goal:'Edit Fasting Goal',
+                edit_sleeping_goal:'Edit Sleeping Goal',
                 cancel: 'Cancel'
             },
             dial: {

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

@@ -193,7 +193,8 @@ export default {
                 start_sleep: '开始睡眠',
                 started_sleeping: '开始睡眠',
                 end_sleep: '结束睡眠',
-                ended_sleeping: '结束睡眠'
+                ended_sleeping: '结束睡眠',
+                start_fasting_first:'开始断食后可设置',
             },
             change_tz_alert:{
                 title:'检测到新时区',
@@ -250,6 +251,7 @@ export default {
                 duration_goals_by_stage: '查看断食阶段目标',  //底部文字按钮 waite for start
                 current_stage: '查看当前断食阶段',              //底部文字按钮 onging
                 timeline: '日程',            //一级页面待开始进行中,segment index=0的值
+                total_time:'总时间',
                 stage: '阶段',
 
             },
@@ -270,6 +272,11 @@ export default {
             action_sheet: {
                 change_schedule: '调整日程',
                 switch_scenario: '选择生物钟',
+                set_new_goals:'设置新目标',
+                set_fast_goal:'设置断食目标(本次)',
+                set_sleep_goal:'设置睡眠目标(本次)',
+                edit_fasting_goal:'编辑断食目标',
+                edit_sleeping_goal:'编辑睡眠目标',
                 cancel: '取消'
             },
             dial: {

+ 237 - 0
src/features/trackTimeDuration/components/ClockHeader.tsx

@@ -0,0 +1,237 @@
+import { useTranslation } from "react-i18next";
+import TitleView from "./TitleView";
+import Taro from "@tarojs/taro";
+import { setScenario, setStep } from "@/store/scenario";
+import { updateScenario } from "@/store/time";
+import { jumpPage } from "../hooks/Common";
+import { useDispatch, useSelector } from "react-redux";
+import { useEffect, useRef, useState } from "react";
+import { durationDatas, durationIndex, getColor, getDurationTitle } from "../hooks/Console";
+import { PageContainer, View } from "@tarojs/components";
+import PickerViews from "@/components/input/PickerViews";
+import Modal from "@/components/layout/Modal.weapp";
+import { ColorType } from "@/context/themes/color";
+
+
+let GradientText
+let useNavigation;
+
+if (process.env.TARO_ENV == 'rn') {
+    GradientText = require('@/components/basic/GradientText').default
+    useNavigation = require("@react-navigation/native").useNavigation
+}
+
+export default function ClockHeader(props: { homeData: any }) {
+    const user = useSelector((state: any) => state.user);
+    const [fastPickerValue, setFastPickerValue] = useState([0, 0])
+    const [sleepPickerValue, setSleepPickerValue] = useState([0, 0])
+    const [fastDuration, setFastDuration] = useState<number>(0);
+    const [sleepDuration, setSleepDuration] = useState<number>(0);
+    const [showDurationPicker, setShowDurationPicker] = useState(false)
+    const [showEditPicker, setShowEditPicker] = useState(false)
+    const [currentRecord, setCurrentRecord] = useState(null)
+    const [isFast, setIsFast] = useState(true)
+    const common = useSelector((state: any) => state.common);
+    const durationPickerRef = useRef(null)
+
+
+    const dispatch = useDispatch();
+    const { t } = useTranslation()
+    let navigation;
+    if (useNavigation) {
+        navigation = useNavigation()
+    }
+
+    useEffect(() => {
+        if (props.homeData) {
+            setCurrentRecord(props.homeData.fast_sleep.current_record)
+            getStateDetail()
+        }
+
+    }, [props.homeData])
+
+    function getStateDetail() {
+        var current_record = props.homeData.fast_sleep.current_record
+        var fastCount = current_record.fast.target_end_time - current_record.fast.target_start_time
+        setFastDuration(fastCount)
+        setFastPickerValue(durationIndex(current_record.fast.target_start_time, current_record.fast.target_end_time, common))
+
+        var sleepCount = current_record.sleep.target_end_time - current_record.sleep.target_start_time
+        setSleepDuration(sleepCount)
+        setSleepPickerValue(durationIndex(current_record.sleep.target_start_time, current_record.sleep.target_end_time, common))
+    }
+
+
+    function tapAddBtn() {
+        var data = props.homeData.fast_sleep
+        var status = data.current_record.status
+        var itemList: any = []
+        if (status == 'WAIT_FOR_START') {
+            itemList.push(t('feature.track_time_duration.action_sheet.set_new_goals'))
+            itemList.push(t('feature.track_time_duration.action_sheet.set_fast_goal'))
+            itemList.push(t('feature.track_time_duration.action_sheet.set_sleep_goal'))
+        }
+        else if (status == 'ONGOING1') {
+            itemList.push(t('feature.track_time_duration.action_sheet.set_sleep_goal'))
+            itemList.push(t('feature.track_time_duration.action_sheet.edit_fasting_goal'))
+        }
+        else if (status == 'ONGOING2') {
+            itemList.push(t('feature.track_time_duration.action_sheet.edit_sleeping_goal'))
+            itemList.push(t('feature.track_time_duration.action_sheet.edit_fasting_goal'))
+        }
+        else if (status == 'ONGOING3') {
+            itemList.push(t('feature.track_time_duration.action_sheet.edit_fasting_goal'))
+        }
+        Taro.showActionSheet({
+            itemList: itemList
+        }).then(res => {
+            switch (res.tapIndex) {
+                case 0:
+                    {
+                        if (status == 'WAIT_FOR_START') {
+                            dispatch(setStep('fast'))
+                            dispatch(updateScenario(data.current_record))
+                            dispatch(setScenario(data.scenario));
+                            jumpPage('/pages/clock/SetSchedule', 'SetSchedule', navigation)
+                        }
+                        else if (status == 'ONGOING1') {
+                            setIsFast(false)
+                            setShowDurationPicker(true)
+                        }
+                        else if (status == 'ONGOING2') {
+                            setIsFast(false)
+                            setShowEditPicker(true)
+                        }
+                        else if (status == 'ONGOING3') {
+                            setIsFast(true)
+                            setShowEditPicker(true)
+                        }
+                    }
+                    break;
+                case 1:
+                    {
+                        if (status == 'WAIT_FOR_START') {
+                            setIsFast(true)
+                            setShowDurationPicker(true)
+                        }
+                        else if (status == 'ONGOING1') {
+                            setIsFast(true)
+                            setShowEditPicker(true)
+                        }
+                        else if (status == 'ONGOING2') {
+                            setIsFast(true)
+                            setShowEditPicker(true)
+                        }
+                    }
+                    break;
+                case 2: {
+                    if (status == 'WAIT_FOR_START') {
+                        Taro.showToast({
+                            title: t('feature.track_time_duration.common.start_fasting_first'),
+                            icon: 'none'
+                        })
+                    }
+                }
+            }
+        })
+    }
+
+    function durationPickerContent() {
+        var color = getColor(currentRecord)
+        var title = getDurationTitle(currentRecord, t)
+        return <View style={{ color: '#fff', backgroundColor: 'transparent' }}>
+
+
+            <PickerViews ref={durationPickerRef}
+                onChange={durationChange}
+                items={durationDatas(common)}
+                value={isFast ? fastPickerValue : sleepPickerValue}
+                themeColor={color}
+                title={title}
+                showBtns={true}
+                onCancel={() => {
+                    setShowDurationPicker(false)
+                }} />
+        </View>
+    }
+
+    function editPickerContent() {
+        return <View style={{ color: '#fff', backgroundColor: 'transparent' }}>
+            <PickerViews ref={durationPickerRef}
+                onChange={durationChange}
+                items={durationDatas(common)}
+                value={isFast ? fastPickerValue : sleepPickerValue}
+                themeColor={isFast ? ColorType.fast : ColorType.sleep}
+                title={isFast ? t('feature.track_time_duration.action_sheet.edit_fasting_goal') :
+                    t('feature.track_time_duration.action_sheet.edit_sleeping_goal')}
+                showBtns={true}
+                onCancel={() => {
+                    setShowEditPicker(false)
+                }} />
+        </View>
+    }
+
+    function durationChange(e) {
+        // debugger
+        // var count = (e[0] + common.duration.min) * 60 + e[1] * common.duration.step
+        var count = (e[0] + 1) * 60 + e[1] * 5
+        if (showDurationPicker) {
+            global.changeTargetDuration(count, isFast)
+        }
+        else {
+
+        }
+        setShowDurationPicker(false)
+        setShowEditPicker(false)
+    }
+
+    function modalContent() {
+        if (showDurationPicker || showEditPicker) {
+            if (process.env.TARO_ENV == 'weapp') {
+                return <Modal
+                    testInfo={null}
+                    dismiss={() => {
+                        setShowDurationPicker(false)
+                        setShowEditPicker(false)
+                    }}
+                    confirm={() => { }}>
+                    {
+                        showDurationPicker ? durationPickerContent() : editPickerContent()
+                    }
+                </Modal>
+            }
+            else if (process.env.TARO_ENV == 'rn') {
+                return <PageContainer style={{ backgroundColor: '#1c1c1c' }}
+                    // overlayStyle='background-color:rgba(0,0,0,0.9)'
+                    // custom-style='background-color:#1c1c1c'
+                    overlayStyle={{ backgroundColor: 'rgba(0,0,0,0.9)' }}
+                    customStyle={{ backgroundColor: '#1c1c1c' }}
+                    closeOnSlideDown={false}
+                    onBeforeEnter={() => {
+                        Taro.hideTabBar();
+                    }}
+                    onBeforeLeave={() => {
+                        Taro.showTabBar();
+                    }}
+                    onClick={() => { alert('b') }}
+                    onClickOverlay={() => { alert('a') }}
+                    onAfterLeave={() => { setShowDurationPicker(false); setShowEditPicker(false) }}
+                    show={showDurationPicker} round={true} overlay={true} position='bottom'
+                >
+                    {
+                        showDurationPicker ? durationPickerContent() : editPickerContent()
+                    }
+                </PageContainer>
+            }
+        }
+        return <View />
+    }
+
+
+    return <TitleView title={t('page.clock.title')} onClick={tapAddBtn} showAddBtn={user.isLogin ? true : false}>
+        {/* <StatusIndicator /> */}
+        {
+            modalContent()
+        }
+    </TitleView>
+}

+ 1 - 1
src/features/trackTimeDuration/components/IndexItem.scss

@@ -11,7 +11,7 @@
     border-radius: $boxBorderRadius;
     padding-left: 40px;
     padding-right: 40px;
-    margin-bottom: 16px;
+    // margin-bottom: 16px;
 }
 
 .modalTitle1{

+ 141 - 132
src/features/trackTimeDuration/components/IndexItem.tsx

@@ -10,6 +10,9 @@ import { TimeFormatter } from "@/utils/time_format";
 import { useSelector } from "react-redux";
 import { useEffect, useState } from "react";
 import Taro from "@tarojs/taro";
+import Modal from "@/components/layout/Modal.weapp";
+import { ModalType } from "@/utils/types";
+import TimelineStage from "./TimelineStage";
 
 let useNavigation;
 if (process.env.TARO_ENV == 'rn') {
@@ -22,6 +25,7 @@ export default function Component(props: { type: string, data: any, time: any })
     const dayNight = useSelector((state: any) => state.dayNight);
     const [stageList, setStageList] = useState([true, false, false])
     const [isStageMode, setIsStageMode] = useState(false)
+    const [showDetailModal, setShowDetailModal] = useState(false)
     let navigation;
     if (useNavigation) {
         navigation = useNavigation()
@@ -58,140 +62,117 @@ export default function Component(props: { type: string, data: any, time: any })
         common.lineWidth = 9;
         var bgRing = getBgRing()
 
-        if (props.type == 'SLEEP') {
-            var realRing = getReal(record, false, true)
-            var currentDot1 = getDot(record, true)
-            var targetBigRing1 = getTarget(record, true)
-            if (record.status == 'ONGOING') {
-                var realRing1 = getReal(record, true, false)
-
-                return <Rings common={common} bgRing={bgRing} currentDot={currentDot1} realRing={realRing1} targetRing={targetBigRing1} canvasId={props.type + props.time + 'big'} />
-            }
+        var currentDot1 = getDot(record, true)
+        var targetBigRing1 = getTarget(record, true)
+        if (record.status == 'ONGOING') {
+            var realRing1 = getReal(record, true, false)
 
-            if (record.status == 'WAIT_FOR_START' || record.status == 'ONGOING1') {
-                var realRing1 = getSchedule(record, props.type != 'SLEEP', true)
-                var currentDot1 = getDot(record, true)
-                return <Rings common={common} bgRing={bgRing} realRing={realRing1} currentDot={currentDot1} canvasId={props.type + props.time + 'big'} />
-            }
-            if (props.data.status == 'ONGOING3') {
-                realRing.color = 'rgba(0,0,0,0)'
-                // bgRing.color = 'rgba(0,0,0,0)'
-            }
-            return <Rings common={common} bgRing={bgRing} canvasId={props.type + props.time + 'big'} realRing={realRing} />
+            return <Rings common={common} bgRing={bgRing} currentDot={currentDot1} realRing={realRing1} targetRing={targetBigRing1} canvasId={props.type + props.time + 'big'} />
         }
-        else {
-            var currentDot1 = getDot(record, true)
-            var targetBigRing1 = getTarget(record, true)
-            if (record.status == 'ONGOING') {
-                var realRing1 = getReal(record, true, false)
-
-                return <Rings common={common} bgRing={bgRing} currentDot={currentDot1} realRing={realRing1} targetRing={targetBigRing1} canvasId={props.type + props.time + 'big'} />
-            }
-            if (record.status == 'WAIT_FOR_START') {
-                var realRing1 = getSchedule(record, props.type != 'SLEEP', true)
-                var list: any = []
-                if (props.type == 'FAST_SLEEP') {
-                    realRing1.color = ColorType.fast + '66'
-
-                    if (dotIsOuterRange(true, record.fast)) {
-                        currentDot1.color = ColorType.ring
-                    }
+        if (record.status == 'WAIT_FOR_START') {
+            var realRing1 = getSchedule(record, props.type != 'SLEEP', true)
+            var list: any = []
+            if (props.type == 'FAST_SLEEP') {
+                realRing1.color = ColorType.fast + '66'
 
-                    if (stageList[0]) {
+                if (dotIsOuterRange(true, record.fast)) {
+                    currentDot1.color = ColorType.ring
+                }
 
-                        const realRingBig: RealRing = {
-                            color: global.fastColor ? global.fastColor : ColorType.fast,
-                            startArc: startArc(record.fast.target_start_time),
-                            durationArc: durationArc(record.fast.target_start_time, record.sleep.target_start_time)
-                        }
+                if (stageList[0]) {
 
-                        list.push(realRingBig)
+                    const realRingBig: RealRing = {
+                        color: global.fastColor ? global.fastColor : ColorType.fast,
+                        startArc: startArc(record.fast.target_start_time),
+                        durationArc: durationArc(record.fast.target_start_time, record.sleep.target_start_time)
                     }
-                    if (stageList[1]) {
-                        const realRingBig: RealRing = {
-                            color: global.fastColor ? global.fastColor : ColorType.fast,
-                            startArc: startArc(record.sleep.target_start_time),
-                            durationArc: durationArc(record.sleep.target_start_time, record.sleep.target_end_time)
-                        }
-
-                        list.push(realRingBig)
-                    }
-                    if (stageList[2]) {
-                        const realRingBig: RealRing = {
-                            color: global.fastColor ? global.fastColor : ColorType.fast,
-                            startArc: startArc(record.sleep.target_end_time),
-                            durationArc: durationArc(record.sleep.target_end_time, record.fast.target_end_time)
-                        }
-
-                        list.push(realRingBig)
+
+                    list.push(realRingBig)
+                }
+                if (stageList[1]) {
+                    const realRingBig: RealRing = {
+                        color: global.fastColor ? global.fastColor : ColorType.fast,
+                        startArc: startArc(record.sleep.target_start_time),
+                        durationArc: durationArc(record.sleep.target_start_time, record.sleep.target_end_time)
                     }
+
+                    list.push(realRingBig)
                 }
+                if (stageList[2]) {
+                    const realRingBig: RealRing = {
+                        color: global.fastColor ? global.fastColor : ColorType.fast,
+                        startArc: startArc(record.sleep.target_end_time),
+                        durationArc: durationArc(record.sleep.target_end_time, record.fast.target_end_time)
+                    }
 
-                if (!isStageMode) {
-                    list = []
+                    list.push(realRingBig)
                 }
-                return <Rings common={common} bgRing={bgRing} currentDot={isStageMode ? null : currentDot1} stageList={list} realRing={realRing1} canvasId={props.type + props.time + 'big'} />
             }
-            var realRing1 = getReal(record, true, false)
-            return <Rings common={common} bgRing={bgRing} realRing={realRing1} currentDot={currentDot1} targetRing={targetBigRing1} canvasId={props.type + props.time + 'big'} />
+
+            if (!isStageMode) {
+                list = []
+            }
+            return <Rings common={common} bgRing={bgRing} currentDot={isStageMode ? null : currentDot1} stageList={list} realRing={realRing1} canvasId={props.type + props.time + 'big'} />
         }
+        var realRing1 = getReal(record, true, false)
+        return <Rings common={common} bgRing={bgRing} realRing={realRing1} currentDot={currentDot1} targetRing={targetBigRing1} canvasId={props.type + props.time + 'big'} />
+
     }
 
     function smallRing() {
-        if (record.scenario == 'FAST_SLEEP') {
-            var common = getCommon(null, false)
-            common.radius = 28;
-            common.lineWidth = 9;
-            var bgRing = getBgRing()
-            var realRing = getReal(record, false, false)
-            if (props.type == 'SLEEP' || props.type == 'FAST_SLEEP') {
-                if (record.sleep.status == 'WAIT_FOR_END') {
-                    var targetBigRing1 = getTarget(record, false)
-                    targetBigRing1.color = ColorType.sleep + '66'
-                    var currentDot = getDot(record, false)
-                    realRing.durationArc = durationArc(record.sleep.target_start_time, (new Date()).getTime())
-                    return <Rings common={common} bgRing={bgRing} currentDot={currentDot} canvasId={props.type + props.time + 'small'} targetRing={targetBigRing1} realRing={realRing} />
-                }
-                else if (record.status == 'WAIT_FOR_START' || record.status == 'ONGOING1') {
-                    realRing = getSchedule(record, false, true)
-                    var currentDot = getDot(record, false)
-                    if (dotIsOuterRange(true, record.sleep)) {
-                        currentDot.color = ColorType.ring
-                    }
 
-                    return <Rings common={common} bgRing={bgRing} currentDot={isStageMode ? null : currentDot} realRing={realRing} canvasId={props.type + props.time + 'small'} />
-                }
-                else if (record.sleep.status == 'NOT_COMPLETED') {
-                    realRing.durationArc = 0.01
-                    var currentDot = getDot(record, false)
-                    return <Rings common={common} bgRing={bgRing} currentDot={currentDot} canvasId={props.type + props.time + 'small'} realRing={realRing} />
-                }
-                else if (record.sleep.status == 'COMPLETED') {
-                    realRing = getReal(record, false, true)
-                    return <Rings common={common} bgRing={bgRing} canvasId={props.type + props.time + 'small'} realRing={realRing} />
-                }
-                else if (record.sleep.status == 'ONGOING2') {
-                    var currentDot = getDot(record, false)
-                    return <Rings common={common} bgRing={bgRing} currentDot={currentDot} canvasId={props.type + props.time + 'small'} />
-                }
-                return <Rings common={common} bgRing={bgRing} canvasId={props.type + props.time + 'small'} />
+        var common = getCommon(null, false)
+        common.radius = 28;
+        common.lineWidth = 9;
+        var bgRing = getBgRing()
+        var realRing = getReal(record, false, false)
+        if (props.type == 'SLEEP' || props.type == 'FAST_SLEEP') {
+            if (record.sleep.status == 'WAIT_FOR_END') {
+                var targetBigRing1 = getTarget(record, false)
+                targetBigRing1.color = ColorType.sleep + '66'
+                var currentDot = getDot(record, false)
+                realRing.durationArc = durationArc(record.sleep.target_start_time, (new Date()).getTime())
+                return <Rings common={common} bgRing={bgRing} currentDot={currentDot} canvasId={props.type + props.time + 'small'} targetRing={targetBigRing1} realRing={realRing} />
             }
-            else {
-
-
+            else if (record.status == 'WAIT_FOR_START' || record.status == 'ONGOING1') {
+                realRing = getSchedule(record, false, true)
                 var currentDot = getDot(record, false)
-                var targetRing = getTarget(record, false)
-                if (record.status == 'ONGOING2') {
-                    var realRing = getReal(record, false, false)
-                    return <Rings common={common} bgRing={bgRing} realRing={realRing} currentDot={currentDot} targetRing={targetRing} canvasId={props.type + props.time + 'small'} />
-                }
-                if (record.status == 'ONGOING3') {
-                    currentDot.color = 'rgba(0, 255, 255, 0.5)'
+                if (dotIsOuterRange(true, record.sleep)) {
+                    currentDot.color = ColorType.ring
                 }
+
+                return <Rings common={common} bgRing={bgRing} currentDot={isStageMode ? null : currentDot} realRing={realRing} canvasId={props.type + props.time + 'small'} />
+            }
+            else if (record.sleep.status == 'NOT_COMPLETED') {
+                realRing.durationArc = 0.01
+                var currentDot = getDot(record, false)
+                return <Rings common={common} bgRing={bgRing} currentDot={currentDot} canvasId={props.type + props.time + 'small'} realRing={realRing} />
+            }
+            else if (record.sleep.status == 'COMPLETED') {
+                realRing = getReal(record, false, true)
+                return <Rings common={common} bgRing={bgRing} canvasId={props.type + props.time + 'small'} realRing={realRing} />
+            }
+            else if (record.sleep.status == 'ONGOING2') {
+                var currentDot = getDot(record, false)
                 return <Rings common={common} bgRing={bgRing} currentDot={currentDot} canvasId={props.type + props.time + 'small'} />
             }
+            return <Rings common={common} bgRing={bgRing} canvasId={props.type + props.time + 'small'} />
+        }
+        else {
+
+
+            var currentDot = getDot(record, false)
+            var targetRing = getTarget(record, false)
+            if (record.status == 'ONGOING2') {
+                var realRing = getReal(record, false, false)
+                return <Rings common={common} bgRing={bgRing} realRing={realRing} currentDot={currentDot} targetRing={targetRing} canvasId={props.type + props.time + 'small'} />
+            }
+            if (record.status == 'ONGOING3') {
+                currentDot.color = 'rgba(0, 255, 255, 0.5)'
+            }
+            return <Rings common={common} bgRing={bgRing} currentDot={currentDot} canvasId={props.type + props.time + 'small'} />
         }
-        return null
+
     }
 
     function dayRing() {
@@ -205,16 +186,16 @@ export default function Component(props: { type: string, data: any, time: any })
             startArc: 0,
             durationArc: 2
         }
-        var sunRise = 24 * 60 +  6 * 60
+        var sunRise = 24 * 60 + 6 * 60
         var sunSet = 18 * 60
 
-        if (dayNight.gpsInfo && user.test_user){
+        if (dayNight.gpsInfo && user.test_user) {
             var sunRiseObj = dayNight.gpsInfo.daylights[0].sunrise
             var sunSetObj = dayNight.gpsInfo.daylights[0].sunset
-            sunRise = 24*60+parseInt(sunRiseObj.split(':')[0])*60+parseInt(sunRiseObj.split(':')[1])
-            sunSet = parseInt(sunSetObj.split(':')[0])*60+parseInt(sunSetObj.split(':')[1])
-            if (sunSetObj.indexOf('PM')!=-1){
-                sunSet+=12*60
+            sunRise = 24 * 60 + parseInt(sunRiseObj.split(':')[0]) * 60 + parseInt(sunRiseObj.split(':')[1])
+            sunSet = parseInt(sunSetObj.split(':')[0]) * 60 + parseInt(sunSetObj.split(':')[1])
+            if (sunSetObj.indexOf('PM') != -1) {
+                sunSet += 12 * 60
             }
         }
         var duration = sunRise - sunSet
@@ -286,8 +267,20 @@ export default function Component(props: { type: string, data: any, time: any })
 
     function fastDuration() {
         if (record.fast.status == 'WAIT_FOR_END') {
+
             return TimeFormatter.formateTimeDifference(record.fast.real_start_time, new Date().getTime(), false)
         }
+        if (isStageMode && record.scenario == 'FAST_SLEEP') {
+            if (stageList[0]) {
+                return TimeFormatter.durationFormate(record.fast.target_start_time, record.sleep.target_start_time)
+            }
+            if (stageList[1]) {
+                return TimeFormatter.durationFormate(record.sleep.target_start_time, record.sleep.target_end_time)
+            }
+            if (stageList[2]) {
+                return TimeFormatter.durationFormate(record.sleep.target_end_time, record.fast.target_end_time)
+            }
+        }
         return getDuration(record.fast)
     }
 
@@ -303,29 +296,39 @@ export default function Component(props: { type: string, data: any, time: any })
             jumpPage('/pages/account/ChooseAuth', 'ChooseAuth', navigation)
             return
         }
-        global.selectData = props.data
-        global.scenario = props.type
-        jumpPage('/pages/clock/Clock', 'Clock', navigation)
+        setShowDetailModal(true)
+        // global.selectData = props.data
+        // global.scenario = props.type
+        // jumpPage('/pages/clock/Clock', 'Clock', navigation)
     }
 
-    function nightDuration(){
-        if (dayNight.gpsInfo && dayNight.isMember){
+    function nightDuration() {
+        if (dayNight.gpsInfo && dayNight.isMember) {
             var sunRiseObj = dayNight.gpsInfo.daylights[0].sunrise
             var sunSetObj = dayNight.gpsInfo.daylights[0].sunset
-            var sunRise = 24*60+parseInt(sunRiseObj.split(':')[0])*60+parseInt(sunRiseObj.split(':')[1])
-            var sunSet = parseInt(sunSetObj.split(':')[0])*60+parseInt(sunSetObj.split(':')[1])
-            if (sunSetObj.indexOf('PM')!=-1){
-                sunSet+=12*60
+            var sunRise = 24 * 60 + parseInt(sunRiseObj.split(':')[0]) * 60 + parseInt(sunRiseObj.split(':')[1])
+            var sunSet = parseInt(sunSetObj.split(':')[0]) * 60 + parseInt(sunSetObj.split(':')[1])
+            if (sunSetObj.indexOf('PM') != -1) {
+                sunSet += 12 * 60
             }
 
-            var duration = (sunRise-sunSet)*60*1000
+            var duration = (sunRise - sunSet) * 60 * 1000
 
-            return TimeFormatter.calculateTimeDifference(new Date().getTime(),new Date().getTime()+duration);
-        }else {
+            return TimeFormatter.calculateTimeDifference(new Date().getTime(), new Date().getTime() + duration);
+        } else {
             return '12小时'
         }
     }
 
+    function schedules() {
+        var timestamp = new Date().getTime()//props.data.first_real_check_time
+
+        return <View style={{ display: 'flex', flexDirection: 'column' }}>
+            <TimelineStage data={record} title={t('feature.track_time_duration.record_fast_sleep.pop_title')}
+                subTitle='今天' first_real_check_time={timestamp} />
+        </View>
+    }
+
     return <View className="time_operate_item" onClick={goClock}>
         <View className="fast_sleep_item">
             {
@@ -354,12 +357,18 @@ export default function Component(props: { type: string, data: any, time: any })
                 }
             </View>
             {/* <Image className="arrow1" src={require('@/assets/images/arrow.png')} /> */}
-            <View className="record_arrow_bg" style={{ backgroundColor: global.isDebug ? 'red' : 'transparent' }}>
+            {/* <View className="record_arrow_bg" style={{ backgroundColor: global.isDebug ? 'red' : 'transparent' }}>
                 <View style={{ flex: 1 }} />
                 <Text className='recordTime'>{getArrowText()}</Text>
                 <Image className="arrow2" src={require('@/assets/images/arrow3.png')} />
-            </View>
+            </View> */}
 
         </View>
+        {
+            showDetailModal && <Modal children={schedules()}
+                modalType={ModalType.center}
+                dismiss={() => setShowDetailModal(false)}
+                confirm={() => { }} />
+        }
     </View>
 }

+ 377 - 0
src/features/trackTimeDuration/components/IndexItem的副本.tsx

@@ -0,0 +1,377 @@
+import { View, Text, Image } from "@tarojs/components";
+import { dotIsOuterRange, getBgRing, getCommon, getDot, getReal, getSchedule, getTarget } from "../hooks/RingData";
+import { RealRing, CurrentDot } from "@/features/trackTimeDuration/components/Rings";
+import Rings from "./Rings";
+import './IndexItem.scss'
+import { useTranslation } from "react-i18next";
+import { ColorType } from "@/context/themes/color";
+import { jumpPage } from "@/features/trackTimeDuration/hooks/Common";
+import { TimeFormatter } from "@/utils/time_format";
+import { useSelector } from "react-redux";
+import { useEffect, useState } from "react";
+import Taro from "@tarojs/taro";
+
+let useNavigation;
+if (process.env.TARO_ENV == 'rn') {
+    useNavigation = require("@react-navigation/native").useNavigation
+}
+export default function Component(props: { type: string, data: any, time: any }) {
+    const { t } = useTranslation()
+    const record = props.data.current_record;
+    const user = useSelector((state: any) => state.user);
+    const dayNight = useSelector((state: any) => state.dayNight);
+    const [stageList, setStageList] = useState([true, false, false])
+    const [isStageMode, setIsStageMode] = useState(false)
+    let navigation;
+    if (useNavigation) {
+        navigation = useNavigation()
+    }
+
+    useEffect(() => {
+        if (props.type == 'FAST_SLEEP') {
+            global.updateMixItem = (data) => {
+                setStageList(data)
+            }
+
+            global.changeMixIndex = (index) => {
+                setIsStageMode(index == 1)
+            }
+        }
+    }, [])
+
+    function durationArc(start_time: number, end_time: number) {
+        var duration = (end_time - start_time) / 1000;
+        return duration / (24 * 3600) * 2 * Math.PI;
+    }
+
+    const startArc = (time: number) => {
+        var date = new Date(time);
+        var hour = date.getHours();
+        var minute = date.getMinutes();
+        var second = date.getSeconds();
+        return (hour * 3600 + minute * 60 + second) / (24 * 3600) * 2 * Math.PI - Math.PI / 2.0;
+    }
+
+    function bigRing() {
+        var common = getCommon(null, true)
+        common.radius = 42;
+        common.lineWidth = 9;
+        var bgRing = getBgRing()
+
+        if (props.type == 'SLEEP') {
+            var realRing = getReal(record, false, true)
+            var currentDot1 = getDot(record, true)
+            var targetBigRing1 = getTarget(record, true)
+            if (record.status == 'ONGOING') {
+                var realRing1 = getReal(record, true, false)
+
+                return <Rings common={common} bgRing={bgRing} currentDot={currentDot1} realRing={realRing1} targetRing={targetBigRing1} canvasId={props.type + props.time + 'big'} />
+            }
+
+            if (record.status == 'WAIT_FOR_START' || record.status == 'ONGOING1') {
+                var realRing1 = getSchedule(record, props.type != 'SLEEP', true)
+                var currentDot1 = getDot(record, true)
+                return <Rings common={common} bgRing={bgRing} realRing={realRing1} currentDot={currentDot1} canvasId={props.type + props.time + 'big'} />
+            }
+            if (props.data.status == 'ONGOING3') {
+                realRing.color = 'rgba(0,0,0,0)'
+                // bgRing.color = 'rgba(0,0,0,0)'
+            }
+            return <Rings common={common} bgRing={bgRing} canvasId={props.type + props.time + 'big'} realRing={realRing} />
+        }
+        else {
+            var currentDot1 = getDot(record, true)
+            var targetBigRing1 = getTarget(record, true)
+            if (record.status == 'ONGOING') {
+                var realRing1 = getReal(record, true, false)
+
+                return <Rings common={common} bgRing={bgRing} currentDot={currentDot1} realRing={realRing1} targetRing={targetBigRing1} canvasId={props.type + props.time + 'big'} />
+            }
+            if (record.status == 'WAIT_FOR_START') {
+                var realRing1 = getSchedule(record, props.type != 'SLEEP', true)
+                var list: any = []
+                if (props.type == 'FAST_SLEEP') {
+                    realRing1.color = ColorType.fast + '66'
+
+                    if (dotIsOuterRange(true, record.fast)) {
+                        currentDot1.color = ColorType.ring
+                    }
+
+                    if (stageList[0]) {
+
+                        const realRingBig: RealRing = {
+                            color: global.fastColor ? global.fastColor : ColorType.fast,
+                            startArc: startArc(record.fast.target_start_time),
+                            durationArc: durationArc(record.fast.target_start_time, record.sleep.target_start_time)
+                        }
+
+                        list.push(realRingBig)
+                    }
+                    if (stageList[1]) {
+                        const realRingBig: RealRing = {
+                            color: global.fastColor ? global.fastColor : ColorType.fast,
+                            startArc: startArc(record.sleep.target_start_time),
+                            durationArc: durationArc(record.sleep.target_start_time, record.sleep.target_end_time)
+                        }
+
+                        list.push(realRingBig)
+                    }
+                    if (stageList[2]) {
+                        const realRingBig: RealRing = {
+                            color: global.fastColor ? global.fastColor : ColorType.fast,
+                            startArc: startArc(record.sleep.target_end_time),
+                            durationArc: durationArc(record.sleep.target_end_time, record.fast.target_end_time)
+                        }
+
+                        list.push(realRingBig)
+                    }
+                }
+
+                if (!isStageMode) {
+                    list = []
+                }
+                return <Rings common={common} bgRing={bgRing} currentDot={isStageMode ? null : currentDot1} stageList={list} realRing={realRing1} canvasId={props.type + props.time + 'big'} />
+            }
+            var realRing1 = getReal(record, true, false)
+            return <Rings common={common} bgRing={bgRing} realRing={realRing1} currentDot={currentDot1} targetRing={targetBigRing1} canvasId={props.type + props.time + 'big'} />
+        }
+    }
+
+    function smallRing() {
+        if (record.scenario == 'FAST_SLEEP') {
+            var common = getCommon(null, false)
+            common.radius = 28;
+            common.lineWidth = 9;
+            var bgRing = getBgRing()
+            var realRing = getReal(record, false, false)
+            if (props.type == 'SLEEP' || props.type == 'FAST_SLEEP') {
+                if (record.sleep.status == 'WAIT_FOR_END') {
+                    var targetBigRing1 = getTarget(record, false)
+                    targetBigRing1.color = ColorType.sleep + '66'
+                    var currentDot = getDot(record, false)
+                    realRing.durationArc = durationArc(record.sleep.target_start_time, (new Date()).getTime())
+                    return <Rings common={common} bgRing={bgRing} currentDot={currentDot} canvasId={props.type + props.time + 'small'} targetRing={targetBigRing1} realRing={realRing} />
+                }
+                else if (record.status == 'WAIT_FOR_START' || record.status == 'ONGOING1') {
+                    realRing = getSchedule(record, false, true)
+                    var currentDot = getDot(record, false)
+                    if (dotIsOuterRange(true, record.sleep)) {
+                        currentDot.color = ColorType.ring
+                    }
+
+                    return <Rings common={common} bgRing={bgRing} currentDot={isStageMode ? null : currentDot} realRing={realRing} canvasId={props.type + props.time + 'small'} />
+                }
+                else if (record.sleep.status == 'NOT_COMPLETED') {
+                    realRing.durationArc = 0.01
+                    var currentDot = getDot(record, false)
+                    return <Rings common={common} bgRing={bgRing} currentDot={currentDot} canvasId={props.type + props.time + 'small'} realRing={realRing} />
+                }
+                else if (record.sleep.status == 'COMPLETED') {
+                    realRing = getReal(record, false, true)
+                    return <Rings common={common} bgRing={bgRing} canvasId={props.type + props.time + 'small'} realRing={realRing} />
+                }
+                else if (record.sleep.status == 'ONGOING2') {
+                    var currentDot = getDot(record, false)
+                    return <Rings common={common} bgRing={bgRing} currentDot={currentDot} canvasId={props.type + props.time + 'small'} />
+                }
+                return <Rings common={common} bgRing={bgRing} canvasId={props.type + props.time + 'small'} />
+            }
+            else {
+
+
+                var currentDot = getDot(record, false)
+                var targetRing = getTarget(record, false)
+                if (record.status == 'ONGOING2') {
+                    var realRing = getReal(record, false, false)
+                    return <Rings common={common} bgRing={bgRing} realRing={realRing} currentDot={currentDot} targetRing={targetRing} canvasId={props.type + props.time + 'small'} />
+                }
+                if (record.status == 'ONGOING3') {
+                    currentDot.color = 'rgba(0, 255, 255, 0.5)'
+                }
+                return <Rings common={common} bgRing={bgRing} currentDot={currentDot} canvasId={props.type + props.time + 'small'} />
+            }
+        }
+        return null
+    }
+
+    function dayRing() {
+        var common = getCommon(null, true)
+        common.radius = 56;
+        common.lineWidth = 9;
+        var bgRing = getBgRing()
+
+        const realRingBig: RealRing = {
+            color: ColorType.night + '66',
+            startArc: 0,
+            durationArc: 2
+        }
+        var sunRise = 24 * 60 +  6 * 60
+        var sunSet = 18 * 60
+
+        if (dayNight.gpsInfo && user.test_user){
+            var sunRiseObj = dayNight.gpsInfo.daylights[0].sunrise
+            var sunSetObj = dayNight.gpsInfo.daylights[0].sunset
+            sunRise = 24*60+parseInt(sunRiseObj.split(':')[0])*60+parseInt(sunRiseObj.split(':')[1])
+            sunSet = parseInt(sunSetObj.split(':')[0])*60+parseInt(sunSetObj.split(':')[1])
+            if (sunSetObj.indexOf('PM')!=-1){
+                sunSet+=12*60
+            }
+        }
+        var duration = sunRise - sunSet
+        realRingBig.startArc = (sunSet * 60) / (24 * 3600) * 2 * Math.PI - Math.PI / 2.0;
+        realRingBig.durationArc = (duration * 60) / (24 * 3600) * 2 * Math.PI;
+
+        var currentDot = getDot(record, false)
+        if (dotIsOuterRange(false, null, { sunrise: dayNight.sunRise, sunset: dayNight.sunSet })) {
+            currentDot.color = ColorType.ring
+        }
+        else {
+            currentDot.color = ColorType.night + '66'
+        }
+
+        return <Rings common={common} bgRing={bgRing} realRing={realRingBig} currentDot={currentDot} canvasId={props.type + props.time + 'day'} />
+    }
+
+    function rings() {
+        return <View style={{ position: 'relative', zIndex: 1 }}>
+            {
+                bigRing()
+            }
+            {
+                props.type == 'FAST_SLEEP' && <View style={{ display: 'flex', position: 'absolute', left: 0, right: 0, top: 0, bottom: 0, alignItems: 'center', justifyContent: 'center' }}>
+                    {
+                        smallRing()
+                    }
+                </View>
+            }
+            {
+                props.type == 'FAST_SLEEP' && user.isLogin && global.showNightRing === true && <View style={{ display: 'flex', position: 'absolute', left: -14, top: -14, right: -14, bottom: -14 }}>
+                    {
+                        dayRing()
+                    }
+                </View>
+            }
+
+        </View>
+    }
+
+    function getArrowText() {
+        if (record.status == 'WAIT_FOR_START') {
+            return '去开始'
+        }
+        if (record.status == 'ONGOING1' && props.type == 'SLEEP') {
+            return '去开始'
+        }
+        return '去结束'
+    }
+
+    function getDuration(obj) {
+        if (!obj) {
+        }
+        if (obj.status == 'NOT_STARTED' || obj.status == 'NOT_COMPLETED') {
+            return ''
+        }
+        var start = obj.real_start_time
+        var end = obj.real_end_time
+        if (!end) {
+            end = (new Date()).getTime()
+        }
+        if (obj.status == 'WAIT_FOR_START') {
+            start = obj.target_start_time
+            end = obj.target_end_time
+        }
+        return TimeFormatter.durationFormate(start, end)
+        // return TimeFormatter.calculateTimeDifference(start, end)
+    }
+
+    function fastDuration() {
+        if (record.fast.status == 'WAIT_FOR_END') {
+            
+            return TimeFormatter.formateTimeDifference(record.fast.real_start_time, new Date().getTime(), false)
+        }
+        if (isStageMode && record.scenario=='FAST_SLEEP'){
+            if (stageList[0]){
+                return TimeFormatter.durationFormate(record.fast.target_start_time, record.sleep.target_start_time)
+            }
+            if (stageList[1]){
+                return TimeFormatter.durationFormate(record.sleep.target_start_time, record.sleep.target_end_time)
+            }
+            if (stageList[2]){
+                return TimeFormatter.durationFormate(record.sleep.target_end_time, record.fast.target_end_time)
+            }
+        }
+        return getDuration(record.fast)
+    }
+
+    function sleepDuration() {
+        if (record.sleep.status == 'WAIT_FOR_END') {
+            return TimeFormatter.formateTimeDifference(record.sleep.real_start_time, new Date().getTime(), false)
+        }
+        return getDuration(record.sleep)
+    }
+
+    function goClock() {
+        if (!user.isLogin) {
+            jumpPage('/pages/account/ChooseAuth', 'ChooseAuth', navigation)
+            return
+        }
+        global.selectData = props.data
+        global.scenario = props.type
+        jumpPage('/pages/clock/Clock', 'Clock', navigation)
+    }
+
+    function nightDuration(){
+        if (dayNight.gpsInfo && dayNight.isMember){
+            var sunRiseObj = dayNight.gpsInfo.daylights[0].sunrise
+            var sunSetObj = dayNight.gpsInfo.daylights[0].sunset
+            var sunRise = 24*60+parseInt(sunRiseObj.split(':')[0])*60+parseInt(sunRiseObj.split(':')[1])
+            var sunSet = parseInt(sunSetObj.split(':')[0])*60+parseInt(sunSetObj.split(':')[1])
+            if (sunSetObj.indexOf('PM')!=-1){
+                sunSet+=12*60
+            }
+
+            var duration = (sunRise-sunSet)*60*1000
+
+            return TimeFormatter.calculateTimeDifference(new Date().getTime(),new Date().getTime()+duration);
+        }else {
+            return '12小时'
+        }
+    }
+
+    return <View className="time_operate_item" onClick={goClock}>
+        <View className="fast_sleep_item">
+            {
+                rings()
+            }
+            <View className="duration_bg">
+                {
+                    props.type == 'FAST_SLEEP' && user.isLogin && global.showNightRing === true &&
+                    <Text className="duration_title">夜间</Text>
+                }
+                {
+                    props.type == 'FAST_SLEEP' && user.isLogin && global.showNightRing === true &&
+                    <Text className="duration_value" style={{ color: ColorType.night }}>{nightDuration()}</Text>
+                }
+                {
+                    (props.type == 'FAST' || props.type == 'FAST_SLEEP') && <Text className="duration_title">{t('feature.track_time_duration.record_fast_sleep.item.fast')}</Text>
+                }
+                {
+                    (props.type == 'FAST' || props.type == 'FAST_SLEEP') && <Text className="duration_value" style={{ color: global.fastColor ? global.fastColor : ColorType.fast }}>{fastDuration()}</Text>
+                }
+                {
+                    (props.type == 'SLEEP' || props.type == 'FAST_SLEEP') && <Text className="duration_title">{t('feature.track_time_duration.record_fast_sleep.item.sleep')}</Text>
+                }
+                {
+                    (props.type == 'SLEEP' || props.type == 'FAST_SLEEP') && <Text className="duration_value" style={{ color: global.sleepColor ? global.sleepColor : ColorType.sleep }}>{sleepDuration()}</Text>
+                }
+            </View>
+            {/* <Image className="arrow1" src={require('@/assets/images/arrow.png')} /> */}
+            {/* <View className="record_arrow_bg" style={{ backgroundColor: global.isDebug ? 'red' : 'transparent' }}>
+                <View style={{ flex: 1 }} />
+                <Text className='recordTime'>{getArrowText()}</Text>
+                <Image className="arrow2" src={require('@/assets/images/arrow3.png')} />
+            </View> */}
+
+        </View>
+    </View>
+}

+ 30 - 9
src/features/trackTimeDuration/components/RecordFastSleep.scss

@@ -1,5 +1,6 @@
 @import '@/utils/common.scss';
-.time_operate_item{
+
+.time_operate_item {
     padding-top: 40px;
     padding-bottom: 40px;
     margin-left: 46px;
@@ -11,15 +12,16 @@
     border-radius: $boxBorderRadius;
     padding-left: 40px;
     padding-right: 40px;
-    margin-bottom: 16px;
+    margin-top: 20px;
+    // margin-bottom: 16px;
 }
 
-.modalTitle1{
+.modalTitle1 {
     font-size: 40px;
     line-height: 40px;
 }
 
-.segment_detail{
+.segment_detail {
     width: 578px;
 }
 
@@ -88,7 +90,7 @@
 
 
 
-.single_check_nor{
+.single_check_nor {
     margin-bottom: 16px;
     height: 84px;
     border-radius: 42px;
@@ -103,7 +105,7 @@
     padding-right: 44px;
 }
 
-.single_check_sel{
+.single_check_sel {
     margin-bottom: 16px;
     height: 84px;
     border-radius: 42px;
@@ -118,21 +120,40 @@
     box-sizing: border-box;
 }
 
-.single_check_text_nor{
+.single_check_text_nor {
     color: $fastColor;
     font-weight: bold;
     font-size: 32px;
     flex: 1;
 }
 
-.single_check_text_sel{
+.single_check_text_sel {
     color: #000;
     font-weight: bold;
     font-size: 32px;
     flex: 1;
 }
 
-.single_checked{
+.single_checked {
     width: 48px;
     height: 48px;
+}
+
+.more_stage {
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    border-radius: 23px;
+    height: 46px;
+    padding-left: 24px;
+    padding-right: 24px;
+    background-color: #252525;
+    // margin-bottom: 20px;
+}
+
+.more_stage_text {
+    font-weight: bold;
+    color: $fastColor;
+    font-size: 20px;
+    line-height: 20px;
 }

+ 32 - 35
src/features/trackTimeDuration/components/RecordFastSleep.tsx

@@ -406,18 +406,11 @@ export default function RecordFastSleep(props: { data: any, type: string, delSuc
         common.lineWidth = 9;
         var bgRing = getBgRing()
         var realRing = getReal(record, false, true)
-        return <View>
-            <View style={{ display: 'flex', flexDirection: 'row', alignItems: 'center' }}>
-                <View style={{ position: 'relative', zIndex: 1 }}>
-                    {
-                        bigMoreRing()
-                    }
-                    <View style={{ display: 'flex', position: 'absolute', left: 0, right: 0, top: 0, bottom: 0, alignItems: 'center', justifyContent: 'center' }}>
-                        {/* {
-                            smallRing(123 + props.index)
-                        } */}
-                        <Rings common={common} bgRing={bgRing} canvasId={'hello'} realRing={realRing} />
-                    </View>
+        return <View style={{ zIndex: 10000 }}>
+            <View style={{ display: 'flex', flexDirection: 'row', alignItems: 'center', position: 'relative' }}>
+                {bigMoreRing()}
+                <View style={{ display: 'flex', position: 'absolute', left: 0, width: 99, top: 0, height: 99, alignItems: 'center', justifyContent: 'center', zIndex: 10000 }}>
+                    <Rings common={common} bgRing={bgRing} canvasId={stageCanvasId + 'small'} realRing={realRing} />
                 </View>
                 <View className="duration_bg">
                     {
@@ -515,38 +508,42 @@ export default function RecordFastSleep(props: { data: any, type: string, delSuc
                 </View>
 
             </View>
-            {
-                (props.type == 'record' || props.type == 'latest') &&
-                record.scenario == 'FAST_SLEEP' &&
-                record.sleep.status == 'COMPLETED' &&
-                <Text style={{ color: '#fff', marginTop: 20 }} onClick={(e) => {
-                    e.stopPropagation()
-                    setShowMoreModal(true)
-                    // setShowMore(!showMore)
-                }}>{showMore ? '隐藏更多' : '显示更多'}</Text>
-            }
+
         </View>
     }
 
-    return <View>
+    return <View style={{ display: 'flex', flexDirection: 'column', alignItems: 'center' }}>
         <View style={{ position: 'absolute', left: 0, top: 0, width: 0, height: 0, opacity: 0 }}>{count}</View>
         <View className="time_operate_item">
             <RecordItem canDel={record.status == 'COMPLETED'} delete={del}
                 onClick={showDetail}
             >{recordDetail()}
             </RecordItem>
-            {
-                showDetailModal && <Modal children={schedules()}
-                    modalType={ModalType.center}
-                    dismiss={() => setShowDetailModal(false)}
-                    confirm={() => { }} />
-            }
-            {
-                showMoreModal && <Modal children={moreStage()}
-                    modalType={ModalType.center}
-                    dismiss={() => setShowMoreModal(false)}
-                    confirm={() => { }} />
-            }
+
         </View>
+        {
+            (props.type == 'record' || props.type == 'latest') &&
+            record.scenario == 'FAST_SLEEP' &&
+            record.sleep.status == 'COMPLETED' &&
+            <View className="more_stage" onClick={(e) => {
+                e.stopPropagation()
+                setShowMoreModal(true)
+                // setShowMore(!showMore)
+            }}>
+                <Text className="more_stage_text">{showMore ? '隐藏更多' : '显示更多'}</Text>
+            </View>
+        }
+        {
+            showDetailModal && <Modal children={schedules()}
+                modalType={ModalType.center}
+                dismiss={() => setShowDetailModal(false)}
+                confirm={() => { }} />
+        }
+        {
+            showMoreModal && <Modal children={moreStage()}
+                modalType={ModalType.center}
+                dismiss={() => setShowMoreModal(false)}
+                confirm={() => { }} />
+        }
     </View>
 }

+ 6 - 1
src/features/trackTimeDuration/components/Rings.weapp.tsx

@@ -62,10 +62,12 @@ export default function Rings(props: {
     const user = useSelector((state: any) => state.user);
 
     useEffect(()=>{
-        drawCircle()
+        
+        // drawCircle()
     },[])
 
     useReady(() => {
+        drawCircle()
     })
 
     useEffect(() => {
@@ -121,6 +123,9 @@ export default function Rings(props: {
         const query = Taro.createSelectorQuery();
         query.select(`.${canvasId}`).fields({ node: true, size: true });
         query.exec((res) => {
+            if (props.canvasId=='hello'){
+                debugger
+            }
             if (res[0] == null) {
                 drawCircle()
                 return;

+ 1 - 1
src/features/trackTimeDuration/components/SetSchedule.weapp.tsx

@@ -193,7 +193,7 @@ export default function Component() {
     }).then(res => {
       setBtnDisable(false)
       dispatch(setStep('fast'))
-      global.checkData()
+      // global.checkData()
       Taro.navigateBack({ delta: 4 })
       global.indexPageRefresh()
     }).catch(e => {

+ 1 - 0
src/features/trackTimeDuration/components/TimelineFastSleep.tsx

@@ -140,6 +140,7 @@ export default function TimelineFastSleep(props: { data: any, title?: string, fi
         if (props.data.fast.real_start_time_zone) {
             timeZone = ' ' + props.data.fast.real_start_time_zone
         }
+        debugger
         timelineItems.push(
             {
                 status: getStatus(true, true, props.data),

+ 14 - 10
src/features/trackTimeDuration/components/TimelineStage.weapp.tsx

@@ -10,10 +10,11 @@ import { useSelector } from 'react-redux';
 import Taro from '@tarojs/taro';
 import { jumpPage } from '../hooks/Common';
 import { rpxToPx } from '@/utils/tools';
+import TotalTime from './TotalTime';
 
 
 
-export default function Component(props: { data: any, title?: string, subTitle?: string, isSchedule?: boolean,first_real_check_time?:number }) {
+export default function Component(props: { data: any, title?: string, subTitle?: string, isSchedule?: boolean, first_real_check_time?: number }) {
     // debugger
     const [segmentIndex, setSegmentIndex] = useState(0)
     const permission = useSelector((state: any) => state.permission);
@@ -29,8 +30,8 @@ export default function Component(props: { data: any, title?: string, subTitle?:
             return item.code == 'follow_wx_pub'
         })
 
-        const title = permission.wxPubFollow ?t('feature.track_time_duration.follow_wx_pub.h5_followed_title'):
-        t('feature.track_time_duration.follow_wx_pub.h5_unfollowed_title')
+        const title = permission.wxPubFollow ? t('feature.track_time_duration.follow_wx_pub.h5_followed_title') :
+            t('feature.track_time_duration.follow_wx_pub.h5_unfollowed_title')
 
         Taro.showModal({
             title: permission.wxPubFollow ? t('feature.track_time_duration.follow_wx_pub.modal_followed_title') :
@@ -56,7 +57,7 @@ export default function Component(props: { data: any, title?: string, subTitle?:
         <View className="box_header" style={{ backgroundColor: global.isDebug ? 'pink' : 'transparent' }}>
             <Text className="box_title" style={{ backgroundColor: global.isDebug ? 'red' : 'transparent' }}>{props.title ? props.title : 'Title'}</Text>
             {
-                props.isSchedule && process.env.TARO_ENV=='weapp' &&
+                props.isSchedule && process.env.TARO_ENV == 'weapp' &&
                 <Switch isOn={permission.wxPubFollow} onClick={() => followWxPub()} />
             }
         </View>
@@ -76,14 +77,16 @@ export default function Component(props: { data: any, title?: string, subTitle?:
                 </View> */}
 
                 <View style={{ position: 'relative' }}>
-                    <View style={{ opacity: segmentIndex == 0 ? 1 : 0 }}>
-                        <TimelineFastSleep data={props.data} first_real_check_time={props.first_real_check_time}/>
+                    <View style={{ opacity: segmentIndex == 0 ? 1 : 0,height:200 }}>
+                        <TotalTime record={props.data} />
+
                     </View>
                     {props.data.scenario == 'FAST_SLEEP' && <View style={{
                         opacity: segmentIndex == 1 ? 1 : 0,
-                        position: 'absolute', left: 0, top: 0, right: 0, bottom: 0,
+                        // position: 'absolute', left: 0, top: 0, right: 0, bottom: 0,
                     }}>
-                        <Stage data={props.data} />
+                        <TimelineFastSleep data={props.data} first_real_check_time={props.first_real_check_time} />
+                        {/* <Stage data={props.data} /> */}
                     </View>}
                 </View>
 
@@ -105,9 +108,10 @@ export default function Component(props: { data: any, title?: string, subTitle?:
         {
             props.data.scenario == 'FAST_SLEEP' &&
             <View style={{ marginBottom: 0 }}>
-                <Segment titles={[props.isSchedule ? t('feature.track_time_duration.schedule.timeline') :
+                <Segment titles={[
+                    t('feature.track_time_duration.schedule.total_time'),
                     t('feature.track_time_duration.record_fast_sleep.timeline'),
-                t('feature.track_time_duration.schedule.stage')]} changed={(e) => {
+                ]} changed={(e) => {
                     setSegmentIndex(e);
                     global.segmentIndex = e
                 }} />

+ 0 - 0
src/features/trackTimeDuration/components/TotalTime.scss


+ 148 - 0
src/features/trackTimeDuration/components/TotalTime.tsx

@@ -0,0 +1,148 @@
+import { View, Text, Image } from "@tarojs/components";
+import './TotalTime.scss'
+import { useTranslation } from "react-i18next";
+import { ColorType } from "@/context/themes/color";
+import { rpxToPx } from "@/utils/tools";
+import { TimeFormatter } from "@/utils/time_format";
+
+export default function TotalTime(props: { record: any }) {
+    const { t } = useTranslation()
+
+    function sleepCompleteStatus() {
+        debugger
+        if (props.record.sleep.status == "NOT_STARTED") {
+            return t('feature.common.not_started')
+        }
+        else if (props.record.sleep.status == 'NOT_COMPLETED') {
+            return t('feature.common.not_completed')
+        }
+        return TimeFormatter.durationFormate(props.record.sleep.real_start_time, props.record.sleep.real_end_time)
+    }
+
+    function fastGoingText() {
+        if (props.record.status == 'WAIT_FOR_START') {
+            return '00:00:00'
+        }
+        return TimeFormatter.formateTimeNow(props.record.fast.real_start_time)
+    }
+
+    function fastEndText() {
+        if (props.record.status == 'WAIT_FOR_START') {
+            return TimeFormatter.formateTimeDifference(new Date().getTime(), new Date().getTime() + props.record.fast.target_end_time - props.record.fast.target_start_time)
+        }
+        return TimeFormatter.countdown(props.record.fast.target_end_time)
+    }
+
+    function sleepGoingText() {
+        if (props.record.status == 'WAIT_FOR_START' || props.record.status == 'ONGOING1') {
+            return '00:00:00'
+        }
+        return TimeFormatter.formateTimeNow(props.record.sleep.real_start_time)
+    }
+
+    function sleepEndText() {
+        if (props.record.status == 'WAIT_FOR_START' || props.record.status == 'ONGOING1') {
+            return TimeFormatter.formateTimeDifference(new Date().getTime(), new Date().getTime() + props.record.sleep.target_end_time - props.record.sleep.target_start_time)
+        }
+        return TimeFormatter.countdown(props.record.sleep.target_end_time)
+    }
+
+    function fastOtherStatus() {
+        return <View>
+            <View className="cell_full" >
+                <Text className="cell_title" style={{ opacity: 0.2 }}>已进行</Text>
+                <Text className="cell_value" 
+                style={{ color: props.record.status == 'WAIT_FOR_START' ?
+                 '#fff' : ColorType.fast, 
+                 opacity: props.record.status == 'WAIT_FOR_START' ? 0.2 : 1 }}>{fastGoingText()}</Text>
+            </View>
+            <View className="cell_line" style={{ height: 1 }} />
+            <View className="cell_full" >
+                <Text className="cell_title" style={{ opacity: 0.2 }}>{new Date().getTime() < props.record.fast.target_end_time ? '距结束' : '已超时'}</Text>
+                <Text className="cell_value" style={{ opacity: 0.2 }}>{fastEndText()}</Text>
+            </View>
+        </View>
+    }
+
+    function sleepOtherStatus() {
+        return <View>
+            <View className="cell_full" >
+                <Text className="cell_title" style={{ opacity: 0.2 }}>已进行</Text>
+                <Text className="cell_value" style={{ color: props.record.status == 'WAIT_FOR_START'||props.record.status == 'ONGOING1' ?
+                 '#fff' : ColorType.sleep, 
+                 opacity: props.record.status == 'WAIT_FOR_START'||props.record.status == 'ONGOING1' ? 0.2 : 1 }}>{sleepGoingText()}</Text>
+            </View>
+            <View className="cell_line" style={{ height: 1 }} />
+            <View className="cell_full" >
+                <Text className="cell_title" style={{ opacity: 0.2 }}>{new Date().getTime() < props.record.sleep.target_end_time ? '距结束' : '已超时'}</Text>
+                <Text className="cell_value" style={{ opacity: 0.2 }}>{sleepEndText()}</Text>
+            </View>
+        </View>
+    }
+
+    return <View style={{ marginLeft: -rpxToPx(50), marginRight: -rpxToPx(50) }}>
+        {
+            props.record.fast && <View>
+                <Text className="cell_header">断食</Text>
+                <View className="cell_bg">
+                    {
+                        props.record.status == 'COMPLETED' ?
+                            <View className="cell_full" >
+                                <Text className="cell_title">实际完成</Text>
+                                <Text className="cell_value" style={{ color: ColorType.fast }}>{TimeFormatter.durationFormate(props.record.fast.real_start_time, props.record.fast.real_end_time)}</Text>
+                                <Image className="cell_arrow" src={require('@/assets/images/arrow3.png')} />
+                            </View> :
+                            <View className="cell_full" >
+                                <Text className="cell_title">本次目标</Text>
+                                <Text className="cell_value">{TimeFormatter.durationFormate(props.record.fast.target_start_time, props.record.fast.target_end_time)}</Text>
+                                <Image className="cell_arrow" src={require('@/assets/images/arrow3.png')} />
+                            </View>
+                    }
+                    <View className="cell_line" style={{ height: 1 }} />
+                    {
+                        props.record.status == 'COMPLETED' ?
+                            <View className="cell_full" >
+                                <Text className="cell_title" style={{ opacity: 0.2 }}>本次目标</Text>
+                                <Text className="cell_value" style={{ opacity: 0.2,color:'#fff' }}>{TimeFormatter.durationFormate(props.record.fast.target_start_time, props.record.fast.target_end_time)}</Text>
+                                <Image className="cell_arrow" src={require('@/assets/images/arrow3.png')} />
+                            </View> :
+                            fastOtherStatus()
+                    }
+                </View>
+
+            </View>
+        }
+        {
+            props.record.sleep && <View style={{ marginTop: 10 }}>
+                <Text className="cell_header">睡眠</Text>
+                <View className="cell_bg">
+                    {
+                        props.record.status == 'COMPLETED' || props.record.status == 'ONGOING3' ?
+                            <View className="cell_full" >
+                                <Text className="cell_title">实际完成</Text>
+                                <Text className="cell_value" style={{ color: ColorType.sleep }}>{sleepCompleteStatus()}</Text>
+                                <Image className="cell_arrow" src={require('@/assets/images/arrow3.png')} />
+                            </View> :
+                            <View className="cell_full" >
+                                <Text className="cell_title">本次目标</Text>
+                                <Text className="cell_value">{TimeFormatter.durationFormate(props.record.sleep.target_start_time, props.record.sleep.target_end_time)}</Text>
+                                <Image className="cell_arrow" src={require('@/assets/images/arrow3.png')} />
+                            </View>
+                    }
+                    <View className="cell_line" style={{ height: 1 }} />
+                    {
+                        props.record.status == 'COMPLETED' || props.record.status == 'ONGOING3' ?
+                            <View className="cell_full" >
+                                <Text className="cell_title" style={{ opacity: 0.2 }}>本次目标</Text>
+                                <Text className="cell_value" style={{ opacity: 0.2,color:'#fff' }}>{TimeFormatter.durationFormate(props.record.sleep.target_start_time, props.record.sleep.target_end_time)}</Text>
+                                <Image className="cell_arrow" src={require('@/assets/images/arrow3.png')} />
+                            </View> :
+                            sleepOtherStatus()
+                    }
+                </View>
+            </View>
+        }
+
+
+    </View>
+}

+ 11 - 3
src/features/trackTimeDuration/components/WeekCalendar.tsx

@@ -1,6 +1,6 @@
 import { View, ScrollView, Text } from "@tarojs/components";
 import './WeekCalendar.scss'
-import { useEffect, useState } from "react";
+import { useEffect, useState,useMemo,memo } from "react";
 import { ColorType } from "@/context/themes/color";
 import WeekCalendarItem from "./WeekCalendarItem";
 import { rpxToPx } from "@/utils/tools";
@@ -12,7 +12,11 @@ let timer;
 let scrollTimer;
 let isScrolling;
 let fingerDrag = false;
-export default function WeekCalendar() {
+
+const MyPage = memo(()=>{
+    return <View />
+})
+const WeekCalendar = memo(()=>{
     const [calendars, setCalendars] = useState<any>([])
     const [current, setCurrent] = useState(0)
     const [summary, setSummary] = useState<any>(null)
@@ -22,6 +26,8 @@ export default function WeekCalendar() {
     const [isLoading, setIsLoading] = useState(false)
     const pageSize = 7
 
+    console.log('sss')
+
     useEffect(() => {
         pageIndex = -1
         getRecords()
@@ -154,4 +160,6 @@ export default function WeekCalendar() {
         </View>
 
     </View>
-}
+})
+
+export default WeekCalendar;

+ 148 - 130
src/pages/clock/Index.tsx

@@ -10,7 +10,7 @@ import { getInfoSuccess } from "@/store/user";
 import { clockHome, clockSummaryRecords, clockSummaryStats, getClockRecords, getClocks } from "@/services/trackTimeDuration";
 import { updateScenario } from "@/store/time";
 import { setConfigs } from "@/store/common";
-import { setScenario } from "@/store/scenario";
+import { setScenario, setStep } from "@/store/scenario";
 import { useEffect, useState } from "react";
 import { IconPlus, IconRadioCheck, IconRadioCross } from "@/components/basic/Icons";
 import { ColorType } from "@/context/themes/color";
@@ -26,6 +26,10 @@ import { TimeFormatter } from "@/utils/time_format";
 import WeekCalendar from "@/features/trackTimeDuration/components/WeekCalendar";
 import { useTranslation } from "react-i18next";
 import { jumpPage } from "@/features/trackTimeDuration/hooks/Common";
+import Layout from "@/components/layout/layout";
+import { NaviBarTitleShowType, TemplateType } from "@/utils/types";
+import TitleView from "@/features/trackTimeDuration/components/TitleView";
+import ClockHeader from "@/features/trackTimeDuration/components/ClockHeader";
 
 let GradientText
 let useNavigation;
@@ -64,7 +68,7 @@ export default function Page() {
     const [isMulti, setIsMulti] = useState(false)
     const [records, setRecords] = useState([])
 
-    const [calendars, setCalendars] = useState([])
+    const [loaded, setLoaded] = useState(false)
 
 
     const [multiData, setMultiData] = useState([
@@ -129,13 +133,20 @@ export default function Page() {
     function getCheckData() {
         clockHome().then(res => {
             setHomeData(res as any)
+            setLoaded(true)
             global.homeData = res
+
+            if (user.isLogin) {
+                dispatch(updateScenario((res as any).fast_sleep.current_record))
+
+                dispatch(setScenario((res as any).fast_sleep.scenario));
+            }
         })
 
         getHistory()
     }
 
-    
+
 
     function getHistory() {
         if (user.isLogin)
@@ -262,6 +273,17 @@ export default function Page() {
         setModalDetail2(detail)
     }
 
+    global.changeTargetDuration = (duration: number, isFast: boolean) => {
+        var record = (homeData as any).fast_sleep.current_record
+        if (isFast) {
+            record.fast.target_end_time = record.fast.target_start_time + duration * 60 * 1000
+        }
+        else {
+            record.sleep.target_end_time = record.sleep.target_start_time + duration * 60 * 1000
+        }
+        setHomeData(JSON.parse(JSON.stringify(homeData)))
+    }
+
     function modalContent() {
         if (showModal || showModal2) {
             if (process.env.TARO_ENV == 'weapp') {
@@ -325,152 +347,148 @@ export default function Page() {
         })
     }
 
+
+
+    function headerView() {
+        return <ClockHeader homeData={homeData} />
+    }
+
     var timestamp = new Date().getTime()
 
     function render() {
-        return <View className="index_container">
-            <Text className="count">{count}</Text>
-            <IndexItem type="FAST" data={(homeData as any).fast} time={timestamp} />
-            <IndexItem type='SLEEP' data={(homeData as any).sleep} time={timestamp} />
-            <Text className="discovery">探索</Text>
-            <IndexItem type="FAST_SLEEP" data={(homeData as any).fast_sleep} time={timestamp} />
-            <Swiper className='swiper1' indicatorColor='#333'
-                indicatorActiveColor='#999'
-                current={0}
-                autoplay={false}
-                duration={300}
-                interval={300}
-                indicator-offset={[0, -30]}
-                indicator-height={30}
-                indicatorDots={(homeData as any).fast_sleep.current_record.status == 'WAIT_FOR_START'}
-                onChange={(e) => {
-                    var pageIndex = e.detail.current
-                    global.changeMixIndex(pageIndex)
-                }}
-            >
-                <SwiperItem className='swiperItem'>
-                    <IndexConsole record={(homeData as any).fast_sleep} />
-
-                </SwiperItem>
-
-                {
-                    (homeData as any).fast_sleep.current_record.status == 'WAIT_FOR_START' &&
+        return <Layout type={TemplateType.customHeader} header={headerView()} title={t('page.clock.title')} titleShowStyle={NaviBarTitleShowType.scrollToShow}>
+
+            <View className="index_container">
+                <Text className="count">{count}</Text>
+                {/* <Text className="discovery">探索</Text> */}
+                <IndexItem type="FAST_SLEEP" data={(homeData as any).fast_sleep} time={timestamp} />
+                <Swiper className='swiper1' indicatorColor='#333'
+                    indicatorActiveColor='#999'
+                    current={0}
+                    autoplay={false}
+                    duration={300}
+                    interval={300}
+                    indicator-offset={[0, -30]}
+                    indicator-height={30}
+                    indicatorDots={(homeData as any).fast_sleep.current_record.status == 'WAIT_FOR_START'}
+                    onChange={(e) => {
+                        var pageIndex = e.detail.current
+                        global.changeMixIndex(pageIndex)
+                    }}
+                >
                     <SwiperItem className='swiperItem'>
-                        <View>
-                            {
-                                isMulti ? <View>
-                                    {
-                                        multiData.map((item, index) => {
-                                            return <View className={item.checked ? "single_check_sel" : "single_check_nor"} onClick={() => {
-                                                item.checked = !item.checked
-                                                global.updateMixItem([multiData[0].checked, multiData[1].checked, multiData[2].checked])
-                                                setMultiData(JSON.parse(JSON.stringify(multiData)))
-                                                setCount((prevCounter) => prevCounter + 1)
-                                            }}>
-                                                <Text className={item.checked ? "single_check_text_sel" : "single_check_text_nor"}>{item.title}</Text>
-                                                {
-                                                    item.checked ? <Image src={require('@assets/images/check_black.png')} className="single_checked" /> :
-                                                        <IconPlus color={ColorType.fast} />
-                                                }
-                                            </View>
-                                        })
-                                    }
-                                </View> : <View>
-
-                                    <View className={selIndex == 0 ? "single_check_sel" : "single_check_nor"} onClick={() => { setSelIndex(0); global.updateMixItem([true, false, false]); setCount((prevCounter) => prevCounter + 1) }}>
-                                        <Text className={selIndex == 0 ? "single_check_text_sel" : "single_check_text_nor"}>睡前断食</Text>
+                        <IndexConsole record={(homeData as any).fast_sleep} />
+
+                    </SwiperItem>
+
+                    {
+                        (homeData as any).fast_sleep.current_record.status == 'WAIT_FOR_START' &&
+                        <SwiperItem className='swiperItem'>
+                            <View>
+                                {
+                                    isMulti ? <View>
                                         {
-                                            selIndex == 0 && <Image src={require('@assets/images/check_black.png')} className="single_checked" />
+                                            multiData.map((item, index) => {
+                                                return <View className={item.checked ? "single_check_sel" : "single_check_nor"} onClick={() => {
+                                                    item.checked = !item.checked
+                                                    global.updateMixItem([multiData[0].checked, multiData[1].checked, multiData[2].checked])
+                                                    setMultiData(JSON.parse(JSON.stringify(multiData)))
+                                                    setCount((prevCounter) => prevCounter + 1)
+                                                }}>
+                                                    <Text className={item.checked ? "single_check_text_sel" : "single_check_text_nor"}>{item.title}</Text>
+                                                    {
+                                                        item.checked ? <Image src={require('@assets/images/check_black.png')} className="single_checked" /> :
+                                                            <IconPlus color={ColorType.fast} />
+                                                    }
+                                                </View>
+                                            })
                                         }
+                                    </View> : <View>
+
+                                        <View className={selIndex == 0 ? "single_check_sel" : "single_check_nor"} onClick={() => { setSelIndex(0); global.updateMixItem([true, false, false]); setCount((prevCounter) => prevCounter + 1) }}>
+                                            <Text className={selIndex == 0 ? "single_check_text_sel" : "single_check_text_nor"}>睡前断食</Text>
+                                            {
+                                                selIndex == 0 && <Image src={require('@assets/images/check_black.png')} className="single_checked" />
+                                            }
+                                        </View>
+                                        <View className={selIndex == 1 ? "single_check_sel" : "single_check_nor"} onClick={() => { setSelIndex(1); global.updateMixItem([false, true, false]); setCount((prevCounter) => prevCounter + 1) }}>
+                                            <Text className={selIndex == 1 ? "single_check_text_sel" : "single_check_text_nor"}>睡眠中断食</Text>
+                                            {
+                                                selIndex == 1 && <Image src={require('@assets/images/check_black.png')} className="single_checked" />
+                                            }
+                                        </View>
+                                        <View className={selIndex == 2 ? "single_check_sel" : "single_check_nor"} onClick={() => { setSelIndex(2); global.updateMixItem([false, false, true]); setCount((prevCounter) => prevCounter + 1) }}>
+                                            <Text className={selIndex == 2 ? "single_check_text_sel" : "single_check_text_nor"}>起床后断食</Text>
+                                            {
+                                                selIndex == 2 && <Image src={require('@assets/images/check_black.png')} className="single_checked" />
+                                            }
+                                        </View>
                                     </View>
-                                    <View className={selIndex == 1 ? "single_check_sel" : "single_check_nor"} onClick={() => { setSelIndex(1); global.updateMixItem([false, true, false]); setCount((prevCounter) => prevCounter + 1) }}>
-                                        <Text className={selIndex == 1 ? "single_check_text_sel" : "single_check_text_nor"}>睡眠中断食</Text>
-                                        {
-                                            selIndex == 1 && <Image src={require('@assets/images/check_black.png')} className="single_checked" />
+                                }
+                                <View style={{ display: 'flex', alignItems: 'center', flexDirection: 'row', paddingRight: rpxToPx(46), width: rpxToPx(750), boxSizing: 'border-box' }}>
+                                    <View style={{ flex: 1 }} />
+                                    <Text style={{ marginRight: 10 }}>多选</Text>
+                                    <Switch color={ColorType.fast} onChange={(e) => {
+                                        setIsMulti(e.detail.value)
+                                        if (e.detail.value) {
+                                            global.updateMixItem([multiData[0].checked, multiData[1].checked, multiData[2].checked])
                                         }
-                                    </View>
-                                    <View className={selIndex == 2 ? "single_check_sel" : "single_check_nor"} onClick={() => { setSelIndex(2); global.updateMixItem([false, false, true]); setCount((prevCounter) => prevCounter + 1) }}>
-                                        <Text className={selIndex == 2 ? "single_check_text_sel" : "single_check_text_nor"}>起床后断食</Text>
-                                        {
-                                            selIndex == 2 && <Image src={require('@assets/images/check_black.png')} className="single_checked" />
+                                        else {
+                                            global.updateMixItem([selIndex == 0, selIndex == 1, selIndex == 2])
                                         }
-                                    </View>
+                                        setCount((prevCounter) => prevCounter + 1)
+                                    }} />
                                 </View>
-                            }
-                            <View style={{ display: 'flex', alignItems: 'center', flexDirection: 'row', paddingRight: rpxToPx(46), width: rpxToPx(750), boxSizing: 'border-box' }}>
-                                <View style={{ flex: 1 }} />
-                                <Text style={{ marginRight: 10 }}>多选</Text>
-                                <Switch color={ColorType.fast} onChange={(e) => {
-                                    setIsMulti(e.detail.value)
-                                    if (e.detail.value) {
-                                        global.updateMixItem([multiData[0].checked, multiData[1].checked, multiData[2].checked])
-                                    }
-                                    else {
-                                        global.updateMixItem([selIndex == 0, selIndex == 1, selIndex == 2])
-                                    }
-                                    setCount((prevCounter) => prevCounter + 1)
-                                }} />
                             </View>
-                        </View>
-                    </SwiperItem>
-                }
-
-            </Swiper>
-            {
-                user.isLogin && <DayLight />
-            }
-            {
-                user.isLogin && records.length > 0 && <View style={{ display: 'flex', flexDirection: 'row', justifyContent: 'space-between' }}>
-                    {
-                        <Text className="discovery">最近</Text>
-                    }
-                    {
-                        process.env.TARO_ENV == 'weapp' && <Text className="fast_sleep_more index_more" onClick={more}>{t('feature.track_time_duration.record_fast_sleep.header.btn_show_all')}</Text>
+                        </SwiperItem>
                     }
-                    {
-                        process.env.TARO_ENV == 'rn' && <GradientText onClick={more} style={{ fontSize: rpxToPx(32), fontWeight: 'bold' }}>{t('feature.track_time_duration.record_fast_sleep.header.btn_show_all')}</GradientText>
-                        //<Text className="header_action fast_sleep_text"  onClick={() => { props.action!() }}>{t('feature.track_time_duration.record_fast_sleep.header.btn_show_all')}</Text>
-                    }
-                </View>
-            }
-
-            {
-                records.length > 0 && <View className="fast_sleep_item_bg">
-                    <RecordFastSleep data={records[0]} type='record' delSuccess={() => { }} index={-20000}/>
-                </View>
-            }
-
-            {
-                user.isLogin && <View>
-                    <Text className="discovery">周统计</Text>
-                    <WeekCalendar />
-                </View>
-            }
 
+                </Swiper>
+                {
+                    user.isLogin && <DayLight />
+                }
+                {
+                    user.isLogin && records.length > 0 && <View style={{ display: 'flex', flexDirection: 'row', justifyContent: 'space-between' }}>
+                        {
+                            <Text className="discovery">最近</Text>
+                        }
+                        {
+                            process.env.TARO_ENV == 'weapp' && <Text className="fast_sleep_more index_more" onClick={more}>{t('feature.track_time_duration.record_fast_sleep.header.btn_show_all')}</Text>
+                        }
+                        {
+                            process.env.TARO_ENV == 'rn' && <GradientText onClick={more} style={{ fontSize: rpxToPx(32), fontWeight: 'bold' }}>{t('feature.track_time_duration.record_fast_sleep.header.btn_show_all')}</GradientText>
+                        }
+                    </View>
+                }
 
-            {/* 
-            <View style={{ marginTop: 50 }}>
-                <Text>Multi Sel</Text>
                 {
-                    rings()
+                    records.length > 0 && <View className="fast_sleep_item_bg">
+                        <RecordFastSleep data={records[0]} type='record' delSuccess={() => { }} index={-20000} />
+                    </View>
                 }
 
-            </View> */}
+                {
+                    user.isLogin && <View>
+                        <Text className="discovery">周统计</Text>
+                        <WeekCalendar />
+                    </View>
+                }
 
-            <View style={{ height: 100 }} />
-            {
-                modalContent()
-            }
-            <Tabbar index={0} />
-        </View>
+                <View style={{ height: 100 }} />
+                {
+                    modalContent()
+                }
+                <Tabbar index={0} />
+            </View>
+        </Layout>
     }
 
-    if (process.env.TARO_ENV == 'rn') {
-        return <ScrollView>
-            {
-                render()
-            }
-        </ScrollView>
-    }
+    // if (process.env.TARO_ENV == 'rn') {
+    //     return <ScrollView>
+    //         {
+    //             render()
+    //         }
+    //     </ScrollView>
+    // }
     return render()
 }

+ 465 - 0
src/pages/clock/Index的副本.tsx

@@ -0,0 +1,465 @@
+import { View, Text, Image, ScrollView, PageContainer, Swiper, SwiperItem, Switch } from "@tarojs/components";
+import Tabbar from "@/components/navigation/TabBar";
+import IndexItem from '@/features/trackTimeDuration/components/IndexItem';
+import Rings from "@/features/trackTimeDuration/components/Rings";
+import './Index.scss'
+import { useDispatch, useSelector } from "react-redux";
+import { useDidShow, useReady } from "@tarojs/taro";
+import Taro from "@tarojs/taro";
+import { getInfoSuccess } from "@/store/user";
+import { clockHome, clockSummaryRecords, clockSummaryStats, getClockRecords, getClocks } from "@/services/trackTimeDuration";
+import { updateScenario } from "@/store/time";
+import { setConfigs } from "@/store/common";
+import { setScenario } from "@/store/scenario";
+import { useEffect, useState } from "react";
+import { IconPlus, IconRadioCheck, IconRadioCross } from "@/components/basic/Icons";
+import { ColorType } from "@/context/themes/color";
+import { getBgRing, getCommon, getDot, getSchedule } from "@/features/trackTimeDuration/hooks/RingData";
+import { RealRing, CurrentDot } from "@/features/trackTimeDuration/components/Rings";
+import IndexConsole from "@/features/trackTimeDuration/components/IndexConsole";
+import Modal from '@/components/layout/Modal'
+import { rpxToPx } from "@/utils/tools";
+import RecordFastSleep from "@/features/trackTimeDuration/components/RecordFastSleep";
+import DayLight from "@/features/trackTimeDuration/components/DayLight";
+import { getInfo } from "@/services/user";
+import { TimeFormatter } from "@/utils/time_format";
+import WeekCalendar from "@/features/trackTimeDuration/components/WeekCalendar";
+import { useTranslation } from "react-i18next";
+import { jumpPage } from "@/features/trackTimeDuration/hooks/Common";
+
+let GradientText
+let useNavigation;
+
+if (process.env.TARO_ENV == 'rn') {
+    GradientText = require('@/components/basic/GradientText').default
+    useNavigation = require("@react-navigation/native").useNavigation
+}
+
+export default function Page() {
+    const dispatch = useDispatch();
+    global.dispatch = dispatch;
+    let navigation;
+    if (useNavigation) {
+        navigation = useNavigation()
+    }
+
+    const { t } = useTranslation()
+    const user = useSelector((state: any) => state.user);
+    const time = useSelector((state: any) => state.time);
+    const [showErrorPage, setErrorPage] = useState(false)
+    const [data, setData] = useState(null)
+    const [count, setCount] = useState(0)
+    const [homeData, setHomeData] = useState(null)
+
+    const [selIndex, setSelIndex] = useState(0)
+    const [showModal, setShowModal] = useState(false)
+    const [modalDetail, setModalDetail] = useState<any>(null)
+
+    const [showModal2, setShowModal2] = useState(false)
+    const [modalDetail2, setModalDetail2] = useState<any>(null)
+
+    const [isModal1, setIsModal1] = useState(false)
+    const [debugInfo, setDebugInfo] = useState(null)
+
+    const [isMulti, setIsMulti] = useState(false)
+    const [records, setRecords] = useState([])
+
+    const [calendars, setCalendars] = useState([])
+
+
+    const [multiData, setMultiData] = useState([
+        {
+            title: '睡前断食',
+            checked: false
+        },
+        {
+            title: '睡眠中断食',
+            checked: false
+        },
+        {
+            title: '起床后断食',
+            checked: false
+        },
+    ])
+
+    useEffect(() => {
+        global.showNightRing = false;
+        setInterval(() => {
+            setCount((prevCounter) => prevCounter + 1)
+        }, 1000)
+    }, [])
+
+    useEffect(() => {
+        getCheckData()
+    }, [user.isLogin, time.status])
+
+    useReady(async () => {
+        const userData = await getStorage('userData');
+        if (userData) {
+            dispatch(getInfoSuccess(JSON.parse(userData as string)) as any);
+            // setTimeout(() => {
+            //     // checkWXPubFollow()
+            //     getCheckData()
+
+            // }, 200)
+            getHistory()
+
+
+        }
+
+    })
+
+    useDidShow(() => {
+        if (user.isLogin)
+            refresh()
+    })
+
+    global.refreshIndex = () => {
+        setCount((prevCounter) => prevCounter + 1)
+    }
+
+    function refresh() {
+        getInfo().then(res => {
+            dispatch(getInfoSuccess(res))
+        }).catch(e => {
+
+        })
+    }
+
+    function getCheckData() {
+        clockHome().then(res => {
+            setHomeData(res as any)
+            global.homeData = res
+        })
+
+        getHistory()
+    }
+
+    
+
+    function getHistory() {
+        if (user.isLogin)
+            getClockRecords({
+                page: 1,
+                limit: 1,
+                completed: true
+            }).then(res => {
+                setRecords((res as any).data)
+            })
+    }
+
+    const startArc = (time: number) => {
+        var date = new Date(time);
+        var hour = date.getHours();
+        var minute = date.getMinutes();
+        var second = date.getSeconds();
+        return (hour * 3600 + minute * 60 + second) / (24 * 3600) * 2 * Math.PI - Math.PI / 2.0;
+    }
+
+    const durationArc = (start_time: number, end_time: number) => {
+        var duration = (end_time - start_time) / 1000;
+        return duration / (24 * 3600) * 2 * Math.PI;
+    }
+
+    function bigRing() {
+        var currentRecord = (homeData as any).fast_sleep.current_record
+
+        var common = getCommon(null, true)
+        common.radius = 42;
+        common.lineWidth = 9;
+        var bgRing = getBgRing()
+        var realRing1 = getSchedule(currentRecord, true, true)
+        realRing1.color = ColorType.fast + '66'
+
+        var list: any = []
+        if (multiData[0].checked) {
+
+            const realRingBig: RealRing = {
+                color: global.fastColor ? global.fastColor : ColorType.fast,
+                startArc: startArc(currentRecord.fast.target_start_time),
+                durationArc: durationArc(currentRecord.fast.target_start_time, currentRecord.sleep.target_start_time)
+            }
+
+            list.push(realRingBig)
+        }
+        if (multiData[1].checked) {
+            const realRingBig: RealRing = {
+                color: global.fastColor ? global.fastColor : ColorType.fast,
+                startArc: startArc(currentRecord.sleep.target_start_time),
+                durationArc: durationArc(currentRecord.sleep.target_start_time, currentRecord.sleep.target_end_time)
+            }
+
+            list.push(realRingBig)
+        }
+        if (multiData[2].checked) {
+            const realRingBig: RealRing = {
+                color: global.fastColor ? global.fastColor : ColorType.fast,
+                startArc: startArc(currentRecord.sleep.target_end_time),
+                durationArc: durationArc(currentRecord.sleep.target_end_time, currentRecord.fast.target_end_time)
+            }
+
+            list.push(realRingBig)
+        }
+
+        var points: any = []
+        for (var i = 0; i < 12; i++) {
+            var dot: CurrentDot = {
+                color: 'red',
+                lineWidth: 8,
+                borderColor: 'black',
+                timestamp: new Date().getTime() + i * 3600 * 1000 * 2
+            }
+            points.push(dot)
+        }
+        return <Rings common={common} bgRing={bgRing} realRing={realRing1} stageList={list} dotList={points} canvasId={'testA'} />
+
+    }
+
+    function smallRing() {
+        var common = getCommon(null, true)
+        common.radius = 28;
+        common.lineWidth = 9;
+        var bgRing = getBgRing()
+        var realRing1 = getSchedule((homeData as any).fast_sleep.current_record, false, false)
+        return <Rings common={common} bgRing={bgRing} realRing={realRing1} canvasId={'testB'} />
+    }
+
+    function rings() {
+        return <View style={{ display: 'flex', flexDirection: 'row', marginLeft: 100, marginBottom: 30 }}>
+            <View style={{ position: 'relative', zIndex: 1 }}>
+                {
+                    bigRing()
+                }
+                {
+                    <View style={{ display: 'flex', position: 'absolute', left: 0, right: 0, top: 0, bottom: 0, alignItems: 'center', justifyContent: 'center' }}>
+                        {
+                            smallRing()
+                        }
+                    </View>
+                }
+
+            </View>
+        </View>
+    }
+
+    global.indexPageRefresh = () => {
+        getCheckData()
+    }
+
+    global.showIndexModal = (isShow: boolean, detail: any, debugNode?: any) => {
+        global.showModal = isShow
+        setIsModal1(true)
+        setDebugInfo(debugNode)
+        setShowModal(isShow)
+        setModalDetail(detail)
+    }
+
+    global.showIndexModal2 = (isShow: boolean, detail: any) => {
+        setDebugInfo(null)
+        global.showModal = isShow
+        setIsModal1(false)
+        setShowModal2(isShow)
+        setModalDetail2(detail)
+    }
+
+    function modalContent() {
+        if (showModal || showModal2) {
+            if (process.env.TARO_ENV == 'weapp') {
+                return <Modal
+                    testInfo={debugInfo}
+                    dismiss={() => {
+                        setDebugInfo(null)
+                        setShowModal(false); setShowModal2(false)
+                    }}
+                    confirm={() => { }}>
+                    {
+                        isModal1 ? modalDetail : modalDetail2
+                    }
+                </Modal>
+            }
+            else if (process.env.TARO_ENV == 'rn') {
+                return <PageContainer style={{ backgroundColor: '#1c1c1c' }}
+                    // overlayStyle='background-color:rgba(0,0,0,0.9)'
+                    // custom-style='background-color:#1c1c1c'
+                    overlayStyle={{ backgroundColor: 'rgba(0,0,0,0.9)' }}
+                    customStyle={{ backgroundColor: '#1c1c1c' }}
+                    closeOnSlideDown={false}
+                    onBeforeEnter={() => {
+                        Taro.hideTabBar();
+                    }}
+                    onBeforeLeave={() => {
+                        Taro.showTabBar();
+                    }}
+                    onClick={() => { alert('b') }}
+                    onClickOverlay={() => { alert('a') }}
+                    onAfterLeave={() => { setShowModal(false); setShowModal2(false) }}
+                    show={showModal || showModal2} round={true} overlay={true} position='bottom'
+                >
+                    {
+                        isModal1 ? modalDetail : modalDetail2
+                    }
+                </PageContainer>
+            }
+        }
+        return <View />
+    }
+
+    async function getStorage(key: string) {
+        try {
+            const res = await Taro.getStorage({ key });
+            return res.data;
+        } catch {
+            return '';
+        }
+    }
+    if (!homeData) {
+        return <View>
+            <Tabbar index={0} />
+        </View>
+    }
+
+    function more() {
+        jumpPage('/pages/common/RecordsHistory?type=time&title=time', 'RecordsHistory', navigation, {
+            type: 'time',
+            title: 'time'
+        })
+    }
+
+    var timestamp = new Date().getTime()
+
+    function render() {
+        return <View className="index_container">
+            <Text className="count">{count}</Text>
+            <IndexItem type="FAST" data={(homeData as any).fast} time={timestamp} />
+            <IndexItem type='SLEEP' data={(homeData as any).sleep} time={timestamp} />
+            <Text className="discovery">探索</Text>
+            <IndexItem type="FAST_SLEEP" data={(homeData as any).fast_sleep} time={timestamp} />
+            <Swiper className='swiper1' indicatorColor='#333'
+                indicatorActiveColor='#999'
+                current={0}
+                autoplay={false}
+                duration={300}
+                interval={300}
+                indicator-offset={[0, -30]}
+                indicator-height={30}
+                indicatorDots={(homeData as any).fast_sleep.current_record.status == 'WAIT_FOR_START'}
+                onChange={(e) => {
+                    var pageIndex = e.detail.current
+                    global.changeMixIndex(pageIndex)
+                }}
+            >
+                <SwiperItem className='swiperItem'>
+                    <IndexConsole record={(homeData as any).fast_sleep} />
+
+                </SwiperItem>
+
+                {
+                    (homeData as any).fast_sleep.current_record.status == 'WAIT_FOR_START' &&
+                    <SwiperItem className='swiperItem'>
+                        <View>
+                            {
+                                isMulti ? <View>
+                                    {
+                                        multiData.map((item, index) => {
+                                            return <View className={item.checked ? "single_check_sel" : "single_check_nor"} onClick={() => {
+                                                item.checked = !item.checked
+                                                global.updateMixItem([multiData[0].checked, multiData[1].checked, multiData[2].checked])
+                                                setMultiData(JSON.parse(JSON.stringify(multiData)))
+                                                setCount((prevCounter) => prevCounter + 1)
+                                            }}>
+                                                <Text className={item.checked ? "single_check_text_sel" : "single_check_text_nor"}>{item.title}</Text>
+                                                {
+                                                    item.checked ? <Image src={require('@assets/images/check_black.png')} className="single_checked" /> :
+                                                        <IconPlus color={ColorType.fast} />
+                                                }
+                                            </View>
+                                        })
+                                    }
+                                </View> : <View>
+
+                                    <View className={selIndex == 0 ? "single_check_sel" : "single_check_nor"} onClick={() => { setSelIndex(0); global.updateMixItem([true, false, false]); setCount((prevCounter) => prevCounter + 1) }}>
+                                        <Text className={selIndex == 0 ? "single_check_text_sel" : "single_check_text_nor"}>睡前断食</Text>
+                                        {
+                                            selIndex == 0 && <Image src={require('@assets/images/check_black.png')} className="single_checked" />
+                                        }
+                                    </View>
+                                    <View className={selIndex == 1 ? "single_check_sel" : "single_check_nor"} onClick={() => { setSelIndex(1); global.updateMixItem([false, true, false]); setCount((prevCounter) => prevCounter + 1) }}>
+                                        <Text className={selIndex == 1 ? "single_check_text_sel" : "single_check_text_nor"}>睡眠中断食</Text>
+                                        {
+                                            selIndex == 1 && <Image src={require('@assets/images/check_black.png')} className="single_checked" />
+                                        }
+                                    </View>
+                                    <View className={selIndex == 2 ? "single_check_sel" : "single_check_nor"} onClick={() => { setSelIndex(2); global.updateMixItem([false, false, true]); setCount((prevCounter) => prevCounter + 1) }}>
+                                        <Text className={selIndex == 2 ? "single_check_text_sel" : "single_check_text_nor"}>起床后断食</Text>
+                                        {
+                                            selIndex == 2 && <Image src={require('@assets/images/check_black.png')} className="single_checked" />
+                                        }
+                                    </View>
+                                </View>
+                            }
+                            <View style={{ display: 'flex', alignItems: 'center', flexDirection: 'row', paddingRight: rpxToPx(46), width: rpxToPx(750), boxSizing: 'border-box' }}>
+                                <View style={{ flex: 1 }} />
+                                <Text style={{ marginRight: 10 }}>多选</Text>
+                                <Switch color={ColorType.fast} onChange={(e) => {
+                                    setIsMulti(e.detail.value)
+                                    if (e.detail.value) {
+                                        global.updateMixItem([multiData[0].checked, multiData[1].checked, multiData[2].checked])
+                                    }
+                                    else {
+                                        global.updateMixItem([selIndex == 0, selIndex == 1, selIndex == 2])
+                                    }
+                                    setCount((prevCounter) => prevCounter + 1)
+                                }} />
+                            </View>
+                        </View>
+                    </SwiperItem>
+                }
+
+            </Swiper>
+            {
+                user.isLogin && <DayLight />
+            }
+            {
+                user.isLogin && records.length > 0 && <View style={{ display: 'flex', flexDirection: 'row', justifyContent: 'space-between' }}>
+                    {
+                        <Text className="discovery">最近</Text>
+                    }
+                    {
+                        process.env.TARO_ENV == 'weapp' && <Text className="fast_sleep_more index_more" onClick={more}>{t('feature.track_time_duration.record_fast_sleep.header.btn_show_all')}</Text>
+                    }
+                    {
+                        process.env.TARO_ENV == 'rn' && <GradientText onClick={more} style={{ fontSize: rpxToPx(32), fontWeight: 'bold' }}>{t('feature.track_time_duration.record_fast_sleep.header.btn_show_all')}</GradientText>
+                    }
+                </View>
+            }
+
+            {
+                records.length > 0 && <View className="fast_sleep_item_bg">
+                    <RecordFastSleep data={records[0]} type='record' delSuccess={() => { }} index={-20000}/>
+                </View>
+            }
+
+            {
+                user.isLogin && <View>
+                    <Text className="discovery">周统计</Text>
+                    <WeekCalendar />
+                </View>
+            } 
+
+            <View style={{ height: 100 }} />
+            {
+                modalContent()
+            }
+            <Tabbar index={0} />
+        </View>
+    }
+
+    if (process.env.TARO_ENV == 'rn') {
+        return <ScrollView>
+            {
+                render()
+            }
+        </ScrollView>
+    }
+    return render()
+}

+ 50 - 0
src/pages/demo.scss

@@ -1,3 +1,4 @@
+@import '@/utils/common.scss';
 .virtual-waterfall-0-left{
     height: 0;
 }
@@ -27,4 +28,53 @@
     // background-color: paleturquoise;
     margin-left: 20px;
     margin-bottom: 20px;
+}
+
+.single_check_nor{
+    margin-bottom: 16px;
+    height: 84px;
+    border-radius: 42px;
+    border: solid 4px $fastColor;
+    box-sizing: border-box;
+    margin-left: 46px;
+    margin-right: 46px;
+    display: flex;
+    flex-direction: row;
+    align-items: center;
+    padding-left: 44px;
+    padding-right: 44px;
+}
+
+.single_check_sel{
+    margin-bottom: 16px;
+    height: 84px;
+    border-radius: 42px;
+    background-color: $fastColor;
+    margin-left: 46px;
+    margin-right: 46px;
+    display: flex;
+    flex-direction: row;
+    align-items: center;
+    padding-left: 44px;
+    padding-right: 44px;
+    box-sizing: border-box;
+}
+
+.single_check_text_nor{
+    color: $fastColor;
+    font-weight: bold;
+    font-size: 32px;
+    flex: 1;
+}
+
+.single_check_text_sel{
+    color: #000;
+    font-weight: bold;
+    font-size: 32px;
+    flex: 1;
+}
+
+.single_checked{
+    width: 48px;
+    height: 48px;
 }

+ 26 - 3
src/pages/demo.tsx

@@ -1,7 +1,7 @@
 import MoveList from '@/features/trackSomething/components/MoveList';
 import MoveOrderList from '@/features/trackSomething/components/MoveOrderList';
 import { rpxToPx } from '@/utils/tools';
-import { Canvas, View, Text, PageContainer, ScrollView,Image } from '@tarojs/components';
+import { Canvas, View, Text, PageContainer, ScrollView, Image } from '@tarojs/components';
 
 import { MovableArea, MovableView } from "@tarojs/components";
 import VirtualList from '@tarojs/components/virtual-list';
@@ -17,6 +17,8 @@ import Timer from '@/components/basic/Timer';
 
 
 export default function Demo() {
+  const [selIndex, setSelIndex] = useState(0)
+  
   // 定义一个二维数组
   const array: number[][] = [];
 
@@ -28,7 +30,28 @@ export default function Demo() {
   console.log(array)
   return (
     <View>
-      <Timer />
+      <View>
+
+        <View className={selIndex == 0 ? "single_check_sel" : "single_check_nor"} onClick={() => { setSelIndex(0); global.updateMixItem([true, false, false]); setCount((prevCounter) => prevCounter + 1) }}>
+          <Text className={selIndex == 0 ? "single_check_text_sel" : "single_check_text_nor"}>睡前断食</Text>
+          {
+            selIndex == 0 && <Image src={require('@assets/images/check_black.png')} className="single_checked" />
+          }
+        </View>
+        <View className={selIndex == 1 ? "single_check_sel" : "single_check_nor"} onClick={() => { setSelIndex(1); global.updateMixItem([false, true, false]); setCount((prevCounter) => prevCounter + 1) }}>
+          <Text className={selIndex == 1 ? "single_check_text_sel" : "single_check_text_nor"}>睡眠中断食</Text>
+          {
+            selIndex == 1 && <Image src={require('@assets/images/check_black.png')} className="single_checked" />
+          }
+        </View>
+        <View className={selIndex == 2 ? "single_check_sel" : "single_check_nor"} onClick={() => { setSelIndex(2); global.updateMixItem([false, false, true]); setCount((prevCounter) => prevCounter + 1) }}>
+          <Text className={selIndex == 2 ? "single_check_text_sel" : "single_check_text_nor"}>起床后断食</Text>
+          {
+            selIndex == 2 && <Image src={require('@assets/images/check_black.png')} className="single_checked" />
+          }
+        </View>
+      </View>
+      {/* <Timer />
 
       <ScrollView scrollX scrollY enableFlex className='demoMain'>
         {
@@ -43,7 +66,7 @@ export default function Demo() {
             </View>
           })
         }
-      </ScrollView>
+      </ScrollView> */}
     </View>
   )
 }

+ 1 - 0
src/utils/time_format.ts

@@ -318,6 +318,7 @@ export class TimeFormatter {
   }
   //格式化时间间隔
   static formateTimeDifference(startTimestamp: number, endTimestamp: number, ingoreSeconds?: boolean): string {
+    debugger
     const diff = Math.abs(endTimestamp - startTimestamp);
     // 计算小时、分钟和秒数
     const hours = Math.floor(diff / (1000 * 60 * 60));