Leon hace 2 años
padre
commit
b4338de5bc

+ 2 - 2
src/app.config.ts

@@ -1,9 +1,9 @@
 const appConfig = defineAppConfig({
   pages: [
-    'pages/demo',
-    'pages/clock/Clock',
     
+    'pages/clock/Clock',
     
+    'pages/demo',
     
     
     'pages/index/index',

+ 2 - 2
src/components/input/LimitPickers.tsx

@@ -122,7 +122,7 @@ const Component = forwardRef((props: {
             // console.log('oppsu')
             Taro.showToast({
                 icon: 'none',
-                title: '不能更大了',
+                title: t('feature.common.toast.min_value'),
             })
             // console.log(list[0], (new Date(global.set_time)).getHours(), (new Date(global.set_time)).getMinutes())
             setValues([list[0], (new Date(global.set_time)).getHours(), (new Date(global.set_time)).getMinutes()])
@@ -134,7 +134,7 @@ const Component = forwardRef((props: {
             if (getTimestamp(time) < props.limit) {
                 Taro.showToast({
                     icon: 'none',
-                    title: '不能更小了',
+                    title: t('feature.common.toast.max_value'),
                 })
                 setValues([(props.limitDay ? props.limitDay - 1 : 6) - getDaysDiff(limitDate), limitDate.getHours(), limitDate.getMinutes()])
                 disableConfirm()

+ 4 - 1
src/context/locales/zh.js

@@ -294,7 +294,10 @@ export default {
                 no_record: '无记录',
                 un_login: '未登录',
                 login_can_check: '登录后可记录',
-                check_unlock_data: '记录解锁趋势'
+                check_unlock_data: '记录解锁趋势',
+                choose_metric:'选择指标项',
+                order:'调整排序'
+
             },
             werun_auth: {
                 modal_open_setting_title: '提示',

+ 119 - 110
src/features/trackSomething/components/Metric.tsx

@@ -3,7 +3,7 @@ import './Metric.scss'
 import { useDispatch, useSelector } from "react-redux";
 import { useEffect, useRef, useState } from "react";
 import Taro from "@tarojs/taro";
-import { metricCards, metricGroups, uploadMetric, uploadSteps } from "@/services/trackSomething";
+import { metricCards, metricFollows, metricGroups, uploadMetric, uploadSteps } from "@/services/trackSomething";
 import { TimeFormatter } from "@/utils/time_format";
 import MetricItem from "./MetricItem";
 import Modal from "@/components/layout/Modal";
@@ -12,17 +12,21 @@ import SlidngScale from "@/components/input/SlidngScale";
 import NoData from "@/components/view/NoData";
 import { alphaToHex } from "@/utils/tools";
 import Layout from "@/components/layout/layout";
-import { NaviBarTitleShowType, TemplateType } from "@/utils/types";
+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';
 
 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);
@@ -46,6 +50,11 @@ export default function Component(props: any) {
     const limitPickerRef = useRef<any>(null);
     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 [limits, setLimits] = useState(null)
+    const [orders, setOrders] = useState([])
     const dispatch = useDispatch();
     let navigation;
     if (useNavigation) {
@@ -86,6 +95,19 @@ export default function Component(props: any) {
             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
+                })
+            })
+            setOrders(list)
+
         }).catch(e => {
             Taro.stopPullDownRefresh()
             if (list.length == 0) {
@@ -95,9 +117,10 @@ export default function Component(props: any) {
         })
     }
 
-    function getGroups(){
-        metricGroups().then(res=>{
-            
+    function getGroups() {
+        metricGroups().then(res => {
+            setGroups((res as any).groups)
+            setLimits((res as any).num_options_limit)
         })
     }
 
@@ -143,106 +166,8 @@ export default function Component(props: any) {
         }
     }
 
-    function pointPicker(item: any) {
-        var min = item.min
-        var max = item.max
-        var step = item.step
-        var value = item.default_value
-        var items: number[] = []
-        var items2: number[] = []
-
-        var value0Index = 0
-        var value1Index = 0
-
-        for (var i = min; i <= max; i++) {
-            if (i == Math.floor(value)) {
-                value0Index = i - min
-            }
-            items.push(i)
-            // items2.push(i)
-        }
-
-        for (var i = 0; i <= 9; i++) {
-            items2.push(i)
-        }
-        value1Index = Math.round(10 * (value - Math.floor(value)));
-
-        setPickerValue([value0Index, value1Index] as any)
-        setPickerItems([items, items2] as any)
-        setIsPoint(true)
-
-        openModal()
-    }
-
-    function singlePicker(item: any) {
-        var min = item.min
-        var max = item.max
-        var step = 1//item.step
-        var value = item.default_value
-
-        var items: number[] = []
-        for (var i = min; i <= max; i += step) {
-            if (i == value) {
-                setPickerValue([i - min] as any)
-            }
-            items.push(i)
-        }
-
-        setPickerItems([items] as any)
-        setIsPoint(false)
-
-        openModal()
-    }
-
-    function pickerChanged(e) {
-        closeModal();
-        var params = {}
-        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());
-
-        if ((metricItem as any).schemas[0].type == 'DECIMAL') {
-            var array = pickerItems;
-            var value = array[0][e[0]] + '.' + array[1][e[1]]
-
-
-            params = {
-                code: (metricItem as any).code,
-                timestamp: time,
-                date: strDate,
-                items: [{ code: (metricItem as any).schemas[0].code, value: value }]
-            }
-        }
-        else if ((metricItem as any).schemas.length > 1) {
-
-        }
-        else {
-            var array = pickerItems;
-            var value = array[0][e[0]] + ''
-            params = {
-                code: (metricItem as any).code,
-                timestamp: time,
-                date: strDate,
-                items: [{ code: (metricItem as any).schemas[0].code, value: value }]
-            }
-        }
-
-        uploadMetric(params).then(res => {
-            list.map((item, index) => {
-                if ((item as any).code == (res as any).code) {
-                    (item as any).latest_record = (res as any).latest_record
-                }
-            })
-            setList(list)
-
-            setTimeout(() => {
-                setCount(count + 1)
-            }, 31000)
-            // getCards();
-        })
-    }
-
     function showTimePicker() {
-        
+
         setIsTimePickerOpen(true)
     }
 
@@ -364,8 +289,31 @@ export default function Component(props: any) {
     }
 
     function addBtnClick() {
-        dispatch(setTabbarStatus(false))
-        setShowPageContainer(true)
+        Taro.showActionSheet({
+            itemList: [t('feature.track_something.metric.choose_metric'),
+            t('feature.track_something.metric.order')]
+        })
+            .then(res => {
+                switch (res.tapIndex) {
+                    case 0:
+                        global.metricAdd = true
+                        setModalType(MetricModalType.choose)
+                        dispatch(setTabbarStatus(false))
+                        setShowPageContainer(true)
+
+                        break;
+                    case 1:
+                        global.metricAdd = false
+                        setModalType(MetricModalType.order)
+                        dispatch(setTabbarStatus(false))
+                        setShowPageContainer(true)
+                        break;
+                }
+            })
+            .catch(err => {
+                console.log(err.errMsg)
+            })
+
     }
 
     function headerView() {
@@ -373,6 +321,64 @@ export default function Component(props: any) {
         </TitleView>
     }
 
+    function metricModalContent() {
+        switch (modalType) {
+            case MetricModalType.choose:
+                return <MetricModalChoose
+                    themeColor={themeColor}
+                    cancel={modalCancel}
+                    confirm={modalConfirm}
+                    array={groups}
+                    orders={orders}
+                    limit={limits}
+                />
+            case MetricModalType.order:
+                return <MetricModalOrder themeColor={themeColor} cancel={modalOrderCancel} confirm={modalOrderConfirm} array={orders} />
+        }
+        return <View />
+    }
+
+    function modalCancel() {
+        setShowPageContainer(false)
+    }
+
+    function modalConfirm(datas) {
+        var array: any = []
+        datas.map(item => {
+            array.push(item.code)
+        })
+        metricFollows({ codes: array }).then(res => {
+            getCards()
+            getGroups()
+        })
+        setShowPageContainer(false)
+
+        setTimeout(() => {
+            dispatch(setTabbarStatus(false))
+            setModalType(MetricModalType.order)
+            setShowPageContainer(true)
+        }, 500)
+    }
+
+    function modalOrderCancel() {
+        global.metricAdd ? modalCancel() : modalCancel()
+        if (global.metricAdd) {
+            setShowPageContainer(false)
+            setTimeout(() => {
+                dispatch(setTabbarStatus(false))
+                setModalType(MetricModalType.choose)
+                setShowPageContainer(true)
+            }, 500)
+        }
+        else {
+            setShowPageContainer(false)
+        }
+    }
+
+    function modalOrderConfirm() {
+        setShowPageContainer(false)
+    }
+
     return <View style={{ position: 'relative' }}>
         <Layout children={showErrorPage ? <NoData refresh={() => { getCards() }} /> : detailContent()}
             title={t('page.metric.title')}
@@ -385,10 +391,13 @@ export default function Component(props: any) {
         <PageContainer style={{ backgroundColor: '#1c1c1c' }}
             overlayStyle='background-color:rgba(0,0,0,0.9)'
             custom-style='background-color:#1c1c1c'
-            show={showPageContainer} round={true} overlay={true} position='bottom' onAfterLeave={() => {setShowPageContainer(false);dispatch(setTabbarStatus(true))}}>
-            <Text style={{color:'#000'}} onClick={()=>{console.log('ssss')}}>1111</Text>
-            <View style={{ width: 200, height: 200, backgroundColor: 'pink', margin: 50 }} />
-            <Text style={{color:'#000'}} onClick={()=>{console.log('ssss')}}>1111</Text>
+            closeOnSlideDown={false}
+            show={showPageContainer} round={true} overlay={true} position='bottom'
+            onBeforeLeave={() => { dispatch(setTabbarStatus(true)) }}
+            onAfterLeave={() => { setShowPageContainer(false); }}>
+            {
+                metricModalContent()
+            }
         </PageContainer>
         {
             isModalOpen && <Modal dismiss={closeModal} title={(metricItem as any).name}

+ 72 - 0
src/features/trackSomething/components/MetricModalChoose.scss

@@ -0,0 +1,72 @@
+.modal_content{
+    padding-bottom: 120px;
+    
+}
+
+.modal_title_view{
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    margin-top: 40px;
+}
+
+
+.modal_title1{
+    font-size: 40px;
+    line-height: 40px;
+    font-weight: bold;
+    color: #fff;
+}
+
+.modal_subtitle{
+    margin-top: 16px;
+    color: #fff;
+    opacity: 0.4;
+    font-size: 28px;
+    line-height: 28px;
+}
+
+.modal_detail{
+    margin-top: 64px;
+    margin-bottom: 40px;
+    margin-left: 46px;
+    margin-right: 46px;
+    max-height: 60vh;
+    overflow-y: scroll;
+}
+
+.modal_detail::-webkit-scrollbar {
+    // display: none;
+    width: 0;
+    height: 0;
+    color: transparent;
+}
+
+.modal_group{
+    margin-bottom: 60px;
+    display: flex;
+    flex-direction: column;
+}
+
+.modal_group_title{
+    font-size: 36px;
+    line-height: 48px;
+    font-weight: bold;
+    color: #fff;
+    opacity: 0.8;
+}
+
+.modal_item{
+    display: flex;
+    flex-direction: row;
+    height: 80px;
+    border-bottom-color: #121212;
+    border-bottom-style: solid;
+    border-bottom-width: 1px;
+    align-items: center;
+}
+
+.modal_item_text{
+    font-size: 32px;
+    line-height: 80px;
+}

+ 116 - 0
src/features/trackSomething/components/MetricModalChoose.tsx

@@ -0,0 +1,116 @@
+import { View, Text } from '@tarojs/components'
+import './MetricModalChoose.scss'
+import { alphaToHex } from '@/utils/tools'
+import { useTranslation } from 'react-i18next'
+import { useState } from 'react'
+import { IconRadio, IconRadioCheck } from '@/components/basic/Icons'
+import Taro from '@tarojs/taro'
+
+export default function Component(props: { themeColor: string, cancel: Function, confirm: Function, array: any, limit: any, orders: any }) {
+    const color = props.themeColor ? props.themeColor : '#ff0000'
+    const [list, setList] = useState(props.array)
+    const [orderList,setOrderList] = useState(props.orders)
+    const min = props.limit.min
+    const max = props.limit.max
+    const { t } = useTranslation()
+    var alpha = alphaToHex(0.4)
+
+    function cancel() {
+        props.cancel()
+    }
+
+    function confirm() {
+        // var datas: any = []
+        // list.map(item => {
+        //     item.items.map(data => {
+        //         if (data.is_following) {
+        //             datas.push(data as any)
+        //         }
+        //     })
+        // })
+
+        if (min > orderList.length) {
+            Taro.showToast({
+                icon: 'none',
+                title: t('feature.common.toast.min_value'),
+            })
+            return
+        }
+        if (max < orderList.length) {
+            Taro.showToast({
+                icon: 'none',
+                title: t('feature.common.toast.max_value'),
+            })
+            return
+        }
+
+        props.confirm(orderList)
+    }
+
+    function tapItem(obj) {
+        var check = !obj.is_following
+        if (check){
+            orderList.push({
+                name:obj.name,
+                code:obj.code
+            })
+        }
+        else {
+            for (var i =0;i<orderList.length;i++){
+                if (orderList[i].code == obj.code){
+                    orderList.splice(i,1)
+                }
+            }
+        }
+        for (var i = 0; i < list.length; i++) {
+            for (var j = 0; j < list[i].items.length; j++) {
+                var temp = list[i].items[j]
+                if (obj.code == temp.code) {
+                    temp.is_following = check
+                }
+            }
+        }
+        
+        setList(JSON.parse(JSON.stringify(list)))
+        setOrderList(JSON.parse(JSON.stringify(orderList)))
+    }
+
+
+    return <View className='modal_content'>
+        <View className='modal_title_view'>
+            <Text className='modal_title1'>{t('feature.track_something.metric.choose_metric')}</Text>
+            <Text className='modal_subtitle'>按需选择自己常用的指标</Text>
+        </View>
+        <View className='modal_detail'>
+            {
+                list.map((item, index) => {
+                    return <View className='modal_group' key={index}>
+                        <Text className='modal_group_title'>{item.name}</Text>
+                        {
+                            item.items.map((obj, i) => {
+                                return <View className='modal_item' onClick={() => tapItem(obj)}>
+                                    {
+                                        obj.is_following ? <IconRadioCheck width={16} color='#fff' /> : <IconRadio width={16} color='#fff' />
+                                    }
+
+                                    <Text className='modal_item_text' style={{ color: color, marginLeft: 10 }}>{obj.name}</Text>
+                                </View>
+                            })
+                        }
+                    </View>
+                })
+            }
+        </View>
+        <View className='modal_operate'>
+            <View className='modal_btn' style={{ backgroundColor: color + alpha }} onClick={cancel}>
+                <Text className='modal_cancel_text' style={{ color: color }}>取消</Text>
+            </View>
+            <View className='btn_space' />
+            <View className='modal_btn' style={{ backgroundColor: color }} onClick={confirm}>
+                <Text className='modal_confirm_text' style={{ color: '#000' }}>下一步</Text>
+            </View>
+
+
+        </View>
+    </View>
+}

+ 3 - 0
src/features/trackSomething/components/MetricModalOrder.scss

@@ -0,0 +1,3 @@
+.modal_content{
+    padding-bottom: 120px;
+}

+ 40 - 0
src/features/trackSomething/components/MetricModalOrder.tsx

@@ -0,0 +1,40 @@
+import { View, Text } from '@tarojs/components'
+import './MetricModalOrder.scss'
+import { alphaToHex } from '@/utils/tools'
+import { useTranslation } from 'react-i18next'
+import { useState } from 'react'
+
+export default function Component(props: { themeColor: string, cancel: Function, confirm: Function, array: any }) {
+    var color = props.themeColor ? props.themeColor : '#ff0000'
+    const [list, setList] = useState(props.array)
+    const { t } = useTranslation()
+    var alpha = alphaToHex(0.4)
+
+    function cancel() {
+        props.cancel()
+    }
+
+    function confirm() {
+        props.confirm()
+    }
+    return <View className='modal_content'>
+        <View className='modal_title_view'>
+            <Text className='modal_title1'>{t('feature.track_something.metric.order')}</Text>
+            <Text className='modal_subtitle'>长按可拖动排序</Text>
+        </View>
+        <View className='modal_detail'>
+
+        </View>
+        <View className='modal_operate'>
+            <View className='modal_btn' style={{ backgroundColor: color + alpha }} onClick={cancel}>
+                <Text className='modal_cancel_text' style={{ color: color }}>{global.metricAdd?'上一步':'取消'}</Text>
+            </View>
+            <View className='btn_space' />
+            <View className='modal_btn' style={{ backgroundColor: color }} onClick={confirm}>
+                <Text className='modal_confirm_text' style={{ color: '#000' }}>{global.metricAdd?'完成':'确定'}</Text>
+            </View>
+
+
+        </View>
+    </View>
+}

+ 2 - 1
src/services/http/api.js

@@ -1,4 +1,4 @@
-let online = true;
+let online = false;
 export let baseUrl = online ? 'https://api2.fast.liveplus.fun' : 'https://api.fast.dev.liveplus.fun';
 export let imgUrl = online
     ? 'https://api.fast.liveplus.fun/static/image/'
@@ -40,6 +40,7 @@ export const API_ACTIVITY_RECORDS = `${baseUrl}/api/activity/records`
 export const API_METRIC_CARDS = `${baseUrl}/api/metric/cards`
 export const API_METRIC_RECORDS = `${baseUrl}/api/metric/records`
 export const API_METRIC_GROUPS = `${baseUrl}/api/metric/groups`
+export const API_METRIC_FOLLOWS = `${baseUrl}/api/metric/follows`
 
 //journal
 

+ 14 - 2
src/services/trackSomething.tsx

@@ -1,5 +1,5 @@
 
-import { API_ACTIVITY_CARDS, API_ACTIVITY_RECORDS, API_METRIC_CARDS, API_METRIC_GROUPS, API_METRIC_RECORDS, API_UPLOAD_STEPS } from './http/api';
+import { API_ACTIVITY_CARDS, API_ACTIVITY_RECORDS, API_METRIC_CARDS, API_METRIC_FOLLOWS, API_METRIC_GROUPS, API_METRIC_RECORDS, API_UPLOAD_STEPS } from './http/api';
 import { request } from './http/request';
 
 export const uploadSteps = (params) => {
@@ -138,4 +138,16 @@ export const metricRecords = (params) => {
             // dispatch(loginSuccess(res));
         })
     })
-}
+}
+
+export const metricFollows = (params) => {
+    return new Promise((resolve) => {
+        request({
+            url: API_METRIC_FOLLOWS, method: 'POST', data: { ...params }
+        }).then(res => {
+            resolve(res);
+            // dispatch(loginSuccess(res));
+        })
+    })
+}
+

+ 8 - 0
src/utils/types.ts

@@ -59,4 +59,12 @@ export enum CheckBoxType {
     check = 'check',
     arrow = 'arrow',
     dot = 'dot'
+}
+
+export enum MetricModalType {
+    none = 'none',
+    choose = 'choose',
+    order = 'order',
+    add = 'add',
+    time = 'time',
 }