Leon 1 jaar geleden
bovenliggende
commit
85b1bbff80

+ 1 - 0
src/_health/components/post_moment_time.scss

@@ -37,4 +37,5 @@
     justify-content: center;
     background-color: #B2B2B21A;
     color: #000;
+    
 }

+ 3 - 0
src/_health/components/post_moment_time.tsx

@@ -143,6 +143,9 @@ export default function PostMomentTime(props: {
 
     function getMinTimestamp() {
         var scenario = getScenario(health.windows, health.mode)
+        if (!scenario || !scenario.picker_min_timestamp){
+            return new Date().getTime()-24*3600*1000
+        }
         return scenario.picker_min_timestamp
     }
 

+ 18 - 0
src/_record/pages/log_record.config.ts

@@ -0,0 +1,18 @@
+export default definePageConfig({
+    // // "lazyCodeLoading": "requiredComponents",
+    // // "componentFramework": "glass-easel",
+    // // "renderer": "skyline",
+    // // "rendererOptions": {
+    // //     "skyline": {
+    // //         "disableABTest": true,
+    // //         "defaultDisplayBlock": true
+    // //     }
+    // // },
+    // "usingComponents": {
+    //     "recycle-view": "../../components/miniprogram-recycle-view/recycle-view",
+    //     "recycle-item": "../../components/miniprogram-recycle-view/recycle-item"
+    // },
+    // "disableScroll": true,
+    "navigationStyle": "custom",
+    enablePageMeta:true
+})

+ 158 - 0
src/_record/pages/log_record.scss

@@ -0,0 +1,158 @@
+// page {
+//     background: linear-gradient(to bottom, #F0CABF, #E1CDEE)
+// }
+
+.main_bg {
+    position: fixed;
+    left: 0;
+    top: 0;
+    width: 100vw;
+    height: 100vh;
+    z-index: -1;
+}
+
+.navi_bar {
+    position: fixed;
+    left: 0;
+    right: 0;
+    top: 0;
+}
+
+.operate_bg {
+    display: flex;
+    flex-direction: row;
+    flex-wrap: wrap;
+    width: 750px;
+    box-sizing: border-box;
+    padding-left: 44px;
+    margin-top: 64px;
+}
+
+.operate_item {
+    margin-right: 32px;
+    margin-bottom: 32px;
+    width: 202px;
+    height: 240px;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    border-radius: 24px;
+    background-color: rgba($color: #fff, $alpha: 0.25);
+}
+
+.input_form {
+    width: 670px;
+    height: 360px;
+    border-radius: 24px;
+    background-color: rgba($color: #fff, $alpha: 0.25);
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+}
+
+.input_content {
+    width: 578px;
+    height: 128px;
+    border-radius: 12px;
+    margin-top: 60px;
+    text-align: center;
+    background-color: #fff;
+}
+
+.form_btns {
+    display: flex;
+    flex-direction: row;
+    margin-top: 20px;
+    margin-left: 46px;
+    margin-right: 46px;
+    width: 578px;
+    height: 100px;
+}
+
+.form_cancel {
+    flex: 1;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+}
+
+.form_confirm {
+    color: rgba($color: #000, $alpha: 0.4);
+}
+
+.sel_tag {
+    height: 64px;
+    border-radius: 32px;
+    background-color: rgba($color: #fff, $alpha: 0.20);
+    padding-left: 24px;
+    display: flex;
+    flex-direction: row;
+    align-items: center;
+    padding-right: 16px;
+    margin-left: 40px;
+}
+
+.textarea2 {
+    height: 400px;
+    width: 750px;
+    box-sizing: border-box;
+    padding: 30px 56px;
+    margin-top: 24px;
+    margin-bottom: 30px;
+}
+
+.cover {
+    width: 155px;
+    height: 155px;
+    background-color: #F5F5F5;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    border-radius: 0px;
+    overflow: hidden;
+    margin-right: 20px;
+    margin-bottom: 20px;
+    position: relative;
+}
+
+.cover_del {
+    position: absolute;
+    right: 0;
+    top: 0;
+    width: 52px;
+    height: 52px;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+}
+
+.cover_del_btn {
+    width: 28px;
+    height: 28px;
+    border-radius: 15px;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    background-color: #66666680;
+    flex-shrink: 0;
+}
+
+.form{
+    display: flex;
+    flex-direction: row;
+    flex-wrap: wrap;
+    margin-left: 96px;
+    margin-bottom: 54px;
+    width: 80%;
+}
+
+.time_view{
+    position: relative;
+    display: flex;
+    flex-direction: row;
+    align-items: center;
+    margin-top: 100px;
+    margin-left: 56px;
+    padding-right: 28px;
+    height: 108px;
+}

+ 560 - 3
src/_record/pages/log_record.tsx

@@ -1,5 +1,562 @@
-import { View, Image } from "@tarojs/components";
+import { View, Image, PageMeta, NavigationBar, Input, Textarea } from "@tarojs/components";
+import './log_record.scss'
+import { useEffect, useState } from "react";
+import Taro, { useRouter } from "@tarojs/taro";
+import { rpxToPx } from "@/utils/tools";
+import { IconArrow, IconClose } from "@/components/basic/Icons";
+import { MainColorType } from "@/context/themes/color";
+import { useTranslation } from "react-i18next";
+import showAlert from "@/components/basic/Alert";
+import showActionSheet from "@/components/basic/ActionSheet";
+import { baseUrl } from "@/services/http/api";
+import { checkAuthorized } from "@/utils/check_authorized";
+import NewButton, { NewButtonType } from "@/_health/base/new_button";
+import dayjs from "dayjs";
+import { TimeFormatter } from "@/utils/time_format";
+import { useSelector } from "react-redux";
+import { createMoment, updateMoment } from "@/services/health";
+import PostMomentTime from "@/_health/components/post_moment_time";
 
-export default function LogRecord(){
-    return <View></View>
+let useRoute;
+let useNavigation;
+let scenario = '';
+if (process.env.TARO_ENV == 'rn') {
+    useRoute = require("@react-navigation/native").useRoute
+    useNavigation = require("@react-navigation/native").useNavigation
+}
+export default function LogRecord() {
+    const systemInfo: any = Taro.getWindowInfo ? Taro.getWindowInfo() : Taro.getSystemInfoSync();
+    const navigationBarHeight = systemInfo.statusBarHeight + 44;
+    const scale = '?x-oss-process=image/format,jpg/resize,w_400'
+    const long = useSelector((state: any) => state.long);
+    const health = useSelector((state: any) => state.health);
+    const [pics, setPics] = useState<any>([])
+    const [title, setTitle] = useState('')
+    const [desc, setDesc] = useState('')
+    const [step, setStep] = useState(0)
+    const { t } = useTranslation()
+
+    const [time, setTime] = useState(dayjs().format('HH:mm'))
+    const [selDate, setSelDate] = useState(dayjs().format('YYYY-MM-DD'))
+
+    const [enterTimestmap] = useState(new Date().getTime())
+    const [posting, setPosting] = useState(false)
+    const [showTimePicker, setShowTimePicker] = useState(false)
+
+
+
+    let router
+    let navigation;
+    if (useNavigation) {
+        navigation = useNavigation()
+    }
+
+    if (process.env.TARO_ENV == 'rn') {
+        router = useRoute()
+    }
+    else {
+        router = useRouter()
+    }
+
+    const { event_id, is_temp, schedule_id } = router.params
+
+    const moment = router.params.moment ? JSON.parse(router.params.moment) : null
+
+    const window = router.params.window ?? health.mode
+
+    useEffect(() => {
+        console.log('sss')
+        // Taro.setBackgroundColor({
+        //     backgroundColor:'red'
+        // })
+    }, [])
+
+    function tapPic() {
+        //, t('health.delete')
+        showActionSheet({
+            title: '',
+            itemList: [t('health.choose_photo'), t('health.import_wechat'), t('health.camera')],
+            success: function (res) {
+                switch (res) {
+                    case 0:
+                        addImage(false)
+                        break;
+                    case 1:
+                        Taro.chooseMessageFile({
+                            count: 9 - pics.length,
+                            type: 'image',
+                            success: async function (res) {
+                                const results = await Promise.all(res.tempFiles.map(getImageInfo));
+                                chooseSuccess(results, true)
+                            },
+                            fail(res) {
+                            },
+                        })
+                        break;
+                    case 2:
+                        addImage(true)
+                        break;
+                    case 3:
+                        // setImgUrl('')
+                        break;
+                }
+            }
+        })
+    }
+
+    function addImage(isCamera) {
+        var source: any = isCamera ? ['camera'] : ['album']
+        console.log(source)
+        Taro.chooseMedia({
+            count: 9 - pics.length,
+            sizeType: ['compressed'],
+            mediaType: ['image'],
+            sourceType: source,
+            success: async function (res) {
+                const results = await Promise.all(res.tempFiles.map(getImageInfo));
+
+
+                chooseSuccess(results, true)
+                checkAuthorized()
+            },
+            fail: function (res) {
+            }
+        })
+    }
+
+    async function chooseSuccess(res, isAlbum) {
+        console.log('选择图片', res)
+        // const filePaths = res.map(file => file.path
+        //     // process.env.TARO_ENV === 'rn' || isFilePath ? file.path : file.tempFilePath
+        // )
+        Taro.showLoading({
+            title: t('health.uploading')
+        })
+
+        try {
+            const uploadedUrls = await Promise.all(res.map(path => uploadFile2(path, isAlbum ? 'album' : 'camera')))
+            setPics([...pics, ...uploadedUrls])
+            Taro.hideLoading()
+        } catch (error) {
+            console.error('Error uploading files:', error)
+            Taro.hideLoading()
+        }
+    }
+
+    function uploadFile2(obj: any, source: string): Promise<string> {
+        return new Promise((resolve, reject) => {
+            var path = obj.path
+            const dot = path.lastIndexOf('.')
+            const fileExt = dot > 0 ? path.substring(dot) : ''
+            Taro.request({
+                method: 'GET',
+                url: `${baseUrl}/api/thirdparty/aliyun/oss-form-upload`,
+                header: {
+                    'Authorization': 'bearer ' + global.token
+                },
+                data: {
+                    type: 'FOOD_JOURNAL',
+                    file_ext: fileExt
+                },
+                success: (rsp) => {
+                    if (rsp.statusCode !== 200) {
+                        reject(new Error(t('health.networkError')))
+                        return
+                    }
+                    Taro.uploadFile({
+                        url: rsp.data.upload_url,
+                        filePath: path,
+                        name: 'file',
+                        formData: rsp.data.fields,
+                        success: () => {
+                            var temp = JSON.parse(JSON.stringify(obj))
+                            temp.url = rsp.data.view_url
+                            // resolve(rsp.data.view_url)
+                            resolve(temp)
+                        },
+                        fail: (error) => {
+
+                            reject(error)
+                        }
+                    })
+                },
+                fail: reject
+            })
+        })
+    }
+
+
+    const getImageInfo = (src) => {
+        const { tempFilePath, path } = src
+        return new Promise((resolve) => {
+            Taro.getImageInfo({
+                src: tempFilePath ? tempFilePath : path,
+                success: (result) => resolve({
+                    height: result.height,
+                    width: result.width,
+                    orientation: result.orientation,
+                    path: result.path,
+                    type: result.type
+                }),
+                fail: (error) => resolve({
+                    height: 1024,
+                    width: 1024,
+                    orientation: 'up',
+                    path: tempFilePath,
+                    type: 'unknown'
+                }),
+            });
+        });
+    };
+
+    function save() {
+        if (router.params.edit) {
+            edit()
+            return
+        }
+        // var str = selDate + ' ' + time + ':' + dayjs(enterTimestmap).format('ss')
+        // console.log('系统时间',new Date())
+        // console.log('提交日期格式',str)
+        // console.log('转成日期',new Date(str))
+
+        // var date = new Date(selDate + 'T' + time + ':' + dayjs(enterTimestmap).format('ss'))
+        var date = TimeFormatter.stringToDate(selDate, time)
+        date.setMilliseconds(new Date(enterTimestmap).getMilliseconds())
+
+
+        var params: any = {
+            schedule_id: schedule_id,
+            title: title,
+            description: desc,
+            start: {
+                date: dayjs(date.getTime()).format('YYYYMMDD'),
+                timestamp: date.getTime()
+            }
+        }
+
+        if (router.params.join_id) {
+            params.join_key = router.params.join_id
+        }
+
+        if (pics.length > 0) {
+            var picList: any = []
+            pics.map((item) => {
+                picList.push({
+                    url: item.url,
+                    type: item.url.indexOf('mp4') != -1 ? 'video' : 'image',
+                    source: 'album',
+                    width: item.width,
+                    height: item.height,
+                    format: item.format
+                })
+            })
+            params.media = picList
+        }
+
+
+        // if (imgUrl.length > 0) {
+        //     params.media = [{
+        //         url: imgUrl,
+        //         type: imgUrl.indexOf('mp4') != -1 ? 'video' : 'image',
+        //         source: 'album'
+        //     }]
+        // }
+        if (event_id && event_id != 'undefined') {
+            params.event_id = event_id
+        }
+
+        if (is_temp) {
+            params.event = window == 'EAT' ? 'EAT_CUSTOM' : 'ACTIVE_CUSTOM'
+        }
+        params.op_page = window == 'EAT' ? 'HOME_EAT' : 'HOME_ACTIVE'
+        // if (moment.target && moment.target.duration) {
+        //     params.duration = durationT//moment.target.duration
+        // }
+
+
+
+        params.extra = {
+            set_time: global.set_time ? global.set_time : new Date().getTime(),
+            confirm_time: new Date().getTime()
+        }
+        console.log('打卡提交数据', params)
+        if (posting) return
+        setPosting(true)
+        createMoment(params).then(res => {
+            // setTimeout(() => {
+            setPosting(false)
+            Taro.eventCenter.trigger('refreshMoments', '')
+            // }, 1000)
+
+            if (process.env.TARO_ENV == 'weapp') {
+                // Taro.navigateBack();
+                Taro.redirectTo({
+                    url: '/_health/pages/post_result?data=' + JSON.stringify(res)
+                })
+                // Taro.navigateTo({
+                //     url:'/_health/pages/post_result?data=' + JSON.stringify(res)
+                // })
+            }
+
+            Taro.disableAlertBeforeUnload({
+
+            })
+
+            global.refreshWindow()
+            global.refreshHistory()
+
+            if (global.postMomentSuccess) {
+                global.postMomentSuccess()
+            }
+        }).catch(e => {
+            debugger
+            setPosting(false)
+        })
+    }
+
+    function edit() {
+        // var date = new Date(selDate + 'T' + time + ':' + dayjs(enterTimestmap).format('ss'))
+        var date = TimeFormatter.stringToDate(selDate, time)
+        var params: any = {
+            schedule_id: schedule_id,
+            title: title,
+            description: desc,
+            start: {
+                date: dayjs(date.getTime()).format('YYYYMMDD'),
+                timestamp: date.getTime()
+            }
+        }
+
+
+        // if (imgUrl.length > 0) {
+        //     params.media = [{
+        //         url: imgUrl,
+        //         type: imgUrl.indexOf('mp4') != -1 ? 'video' : 'image',
+        //         source: 'album'
+        //     }]
+        // }
+        if (pics.length > 0) {
+            var picList: any = []
+            pics.map((item) => {
+                picList.push({
+                    url: item.url,
+                    type: item.url.indexOf('mp4') != -1 ? 'video' : 'image',
+                    source: 'album',
+                    width: item.width,
+                    height: item.height,
+                    format: item.format
+                })
+            })
+            params.media = picList
+        }
+        else {
+            params.media = []
+        }
+        if (event_id && event_id != 'undefined') {
+            params.event_id = event_id
+        }
+
+        if (is_temp) {
+            params.event = window == 'EAT' ? 'EAT_CUSTOM' : 'ACTIVE_CUSTOM'
+        }
+
+
+
+        params.extra = {
+            set_time: global.set_time ? global.set_time : new Date().getTime(),
+            confirm_time: new Date().getTime()
+        }
+
+        if (posting) return
+        setPosting(true)
+        updateMoment(params, router.params.id).then(res => {
+            Taro.eventCenter.trigger('refreshMoments', '')
+            setPosting(false)
+            if (process.env.TARO_ENV == 'weapp') {
+                Taro.navigateBack();
+            }
+
+            global.refreshWindow()
+            global.refreshHistory()
+            global.refreshMoment()
+        }).catch(e => {
+            setPosting(false)
+        })
+    }
+
+    function getDate() {
+        var sel = dayjs(selDate)
+        var now = dayjs().format('YYYY-MM-DD')
+        const yesterday = dayjs().subtract(1, 'day');
+        if (sel.format('YYYY-MM-DD') == now) {
+            return ''
+        }
+        if (yesterday.format('YYYY-MM-DD') == sel.format('YYYY-MM-DD')) {
+            return global.language == 'en' ? 'Yesterday ' : '昨天 '
+        }
+        else {
+            return global.language == 'en' ? sel.format('MMM D ') : sel.format('MMMD日 ')
+        }
+    }
+
+    return <View style={{ position: 'relative' }}>
+        <View className="main_bg" style={{ background: 'linear-gradient(to bottom, #F0CABF, #E1CDEE)' }} />
+        <View className="navi_bar" style={{ height: navigationBarHeight }}>
+            <View style={{
+                position: 'absolute',
+                left: 0,
+                right: 0,
+                bottom: 0,
+                height: 44,
+                display: 'flex',
+                alignItems: 'center',
+                justifyContent: 'center'
+            }}>
+                <Image src={require('@assets/_health/navi_back.png')} style={{
+                    position: 'absolute',
+                    width: rpxToPx(92),
+                    height: rpxToPx(64),
+                    left: 0,
+                    top: 22 - rpxToPx(32)
+                }}
+                    onClick={() => {
+                        Taro.navigateBack()
+                    }}
+                />
+                {/* <View className="h36 bold">upcoming fast</View> */}
+            </View>
+        </View>
+        <View style={{ height: navigationBarHeight }} />
+        {
+            step == 0 && <View style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', marginTop: rpxToPx(152) }}>
+                <Image src={require('@assets/_health/eat.png')} style={{ width: rpxToPx(96), height: rpxToPx(96) }} />
+                <View className="h50 bold">选择打卡的餐次</View>
+                <View className="operate_bg">
+                    <View className="operate_item h30 bold" onClick={() => {
+                        setStep(2)
+                    }}>早餐</View>
+                    <View className="operate_item h30 bold" onClick={() => {
+                        setStep(1)
+                    }}>自定义</View>
+                </View>
+            </View>
+        }
+        {
+            step == 1 && <View style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', marginTop: rpxToPx(152) }}>
+                <View className="input_form">
+                    <Input className="input_content h36" placeholder="请输入自定义名称" value={title}
+                        onInput={(e: any) => {
+                            setTitle(e.target.value)
+                        }} />
+                    <View className="form_btns">
+                        <View className="form_cancel h30 bold" onClick={() => {
+                            setStep(0)
+                        }}>取消</View>
+                        <View className={title.length == 0 ? 'form_cancel form_confirm h30 bold' : 'form_cancel h30 bold'}
+                            onClick={() => {
+                                if (title.length == 0) return
+                                setStep(2)
+                            }}
+                        >确定</View>
+                    </View>
+                </View>
+            </View>
+        }
+        {
+            step == 2 && <View>
+                <View style={{ display: 'flex', flexDirection: 'row' }} onClick={()=>{
+                    setStep(0)
+                }}>
+                    <View className="sel_tag h34 bold">
+                        {title}
+                        <View style={{ width: rpxToPx(6) }} />
+                        <IconArrow width={rpxToPx(34)} color={MainColorType.g02} />
+                    </View>
+                </View>
+
+                <Textarea placeholder={t('health.add_text')} className="textarea2 h44 bold"
+                    placeholder-style="color:rgba(0,0,0,0.2)"
+                    value={desc}
+                    onInput={e => {
+                        setDesc(e.detail.value)
+                    }} />
+                <View className="form">
+                    {
+                        pics.map((item, index) => {
+                            return <View className="cover" key={index}>
+                                <Image src={item.url + scale} mode="aspectFill" className="cover" style={{
+                                    margin: 0
+                                }} key={index} onClick={() => {
+                                    Taro.previewImage({
+                                        current: pics[index].url,
+                                        urls: pics.map(file => file.url)
+                                    })
+                                }} />
+                                <View className="cover_del" onClick={() => {
+                                    showAlert({
+                                        title: t('health.del_title'),
+                                        content: '',
+                                        cancelText: t('health.del_cancel'),
+                                        confirmText: t('health.del_confirm'),
+                                        showCancel: true,
+                                        confirm: () => {
+                                            var array = JSON.parse(JSON.stringify(pics))
+                                            array.splice(index, 1)
+                                            setPics(array)
+                                        }
+                                    })
+                                }}>
+                                    <View className="cover_del_btn">
+                                        <IconClose width={10} height={10} color="#fff" />
+                                    </View>
+                                </View>
+                            </View>
+                        })
+                    }
+                    {
+                        pics.length < 9 && <View onClick={tapPic} className="cover" style={{}}><Image src={require('@assets/_health/camera.png')} style={{ width: 40, height: 40 }} /></View>
+                    }
+                </View>
+                <View className="time_view" onClick={() => {
+                    setShowTimePicker(true)
+                }}>
+                    
+                    <View className="h30" style={{ opacity: 0.3 }}>时间</View>
+                    <View style={{ flex: 1 }} />
+                    <View className="h30" style={{ opacity: 0.3 }}>{getDate() + time}</View>
+                    <IconArrow width={rpxToPx(34)} color={MainColorType.g02} />
+                    <View className="border_footer_line" style={{left:rpxToPx(48)}}/>
+                </View>
+                <View style={{ flex: 1 }} />
+
+                <View className="main_footer" style={{ backgroundColor: 'transparent' }}><NewButton
+                    type={NewButtonType.fill}
+                    color={MainColorType.orange}
+                    width={rpxToPx(646)}
+                    height={rpxToPx(96)}
+                    title={t('health.log_moment')}
+                    onClick={save}
+                /></View>
+
+            </View>
+        }
+        {
+            showTimePicker && <PostMomentTime
+                title={t('health.log_time_title')}
+                time={time}
+                date={selDate}
+                isTemp={is_temp}
+                moment={moment}
+                onChange={(e) => {
+                    const { date, duration, time, isYesterday } = e;
+                    setTime(time)
+                    setSelDate(date)
+                    // setIsYesterday(isYesterday)
+                    // setDurationT(duration)
+                    setShowTimePicker(false)
+                }} dismiss={() => {
+                    setShowTimePicker(false)
+                }} />
+        }
+    </View>
 }

+ 22 - 0
src/_record/pages/time_record.scss

@@ -7,4 +7,26 @@ page {
     left: 0;
     right: 0;
     top: 0;
+}
+
+.time_card_bg {
+    display: flex;
+    flex-direction: row;
+    padding-left: 40px;
+    padding-right: 40px;
+    justify-content: space-between;
+    box-sizing: border-box;
+    width: 750px;
+    margin-top: 170px;
+}
+
+.time_card {
+    width: 320px;
+    border-radius: 24px;
+    background-color: rgba($color: #ffffff, $alpha: 0.25);
+    padding: 30px 0;
+    box-sizing: border-box;
+    display: flex;
+    flex-direction: column;
+    align-items: center;
 }

+ 56 - 6
src/_record/pages/time_record.tsx

@@ -4,15 +4,24 @@ import Taro from "@tarojs/taro";
 import { rpxToPx } from "@/utils/tools";
 import Rings, { RingCommon, BgRing, TargetRing, CurrentDot } from "@/features/trackTimeDuration/components/Rings";
 import { MainColorType } from "@/context/themes/color";
+import NewButton, { NewButtonType } from "@/_health/base/new_button";
+import { useState } from "react";
+import NewDateTimePicker from "@/_health/base/new_date_time_picker";
+import dayjs from "dayjs";
 
 export default function TimeRecord() {
     const systemInfo: any = Taro.getWindowInfo ? Taro.getWindowInfo() : Taro.getSystemInfoSync();
     const navigationBarHeight = systemInfo.statusBarHeight + 44;
 
+    const [enterTime] = useState(new Date().getTime())
+
+    const [showDatePicker, setShowDatePicker] = useState(false)
+    const [showDurationPicker, setShowDurationPicker] = useState(false)
+
     const common: RingCommon = {
         useCase: 'ChooseScenario',
-        radius: 27,
-        lineWidth: 12,
+        radius: 110,
+        lineWidth: 22,
         isFast: true,
         status: 'WAIT_FOR_START'
     }
@@ -42,9 +51,9 @@ export default function TimeRecord() {
 
         return {
             color: MainColorType.eat,
-            lineWidth: 2,
+            lineWidth: 6,
             borderColor: '#F5F5F5',
-            offset: 0
+            offset: 6
         }
 
     }
@@ -61,7 +70,15 @@ export default function TimeRecord() {
         />
     }
 
-    return <View>
+    function tapStart() {
+        setShowDatePicker(true)
+    }
+
+    function tapGoal() {
+        setShowDurationPicker(true)
+    }
+
+    return <View style={{ display: 'flex', flexDirection: 'column', alignItems: 'center' }}>
         <View className="navi_bar" style={{ height: navigationBarHeight }}>
             <View style={{
                 position: 'absolute',
@@ -88,8 +105,41 @@ export default function TimeRecord() {
             </View>
         </View>
         <View style={{ height: navigationBarHeight }} />
+        <View>
+            {
+                ring()
+            }
+        </View>
+
+        <View className="time_card_bg">
+            <View className="time_card" onClick={tapStart}>
+                <View className="h30" style={{ opacity: 0.4 }}>Start</View>
+                <View className="h44 bold" style={{ marginTop: rpxToPx(12) }}>10:00</View>
+            </View>
+            <View className="time_card" onClick={tapGoal}>
+                <View className="h30" style={{ opacity: 0.4 }}>Goal</View>
+                <View className="h44 bold" style={{ marginTop: rpxToPx(12) }}>10:00</View>
+            </View>
+        </View>
+        <NewButton
+            onClick={() => { }}
+            type={NewButtonType.fill}
+            color={MainColorType.orange}
+            width={rpxToPx(669)}
+            height={rpxToPx(96)}
+            title="开始断食"
+        />
         {
-            ring()
+            showDatePicker && <NewDateTimePicker date={dayjs().format('YYYY-MM-DD')} count={1} time={dayjs().format('HH:mm')}
+                minTimestamp={ new Date().getTime() - 24 * 3600 * 1000}
+                maxTimestamp={ new Date().getTime()}
+                onChange={(e) => {
+                    // if (props.dateChange)
+                    //     props.dateChange(e[0])
+                    // if (props.timeChange)
+                    //     props.timeChange(e[1])
+                    // props.change(e)
+                }} color={MainColorType.orange} />
         }
     </View>
 }

+ 5 - 0
src/app.scss

@@ -460,6 +460,11 @@ page {
     justify-content: center;
 }
 
+.h60{
+    font-size: 60px;
+    line-height: 72px;
+}
+
 .h50 {
     font-size: 50px;
     line-height: 60px;

+ 19 - 0
src/components/basic/Icons.tsx

@@ -686,4 +686,23 @@ export const IconMenu = (props: { width: number, color: string }) => {
     </g>
 </svg>`
     return Icon(props.width, props.width, icon);
+}
+
+export const IconNext = (props: { width: number, color: string }) => {
+    const icon = `<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none"
+    version="1.1" width="36" height="36" viewBox="0 0 36 36">
+    <defs>
+        <clipPath id="master_svg0_2314_69697">
+            <rect x="0" y="0" width="36" height="36" rx="0" />
+        </clipPath>
+    </defs>
+    <g clip-path="url(#master_svg0_2314_69697)">
+        <g>
+            <path
+                d="M28.813903125,19.87505L16.676203125,32.01265C15.944003125,32.74485,15.944003125,33.93205,16.676203125,34.66425C17.408503125,35.39655,18.595703125,35.39655,19.327903125,34.66425L34.668303125,19.32385C35.400503125,18.59165,35.400503125,17.40445,34.668303125,16.67225L19.325803125,1.329731C18.593603125,0.597498,17.406403125,0.597498,16.674203125,1.329732C15.941903125,2.06196,15.941903125,3.24915,16.674203125,3.98138L28.817803125,16.12505L2.658203125,16.12505C1.622669125,16.12505,0.783203125,16.96445,0.783203125,18.00005C0.783203125,19.03555,1.622669125,19.87505,2.658203125,19.87505L28.813903125,19.87505Z"
+                fill-rule="evenodd" fill="${props.color}" fill-opacity="1" />
+        </g>
+    </g>
+</svg>`
+    return Icon(props.width, props.width, icon);
 }

+ 1 - 0
src/context/themes/color.tsx

@@ -34,6 +34,7 @@ export enum MainColorType {
     error = '#ff0000',
     success = '#00b218',
     blue = '#0080ff',
+    orange = '#FF5719',
 
     black = '#000000',
     white = '#ffffff',

+ 2 - 0
src/pages/clock/Clock.tsx

@@ -256,6 +256,8 @@ export default function Clock() {
     if (!loaded)
         return <View />
 
+    return <ClockIndex />
+
     return <View style={{ flex: 1, position: 'relative' }}>
         <View style={{ height: navigationBarHeight, backgroundColor: MainColorType.g05 }} />
         <View className="navi-bar" style={{ height: navigationBarHeight, zIndex: 1000, backgroundColor: showCalendar ? '#fff' : MainColorType.g05 }}>

+ 24 - 0
src/pages/clock/ClockIndex.scss

@@ -0,0 +1,24 @@
+page {
+    background: linear-gradient(to bottom, #F0CABF, #E1CDEE)
+}
+
+.operate_panel {
+    display: flex;
+    flex-direction: row;
+    flex-wrap: wrap;
+    padding-left: 40px;
+    padding-right: 40px;
+    justify-content: space-between;
+}
+
+.operate_card {
+    background-color: rgba($color: #ffffff, $alpha: 0.25);
+    width: 320px;
+    height: 260px;
+    border-radius: 24px;
+    margin-bottom: 30px;
+    display: flex;
+    flex-direction: column;
+    box-sizing: border-box;
+    padding: 36px 40px;
+}

+ 40 - 5
src/pages/clock/ClockIndex.tsx

@@ -1,10 +1,45 @@
 import { jumpPage } from "@/features/trackTimeDuration/hooks/Common";
 import { View } from "@tarojs/components";
+import './ClockIndex.scss'
+import TabBar from "@/components/navigation/TabBar";
+import { IconNext } from "@/components/basic/Icons";
+import { rpxToPx } from "@/utils/tools";
+
 
 export default function ClockIndex() {
-    return <View 
-    onClick={()=>{
-        jumpPage('/_record/pages/time_record')
-    }}
-    style={{height:100,width:100,backgroundColor:'pink'}}>demo</View>
+    return <View><View
+        onClick={() => {
+            jumpPage('/_record/pages/time_record')
+        }}
+        style={{ height: 100, width: 100, backgroundColor: 'pink' }}>demo</View>
+        <View className="h60 bold" style={{marginLeft:rpxToPx(52)}}>早上好</View>
+        <View className="h44 bold" style={{marginLeft:rpxToPx(52),marginTop:rpxToPx(66),marginBottom:rpxToPx(58)}}>打卡</View>
+        <View className="operate_panel">
+            <View className="operate_card" onClick={()=>{
+                jumpPage('/_record/pages/log_record')
+            }}>
+                <View className="h36 bold">饮食</View>
+                <View style={{ flex: 1 }} />
+                <View style={{display:'flex',justifyContent:'space-between',alignItems:'center'}}>
+                    <IconNext width={rpxToPx(36)} color="#000" />
+                    <IconNext width={rpxToPx(36)} color="#000" />
+                </View>
+            </View>
+            <View className="operate_card" onClick={()=>{
+                jumpPage('/_record/pages/log_record')
+            }}></View>
+            <View className="operate_card" onClick={()=>{
+                jumpPage('/_record/pages/time_record')
+            }}></View>
+            <View className="operate_card" onClick={()=>{
+                jumpPage('/_record/pages/time_record')
+            }}></View>
+
+            <View className="operate_card" onClick={()=>{
+                jumpPage('/_record/pages/metric_record')
+            }}></View>
+        </View>
+        {
+            process.env.TARO_ENV == 'weapp' && <TabBar index={0} />
+        }</View>
 }