Leon 2 年 前
コミット
ff6c130581

+ 11 - 1
src/components/basic/Icons.tsx

@@ -27,6 +27,16 @@ export const IconClear = () => {
     </View>
 }
 
+export const IconShare = (props: { width: number, height: 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="20.596546173095703" height="17.310691833496094" viewBox="0 0 20.596546173095703 17.310691833496094"><g><path d="M0.750904,17.3107C0.671866,17.3111,0.593304,17.2984,0.518404,17.2732C0.1964,17.1686,-0.0156423,16.8613,0.000903904,16.5232C0.000903904,16.4107,0.773404,5.52068,11.6934,4.66568L11.6934,0.750681C11.6931,0.445681,11.8776,0.170896,12.16,0.055638C12.4424,-0.0596205,12.7664,0.00760603,12.9797,0.225681L20.3822,7.78568C20.668,8.07731,20.668,8.54405,20.3822,8.83568L12.9797,16.3957C12.7664,16.6138,12.4424,16.681,12.16,16.5657C11.8776,16.4505,11.6931,16.1757,11.6934,15.8707L11.6934,12.0307C4.4034,12.3082,1.41465,16.9057,1.38465,16.9619C1.2472,17.1791,1.00803,17.3107,0.750904,17.3107ZM13.1934,2.58818L13.1934,5.36693C13.1937,5.77111,12.8736,6.10279,12.4697,6.11693C5.40465,6.37568,2.87715,11.0819,1.96965,14.1082C3.84465,12.4882,7.1859,10.5082,12.3984,10.5082L12.4322,10.5082C12.8464,10.5082,13.1822,10.844,13.1822,11.2582L13.1822,14.0369L18.8072,8.31443L13.1934,2.58818Z" fill="#FF7A4E" fill-opacity="1"/></g></svg>`
+    return <View style={{ width: props.width, height: props.height }}>
+        {
+            process.env.TARO_ENV == 'weapp' ? <mysvg src={icon} colors={[props.color]} /> :
+                <SvgXml xml={icon} width={props.width} height={props.width} />
+        }
+    </View>
+}
+
 export const IconRadio = (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="16" height="16" viewBox="0 0 16 16"><g><g><ellipse cx="8" cy="8" rx="7.5" ry="7.5" fill-opacity="0" stroke-opacity="1" stroke="${props.color}" fill="none" stroke-width="1"/></g></g></svg>`
     return <View style={{ width: props.width, height: props.width }}>
@@ -64,7 +74,7 @@ export const IconSwitchOff = (props: { width: number, height: number }) => {
     </View>
 }
 
-export const IconDrag = (props: { width: number,height:number }) => {
+export const IconDrag = (props: { width: number, height: number }) => {
     const icon = `<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none" version="1.1" width="16.66666603088379" height="11.666666030883789" viewBox="0 0 16.66666603088379 11.666666030883789"><g><path d="M0,0.833333C0,0.373096,0.373096,0,0.833333,0C0.833333,0,15.8333,0,15.8333,0C16.2936,0,16.6667,0.373096,16.6667,0.833333C16.6667,1.29357,16.2936,1.66667,15.8333,1.66667C15.8333,1.66667,0.833333,1.66667,0.833333,1.66667C0.373096,1.66667,0,1.29357,0,0.833333C0,0.833333,0,0.833333,0,0.833333ZM0,5.83333C0,5.3731,0.373096,5,0.833333,5C0.833333,5,15.8333,5,15.8333,5C16.2936,5,16.6667,5.3731,16.6667,5.83333C16.6667,6.29357,16.2936,6.66667,15.8333,6.66667C15.8333,6.66667,0.833333,6.66667,0.833333,6.66667C0.373096,6.66667,0,6.29357,0,5.83333C0,5.83333,0,5.83333,0,5.83333ZM0,10.8333C0,10.3731,0.373096,10,0.833333,10C0.833333,10,15.8333,10,15.8333,10C16.2936,10,16.6667,10.3731,16.6667,10.8333C16.6667,11.2936,16.2936,11.6667,15.8333,11.6667C15.8333,11.6667,0.833333,11.6667,0.833333,11.6667C0.373096,11.6667,0,11.2936,0,10.8333C0,10.8333,0,10.8333,0,10.8333Z" fill-rule="evenodd" fill="#999999" fill-opacity="1"/></g></svg>`
     return <View style={{ width: props.width, height: props.height }}>
         {process.env.TARO_ENV == 'weapp' ? <mysvg src={icon} colors={[]} /> : <SvgXml xml={icon} width={props.width} height={props.height} />}

+ 8 - 3
src/components/input/PickerViews.tsx

@@ -4,6 +4,8 @@ import { forwardRef, useEffect, useImperativeHandle, useState } from "react";
 import { useTranslation } from "react-i18next";
 
 // export default function Component(props: { value: any, onChange: Function, items: any, height?: number, showBtns?: boolean, onCancel?: Function, }) {
+
+let detailValue
 const Component = forwardRef((props: {
     value: any, onChange: Function, items: any, height?: number, showBtns?: boolean, onCancel?: Function,
     themeColor?: string, title?: string
@@ -13,15 +15,18 @@ const Component = forwardRef((props: {
     var color = props.themeColor ? props.themeColor : '#ff0000'
     var alpha = alphaToHex(0.4)
 
+    console.log('apple')
+
     useEffect(() => {
         setV(props.value)
     }, [props.value])
 
     function onPickerChange(e) {
         setV(e.detail.value)
-        if (props.showBtns) {
-            return;
-        }
+        // detailValue = e.detail.value
+        // if (props.showBtns) {
+        //     return;
+        // }
         // props.onChange(e.detail.value)
     }
 

+ 12 - 6
src/context/locales/zh.js

@@ -7,7 +7,8 @@ export default {
         more: '更多'
     },
     share: {
-        title: '减脂/断食睡眠/身材管理/指标记录/运动打卡, 尽在fast16cc'
+        title: '减脂/断食睡眠/身材管理/指标记录/运动打卡, 尽在fast16cc',
+        food_title:'Food Journal'
     },
     page: {
         clock: {
@@ -20,7 +21,7 @@ export default {
             title: '指标',
         },
         food: {
-            title: '饮食',
+            title: '饮食日记',
         },
         more: {
             title: '更多',
@@ -276,14 +277,19 @@ export default {
         },
         food: {
             action_sheet: {
+                alert_text: '编辑或分享',
                 tag: '标签',
-                title: '选择要编辑的信息',
                 start_time: '开始时间',
-                end_time: '结束时间'
+                end_time: '结束时间',
+                edit_pic:'编辑图片',
+                share_pic:'分享图片',
             },
-            picker_tag_title:'编辑标签',
+            picker_tag_title:'标签',
             picker_start_title:'开始时间',
-            picker_end_title:'结束时间'
+            picker_end_title:'结束时间',
+            camera:'拍摄食物',
+            album:'从相册选择',
+            share_title:'我的饮食日记'
         },
         track_something: {
             btn_record: '记录',

+ 9 - 9
src/features/food/FoodConsole.scss

@@ -28,10 +28,10 @@
 }
 
 .camera_bg{
-    width: 300px;
-    height: 300px;
-    border-radius: 32px;
-    background-color: #2b2b2b;
+    width: 304px;
+    height: 304px;
+    border-radius: 36px;
+    background-color: #1c1c1c;
     display: flex;
     flex-direction: column;
     align-items: center;
@@ -43,7 +43,7 @@
     left: 0;
     right: 0;
     bottom: 0;
-    height: 33%;
+    height: 88px;
 }
 
 .camera_icon{
@@ -53,16 +53,16 @@
 }
 
 .camera_text{
-    margin-top: 16px;
-    font-size: 28px;
-    line-height: 30px;
+    margin-top: 18px;
+    font-size: 32px;
+    line-height: 32px;
     color: #fff;
     opacity: 0.4;
     font-weight: bold;
 }
 
 .album_text{
-    margin-top: 64px;
+    margin-top: 60px;
     font-size: 24px;
     line-height: 26px;
     color: #fff;

+ 25 - 10
src/features/food/FoodConsole.tsx

@@ -8,6 +8,9 @@ import { baseUrl } from '@/services/http/api'
 import { createFoodJournal } from '@/services/foodJournal'
 import { useSelector } from 'react-redux'
 import { jumpPage } from '../trackTimeDuration/hooks/Common'
+import { IconShare } from '@/components/basic/Icons'
+import { useTranslation } from 'react-i18next'
+import { ColorType } from '@/context/themes/color'
 let useNavigation;
 if (process.env.TARO_ENV == 'rn') {
     useNavigation = require("@react-navigation/native").useNavigation
@@ -15,6 +18,7 @@ if (process.env.TARO_ENV == 'rn') {
 
 export default function Component(props: { addItem: Function }) {
     const user = useSelector((state: any) => state.user);
+    const { t } = useTranslation()
     const [imgUrl, setImgUrl] = useState('')
     let navigation;
     if (useNavigation) {
@@ -34,15 +38,22 @@ export default function Component(props: { addItem: Function }) {
             return;
         }
         clearFile()
-        Taro.chooseImage({
+        Taro.chooseMedia({
             count: 1,
             sizeType: ['compressed'],
+            mediaType: ['image'],
             sourceType: [isAlbum ? 'album' : 'camera'],
             success: function (res) {
                 console.log(res)
-                var tempFilePaths = res.tempFilePaths
+                var tempFilePath = res.tempFiles[0].tempFilePath
+                // Taro.editImage({
+                //     src:tempFilePath,
+                //     success:function(res){
+                //         console.log(res)
+                //     }
+                // })
                 Taro.getFileSystemManager().saveFile({
-                    tempFilePath: tempFilePaths[0],
+                    tempFilePath: tempFilePath,
                     success: function (res) {
                         var savedFilePath = res.savedFilePath
                         Taro.setStorageSync('pic', savedFilePath)
@@ -143,7 +154,10 @@ export default function Component(props: { addItem: Function }) {
         var strDate = (date.getFullYear() + '') + (date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : (date.getMonth() + 1)) + (date.getDate() < 10 ? '0' + date.getDate() : date.getDate());
 
         createFoodJournal({
-            cover: url,
+            cover: {
+                url,
+                type: url.indexOf('mp4') != -1 ? 'video' : 'image'
+            },
             start: {
                 timestamp: time,
                 date: strDate
@@ -161,23 +175,24 @@ export default function Component(props: { addItem: Function }) {
         })
     }
 
-    return <View >
+    return <View style={{ marginBottom: rpxToPx(60) }}>
         <View style={{ display: 'flex', width: rpxToPx(750), alignItems: 'center', justifyContent: 'center', flexDirection: 'column' }}>
             <View style={{ display: 'flex', flexDirection: 'column' }}>
-                <Slider />
+                {/* <Slider /> */}
                 {/* <View className='box11' onClick={()=>choose(true)}>{
                     imgUrl && <Image style={{ width: '100%', height: '100%' }} src={imgUrl} mode="aspectFill" />
                 }
                 </View> */}
                 <View className='camera_bg' onClick={() => choose(false)}>
                     <Image src={require('@assets/images/camera2.png')} className='camera_icon' />
-                    <Text className='camera_text'>拍摄食物</Text>
-                    <Text className='album_text'>从相册选择</Text>
+                    <Text className='camera_text'>{t('feature.food.camera')}</Text>
+                    <Text className='album_text'>{t('feature.food.album')}</Text>
                     <View className='album_bottom' onClick={(e) => { choose(true); e.stopPropagation() }} />
                 </View>
-                <Slider />
+                {/* <Slider /> */}
             </View>
-            <View className='demo1' />
+            {/* <IconShare color={ColorType.food} width={100} height={100} /> */}
+            {/* <View className='demo1' /> */}
             {/* <Text style={{ color: '#fff',marginBottom:20 }} onClick={()=>choose(false)}>拍照</Text>
             <Text style={{ color: '#fff' }} onClick={uploadFile}>上传</Text> */}
 

+ 9 - 0
src/features/food/FoodJournal.scss

@@ -0,0 +1,9 @@
+.center_line{
+    position: absolute;
+    left: 374px;
+    width: 2px;
+    top: 0;
+    background-color: #fff;
+    opacity: 0.2;
+    z-index: -1;
+}

+ 33 - 3
src/features/food/FoodJournal.tsx

@@ -7,10 +7,13 @@ import Layout from "@/components/layout/layout"
 import { NaviBarTitleShowType, TemplateType } from "@/utils/types"
 import { useEffect, useState } from "react"
 import { getFoodJournals, getFoodTags } from "@/services/foodJournal"
-import { usePullDownRefresh, useReachBottom } from "@tarojs/taro"
+import { usePullDownRefresh, useReachBottom, useReady } from "@tarojs/taro"
 import Taro from "@tarojs/taro"
 import { useDispatch, useSelector } from "react-redux"
 import { setMealTags } from "@/store/common"
+import { getInfoSuccess } from "@/store/user"
+import './FoodJournal.scss'
+import { rpxToPx } from "@/utils/tools"
 
 export default function Component() {
     const { t } = useTranslation()
@@ -30,7 +33,22 @@ export default function Component() {
         }
     }, [user.isLogin])
 
+    useReady(async () => {
+        const userData = await getStorage('userData');
+        if (userData) {
+            dispatch(getInfoSuccess(JSON.parse(userData as string)) as any);
+            setTimeout(() => {
+                getList(1)
+
+            }, 200)
+
+        }
+    })
+
+
+
     usePullDownRefresh(() => {
+        setPageIndex(1)
         getList(1)
     })
 
@@ -51,6 +69,15 @@ export default function Component() {
         })
     }
 
+    async function getStorage(key: string) {
+        try {
+            const res = await Taro.getStorage({ key });
+            return res.data;
+        } catch {
+            return '';
+        }
+    }
+
     function more() {
         if (total <= list.length || isLoading) {
             return;
@@ -93,11 +120,11 @@ export default function Component() {
     }
 
     function headerView() {
-        return <TitleView title={t('page.food.title')} subTitle="hello world" showAddBtn={false}>
+        return <TitleView title={t('page.food.title')} showAddBtn={false}>
         </TitleView>
     }
     function detail() {
-        return <View>
+        return <View style={{ position: 'relative', marginTop: rpxToPx(52) }}>
             {
                 <FoodConsole addItem={addItem} />
             }
@@ -105,6 +132,9 @@ export default function Component() {
                 user.isLogin && list && <FoodTimeline array={list} />
             }
             <View style={{ height: 60 }} />
+            {
+                user.isLogin && <View className="center_line" style={{ height: list.length == 0 ? rpxToPx(304) : rpxToPx(364 * (list.length + 1) - 120) }} />
+            }
         </View>
     }
 

+ 18 - 4
src/features/food/FoodTimeline.tsx

@@ -21,14 +21,28 @@ export default function Component(props: { array: any }) {
         })
     }
 
+    // function preview(index){
+    //     var urls:any = []
+    //     list.map(item=>{
+    //         urls.push(item.cover)
+    //     })
+    //     Taro.previewImage({
+    //         current: list[index].cover,
+    //         urls: urls
+    //     })
+    // }
+
     function preview(index){
         var urls:any = []
         list.map(item=>{
-            urls.push(item.cover)
+            urls.push({
+                url:item.cover,
+                type:item.cover.indexOf('mp4')!=-1?'video':'image'
+            })
         })
-        Taro.previewImage({
-            current: list[index].cover,
-            urls: urls
+        Taro.previewMedia({
+            current: index,
+            sources: urls
         })
     }
 

+ 89 - 14
src/features/food/FoodTimelineItem.scss

@@ -1,34 +1,109 @@
-.food_timeline_item{
-    margin-bottom: 40px;
+.food_timeline_item {
+    margin-bottom: 60px;
     display: flex;
     flex-direction: row;
 }
-.tags{
-    width: 100px;
+
+.tags {
+    margin-left: 55px;
+    width: 144px;
     display: flex;
     flex-direction: column;
-    color: #fff;
     font-size: 24px;
+    align-items: center;
+    box-sizing: border-box;
+    
+}
+
+.tag-item{
+    height: 48px;
+    box-sizing: border-box;
+    border-radius: 24px;
+    border: solid 2px #ffffff66;
+    padding-left: 24px;
+    padding-right: 24px;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    margin-top: 24px;
+}
+
+.more_tag{
+    margin-top: 16px;
+    height: 72px;
+    width: 100%;
+    line-height: 72px;
+    text-align: center;
+    color: #fff;
+    font-size: 20px;
+    opacity: 0.4;
 }
-.thumb_bg{
+
+.thumb_bg {
     position: relative;
-    width: 300px;
-    height: 300px;
+    width: 304px;
+    height: 304px;
+    border-radius: 36px;
+    overflow: hidden;
 }
-.thumb{
-    width: 300px;
-    height: 300px;
+
+.thumb {
+    width: 304px;
+    height: 304px;
 }
 
-.food_desc{
+.food_desc {
     position: absolute;
     left: 0;
     right: 0;
     bottom: 0;
-    height: 60px;
+    height: 72px;
+    border-bottom-left-radius: 36px;
+    border-bottom-right-radius: 36px;
     backdrop-filter: blur(20px);
+    display: flex;
+    flex-direction: row;
+    align-items: center;
+    justify-content: center;
+    color: #fff;
+}
+
+.food_desc_text {
+    color: #fff;
+    opacity: 0.8;
+    font-size: 24px;
+    line-height: 26px;
+    text-shadow: 0px 4px 10px rgba(0, 0, 0, 0.3);
+    font-weight: bold;
+}
+
+.food_item_date {
+    color: #fff;
+}
+
+.food_share {
+    width: 72px;
+    height: 72px;
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    position: relative;
+    margin-left: 36px;
+}
+
+.food_share_btn {
+    position: absolute;
+    left: 0;
+    top: 0;
+    right: 0;
+    bottom: 0;
+    opacity: 0;
 }
 
-.food_item_date{
+.food_share_text {
+    font-size: 20px;
+    line-height: 24px;
     color: #fff;
+    opacity: 0.4;
+    margin-top: 12px;
 }

+ 145 - 25
src/features/food/FoodTimelineItem.tsx

@@ -1,4 +1,4 @@
-import { View, Image, Text } from "@tarojs/components";
+import { View, Image, Text, Button } from "@tarojs/components";
 import './FoodTimelineItem.scss'
 import Taro from "@tarojs/taro";
 import { useTranslation } from "react-i18next";
@@ -9,6 +9,9 @@ import Modal from "@/components/layout/Modal";
 import { ColorType } from "@/context/themes/color";
 import { useSelector } from "react-redux";
 import PickerViews from "@/components/input/PickerViews";
+import { IconShare } from "@/components/basic/Icons";
+import { TimeFormatter } from "@/utils/time_format";
+import { baseUrl } from "@/services/http/api";
 
 export default function Component(props: { data: any, index: number, delete: Function, preview: Function, update: Function }) {
     const common = useSelector((state: any) => state.common);
@@ -21,6 +24,9 @@ export default function Component(props: { data: any, index: number, delete: Fun
 
     useEffect(() => {
         setDetail(props.data)
+        if (props.index == 0) {
+            global.food_share_img_url = props.data.cover
+        }
     }, [props.data])
 
     function preview() {
@@ -57,30 +63,42 @@ export default function Component(props: { data: any, index: number, delete: Fun
 
     function operateActionSheet() {
         Taro.showActionSheet({
-            alertText: t('feature.food.action_sheet.title'),
-            itemList: [t('feature.food.action_sheet.tag'),
-            t('feature.food.action_sheet.start_time'),
-            t('feature.food.action_sheet.end_time')]
+            alertText: t('feature.food.action_sheet.alert_text'),
+            itemList: [
+                t('feature.food.action_sheet.tag'),
+                t('feature.food.action_sheet.start_time'),
+                t('feature.food.action_sheet.end_time'),
+                t('feature.food.action_sheet.edit_pic'),
+                t('feature.food.action_sheet.share_pic')]
         })
             .then(res => {
                 switch (res.tapIndex) {
                     case 0:
                         setShowTagModal(true)
                         break;
+
                     case 1:
                         {
-                            global.set_time = new Date().getTime()
+                            global.set_time = new Date().getTime()+24*3600*1000
                             setIsStart(true)
                             setShowModal(true)
                         }
                         break;
                     case 2:
                         {
-                            global.set_time = new Date().getTime()
+                            global.set_time = new Date().getTime()+24*3600*1000
                             setIsStart(false)
                             setShowModal(true)
                         }
                         break;
+                    case 3:
+                        {
+                            editPic();
+                        };
+                        break;
+                    case 4:
+                        share()
+                        break;
                 }
             })
             .catch(err => {
@@ -88,6 +106,94 @@ export default function Component(props: { data: any, index: number, delete: Fun
             })
     }
 
+    function editPic() {
+        Taro.downloadFile({
+            url: detail.cover,
+            success: (res) => {
+                Taro.editImage({
+                    src: res.tempFilePath,
+                    success: (res) => {
+                        console.log(res.tempFilePath)
+                        postPic(res.tempFilePath)
+                    }
+                })
+                // Taro.showShareImageMenu({
+                //     path: res.tempFilePath
+                // })
+            }
+        })
+    }
+
+    function postPic(path) {
+        Taro.showLoading({
+            title: '加载中'
+        })
+        var dot = path.lastIndexOf('.')
+        var fileExt = dot > 0 ? path.substring(dot) : ''
+        // console.log(avatarUrl)
+        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) => {
+                console.log(rsp)
+                Taro.uploadFile({
+                    url: rsp.data.upload_url,
+                    filePath: path,
+                    name: 'file',
+                    formData: rsp.data.fields,
+                    success: rlt => {
+                        console.log(rlt)
+                        updatePic(rsp.data.view_url)
+
+                        // uploadAvatar(rsp.data.view_url)
+                        // _this.changeAvatar(rsp.data.view_url);
+                    },
+                    fail: rlt => {
+                        Taro.hideLoading()
+                        Taro.showModal({
+                            content: rlt.errMsg
+                        })
+                    }
+                })
+            }
+        })
+    }
+
+    function updatePic(url) {
+        editFoodJournal({
+            cover: {
+                url: url,
+                type: url.indexOf('mp4') != -1 ? 'video' : 'image'
+            }
+        }, detail.id).then(res => {
+            setDetail(res)
+            setCount(count + 1)
+
+            props.update(res)
+            Taro.hideLoading()
+        }).catch(e => {
+            Taro.hideLoading()
+        })
+    }
+
+    function share() {
+        Taro.downloadFile({
+            url: detail.cover,
+            success: (res) => {
+                Taro.showShareImageMenu({
+                    path: res.tempFilePath
+                })
+            }
+        })
+    }
+
     function updateTag(index) {
         var tag = common.meal_tags[index]
         editFoodJournal({
@@ -142,13 +248,6 @@ export default function Component(props: { data: any, index: number, delete: Fun
         })
     }
 
-    function getTime(t) {
-        var date = new Date(t)
-        var hour = date.getHours()
-        var minute = date.getMinutes()
-        return (hour < 10 ? '0' + hour : hour) + ':' + (minute < 10 ? '0' + minute : minute)
-    }
-
     function pickerTagIndex() {
         var list = common.meal_tags
         if (detail.meal_tag) {
@@ -159,7 +258,7 @@ export default function Component(props: { data: any, index: number, delete: Fun
             }
         }
 
-        return 0;
+        return 3;
     }
 
     function pickerTagItems() {
@@ -196,24 +295,45 @@ export default function Component(props: { data: any, index: number, delete: Fun
 
     return <View className="food_timeline_item" onLongPress={showActionSheet}>
         {/* <View className="thumb" style={{backgroundColor:'pink'}}/> */}
-        <View className="tags">
+
+        <View style={{ flex: 1 }}>
             {
-                props.index == 0 && !detail.meal_tag && common.meal_tags.map((item, index) => {
-                    return <Text onClick={() => updateTag(index)}>{item.label}</Text>
-                })
+                props.index == 0 && !detail.meal_tag && <View className="tags">
+                    {
+                        common.meal_tags.map((item, index) => {
+                            return index <= 2 ? <View className="tag-item" onClick={() => updateTag(index)}>
+                                <Text style={{ color: ColorType.food }}>{item.label}</Text>
+                            </View> : <View />
+
+                        })
+                    }
+                    <View className="more_tag" onClick={() => { setShowTagModal(true) }}>更多标签</View>
+                </View>
             }
+
         </View>
         <View className="thumb_bg">
-            <Image className="thumb" src={detail.cover} mode="aspectFill" onClick={preview} />
+            <Image className="thumb" src={detail.cover.url} mode="aspectFill" onClick={preview} />
+            {/* <Image className="thumb" src={detail.cover+'?x-oss-process=image/resize,w_300,limit_0'} mode="aspectFill" onClick={preview} /> */}
             <View className="food_desc" onClick={operateActionSheet}>
-                <Text>{detail.meal_tag && detail.meal_tag.label}</Text>
-                <Text>{detail.start && getTime(detail.start.timestamp)} </Text>
-                {
+                <Text className="food_desc_text">{detail.start && TimeFormatter.getMonthDayByTimestamp(detail.start.timestamp)}</Text>
+                <Text className="food_desc_text">{detail.meal_tag && detail.meal_tag.label}</Text>
+                <Text className="food_desc_text">{detail.start && TimeFormatter.getTimeByTimestamp(detail.start.timestamp)}</Text>
+                {/* {
                     detail.end.timestamp && <Text>{'-' + getTime(detail.end.timestamp)}</Text>
-                }
+                } */}
             </View>
         </View>
-        <Text className="food_item_date">{detail.start.date}</Text>
+        {/* <Text className="food_item_date">{detail.start.date}</Text> */}
+        <View style={{ flex: 1 }}>
+            {
+                props.index == 0 && <View className="food_share">
+                    <IconShare color={ColorType.food} width={20} height={17} />
+                    <Text className="food_share_text">分享</Text>
+                    <Button openType="share" className="food_share_btn" />
+                </View>
+            }
+        </View>
         {
             showModal && <Modal dismiss={() => { setShowModal(false) }} confirm={() => { setShowModal(false) }}>
                 <View className='modal_content'>

+ 8 - 1
src/features/trackTimeDuration/components/TitleView.tsx

@@ -5,6 +5,7 @@ import Taro from '@tarojs/taro';
 import { setStep } from '@/store/scenario';
 import { useTranslation } from 'react-i18next';
 import { jumpPage } from '../hooks/Common';
+import { useEffect, useState } from 'react';
 
 export default function Component(props: {
     children?: any,
@@ -17,10 +18,15 @@ export default function Component(props: {
 }) {
     const time = useSelector((state: any) => state.time);
     const user = useSelector((state: any) => state.user);
+    const  [count,setCount]  = useState(0)
     const { t } = useTranslation()
     const dispatch = useDispatch();
     const isFastFirst = true
 
+    useEffect(()=>{
+        setCount(count+1)
+    },[global.isDebug])
+
 
 
     function more() {
@@ -73,7 +79,8 @@ export default function Component(props: {
 
     var showAddIcon = user.isLogin && props.showAddBtn
 
-    return <View className={(props.children||props.subTitle) ? 'title_view' : 'title_view no_sub_element'} >
+    return <View className={(props.children||props.subTitle) ? 'title_view' : 'title_view no_sub_element'} 
+    style={{backgroundColor:global.isDebug?'red':'transparent'}}>
         <View className='title_bg'>
             <Text className='title' style={{
                 color: props.titleColor ? props.titleColor : '#fff',

+ 10 - 2
src/pages/account/Profile.tsx

@@ -14,6 +14,7 @@ import { useEffect, useState } from "react";
 import { jumpPage } from "@/features/trackTimeDuration/hooks/Common";
 import Tabbar from "@/components/navigation/TabBar";
 import { getInfoSuccess } from "@/store/user";
+import TitleView from "@/features/trackTimeDuration/components/TitleView";
 let useNavigation;
 if (process.env.TARO_ENV == 'rn') {
     useNavigation = require("@react-navigation/native").useNavigation
@@ -131,8 +132,14 @@ export default function Page() {
         })
     }
 
+    function headerView() {
+        return <TitleView title={t('page.more.title')} showAddBtn={false}>
+        </TitleView>
+    }
+
     function detail() {
         return <View className="container">
+
             <Box>
                 <View className="profile_card" onClick={tapProfile}>
                     <View className="avatar" style={{
@@ -170,7 +177,7 @@ export default function Page() {
 
             {
                 user.isLogin && user.test_user && <TableCell title="user_id" showArrow={true} onClick={clearF}>
-                    <Text style={{ opacity: 0.8 }}>******{user.id.substring(user.id.length - 10, user.id.length)}</Text>
+                    <Text style={{ opacity: 0.8 }}>{user.id.substring(0, 6)}***{user.id.substring(user.id.length - 10, user.id.length)}</Text>
                 </TableCell>
             }
             {
@@ -239,7 +246,8 @@ export default function Page() {
     return <View>
         <Layout title={t('page.more.title')}
             titleShowStyle={NaviBarTitleShowType.scrollToShow}
-            type={TemplateType.flex}
+            type={TemplateType.customHeader}
+            header={headerView()}
             triggered={triggered}
             refresh={refresh}
         >

+ 16 - 0
src/pages/food/Food.tsx

@@ -2,8 +2,24 @@ import { View } from "@tarojs/components";
 import Tabbar from "@/components/navigation/TabBar";
 import './Food.scss'
 import FoodJournal from "@/features/food/FoodJournal";
+import { useDidShow, useReady, useShareAppMessage } from "@tarojs/taro";
+import { useTranslation } from "react-i18next";
 
 export default function Page() {
+    const {t} = useTranslation()
+    
+
+    if (process.env.TARO_ENV == 'weapp') {
+        useShareAppMessage((e) => {
+            return {
+                title: t('feature.food.share_title'),
+                path: 'pages/food/Food',
+                imageUrl:global.food_share_img_url?global.food_share_img_url:''
+            }
+        })
+    }
+
+    
 
     return <View>
         <FoodJournal />

+ 25 - 1
src/utils/time_format.ts

@@ -69,7 +69,7 @@ export class TimeFormatter {
       return `昨天 ${TimeFormatter.padZero(inputDate.getHours())}:${TimeFormatter.padZero(inputDate.getMinutes())}`;
     }
 
-    return TimeFormatter.getDateAndWeek(timestamp)+' '+`${TimeFormatter.padZero(inputDate.getHours())}:${TimeFormatter.padZero(inputDate.getMinutes())}`
+    return TimeFormatter.getDateAndWeek(timestamp) + ' ' + `${TimeFormatter.padZero(inputDate.getHours())}:${TimeFormatter.padZero(inputDate.getMinutes())}`
 
   }
 
@@ -201,6 +201,30 @@ export class TimeFormatter {
     }
   }
 
+  static getMonthDayByTimestamp(num: number): string {
+    const dt = new Date(num);
+    const now = new Date();
+    const diff = now.getTime() - dt.getTime();
+    const day = 1000 * 60 * 60 * 24;
+    if (diff < day) {
+      return '今日';
+    } else if (diff < 2 * day) {
+      return '昨日';
+    } else {
+      var month = dt.getMonth() + 1
+      var date = dt.getDate()
+      return month + '月' + date + '日'
+    }
+  }
+
+  static getTimeByTimestamp(num: number): string {
+    const dt = new Date(num);
+    var hour = dt.getHours()
+    var minute = dt.getMinutes()
+    var formateTime = TimeFormatter.padZero(hour) + ':' + TimeFormatter.padZero(minute)
+    return formateTime
+  }
+
   //duration 根据起终点时间,忽略精度,如果两个时间点小于60s,则保留精度,否则为分钟
   static durationFormate(startTimestamp: number, endTimestamp: number) {
     var start = startTimestamp;