| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502 |
- import { View, Text, Image, PageContainer } from "@tarojs/components";
- import './Metric.scss'
- import { useDispatch, useSelector } from "react-redux";
- import { useEffect, useRef, useState } from "react";
- import Taro from "@tarojs/taro";
- import { metricCards, metricFollows, metricGroups, uploadMetric, uploadSteps } from "@/services/trackSomething";
- import { TimeFormatter } from "@/utils/time_format";
- import MetricItem from "./MetricItem";
- import NoData from "@/components/view/NoData";
- import Layout from "@/components/layout/layout";
- import { MetricModalType, ModalType, NaviBarTitleShowType, TemplateType } from "@/utils/types";
- import { useTranslation } from "react-i18next";
- import { jumpPage } from "@/features/trackTimeDuration/hooks/Common";
- import TitleView from "@/features/trackTimeDuration/components/TitleView";
- import { setTabbarStatus } from "@/store/common";
- import MetricModalChoose from "./MetricModalChoose";
- import MetricModalOrder from './MetricModalOrder';
- import MetricModalAdd from "./MetricModalAdd";
- import MetricModalTime from "./MetricModalTime";
- import Modal from "@/components/layout/Modal";
- import { rpxToPx } from "@/utils/tools";
- let useNavigation;
- if (process.env.TARO_ENV == 'rn') {
- useNavigation = require("@react-navigation/native").useNavigation
- }
- export default function Component(props: any) {
- const { t } = useTranslation()
- const user = useSelector((state: any) => state.user);
- const [list, setList] = useState([])
- const [metricItem, setMetricItem] = useState({})
- const [strTime, setStrTime] = useState('')
- const [time, setTime] = useState(0)
- const [showErrorPage, setErrorPage] = useState(false)
- const [setupTime, setSetupTime] = useState(0)
- const [triggered, setTriggered] = useState(true)
- const [count, setCount] = useState(0)
- const [showPageContainer, setShowPageContainer] = useState(false)
- const [modalType, setModalType] = useState(MetricModalType.none)
- const [themeColor, setThemeColor] = useState('#00ffff')
- const [groups, setGroups] = useState([])
- const [orignalGroups, setOrignalGroups] = useState([])
- const [limits, setLimits] = useState(null)
- const [orders, setOrders] = useState([])
- const [newOrders, setNewOrders] = useState([])
- const [resultOrders, setResultOrders] = useState([])
- const [tempMetricItem, setTempMetricItem] = useState(null)
- const [loaded, setLoaded] = useState(false)
- const dispatch = useDispatch();
- let navigation;
- if (useNavigation) {
- navigation = useNavigation()
- }
- //未登录<->已登录 状态切换时,执行一次授权检查
- useEffect(() => {
- getCards();
- getGroups();
- const now = new Date();
- const nextMidnight = new Date(now.getFullYear(), now.getMonth(), now.getDate() + 1, 0, 0, 0);
- const timeUntilMidnight = nextMidnight.getTime() - now.getTime();
- setTimeout(() => {
- setCount(count + 1)
- }, timeUntilMidnight);
- }, [user.isLogin])
- const openModal = () => {
- setSetupTime(new Date().getTime())
- setModalType(MetricModalType.add)
- setShowPageContainer(true)
- };
- global.refreshMetric = () => {
- getCards()
- }
- function getCards() {
- setTriggered(true)
- metricCards().then(res => {
- Taro.stopPullDownRefresh()
- setErrorPage(false)
- setList((res as any).cards)
- setTriggered(false)
- if ((res as any).cards.length > 0) {
- var obj = (res as any).cards[0]
- setThemeColor(obj.theme_color)
- }
- var list: any = [];
- (res as any).cards.map(item => {
- list.push({
- name: item.name,
- code: item.code,
- is_following: true
- })
- })
- setOrders(list)
- setResultOrders(list)
- setLoaded(true)
- }).catch(e => {
- Taro.stopPullDownRefresh()
- if (list.length == 0) {
- setErrorPage(true)
- }
- setTriggered(false)
- setLoaded(false)
- })
- }
- function getGroups() {
- metricGroups().then(res => {
- var array = (res as any).groups
- setOrignalGroups(JSON.parse(JSON.stringify(array)))
- setGroups(array)
- setLimits((res as any).num_options_limit)
- setNewOrders([])
- })
- }
- //ts 把数组items: [{code: "_walk", value: 2180},{code: "_walk", value: 4444}]中的value取出来,/分割,组成字符串,如2180/4444
- function getValues(items) {
- var values = ''
- items.map((item, index) => {
- if (index == 0) {
- values = item.value
- }
- else {
- values = values + '/' + item.value
- }
- })
- return values
- }
- function goDetail(item) {
- if (user.isLogin) {
- if (!item.latest_record) {
- return
- }
- global.selMetricItem = item
- jumpPage('/pages/common/RecordsHistory?type=metric&refreshList=getCards&code='
- + item.code + `&title=${item.name}` + '&themeColor=' + item.theme_color, 'RecordsHistory', navigation, {
- type: 'metric',
- refreshList: 'getCards',
- code: item.code,
- title: item.name,
- themeColor: item.theme_color
- })
- }
- else {
- jumpPage('/pages/account/ChooseAuth', 'ChooseAuth', navigation)
- }
- }
- function record(item: any) {
- if (user.isLogin) {
- var now = new Date();
- var t = (now.getHours() < 10 ? '0' + now.getHours() : now.getHours()) + ":" + (now.getMinutes() < 10 ? '0' + now.getMinutes() : now.getMinutes());
- // setStrTime(t)
- setStrTime(TimeFormatter.dateTimeFormate(now.getTime()))
- setTime(now.getTime())
- setMetricItem(item)
- openModal()
- }
- else {
- jumpPage('/pages/account/ChooseAuth', 'ChooseAuth', navigation)
- }
- }
- function chooseTime(e) {
- setTime(e);
- setStrTime(TimeFormatter.dateTimeFormate(e))
- }
- const limitDay = 500
- const limit = new Date().getTime() - limitDay * 3600 * 1000 * 24;
- //获取参考值
- function getTargetValue(item) {
- for (var i = 0; i < item.references.length; i++) {
- for (var j = 0; j < item.references[i].categories.length; j++) {
- if (item.references[i].categories[j].is_default) {
- return item.references[i].categories[j].value_range
- }
- }
- }
- return null
- }
- function detail() {
- return <View>
- <View className="metric_container">
- {
- list.map((item: any, index: number) => {
- var unit = ''
- var value = t('feature.track_something.metric.no_record')
- var desc = t('feature.track_something.metric.check_unlock_data')
- var showDetail = false;
- if (item.latest_record) {
- if (item.type == 'composite') {
- unit = item.latest_record.unit ? item.latest_record.unit : ''
- value = item.latest_record.value
- }
- else {
- unit = item.schemas[0].default_unit
- value = getValues(item.latest_record.items)
- }
- desc = TimeFormatter.dateDescription(item.latest_record.timestamp, true)
- showDetail = true
- }
- if (!user.isLogin) {
- value = t('feature.track_something.metric.un_login')
- desc = t('feature.track_something.metric.login_can_check')
- }
- if (getTargetValue(item)) {
- desc = getTargetValue(item)
- }
- // desc = '90~140/60~90 mmHg'
- return <MetricItem title={item.name}
- value={value}
- unit={unit}
- desc={desc}
- btnText={t('feature.track_something.btn_record')}
- isDisabled={false}
- showDetail={showDetail}
- themeColor={item.theme_color}
- onClickDetail={() => { goDetail(item) }}
- onClick={() => { record(item) }}
- showTag={item.type == 'composite'}
- tagName={t('feature.track_something.metric.composite')}
- />
- })
- }
- {
- user.isLogin && list.length > 0 && <View className="add_more" onClick={chooseMore}>
- <Image style={{ width: rpxToPx(48), height: rpxToPx(48) }} src={require('@assets/images/add2.png')} />
- <Text className="add_more_text">{t('feature.workout.add_more')}</Text>
- </View>
- }
- </View>
- <View className="space_width" ></View>
- </View>
- }
- function addBtnClick() {
- Taro.showActionSheet({
- itemList: [t('feature.track_something.metric.choose_metric'),
- t('feature.track_something.metric.order')]
- })
- .then(res => {
- switch (res.tapIndex) {
- case 0:
- chooseMore()
- break;
- case 1:
- global.metricAdd = false
- setModalType(MetricModalType.order)
- setShowPageContainer(true)
- break;
- }
- })
- .catch(err => {
- console.log(err.errMsg)
- })
- }
- function chooseMore() {
- global.metricAdd = true
- setModalType(MetricModalType.choose)
- setShowPageContainer(true)
- }
- function headerView() {
- return <TitleView title={t('page.metric.title')} showAddBtn={loaded && !showErrorPage ? true : false} onClick={addBtnClick}>
- </TitleView>
- }
- function metricModalContent() {
- switch (modalType) {
- case MetricModalType.choose:
- return <MetricModalChoose
- themeColor={themeColor}
- cancel={modalCancel}
- confirm={modalConfirm}
- array={groups}
- orders={orders}
- newOrders={newOrders}
- limit={limits}
- />
- case MetricModalType.order:
- return <MetricModalOrder
- themeColor={themeColor}
- cancel={modalOrderCancel}
- confirm={modalOrderConfirm}
- array={resultOrders} />
- case MetricModalType.add:
- return <MetricModalAdd
- item={tempMetricItem ? tempMetricItem : metricItem}
- strTime={strTime}
- showPicker={(tempItem) => {
- var temp = JSON.parse(JSON.stringify(tempItem))
- temp.schemas.map(item => {
- if (item.tempValue) {
- item.default_value = item.tempValue
- }
- })
- setTempMetricItem(temp)
- setModalType(MetricModalType.time)
- }}
- cancel={modalAddCancel}
- confirm={modalAddConfirm} />
- case MetricModalType.time:
- return <MetricModalTime
- item={metricItem}
- time={time}
- limit={limit}
- limitDay={limitDay}
- cancel={() => {
- setModalType(MetricModalType.add)
- }}
- confirm={(e) => {
- chooseTime(e)
- setModalType(MetricModalType.add)
- }}
- />
- }
- return <View />
- }
- function modalCancel() {
- setShowPageContainer(false)
- onPageContainerCancel()
- }
- function modalConfirm(datas, newOrders, resultOrders, groups) {
- setOrders(datas)
- setGroups(groups)
- setNewOrders(newOrders)
- setResultOrders(resultOrders)
- setModalType(MetricModalType.order)
- }
- function modalOrderCancel() {
- if (global.metricAdd) {
- setModalType(MetricModalType.choose)
- }
- else {
- setShowPageContainer(false)
- onPageContainerCancel()
- }
- }
- function modalOrderConfirm(datas) {
- var array: any = []
- datas.map(item => {
- array.push(item.code)
- })
- metricFollows({ codes: array }).then(res => {
- getCards()
- getGroups()
- setList((res as any).cards)
- // setOrignalGroups(groups)
- })
- setShowPageContainer(false)
- }
- function modalAddCancel() {
- setShowPageContainer(false)
- onPageContainerCancel()
- }
- function modalAddConfirm(result) {
- setShowPageContainer(false)
- var date = new Date(time)
- var strDate = (date.getFullYear() + '') + (date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : (date.getMonth() + 1)) + (date.getDate() < 10 ? '0' + date.getDate() : date.getDate());
- var array: any[] = [];
- result.schemas.map((item, index) => {
- array.push({
- code: item.code,
- value: item.tempValue && item.tempValue > 0 ? item.tempValue : item.default_value
- })
- })
- var params = {
- code: result.code,
- timestamp: time,
- date: strDate,
- items: array,
- extra: {
- set_time: setupTime,
- confirm_time: new Date().getTime()
- }
- }
- global.postBtnUpdateStatus('normal');
- uploadMetric(params).then(res => {
- // getCards();
- result.schemas.map((item, index) => {
- item.tempValue = ''
- })
- list.map((item, index) => {
- if ((item as any).code == (res as any).code) {
- (item as any).latest_record = (res as any).latest_record;
- (item as any).schemas = (res as any).schemas;
- }
- })
- setList(JSON.parse(JSON.stringify(list)))
- global.postBtnUpdateStatus('idle');
- setTimeout(() => {
- setCount(count + 1)
- }, 31000)
- getCards()
- })
- }
- function onPageContainerCancel() {
- if (modalType == MetricModalType.choose || modalType == MetricModalType.order) {
- var array: any = [];
- list.map(item => {
- array.push({
- name: (item as any).name,
- code: (item as any).code,
- is_following: true
- })
- })
- setOrders(array)
- setNewOrders([])
- setGroups(JSON.parse(JSON.stringify(orignalGroups)))
- // setGroups(orignalGroups)
- }
- else {
- setTempMetricItem(null)
- }
- }
- function modalContent() {
- if (showPageContainer) {
- if (process.env.TARO_ENV == 'weapp') {
- return <Modal dismiss={() => {
- onPageContainerCancel()
- setShowPageContainer(false)
- }} confirm={() => { }}>
- {
- metricModalContent()
- }
- </Modal>
- }
- else if (process.env.TARO_ENV == 'rn') {
- return <PageContainer style={{ backgroundColor: '#1c1c1c' }}
- overlayStyle={{ backgroundColor: 'rgba(0,0,0,0.9)' }}
- customStyle={{ backgroundColor: '#1c1c1c' }}
- closeOnSlideDown={false}
- show={showPageContainer} round={true} overlay={true} position='bottom'
- onClickOverlay={onPageContainerCancel}
- onAfterLeave={() => { setShowPageContainer(false); setModalType(MetricModalType.none) }}
- onBeforeEnter={() => { dispatch(setTabbarStatus(false)); Taro.hideTabBar() }}
- onBeforeLeave={() => { dispatch(setTabbarStatus(true)); Taro.showTabBar() }}
- >
- {
- metricModalContent()
- }
- </PageContainer>
- }
- }
- return <View />
- }
- return <View style={{ position: 'relative' }}>
- <Layout children={showErrorPage ? <NoData refresh={() => { getCards() }} /> : detail()}
- title={t('page.metric.title')}
- type={TemplateType.customHeader}
- header={headerView()}
- refresh={() => { getCards() }}
- triggered={triggered}
- titleShowStyle={NaviBarTitleShowType.scrollToShow}
- />
- {
- modalContent()
- }
- </View>
- }
|