Leon 2 år sedan
förälder
incheckning
b6e57fc1c7

+ 2 - 0
src/app.config.ts

@@ -3,6 +3,8 @@ const appConfig = defineAppConfig({
     'pages/Clock',
     'pages/demo',
     
+    
+    
     'pages/index/index',
     'pages/Login',
     'pages/Auth',

BIN
src/assets/images/timeline_done.png


BIN
src/assets/images/timeline_pedding.png


BIN
src/assets/images/timeline_undone.png


+ 9 - 2
src/components/LimitPickers.tsx

@@ -1,13 +1,12 @@
 import { PickerView, PickerViewColumn, View, Text } from "@tarojs/components";
 import { forwardRef, useEffect, useImperativeHandle, useState } from "react";
 import './LimitPickers.scss'
+import Taro from "@tarojs/taro";
 // export default function Component(props: { limit: number, onChange: Function, onCancel: Function,isRealTime?:boolean,limitDay?:number,time?:number,ref?:any }) {
 const Component = forwardRef((props: { limit: number, onChange: Function, onCancel: Function, isRealTime?: boolean, limitDay?: number, time?: number }, ref) => {
     const days: string[] = [];
     const today = new Date();
     const [values, setValues] = useState([props.limitDay ? props.limitDay - 1 : 6, today.getHours(), today.getMinutes()])
-
-    debugger
     useEffect(() => {
         global.picker_time = global.set_time
         if (props.time) {
@@ -99,6 +98,10 @@ const Component = forwardRef((props: { limit: number, onChange: Function, onCanc
         //     setValues([list[0], today.getHours(), today.getMinutes()])
         // }
         if (getTimestamp(time) > global.set_time) {
+            Taro.showToast({
+                icon: 'none',
+                title: '不能更大了',
+            })
             setValues([list[0], (new Date(global.set_time)).getHours(), (new Date(global.set_time)).getMinutes()])
         }
         else {
@@ -113,6 +116,10 @@ const Component = forwardRef((props: { limit: number, onChange: Function, onCanc
             // 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))
+                Taro.showToast({
+                    icon: 'none',
+                    title: '不能更小了',
+                })
                 setValues([(props.limitDay ? props.limitDay - 1 : 6) - getDaysDiff(limitDate), limitDate.getHours(), limitDate.getMinutes()])
                 return
             }

+ 63 - 0
src/components/Timeline.scss

@@ -0,0 +1,63 @@
+.timeline {
+    display: flex;
+    flex-direction: column;
+    
+  }
+  
+  .timeline-item {
+    display: flex;
+    // align-items: center;
+    margin-bottom: 20px;
+    position: relative;
+  }
+  
+  .timeline-icon {
+    width: 20px;
+    height: 20px;
+    border-radius: 50%;
+    margin-right: 10px;
+  }
+  
+  .padding {
+    background-color: #ccc;
+  }
+  
+  .done {
+    background-color: green;
+  }
+  
+  .un_done {
+    background-color: red;
+  }
+  
+  .timeline-line {
+    width: 1px;
+    background-color: #FFFFFF66;
+    position: absolute;
+    top: 25px;
+    left: 10px;
+    bottom: -15px;
+    
+  }
+
+  .dash{
+    background-color: transparent;
+    border-left-style: dashed;
+    border-left-color: #FFFFFF66;
+    border-left-width: 1px;
+  }
+
+
+  
+  .timeline-content {
+    display: flex;
+    flex-direction: column;
+  }
+  
+  .timeline-text {
+    margin-bottom: 5px;
+  }
+  
+  .timeline-time {
+    color: #999;
+  }

+ 24 - 0
src/components/Timeline.tsx

@@ -0,0 +1,24 @@
+import { View, Image, Text } from '@tarojs/components'
+import './Timeline.scss'
+
+// interface TimelineItem {
+//     status: 'padding' | 'done' | 'not_done';
+//     content: string;
+//     time: string;
+// }
+
+
+export default function Component(props: { items: any[] }) {
+    return <View className="timeline">
+        {props.items.map((item, index) => (
+            <View className="timeline-item" key={index}>
+                <View className={`timeline-icon ${item.status}`} />
+                {index !== props.items.length - 1 && <View className={(props.items[index + 1].status == 'done' && item.status == 'done') ? 'timeline-line' : 'timeline-line dash'} />}
+                <View className="timeline-content">
+                    <View className="timeline-text">{item.title}</View>
+                    <View className="timeline-time">{item.content}</View>
+                </View>
+            </View>
+        ))}
+    </View>
+}

+ 3 - 1
src/features/trackTimeDuration/components/Console.tsx

@@ -188,16 +188,18 @@ 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
+            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
             }
         }
             
-        global.limit = limit
+        
         return <LimitPickers ref={limitPickerRef} limit={limit} limitDay={8} onCancel={hidePicker} onChange={(e) => {
             console.log(new Date(e))
             pickerConfirm(e)

+ 4 - 1
src/features/trackTimeDuration/components/More.tsx

@@ -119,15 +119,18 @@ const Component = forwardRef((props, ref) => {
     function layoutContent() {
         var limit = global.set_time - 7 * 3600 * 1000 * 24;
         var current_record = machine.context.checkData ? (machine.context.checkData as any).current_record : null;
+        global.limit = limit
         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
             }
         }
 
-        global.limit = limit
+        
         return <LimitPickers ref={limitPickerRef} limit={limit} onCancel={() => { setIsOpen(false); setShowModal(false) }} onChange={(e) => {
             endFast(e)
             setIsOpen(false)

+ 103 - 53
src/features/trackTimeDuration/components/Schedule.tsx

@@ -8,6 +8,7 @@ import { delRecord } from "@/services/trackTimeDuration";
 import Modal from "@/components/Modal";
 import Rings, { BgRing, CurrentDot, RealRing, RingCommon } from './Rings';
 import { getBgRing, getCommon, getDot, getReal, getTarget } from "../hooks/RingData";
+import Timeline from "@/components/Timeline";
 
 
 export default function Component(props: { type?: string, data?: any, delSuccess?: Function }) {
@@ -214,50 +215,58 @@ export default function Component(props: { type?: string, data?: any, delSuccess
         }
 
         return '⭕️'
-        // if (props.type == 'latest') {
-        //     if (isFast) {
-        //         if ((checkData as any).latest_record.fast.status == 'COMPLETED') {
-        //             return '✅'
-        //         }
-        //     }
-        //     else {
-        //         if ((checkData as any).latest_record.sleep.status == 'COMPLETED') {
-        //             return '✅'
-        //         }
-        //         else if ((checkData as any).latest_record.sleep.status == 'NOT_STARTED') {
-        //             return '🚫'
-        //         }
-        //         else if ((checkData as any).latest_record.sleep.status == 'NOT_COMPLETED') {
-        //             return isStart ? '✅' : '🚫'
-        //         }
-        //     }
-        // }
-        // if (value == 'WAIT_FOR_START') {
-        //     return '⭕️'
-        // }
-        // else if (value == 'ONGOING1'||value == 'ONGOING') {
-        //     if (isFast && isStart) {
-        //         return '✅'
-        //     }
-        //     else if (!isFast && isStart) {
-        //         return '✅'
-        //     }
-        // }
-        // else if (value == 'ONGOING2') {
-        //     if (isStart) {
-        //         return '✅'
-        //     }
-        // }
-        // else if (value == 'ONGOING3') {
-        //     if (isFast && !isStart) {
-        //         return '⭕️'
-        //     }
-        //     else {
-        //         return '✅'
-        //     }
-        // }
+    }
+
+    function getStatus(isFast: boolean, isStart: boolean, data: any) {
+        if (props.type == 'latest' || props.type == 'record') {
+            if (isFast) {
+                if (data.fast.status == 'COMPLETED') {
+                    return 'done'
+                }
+            }
+            else {
+                if (data.sleep.status == 'COMPLETED') {
+                    return 'done'
+                }
+                else if (data.sleep.status == 'NOT_STARTED') {
+                    return 'un_done'
+                }
+                else if (data.sleep.status == 'NOT_COMPLETED') {
+                    return isStart ? 'done' : 'un_done'
+                }
+            }
+        }
+        if (value == 'WAIT_FOR_START') {
+            return 'padding'
+        }
+        else if (value == 'ONGOING') {
+            if (isFast && isStart) {
+                return 'done'
+            }
+            else if (!isFast && isStart) {
+                return 'done'
+            }
+        }
+        else if (value == 'ONGOING1') {
+            if (isFast && isStart) {
+                return 'done'
+            }
+        }
+        else if (value == 'ONGOING2') {
+            if (isStart) {
+                return 'done'
+            }
+        }
+        else if (value == 'ONGOING3') {
+            if (isFast && !isStart) {
+                return 'padding'
+            }
+            else {
+                return 'done'
+            }
+        }
 
-        // return '⭕️'
+        return 'padding'
     }
 
     function scheduleItems(data) {
@@ -268,16 +277,57 @@ export default function Component(props: { type?: string, data?: any, delSuccess
         if (props.type == 'record') {
             obj = data//(data as any).latest_record
         }
-        return <View>
-            {
-                obj && <View style={{ flexDirection: 'column', display: 'flex' }}>
-                    {obj.fast && <Text>{statusString(true, true, obj)}开始断食:{formateTime(obj.fast, false)}</Text>}
-                    {obj.sleep && <Text>{statusString(false, true, obj)}开始睡眠:{formateTime(obj.sleep, false)}</Text>}
-                    {obj.sleep && <Text>{statusString(false, false, obj)}结束睡眠:{formateTime(obj.sleep, true)}</Text>}
-                    {obj.fast && <Text>{statusString(true, false, obj)}结束断食:{formateTime(obj.fast, true)}</Text>}
-                </View>
-            }
-        </View>
+
+        var timelineItems:any = [];
+        if (obj.fast){
+            timelineItems.push(
+                {
+                    status: getStatus(true, true, obj),
+                    title: '开始断食',
+                    content: formateTime(obj.fast, false),
+                  }
+            )
+        }
+        if (obj.sleep){
+            timelineItems.push(
+                {
+                    status: getStatus(false, true, obj),
+                    title: '开始睡眠',
+                    content: formateTime(obj.sleep, false),
+                  }
+            )
+        }
+        if (obj.sleep){
+            timelineItems.push(
+                {
+                    status: getStatus(false, false, obj),
+                    title: '结束睡眠',
+                    content: formateTime(obj.sleep, true),
+                  }
+            )
+        }
+        if (obj.fast){
+            timelineItems.push(
+                {
+                    status: getStatus(true, false, obj),
+                    title: '结束断食',
+                    content: formateTime(obj.fast, true),
+                  }
+            )
+        }
+
+        return <Timeline items={timelineItems} />
+
+        // return <View>
+        //     {
+        //         obj && <View style={{ flexDirection: 'column', display: 'flex' }}>
+        //             {obj.fast && <Text>{statusString(true, true, obj)}开始断食:{formateTime(obj.fast, false)}</Text>}
+        //             {obj.sleep && <Text>{statusString(false, true, obj)}开始睡眠:{formateTime(obj.sleep, false)}</Text>}
+        //             {obj.sleep && <Text>{statusString(false, false, obj)}结束睡眠:{formateTime(obj.sleep, true)}</Text>}
+        //             {obj.fast && <Text>{statusString(true, false, obj)}结束断食:{formateTime(obj.fast, true)}</Text>}
+        //         </View>
+        //     }
+        // </View>
     }
 
     function formateTime(obj: any, isEnd: boolean) {

+ 0 - 2
src/pages/ChooseAuth.tsx

@@ -10,7 +10,6 @@ import { wxLogin } from "@/services/user";
 
 export default function Page() {
     const dispatch = useDispatch();
-    const counter = useSelector((state: any) => state.counter.value);
     var code = '';
 
     const user = useSelector((state: any) => state.user);
@@ -64,7 +63,6 @@ export default function Page() {
 
     return <View className="container choose_container">
         <Texts text='App name' type={TextType.big} />
-        <Texts text={counter} />
         <View style={{ height: 100 }} />
         <Buttons title='WeChat' onClick={login} style={{ width: 289, marginBottom: 30 }} />
         <Buttons title='Create account' type={ButtonType.outline} onClick={createAccount} style={{ width: 289, marginBottom: 30 }} />

+ 64 - 43
src/pages/demo.tsx

@@ -1,6 +1,7 @@
 import Taro from '@tarojs/taro';
 import { Canvas, View } from '@tarojs/components';
 import { useEffect, useRef } from 'react';
+import Timeline from '@/components/Timeline';
 
 export default function Demo() {
   const canvasRef = useRef<any>(null);
@@ -20,8 +21,8 @@ export default function Demo() {
 
   var currentContext;
 
-  var startAngle = 45*Math.PI/180;
-  var endAngle = 120*Math.PI/180;
+  var startAngle = 45 * Math.PI / 180;
+  var endAngle = 120 * Math.PI / 180;
   var lastAngle;
   var lastDuration = 0;
 
@@ -56,7 +57,7 @@ export default function Demo() {
 
 
     ctx.clearRect(0, 0, canvasWidth, canvasHeight);
-      
+
 
     ctx.beginPath();
     ctx.arc(centerX, centerY, radius, 0, 2 * Math.PI);
@@ -66,7 +67,7 @@ export default function Demo() {
 
     ctx.beginPath();
     ctx.arc(centerX, centerY, radius, startAngle, endAngle);
-    ctx.strokeStyle = canRingDrag?"red":"rgba(255,0,0,0.5)";
+    ctx.strokeStyle = canRingDrag ? "red" : "rgba(255,0,0,0.5)";
     ctx.lineWidth = 10;
     ctx.stroke();
 
@@ -95,87 +96,87 @@ export default function Demo() {
     return dep;
   }
 
-  function limitAngle(start,end) {
-    var angle1 = start<0?start+2*Math.PI:start;
-    var angle2 = end<0?end+2*Math.PI:end;
-    if (angle2<angle1){
-      angle2 = angle2+2*Math.PI;
+  function limitAngle(start, end) {
+    var angle1 = start < 0 ? start + 2 * Math.PI : start;
+    var angle2 = end < 0 ? end + 2 * Math.PI : end;
+    if (angle2 < angle1) {
+      angle2 = angle2 + 2 * Math.PI;
     }
 
-    var leftAngle = angle2-angle1;
-    if (leftAngle>Math.PI*23/12){
+    var leftAngle = angle2 - angle1;
+    if (leftAngle > Math.PI * 23 / 12) {
       return 1;
     }
-    else if (leftAngle<Math.PI/12){
+    else if (leftAngle < Math.PI / 12) {
       return 2;
     }
     return 0;
   }
 
-  function durationAngle(end,start) {
-    var angle1 = start<0?start+2*Math.PI:start;
-    var angle2 = end<0?end+2*Math.PI:end;
-    if (angle2<angle1){
-      angle2 = angle2+2*Math.PI;
+  function durationAngle(end, start) {
+    var angle1 = start < 0 ? start + 2 * Math.PI : start;
+    var angle2 = end < 0 ? end + 2 * Math.PI : end;
+    if (angle2 < angle1) {
+      angle2 = angle2 + 2 * Math.PI;
     }
 
-    return angle2-angle1;
+    return angle2 - angle1;
   }
 
   const handleTouchMove = (e: any) => {
     const ctx = currentContext;//canvasRef.current.getContext('2d');
-    if (!canStartDrag && !canEndDrag && !canRingDrag){
+    if (!canStartDrag && !canEndDrag && !canRingDrag) {
       drawCanvas(ctx);
       return;
     }
-    
+
     const { x, y } = e.touches[0];
 
-    let angle = Math.atan2(y-canvasWidth/2.0, x-canvasWidth/2.0)
+    let angle = Math.atan2(y - canvasWidth / 2.0, x - canvasWidth / 2.0)
 
-    if (canStartDrag){
-      if (Math.abs(durationAngle(endAngle,angle)-lastDuration)>Math.PI){
+    if (canStartDrag) {
+      if (Math.abs(durationAngle(endAngle, angle) - lastDuration) > Math.PI) {
         //禁止跨越
         return;
       }
 
-      var result = limitAngle(angle,endAngle);
-      switch (result){
+      var result = limitAngle(angle, endAngle);
+      switch (result) {
         case 0:
           startAngle = angle;
           break;
         case 1:
-          startAngle = endAngle-23*Math.PI/12;
+          startAngle = endAngle - 23 * Math.PI / 12;
           break;
         case 2:
-          startAngle = endAngle-Math.PI/12;
+          startAngle = endAngle - Math.PI / 12;
           break;
       }
-      
+
     }
 
-    if (canEndDrag){
-      if (Math.abs(durationAngle(angle,startAngle)-lastDuration)>Math.PI){
+    if (canEndDrag) {
+      if (Math.abs(durationAngle(angle, startAngle) - lastDuration) > Math.PI) {
         //禁止跨越
         return;
       }
 
-      var result = limitAngle(startAngle,angle);
-      switch (result){
+      var result = limitAngle(startAngle, angle);
+      switch (result) {
         case 0:
           endAngle = angle;
           break;
         case 1:
-          endAngle = startAngle+23*Math.PI/12;
+          endAngle = startAngle + 23 * Math.PI / 12;
           break;
         case 2:
-          endAngle = startAngle+Math.PI/12;
+          endAngle = startAngle + Math.PI / 12;
           break;
       }
-      
+
     }
 
-    if (canRingDrag){
+    if (canRingDrag) {
       let delta = angle - lastAngle;
       startAngle += delta;
       endAngle += delta;
@@ -184,7 +185,7 @@ export default function Demo() {
 
     drawCanvas(ctx);
 
-    lastDuration = durationAngle(endAngle,startAngle);
+    lastDuration = durationAngle(endAngle, startAngle);
   };
 
   const handleClick = (e) => {
@@ -220,14 +221,14 @@ export default function Demo() {
       canEndDrag = false;
     }
 
-    if (canStartDrag || canEndDrag){
+    if (canStartDrag || canEndDrag) {
       canRingDrag = false;
       return;
     }
 
-    const distance3 = twoPointDistance({x:canvasX,y:canvasY},{x:centerX,y:centerY});
-    let angle = Math.atan2(canvasY-canvasWidth/2.0, canvasX-canvasWidth/2.0)
-    if (distance3>80&& distance3<105 && startAngle<angle && angle<endAngle){
+    const distance3 = twoPointDistance({ x: canvasX, y: canvasY }, { x: centerX, y: centerY });
+    let angle = Math.atan2(canvasY - canvasWidth / 2.0, canvasX - canvasWidth / 2.0)
+    if (distance3 > 80 && distance3 < 105 && startAngle < angle && angle < endAngle) {
       canRingDrag = true;
     }
     lastAngle = angle;
@@ -235,19 +236,39 @@ export default function Demo() {
     drawCanvas(currentContext);
   };
 
-  const handleTouchEnd = (e) =>{
+  const handleTouchEnd = (e) => {
     canStartDrag = false;
     canEndDrag = false;
     canRingDrag = false;
     handleTouchMove(e)
   }
 
-  return <View style={{ width: '100%', height: 600, backgroundColor: 'white' }}>
+  const timelineItems = [
+    {
+      status: 'padding',
+      content: 'Item 1',
+      time: '10:00 AM',
+    },
+    {
+      status: 'done',
+      content: 'Item 2',
+      time: '11:00 AM',
+    },
+    {
+      status: 'un_done',
+      content: 'Item 3',
+      time: '12:00 PM',
+    },
+  ];
+
+  return <View style={{ width: '100%', height: 600, backgroundColor: 'white',display:'flex',flexDirection:'column' }}>
     <Canvas canvasId={canvasId} id={canvasId} className={canvasId} type="2d"
       style={{ width: 300, height: 300, zIndex: 0, backgroundColor: 'yellow' }}
       onTouchMove={handleTouchMove}
       onTouchEnd={handleTouchEnd}
       onTouchStart={handleClick}
       ref={canvasRef} />
+    <Timeline items={timelineItems} />
+
   </View>
 }

+ 0 - 40
src/store/demo.tsx

@@ -1,40 +0,0 @@
-import { createAsyncThunk, createSlice, PayloadAction } from '@reduxjs/toolkit';
-
-interface CounterState {
-    value: number;
-}
-
-const initialState: CounterState = {
-    value: 0,
-};
-
-const counterSlice = createSlice({
-    name: 'counter',
-    initialState,
-    reducers: {
-        increment: (state) => {
-            state.value += 1;
-        },
-        decrement: (state) => {
-            state.value -= 1;
-        },
-        incrementByAmount: (state, action: PayloadAction<number>) => {
-            state.value += action.payload;
-        },
-    },
-});
-
-export const { increment, decrement, incrementByAmount } = counterSlice.actions;
-
-export const apple = createAsyncThunk('user/wxLogin', async (payload: { code: string }, { dispatch }) => {
-    dispatch(increment());
-    // console.log(payload.code)
-    // request({
-    //     url: API_LOGIN, method: 'POST', data: { 'code':payload.code,type:'WX_MP',app_version:'1',client_version:'1',client_type:'WXP_MP' }
-    // }).then(res => {
-    //     console.log(res);
-    //     dispatch(loginSuccess(res));
-    // })
-});
-
-export default counterSlice.reducer;

+ 0 - 2
src/store/store.tsx

@@ -1,7 +1,6 @@
 import { configureStore } from '@reduxjs/toolkit';
 import userReducer from './user';
 import scenarioReducer from './scenario';
-import counterReducer from './demo';
 import permissionReducer from './permission';
 import commonReducer from './common';
 import resultReducer from './action_results';
@@ -10,7 +9,6 @@ const store = configureStore({
   reducer: {
     // 添加你的 reducer
     user: userReducer,
-    counter: counterReducer,
     scenario: scenarioReducer,
     permission: permissionReducer,
     common: commonReducer,