Leon 2 лет назад
Родитель
Сommit
99ae3029e1

+ 4 - 2
src/app.config.ts

@@ -1,5 +1,6 @@
 const appConfig = defineAppConfig({
   pages: [
+    'pages/clock/Index',
     'pages/clock/Clock',
     'pages/demo',
     'pages/food/Food',
@@ -73,7 +74,8 @@ process.env.TARO_ENV === 'weapp' && (appConfig.tabBar = {
   borderStyle: 'black',
   list: [
     {
-      pagePath: 'pages/clock/Clock',
+      // pagePath: 'pages/clock/Clock',
+      pagePath: 'pages/clock/Index',
       text: '生物钟',
     },
     {
@@ -86,7 +88,7 @@ process.env.TARO_ENV === 'weapp' && (appConfig.tabBar = {
     },
     {
       // pagePath: 'pages/activity/Activity',
-      pagePath:'pages/workout/Workout',
+      pagePath: 'pages/workout/Workout',
       text: '运动',
     },
     {

+ 1 - 1
src/components/navigation/TabBar.tsx

@@ -13,7 +13,7 @@ export default function Component(props: { index: number }) {
             case 0:
 
                 Taro.switchTab({
-                    url: '/pages/clock/Clock'
+                    url: '/pages/clock/Index'
                 })
                 break;
             case 1:

+ 4 - 2
src/features/trackTimeDuration/components/Console.tsx

@@ -316,7 +316,7 @@ export default function Component(props: { isNextStep?: boolean }) {
         return <View className="btn_bg">
             {
                 (time.status == 'WAIT_FOR_START') &&
-                <StartSleepBtn onClick={() => { vibrate()}} />
+                <StartSleepBtn onClick={() => { vibrate() }} />
             }
             {
                 time.status == 'ONGOING1' && <EndFastBtn onClick={showPicker} lowLight={time.fast.target_end_time > new Date().getTime()} />
@@ -387,6 +387,8 @@ export default function Component(props: { isNextStep?: boolean }) {
         var color = getColor(time)
         var title = getDurationTitle(time, t)
         return <View style={{ color: '#fff', backgroundColor: 'transparent' }}>
+
+            
             <PickerViews ref={durationPickerRef}
                 onChange={durationChange}
                 items={durationDatas(common)}
@@ -511,7 +513,7 @@ export default function Component(props: { isNextStep?: boolean }) {
             }}>
                 {
                     (time.status == 'WAIT_FOR_START') && <Stepper children={
-                        <Text className="stepper_text" style={{ color: global.sleepColor ? global.sleepColor : ColorType.sleep, opacity: textAlpha(time) }} onClick={() => {vibrate() }}>{durationFormate()}</Text>
+                        <Text className="stepper_text" style={{ color: global.sleepColor ? global.sleepColor : ColorType.sleep, opacity: textAlpha(time) }} onClick={() => { vibrate() }}>{durationFormate()}</Text>
                     } minus={minus} plus={plus}
                         themeColor={global.sleepColor ? global.sleepColor : ColorType.sleep} disableMinus={disableMinus()} disablePlus={disablePlus()} />
                 }

+ 87 - 0
src/features/trackTimeDuration/components/IndexItem.scss

@@ -0,0 +1,87 @@
+@import '@/utils/common.scss';
+.time_operate_item{
+    padding-top: 40px;
+    padding-bottom: 40px;
+    margin-left: 46px;
+    margin-right: 46px;
+    display: flex;
+    flex-direction: row;
+    align-items: center;
+    background-color: $boxColor;
+    border-radius: $boxBorderRadius;
+    padding-left: 40px;
+    padding-right: 40px;
+    margin-bottom: 16px;
+}
+
+.modalTitle1{
+    font-size: 40px;
+    line-height: 40px;
+}
+
+.segment_detail{
+    width: 578px;
+}
+
+
+.fast_sleep_item {
+    // display: 'flex',position:'relative', flex-: 'row', alignItems: 'center'
+    display: flex;
+    position: relative;
+    flex-direction: row;
+    align-items: center;
+    width: 578px;
+    // padding-top: 20px;
+    // padding-bottom: 20px;
+}
+
+.duration_bg {
+    margin-left: 50px;
+    display: flex;
+    flex-direction: column;
+    flex: 1;
+}
+
+.duration_title {
+    font-size: 32px;
+    line-height: 32px;
+    color: #fff;
+    opacity: 0.6;
+    font-weight: 400;
+}
+
+.duration_value {
+    margin-top: 2px;
+    font-size: 36px;
+    line-height: 36px;
+    font-weight: 500;
+    margin-bottom: 12px;
+}
+
+.arrow2 {
+    width: 40px;
+    height: 40px;
+    opacity: 0.2;
+}
+
+.recordTime {
+
+    font-size: 28px;
+    line-height: 28px;
+    height: 28px;
+    color: #ffffff;
+    opacity: 0.4;
+    font-weight: 400;
+
+}
+
+.record_arrow_bg {
+    position: absolute;
+    right: -10px;
+    bottom: -10px;
+    display: flex;
+    flex-direction: row;
+    align-items: center;
+    height: 40px;
+    width: 300px;
+}

+ 199 - 0
src/features/trackTimeDuration/components/IndexItem.tsx

@@ -0,0 +1,199 @@
+import { View, Text, Image } from "@tarojs/components";
+import { getBgRing, getCommon, getDot, getReal, getSchedule, getTarget } from "../hooks/RingData";
+import Rings from "./Rings";
+import './IndexItem.scss'
+import { useTranslation } from "react-i18next";
+import { ColorType } from "@/context/themes/color";
+import { jumpPage } from "@/features/trackTimeDuration/hooks/Common";
+import { TimeFormatter } from "@/utils/time_format";
+
+let useNavigation;
+if (process.env.TARO_ENV == 'rn') {
+    useNavigation = require("@react-navigation/native").useNavigation
+}
+export default function Component(props: { type: string, data: any, time: any }) {
+    const { t } = useTranslation()
+    const record = props.data.current_record;
+    let navigation;
+    if (useNavigation) {
+        navigation = useNavigation()
+    }
+
+    function durationArc(start_time: number, end_time: number) {
+        var duration = (end_time - start_time) / 1000;
+        return duration / (24 * 3600) * 2 * Math.PI;
+    }
+
+
+    function bigRing() {
+        debugger
+        var common = getCommon(null, true)
+        common.radius = 42;
+        common.lineWidth = 9;
+        var bgRing = getBgRing()
+
+        if (props.type == 'SLEEP') {
+            var realRing = getReal(record, false, true)
+            if (record.status == 'WAIT_FOR_START' || record.status == 'ONGOING1') {
+                var realRing1 = getSchedule(record, props.type != 'SLEEP', true)
+                return <Rings common={common} bgRing={bgRing} realRing={realRing1} canvasId={props.type + props.time + 'big'} />
+            }
+            if (props.data.status == 'ONGOING3') {
+                realRing.color = 'rgba(0,0,0,0)'
+                // bgRing.color = 'rgba(0,0,0,0)'
+            }
+            return <Rings common={common} bgRing={bgRing} canvasId={props.type + props.time + 'big'} realRing={realRing} />
+        }
+        else {
+            var currentDot1 = getDot(record, true)
+            var targetBigRing1 = getTarget(record, true)
+            if (record.status == 'ONGOING') {
+                var realRing1 = getReal(record, true, false)
+
+                return <Rings common={common} bgRing={bgRing} currentDot={currentDot1} realRing={realRing1} targetRing={targetBigRing1} canvasId={props.type + props.time + 'big'} />
+            }
+            if (record.status == 'WAIT_FOR_START') {
+                var realRing1 = getSchedule(record, props.type != 'SLEEP', true)
+                return <Rings common={common} bgRing={bgRing} realRing={realRing1} canvasId={props.type + props.time + 'big'} />
+            }
+            var realRing1 = getReal(record, true, false)
+            return <Rings common={common} bgRing={bgRing} realRing={realRing1} currentDot={currentDot1} targetRing={targetBigRing1} canvasId={props.type + props.time + 'big'} />
+        }
+    }
+
+    function smallRing() {
+        if (record.scenario == 'FAST_SLEEP') {
+            var common = getCommon(null, false)
+            common.radius = 28;
+            common.lineWidth = 9;
+            var bgRing = getBgRing()
+            var realRing = getReal(record, false, false)
+            if (props.type == 'SLEEP' || props.type == 'FAST_SLEEP') {
+                if (record.sleep.status == 'WAIT_FOR_END') {
+                    realRing.durationArc = durationArc(record.sleep.target_start_time, (new Date()).getTime())
+                    return <Rings common={common} bgRing={bgRing} canvasId={props.type + props.time + 'small'} realRing={realRing} />
+                }
+                else if (record.status == 'WAIT_FOR_START' || record.status == 'ONGOING1') {
+                    realRing = getSchedule(record, false, true)
+                    return <Rings common={common} bgRing={bgRing} realRing={realRing} canvasId={props.type + props.time + 'small'} />
+                }
+                else if (record.sleep.status == 'NOT_COMPLETED') {
+                    realRing.durationArc = 0.01
+                    return <Rings common={common} bgRing={bgRing} canvasId={props.type + props.time + 'small'} realRing={realRing} />
+                }
+                else if (record.sleep.status == 'COMPLETED') {
+                    realRing = getReal(record, false, true)
+                    return <Rings common={common} bgRing={bgRing} canvasId={props.type + props.time + 'small'} realRing={realRing} />
+                }
+                return <Rings common={common} bgRing={bgRing} canvasId={props.type + props.time + 'small'} />
+            }
+            else {
+
+
+                var currentDot = getDot(record, false)
+                var targetRing = getTarget(record, false)
+                if (record.status == 'ONGOING2') {
+                    var realRing = getReal(record, false, false)
+                    return <Rings common={common} bgRing={bgRing} realRing={realRing} currentDot={currentDot} targetRing={targetRing} canvasId={props.type + props.time + 'small'} />
+                }
+                if (record.status == 'ONGOING3') {
+                    currentDot.color = 'rgba(0, 255, 255, 0.5)'
+                }
+                return <Rings common={common} bgRing={bgRing} currentDot={currentDot} canvasId={props.type + props.time + 'small'} />
+            }
+        }
+        return null
+    }
+
+    function rings() {
+        return <View style={{ position: 'relative', zIndex: 1 }}>
+            {
+                bigRing()
+            }
+            {
+                props.type == 'FAST_SLEEP' && <View style={{ display: 'flex', position: 'absolute', left: 0, right: 0, top: 0, bottom: 0, alignItems: 'center', justifyContent: 'center' }}>
+                    {
+                        smallRing()
+                    }
+                </View>
+            }
+
+        </View>
+    }
+
+    function getArrowText() {
+        if (record.status == 'WAIT_FOR_START') {
+            return '去开始'
+        }
+        if (record.status == 'ONGOING1' && props.type == 'SLEEP') {
+            return '去开始'
+        }
+        return '去结束'
+    }
+
+    function getDuration(obj) {
+        if (!obj) {
+        }
+        if (obj.status == 'NOT_STARTED' || obj.status == 'NOT_COMPLETED') {
+            return ''
+        }
+        var start = obj.real_start_time
+        var end = obj.real_end_time
+        if (!end) {
+            end = (new Date()).getTime()
+        }
+        if (obj.status == 'WAIT_FOR_START') {
+            start = obj.target_start_time
+            end = obj.target_end_time
+        }
+        return TimeFormatter.durationFormate(start, end)
+        // return TimeFormatter.calculateTimeDifference(start, end)
+    }
+
+    function fastDuration() {
+        if (record.fast.status == 'WAIT_FOR_END') {
+            return TimeFormatter.formateTimeDifference(record.fast.real_start_time, new Date().getTime(), true)
+        }
+        return getDuration(record.fast)
+    }
+
+    function sleepDuration() {
+        if (record.sleep.status == 'WAIT_FOR_END') {
+            return TimeFormatter.formateTimeDifference(record.sleep.real_start_time, new Date().getTime(), true)
+        }
+        return getDuration(record.sleep)
+    }
+
+    function goClock() {
+        jumpPage('/pages/clock/Clock', 'Clock', navigation)
+    }
+
+    return <View className="time_operate_item" onClick={goClock}>
+        <View className="fast_sleep_item">
+            {
+                rings()
+            }
+            <View className="duration_bg">
+                {
+                    (props.type == 'FAST' || props.type == 'FAST_SLEEP') && <Text className="duration_title">{t('feature.track_time_duration.record_fast_sleep.item.fast')}</Text>
+                }
+                {
+                    (props.type == 'FAST' || props.type == 'FAST_SLEEP') && <Text className="duration_value" style={{ color: global.fastColor ? global.fastColor : ColorType.fast }}>{fastDuration()}</Text>
+                }
+                {
+                    (props.type == 'SLEEP' || props.type == 'FAST_SLEEP') && <Text className="duration_title">{t('feature.track_time_duration.record_fast_sleep.item.sleep')}</Text>
+                }
+                {
+                    (props.type == 'SLEEP' || props.type == 'FAST_SLEEP') && <Text className="duration_value" style={{ color: global.sleepColor ? global.sleepColor : ColorType.sleep }}>{sleepDuration()}</Text>
+                }
+            </View>
+            {/* <Image className="arrow1" src={require('@/assets/images/arrow.png')} /> */}
+            <View className="record_arrow_bg" style={{ backgroundColor: global.isDebug ? 'red' : 'transparent' }}>
+                <View style={{ flex: 1 }} />
+                <Text className='recordTime'>{getArrowText()}</Text>
+                <Image className="arrow2" src={require('@/assets/images/arrow3.png')} />
+            </View>
+
+        </View>
+    </View>
+}

+ 35 - 2
src/features/trackTimeDuration/hooks/RingData.tsx

@@ -107,6 +107,7 @@ export const getTarget = (data: any, isBigRing: boolean) => {
             // if (data.fast.real_start_time_zone) {
             //     timestamp = TimeFormatter.transferTimestamp(timestamp, data.fast.real_start_time_zone)
             // }
+            targetRingBig.color = (global.fastColor ? global.fastColor : ColorType.fast)+'66'
             targetRingBig.startArc = startArc(timestamp)
             targetRingBig.durationArc = durationArc(data.fast.target_start_time, data.fast.target_end_time)
         }
@@ -123,6 +124,38 @@ export const getTarget = (data: any, isBigRing: boolean) => {
     }
 }
 
+export const getSchedule = (data: any, isFast: boolean, isBigRing: boolean) => {
+    const realRingBig: RealRing = {
+        color: global.fastColor ? global.fastColor : ColorType.fast,
+        startArc: 0,
+        durationArc: 0
+    }
+
+    const realRingSmall: RealRing = {
+        color: global.sleepColor ? global.sleepColor : ColorType.sleep,
+        startArc: 0,
+        durationArc: 0
+    }
+
+    if (isBigRing) {
+        if (isFast) {
+            realRingBig.startArc = startArc(data.fast.target_start_time)
+            realRingBig.durationArc = durationArc(data.fast.target_start_time, data.fast.target_end_time)
+        }
+        else {
+            realRingBig.color = global.sleepColor ? global.sleepColor : ColorType.sleep
+            realRingBig.startArc = startArc(data.sleep.target_start_time)
+            realRingBig.durationArc = durationArc(data.sleep.target_start_time, data.sleep.target_end_time)
+        }
+        return realRingBig
+    }
+    else {
+        realRingSmall.startArc = startArc(data.sleep.target_start_time)
+        realRingSmall.durationArc = durationArc(data.sleep.target_start_time, data.sleep.target_end_time)
+        return realRingSmall
+    }
+}
+
 export const getReal = (data: any, isBigRing: boolean, isRecord: boolean) => {
     // console.log(data)
     const realRingBig: RealRing = {
@@ -153,7 +186,7 @@ export const getReal = (data: any, isBigRing: boolean, isRecord: boolean) => {
         else {
             if (data.fast.real_end_time_zone && data.status == 'COMPLETED') {
                 var timestamp = TimeFormatter.transferTimestamp(data.fast.real_start_time, data.fast.real_end_time_zone)
-         
+
                 realRingBig.startArc = startArc(timestamp)
             }
             else {
@@ -167,7 +200,7 @@ export const getReal = (data: any, isBigRing: boolean, isRecord: boolean) => {
     else {
         if (data.sleep.real_end_time_zone && data.status == 'COMPLETED') {
             // alert(data.fast.real_end_time_zone)
-            var timestamp = TimeFormatter.transferTimestamp(data.sleep.real_start_time, data.fast.real_end_time_zone?data.fast.real_end_time_zone:data.sleep.real_end_time_zone)
+            var timestamp = TimeFormatter.transferTimestamp(data.sleep.real_start_time, data.fast.real_end_time_zone ? data.fast.real_end_time_zone : data.sleep.real_end_time_zone)
             // alert(timestamp)
             realRingSmall.startArc = startArc(timestamp)
         }

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

@@ -602,6 +602,6 @@ export default function IndexPage() {
 
   return <View>
     {detail()}
-    <Tabbar index={0} />
+    {/* <Tabbar index={0} /> */}
   </View>
 }

+ 17 - 0
src/pages/clock/Index.scss

@@ -0,0 +1,17 @@
+.index_container{
+    display: flex;
+    flex-direction: column;
+    color: #fff;
+}
+
+.discovery{
+    margin-left: 46px;
+    font-weight: bold;
+    font-size: 48px;
+    margin-top: 64px;
+    margin-bottom: 22px;
+}
+
+.count{
+    opacity: 0;
+}

+ 88 - 0
src/pages/clock/Index.tsx

@@ -0,0 +1,88 @@
+import { View, Text } from "@tarojs/components";
+import Tabbar from "@/components/navigation/TabBar";
+import IndexItem from '@/features/trackTimeDuration/components/IndexItem';
+
+import './Index.scss'
+import { useDispatch, useSelector } from "react-redux";
+import { useReady } from "@tarojs/taro";
+import Taro from "@tarojs/taro";
+import { getInfoSuccess } from "@/store/user";
+import { getClocks } from "@/services/trackTimeDuration";
+import { updateScenario } from "@/store/time";
+import { setConfigs } from "@/store/common";
+import { setScenario } from "@/store/scenario";
+import { useEffect, useState } from "react";
+
+export default function Page() {
+    const dispatch = useDispatch();
+    global.dispatch = dispatch;
+    const user = useSelector((state: any) => state.user);
+    const time = useSelector((state: any) => state.time);
+    const [showErrorPage, setErrorPage] = useState(false)
+    const [data, setData] = useState(null)
+    const [count,setCount] = useState(0)
+
+    useEffect(()=>{
+        setInterval(()=>{
+            setCount((prevCounter) => prevCounter + 1)
+        },1000)
+    },[])
+
+    useEffect(() => {
+        if (user.isLogin) {
+          getCheckData()
+        }
+      }, [user.isLogin,time.status])
+
+    useReady(async () => {
+        const userData = await getStorage('userData');
+        if (userData) {
+            dispatch(getInfoSuccess(JSON.parse(userData as string)) as any);
+            // setTimeout(() => {
+            //     // checkWXPubFollow()
+            //     getCheckData()
+
+            // }, 200)
+
+        }
+    })
+
+    function getCheckData() {
+        getClocks().then(res => {
+            setErrorPage(false)
+            setData(res as any)
+            dispatch(updateScenario((res as any).current_record))
+            dispatch(setConfigs((res as any).time_input_schema));
+            dispatch(setScenario((res as any).scenario));
+
+            if ((res as any).theme_color) {
+                global.fastColor = (res as any).theme_color.fast
+                global.sleepColor = (res as any).theme_color.sleep
+            }
+        })
+    }
+
+    async function getStorage(key: string) {
+        try {
+            const res = await Taro.getStorage({ key });
+            return res.data;
+        } catch {
+            return '';
+        }
+    }
+    if (!data){
+        return <View>
+            <Tabbar index={0} />
+        </View>
+    }
+
+    var timestamp = new Date().getTime()
+    return <View className="index_container">
+        <Text className="count">{count}</Text>
+        <IndexItem type="FAST" data={data} time={timestamp}/>
+        <IndexItem type='SLEEP' data={data}  time={timestamp}/>
+        <Text className="discovery">探索</Text>
+        <IndexItem type="FAST_SLEEP" data={data}  time={timestamp}/>
+        <Tabbar index={0} />
+    </View>
+}

+ 25 - 0
src/utils/tools.ts

@@ -9,6 +9,31 @@ export function alphaToHex(alpha) {
     return hexValue;
 }
 
+export function rgbaToRgb(rgba) {
+    if (rgba.startsWith("rgba")) {
+        // 提取 RGBA 值
+        const regex = /rgba\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+(\.\d+)?)\s*\)/;
+        const matches = rgba.match(regex);
+
+        if (matches && matches.length === 6) {
+            const red = parseInt(matches[1]);
+            const green = parseInt(matches[2]);
+            const blue = parseInt(matches[3]);
+            const alpha = parseFloat(matches[4]);
+
+            // 计算 RGB 值
+            const rgbRed = Math.round(red * alpha);
+            const rgbGreen = Math.round(green * alpha);
+            const rgbBlue = Math.round(blue * alpha);
+
+            return `rgb(${rgbRed}, ${rgbGreen}, ${rgbBlue})`;
+        }
+    }
+
+    // 如果无法解析或不是 RGBA 值,则返回原始值
+    return rgba;
+}
+
 export function rpxToPx(n: number) {
     var rate = Taro.getSystemInfoSync().windowWidth / 750;
     return n * rate;