import { ColorType } from "@/context/themes/color"; import { TimeFormatter } from "@/utils/time_format"; import { View, Text } from "@tarojs/components"; import { useEffect, useState } from "react"; import { ChooseScenarioBtn, WorkoutEndBtn } from "../common/SpecBtns"; import Taro, { useRouter } from "@tarojs/taro"; import { WorkoutType } from "@/utils/types"; import Modal from "@/components/layout/Modal"; import PickerViews from "@/components/input/PickerViews"; import { useDispatch, useSelector } from "react-redux"; import { endSuccess, startSuccess } from "@/store/workout"; import { uploadWorkout } from "@/services/workout"; import './WorkoutStopWatch.scss' import Box from "@/components/layout/Box"; import { rpxToPx } from "@/utils/tools"; import MultiText from "@/components/view/MultiText"; import { values } from "lodash"; import { IconRadioCross, IconX } from "@/components/basic/Icons"; var timer var lastStrTime var lastTimestamp export default function Component(props: { targetCount: any, end: Function }) { const router = useRouter(); const workout = useSelector((state: any) => state.workout); const [index, setIndex] = useState(1) const [count, setCount] = useState(0) const [startTime, setStartTime] = useState(new Date().getTime()) const [tempTime, setTempTime] = useState(0) // const [lastStrTime, setLastStrTime] = useState('') const [groups, setGroups] = useState([]) const [isDoing, setIsDoing] = useState(true) const [showModal, setShowModal] = useState(false) const [needTerminal, setNeedTerminal] = useState(false) const [isPaused, setIsPaused] = useState(false); const [isPosting, setIsPosting] = useState(false) const dispatch = useDispatch(); const [pickerItems, setPickerItems] = useState([]) const [pickerValue, setPickerValue] = useState([]) const [lastPickerValue,setLastPickerValue] = useState([]) const [isEdit, setIsEdit] = useState(false) const [editIndex, setEditIdex] = useState(-1) useEffect(() => { if (router.params.restore) { Taro.getStorage({ key: 'lastWorkout', success: function (res) { var workouts = JSON.parse(res.data) setGroups(workouts) var workObj = workouts[workouts.length - 1] setIndex(workObj.index) setStartTime(workObj.time) if (workObj.type == 'REST') { setIsDoing(false) } }, fail: function (err) { console.log(err, 'no cache') } }) } else { var array = [{ code: workout.item.code, index: index, time: startTime, duration: props.targetCount, type: 'WORK' }] setGroups(array) saveCache(array) dispatch(startSuccess({ start: startTime, code: workout.item.code, duration: props.targetCount })) } var item = workout.item var items: any = [] var selects: any = [] item.schemas[0].values.map(obj => { var list: any = [] var min = parseInt(obj.min + '') var max = parseInt(obj.max + '') var step = parseInt(obj.step + '') var defaultV = parseInt(obj.default_value) for (var i = min; i <= max; i = i + step) { list.push(i + obj.unit) } items.push(list) for (var i = 0; i < list.length; i++) { if (parseInt(list[i] + '') == defaultV) { selects.push(i) } } }) setLastPickerValue(selects) setPickerValue(selects) setPickerItems(items) setLatestPicker() // setTimeout(()=>{ // Taro.pageScrollTo({ // scrollTop:100000, // duration:0 // }) // },100) }, []) useEffect(() => { if (!isPaused) { timer = setInterval(() => { setCount((count) => count + 1) }, 1000) } return () => clearInterval(timer) }, [isPaused]) function resume() { if (timer) { clearInterval(timer) timer = null } timer = setInterval(() => { setCount((count) => count + 1) }, 1000) } function planTime() { var minutes = props.targetCount / 60 return minutes + '分钟' } function durationTime() { var str = TimeFormatter.formateTimeNow(startTime) lastStrTime = str return str } function twoTimeDuration(start, end) { var time = Math.floor((end - start) / 1000); const hours = Math.floor(time / 3600); const minutes = Math.floor((time % 3600) / 60); const seconds = Math.floor(time % 60); var strDuration = '' if (hours > 0) { strDuration = `${hours}小时` } if (minutes > 0) { strDuration += `${minutes}分钟` } if (seconds > 0) { strDuration += `${seconds}秒` } return strDuration.length == 0 ? '1秒' : strDuration } function twoTimeFormateList(start, end) { var time = Math.floor((end - start) / 1000); if (time<1){ time = 1 } return TimeFormatter.workoutTimeAndUnitList(time) } function setLatestPicker(){ if (lastPickerValue){ setPickerValue(lastPickerValue) } for (var i=groups.length-1;i>=0;i--){ var obj = groups[i] if (obj.pickerValue){ setLastPickerValue(obj.pickerValue) setPickerValue(obj.pickerValue) return } } } function finish() { setTempTime(new Date().getTime()) var schema = workout.item.schemas[0] if (workout.item.schemas[0].values.length > 0 && schema.format != 'TIME_SECONDS') { setLatestPicker() // if (groups[groups.length]) clearInterval(timer) setShowModal(true) return } clearInterval(timer) timer = null resume() var array = groups; var time = new Date().getTime() array.push({ code: workout.item.code, index: index, time: time, type: 'REST' }) setIsDoing(false) setStartTime(time) setGroups(array) saveCache(array) } function start() { clearInterval(timer) timer = null resume() var array = groups; var time = new Date().getTime() array.push({ code: workout.item.code, index: index + 1, time: time, type: 'WORK' }) setStartTime(time) setIndex(index + 1) setIsDoing(true) setGroups(array) saveCache(array) } function saveCache(array) { Taro.setStorage({ key: 'lastWorkout', data: JSON.stringify(array) }) } function clearCache() { Taro.removeStorage({ key: 'lastWorkout' }) } function formateDate(date) { return (date.getFullYear() + '') + (date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : (date.getMonth() + 1)) + (date.getDate() < 10 ? '0' + date.getDate() : date.getDate()); } function getValue(str, unit) { var i = str.indexOf(unit) return str.substring(0, i) } function getUnit() { var schema = workout.item.schemas[0] var units = schema.values if (schema.format == 'TIME_SECONDS') { return units[units.length - 1].unit } else { return units.map(obj => obj.unit).join('·') } } function totalValue() { var count = 0 var schema = workout.item.schemas[0] if (schema.format == 'TIME_SECONDS') { groups.map(item => { if (item.type == 'WORK') { var t = Math.floor((item.end - item.start) / 1000) t = t < 1 ? 1 : t console.log(t) count += t } }) return count } for (var i = 0; i < groups.length; i++) { var obj = groups[i] if (obj.type == 'WORK') { var temp = 0 if (schema.format == 'TIME_SECONDS') { temp = parseInt(obj.value + '') * 3600 + parseInt(obj.value2 + '') * 60 + parseInt(obj.value3 + '') } else { if (obj.value) { temp = parseInt(obj.value + '') } if (obj.value2) { temp *= parseInt(obj.value2 + '') } if (obj.value3) { temp *= parseInt(obj.value3 + '') } } count += temp } } return count } function postData() { setIsPosting(true) var date = new Date() var strDate = formateDate(date) var records: any = [] for (var i = 0; i < groups.length; i++) { var obj = groups[i] if (obj.type == 'WORK') { obj.start = obj.time obj.end = groups[i + 1].time obj.value = groups[i + 1].value obj.value2 = groups[i + 1].value2 obj.value3 = groups[i + 1].value3 } else { if (i != groups.length - 1) { obj.start = obj.time obj.end = groups[i + 1].time } } } for (var i = groups.length - 1; i >= 0; i--) { var obj = groups[i] if (obj.type == 'REST') { groups.splice(i, 1) } else { break; } } var units = workout.item.schemas[0].values for (var i = 0; i < groups.length; i++) { var obj = groups[i] var values: any = [] if (obj.type == 'WORK') { if (obj.value) { if (units) { values.push({ value: getValue(obj.value, units[0].unit), unit: units[0].unit }) } else { values.push({ value: obj.value }) } } if (obj.value2) { values.push({ value: getValue(obj.value2, units[1].unit), unit: units[1].unit }) } if (obj.value3) { values.push({ value: getValue(obj.value3, units[2].unit), unit: units[2].unit }) } } records.push({ type: obj.type, start: { date: formateDate(new Date(obj.start)), timestamp: obj.start }, end: { date: formateDate(new Date(obj.end)), timestamp: obj.end }, values: values }) } var params = { date: strDate, timestamp: date.getTime(), code: workout.item.code, items: [ { code: workout.item.code, duration: props.targetCount * 1000, summary_stats: [ { unit: getUnit(), value: totalValue() } ], groups: records } ] } uploadWorkout(params).then(res => { clearCache() dispatch(endSuccess()) setTimeout(() => { Taro.redirectTo({ url: '/pages/workout/WorkoutDetail?detail=' + JSON.stringify((res as any).latest_record) + '&title=' + workout.item.name + '&themeColor=' + workout.item.theme_color }) }, 0) props.end() global.refreshWorkout() }).catch(e => { setIsPosting(false) resume() }) } function checkEnd() { if (groups[groups.length - 1].type == 'REST') { postData() return } setLatestPicker() setIsPosting(true) setNeedTerminal(true) setShowModal(true) } function terminal() { clearInterval(timer) var tempTimestamp = new Date().getTime() setTempTime(tempTimestamp) lastTimestamp = tempTimestamp Taro.showModal({ title: '提示', content: '确认结束?', success: function (res) { if (res.confirm) { var schema = workout.item.schemas[0] if (workout.item.schemas[0].values.length > 0 && schema.format != 'TIME_SECONDS') { checkEnd() return; } var array = groups; // var time = new Date().getTime() array.push({ index: index, time: tempTimestamp, type: 'REST' }) // setIsDoing(false) setGroups(array) postData() } else if (res.cancel) { resume() console.log('用户点击取消') } } }) } function numChange(e) { if (isEdit) { var array = groups var obj = array[editIndex] obj.value = e.length > 0 ? pickerItems[0][e[0]] : pickerItems[e[0]] obj.value2 = e.length > 1 ? pickerItems[1][e[1]] : null obj.value3 = e.length > 2 ? pickerItems[2][e[2]] : null obj.pickerValue = e saveCache(array) setGroups(array) setIsEdit(false) setEditIdex(-1) setPickerValue(e) setShowModal(false) resume() return } setLastPickerValue(e) setPickerValue(e) setShowModal(false) var array = groups; array.push({ index: index, time: tempTime, pickerValue:e, value: e.length > 0 ? pickerItems[0][e[0]] : pickerItems[e[0]], value2: e.length > 1 ? pickerItems[1][e[1]] : null, value3: e.length > 2 ? pickerItems[2][e[2]] : null, type: 'REST' }) if (needTerminal) { postData() return; } setIsDoing(false) saveCache(array) setStartTime(tempTime) setGroups(array) resume() } function needShowPicker() { var schema = workout.item.schemas[0] if (schema.format == 'TIME_SECONDS') { return false; } if (schema.values.length == 0) { return false; } return true; } function pickerContent() { var color = workout.item.theme_color var title = isEdit?`第${groups[editIndex].index}组`:`第${index}组` return { resume() setIsPosting(false) setNeedTerminal(false) setShowModal(false) }} /> } function totalSummary() { var multiValues: any = [] var multiUnits: any = [] var schema = workout.item.schemas[0] if (schema.format == 'TIME_SECONDS') { var count = 0 for (var i = 0; i < groups.length; i++) { var obj = groups[i] if (obj.type == 'REST') { count += Math.floor((obj.time - groups[i - 1].time) / 1000) } } if (!count) { multiValues.push(0) multiValues.push(0) multiValues.push(0) multiUnits.push('小时') multiUnits.push('分钟') multiUnits.push('秒') } else { var obj = TimeFormatter.workoutTimeAndUnitList(count) as any multiValues = obj.values multiUnits = obj.units } } else { var count = 0 for (var i = 0; i < groups.length; i++) { var obj = groups[i] if (obj.type == 'REST') { var temp = 0 if (obj.value) { temp = parseInt(obj.value + '') } if (obj.value2) { temp *= parseInt(obj.value2 + '') } if (obj.value3) { temp *= parseInt(obj.value3 + '') } count += temp } } var array = workout.item.schemas[0].values var unit = array.map(obj => obj.unit).join('·') multiUnits = [unit] multiValues = [count] } return } function edit(e, index) { if (process.env.TARO_ENV == 'weapp') { e.stopPropagation() } if (groups[index].pickerValue){ setPickerValue(groups[index].pickerValue) } clearInterval(timer) setIsEdit(true) setEditIdex(index) setShowModal(true) } return {workout.item.name} 计时训练 { groups.length > 1 && groups.map((item, index) => { if (index == 0) { return } return {item.type == 'REST' ? `第${item.index}组` : '组间休息'} { item.type == 'REST' &&workout.item.schemas[0].format != 'TIME_SECONDS' && edit(e, index)}>编辑 } {item.type == 'REST' && workout.item.schemas[0].format != 'TIME_SECONDS' && { } { item.value2 && } { item.value2 && } { item.value2 && } { item.value3 && } // {getGroupValue(item)} } { item.type == 'REST' && workout.item.schemas[0].format == 'TIME_SECONDS' && } {twoTimeDuration(groups[index - 1].time, item.time)} }) } { isDoing ? 第{index}组 {isPosting ? lastStrTime : durationTime()} : 组间休息 {isPosting ? lastStrTime : durationTime()} } 结束训练 训练统计 总量 { totalSummary() } {/* */} 已进行 {groups.length > 0 && (isPosting ? TimeFormatter.formateTimeNow(groups[0].time, lastTimestamp) : TimeFormatter.formateTimeNow(groups[0].time))} {groups.length > 0 && new Date().getTime() > groups[0].time + props.targetCount * 1000 ? '已超时' : '距结束'} {groups.length > 0 && (isPosting ? TimeFormatter.countdown(groups[0].time + props.targetCount * 1000, lastTimestamp) : TimeFormatter.countdown(groups[0].time + props.targetCount * 1000))} { showModal && { setShowModal(false) resume() }}> { pickerContent() } } }