|
|
@@ -1,4 +1,4 @@
|
|
|
-import { View, Text } from "@tarojs/components";
|
|
|
+import { View, Text, Image } from "@tarojs/components";
|
|
|
import './move.scss'
|
|
|
import { useDispatch, useSelector } from "react-redux";
|
|
|
import { getScenario, getThemeColor } from "@/features/health/hooks/health_hooks";
|
|
|
@@ -8,16 +8,28 @@ import { checkStart, setResult } from "@/store/action_results";
|
|
|
import RequestType, { thirdPartRequest } from "@/services/thirdPartRequest";
|
|
|
import { setAuth } from "@/features/trackSomething/hooks/werun";
|
|
|
import { useTranslation } from "react-i18next";
|
|
|
-import { uploadActiveMoves } from "@/services/health";
|
|
|
+import { getActiveMoves, getActiveMovesCurrent, uploadActiveMoves } from "@/services/health";
|
|
|
import dayjs from "dayjs";
|
|
|
+import { TimeFormatter } from "@/utils/time_format";
|
|
|
|
|
|
+let timer
|
|
|
export default function Move() {
|
|
|
const health = useSelector((state: any) => state.health);
|
|
|
const [allowRun, setAllowRun] = useState(false)
|
|
|
+ const [loaded, setLoaded] = useState(false)
|
|
|
+ const [count, setCount] = useState(0)
|
|
|
+ const [data, setData] = useState<any>(null)
|
|
|
+ const [list, setList] = useState<any>([])
|
|
|
+ const [total, setTotal] = useState(0)
|
|
|
+ const [index, setIndex] = useState(1)
|
|
|
+ const [hideCurrentRecent, setHideCurrentRecent] = useState(false)
|
|
|
+ const [moreActive, setMoreActive] = useState(false)
|
|
|
const { t } = useTranslation()
|
|
|
const dispatch = useDispatch()
|
|
|
|
|
|
useEffect(() => {
|
|
|
+ getMovesCurrent()
|
|
|
+ getMovesHistory()
|
|
|
Taro.getSetting({
|
|
|
success: res => {
|
|
|
//第一步,检测是否有授权 - 没有授权
|
|
|
@@ -31,10 +43,39 @@ export default function Move() {
|
|
|
}
|
|
|
}
|
|
|
})
|
|
|
+ timer = setInterval(() => {
|
|
|
+ setCount((index) => index + 1)
|
|
|
+ }, 1000)
|
|
|
+
|
|
|
+ return () => {
|
|
|
+ clearInterval(timer)
|
|
|
+ }
|
|
|
}, [])
|
|
|
|
|
|
+ function getMovesCurrent() {
|
|
|
+ getActiveMovesCurrent().then(res => {
|
|
|
+ setLoaded(true)
|
|
|
+ setData(res)
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+ function getMovesHistory() {
|
|
|
+ getActiveMoves().then(res => {
|
|
|
+ if (index == 1) {
|
|
|
+ setList((res as any).data)
|
|
|
+ setTotal((res as any).total)
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ setList([...list, ...(res as any).data])
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
|
|
|
function tapLog() {
|
|
|
+ // if (getStatus() != 'open') {
|
|
|
+ // return
|
|
|
+ // }
|
|
|
if (allowRun) {
|
|
|
checkout()
|
|
|
}
|
|
|
@@ -70,64 +111,275 @@ export default function Move() {
|
|
|
|
|
|
// 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());
|
|
|
|
|
|
+ let schedule_id = null
|
|
|
+ const hour = currentHourPeriod()
|
|
|
+ data.hours.map(item => {
|
|
|
+ if (item.hour == hour) {
|
|
|
+ schedule_id = item.schedule_id
|
|
|
+ }
|
|
|
+ })
|
|
|
|
|
|
thirdPartRequest(RequestType.RequestTypeWXRunData).then(res => {
|
|
|
- var params = {
|
|
|
- is_manual: autoCheck ? 0 : 1,
|
|
|
- timestamp: time,
|
|
|
- encryptedData: (res as any).encryptedData,
|
|
|
- iv: (res as any).iv,
|
|
|
- date: strDate,
|
|
|
- cloudID: (res as any).cloudID,
|
|
|
- }
|
|
|
+ // var params = {
|
|
|
+ // is_manual: autoCheck ? 0 : 1,
|
|
|
+ // timestamp: time,
|
|
|
+ // encryptedData: (res as any).encryptedData,
|
|
|
+ // iv: (res as any).iv,
|
|
|
+ // date: strDate,
|
|
|
+ // cloudID: (res as any).cloudID,
|
|
|
+ // }
|
|
|
|
|
|
uploadActiveMoves({
|
|
|
- wechat_run:{
|
|
|
- encryptedData:(res as any).encryptedData,
|
|
|
- iv:(res as any).iv,
|
|
|
+ wechat_run: {
|
|
|
+ encryptedData: (res as any).encryptedData,
|
|
|
+ iv: (res as any).iv,
|
|
|
},
|
|
|
- date:dayjs().format('YYYYMMDD'),
|
|
|
- timestamp:new Date().getTime(),
|
|
|
- schedule_id:getScenario(health.windows,health.mode).window_id
|
|
|
- }).then(res=>{
|
|
|
+ date: dayjs().format('YYYYMMDD'),
|
|
|
+ hour: hour,
|
|
|
+ timestamp: new Date().getTime(),
|
|
|
+ schedule_id: schedule_id
|
|
|
+ }).then(res => {
|
|
|
Taro.showToast({
|
|
|
- title:'上报成功',
|
|
|
- icon:'none'
|
|
|
+ title: '上报成功',
|
|
|
+ icon: 'none'
|
|
|
})
|
|
|
})
|
|
|
- // uploadSteps(params).then(res => {
|
|
|
- // if ((res as any).error_code == 'WX_STEP_PARSE_FAIL') {
|
|
|
- // retry(params, autoCheck, time)
|
|
|
- // dispatch(checkRetry())
|
|
|
- // }
|
|
|
- // else {
|
|
|
-
|
|
|
- // setShowErrorBadge(false)
|
|
|
- // uploadSuccess(res, autoCheck, time)
|
|
|
- // setTimeout(() => {
|
|
|
- // setCount(count + 1)
|
|
|
- // }, 31000)
|
|
|
- // }
|
|
|
-
|
|
|
- // }).catch(e => {
|
|
|
- // retry(params, autoCheck, time)
|
|
|
- // });
|
|
|
}).catch(_ => {
|
|
|
dispatch(setResult({ isSuccess: false }) as any)
|
|
|
})
|
|
|
+ }
|
|
|
|
|
|
+ function getStatus() {
|
|
|
+ const minute = new Date().getMinutes()
|
|
|
+ if (minute >= 50 || minute < 10) {
|
|
|
+ return 'open'
|
|
|
+ }
|
|
|
+ return 'upcoming'
|
|
|
+ }
|
|
|
|
|
|
+ function currentFootDesc() {
|
|
|
+ const minute = new Date().getMinutes()
|
|
|
+ const pre = new Date().getTime()
|
|
|
+ const next = new Date().getTime() + 3600 * 1000
|
|
|
+ if (minute >= 50) {
|
|
|
+ return `Now open ${dayjs(pre).format('HH:50')}-${dayjs(next).format('HH:10')}`
|
|
|
+ }
|
|
|
+ else if (minute < 10) {
|
|
|
+ let time = new Date()
|
|
|
+ time.setMinutes(10)
|
|
|
+ time.setSeconds(0)
|
|
|
+ time.setMilliseconds(0)
|
|
|
+
|
|
|
+ // 获取总秒数
|
|
|
+ const totalSeconds = Math.floor((time.getTime() - new Date().getTime()) / 1000);
|
|
|
+
|
|
|
+ // 计算小时、分钟和秒
|
|
|
+ // const hours = String(Math.floor(totalSeconds / 3600)).padStart(2, '0');
|
|
|
+ const minutes = String(Math.floor((totalSeconds % 3600) / 60)).padStart(2, '0');
|
|
|
+ const seconds = String(totalSeconds % 60).padStart(2, '0');
|
|
|
+
|
|
|
+ // return `${hours}:${minutes}:${seconds}`;
|
|
|
+ return `Closing in ${minutes}:${seconds}`
|
|
|
+ }
|
|
|
+
|
|
|
+ let time = new Date()
|
|
|
+ time.setMinutes(50)
|
|
|
+ time.setSeconds(0)
|
|
|
+ time.setMilliseconds(0)
|
|
|
+
|
|
|
+ // 获取总秒数
|
|
|
+ const totalSeconds = Math.floor((time.getTime() - new Date().getTime()) / 1000);
|
|
|
+
|
|
|
+ // 计算小时、分钟和秒
|
|
|
+ // const hours = String(Math.floor(totalSeconds / 3600)).padStart(2, '0');
|
|
|
+ const minutes = String(Math.floor((totalSeconds % 3600) / 60)).padStart(2, '0');
|
|
|
+ const seconds = String(totalSeconds % 60).padStart(2, '0');
|
|
|
+
|
|
|
+ // return `${hours}:${minutes}:${seconds}`;
|
|
|
+ return `Opening soon ${minutes}:${seconds}`
|
|
|
}
|
|
|
|
|
|
+ function getDuration() {
|
|
|
+ const pre = new Date().getTime()
|
|
|
+ const next = new Date().getTime() + 3600 * 1000
|
|
|
+ return dayjs(pre).format('H:00') + '-' + dayjs(next).format('H:00')
|
|
|
+ }
|
|
|
+
|
|
|
+ function process() {
|
|
|
+ let count = 0;
|
|
|
+ data.hours.map(item => {
|
|
|
+ // if (item.)
|
|
|
+ })
|
|
|
+ return `${count} / ${data.hours.length}`
|
|
|
+ }
|
|
|
+
|
|
|
+ function currentHourPeriod() {
|
|
|
+ const time = new Date()
|
|
|
+ let hour = time.getHours()
|
|
|
+ //假如00:09,则为23小时
|
|
|
+ if (time.getMinutes() < 10) {
|
|
|
+ hour--;
|
|
|
+ }
|
|
|
+ if (hour < 0) {
|
|
|
+ hour = 23
|
|
|
+ }
|
|
|
+ return hour
|
|
|
+ }
|
|
|
|
|
|
- return <View>
|
|
|
- <Text>Move Every Hour</Text>
|
|
|
- <View className="log_btn" style={{ backgroundColor: getThemeColor(health.mode) }} onClick={tapLog}>
|
|
|
- Log
|
|
|
+ function currentContent() {
|
|
|
+ const hour = currentHourPeriod()
|
|
|
+ let info: any = null
|
|
|
+ data.hours.map(item => {
|
|
|
+ if (item.hour == hour) {
|
|
|
+ info = item
|
|
|
+ }
|
|
|
+ })
|
|
|
+
|
|
|
+ return <View className="move-header">
|
|
|
+ <View className="header-current">
|
|
|
+ <View className="current_intro">
|
|
|
+ <View style={{ color: new Date().getMinutes() < 10 ? getThemeColor(health.mode) : '#b2b2b2' }}>{getDuration()}</View>
|
|
|
+ <Text>0/200 steps</Text>
|
|
|
+ </View>
|
|
|
+ <View className="log_btn" style={{
|
|
|
+ backgroundColor: getStatus() == 'open' ? getThemeColor(health.mode) : '#6666661A',
|
|
|
+ color: getStatus() == 'open' ? '#fff' : '#666666'
|
|
|
+ }} onClick={tapLog}>Log</View>
|
|
|
+ <View className="border_footer_line" />
|
|
|
+ </View>
|
|
|
+ <View className="current_footer">
|
|
|
+ <Text>{currentFootDesc()}</Text>
|
|
|
+ <Text>Show More</Text>
|
|
|
+ </View>
|
|
|
+
|
|
|
+ </View>
|
|
|
+ }
|
|
|
+
|
|
|
+ function currentHistory(item) {
|
|
|
+ var start = item.hour
|
|
|
+ var end = start + 1
|
|
|
+ start = (start + '').padStart(2, '0')
|
|
|
+ end = (end + '').padStart(2, '0')
|
|
|
+ return <View className="current_history_item">
|
|
|
+ <View style={{ display: 'flex', flexDirection: 'column' }}>
|
|
|
+ <Text className="current_item_period">{start}:00-{end}:00</Text>
|
|
|
+ <Text>{item.real_steps}/{item.target_steps}</Text>
|
|
|
+ </View>
|
|
|
+
|
|
|
+ {
|
|
|
+ item.status == 'MISSED' && <Text className="missed">Missed</Text>
|
|
|
+ }
|
|
|
+ {
|
|
|
+ item.status == 'CHECKED' && item.real_steps == 0 && <Image className="history_item_detail_icon" src={require('@assets/_health/sit.png')} />
|
|
|
+ }
|
|
|
+ {
|
|
|
+ item.status == 'CHECKED' && item.real_steps > 0 && <Image className="history_item_detail_icon" src={require('@assets/_health/walk.png')} />
|
|
|
+ }
|
|
|
+ <View className="border_footer_line" />
|
|
|
+ </View>
|
|
|
+ }
|
|
|
+
|
|
|
+ function activeCount() {
|
|
|
+ var count = 0;
|
|
|
+ data.hours.map(item => {
|
|
|
+ if (item.status != 'NOT_CHECK') {
|
|
|
+ count++
|
|
|
+ }
|
|
|
+ })
|
|
|
+ return count
|
|
|
+ }
|
|
|
+
|
|
|
+ function activeHour() {
|
|
|
+
|
|
|
+
|
|
|
+ return <View className="summary">
|
|
|
+ <View className="summary_header">
|
|
|
+ <Text>Active Hours</Text>
|
|
|
+ <Image className="arrow_hide"
|
|
|
+ onClick={() => {
|
|
|
+ setHideCurrentRecent(!hideCurrentRecent)
|
|
|
+ }}
|
|
|
+ src={hideCurrentRecent ? require('@assets/_health/arrow_down.png') : require('@assets/_health/arrow_up.png')} />
|
|
|
+ <View style={{ flex: 1 }} />
|
|
|
+ <Text style={{ color: getThemeColor(health.mode) }}>{process()}</Text>
|
|
|
+ <View className="border_footer_line" />
|
|
|
+ </View>
|
|
|
+ {
|
|
|
+ !hideCurrentRecent && <View className="summary_content">
|
|
|
+ {
|
|
|
+ data.hours.map((item, index) => {
|
|
|
+ if (item.status == 'NOT_CHECK') return <View key={index} />
|
|
|
+ if (index >= 3 && !moreActive) return <View key={index} />
|
|
|
+ return <View key={index}>
|
|
|
+ {
|
|
|
+ currentHistory(item)
|
|
|
+ }
|
|
|
+ </View>
|
|
|
+ })
|
|
|
+ }
|
|
|
+ {
|
|
|
+ activeCount() > 3 && <View className="recent_btn_bg">
|
|
|
+ {
|
|
|
+ moreActive ? <View className="recent_btn" onClick={() => setMoreActive(false)}>收起</View> : <View className="recent_btn" onClick={() => setMoreActive(true)}>展开剩余{activeCount() - 3}条</View>
|
|
|
+ }
|
|
|
+ <View className="border_footer_line" />
|
|
|
+ </View>
|
|
|
+ }
|
|
|
+ </View>
|
|
|
+ }
|
|
|
+
|
|
|
+ <View className="summary_footer">
|
|
|
+ <View className="summary_footer_item">
|
|
|
+ <Text className="light_desc">Steps</Text>
|
|
|
+ <Text>{data.stat.real_steps}/{data.stat.target_steps}</Text>
|
|
|
+ </View>
|
|
|
+ <View className="summary_footer_item">
|
|
|
+ <Text className="light_desc">Calories</Text>
|
|
|
+ <Text>{data.stat.real_calories}/{data.stat.target_calories}</Text>
|
|
|
+ </View>
|
|
|
+ <View className="summary_footer_item">
|
|
|
+ <Text className="light_desc">Distance</Text>
|
|
|
+ <Text>{data.stat.real_distance}/{data.stat.target_distance}</Text>
|
|
|
+ </View>
|
|
|
+ </View>
|
|
|
</View>
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!loaded) return <View />
|
|
|
+
|
|
|
+ return <View style={{ display: 'flex', flexDirection: 'column' }}>
|
|
|
+ <Text className="move-title">Move Every Hour</Text>
|
|
|
+ {
|
|
|
+ currentContent()
|
|
|
+ }
|
|
|
+ {
|
|
|
+ activeHour()
|
|
|
+ }
|
|
|
+ {
|
|
|
+ list.length > 0 && <View className="history">
|
|
|
+ <View className="history_header">
|
|
|
+ <Text className="history_header_title">Recent</Text>
|
|
|
+ <View className="border_footer_line" />
|
|
|
+ </View>
|
|
|
+ {
|
|
|
+ list.map((item, index) => {
|
|
|
+ return <View key={index} className="history_item">
|
|
|
+ <Text className="history_item_date">{(item.date + '').substring(6, 8)}</Text>
|
|
|
+ <View className="history_item_detail_bg">
|
|
|
+ <Image className="history_item_detail_icon" src={require('@assets/_health/walk.png')} />
|
|
|
+ <Text>每小时活动 {item.real_hours}/{item.target_hours} · Steps {item.stat.real_steps}/{item.stat.target_steps}</Text>
|
|
|
+ </View>
|
|
|
+ <View className="border_footer_line" />
|
|
|
+ </View>
|
|
|
+ })
|
|
|
+ }
|
|
|
+ </View>
|
|
|
+ }
|
|
|
+ {
|
|
|
+ (list.length > 0) && (total == list.length) && <Text className="no_more">没有更多了</Text>
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
</View>
|
|
|
}
|