leon 2 년 전
부모
커밋
004bba581d

파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 480 - 394
dist/pages/Clock.js


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 0 - 0
dist/pages/Clock.js.map


+ 2 - 2
dist/pages/Clock.wxss

@@ -227,8 +227,8 @@
   position: absolute;
   bottom: 0;
   width: 100%;
-  min-height: 600rpx;
-  max-height: 950rpx;
+  min-height: 900rpx;
+  max-height: 900rpx;
   background-color: #FFF;
   -webkit-transform: translate3d(0, 100%, 0);
           transform: translate3d(0, 100%, 0);

+ 6 - 6
dist/prebundle/remoteEntry.js

@@ -30,12 +30,12 @@ var moduleMap = {
 	"./xstate": function() {
 		return Promise.all([__webpack_require__.e("vendors-node_modules_taro_weapp_prebundle_chunk-77KB62LY_js"), __webpack_require__.e("vendors-node_modules_taro_weapp_prebundle_chunk-3EXGJ5BE_js"), __webpack_require__.e("vendors-node_modules_taro_weapp_prebundle_xstate_js")]).then(function() { return function() { return (__webpack_require__(/*! ./node_modules/.taro/weapp/prebundle/xstate.js */ "./node_modules/.taro/weapp/prebundle/xstate.js")); }; });
 	},
-	"./taro-ui": function() {
-		return Promise.all([__webpack_require__.e("vendors-node_modules_taro_weapp_prebundle_chunk-77KB62LY_js"), __webpack_require__.e("vendors-node_modules_taro_weapp_prebundle_chunk-3EXGJ5BE_js"), __webpack_require__.e("vendors-node_modules_taro_weapp_prebundle_chunk-LNJCN3VW_js"), __webpack_require__.e("vendors-node_modules_taro_weapp_prebundle_chunk-6GAVBEBQ_js"), __webpack_require__.e("vendors-node_modules_taro_weapp_prebundle_taro-ui_js")]).then(function() { return function() { return (__webpack_require__(/*! ./node_modules/.taro/weapp/prebundle/taro-ui.js */ "./node_modules/.taro/weapp/prebundle/taro-ui.js")); }; });
-	},
 	"./i18next": function() {
 		return __webpack_require__.e("vendors-node_modules_taro_weapp_prebundle_i18next_js").then(function() { return function() { return (__webpack_require__(/*! ./node_modules/.taro/weapp/prebundle/i18next.js */ "./node_modules/.taro/weapp/prebundle/i18next.js")); }; });
 	},
+	"./taro-ui": function() {
+		return Promise.all([__webpack_require__.e("vendors-node_modules_taro_weapp_prebundle_chunk-77KB62LY_js"), __webpack_require__.e("vendors-node_modules_taro_weapp_prebundle_chunk-3EXGJ5BE_js"), __webpack_require__.e("vendors-node_modules_taro_weapp_prebundle_chunk-LNJCN3VW_js"), __webpack_require__.e("vendors-node_modules_taro_weapp_prebundle_chunk-6GAVBEBQ_js"), __webpack_require__.e("vendors-node_modules_taro_weapp_prebundle_taro-ui_js")]).then(function() { return function() { return (__webpack_require__(/*! ./node_modules/.taro/weapp/prebundle/taro-ui.js */ "./node_modules/.taro/weapp/prebundle/taro-ui.js")); }; });
+	},
 	"./react/jsx-runtime": function() {
 		return Promise.all([__webpack_require__.e("vendors-node_modules_taro_weapp_prebundle_chunk-LNJCN3VW_js"), __webpack_require__.e("node_modules_taro_weapp_prebundle_react_jsx-runtime_js")]).then(function() { return function() { return (__webpack_require__(/*! ./node_modules/.taro/weapp/prebundle/react_jsx-runtime.js */ "./node_modules/.taro/weapp/prebundle/react_jsx-runtime.js")); }; });
 	},
@@ -101,12 +101,12 @@ var taroModuleMap = {
 	"./xstate": function() {
 		return function() { return (__webpack_require__(/*! ./node_modules/.taro/weapp/prebundle/xstate.js */ "./node_modules/.taro/weapp/prebundle/xstate.js")); };
 	},
-	"./taro-ui": function() {
-		return function() { return (__webpack_require__(/*! ./node_modules/.taro/weapp/prebundle/taro-ui.js */ "./node_modules/.taro/weapp/prebundle/taro-ui.js")); };
-	},
 	"./i18next": function() {
 		return function() { return (__webpack_require__(/*! ./node_modules/.taro/weapp/prebundle/i18next.js */ "./node_modules/.taro/weapp/prebundle/i18next.js")); };
 	},
+	"./taro-ui": function() {
+		return function() { return (__webpack_require__(/*! ./node_modules/.taro/weapp/prebundle/taro-ui.js */ "./node_modules/.taro/weapp/prebundle/taro-ui.js")); };
+	},
 	"./react/jsx-runtime": function() {
 		return function() { return (__webpack_require__(/*! ./node_modules/.taro/weapp/prebundle/react_jsx-runtime.js */ "./node_modules/.taro/weapp/prebundle/react_jsx-runtime.js")); };
 	},

+ 157 - 0
src/components/LimitPickers.tsx

@@ -0,0 +1,157 @@
+import { PickerView, PickerViewColumn, View, Text } from "@tarojs/components";
+import { useEffect, useState } from "react";
+
+export default function Component(props: { limit: number, onChange: Function, onCancel: Function }) {
+    const days: string[] = [];
+    const today = new Date();
+    const [values, setValues] = useState([6, today.getHours(), today.getMinutes()])
+
+
+    // useEffect(() => {
+    //     setValues([6, today.getHours(), today.getMinutes()])
+    // }, [props.limit])
+
+
+    for (let i = 6; i >= 0; i--) {
+        const date = new Date();
+        date.setDate(today.getDate() - i);
+
+        const month = date.getMonth() + 1;
+        const day = date.getDate();
+        const weekday = ['周日', '周一', '周二', '周三', '周四', '周五', '周六'][date.getDay()];
+
+        const formattedDate = `${month}月${day}日 ${weekday}`;
+        if (i == 0) {
+            days.push('今天 ');
+        }
+        else if (i == 1) {
+            days.push('昨天 ');
+        }
+        else {
+            days.push(formattedDate);
+        }
+
+    }
+
+    const hours: number[] = [];
+
+
+    for (let i = 0; i <= 23; i++) {
+        hours.push(i);
+    }
+
+    const minutes: number[] = [];
+    for (let i = 0; i <= 59; i++) {
+        minutes.push(i);
+    }
+
+
+
+    function getTimestamp(dateTimeString: string): number {
+        const timestamp = Date.parse(dateTimeString);
+        return timestamp;
+    }
+
+    function getDaysDiff(date: Date): number {
+        const today = new Date();
+        today.setHours(0, 0, 0, 0);
+
+        const targetDate = new Date(date.getFullYear(), date.getMonth(), date.getDate());
+        targetDate.setHours(0, 0, 0, 0);
+
+        const timeDiff = today.getTime() - targetDate.getTime();
+        const daysDiff = Math.floor(timeDiff / (1000 * 60 * 60 * 24));
+
+        return daysDiff;
+    }
+
+    function onPickerChange(e) {
+        var list = e.detail.value
+
+        const date = new Date();
+        date.setDate(today.getDate() - (6 - list[0]));
+        const year = date.getFullYear();
+        const month = date.getMonth() + 1;
+        const day = date.getDate();
+
+        const time = `${year}-${expandZero(month)}-${expandZero(day)}T${expandZero(hours[list[1]])}:${expandZero(minutes[list[2]])}:00`;
+        if (getTimestamp(time) > today.getTime()) {
+            setValues([list[0], today.getHours(), today.getMinutes()])
+        }
+        else {
+            var limitDate = new Date(props.limit)
+
+            // const date = new Date();
+            // date.setDate(today.getDate() - (6 - list[0]));
+            // const year = date.getFullYear();
+            // const month = date.getMonth() + 1;
+            // const day = date.getDate();
+            // debugger
+            // const time = `${year}-${expandZero(month)}-${expandZero(day)}T${expandZero(hours[list[1]])}:${expandZero(minutes[list[2]])}:59`;
+            if (getTimestamp(time) < props.limit) {
+                console.log(6 - getDaysDiff(limitDate))
+                setValues([6 - getDaysDiff(limitDate), limitDate.getHours(), limitDate.getMinutes()])
+                return
+            }
+
+            setValues(e.detail.value)
+        }
+
+    }
+
+    function expandZero(num: number): string {
+        return num < 10 ? `0${num}` : `${num}`;
+    }
+
+    function cancel() {
+        props.onCancel()
+    }
+
+    function confirm() {
+        const date = new Date();
+        date.setDate(today.getDate() - (6 - values[0]));
+        date.setHours(values[1])
+        date.setMinutes(values[2])
+        props.onChange(date.getTime())
+    }
+
+    return <View style={{ backgroundColor: '#fff', color: '#000', position: 'relative' }}>
+        <PickerView value={values}
+            onChange={onPickerChange}
+            indicatorStyle='height: 50px;' style='width: 100%; height: 300px;'>
+            <PickerViewColumn style='flex:0 0 45%'>
+                {days.map(item => {
+                    return (
+                        <View style={{ display: 'flex', alignItems: 'center', justifyContent: 'center' }}>{item}</View>
+                    );
+                })}
+            </PickerViewColumn>
+            <PickerViewColumn>
+                {hours.map(item => {
+                    return (
+                        <View style={{ display: 'flex', alignItems: 'center', justifyContent: 'center' }}>{item < 10 ? `0${item}` : item}</View>
+                    );
+                })}
+            </PickerViewColumn>
+            <PickerViewColumn>
+                {minutes.map(item => {
+                    return (
+                        <View style={{ display: 'flex', alignItems: 'center', justifyContent: 'center' }}>{item < 10 ? `0${item}` : item}</View>
+                    );
+                })}
+            </PickerViewColumn>
+        </PickerView>
+
+        <View style={{
+            position: 'absolute', width: '20%', height: 50, backgroundColor: 'transparent', left: '62.5%', top: 125,
+            display: 'flex', alignItems: 'center', justifyContent: 'center'
+        }}>
+            <Text style={{ color: '#000', fontSize: 16, fontWeight: 'bold' }}>:</Text>
+        </View>
+
+        <View style={{ marginBottom: 20, display: 'flex', flexDirection: 'row', width: '100%' }}>
+            <Text style={{ flex: 1, textAlign: 'center' }} onClick={cancel}>取消</Text>
+            <Text style={{ flex: 1, textAlign: 'center' }} onClick={confirm}>确认</Text>
+        </View>
+    </View>
+}

+ 65 - 0
src/features/trackTimeDuration/actions/TrackTimeActions.tsx

@@ -0,0 +1,65 @@
+import { recordCheck } from "@/services/trackTimeDuration";
+import trackTimeService, { machine } from "@/store/trackTimeMachine"
+
+export const startFast = (start_time: number, duration: number) => {
+    // const duration = fastValues[0] * 3600 * 1000 + fastValues[1] * 60 * 1000
+    const extra = {
+        set_time: start_time - 20 * 1000,
+        confirm_time: start_time + 50 * 1000,
+    }
+    recordCheck({
+        action: 'FAST_START',
+        real_check_time: start_time,
+        target_duration: duration,
+        extra: extra
+    }).then(res => {
+        trackTimeService.send({ type: 'START_FAST' });
+    });
+}
+
+export const endFast = (start_time: number) => {
+    const extra = {
+        set_time: start_time - 20 * 1000,
+        confirm_time: start_time + 50 * 1000,
+    }
+    recordCheck({
+        action: 'FAST_END',
+        real_check_time: start_time,
+        extra: extra
+    }).then(res => {
+        trackTimeService.send({ type: 'END_FAST' });
+        trackTimeService.send({ type: 'RESET' });
+        trackTimeService.send({ type: global.scenario });
+    });
+}
+
+
+export const startSleep = (start_time: number, duration: number) => {
+    // const duration = sleepValues[0] * 3600 * 1000 + sleepValues[1] * 60 * 1000
+    const extra = {
+        set_time: start_time - 20 * 1000,
+        confirm_time: start_time + 50 * 1000,
+    }
+    recordCheck({
+        action: 'SLEEP_START',
+        real_check_time: start_time,
+        target_duration: duration,
+        extra: extra
+    }).then(res => {
+        trackTimeService.send({ type: 'START_SLEEP' });
+    });
+}
+export const endSleep = (start_time: number) => {
+    // const duration = 8 * 3600 * 1000;
+    const extra = {
+        set_time: start_time - 20 * 1000,
+        confirm_time: start_time + 50 * 1000,
+    }
+    recordCheck({
+        action: 'SLEEP_END',
+        real_check_time: start_time,
+        extra: extra
+    }).then(res => {
+        trackTimeService.send({ type: 'END_SLEEP' });
+    });
+}

+ 0 - 34
src/features/trackTimeDuration/components/Clock.tsx

@@ -24,42 +24,9 @@ export default function Component() {
         });
     }, []);
 
-    useEffect(() => {
-        startTimer();
-        return () => {
-            // 在组件卸载时清除定时器
-            if (timerId) {
-                clearInterval(timerId);
-            }
-        };
-    }, [timerId]);
-
-    const startTimer = () => {
-        // 避免重复启动定时器
-        if (timerId) {
-            return;
-        }
-        const id = setInterval(() => {
-            setCounter((prevCounter) => prevCounter + 1);
-        }, 1000);
-
-        setTimerId(id as any);
-    };
-
-    const stopTimer = () => {
-        if (timerId) {
-            clearInterval(timerId);
-            setTimerId(null);
-        }
-    };
-
     if (!checkData)
         return <View style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', width: '100%', marginTop: 20 }}>
             <Rings radius={50} />
-            {/* <Text style={{ color: '#AAFF00' }}>00:00:00</Text> */}
-            {/* <View style={{ position: 'absolute' }}> */}
-                <Text style={{ opacity: 0 }}>{counter}</Text>
-            {/* </View> */}
 
         </View>
     return (
@@ -97,7 +64,6 @@ export default function Component() {
                     </Text>
                 </Text>
             }
-            {/* <Text style={{ opacity: 1 }}>{counter}</Text> */}
         </View>
     )
 }

+ 85 - 271
src/features/trackTimeDuration/components/Console.tsx

@@ -1,32 +1,27 @@
 import { recordCheck } from "@/services/trackTimeDuration";
-import { View, Text, PickerView, PickerViewColumn, Picker } from "@tarojs/components";
+import { View, Text } from "@tarojs/components";
 import trackTimeService, { machine } from "@/store/trackTimeMachine"
 import { useEffect, useState } from "react";
 import { TimeFormatter } from "@/utils/time_format";
 import TimePickers from '@/components/TimePickers'
 import { useSelector } from "react-redux";
 import Taro from "@tarojs/taro";
+import { AtFloatLayout } from "taro-ui";
+import LimitPickers from '@/components/LimitPickers';
+import { endFast, endSleep, startFast, startSleep } from "../actions/TrackTimeActions";
 
 export default function Component() {
-    // const [current,send] = useService(machine)
-    // const currentState = trackTimeService.getSnapshot();
-    // console.log(currentState.value);
-    // debugger
     const [key, setKey] = useState('');
     const [value, setValue] = useState('');
-    const [counter, setCounter] = useState(0)
-    const [timerId, setTimerId] = useState(null)
     const user = useSelector((state: any) => state.user);
 
     const [isFast, setIsFast] = useState(true);
     const [fastValues, setFastValues] = useState<number[]>([0, 0]);
     const [sleepValues, setSleepValues] = useState<number[]>([0, 0]);
-    const [fastStr,setFastStr] = useState('00:00');
-    const [sleepStr,setSleepStr] = useState('00:00');
-
-    
-
-
+    const [fastStr, setFastStr] = useState('00:00');
+    const [sleepStr, setSleepStr] = useState('00:00');
+    const [isOpen, setIsOpen] = useState(false);
+    const [resetPicker, setResetPicker] = useState(false);
 
     useEffect(() => {
         getStateDetail();
@@ -34,9 +29,6 @@ export default function Component() {
 
     useEffect(() => {
         trackTimeService.onTransition(state => {
-            // console.log(state.value);
-            var value = trackTimeService.getSnapshot().value
-            // console.log('aaa:'+JSON.parse(JSON.stringify(value)));
             if ((state.value as any).FAST_SLEEP) {
                 setKey('FAST_SLEEP');
                 setValue((state.value as any).FAST_SLEEP);
@@ -52,35 +44,12 @@ export default function Component() {
         });
     }, []);
 
-    useEffect(() => {
-        startTimer();
-        return () => {
-            // 在组件卸载时清除定时器
-            if (timerId) {
-                clearInterval(timerId);
-            }
-        };
-    }, [timerId]);
-
-    const startTimer = () => {
-        // 避免重复启动定时器
-        if (timerId) {
-            return;
-        }
-
-        const id = setInterval(() => {
-            setCounter((prevCounter) => prevCounter + 1);
-        }, 1000);
-
-        setTimerId(id as any);
-    };
-
     function getStateDetail() {
         var state = trackTimeService.getSnapshot().value
         if ((state as any).FAST_SLEEP) {
             setKey('FAST_SLEEP');
             setValue((state as any).FAST_SLEEP);
-            if ((state as any).FAST_SLEEP == 'WAIT_FOR_START') {
+            if ((state as any).FAST_SLEEP == 'WAIT_FOR_START' || (state as any).FAST_SLEEP == 'ONGOING3') {
                 setIsFast(true);
             }
             else if ((state as any).FAST_SLEEP == 'ONGOING1') {
@@ -99,272 +68,121 @@ export default function Component() {
         }
 
         var checkData = machine.context.checkData;
-        if (checkData){
+        if (checkData) {
             var fastTime = TimeFormatter.formateHourMinute((checkData as any).current_record.fast.target_start_time,
-            (checkData as any).current_record.fast.target_end_time);
+                (checkData as any).current_record.fast.target_end_time);
             var sleepTime = TimeFormatter.formateHourMinute((checkData as any).current_record.sleep.target_start_time,
-            (checkData as any).current_record.sleep.target_end_time);
+                (checkData as any).current_record.sleep.target_end_time);
 
             setFastValues(fastTime.split(':').map(x => parseInt(x)));
             setSleepValues(sleepTime.split(':').map(x => parseInt(x)));
             setFastStr(fastTime);
             setSleepStr(sleepTime);
-            console.log(fastTime);
-            console.log(sleepTime)
-            console.log(fastValues)
-            console.log(sleepValues)
-            console.log('--------------')
         }
-        
-
     }
 
-    function isMap(obj: any): obj is Map<any, any> {
-        return obj instanceof Map;
-    }
 
-    function startFast(start_time: number) {
-        const duration = fastValues[0] * 3600 * 1000 + fastValues[1] * 5 * 60 * 1000//8 * 3600 * 1000;
-        const extra = {
-            set_time: start_time - 20 * 1000,
-            confirm_time: start_time + 50 * 1000,
-        }
-        recordCheck({
-            action: 'FAST_START',
-            real_check_time: start_time,
-            target_duration: duration,
-            extra: extra
-        }).then(res => {
-            console.log(res);
-            trackTimeService.send({ type: 'START_FAST' });
-        });
-        // dispatch(startFast());
-    }
-    function startSleep(start_time: number) {
-        const duration = sleepValues[0] * 3600 * 1000 + sleepValues[1] * 5 * 60 * 1000
-        const extra = {
-            set_time: start_time - 20 * 1000,
-            confirm_time: start_time + 50 * 1000,
-        }
-        recordCheck({
-            action: 'SLEEP_START',
-            real_check_time: start_time,
-            target_duration: duration,
-            extra: extra
-        }).then(res => {
-            console.log(res);
-            trackTimeService.send({ type: 'START_SLEEP' });
-        });
-        // dispatch(startSleep());
+    function showPicker() {
+        setIsOpen(true)
     }
-    function endSleep(start_time: number) {
-        // const duration = 8 * 3600 * 1000;
-        const extra = {
-            set_time: start_time - 20 * 1000,
-            confirm_time: start_time + 50 * 1000,
-        }
-        recordCheck({
-            action: 'SLEEP_END',
-            real_check_time: start_time,
-            extra: extra
-        }).then(res => {
-            console.log(res);
-            trackTimeService.send({ type: 'END_SLEEP' });
-        });
-    }
-    function endFast(start_time: number) {
-        const extra = {
-            set_time: start_time - 20 * 1000,
-            confirm_time: start_time + 50 * 1000,
-        }
-        recordCheck({
-            action: 'FAST_END',
-            real_check_time: start_time,
-            extra: extra
-        }).then(res => {
-            console.log(res);
-            trackTimeService.send({ type: 'END_FAST' });
-            trackTimeService.send({ type: 'RESET' });
-            trackTimeService.send({ type: global.scenario });
-        });
-    }
-
-    function minTime() {
-        if (value == 'WAIT_FOR_START' || !(machine.context.checkData as any).current_record.fast.real_start_time) {
-            return '00:00'
-        }
-        var time = new Date((machine.context.checkData as any).current_record.fast.real_start_time);
-        const formatter = new Intl.DateTimeFormat('en-US', {
-            hour: '2-digit',
-            minute: '2-digit',
-        });
 
-        return formatter.format(time);
+    function hidePicker() {
+        setIsOpen(false)
+        setTimeout(() => {
+            setResetPicker(true)
+        }, 500)
+        setTimeout(() => {
+            setResetPicker(false)
+        }, 1000)
     }
 
-    function sleepEndMinTime(){
-        if (!(machine.context.checkData as any).current_record.sleep.real_start_time){
-            return '00:00'
+    function layoutContent() {
+        var limit = new Date().getTime() - 7 * 3600 * 1000 * 24;
+        var current_record = machine.context.checkData ? (machine.context.checkData as any).current_record : null;
+        if (current_record && current_record.last_real_check_time)
+            limit = current_record.last_real_check_time
+        if (resetPicker) {
+            return <View />
         }
-        var time = new Date((machine.context.checkData as any).current_record.sleep.real_start_time);
-        
-        const formatter = new Intl.DateTimeFormat('en-US', {
-            hour: '2-digit',
-            minute: '2-digit',
-        });
-        debugger
-        return formatter.format(time);
+        return <View>
+            <LimitPickers limit={limit} onCancel={() => { setIsOpen(false) }} onChange={(e) => {
+                console.log(new Date(e))
+                pickerConfirm(e)
+                hidePicker()
+            }} />
+        </View>
     }
 
-    function fastEndMinTime(){
-        if (value == 'ONGOING'||!(machine.context.checkData as any).current_record.sleep.real_end_time){
-            return '00:00'
+    function pickerConfirm(t: number) {
+        if (isFast) {
+            if (value == 'WAIT_FOR_START') {
+                const duration = fastValues[0] * 3600 * 1000 + fastValues[1] * 60 * 1000
+                startFast(t, duration);
+            }
+            else {
+                endFast(t)
+            }
         }
-        var time = new Date((machine.context.checkData as any).current_record.sleep.real_end_time);
-        if (!time){
-            return '00:00'
+        else {
+            if (value == 'WAIT_FOR_START' || value == 'ONGOING1') {
+                const duration = sleepValues[0] * 3600 * 1000 + sleepValues[1] * 60 * 1000
+                startSleep(t, duration);
+            }
+            else {
+                endSleep(t)
+            }
         }
-        const formatter = new Intl.DateTimeFormat('en-US', {
-            hour: '2-digit',
-            minute: '2-digit',
-        });
-
-        return formatter.format(time);
-    }
-
-    function currentTime() {
-        var time = new Date();
-        const formatter = new Intl.DateTimeFormat('en-US', {
-            hour: '2-digit',
-            minute: '2-digit',
-        });
-
-        return formatter.format(time);
     }
 
     function mixedBtns() {
         return <View>
             {
                 (value == 'WAIT_FOR_START' || value == 'DONE') &&
-                <Picker mode="time" onChange={timePickerChange} value={currentTime()} end={currentTime()}><Text style={{ color: '#AAFF00' }}>Start Fast</Text></Picker>
+                <Text style={{ color: '#AAFF00' }} onClick={showPicker}>Start Fast</Text>
             }
             {
                 (value == 'ONGOING'/* ||value == 'ONGOING1' || value == 'ONGOING2'*/ || value == 'ONGOING3') &&
-                <Picker mode="time" onChange={timePickerChange} value={currentTime()} start={fastEndMinTime()} end={currentTime()}>
-                    <Text>End Fast</Text>
-                </Picker>
+                <Text style={{ color: '#AAFF00' }} onClick={showPicker}>End Fast</Text>
             }
             {
-                value == 'ONGOING1' && <Picker mode="time" onChange={timePickerChange} value={currentTime()} start={minTime()} end={currentTime()}>
-                    <Text style={{ color: '#00ffff' }}>Start Sleep</Text>
-                </Picker>
+                value == 'ONGOING1' && <Text style={{ color: '#00ffff' }} onClick={showPicker}>Start Sleep</Text>
             }
             {
-                value == 'ONGOING2' && <Picker mode="time" onChange={timePickerChange} value={currentTime()} start={sleepEndMinTime()} end={currentTime()}>
-                    <Text>End Sleep</Text>
-                </Picker>
+                value == 'ONGOING2' && <Text style={{ color: '#00ffff' }} onClick={showPicker}>End Sleep</Text>
+ 
             }
         </View>
     }
 
     function fastBtns() {
         return <View>
-            {
-                value == 'ONGOING' ?
-                    <Picker mode="time" onChange={timePickerChange} value={currentTime()} end={currentTime()}>
-                        <Text>End Fast</Text>
-                    </Picker> :
-                    <Picker mode="time" onChange={timePickerChange} value={currentTime()} end={currentTime()}>
-                        <Text style={{ color: '#AAFF00' }}>Start Fast</Text>
-                    </Picker>
-            }
+            <Text style={{ color: '#AAFF00' }} onClick={showPicker}>{value == 'ONGOING' ? 'End Fast' : 'Start Fast'}</Text>
         </View>
     }
 
     function sleepBtns() {
         return <View>
             {
-                value == 'ONGOING' ?
-                    <Picker mode="time" onChange={timePickerChange} value={currentTime()} end={currentTime()}>
-                        <Text >End Sleep</Text>
-                    </Picker> :
-                    <Picker mode="time" onChange={timePickerChange} value={currentTime()} end={currentTime()}>
-                        <Text style={{ color: '#00ffff' }}>Start Sleep</Text></Picker>
+                value == 'ONGOING' ? <Text style={{ color: '#00ffff' }} onClick={showPicker}>End Sleep</Text> :
+                    <Text style={{ color: '#00ffff' }} onClick={showPicker}>Start Sleep</Text>
             }
         </View>
     }
 
-    function timePickerChange(e) {
-        var time = e.detail.value;
-        var hour = time.split(':')[0];
-        var minute = time.split(':')[1];
-        var dt = new Date();
-        dt.setHours(hour);
-        dt.setMinutes(minute);
-        if (value == 'ONGOING2') {
-            endSleep(dt.getTime());
-            return;
-        }
-        else if (value == 'ONGOING3') {
-            endFast(dt.getTime());
-            return;
-        }
-        if (isFast) {
-            if (value == 'ONGOING') {
-                endFast(dt.getTime());
-            }
-            else {
-                startFast(dt.getTime())
-            }
-
-        }
-        else {
-            if (value == 'ONGOING') {
-                endSleep(dt.getTime());
-            }
-            else {
-                startSleep(dt.getTime())
-            }
-
-        }
-
-    }
-
     const handlePickerChange = (e: string) => {
         var [hour, minute] = e.split(':').map(x => parseInt(x))
         isFast ? setFastValues([hour, minute]) : setSleepValues([hour, minute]);
-        debugger
     };
 
-    function login(){
+    function login() {
         Taro.navigateTo({
             url: '/pages/ChooseAuth'
-          })
+        })
     }
 
     if (!user.isLogin) {
         return <View style={{ display: 'flex', flexDirection: 'column', width: '100%', alignItems: 'center' }}>
-            <TimePickers time={isFast ? fastStr : sleepStr} content="" change={handlePickerChange} isPickerView={true}/>
-            {/* <PickerView
-
-                value={isFast ? fastValues : sleepValues}
-                onChange={handlePickerChange}
-                indicatorStyle='height: 50px;' style='width: 100%; height: 100px;'>
-                <PickerViewColumn>
-                    {hours.map(item => {
-                        return (
-                            <View style={{ display: 'flex', alignItems: 'center', justifyContent: 'center' }}>{item}小时</View>
-                        );
-                    })}
-                </PickerViewColumn>
-                <PickerViewColumn>
-                    {minutes.map(item => {
-                        return (
-                            <View style={{ display: 'flex', alignItems: 'center', justifyContent: 'center' }}>{item}分钟</View>
-                        );
-                    })}
-                </PickerViewColumn>
-            </PickerView> */}
+            <TimePickers time={isFast ? fastStr : sleepStr} content="" change={handlePickerChange} isPickerView={true} />
             <Text style={{ color: '#AAFF00' }} onClick={login}>Start Fast</Text>
         </View>
     }
@@ -372,34 +190,14 @@ export default function Component() {
         <View style={{ display: 'flex', flexDirection: 'column', width: '100%', alignItems: 'center' }}>
             {
                 value == 'ONGOING' && <View>
-                    <Text>{(machine.context.checkData as any).current_record.scenario=='FAST'?
-                    TimeFormatter.countdown((machine.context.checkData as any).current_record.fast.target_end_time):
-                    TimeFormatter.countdown((machine.context.checkData as any).current_record.sleep.target_end_time)}</Text>
+                    <Text>{(machine.context.checkData as any).current_record.scenario == 'FAST' ?
+                        TimeFormatter.countdown((machine.context.checkData as any).current_record.fast.target_end_time) :
+                        TimeFormatter.countdown((machine.context.checkData as any).current_record.sleep.target_end_time)}</Text>
                 </View>
             }
             {
                 (value == 'ONGOING1' || value == 'WAIT_FOR_START') &&
-                <TimePickers time={isFast ? fastStr : sleepStr} content="" change={handlePickerChange} isPickerView={true}/>
-                // <PickerView
-
-                //     value={isFast ? fastValues : sleepValues}
-                //     onChange={handlePickerChange}
-                //     indicatorStyle='height: 50px;' style='width: 100%; height: 100px;'>
-                //     <PickerViewColumn>
-                //         {hours.map(item => {
-                //             return (
-                //                 <View style={{ display: 'flex', alignItems: 'center', justifyContent: 'center' }}>{item}小时</View>
-                //             );
-                //         })}
-                //     </PickerViewColumn>
-                //     <PickerViewColumn>
-                //         {minutes.map(item => {
-                //             return (
-                //                 <View style={{ display: 'flex', alignItems: 'center', justifyContent: 'center' }}>{item}分钟</View>
-                //             );
-                //         })}
-                //     </PickerViewColumn>
-                // </PickerView>
+                <TimePickers time={isFast ? fastStr : sleepStr} content="" change={handlePickerChange} isPickerView={true} />
             }
             {
                 machine.context.checkData && value == 'ONGOING2' && <View>
@@ -424,7 +222,23 @@ export default function Component() {
                     key === 'SLEEP' && sleepBtns()
                 }
             </View>
-            {/* <TimePickers time="00:10"/> */}
+
+            {
+                machine.context.checkData && (machine.context.checkData as any).current_record.last_real_check_time &&
+                <Text style={{ width: '100%', textAlign: 'center' }}>
+                    {TimeFormatter.formateTime((machine.context.checkData as any).current_record.last_real_check_time)}
+                </Text>
+            }
+            <AtFloatLayout
+                isOpened={isOpen}
+                onClose={() => {
+                    setIsOpen(false)
+                }}
+                title="">
+                {
+                    layoutContent()
+                }
+            </AtFloatLayout>
         </View>
     )
 }

+ 48 - 37
src/features/trackTimeDuration/components/More.tsx

@@ -1,15 +1,19 @@
 import { View, Text } from "@tarojs/components";
 import Taro from "@tarojs/taro";
-import { useEffect } from "react";
+import { forwardRef, useEffect, useState } from "react";
 import { useTranslation } from "react-i18next";
 import { useSelector } from "react-redux";
 import trackTimeService, { machine } from "@/store/trackTimeMachine"
 import { recordCheck } from "@/services/trackTimeDuration";
+import { AtFloatLayout } from "taro-ui";
+import LimitPickers from "@/components/LimitPickers";
+import { endFast } from "../actions/TrackTimeActions";
 
-export default function Component() {
+const Component = forwardRef((props, ref) => {
     const { t } = useTranslation()
     const scenario = useSelector((state: any) => state.scenario);
     const user = useSelector((state: any) => state.user);
+    const [isOpen, setIsOpen] = useState(false);
 
     useEffect(() => {
         var value = trackTimeService.getSnapshot().value
@@ -21,10 +25,14 @@ export default function Component() {
         });
     }, []);
 
-    function login(){
+    function login() {
         Taro.navigateTo({
             url: '/pages/ChooseAuth'
-          })
+        })
+    }
+
+    function demo(){
+        console.log('demo')
     }
 
     function waitActionSheet() {
@@ -61,23 +69,7 @@ export default function Component() {
                     case 0:
                         {
 
-                            const start_time = new Date().getTime();
-                            // const duration = 8 * 3600 * 1000;
-                            const extra = {
-                                set_time: start_time - 20 * 1000,
-                                confirm_time: start_time + 50 * 1000,
-                            }
-                            recordCheck({
-                                action: 'FAST_END',
-                                real_check_time: start_time,
-                                extra: extra
-                            }).then(res => {
-                                trackTimeService.send({ type: 'END_FAST' });
-                                console.log(res);
-                                trackTimeService.send({ type: 'RESET' });
-
-                                trackTimeService.send({ type: global.scenario });
-                            });
+                            setIsOpen(true)
                         }
                         break;
                 }
@@ -87,21 +79,9 @@ export default function Component() {
             })
     }
 
-
-    function ongoingActionSheet() {
-        Taro.showActionSheet({
-            itemList: [t('feature.track_time_duration.action_sheet.give_up'), t('feature.track_time_duration.action_sheet.switch_scenario')]
-        })
-            .then(res => {
-                console.log(res.tapIndex)
-            })
-            .catch(err => {
-                console.log(err.errMsg)
-            })
-    }
-
     function checkActionSheetData() {
-        if (!user.isLogin){
+        console.log('checkActionSheetData')
+        if (!user.isLogin) {
             return login()
         }
         var state = trackTimeService.getSnapshot().value
@@ -123,9 +103,40 @@ export default function Component() {
         }
     }
 
+    global.checkActionSheetData = checkActionSheetData
+
+    function layoutContent() {
+        var limit = new Date().getTime() - 7 * 3600 * 1000 * 24;
+        var current_record = machine.context.checkData ? (machine.context.checkData as any).current_record : null;
+        if (current_record && current_record.last_real_check_time)
+            limit = current_record.last_real_check_time
+        return <View>
+            <LimitPickers limit={limit} onCancel={() => { setIsOpen(false) }} onChange={(e) => {
+                console.log(new Date(e))
+                endFast(e)
+                setIsOpen(false)
+            }} />
+        </View>
+    }
+
     return (
-        <View style={{width:'100%',marginTop:20,marginBottom:20,display:'flex',alignItems:'center',justifyContent:'center'}}>
+        <View  ref={ref} style={{ width: '100%', marginTop: 20, marginBottom: 20, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
             <Text onClick={checkActionSheetData}>More Component</Text>
+            <AtFloatLayout
+                isOpened={isOpen}
+                onClose={() => {
+                    setIsOpen(false)
+                }}
+                title="">
+                {
+                    layoutContent()
+                }
+
+
+            </AtFloatLayout>
         </View>
     )
-}
+}
+)
+
+export default Component;

+ 2 - 84
src/features/trackTimeDuration/components/TitleBar.tsx

@@ -27,90 +27,8 @@ export default function Component() {
     }, []);
 
     function more() {
-        if (user.isLogin == false) {
-            Taro.navigateTo({
-                url: '/pages/ChooseAuth'
-            })
-            return
-        }
-        var state = trackTimeService.getSnapshot().value
-        if ((state as any).FAST_SLEEP === 'WAIT_FOR_START' ||
-            (state as any).FAST === 'WAIT_FOR_START' ||
-            (state as any).SLEEP === 'WAIT_FOR_START') {
-            waitActionSheet()
-        }
-        else if ((state as any).FAST_SLEEP === 'ONGOING1' ||
-            (state as any).FAST_SLEEP === 'ONGOING2') {
-            endFastActionSheet()
-        }
-        else if ((state as any).FAST_SLEEP === 'ONGOING3') {
-            Taro.showToast({
-                title: '暂无更多操作',
-                icon: 'none',
-                duration: 2000
-            })
-        }
-    }
-
-    function waitActionSheet() {
-        Taro.showActionSheet({
-            itemList: [t('feature.track_time_duration.action_sheet.change_schedule'), t('feature.track_time_duration.action_sheet.switch_scenario')]
-        })
-            .then(res => {
-                console.log(res.tapIndex)
-                switch (res.tapIndex) {
-                    case 0:
-                        Taro.navigateTo({
-                            url: '/pages/SetSchedule'
-                        })
-                        break;
-                    case 1:
-                        Taro.navigateTo({
-                            url: '/pages/ChooseScenario'
-                        })
-                        break;
-                }
-            })
-            .catch(err => {
-                console.log(err.errMsg)
-            })
-    }
-
-    function endFastActionSheet() {
-        Taro.showActionSheet({
-            itemList: [t('feature.track_time_duration.action_sheet.end_fast')]
-        })
-            .then(res => {
-                console.log(res.tapIndex)
-                switch (res.tapIndex) {
-                    case 0:
-                        {
-
-                            const start_time = new Date().getTime();
-                            // const duration = 8 * 3600 * 1000;
-                            const extra = {
-                                set_time: start_time - 20 * 1000,
-                                confirm_time: start_time + 50 * 1000,
-                            }
-                            recordCheck({
-                                action: 'FAST_END',
-                                real_check_time: start_time,
-                                extra: extra
-                            }).then(res => {
-                                trackTimeService.send({ type: 'END_FAST' });
-                                console.log(res);
-                                trackTimeService.send({ type: 'RESET' });
-
-                                trackTimeService.send({ type: global.scenario });
-                            });
-                        }
-                        break;
-                }
-            })
-            .catch(err => {
-                console.log(err.errMsg)
-            })
-    }
+        global.checkActionSheetData()
+    } 
 
     if (!user.isLogin) {
         return <View className="detail" onClick={more}>

+ 7 - 27
src/pages/clock.tsx

@@ -1,4 +1,4 @@
-import { Component, PropsWithChildren, useEffect, useState } from 'react'
+import { Component, PropsWithChildren, useEffect, useRef, useState } from 'react'
 import { View, Text, Button, Input, Picker } from '@tarojs/components'
 import './index/index.scss'
 import './Clock.scss'
@@ -6,6 +6,7 @@ import Taro, { useDidShow, useReady, useRouter } from '@tarojs/taro'
 // import ComponentA from './component'
 import Rings from '@components/Rings';
 import SingleSelect from '@components/SingleSelect';
+import LimitPickers from '@components/LimitPickers';
 import { useDispatch, useSelector } from 'react-redux';
 import { getInfoSuccess } from '@/store/user';
 import { wxPubFollow } from '@/services/permission';
@@ -34,6 +35,8 @@ export default function IndexPage() {
   const common = useSelector((state: any) => state.common);
   const [counter, setCounter] = useState(0)
   const [timerId, setTimerId] = useState(null)
+  // const moreRef = useRef<any>(null);
+  // global.moreRef = Taro.createRef()
   array.push('ffff');
   array.push(<Text>ffff</Text>)
   // array.push(<Rings radius={50}/>)
@@ -210,41 +213,18 @@ export default function IndexPage() {
     }
   }
 
-  function goDetail() {
-    Taro.navigateTo({
-      // url: '/pages/index/detail'
-      //src/moduleA/pages/third.tsx
-      url: '../../moduleA/pages/third'
-    })
-  }
-
-  function login() {
-    if (user.isLogin) {
-      Taro.navigateTo({
-        url: '/pages/ChooseScenario'
-      })
-    }
-    else {
-      Taro.navigateTo({
-        url: '/pages/ChooseAuth'
-      })
-    }
-
-  }
-
   function schedule() {
     if (!user.isLogin) {
       return <View />
     }
-    // if (!isFollowed){
-    //   return <Text onClick={() => followWxPub()}>去关注公众号</Text>
-    // }
 
     if ((checkData as any).current_record.scenario == 'FAST_SLEEP') {
       return <Schedule />
     }
     return <View />
   }
+
+
   return (
     <View style={{ flex: 1, flexDirection: 'column', display: 'flex', backgroundColor: '#000', color: '#fff' }}>
       <TitleBar />
@@ -253,7 +233,7 @@ export default function IndexPage() {
         <Console />
       </View>
 
-      <More />
+      <More ref={global.moreRef}/>
       {
         !isFollowed && user.isLogin && <Text style={{ textAlign: 'center', width: '100%' }} onClick={() => followWxPub()}>去关注公众号</Text>
       }

+ 6 - 1
src/utils/time_format.ts

@@ -70,6 +70,11 @@ export class TimeFormatter {
     }
   }
 
+  static formateTime(timestamp:number){
+    const date = new Date(timestamp);
+    return `${TimeFormatter.padZero(date.getMonth()+1)}-${TimeFormatter.padZero(date.getDate())} ${TimeFormatter.padZero(date.getHours())}:${TimeFormatter.padZero(date.getMinutes())}:${TimeFormatter.padZero(date.getSeconds())}`;
+  }
+
   static formateHourMinute(startTimestamp: number, endTimestamp: number): string {
     const diff = Math.abs(endTimestamp - startTimestamp);
     // 计算小时、分钟和秒数
@@ -80,7 +85,7 @@ export class TimeFormatter {
 
   static countdown=(dt: number): string => {
     const end = Date.now();
-    const time = Math.ceil((end>dt?end-dt:dt-end)/1000);
+    const time = end>dt?Math.floor((end-dt)/1000):Math.ceil((dt-end)/1000)//Math.ceil((end>dt?end-dt:dt-end)/1000);
     const hours = Math.floor(time / 3600);
     const minutes = Math.floor((time % 3600) / 60);
     const seconds = Math.floor(time % 60);

이 변경점에서 너무 많은 파일들이 변경되어 몇몇 파일들은 표시되지 않았습니다.