Leon %!s(int64=2) %!d(string=hai) anos
pai
achega
5be273ebfa

+ 7 - 10
src/app.tsx

@@ -4,21 +4,18 @@ import './context/locales/index'
 import { Provider } from 'react-redux'
 import store from './store/store'
 import { View } from '@tarojs/components'
+import GlobalModal from './components/layout/GlobalModal'
 
 // import 'taro-ui/dist/style/index.scss'
 
 
 const App: React.FC<PropsWithChildren> = ({ children }) => {
-  return <Provider store={store}>{children}</Provider>
-  // return <View>
-  //   <Provider store={store}>
-  //     <View style={{ position: 'relative' }}>
-  //       {children}
-  //       <View style={{ position: 'absolute', left: 0, bottom: 0, width: 100, height: 100, backgroundColor: 'red',zIndex:10000 }}></View>
-  //     </View>
-  //   </Provider>
-
-  // </View>
+  return <Provider store={store}>
+    <View style={{position:'absolute',left:0,right:0,top:0,height:300,backgroundColor:'red'}}/>
+    {children}
+    <GlobalModal />
+    <View style={{position:'absolute',left:0,right:0,top:0,height:300,backgroundColor:'red'}}/>
+  </Provider>
 }
 // class App extends Component<PropsWithChildren> {
 

+ 4 - 0
src/components/basic/Buttons.scss

@@ -68,4 +68,8 @@
 .textClass {
     height: '100%';
     line-height: '100%';
+}
+
+.outlined{
+    box-sizing: border-box;
 }

+ 2 - 0
src/components/input/Stepper.scss

@@ -4,6 +4,8 @@
     align-items: center;
     background-color: #000;
     height: 104px;
+    margin-top: 24px;
+    margin-bottom: 60px;
     border-radius: 52px;
     padding: 16px;
     box-sizing: border-box;

+ 39 - 0
src/components/layout/GlobalModal.scss

@@ -0,0 +1,39 @@
+// GlobalModal.scss
+
+.modal {
+    position: fixed;
+    top: 0;
+    left: 0;
+    right: 0;
+    bottom: 0;
+    background-color: 'red';
+    // background-color: rgba(0, 0, 0, 0.5);
+    display: flex;
+    align-items: center;
+    justify-content: center;
+  }
+  
+  .modal-content {
+    background-color: white;
+    padding: 16px;
+    border-radius: 4px;
+  }
+  
+  .modal-title {
+    font-size: 18px;
+    font-weight: bold;
+    margin-bottom: 8px;
+  }
+  
+  .modal-content {
+    font-size: 14px;
+    margin-bottom: 16px;
+  }
+  
+  .modal-close {
+    background-color: #e5e5e5;
+    border-radius: 4px;
+    padding: 8px 16px;
+    font-size: 14px;
+    cursor: pointer;
+  }

+ 36 - 0
src/components/layout/GlobalModal.tsx

@@ -0,0 +1,36 @@
+// GlobalModal.tsx
+
+import React from 'react';
+import { useSelector, useDispatch } from 'react-redux';
+import { View, Text, Button } from '@tarojs/components';
+import { hideModal } from '@/store/modal';
+import './GlobalModal.scss'
+
+
+const GlobalModal: React.FC = () => {
+  const modal = useSelector((state: any) => state.modal);
+  const dispatch = useDispatch();
+
+  const handleClose = () => {
+    dispatch(hideModal());
+  };
+
+  if (!modal.isOpen) {
+    return null;
+  }
+  console.log('9527')
+
+  return (
+    <View className="modal">
+      <View className="modal-content">
+        <Text className="modal-title">{modal.title}</Text>
+        <Text className="modal-content">{modal.content}</Text>
+        <Button className="modal-close" onClick={handleClose}>
+          Close
+        </Button>
+      </View>
+    </View>
+  );
+};
+
+export default GlobalModal;

+ 27 - 1
src/features/trackTimeDuration/components/Console.scss

@@ -1,7 +1,7 @@
 .stepper_text {
     font-size: 48px;
     font-weight: 500;
-    width: 300px;
+    width: 350px;
     text-align: center;
 }
 
@@ -9,4 +9,30 @@
     font-size: 48px;
     font-weight: 500;
     text-align: center;
+    margin-top: 20px;
+    height: 72px;
+    line-height: 72px;
+    display: flex;
+    flex-shrink: 0;
+}
+
+.target_view{
+    height: 46px;
+    padding-left: 24px;
+    padding-right: 24px;
+    border-radius: 12px;
+    margin-bottom: 50px;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+}
+.target_text{
+    height: 46px;
+    line-height: 46px;
+    font-size: 20px;
+}
+
+.btn_bg{
+    margin-bottom: 32px;
+    display: flex;
 }

+ 195 - 216
src/features/trackTimeDuration/components/Console.tsx

@@ -1,14 +1,12 @@
-import { recordCheck } from "@/services/trackTimeDuration";
+
 import { View, Text, PickerView } from "@tarojs/components";
-import trackTimeService, { machine } from "@/store/trackTimeMachine"
 import { useEffect, useRef, useState } from "react";
 import { TimeFormatter } from "@/utils/time_format";
-import TimePickers from '@/components/input/TimePickers'
 import { useSelector } from "react-redux";
 import Taro from "@tarojs/taro";
 import LimitPickers from '@/components/input/LimitPickers';
 import { endFast, endSleep, startFast, startSleep } from "../actions/TrackTimeActions";
-import { durationDatas, durationIndex, getTitle, pickerDurations } from "../hooks/Console";
+import { durationDatas, durationIndex, getColor, getTitle, textAlpha, textNextStepAlpha } from "../hooks/Console";
 import PickerViews from "@/components/input/PickerViews";
 import Modal from "@/components/layout/Modal";
 import Stepper from "@/components/input/Stepper";
@@ -16,142 +14,91 @@ import { EndFastBtn, EndSleepBtn, StartFastBtn, StartSleepBtn } from "@/features
 import Box from "@/components/layout/Box";
 import './Console.scss'
 
-export default function Component() {
+export default function Component(props: { isNextStep?: boolean }) {
     const scenario = useSelector((state: any) => state.scenario);
-    const [key, setKey] = useState('');
-    const [value, setValue] = useState('');
+    const time = useSelector((state: any) => state.time);
     const user = useSelector((state: any) => state.user);
     const common = useSelector((state: any) => state.common);
     const [isFast, setIsFast] = useState(true);
-    const [fastValues, setFastValues] = useState<number[]>([0, 0]);
-    const [sleepValues, setSleepValues] = useState<number[]>([0, 0]);
     const [fastDuration, setFastDuration] = useState<number>(0);
     const [sleepDuration, setSleepDuration] = useState<number>(0);
-    const [fastStr, setFastStr] = useState('00:00');
-    const [sleepStr, setSleepStr] = useState('00:00');
-    const [isOpen, setIsOpen] = useState(false);
-    const [showModal, setShowModal] = useState(false);
+
     const [fastPickerValue, setFastPickerValue] = useState([0, 0])
     const [sleepPickerValue, setSleepPickerValue] = useState([0, 0])
-    const [isOpenDurationPicker, setIsOpenDurationPicker] = useState(false)
     const limitPickerRef = useRef(null)
     const durationPickerRef = useRef(null)
 
-    // const [pickerValue, setPickerValue] = useState([0,0])
-
-    // const pickerDurations = pickerDurations();
-
-    // console.log(pickerDurations())
-
-    useEffect(() => {
-        getStateDetail();
-    }, [machine.context.checkData]);
 
     useEffect(() => {
         getStateDetail();
-    }, [machine.context.currentStatus])
-
-    useEffect(() => {
-        trackTimeService.onTransition(state => {
-            if ((state.value as any).FAST_SLEEP) {
-                setKey('FAST_SLEEP');
-                setValue((state.value as any).FAST_SLEEP);
-            }
-            if ((state.value as any).FAST) {
-                setKey('FAST');
-                setValue((state.value as any).FAST);
-            }
-            if ((state.value as any).SLEEP) {
-                setKey('SLEEP');
-                setValue((state.value as any).SLEEP);
-            }
-        });
-    }, []);
+    }, [time.fast, time.sleep, time.status, time.scenario]);
 
     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' || (state as any).FAST_SLEEP == 'ONGOING3') {
-                setIsFast(true);
-            }
-            else if ((state as any).FAST_SLEEP == 'ONGOING1') {
-                setIsFast(false);
-            }
+        if (time.fast) {
+            var fastCount = time.fast.target_end_time - time.fast.target_start_time
+            setFastDuration(fastCount)
+            setFastPickerValue(durationIndex(time.fast.target_start_time, time.fast.target_end_time, common))
         }
-        if ((state as any).FAST) {
-            setKey('FAST');
-            setValue((state as any).FAST);
-            setIsFast(true);
-        }
-        if ((state as any).SLEEP) {
-            setKey('SLEEP');
-            setValue((state as any).SLEEP);
-            setIsFast(false);
+
+        if (time.sleep) {
+            var sleepCount = time.sleep.target_end_time - time.sleep.target_start_time
+            setSleepDuration(sleepCount)
+            setSleepPickerValue(durationIndex(time.sleep.target_start_time, time.sleep.target_end_time, common))
         }
 
-        var checkData = machine.context.checkData;
-        if (checkData) {
-            var current_record = (checkData as any).current_record;
-            if (current_record.fast) {
-                var fastTime = TimeFormatter.formateHourMinute(current_record.fast.target_start_time,
-                    current_record.fast.target_end_time);
-                setFastValues(fastTime.split(':').map(x => parseInt(x)));
-                setFastStr(fastTime);
-                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))
-                // setFastPickerValue([fastCount / 60000 / 5 - 12])
+        if (time.scenario == 'FAST') {
+            setIsFast(true)
+        }
+        else if (time.scenario == 'SLEEP') {
+            setIsFast(false)
+        }
+        else {
+            if (time.status == 'WAIT_FOR_START' || time.status == 'ONGOING3') {
+                setIsFast(true)
             }
-
-            if (current_record.sleep) {
-                var sleepTime = TimeFormatter.formateHourMinute(current_record.sleep.target_start_time,
-                    current_record.sleep.target_end_time);
-
-
-                setSleepValues(sleepTime.split(':').map(x => parseInt(x)));
-
-                setSleepStr(sleepTime);
-
-                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))
-                // setSleepPickerValue([sleepCount / 60000 / 5 - 12])
+            else {
+                setIsFast(false)
             }
         }
     }
 
 
     function showPicker() {
-        setShowModal(true)
-        setIsOpen(true)
         global.set_time = new Date().getTime()
-        console.log(global.set_time)
+
+        global.testInfotimer = setInterval(() => {
+            var node = (<Modal testInfo={testLayout()} children={layoutContent()} dismiss={() => {
+                global.showClockModal(false, null);
+                hidePicker()
+            }} confirm={() => {
+                hidePicker()
+                var picker = limitPickerRef.current;
+                pickerConfirm((picker as any).getConfirmData());
+                global.showClockModal(false, null);
+            }} />);
+            global.showClockModal(true, node);
+
+        }, 1000)
+
     }
 
     function hidePicker() {
-        setIsOpen(false)
-        setTimeout(() => {
-            setShowModal(false)
-        }, 1000)
+        global.showClockModal(false, null);
+        if (global.testInfotimer) {
+            clearInterval(global.testInfotimer)
+        }
     }
 
     function testLayout() {
         if (!user.test_user) {
             return <View />
         }
-        var current_record = machine.context.checkData ? (machine.context.checkData as any).current_record : null;
-        if (current_record == null) {
-            return <View />
-        }
         var isStart = false;
-        if (value == 'WAIT_FOR_START' || value == 'ONGOING1') {
+        if (time.status == 'WAIT_FOR_START' || time.status == 'ONGOING1') {
             isStart = true
         }
         var isFast = false;
-        switch (value) {
+        switch (time.status) {
             case 'WAIT_FOR_START':
             case 'ONGOING':
                 {
@@ -173,7 +120,10 @@ export default function Component() {
 
         }
 
-
+        if (props.isNextStep){
+            isFast = true
+            isStart = false
+        }
 
         return <View style={{ color: '#fff', paddingTop: 30, paddingLeft: 30, display: 'flex', flexDirection: 'column' }}>
             <Text>check scenario:{isFast ? 'fast' : 'sleep'}</Text>
@@ -186,8 +136,8 @@ export default function Component() {
             <Text style={{ marginTop: 30 }}>now:{TimeFormatter.formatTimestamp(new Date().getTime())}</Text>
             <Text>elapsed:{TimeFormatter.calculateTimeDifference(global.picker_time, new Date().getTime())}</Text>
 
-            <Text style={{ marginTop: 30 }}>real start:{isStart ? '-' : TimeFormatter.formatTimestamp(isFast ? current_record.fast.real_start_time : current_record.sleep.real_start_time)}</Text>
-            <Text>real duration:{isStart ? '-' : TimeFormatter.calculateTimeDifference(isFast ? current_record.fast.real_start_time : current_record.sleep.real_start_time, new Date().getTime())}</Text>
+            <Text style={{ marginTop: 30 }}>real start:{isStart ? '-' : TimeFormatter.formatTimestamp(isFast ? time.fast.real_start_time : time.sleep.real_start_time)}</Text>
+            <Text>real duration:{isStart ? '-' : TimeFormatter.calculateTimeDifference(isFast ? time.fast.real_start_time : time.sleep.real_start_time, new Date().getTime())}</Text>
         </View>
     }
 
@@ -195,25 +145,23 @@ export default function Component() {
     function layoutContent() {
         var limit = global.set_time - 7 * 3600 * 1000 * 24;
         global.limit = limit
-        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 (time.last_real_check_time) {
+            limit = time.last_real_check_time
             global.limit = limit
             //当set_time秒数<=latest_record_time秒数时,最小限制时间戳需+1分钟
-            if (new Date(global.set_time).getSeconds() <= new Date(current_record.last_real_check_time).getSeconds()) {
+            if (new Date(global.set_time).getSeconds() <= new Date(time.last_real_check_time).getSeconds()) {
                 limit = limit + 60 * 1000
             }
         }
 
-        var color = isFast ? '#aaff00' : '#00ffff'
-        if (value == 'ONGOING2') {
-            color = '#00ffff'
+        var title = getTitle(time)
+        var color = getColor(time)
+        if (props.isNextStep){
+            title = '结束断食'
+            color = '#AAFF00'
         }
 
-        var checkData = machine.context.checkData;
-        var current = (checkData as any).current_record
-        var title = getTitle(current)
-
 
         return <LimitPickers ref={limitPickerRef} limit={limit} limitDay={8}
             themeColor={color}
@@ -232,9 +180,13 @@ export default function Component() {
 
         t = date.getTime();
 
+        if (props.isNextStep){
+            endFast(t)
+            return;
+        }
+
         if (isFast) {
-            if (value == 'WAIT_FOR_START') {
-                // const duration = fastValues[0] * 3600 * 1000 + fastValues[1] * 60 * 1000
+            if (time.status == 'WAIT_FOR_START') {
                 startFast(t, fastDuration);
             }
             else {
@@ -242,8 +194,7 @@ export default function Component() {
             }
         }
         else {
-            if (value == 'WAIT_FOR_START' || value == 'ONGOING1') {
-                // const duration = sleepValues[0] * 3600 * 1000 + sleepValues[1] * 60 * 1000
+            if (time.status == 'WAIT_FOR_START' || time.status == 'ONGOING1') {
                 startSleep(t, sleepDuration);
             }
             else {
@@ -252,76 +203,91 @@ export default function Component() {
         }
     }
 
+    function targetView() {
+        if (props.isNextStep && (time.status == 'ONGOING1' || time.status == 'ONGOING2')) {
+            var opacity = textNextStepAlpha(time)
+            if (opacity == 1) {
+                return <View className="target_view" style={{ backgroundColor: '#FA51511A' }}>
+                    <Text className="target_text" style={{ color: '#FA5151' }}>超出目标结束</Text>
+                </View>
+            }
+            return <View className="target_view" style={{ backgroundColor: '#AAFF001A', opacity: opacity }}>
+                <Text className="target_text" style={{ color: '#AAFF00' }}>距离目标结束</Text>
+            </View>
+        }
+
+        if (time.status == 'ONGOING' || time.status == 'ONGOING2' || time.status == 'ONGOING3') {
+            var opacity = textAlpha(time)
+            if (opacity == 1) {
+                return <View className="target_view" style={{ backgroundColor: '#FA51511A' }}>
+                    <Text className="target_text" style={{ color: '#FA5151' }}>超出目标结束</Text>
+                </View>
+            }
+            return <View className="target_view" style={{ backgroundColor: isFast ? '#AAFF001A' : '#00FFFF1A', opacity: opacity }}>
+                <Text className="target_text" style={{ color: isFast ? '#AAFF00' : '#00FFFF' }}>距离目标结束</Text>
+            </View>
+        }
+        return <View />
+    }
+
     function mixedBtns() {
-        var checkData = machine.context.checkData;
-        var current = (checkData as any).current_record
-        return <View style={{ display: 'flex', marginTop: 22 }}>
+        return <View className="btn_bg">
             {
-                (value == 'WAIT_FOR_START' || value == 'DONE') &&
+                (time.status == 'WAIT_FOR_START' || time.status == 'DONE') &&
                 <StartFastBtn onClick={showPicker} />
-                // <Text style={{ color: '#AAFF00' }} onClick={showPicker}>Start Fast</Text>
             }
             {
-                (value == 'ONGOING' || value == 'ONGOING3') &&
-                <EndFastBtn onClick={showPicker} lowLight={current.fast.target_end_time > new Date().getTime()} />
+                (time.status == 'ONGOING' || time.status == 'ONGOING3') &&
+                <EndFastBtn onClick={showPicker} lowLight={time.fast.target_end_time > new Date().getTime()} />
             }
             {
-                value == 'ONGOING1' && <StartSleepBtn onClick={showPicker} />
+                time.status == 'ONGOING1' && <StartSleepBtn onClick={showPicker} />
             }
             {
-                value == 'ONGOING2' && <EndSleepBtn onClick={showPicker} lowLight={current.sleep.target_end_time > new Date().getTime()} />
+                time.status == 'ONGOING2' && <EndSleepBtn onClick={showPicker} lowLight={time.sleep.target_end_time > new Date().getTime()} />
 
             }
         </View>
     }
 
-    function textAlpha() {
-        var checkData = machine.context.checkData;
-        var current = (checkData as any).current_record
-        if (value == 'WAIT_FOR_START' || value == 'DONE') {
-            return 1;
-        }
+    function nextStepBtns() {
+        return <View className="btn_bg">
+            {
+                (time.status == 'WAIT_FOR_START') &&
+                <StartSleepBtn onClick={showPicker} />
+            }
+            {
+                time.status == 'ONGOING1' && <EndFastBtn onClick={showPicker} />
+            }
+            {
+                time.status == 'ONGOING2' && <EndFastBtn onClick={showPicker} lowLight={time.fast.target_end_time > new Date().getTime()} />
 
-        if (value == 'ONGOING' || value == 'ONGOING3') {
-            if (current.scenario == 'SLEEP') {
-                return current.sleep.target_end_time > new Date().getTime() ? 0.4 : 1
             }
-            return current.fast.target_end_time > new Date().getTime() ? 0.4 : 1
-        }
-        if (value == 'ONGOING1')
-            return 1//current.sleep.target_start_time > new Date().getTime()?0.4:1
-        if (value == 'ONGOING2')
-            return current.sleep.target_end_time > new Date().getTime() ? 0.4 : 1
-        return 1
+        </View>
     }
 
+
     function fastBtns() {
-        return <View style={{ display: 'flex', marginTop: 22 }}>
+        return <View className="btn_bg">
             {
-                value == 'ONGOING' ? <EndFastBtn onClick={showPicker} lowLight={textAlpha() != 1} /> : <StartFastBtn onClick={showPicker} />
+                time.status == 'ONGOING' ? <EndFastBtn onClick={showPicker} lowLight={textAlpha(time) != 1} /> : <StartFastBtn onClick={showPicker} />
             }
         </View>
     }
 
     function sleepBtns() {
-        return <View style={{ display: 'flex', marginTop: 22 }}>
+        return <View className="btn_bg">
             {
-                value == 'ONGOING' ? <EndSleepBtn onClick={showPicker} lowLight={textAlpha() != 1} /> : <StartSleepBtn onClick={showPicker} />
+                time.status == 'ONGOING' ? <EndSleepBtn onClick={showPicker} lowLight={textAlpha(time) != 1} /> : <StartSleepBtn onClick={showPicker} />
             }
         </View>
     }
 
-    const handlePickerChange = (e: string) => {
-        var [hour, minute] = e.split(':').map(x => parseInt(x))
-        isFast ? setFastValues([hour, minute]) : setSleepValues([hour, minute]);
-    };
-
     function durationChange(e) {
         var count = (e[0] + common.duration.min) * 60 + e[1] * common.duration.step
         isFast ? setFastDuration(count * 60000) : setSleepDuration(count * 60000);
         isFast ? setFastPickerValue(e) : setSleepPickerValue(e)
-
-        setIsOpenDurationPicker(false)
+        global.showClockModal2(false, null)
     }
 
     function login() {
@@ -331,43 +297,28 @@ export default function Component() {
     }
 
     function durationFormate() {
-        if (isFast) {
-            var t = fastDuration / 60000
-            var hour = Math.floor(t / 60)
-            var minute = Math.floor(t % 60)
-            return `${hour > 0 ? hour + '小时' : ''}${minute > 0 ? minute + '分钟' : ''}`
-        }
-        else {
-            var t = sleepDuration / 60000
-            var hour = Math.floor(t / 60)
-            var minute = Math.floor(t % 60)
-            return `${hour > 0 ? hour + '小时' : ''}${minute > 0 ? minute + '分钟' : ''}`
-        }
-
+        var t = isFast ? fastDuration / 60000 : sleepDuration / 60000
+        if (props.isNextStep) t = sleepDuration / 60000
+        var hour = Math.floor(t / 60)
+        var minute = Math.floor(t % 60)
+        return `${hour > 0 ? hour + '小时' : ''}${minute > 0 ? minute + '分钟' : ''}`
     }
 
     function showDurationPicker() {
-        setIsOpenDurationPicker(true)
+        var node = <Modal children={durationPickerContent()} dismiss={() => global.showClockModal2(false, null)} confirm={() => {
+            var picker = durationPickerRef.current;
+            durationChange((picker as any).getConfirmData());
+            global.showClockModal2(false, null);
+        }} />
+        global.showClockModal2(true, node);
     }
 
-    if (!user.isLogin) {
-        return <View style={{ display: 'flex', flexDirection: 'column', width: '100%', alignItems: 'center' }}>
-            <Text>16:00</Text>
-            {/* <PickerViews onChange={() => { }} items={[pickerDurations()]} value={[12 * 15]} /> */}
-            {/* <TimePickers time={isFast ? fastStr : sleepStr} content="" change={handlePickerChange} isPickerView={true} /> */}
-            <Text style={{ color: '#AAFF00' }} onClick={login}>Start Fast</Text>
-        </View>
-    }
+    
 
 
     function durationPickerContent() {
-        var color = isFast ? '#aaff00' : '#00ffff'
-        if (value == 'ONGOING2') {
-            color = '#00ffff'
-        }
-        var checkData = machine.context.checkData;
-        var current = (checkData as any).current_record
-        var title = getTitle(current)
+        var color = getColor(time)
+        var title = getTitle(time)
         return <View style={{ color: '#fff', backgroundColor: 'transparent' }}>
             <PickerViews ref={durationPickerRef}
                 onChange={durationChange}
@@ -375,7 +326,7 @@ export default function Component() {
                 value={isFast ? fastPickerValue : sleepPickerValue}
                 themeColor={color}
                 title={title}
-                showBtns={true} onCancel={() => { setIsOpenDurationPicker(false) }} />
+                showBtns={true} onCancel={() => { global.showClockModal2(false, null); }} />
         </View>
     }
 
@@ -447,64 +398,92 @@ export default function Component() {
         return false;
     }
 
-    var textColor = '#AAFF00'
-    if (!isFast) {
-        textColor = '#00FFFF'
+    var textColor = getColor(time)
+    if (time.status != 'ONGOING1' && time.status != 'WAIT_FOR_START') {
+        if (textAlpha(time) == 1) {
+            textColor = '#FA5151';
+        }
     }
 
+    if (!user.isLogin) {
+        return <View style={{ display: 'flex', flexDirection: 'column', width: '100%', alignItems: 'center' }}>
+            <Text>16:00</Text>
+            <Text style={{ color: '#AAFF00' }} onClick={login}>Start Fast</Text>
+        </View>
+    }
+
+    if (props.isNextStep) {
+        return <Box >
+            <View style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', flexShrink: 0 }}>
+                {
+                    (time.status == 'WAIT_FOR_START') && <Stepper child={
+                        <Text className="stepper_text" style={{ color: '#00FFFF', opacity: textAlpha(time) }} onClick={showDurationPicker}>{durationFormate()}</Text>
+                    } minus={minus} plus={plus} disableMinus={disableMinus()} disablePlus={disablePlus()} />
+                }
+                {
+                    time.status == 'ONGOING1' && <View>
+                        <Text className="counter_text" style={{ color: '#AAFF00', opacity: textAlpha(time) }}>{TimeFormatter.countdown(time.fast.target_end_time)}</Text>
+                    </View>
+                }
+
+                {
+                    time.status == 'ONGOING2' && <View>
+                        <Text className="counter_text" style={{ color: '#AAFF00', opacity: textAlpha(time) }}>{TimeFormatter.countdown(time.fast.target_end_time)}</Text>
+                    </View>
+                }
+                {
+                    targetView()
+                }
+
+                <View>
+                    {
+                        nextStepBtns()
+                    }
+                </View>
+            </View>
+        </Box>
+    }
     return (
         <Box >
-            <View  style={{ display:'flex',flexDirection: 'column',alignItems: 'center', flexShrink: 0 }}>
+            <View style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', flexShrink: 0 }}>
                 {
-                    value == 'ONGOING' && <View>
-                        <Text className="counter_text" style={{ color: textColor, opacity: textAlpha() }}>{(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>
+                    time.status == 'ONGOING' && <View>
+                        <Text className="counter_text" style={{ color: textColor, opacity: textAlpha(time) }}>{time.scenario == 'FAST' ?
+                            TimeFormatter.countdown(time.fast.target_end_time) :
+                            TimeFormatter.countdown(time.sleep.target_end_time)}</Text>
                     </View>
                 }
                 {
-                    (value == 'ONGOING1' || value == 'WAIT_FOR_START') && <Stepper child={
-                        <Text className="stepper_text" style={{ color: textColor, opacity: textAlpha() }} onClick={showDurationPicker}>{durationFormate()}</Text>
+                    (time.status == 'ONGOING1' || time.status == 'WAIT_FOR_START') && <Stepper child={
+                        <Text className="stepper_text" style={{ color: textColor, opacity: textAlpha(time) }} onClick={showDurationPicker}>{durationFormate()}</Text>
                     } minus={minus} plus={plus} disableMinus={disableMinus()} disablePlus={disablePlus()} />
-                    // <Text style={{marginBottom:10}} onClick={showDurationPicker}>时长:{durationFormate()}</Text>
                 }
                 {
-                    machine.context.checkData && value == 'ONGOING2' && <View>
-                        <Text className="counter_text" style={{ color: '#00ffff', opacity: textAlpha() }}>{TimeFormatter.countdown((machine.context.checkData as any).current_record.sleep.target_end_time)}</Text>
+                    time.status == 'ONGOING2' && <View>
+                        <Text className="counter_text" style={{ color: textColor, opacity: textAlpha(time) }}>{TimeFormatter.countdown(time.sleep.target_end_time)}</Text>
                     </View>
                 }
 
                 {
-                    machine.context.checkData && value == 'ONGOING3' && <View>
-                        <Text className="counter_text" style={{ color: textColor, opacity: textAlpha() }}>{TimeFormatter.countdown((machine.context.checkData as any).current_record.fast.target_end_time)}</Text>
+                    time.status == 'ONGOING3' && <View>
+                        <Text className="counter_text" style={{ color: textColor, opacity: textAlpha(time) }}>{TimeFormatter.countdown(time.fast.target_end_time)}</Text>
                     </View>
                 }
+                {
+                    targetView()
+                }
 
                 <View>
                     {
-                        key === 'FAST_SLEEP' && mixedBtns()
+                        time.scenario === 'FAST_SLEEP' && mixedBtns()
                     }
                     {
-                        key === 'FAST' && fastBtns()
+                        time.scenario === 'FAST' && fastBtns()
                     }
                     {
-                        key === 'SLEEP' && sleepBtns()
+                        time.scenario === 'SLEEP' && sleepBtns()
                     }
                 </View>
-                {
-                    showModal && isOpen && <Modal testInfo={testLayout()} children={layoutContent()} dismiss={() => setIsOpen(false)} confirm={() => {
-                        var picker = limitPickerRef.current;
-                        pickerConfirm((picker as any).getConfirmData());
-                        setIsOpen(false);
-                    }} />
-                }
-                {
-                    isOpenDurationPicker && <Modal children={durationPickerContent()} dismiss={() => setIsOpenDurationPicker(false)} confirm={() => {
-                        var picker = durationPickerRef.current;
-                        durationChange((picker as any).getConfirmData());
-                        setIsOpenDurationPicker(false);
-                    }} />
-                }
             </View>
         </Box>
     )

+ 482 - 0
src/features/trackTimeDuration/components/Console3.tsx

@@ -0,0 +1,482 @@
+import { recordCheck } from "@/services/trackTimeDuration";
+import { View, Text, PickerView } from "@tarojs/components";
+import trackTimeService, { machine } from "@/store/trackTimeMachine"
+import { useEffect, useRef, useState } from "react";
+import { TimeFormatter } from "@/utils/time_format";
+import TimePickers from '@/components/input/TimePickers'
+import { useSelector } from "react-redux";
+import Taro from "@tarojs/taro";
+import LimitPickers from '@/components/input/LimitPickers';
+import { endFast, endSleep, startFast, startSleep } from "../actions/TrackTimeActions";
+import { durationDatas, durationIndex, getTitle, pickerDurations } from "../hooks/Console";
+import PickerViews from "@/components/input/PickerViews";
+import Modal from "@/components/layout/Modal";
+import Stepper from "@/components/input/Stepper";
+import { EndFastBtn, EndSleepBtn, StartFastBtn, StartSleepBtn } from "@/features/common/SpecBtns";
+import Box from "@/components/layout/Box";
+import './Console.scss'
+
+export default function Component() {
+    const scenario = useSelector((state: any) => state.scenario);
+    const time = useSelector((state: any) => state.time);
+    const [key, setKey] = useState('');
+    const [value, setValue] = useState('');
+    const user = useSelector((state: any) => state.user);
+    const common = useSelector((state: any) => state.common);
+    const [isFast, setIsFast] = useState(true);
+    const [fastDuration, setFastDuration] = useState<number>(0);
+    const [sleepDuration, setSleepDuration] = useState<number>(0);
+
+    const [isOpen, setIsOpen] = useState(false);
+    const [showModal, setShowModal] = useState(false);
+    const [fastPickerValue, setFastPickerValue] = useState([0, 0])
+    const [sleepPickerValue, setSleepPickerValue] = useState([0, 0])
+    const [isOpenDurationPicker, setIsOpenDurationPicker] = useState(false)
+    const limitPickerRef = useRef(null)
+    const durationPickerRef = useRef(null)
+
+
+    useEffect(() => {
+        getStateDetail();
+    }, [machine.context.checkData]);
+
+    useEffect(() => {
+        getStateDetail();
+    }, [machine.context.currentStatus])
+
+    useEffect(() => {
+        trackTimeService.onTransition(state => {
+            if ((state.value as any).FAST_SLEEP) {
+                setKey('FAST_SLEEP');
+                setValue((state.value as any).FAST_SLEEP);
+            }
+            if ((state.value as any).FAST) {
+                setKey('FAST');
+                setValue((state.value as any).FAST);
+            }
+            if ((state.value as any).SLEEP) {
+                setKey('SLEEP');
+                setValue((state.value as any).SLEEP);
+            }
+        });
+    }, []);
+
+    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' || (state as any).FAST_SLEEP == 'ONGOING3') {
+                setIsFast(true);
+            }
+            else if ((state as any).FAST_SLEEP == 'ONGOING1') {
+                setIsFast(false);
+            }
+        }
+        if ((state as any).FAST) {
+            setKey('FAST');
+            setValue((state as any).FAST);
+            setIsFast(true);
+        }
+        if ((state as any).SLEEP) {
+            setKey('SLEEP');
+            setValue((state as any).SLEEP);
+            setIsFast(false);
+        }
+
+        var checkData = machine.context.checkData;
+        if (checkData) {
+            var current_record = (checkData as any).current_record;
+            if (current_record.fast) {
+                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))
+            }
+
+            if (current_record.sleep) {
+                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 showPicker() {
+        setShowModal(true)
+        setIsOpen(true)
+        global.set_time = new Date().getTime()
+        console.log(global.set_time)
+    }
+
+    function hidePicker() {
+        setIsOpen(false)
+        setTimeout(() => {
+            setShowModal(false)
+        }, 1000)
+    }
+
+    function testLayout() {
+        if (!user.test_user) {
+            return <View />
+        }
+        var current_record = machine.context.checkData ? (machine.context.checkData as any).current_record : null;
+        if (current_record == null) {
+            return <View />
+        }
+        var isStart = false;
+        if (value == 'WAIT_FOR_START' || value == 'ONGOING1') {
+            isStart = true
+        }
+        var isFast = false;
+        switch (value) {
+            case 'WAIT_FOR_START':
+            case 'ONGOING':
+                {
+                    isFast = (scenario.name == 'FAST' || scenario.name == 'FAST_SLEEP')
+                }
+                break;
+            case 'ONGOING1':
+            case 'ONGOING2':
+                {
+                    isFast = false;
+                }
+                break
+            case 'ONGOING3':
+                {
+                    isFast = true;
+                }
+                break;
+
+
+        }
+
+
+
+        return <View style={{ color: '#fff', paddingTop: 30, paddingLeft: 30, display: 'flex', flexDirection: 'column' }}>
+            <Text>check scenario:{isFast ? 'fast' : 'sleep'}</Text>
+            <Text>check type:{isStart ? 'start' : 'end'}</Text>
+            <Text style={{ marginTop: 30 }}>picker restriction</Text>
+            <Text style={{ marginLeft: 50 }}>min:{TimeFormatter.formatTimestamp(global.limit)}</Text>
+            <Text style={{ marginLeft: 50 }}>pick:{TimeFormatter.formatTimestamp(global.picker_time)}</Text>
+            <Text style={{ marginLeft: 50 }}>max{TimeFormatter.formatTimestamp(global.set_time)}</Text>
+
+            <Text style={{ marginTop: 30 }}>now:{TimeFormatter.formatTimestamp(new Date().getTime())}</Text>
+            <Text>elapsed:{TimeFormatter.calculateTimeDifference(global.picker_time, new Date().getTime())}</Text>
+
+            <Text style={{ marginTop: 30 }}>real start:{isStart ? '-' : TimeFormatter.formatTimestamp(isFast ? current_record.fast.real_start_time : current_record.sleep.real_start_time)}</Text>
+            <Text>real duration:{isStart ? '-' : TimeFormatter.calculateTimeDifference(isFast ? current_record.fast.real_start_time : current_record.sleep.real_start_time, new Date().getTime())}</Text>
+        </View>
+    }
+
+
+    function layoutContent() {
+        var limit = global.set_time - 7 * 3600 * 1000 * 24;
+        global.limit = limit
+        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
+            global.limit = limit
+            //当set_time秒数<=latest_record_time秒数时,最小限制时间戳需+1分钟
+            if (new Date(global.set_time).getSeconds() <= new Date(current_record.last_real_check_time).getSeconds()) {
+                limit = limit + 60 * 1000
+            }
+        }
+
+        var color = isFast ? '#aaff00' : '#00ffff'
+        if (value == 'ONGOING2') {
+            color = '#00ffff'
+        }
+
+        var checkData = machine.context.checkData;
+        var current = (checkData as any).current_record
+        var title = getTitle(current)
+
+
+        return <LimitPickers ref={limitPickerRef} limit={limit} limitDay={8}
+            themeColor={color}
+            title={title}
+            onCancel={hidePicker} onChange={(e) => {
+                pickerConfirm(e)
+                hidePicker()
+            }} />
+    }
+
+    function pickerConfirm(t: number) {
+        var date = new Date(t)
+        var setDate = new Date(global.set_time);
+        date.setMilliseconds(setDate.getMilliseconds());
+        date.setSeconds(setDate.getSeconds());
+
+        t = date.getTime();
+
+        if (isFast) {
+            if (value == 'WAIT_FOR_START') {
+                startFast(t, fastDuration);
+            }
+            else {
+                endFast(t)
+            }
+        }
+        else {
+            if (value == 'WAIT_FOR_START' || value == 'ONGOING1') {
+                startSleep(t, sleepDuration);
+            }
+            else {
+                endSleep(t)
+            }
+        }
+    }
+
+    function mixedBtns() {
+        var checkData = machine.context.checkData;
+        var current = (checkData as any).current_record
+        return <View style={{ display: 'flex', marginTop: 22 }}>
+            {
+                (value == 'WAIT_FOR_START' || value == 'DONE') &&
+                <StartFastBtn onClick={showPicker} />
+            }
+            {
+                (value == 'ONGOING' || value == 'ONGOING3') &&
+                <EndFastBtn onClick={showPicker} lowLight={current.fast.target_end_time > new Date().getTime()} />
+            }
+            {
+                value == 'ONGOING1' && <StartSleepBtn onClick={showPicker} />
+            }
+            {
+                value == 'ONGOING2' && <EndSleepBtn onClick={showPicker} lowLight={current.sleep.target_end_time > new Date().getTime()} />
+
+            }
+        </View>
+    }
+
+    function textAlpha() {
+        var checkData = machine.context.checkData;
+        var current = (checkData as any).current_record
+        if (value == 'WAIT_FOR_START' || value == 'DONE') {
+            return 1;
+        }
+
+        if (value == 'ONGOING' || value == 'ONGOING3') {
+            if (current.scenario == 'SLEEP') {
+                return current.sleep.target_end_time > new Date().getTime() ? 0.4 : 1
+            }
+            return current.fast.target_end_time > new Date().getTime() ? 0.4 : 1
+        }
+        if (value == 'ONGOING1')
+            return 1//current.sleep.target_start_time > new Date().getTime()?0.4:1
+        if (value == 'ONGOING2')
+            return current.sleep.target_end_time > new Date().getTime() ? 0.4 : 1
+        return 1
+    }
+
+    function fastBtns() {
+        return <View style={{ display: 'flex', marginTop: 22 }}>
+            {
+                value == 'ONGOING' ? <EndFastBtn onClick={showPicker} lowLight={textAlpha() != 1} /> : <StartFastBtn onClick={showPicker} />
+            }
+        </View>
+    }
+
+    function sleepBtns() {
+        return <View style={{ display: 'flex', marginTop: 22 }}>
+            {
+                value == 'ONGOING' ? <EndSleepBtn onClick={showPicker} lowLight={textAlpha() != 1} /> : <StartSleepBtn onClick={showPicker} />
+            }
+        </View>
+    }
+
+    function durationChange(e) {
+        var count = (e[0] + common.duration.min) * 60 + e[1] * common.duration.step
+        isFast ? setFastDuration(count * 60000) : setSleepDuration(count * 60000);
+        isFast ? setFastPickerValue(e) : setSleepPickerValue(e)
+
+        setIsOpenDurationPicker(false)
+    }
+
+    function login() {
+        Taro.navigateTo({
+            url: '/pages/account/ChooseAuth'
+        })
+    }
+
+    function durationFormate() {
+        if (isFast) {
+            var t = fastDuration / 60000
+            var hour = Math.floor(t / 60)
+            var minute = Math.floor(t % 60)
+            return `${hour > 0 ? hour + '小时' : ''}${minute > 0 ? minute + '分钟' : ''}`
+        }
+        else {
+            var t = sleepDuration / 60000
+            var hour = Math.floor(t / 60)
+            var minute = Math.floor(t % 60)
+            return `${hour > 0 ? hour + '小时' : ''}${minute > 0 ? minute + '分钟' : ''}`
+        }
+
+    }
+
+    function showDurationPicker() {
+        setIsOpenDurationPicker(true)
+    }
+
+    if (!user.isLogin) {
+        return <View style={{ display: 'flex', flexDirection: 'column', width: '100%', alignItems: 'center' }}>
+            <Text>16:00</Text>
+            {/* <PickerViews onChange={() => { }} items={[pickerDurations()]} value={[12 * 15]} /> */}
+            {/* <TimePickers time={isFast ? fastStr : sleepStr} content="" change={handlePickerChange} isPickerView={true} /> */}
+            <Text style={{ color: '#AAFF00' }} onClick={login}>Start Fast</Text>
+        </View>
+    }
+
+
+    function durationPickerContent() {
+        var color = isFast ? '#aaff00' : '#00ffff'
+        if (value == 'ONGOING2') {
+            color = '#00ffff'
+        }
+        var checkData = machine.context.checkData;
+        var current = (checkData as any).current_record
+        var title = getTitle(current)
+        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={() => { setIsOpenDurationPicker(false) }} />
+        </View>
+    }
+
+    function minus() {
+        if (isFast) {
+            var count = fastDuration - 5 * 60 * 1000
+            setFastDuration(count)
+            var hour = count / 60000 / 60
+            var minute = count / 60000 % 60
+
+            setFastPickerValue(durationIndex('00:00', `${hour > 10 ? hour : '0' + hour}:${minute > 10 ? minute : '0' + minute}`, common))
+        }
+        else {
+            var count = sleepDuration - 5 * 60 * 1000
+
+            setSleepDuration(count)
+            var hour = count / 60000 / 60
+            var minute = count / 60000 % 60
+
+            setSleepPickerValue(durationIndex('00:00', `${hour > 10 ? hour : '0' + hour}:${minute > 10 ? minute : '0' + minute}`, common))
+        }
+    }
+
+    function plus() {
+        if (isFast) {
+            var count = fastDuration + 5 * 60 * 1000
+            setFastDuration(count)
+            var hour = count / 60000 / 60
+            var minute = count / 60000 % 60
+
+            setFastPickerValue(durationIndex('00:00', `${hour > 10 ? hour : '0' + hour}:${minute > 10 ? minute : '0' + minute}`, common))
+        }
+        else {
+            var count = sleepDuration + 5 * 60 * 1000
+
+            setSleepDuration(count)
+            var hour = count / 60000 / 60
+            var minute = count / 60000 % 60
+
+            setSleepPickerValue(durationIndex('00:00', `${hour > 10 ? hour : '0' + hour}:${minute > 10 ? minute : '0' + minute}`, common))
+        }
+    }
+
+    function disableMinus() {
+        if (isFast) {
+            if (fastDuration <= 60 * 60 * 1000) {
+                return true;
+            }
+        }
+        else {
+            if (sleepDuration <= 60 * 60 * 1000) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    function disablePlus() {
+        if (isFast) {
+            if (fastDuration >= 23 * 60 * 60 * 1000) {
+                return true;
+            }
+        }
+        else {
+            if (sleepDuration >= 23 * 60 * 60 * 1000) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    var textColor = '#AAFF00'
+    if (!isFast) {
+        textColor = '#00FFFF'
+    }
+
+    return (
+        <Box >
+            <View  style={{ display:'flex',flexDirection: 'column',alignItems: 'center', flexShrink: 0 }}>
+                {
+                    value == 'ONGOING' && <View>
+                        <Text className="counter_text" style={{ color: textColor, opacity: textAlpha() }}>{(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') && <Stepper child={
+                        <Text className="stepper_text" style={{ color: textColor, opacity: textAlpha() }} onClick={showDurationPicker}>{durationFormate()}</Text>
+                    } minus={minus} plus={plus} disableMinus={disableMinus()} disablePlus={disablePlus()} />
+                    // <Text style={{marginBottom:10}} onClick={showDurationPicker}>时长:{durationFormate()}</Text>
+                }
+                {
+                    machine.context.checkData && value == 'ONGOING2' && <View>
+                        <Text className="counter_text" style={{ color: '#00ffff', opacity: textAlpha() }}>{TimeFormatter.countdown((machine.context.checkData as any).current_record.sleep.target_end_time)}</Text>
+                    </View>
+                }
+
+                {
+                    machine.context.checkData && value == 'ONGOING3' && <View>
+                        <Text className="counter_text" style={{ color: textColor, opacity: textAlpha() }}>{TimeFormatter.countdown((machine.context.checkData as any).current_record.fast.target_end_time)}</Text>
+                    </View>
+                }
+
+                <View>
+                    {
+                        key === 'FAST_SLEEP' && mixedBtns()
+                    }
+                    {
+                        key === 'FAST' && fastBtns()
+                    }
+                    {
+                        key === 'SLEEP' && sleepBtns()
+                    }
+                </View>
+                {
+                    showModal && isOpen && <Modal testInfo={testLayout()} children={layoutContent()} dismiss={() => setIsOpen(false)} confirm={() => {
+                        var picker = limitPickerRef.current;
+                        pickerConfirm((picker as any).getConfirmData());
+                        setIsOpen(false);
+                    }} />
+                }
+                {
+                    isOpenDurationPicker && <Modal children={durationPickerContent()} dismiss={() => setIsOpenDurationPicker(false)} confirm={() => {
+                        var picker = durationPickerRef.current;
+                        durationChange((picker as any).getConfirmData());
+                        setIsOpenDurationPicker(false);
+                    }} />
+                }
+            </View>
+        </Box>
+    )
+}

+ 60 - 19
src/features/trackTimeDuration/hooks/Console.tsx

@@ -20,7 +20,7 @@ export const durationDatas = (common: any) => {
     var min: number = 1
     var max: number = 23
     var step: number = 5
-    
+
     if (common.duration) {
         min = common.duration.min
         max = common.duration.max
@@ -28,22 +28,22 @@ export const durationDatas = (common: any) => {
     }
     var minutes: string[] = []
     for (let i = 0; i < 60; i += step) {
-        minutes.push(i+'分钟')
+        minutes.push(i + '分钟')
     }
     var hours: string[] = []
     for (let i = min; i <= max; i++) {
-        hours.push(i+'小时')
+        hours.push(i + '小时')
     }
     return [hours, minutes]
 }
 
 //通过开始时间和结束时间计算picker的index值,返回格式为[hourIndex,minuteIndex]
-export const durationIndex = (start: string, end: string,common: any) => {
-    if ((start+'').indexOf(':') == -1) {
-        start = TimeFormatter.formatTime(new Date(parseInt(start+'')));
+export const durationIndex = (start: string, end: string, common: any) => {
+    if ((start + '').indexOf(':') == -1) {
+        start = TimeFormatter.formatTime(new Date(parseInt(start + '')));
     }
-    if ((end+'').indexOf(':') == -1) {
-        end = TimeFormatter.formatTime(new Date(parseInt(end+'')));
+    if ((end + '').indexOf(':') == -1) {
+        end = TimeFormatter.formatTime(new Date(parseInt(end + '')));
     }
 
     var min: number = 1
@@ -93,29 +93,70 @@ export const durationTime = (start: string, end: string) => {
     return [leftHour, leftMinute]
 }
 
-export const getTitle = (data)=>{
-    if (data.scenario == 'FAST'){
-        if (data.status == 'WAIT_FOR_START'){
+
+//按钮文字
+export const getTitle = (data) => {
+    if (data.scenario == 'FAST') {
+        if (data.status == 'WAIT_FOR_START') {
             return '开始断食'
-        } 
+        }
         return '结束断食'
     }
-    else if (data.scenario == 'SLEEP'){
-        if (data.status == 'WAIT_FOR_START'){
+    else if (data.scenario == 'SLEEP') {
+        if (data.status == 'WAIT_FOR_START') {
             return '开始睡眠'
-        } 
+        }
         return '结束睡眠'
     }
     else {
-        if (data.status == 'WAIT_FOR_START'){
+        if (data.status == 'WAIT_FOR_START') {
             return '开始断食'
-        } 
-        else if (data.status == 'ONGOING1'){
+        }
+        else if (data.status == 'ONGOING1') {
             return '开始睡眠'
         }
-        else if (data.state == 'ONGOING2'){
+        else if (data.state == 'ONGOING2') {
             return '结束睡眠'
         }
         return '结束睡眠'
     }
+}
+
+//按钮颜色
+export const getColor = (data) => {
+    if (data.scenario == 'FAST') {
+        return '#aaff00'
+    }
+    else if (data.scenario == 'SLEEP') {
+        return '#00ffff'
+    }
+    else {
+        if (data.status == 'WAIT_FOR_START' || data.status == 'ONGOING3') {
+            return '#aaff00'
+        }
+    }
+    return '#00ffff'
+}
+
+//透明度
+export const textAlpha = (time) => {
+    if (time.status == 'WAIT_FOR_START' || time.status == 'DONE') {
+        return 1;
+    }
+
+    if (time.status == 'ONGOING' || time.status == 'ONGOING3') {
+        if (time.scenario == 'SLEEP') {
+            return time.sleep.target_end_time > new Date().getTime() ? 0.4 : 1
+        }
+        return time.fast.target_end_time > new Date().getTime() ? 0.4 : 1
+    }
+    if (time.status == 'ONGOING1')
+        return 1//current.sleep.target_start_time > new Date().getTime()?0.4:1
+    if (time.status == 'ONGOING2')
+        return time.sleep.target_end_time > new Date().getTime() ? 0.4 : 1
+    return 1
+}
+
+export const textNextStepAlpha = (time) => {
+    return time.fast.target_end_time > new Date().getTime() ? 0.4 : 1
 }

+ 4 - 0
src/pages/clock/Clock.scss

@@ -31,6 +31,10 @@
     justify-content: center;
   }
 
+  .swiper{
+    height: 400px;
+  }
+
   .swiperItem{
     // height: 300px !important;
     // height: auto !important;

+ 47 - 19
src/pages/clock/Clock.tsx

@@ -29,6 +29,8 @@ import RecordFastSleep from '@/features/trackTimeDuration/components/RecordFastS
 import Box from '@/components/layout/Box'
 import Layout from '@/components/layout/layout'
 import { NaviBarTitleShowType, TemplateType } from '@/utils/types'
+import { updateScenario } from '@/store/time'
+import { showModal } from '@/store/modal'
 // import TabBar from '../../components/Tabbar';
 
 export default function IndexPage() {
@@ -36,11 +38,19 @@ export default function IndexPage() {
   const array: any[] = []
   const [checkData, setCheckData] = useState(null)
   const user = useSelector((state: any) => state.user);
+  const time = useSelector((state: any) => state.time);
   const permission = useSelector((state: any) => state.permission);
   const common = useSelector((state: any) => state.common);
   const [counter, setCounter] = useState(0)
   const [timerId, setTimerId] = useState(null)
   const [needShowAddTip, setNeedShowAddTip] = useState(false)
+
+  const [showModal, setShowModal] = useState(false)
+  const [modalDetail, setModalDetail] = useState<any>({})
+
+  const [showModal2, setShowModal2] = useState(false)
+  const [modalDetail2, setModalDetail2] = useState<any>({})
+
   array.push(<Text>ffff</Text>)
   // array.push(<Rings radius={50}/>)
   global.dispatch = dispatch;
@@ -169,6 +179,7 @@ export default function IndexPage() {
 
   function getCheckData() {
     getClocks().then(res => {
+      dispatch(updateScenario((res as any).current_record))
       dispatch(setConfigs((res as any).time_input_schema));
       dispatch(setScenario((res as any).scenario));
       machine.context.checkData = res as any;
@@ -285,13 +296,24 @@ export default function IndexPage() {
   }
 
   function needSwiper() {
-    var isNeed = checkData &&
-      (checkData as any).current_record &&
-      (checkData as any).current_record.scenario == 'FAST_SLEEP' &&
-      (checkData as any).current_record.status == 'WAIT_FOR_START'
+    var isNeed = time.scenario == 'FAST_SLEEP' &&
+      (time.status == 'WAIT_FOR_START' ||
+        time.status == 'ONGOING1' ||
+        time.status == 'ONGOING2')
     return isNeed
   }
 
+  global.showClockModal = (isShow: boolean, detail: any) => {
+    setShowModal(isShow)
+    setModalDetail(detail)
+  }
+
+  global.showClockModal2 = (isShow: boolean, detail: any) => {
+    setShowModal2(isShow)
+    setModalDetail2(detail)
+  }
+
+
   return (
     <Layout type={TemplateType.flex} title='时钟' titleShowStyle={NaviBarTitleShowType.scrollToShow}>
       <View style={{ flex: 1, flexDirection: 'column', display: 'flex', backgroundColor: '#000', color: '#fff' }}>
@@ -307,24 +329,24 @@ export default function IndexPage() {
 
         </Box>
 
-        {/* {
-        needSwiper() ? <Swiper className='swiper' style={{ flexShrink: 0, display: 'flex', height: 173 }} indicatorColor='#999'
-          indicatorActiveColor='#333'
-          indicatorDots>
-          <SwiperItem className='swiperItem'>
-            <Console />
-
-          </SwiperItem>
-
-          <SwiperItem className='swiperItem'>
+        {
+          needSwiper() ? <Swiper className='swiper' indicatorColor='#333'
+            indicatorActiveColor='#999'
+            indicatorDots>
+            <SwiperItem className='swiperItem'>
+              <Console />
+
+            </SwiperItem>
+
+            <SwiperItem className='swiperItem'>
+              <Console isNextStep={true} />
+            </SwiperItem>
+          </Swiper> :
             <Console />
-          </SwiperItem>
-        </Swiper> :
-          <Console />
 
-      } */}
+        }
 
-        <Console />
+        {/* <Console /> */}
 
 
         <More ref={global.moreRef} />
@@ -343,6 +365,12 @@ export default function IndexPage() {
         }
         <View style={{ height: 100 }} />
       </View>
+      {
+        showModal && modalDetail
+      }
+      {
+        showModal2 && modalDetail2
+      }
     </Layout>
   )
 }

+ 1 - 1
src/services/trackTimeDuration.tsx

@@ -63,7 +63,7 @@ export const recordCheck = (params: Record<string, any>) => {
         var month = date.getMonth()+1
         var day = date.getDate()
         
-        params.real_check_date = date.getFullYear+(month<10?'0'+month:month+'')+(day<10?'0'+day:day+'')
+        params.real_check_date = date.getFullYear()+(month<10?'0'+month:month+'')+(day<10?'0'+day:day+'')
     }
     return new Promise((resolve) => {
         request({

+ 36 - 0
src/store/modal.tsx

@@ -0,0 +1,36 @@
+// modalReducer.ts
+
+import { createSlice, PayloadAction } from '@reduxjs/toolkit';
+
+interface ModalState {
+  isOpen: boolean;
+  title: string;
+  content: string;
+}
+
+const initialState: ModalState = {
+  isOpen: false,
+  title: '',
+  content: '',
+};
+
+const modalSlice = createSlice({
+  name: 'modal',
+  initialState,
+  reducers: {
+    showModal: (state, action: PayloadAction<{ title: string; content: string }>) => {
+      state.isOpen = true;
+      state.title = action.payload.title;
+      state.content = action.payload.content;
+      debugger
+    },
+    hideModal: (state) => {
+      state.isOpen = false;
+      state.title = '';
+      state.content = '';
+    },
+  },
+});
+
+export const { showModal, hideModal } = modalSlice.actions;
+export default modalSlice.reducer;

+ 5 - 1
src/store/store.tsx

@@ -4,6 +4,8 @@ import scenarioReducer from './scenario';
 import permissionReducer from './permission';
 import commonReducer from './common';
 import resultReducer from './action_results';
+import timeReducer from './time';
+import modalReducer from './modal';
 
 const store = configureStore({
   reducer: {
@@ -13,7 +15,9 @@ const store = configureStore({
     permission: permissionReducer,
     common: commonReducer,
     checkResult: resultReducer,
-    codeResult: resultReducer
+    codeResult: resultReducer,
+    time: timeReducer,
+    modal:modalReducer
   },
 });
 

+ 67 - 0
src/store/time.tsx

@@ -0,0 +1,67 @@
+import { createSlice, PayloadAction } from '@reduxjs/toolkit';
+import Taro from '@tarojs/taro';
+interface TimeState {
+    scenario: string | null;
+    status: string | null;
+    fast: any | null;
+    sleep: any | null;
+    last_real_check_time: number | null;
+}
+
+const initialState: TimeState = {
+    fast: null,
+    sleep: null,
+    scenario: '',
+    status: '',
+    last_real_check_time:null
+}
+
+const timeSlice = createSlice({
+    name: 'time',
+    initialState,
+    reducers: {
+        updateScenario(state, action: PayloadAction<any>) {
+            const { fast, sleep, status, scenario,last_real_check_time } = action.payload;
+            state.fast = fast
+            state.sleep = sleep
+            state.status = status
+            state.scenario = scenario
+            state.last_real_check_time = last_real_check_time
+        },
+        fastStartSuccess(state, action: PayloadAction<any>) {
+            const { fast, sleep, status, scenario,last_real_check_time } = action.payload;
+            state.fast = fast
+            state.sleep = sleep
+            state.status = status
+            state.scenario = scenario
+            state.last_real_check_time = last_real_check_time
+        },
+        fastEndSuccess(state, action: PayloadAction<any>) {
+            const { fast, sleep, status, scenario,last_real_check_time } = action.payload;
+            state.fast = fast
+            state.sleep = sleep
+            state.status = status
+            state.scenario = scenario
+            state.last_real_check_time = last_real_check_time
+        },
+        sleepStartSuccess(state, action: PayloadAction<any>) {
+            const { fast, sleep, status, scenario,last_real_check_time } = action.payload;
+            state.fast = fast
+            state.sleep = sleep
+            state.status = status
+            state.scenario = scenario
+            state.last_real_check_time = last_real_check_time
+        },
+        sleepEndSuccess(state, action: PayloadAction<any>) {
+            const { fast, sleep, status, scenario,last_real_check_time } = action.payload;
+            state.fast = fast
+            state.sleep = sleep
+            state.status = status
+            state.scenario = scenario
+            state.last_real_check_time = last_real_check_time
+        },
+    },
+});
+
+export const { fastStartSuccess, fastEndSuccess, sleepStartSuccess, sleepEndSuccess, updateScenario } = timeSlice.actions;
+export default timeSlice.reducer;