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

+ 208 - 0
src/features/trackSomething/components/Activity.tsx

@@ -0,0 +1,208 @@
+import { View, Text } from "@tarojs/components";
+import './Metric.scss'
+import { setAuth } from "../hooks/werun";
+import { useReady } from "@tarojs/taro";
+import { useDispatch, useSelector } from "react-redux";
+import { useEffect, useState } from "react";
+import Taro from "@tarojs/taro";
+import { activityCards, uploadSteps } from "@/services/trackSomething";
+import { TimeFormatter } from "@/utils/time_format";
+import MetricItem from "./MetricItem";
+import { checkFail, checkStart, checkSuccess, setResult } from "@/store/action_results";
+
+export default function Component(props: any) {
+    const user = useSelector((state: any) => state.user);
+    const checkResult = useSelector((state: any) => state.checkResult);
+    const [allowRun, setAllowRun] = useState(false)
+    const [stepInfo, setStepInfo] = useState(null)
+    const [lastTime, setLastTime] = useState(new Date().getTime())
+    const [isCheking, setIsChecking] = useState(false)
+    const [strBtnTitle, setStrBtnTitle] = useState('')
+    const [list, setList] = useState([])
+    const dispatch = useDispatch();
+    // const [title, setTitle] = useState('打卡')
+
+    //未登录<->已登录 状态切换时,执行一次授权检查
+    useEffect(() => {
+        checkAuth()
+    }, [user.isLogin])
+
+    useEffect(() => {
+        debugger
+        console.log('checkResult.type:' + checkResult.type)
+    }, [
+        checkResult.type
+    ])
+
+    //页面渲染完成后执行一次授权检查
+    useReady(() => {
+        getCards();
+    })
+
+    function getCards() {
+        activityCards().then(res => {
+            setList((res as any).cards)
+        })
+    }
+
+    function checkAuth() {
+        // Taro.checkSession
+        if (user.isLogin) {
+            // setAuth()
+            Taro.getSetting({
+                success: res => {
+                    //第一步,检测是否有授权 - 没有授权
+                    if (!res.authSetting['scope.werun']) {
+                        // setTitle('开启')
+                        setAllowRun(false)
+                    }
+                    else {
+                        setAllowRun(true)
+                        // setTitle('打卡')
+                        //自动打卡流程
+
+                        var time = Taro.getStorageSync('lastUploadStepsTime')
+                        if (time) {
+                            var now = new Date().getTime()
+                            if (now - time >= 48 * 24 * 3600 * 1000) {
+                                getWeRunData(true)
+                            }
+                        }
+                        else {
+                            getWeRunData(true)
+                        }
+                    }
+                }
+            })
+        }
+        else {
+            // Taro.setStorageSync('lastUploadStepsTime', time)
+            setAllowRun(false)
+            // setTitle('开启');
+        }
+    }
+
+    function checkout() {
+        // console.log('开始获取步数的时间戳:' + new Date().getTime())
+        if (allowRun) {
+            setIsChecking(true)
+            dispatch(checkStart());
+        }
+        if (user.isLogin) {
+            setAuth(getWeRunData, refuseAuth)
+        }
+        else {
+            Taro.navigateTo({
+                url: '/pages/ChooseAuth'
+            })
+        }
+    }
+
+    function getWeRunData(autoCheck = false) {
+        // setTitle('打卡');
+        setAllowRun(true)
+        var date = new Date();
+        var time = date.getTime()
+        var strDate = (date.getFullYear() + '') + (date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : (date.getMonth() + 1)) + (date.getDate() < 10 ? '0' + date.getDate() : date.getDate());
+        Taro.getWeRunData({
+            success: res => {
+                // console.log('已获取步数的时间戳:' + new Date().getTime())
+                uploadSteps({
+                    is_manual: autoCheck ? 0 : 1,
+                    timestamp: time,
+                    encryptedData: res.encryptedData,
+                    iv: res.iv,
+                    date: strDate,
+                    cloudID: res.cloudID,
+                }).then(res => {
+                    console.log(res)
+                    Taro.setStorageSync('lastUploadStepsTime', time)
+                    if ((res as any).length > 0) {
+                        // dispatch(checkSuccess());
+                        dispatch(setResult({ isSuccess: true }) as any)
+                        setStepInfo((res as any)[(res as any).length - 1])
+                        setLastTime(time)
+                        console.log('接口返回的时间戳:' + new Date().getTime())
+                        setIsChecking(false)
+                    }
+                    else {
+                        dispatch(checkFail());
+                    }
+                    getCards();
+                }).catch(e => {
+                    dispatch(checkFail());
+                });
+            }
+        })
+    }
+
+    function refuseAuth() {
+        // setTitle('开启');
+        setIsChecking(false)
+        setAllowRun(false)
+    }
+
+    function goDetail() {
+        if (user.isLogin) {
+            Taro.navigateTo({
+                url: '/pages/RecordsHistory?type=activity'
+            })
+        }
+        else {
+            Taro.navigateTo({
+                url: '/pages/ChooseAuth'
+            })
+        }
+
+    }
+
+    // checkResult.type == 'ing' && setStrBtnTitle('打卡中...')
+
+    return <View>
+        {
+            list.map((item, index) => {
+                var value = '0'
+                var desc = ''
+                if ((item as any).latest_record) {
+                    value = (item as any).latest_record.items[0].value
+                    desc = TimeFormatter.formatTimestamp((item as any).latest_record.timestamp)
+                }
+
+                if (!allowRun) {
+                    value = '未开启'
+                    desc = '开启步数仅自己可见'
+                }
+
+                return <MetricItem title={(item as any).name}
+                    // value={allowRun ? stepInfo ? (stepInfo as any).step : '' : '未开启'}
+                    value={value}
+                    unit={(allowRun && stepInfo) ? '步' : ''}
+                    desc={desc}
+                    // desc={allowRun ? stepInfo ? TimeFormatter.formatTimestamp(lastTime) : '' : '开启步数仅自己可见'}
+                    btnText={allowRun ? isCheking ? '打卡中...' : '打卡' : '开启'}
+                    isDisabled={isCheking}
+                    themeColor='#EEC01F'
+                    onClickDetail={goDetail}
+                    onClick={checkout}
+                />
+            })
+        }
+    </View>
+
+    return <View className="metric_bg">
+        <Text className="metric_title">行走</Text>
+        {
+            !allowRun && <Text className="metric_value">未开启</Text>
+        }
+        {
+            !allowRun && <Text className="mteric_desc">开启步数仅自己可见</Text>
+        }
+        {
+            allowRun && stepInfo && <Text className="metric_value">{(stepInfo as any).step}<Text className="metric_unit">步</Text></Text>
+        }
+        {
+            allowRun && stepInfo && <Text className="mteric_desc">{TimeFormatter.formatTimestamp(lastTime)}</Text>
+        }
+        <View className="operate" onClick={checkout}>{allowRun ? '打卡' : '开启'}</View>
+    </View>
+}

+ 54 - 16
src/features/trackSomething/components/ActivityHistory.tsx

@@ -2,29 +2,67 @@ import { View, Text } from "@tarojs/components";
 import './MetricHistory.scss'
 
 export default function Component(props: { records: any[] }) {
-    return <View  style={{display:'flex',flexDirection:'column'}}>
+    function formateDate(date: string) {
+        debugger
+        //yyyyMMdd转换成日期,如果是今天,返回今天,如果是昨天,返回昨天,如果是昨天之前,返回日期
+        const dt = new Date(date.substring(0,4) + '/' + 
+        date.substring(4,6) + '/' +
+        date.substring(6));
+
+        const now = new Date();
+
+        const diff = now.getTime() - dt.getTime();
+        const day = 1000 * 60 * 60 * 24;
+
+        if (diff < day) {
+            return '今天';
+        } else if (diff < 2 * day) {
+            return '昨天';
+        } else {
+            return dt.toISOString().slice(0, 10);
+        }
+    }
+    function formateHourMinutes(timestamp: number) {
+        var date = new Date(timestamp)
+        var hour = date.getHours()
+        var minutes = date.getMinutes()
+        return `${hour < 10 ? '0' + hour : hour}:${minutes < 10 ? '0' + minutes : minutes}`
+    }
+    return <View style={{ display: 'flex', flexDirection: 'column' }}>
         <View className="operate_view">
             <Text>时间倒序</Text>
             <Text style={{ marginLeft: 5, marginRight: 5 }}> | </Text>
             <Text>时间正序</Text>
         </View>
-        <Text className="operate_day">今天</Text>
-        <View className="operate_item">
-            <View className="status_bg">
-                <Text className="status_text">总计</Text>
-            </View>
-            <Text className="value">8888</Text>
-            <Text className="unit">步</Text>
-            <View style={{flex:1}}/>
-            <Text className="time">刚刚</Text>
-        </View>
-        <View className="operate_item">
+        {
+            (props.records as any).map(item => {
+                return <View style={{ display: 'flex', flexDirection: 'column' }}>
+                    <Text className="operate_day">{formateDate(item.date+'')}</Text>
+                    {
+                        item.records.map(record => {
+                            return <View className="operate_item">
+                                <View className="status_bg">
+                                    <Text className="status_text">{record.type == 'total' ? '总计' : record.type == 'sync' ? '同步' : '打卡'}</Text>
+                                </View>
+                                <Text className="value">{record.items[0].value}</Text>
+                                <Text className="unit">步</Text>
+                                <View style={{ flex: 1 }} />
+                                <Text className="time">{formateHourMinutes(record.timestamp)}</Text>
+                            </View>
+                        })
+                    }
+                </View>
+            })
+        }
+
+
+        {/* <View className="operate_item">
             <View className="status_bg">
                 <Text className="status_text">总计</Text>
             </View>
             <Text className="value">8888</Text>
             <Text className="unit">步</Text>
-            <View style={{flex:1}}/>
+            <View style={{ flex: 1 }} />
             <Text className="time">刚刚</Text>
         </View>
         <View className="operate_item">
@@ -33,7 +71,7 @@ export default function Component(props: { records: any[] }) {
             </View>
             <Text className="value">8888</Text>
             <Text className="unit">步</Text>
-            <View style={{flex:1}}/>
+            <View style={{ flex: 1 }} />
             <Text className="time">刚刚</Text>
         </View>
         <View className="operate_item">
@@ -42,8 +80,8 @@ export default function Component(props: { records: any[] }) {
             </View>
             <Text className="value">8888</Text>
             <Text className="unit">步</Text>
-            <View style={{flex:1}}/>
+            <View style={{ flex: 1 }} />
             <Text className="time">刚刚</Text>
-        </View>
+        </View> */}
     </View>
 }

+ 6 - 6
src/pages/Activity.tsx

@@ -1,18 +1,18 @@
 import { View,Text } from "@tarojs/components";
-import Metric from '@/features/trackSomething/components/Metric'
+import Activity from '@/features/trackSomething/components/Activity'
 import { useReady } from "@tarojs/taro";
 import { activityCards } from "@/services/trackSomething";
 
 export default function Page(){
-    useReady(()=>{
-        activityCards().then(res=>{
+    // useReady(()=>{
+    //     activityCards().then(res=>{
             
-        })
-    })
+    //     })
+    // })
     return (
         <View className="container activity">
             <Text>Activity Page</Text>
-            <Metric />
+            <Activity />
         </View>
     )
 }

+ 12 - 7
src/pages/RecordsHistory.tsx

@@ -54,18 +54,19 @@ export default function Page() {
 
     function refresh() {
         setPageIndex(1)
-        getHistory()
+        getHistory(1)
     }
 
     function more() {
-        setPageIndex(pageIndex + 1)
-        getHistory()
+        var page = pageIndex + 1
+        setPageIndex(page)
+        getHistory(page)
     }
 
-    function getHistory() {
+    function getHistory(page = pageIndex) {
         if (router.params.type == 'time') {
             getClockRecords({
-                page: pageIndex,
+                page: page,
                 limit: pageSize,
                 only_finished: false
             }).then(res => {
@@ -79,12 +80,16 @@ export default function Page() {
         else if (router.params.type == 'activity') {
             activityRecords(
                 {
-                    page: pageIndex,
+                    page: page,
                     limit: pageSize,
                     code:'_walk'
                 }
             ).then(res => {
-
+                if (pageIndex == 1) {
+                    setRecords((res as any).data)
+                } else {
+                    setRecords(records.concat((res as any).data))
+                }
             })
         }
 

+ 3 - 1
src/services/trackSomething.tsx

@@ -2,12 +2,14 @@ import { API_ACTIVITY_CARDS, API_ACTIVITY_RECORDS, API_UPLOAD_STEPS } from './ht
 import { request } from './http/request';
 
 export const uploadSteps = (params) => {
-    return new Promise((resolve) => {
+    return new Promise((resolve,reject) => {
         request({
             url: API_UPLOAD_STEPS, method: 'POST', data: { ...params }
         }).then(res => {
             resolve(res);
             // dispatch(loginSuccess(res));
+        }).catch(err => {
+            reject(err)
         })
     })
 }

+ 61 - 10
src/store/action_results.tsx

@@ -1,4 +1,5 @@
-import { createSlice } from "@reduxjs/toolkit";
+import { createAsyncThunk, createSlice } from "@reduxjs/toolkit";
+import { useDispatch } from "react-redux";
 
 export enum ResultType {
     idle = 'idle',
@@ -16,29 +17,64 @@ interface ResultState {
 
 const initialState: ResultState = {
     title: null,
-    type: null,
+    type: ResultType.idle,
     seconds: 0
 }
 
+const resultTime = 2;
+const countdownTime = 20;
+
 const resultSlice = createSlice({
-    name: 'user',
+    name: 'result',
     initialState,
     reducers: {
         checkStart(state) {
-            state.title = 'Success';
             state.type = ResultType.ing;
         },
         checkSuccess(state) {
-            state.title = 'Success';
-            state.type = ResultType.success;
+            debugger
+            console.log('9527')
+            // state.type = ResultType.success;
+            // var count = resultTime;
+            // var timer = setInterval(()=>{
+            //     count--;
+            //     if (count <= 0) {
+            //         clearInterval(timer);
+            //         state.type = ResultType.countdown;
+            //         var count2 = countdownTime;
+            //         var timer2 = setInterval(()=>{
+            //             count2--;
+            //             if (count2 <= 0) {
+            //                 clearInterval(timer2);
+            //                 state.type = ResultType.idle;
+            //             }
+            //         },1000)
+            //     }
+            // },1000)
         },
         checkFail(state) {
-            state.title = 'Fail';
             state.type = ResultType.fail;
+            var count = resultTime;
+            var timer = setInterval(()=>{
+                count--;
+                if (count <= 0) {
+                    clearInterval(timer);
+                    state.type = ResultType.idle;
+                }
+            },1000)
         },
-        checkCountdown(state, action) {
+        checkCountdown(state) {
+            debugger
             state.type = ResultType.countdown;
-            state.seconds = action.payload;
+            var count = 20;
+            var timer = setInterval(()=>{
+                count--;
+                if (count <= 0) {
+                    clearInterval(timer);
+                    state.type = ResultType.idle;
+                }
+            },1000)
+            // state.seconds = action.payload;
         },
         checkCountdownEnd(state) {
             state.type = ResultType.idle;
@@ -53,4 +89,19 @@ const resultSlice = createSlice({
 );
 
 export const { checkStart, checkSuccess, checkFail, checkCountdownEnd, checkCountdown, resetStatus } = resultSlice.actions;
-export default resultSlice.reducer;
+export default resultSlice.reducer;
+
+export const setResult = createAsyncThunk('result/action', async (payload: {isSuccess:boolean}, { dispatch }) => {
+    debugger
+    if (payload.isSuccess) {
+        console.log('aaaa')
+        dispatch(checkSuccess());
+        console.log('successdddd')
+        setTimeout(() => {
+            dispatch(checkCountdown());
+            console.log('zzzzz')
+            debugger
+        }, 2000);
+    }
+
+});