leon 1 năm trước cách đây
mục cha
commit
51fdb36004

+ 0 - 0
src/_health/base/new_button.scss


+ 148 - 0
src/_health/base/new_button.tsx

@@ -0,0 +1,148 @@
+import { View, Text } from '@tarojs/components'
+import './new_button.scss'
+import { rpxToPx } from '@/utils/tools';
+import { useState } from 'react';
+
+export enum NewButtonType {
+    fill = 'fill', //主题实色
+    alpha = 'alpha', //主题半透明
+    border = 'border', //主题边框
+    gray = 'gray', //灰色半透明
+    text = 'text' //纯文本
+}
+
+function hexToHSL(hex) {
+    // 去掉井号,处理3位和6位16进制
+    hex = hex.replace(/^#/, '');
+    if (hex.length === 3) {
+        hex = hex.split('').map(char => char + char).join('');
+    }
+
+    // 解析RGB
+    const r = parseInt(hex.slice(0, 2), 16) / 255;
+    const g = parseInt(hex.slice(2, 4), 16) / 255;
+    const b = parseInt(hex.slice(4, 6), 16) / 255;
+
+    // 计算最大和最小值
+    const max = Math.max(r, g, b);
+    const min = Math.min(r, g, b);
+    let h, s, l = (max + min) / 2;
+
+    // 计算亮度
+    if (max === min) {
+        h = s = 0; // achromatic
+    } else {
+        const d = max - min;
+        s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
+
+        switch (max) {
+            case r:
+                h = (g - b) / d + (g < b ? 6 : 0);
+                break;
+            case g:
+                h = (b - r) / d + 2;
+                break;
+            case b:
+                h = (r - g) / d + 4;
+                break;
+        }
+        h /= 6;
+    }
+
+    // 转换为度和百分比
+    h = Math.round(h * 360);
+    s = Math.round(s * 100);
+    l = Math.round(l * 100);
+    return `hsl(${h}, ${s}%, ${l - 10}%)`;
+}
+export default function NewButton(props: {
+    type: NewButtonType,
+    color?: string,
+    title?: string,
+    component?: any,
+    disable?: boolean,
+    loading?: boolean,
+    onClick?: any,
+    width?: number,
+    height?: number,
+    fontSize?: number,
+    bold?:boolean,
+}) {
+
+    const [isTouched, setIsTouched] = useState(false)
+    let style = {}
+    switch (props.type) {
+        case NewButtonType.fill:
+            style = {
+                height: props.height ?? rpxToPx(72),
+                width: props.width ?? rpxToPx(198),
+                borderRadius: props.height ? props.height / 4 : rpxToPx(72 / 4),
+                backgroundColor: isTouched ? hexToHSL(props.color) : props.disable ? '#B2B2B2' : props.color,
+                color: '#fff',
+                fontSize: props.fontSize ?? rpxToPx(30),
+                display: 'flex',
+                alignItems: 'center',
+                justifyContent: 'center',
+                opacity: props.disable ? 0.6 : 1,
+            }
+            break
+        case NewButtonType.alpha:
+
+            style = {
+                height: props.height ?? rpxToPx(72),
+                width: props.width ?? rpxToPx(198),
+                borderRadius: props.height ? props.height / 4 : rpxToPx(72 / 4),
+                backgroundColor: isTouched ? props.color + '40' : props.disable ? '#B2B2B240' : props.color + '1A',
+                color: props.disable ? '#b2b2b2' : props.color,
+                fontSize: props.fontSize ?? rpxToPx(30),
+                display: 'flex',
+                alignItems: 'center',
+                justifyContent: 'center',
+                opacity: props.disable ? 0.6 : 1,
+            }
+            break;
+        case NewButtonType.border:
+            style = {
+                height: props.height ?? rpxToPx(72),
+                width: props.width ?? rpxToPx(198),
+                borderWidth: rpxToPx(2),
+                borderColor: props.disable ? '#B2B2B2' : props.color,
+                borderStyle: 'solid',
+                borderRadius: props.height ? props.height / 4 : rpxToPx(72 / 4),
+                backgroundColor: isTouched ? props.color + '26' : 'transparent',
+                color: props.disable ? '#b2b2b2' : props.color,
+                fontSize: props.fontSize ?? rpxToPx(30),
+                display: 'flex',
+                alignItems: 'center',
+                justifyContent: 'center',
+                opacity: props.disable ? 0.6 : 1,
+                boxSizing:'border-box'
+            }
+            break;
+    }
+
+    return <View
+        style={{...style,fontWeight:props.bold?'bold':'normal'}}
+        catchMove
+        onClick={(e) => {
+            if (process.env.TARO_ENV == 'weapp') {
+                e.stopPropagation()
+            }
+            if (props.disable) return
+            props.onClick()
+        }}
+        onTouchStart={(e) => {
+            if (process.env.TARO_ENV == 'weapp') {
+                e.stopPropagation()
+            }
+            if (props.disable) return
+            setIsTouched(true)
+        }}
+        onTouchEnd={(e) => {
+            if (process.env.TARO_ENV == 'weapp') {
+                e.stopPropagation()
+            }
+            setIsTouched(false)
+        }}
+    >{props.title}{props.component}</View>
+}

+ 12 - 0
src/_health/pages/schedules.scss

@@ -158,4 +158,16 @@
     color: #FF0000;
     font-size: 20px;
     margin-right: 12px;
+}
+
+.conflict_item {
+    height: 128px;
+    background-color: #fff;
+    display: flex;
+    flex-direction: row;
+    align-items: center;
+    padding-left: 40px;
+    padding-right: 40px;
+    box-sizing: border-box;
+    position: relative;
 }

+ 133 - 38
src/_health/pages/schedules.tsx

@@ -10,6 +10,8 @@ import { jumpPage } from "@/features/trackTimeDuration/hooks/Common";
 import Modal from "@/components/layout/Modal.weapp";
 import TimePicker from "@/features/common/TimePicker";
 import showAlert from "@/components/basic/Alert";
+import { IconAdd } from "@/components/basic/Icons";
+import AddLabel from "../components/add_label";
 
 let useRoute;
 let useNavigation;
@@ -35,11 +37,13 @@ export default function Schedules() {
     }
     const [list, setList] = useState<any>([])
     const [labels, setLabels] = useState<any>([])
+    const [showAutoSave, setShowAutoSave] = useState(false)
     const [errors, setErrors] = useState<any>(router.params.errors ? JSON.parse(router.params.errors) : [])
     const [showTimePicker, setShowTimePicker] = useState(false)
     const health = useSelector((state: any) => state.health);
     const [selItem, setSelItem] = useState<any>(null)
     const [selIndex, setSelIndex] = useState(-1)
+    const [showModal, setShowModal] = useState(false)
     const selMode = router.params.mode;
 
     useEffect(() => {
@@ -56,6 +60,10 @@ export default function Schedules() {
         schedules()
     }
 
+    global.tempRefresh = () => {
+        schedules()
+    }
+
     function schedules() {
         let windows = ''
         switch (selMode) {
@@ -139,6 +147,7 @@ export default function Schedules() {
 
 
             if ((res as any).result) {
+                setShowAutoSave(true)
                 setErrors([])
                 setList((res as any).schedules)
                 global.refreshWindow()
@@ -150,43 +159,104 @@ export default function Schedules() {
                 // }
             }
             else {
-                var array = (res as any).conflict_windows;
-                var showMore = false;
-                if (array.length > 2) {
-                    showMore = true;
-                }
-                else if (array.length == 1) {
-                    showMore = false;
-                }
-                else {
-                    // 判断是否同时存在 FAST 和 EAT
-                    const containsFastAndEat = array.includes('FAST') && array.includes('EAT');
+                setShowAutoSave(false)
+                setList((res as any).schedules)
+                setErrors((res as any).error_messages ? (res as any).error_messages : [])
+                // var array = (res as any).conflict_windows;
+                // var showMore = false;
+                // if (array.length > 2) {
+                //     showMore = true;
+                // }
+                // else if (array.length == 1) {
+                //     showMore = false;
+                // }
+                // else {
+                //     // 判断是否同时存在 FAST 和 EAT
+                //     const containsFastAndEat = array.includes('FAST') && array.includes('EAT');
 
-                    // 判断是否同时存在 SLEEP 和 ACTIVE
-                    const containsSleepAndActive = array.includes('SLEEP') && array.includes('ACTIVE');
+                //     // 判断是否同时存在 SLEEP 和 ACTIVE
+                //     const containsSleepAndActive = array.includes('SLEEP') && array.includes('ACTIVE');
 
-                    // 最终结果
-                    const result = containsFastAndEat || containsSleepAndActive;
-                    showMore = !result;
-                }
-                if (selMode != '' && showMore) {
-                    showAlert({
-                        title: '弹窗标题',
-                        content: '冲突描述',
-                        showCancel: false,
-                        confirm: () => {
-                            jumpPage(`./schedules?mode=&schedules=${JSON.stringify((res as any).schedules)}&errors=${JSON.stringify((res as any).error_messages)}`)
-                        }
-                    })
-                }
-                else {
-                    setList((res as any).schedules)
-                    setErrors((res as any).error_messages ? (res as any).error_messages : [])
-                }
+                //     // 最终结果
+                //     const result = containsFastAndEat || containsSleepAndActive;
+                //     showMore = !result;
+                // }
+                // if (selMode != '' && showMore) {
+                //     showAlert({
+                //         title: '弹窗标题',
+                //         content: '冲突描述',
+                //         showCancel: false,
+                //         confirm: () => {
+                //             jumpPage(`./schedules?mode=&schedules=${JSON.stringify((res as any).schedules)}&errors=${JSON.stringify((res as any).error_messages)}`)
+                //         }
+                //     })
+                // }
+                // else {
+                //     setList((res as any).schedules)
+                //     setErrors((res as any).error_messages ? (res as any).error_messages : [])
+                // }
             }
         })
     }
 
+    function add() {
+        var isMax = false
+        if (selMode == 'FAST' || selMode == 'EAT') {
+            const countFastWindows = list.filter(item => item.window === 'EAT').length;
+            if (countFastWindows >= 4) {
+                isMax = true
+            }
+        }
+        else {
+            const countFastWindows = list.filter(item => item.window === 'ACTIVE').length;
+            if (countFastWindows >= 4) {
+                isMax = true
+            }
+        }
+        if (isMax) {
+            showAlert({
+                title: '会员',
+                content: '会员desc',
+                showCancel: true,
+                confirm: () => {
+                    jumpPage('/pages/store/product_list', 'ProductList', navigation)
+                }
+            })
+            return;
+        }
+        setShowModal(true)
+    }
+
+    function getAddColor() {
+        if (selMode == 'FAST' || selMode == 'EAT') {
+            return getThemeColor('EAT')
+        }
+        return getThemeColor('ACTIVE')
+    }
+
+    function tapEdit() {
+        jumpPage('./schedules_edit?mode=' + selMode)
+    }
+
+    function itemStyle(obj) {
+        if (obj.is_conflict) {
+            return {
+                backgroundColor: '#FF00001A',
+                color: '#FF0000'
+            }
+        }
+        if (errors.length > 0) {
+            return {
+                backgroundColor: '#B2B2B21A',
+                color: '#000'
+            }
+        }
+        return {
+            backgroundColor: obj.window == selMode ? getThemeColor(selMode) + '1A' : '#B2B2B21A',
+            color: obj.window == selMode ? getThemeColor(selMode) : '#000'
+        }
+    }
+
 
     return <View>
         <View style={{ display: 'flex', flexDirection: 'column' }}>
@@ -196,9 +266,9 @@ export default function Schedules() {
                     return <View key={index} className='error_tip'>{item}</View>
                 })
             }
-            {/* {
-                errors.length == 0 && <View className='success_tip'>时间冲突已解决,并保存</View>
-            } */}
+            {
+                showAutoSave && <View className='success_tip'>已自动保存</View>
+            }
             <View style={{ backgroundColor: '#fff' }}>
                 {
                     list.map((obj, i) => {
@@ -217,15 +287,15 @@ export default function Schedules() {
                                 {
                                     obj.is_conflict && <Text className="conflict_tip">时间冲突,请调整</Text>
                                 }
+                                {
+                                    !obj.is_all_day && !obj.reminder && <Image src={require('@assets/images/notification_off.png')} className='notification_icon' />
+                                }
                                 {
                                     !obj.is_all_day && <View className='edit_item_time' onClick={() => {
                                         setSelIndex(i)
                                         setSelItem(obj)
                                         setShowTimePicker(true)
-                                    }} style={{
-                                        backgroundColor: obj.window == selMode ? getThemeColor(selMode) + '1A' : '#B2B2B21A',
-                                        color: obj.window == selMode ? getThemeColor(selMode) : '#000'
-                                    }}>{obj.time}</View>
+                                    }} style={itemStyle(obj)}>{obj.time}</View>
                                 }
 
                                 {
@@ -236,11 +306,26 @@ export default function Schedules() {
                     })
                 }
             </View>
+
+            {
+                selMode != '' && selMode != 'DAY' && selMode != 'NIGHT' && <View className='item_add'
+                    style={{ marginTop: 20 }}
+                    onClick={() => add()}>
+                    <IconAdd color={getAddColor()} width={rpxToPx(34)} />
+                    <View className='toolbar_btn' style={{ color: getAddColor() }} >添加</View>
+                    <View style={{ flex: 1 }} />
+                </View>
+            }
+
+
+
             {
                 selMode != '' && <Text onClick={() => {
                     jumpPage('/_health/pages/schedules?mode=')
                 }}>查看全部</Text>
             }
+
+            <View className="edit_footer_btn" style={{ color: getThemeColor(health.mode), backgroundColor: getThemeColor(health.mode) + '33' }} onClick={tapEdit}>批量编辑</View>
             {
                 showTimePicker && <Modal
                     testInfo={null}
@@ -253,6 +338,16 @@ export default function Schedules() {
                     }
                 </Modal>
             }
+
+            {
+                showModal && <Modal testInfo={null}
+                    dismiss={() => {
+                        setShowModal(false)
+                    }}
+                    confirm={() => { }}>
+                    <AddLabel labels={labels} disMiss={() => setShowModal(false)} />
+                </Modal>
+            }
         </View>
     </View>
 }

+ 4 - 0
src/_health/pages/schedules_edit.tsx

@@ -170,6 +170,10 @@ export default function SchedulesEdit() {
                 if (global.refreshSchedules) {
                     global.refreshSchedules()
                 }
+
+                if (global.tempRefresh) {
+                    global.tempRefresh()
+                }
                 if (global.refreshSchedules2) {
                     global.refreshSchedules2()
                 }

+ 38 - 1
src/_health/pages/timeline_detail.tsx

@@ -21,12 +21,14 @@ export default function TimelineDetail() {
     const health = useSelector((state: any) => state.health);
     const user = useSelector((state: any) => state.user);
     const [list, setList] = useState<any>([])
+    const [detail, setDetail] = useState<any>(null)
     const [desc, setDesc] = useState('')
     const [imgUrl, setImgUrl] = useState('')
     const [btnDisable, setBtnDisable] = useState(true)
     const [showPop, setShowPop] = useState(false)
     const [publish, setPublish] = useState<any>(null)
     const [bottom, setBottom] = useState(0)
+    const [loaded, setLoaded] = useState(false)
     let router
     let navigation;
     if (useNavigation) {
@@ -61,6 +63,8 @@ export default function TimelineDetail() {
 
     function getDatas() {
         getEvents(event_id).then(res => {
+            setLoaded(true)
+            setDetail(res)
             setList((res as any).moments)
             setPublish((res as any).publish)
         })
@@ -187,6 +191,8 @@ export default function TimelineDetail() {
 
     }
 
+    if (!loaded) return <View />
+
     return <View style={{ display: 'flex', flex: 1 }}>
         <View className="detail_header">
             <Image className="detail_header_header"
@@ -196,7 +202,38 @@ export default function TimelineDetail() {
             <View className="detail_header_content">
                 <Text className="detail_nickname">{user.nickname}</Text>
                 {
-                    list.map((item, index) => {
+                    (detail.scenario != 'MEAL' && detail.scenario != 'ACTIVITY') && <View style={{ flexDirection: 'column', display: 'flex' }}>
+
+                        <Text className="detail_time">{dayjs(detail.time.timestamp).format('HH:mm')}
+                            {
+                                detail.title && <Text> {detail.title}</Text>
+                            }
+                            {/* {
+                                item.description && <Text style={{ color: '#000' }}> {item.description}</Text>
+                            } */}
+                        </Text>
+
+                        {/* {
+                            item.media && item.media.length > 0 && <Image mode="aspectFill" src={item.media[0].url} style={{ width: 60, height: 60, marginTop: 5 }} />
+                        } */}
+                    </View>
+                }
+                {
+                    detail.scenario == 'ACTIVITY' && !list && <View style={{ flexDirection: 'column', display: 'flex' }}>
+
+                        <Text className="detail_time">{dayjs(detail.time.timestamp).format('HH:mm')}
+                            {
+                                detail.title && <Text> {detail.title}</Text>
+                            }
+                        </Text>
+
+                        {/* {
+                        item.media && item.media.length > 0 && <Image mode="aspectFill" src={item.media[0].url} style={{ width: 60, height: 60, marginTop: 5 }} />
+                    } */}
+                    </View>
+                }
+                {
+                    list && list.map((item, index) => {
                         return <View key={index} style={{ flexDirection: 'column', display: 'flex' }}>
 
                             <Text className="detail_time">{dayjs(item.time.timestamp).format('HH:mm')}

+ 23 - 0
src/app.scss

@@ -380,6 +380,29 @@ page {
 //     }
 // }
 
+.seperate_line{
+    height: 2px;
+    transform: scaleY(0.5);
+    background-color: #B2B2B2;
+    opacity: 0.4;
+    position: absolute;
+    left: 0;
+    right: 0;
+    bottom: 0;
+}
+
+//历史记录 首页、
+.seperate_light_line{
+    height: 2px;
+    transform: scaleY(0.5);
+    background-color: #B2B2B2;
+    opacity: 0.2;
+    position: absolute;
+    left: 0;
+    right: 0;
+    bottom: 0;
+}
+
 .border_footer_line {
     height: 2px;
     transform: scaleY(0.5);

+ 9 - 3
src/context/themes/color.tsx

@@ -15,12 +15,12 @@ export enum ColorType {
 }
 
 export enum MainColorType {
-    bg = '#f5f5f5',
+    bg = '#e5e5e5',
     ringBg = 'rgba(178,178,178,0.2)',
     day = '#FFBB00',
     dayLight = '#FFE499',
-    night = '#002266',
-    nightLight = '#99A7C2',
+    night = '#0256ff',
+    nightLight = '#99bcff',
     fast = '#26B7FF',
     fastLight = '#A8E2FF',
     eat = '#FF751A',
@@ -29,4 +29,10 @@ export enum MainColorType {
     sleepLight = '#DFC8FF',
     active = '#FF2E66',
     activeLight = '#FFABC2',
+
+    link = '#5c7099',
+    error = '#ff0000',
+    success = '#00b218',
+    blue = '#0055ff',
+
 }

+ 9 - 8
src/features/health/HistoryItem.tsx

@@ -32,15 +32,16 @@ export default function HistoryItem(props: { data: any, preData: any, index: num
     //npm install react-native-text-size
 
     function getTitle(item) {
+        if (item.title) return item.title
         if (item.moment) {
             return item.moment.title
         }
-        if (health.mode == 'FAST') {
-            return '开始断食'
-        }
-        else if (health.mode == 'SLEEP') {
-            return '开始睡眠'
-        }
+        // if (health.mode == 'FAST') {
+        //     return '开始断食'
+        // }
+        // else if (health.mode == 'SLEEP') {
+        //     return '开始睡眠'
+        // }
         return ''
     }
 
@@ -100,7 +101,7 @@ export default function HistoryItem(props: { data: any, preData: any, index: num
                 {
                     props.data.events.map((item, index) => {
                         return <Text key={index}>
-                            <Text className="history_item_title">{item.real && dayjs(item.real.start_timestamp).format('HH:mm')} {getTitle(item)} </Text>
+                            <Text className="history_item_title">{item.time && dayjs(item.time.timestamp).format('HH:mm')} {getTitle(item)} </Text>
                             {
                                 item.moments && item.moments.map((moment,i)=>{
                                     return <Text className="history_item_desc" key={i*1000}>{moment.description}</Text>
@@ -164,6 +165,6 @@ export default function HistoryItem(props: { data: any, preData: any, index: num
                 </View>
             }
         </View>
-        <View className="border_footer_line" />
+        <View className="seperate_light_line" />
     </View>
 }

+ 19 - 11
src/features/health/MainConsole.scss

@@ -4,8 +4,12 @@
     align-items: center;
     padding-right: 40px;
     position: relative;
-    padding-left: 64px;
-    height: 172px;
+    padding-left: 52px;
+    background-color: #fff;
+}
+
+.cell_hover {
+  background-color: #E5E5E5;
 }
 
 .timeline_left {
@@ -14,10 +18,10 @@
     width: 300px;
 }
 
-.timeline_title {
-    font-size: 34px;
-    line-height: 42px;
-    color: #808080;
+.timeline_time {
+    font-size: 24px;
+    line-height: 36px;
+    color: #999999;
     overflow: hidden;
     width: 500px;
     white-space: nowrap;
@@ -28,9 +32,16 @@
     text-overflow: ellipsis; // 超出部分显示省略号
 }
 
+.timeline_title {
+  font-size: 34px;
+  color: #999;
+  line-height: 46px;
+  
+}
+
 .timeline_desc {
     font-size: 24px;
-    line-height: 28px;
+    line-height: 34px;
     width: 500px;
     color: #B2B2B2;
     white-space: nowrap;
@@ -46,10 +57,7 @@
     margin-top: 5px;
 }
 
-.timeline_time {
-    font-size: 34px;
-    color: #4D4D4D;
-}
+
 
 .timeline_operate {
     height: 72px;

+ 53 - 17
src/features/health/MainConsole.tsx

@@ -21,6 +21,7 @@ import { systemLocation } from "@/services/common";
 import { TimeFormatter } from "@/utils/time_format";
 import { clearLocation } from "@/services/user";
 import OnBoard from "@/_health/components/onboard";
+import NewButton, { NewButtonType } from "@/_health/base/new_button";
 
 let useNavigation;
 let min = 0
@@ -169,9 +170,25 @@ export default function MainConsole(props: { type: WindowType }) {
 
             }
             else if (health.mode == 'ACTIVE' && item.action == 'POST_MOMENT') {
-                return <View className="timeline_operate" style={{ color: themeColor, backgroundColor: '#fff', borderColor: themeColor, borderWidth: 1, borderStyle: 'solid' }} onClick={() => record(item)}>{operateTitle(item)}</View>
+                return <NewButton
+                color={themeColor}
+                type={NewButtonType.border}
+                title={operateTitle(item)}
+                width={rpxToPx(128)}
+                height={rpxToPx(72)}
+                bold={true}
+                onClick={() => record(item)} />
+                // return <View className="timeline_operate" style={{ color: themeColor, backgroundColor: '#fff', borderColor: themeColor, borderWidth: 1, borderStyle: 'solid' }} 
+                // onClick={() => record(item)}>{operateTitle(item)}</View>
             }
-            return <View className="timeline_operate" style={{ color: themeColor, backgroundColor: themeColor + '1A' }} onClick={() => record(item)}>{operateTitle(item)}</View>
+            return <NewButton
+                color={themeColor}
+                type={NewButtonType.alpha}
+                title={operateTitle(item)}
+                width={rpxToPx(128)}
+                height={rpxToPx(72)}
+                bold={true}
+                onClick={() => record(item)} />
         }
 
         return <View />
@@ -192,22 +209,44 @@ export default function MainConsole(props: { type: WindowType }) {
     }
 
     function timelineItem(item: any, index: number, count: number) {
-        return <View key={index} className="timeline_item" onClick={() => tapTimeline(item, index)}>
+        var hasDescription = item.moment && item.moment.description
+        return <View key={index}
+            className="timeline_item"
+            // hoverClass='cell_hover' hoverStayTime={50}
+            onClick={() => tapTimeline(item, index)}>
             <View className="timeline_left">
-                <View style={{ display: 'flex', flexDirection: 'row', alignItems: 'center', height: rpxToPx(28) }}>
-                    {
+                {/* space */}
+                <View style={{
+
+                    height: hasDescription ? rpxToPx(28) : rpxToPx(36), flexShrink: 0
+                }} />
+                <View style={{ display: 'flex', flexDirection: 'row', alignItems: 'center' }}>
+                    {/* {
                         !item.reminder && <Image src={require('@assets/images/notification_off.png')} className='notification_icon' />
-                    }
-                    <Text className="timeline_title">{itemTitle(item)}</Text>
+                    } */}
+                    <View style={{
+                        flexShrink: 0,
+                        width: rpxToPx(28),
+                        height: rpxToPx(28),
+                        borderRadius: rpxToPx(14),
+                        marginRight: rpxToPx(8),
+                        backgroundColor: 'gray'
+                    }} />
+                    <Text className="timeline_time">{itemTitle(item)}</Text>
                 </View>
 
 
-                <View style={{ display: 'flex', flexDirection: 'row', alignItems: 'center', marginTop: rpxToPx(5) }}>
-                    <Text className="timeline_time" onClick={() => edit(item)}>{item.title}</Text>
-                </View>
+                <Text className="timeline_title"
+                    onClick={() => edit(item)}>{(item.moment && item.moment.title) ? item.moment.title : item.title}</Text>
+
                 {
-                    (item.moment && item.moment.description) ? <Text className="timeline_desc">{item.moment.description}</Text> : <View className="timeline_thirdspace" />
+                    hasDescription && <Text className="timeline_desc">{item.moment.description}</Text>
                 }
+                {/* space */}
+                <View style={{
+                    height: hasDescription ? rpxToPx(28) : rpxToPx(54), flexShrink: 0,
+
+                }} />
 
             </View>
             <View style={{ flex: 1 }} />
@@ -221,10 +260,7 @@ export default function MainConsole(props: { type: WindowType }) {
             {
                 itemValue(item)
             }
-            {/* {
-                item.action && item.action != 'NA' && 
-            } */}
-            <View className="border_footer_line" style={{ left: count - 1 == index ? -rpxToPx(64) : rpxToPx(64) }} />
+            <View className="seperate_line" style={{ left: count - 1 == index ? -rpxToPx(52) : rpxToPx(52) }} />
         </View>
     }
 
@@ -552,7 +588,7 @@ export default function MainConsole(props: { type: WindowType }) {
         switch (health.mode) {
             case 'DAY':
                 list = day.timeline
-                if (active.onboard == false) {
+                if (day.onboard == false) {
                     return <OnBoard title='你还没有开启位置授权'
                         desc="获取准确的日出日落信息需要您开启微信运动授权,点击下方按钮进行授权"
                         btnTitle="去开启"
@@ -562,7 +598,7 @@ export default function MainConsole(props: { type: WindowType }) {
                 break;
             case 'NIGHT':
                 list = night.timeline
-                if (active.onboard == false) {
+                if (night.onboard == false) {
                     return <OnBoard title='你还没有开启位置授权'
                         desc='获取准确的日出日落信息需要您开启微信运动授权,点击下方按钮进行授权'
                         btnTitle="去开启"

+ 9 - 0
src/features/health/hooks/health_hooks.tsx

@@ -54,6 +54,15 @@ export function getWindowStatus(windows: any, mode: any): WindowStatusType {
     if (scenario.real) {
         return WindowStatusType.process//'In progress'
     }
+    // if (!scenario.onboard && (mode=='DAY'||mode=='NIGHT')){
+    //     var hour = new Date().getHours()
+    //     if (mode == 'DAY'){
+    //         return (hour>=6 && hour<18)?WindowStatusType.open:WindowStatusType.upcoming
+    //     }
+    //     else if (mode == 'NIGHT'){
+    //         return (hour>=6 && hour<18)?WindowStatusType.upcoming:WindowStatusType.open
+    //     }
+    // }
     const now = new Date().getTime()
     if (now >= scenario.target.start_timestamp && now < scenario.target.end_timestamp) {
         return WindowStatusType.open//'Now open'

+ 0 - 10
src/pages/account/Album.scss

@@ -8,16 +8,6 @@
     padding-right: 42px;
 }
 
-.album_line{
-    position: absolute;
-    left: 0;
-    right: 0;
-    bottom: 0;
-    height: 2px;
-    transform: scaleY(0.5);
-    background-color: #B2B2B2;
-    opacity: 0.2;
-}
 
 .photo_wall_text{
     color: #5C7099;

+ 1 - 1
src/pages/account/Album.tsx

@@ -66,7 +66,7 @@ export default function Album() {
                             })
                         }
                     </View>
-                    <View className="album_line" />
+                    <View className="seperate_light_line" />
                 </View>
             })
         }

+ 0 - 11
src/pages/account/Journal.scss

@@ -8,17 +8,6 @@
     padding-right: 42px;
 }
 
-.album_line{
-    position: absolute;
-    left: 0;
-    right: 0;
-    bottom: 0;
-    height: 2px;
-    transform: scaleY(0.5);
-    background-color: #B2B2B2;
-    opacity: 0.2;
-}
-
 .photo_wall_text{
     color: #5C7099;
     font-size: 26px;

+ 22 - 21
src/pages/account/Journal.tsx

@@ -23,11 +23,14 @@ export default function Journal() {
                 let array: any = []
                 element.windows.map(item => {
                     item.events.map(event => {
-                        if (event.moment && event.moment.media && event.moment.media.length > 0) {
-                            event.moment.media.map(media => {
-                                array.push(media.url)
-                            })
-                        }
+                        event.moments && event.moments.map(moment => {
+                            if (moment.media && moment.media.length > 0) {
+                                moment.media.map(media => {
+                                    array.push(media.url)
+                                })
+                            }
+                        })
+
                     })
                 })
                 element.imgs = array
@@ -37,15 +40,12 @@ export default function Journal() {
     }
 
     function getTitle(item) {
+        if (item.title) {
+            return item.title;
+        }
         if (item.moment) {
             return item.moment.title
         }
-        if (item.window == 'FAST') {
-            return '开始断食'
-        }
-        else if (item.window == 'SLEEP') {
-            return '开始睡眠'
-        }
         return ''
     }
 
@@ -53,27 +53,28 @@ export default function Journal() {
     return <View style={{ display: 'flex', flexDirection: 'column' }}>
         {
             journals.map((item, index) => {
-                return <View className="album_item" key={index} onClick={()=>{
-                    jumpPage('/pages/account/JournalDetail?detail='+JSON.stringify(item))
+                return <View className="album_item" key={index} onClick={() => {
+                    jumpPage('/pages/account/JournalDetail?detail=' + JSON.stringify(item))
                 }}>
                     <Text className="album_date">{(item.date + '').substring(6, 9)}</Text>
                     {
                         item.imgs.length > 0 && <JournalCover imgs={item.imgs} />
                     }
 
-                    <View style={{ display: 'flex', 
-                        flexDirection: 'column', 
-                        flex:1,
+                    <View style={{
+                        display: 'flex',
+                        flexDirection: 'column',
+                        flex: 1,
                         backgroundColor: item.imgs.length == 0 ? '#f5f5f5' : 'transparent',
-                        padding:item.imgs.length == 0 ? rpxToPx(10) : 0,
-                        marginRight:rpxToPx(40)
-                        }}>
+                        padding: item.imgs.length == 0 ? rpxToPx(10) : 0,
+                        marginRight: rpxToPx(40)
+                    }}>
                         {
                             item.windows.map((window, i) => {
                                 return <View key={i * 400} style={{ display: 'flex', flexDirection: 'column' }}>{
                                     window.events.map((item2, index2) => {
                                         return <Text key={index2 * 1000}>
-                                            <Text className="history_item_title">{dayjs(item2.real.start_timestamp).format('HH:mm')} {getTitle(item2)} </Text>
+                                            <Text className="history_item_title">{dayjs(item2.time.timestamp).format('HH:mm')} {getTitle(item2)} </Text>
                                             {
                                                 item2.moment && item2.moment.description && <Text className="history_item_desc">{item2.moment.description}</Text>
                                             }
@@ -85,7 +86,7 @@ export default function Journal() {
                         }
 
                     </View>
-                    <View className="album_line" />
+                    <View className="seperate_light_line" />
                 </View>
             })
         }

+ 103 - 18
src/pages/account/JournalDetail.tsx

@@ -20,6 +20,7 @@ export default function JournalDetail() {
     const user = useSelector((state: any) => state.user);
     const [imgs, setImgs] = useState<any>([])
     const [events, setEvents] = useState<any>([])
+    
     let router
     let navigation;
     if (useNavigation) {
@@ -32,8 +33,8 @@ export default function JournalDetail() {
     else {
         router = useRouter()
     }
-
-    const [detail, setDetail] = useState(JSON.parse(router.params.detail))
+    const [data,setData] = useState<any>(JSON.parse(router.params.detail))
+    // const [detail, setDetail] = useState(JSON.parse(router.params.detail))
 
     useEffect(() => {
         let obj = JSON.parse(router.params.detail)
@@ -48,8 +49,9 @@ export default function JournalDetail() {
             })
         })
         const sortedArray = array.sort((a, b) => {
-            return a.real.start_timestamp - b.real.start_timestamp;
+            return a.time.timestamp - b.time.timestamp;
         });
+        debugger
 
         // 返回一个新数组
         const newArray = [...sortedArray];
@@ -66,29 +68,108 @@ export default function JournalDetail() {
         })
     }
 
+    function eventList(detail, index) {
+        const list = detail.moments
+        return <View key={index}>
+            {
+                (detail.scenario != 'MEAL' && detail.scenario != 'ACTIVITY') && <View style={{ flexDirection: 'column', display: 'flex' }}>
+
+                    <Text className="detail_time">{dayjs(detail.time.timestamp).format('HH:mm')}
+                        {
+                            detail.title && <Text> {detail.title}</Text>
+                        }
+                        {/* {
+                                item.description && <Text style={{ color: '#000' }}> {item.description}</Text>
+                            } */}
+                    </Text>
+
+                    {/* {
+                            item.media && item.media.length > 0 && <Image mode="aspectFill" src={item.media[0].url} style={{ width: 60, height: 60, marginTop: 5 }} />
+                        } */}
+                </View>
+            }
+            {
+                detail.scenario == 'ACTIVITY' && !list && <View style={{ flexDirection: 'column', display: 'flex' }}>
+
+                    <Text className="detail_time">{dayjs(detail.time.timestamp).format('HH:mm')}
+                        {
+                            detail.title && <Text> {detail.title}</Text>
+                        }
+                    </Text>
+
+                    {/* {
+                        item.media && item.media.length > 0 && <Image mode="aspectFill" src={item.media[0].url} style={{ width: 60, height: 60, marginTop: 5 }} />
+                    } */}
+                </View>
+            }
+            {
+                list && list.map((item, index) => {
+                    return <View key={index} style={{ flexDirection: 'column', display: 'flex' }}>
+
+                        <Text className="detail_time">{dayjs(item.time.timestamp).format('HH:mm')}
+                            {
+                                item.title && <Text> {item.title}</Text>
+                            }
+                            {
+                                item.description && <Text style={{ color: '#000' }}> {item.description}</Text>
+                            }
+                        </Text>
+
+                        {/* {
+                            item.media && item.media.length > 0 && <Image mode="aspectFill" src={item.media[0].url} style={{ width: 60, height: 60, marginTop: 5 }} />
+                        } */}
+                    </View>
+                })
+            }
+        </View>
+    }
+
 
     return <View>
         <View className="journal_detail">
             <Image className="header_avatar" src={user.avatar} mode="aspectFill" />
             <View className="jounal_content">
                 <Text className="journal_nickname">{user.nickname}</Text>
-                <View style={{ flexDirection: 'column', display: 'flex',marginTop:rpxToPx(16) }}>
+                <View style={{ flexDirection: 'column', display: 'flex', marginTop: rpxToPx(16) }}>
                     {
                         events.map((item, index) => {
-                            return <View key={index} style={{marginBottom:index<events.length-1?rpxToPx(48):0,display:'flex',flexDirection:'column'}}>
-                                <Text >
-                                {
-                                    item.real && <Text style={{color:'#5C7099'}}>{dayjs(item.real.start_timestamp).format('HH:mm')} </Text>
-                                }
-                                {
-                                    item.moment && item.moment.title && <Text> {item.moment.title} </Text>
-                                }
-                                {
-                                    item.moment && item.moment.description && <Text> {item.moment.description} </Text>
-                                }
-
-                            </Text>
-                            </View>
+                            return eventList(item,index)
+                            // if (item.scenario != 'MEAL' && item.scenario != 'ACTIVITY') {
+                            //     return <View key={index} style={{ marginBottom: index < events.length - 1 ? rpxToPx(48) : 0, display: 'flex', flexDirection: 'column' }}>
+
+                            //         <Text style={{ color: '#5C7099' }}>{dayjs(item.time.timestamp).format('HH:mm')}
+                            //             {
+                            //                 item.title && <Text> {item.title}</Text>
+                            //             }
+                            //         </Text>
+                            //     </View>
+                            // }
+
+                            // if (item.scenario == 'ACTIVITY') {
+                            //     return <View key={index} style={{ marginBottom: index < events.length - 1 ? rpxToPx(48) : 0, display: 'flex', flexDirection: 'column' }}>
+
+                            //         <Text style={{ color: '#5C7099' }}>{dayjs(item.time.timestamp).format('HH:mm')}
+                            //             {
+                            //                 item.title && <Text> {item.title}</Text>
+                            //             }
+                            //         </Text>
+                            //     </View>
+                            // }
+
+                            // return <View key={index} style={{ marginBottom: index < events.length - 1 ? rpxToPx(48) : 0, display: 'flex', flexDirection: 'column' }}>
+                            //     <Text >
+                            //         {
+                            //             item.time && <Text style={{ color: '#5C7099' }}>{dayjs(item.time.timestamp).format('HH:mm')} </Text>
+                            //         }
+                            //         {
+                            //             item.title && <Text> {item.title} </Text>
+                            //         }
+                            //         {
+                            //             item.moments && item.moment.description && <Text> {item.moment.description} </Text>
+                            //         }
+
+                            //     </Text>
+                            // </View>
                         })
                     }
                 </View>
@@ -102,7 +183,11 @@ export default function JournalDetail() {
                         })
                     }
                 </View>
+
+                <Text>发布于{dayjs(data.publish_timestamp).format('MM-DD HH:mm')}</Text>
             </View>
+
+            
         </View>
     </View>
 }

+ 58 - 0
src/pages/clock/ClockNew.tsx

@@ -18,6 +18,8 @@ import Modal from "@/components/layout/Modal.weapp";
 import Streak from "@/features/health/Streak";
 import Calendar from "@/features/health/calendar";
 import { MainColorType } from "@/context/themes/color";
+import NewButton, { NewButtonType } from "@/_health/base/new_button";
+import { getThemeColor } from "@/features/health/hooks/health_hooks";
 
 export default function ClockNew() {
     const [count, setCount] = useState(0)
@@ -70,6 +72,52 @@ export default function ClockNew() {
 
     function getWindows() {
         windows().then(res => {
+            if (!(res as any).windows.night_day.night.target) {
+                var date = new Date()
+                var hour = date.getHours()
+                if (hour >= 6 && hour < 18) {
+                    var date1 = new Date()
+                    date1.setHours(6)
+                    date1.setMinutes(0)
+                    date1.setSeconds(0)
+
+                    var date2 = new Date()
+                    date2.setHours(18)
+                    date2.setMinutes(0)
+                    date2.setSeconds(0);
+
+                    (res as any).windows.night_day.day.target = {
+                        start_timestamp: date1.getTime(),
+                        end_timestamp: date2.getTime(),
+                        duration: 12 * 60 * 60 * 1000
+                    };
+
+                    (res as any).windows.night_day.night.target = {
+                        start_timestamp: date2.getTime(),
+                        end_timestamp: date2.getTime() + 12 * 60 * 60 * 1000,
+                        duration: 12 * 60 * 60 * 1000
+                    }
+                }
+                else {
+                    var date1 = new Date()
+                    date1.setHours(18)
+                    date1.setMinutes(0)
+                    date1.setSeconds(0);
+
+                    (res as any).windows.night_day.day.target = {
+                        start_timestamp: date1.getTime(),
+                        end_timestamp: date1.getTime() + 12 * 60 * 60 * 1000,
+                        duration: 12 * 60 * 60 * 1000
+                    };
+
+                    (res as any).windows.night_day.night.target = {
+                        start_timestamp: date1.getTime() + 12 * 60 * 60 * 1000,
+                        end_timestamp: date1.getTime() + 12 * 60 * 60 * 1000 + 12 * 60 * 60 * 1000,
+                        duration: 12 * 60 * 60 * 1000
+                    }
+                }
+            }
+
             dispatch(setWindows((res as any).windows))
             dispatch(setRefreshs((res as any).refresh_timestamps))
         })
@@ -120,6 +168,16 @@ export default function ClockNew() {
             {/* <View onClick={() => {
                 setShowCalendar(true)
             }}>Show Calendar</View> */}
+            {/* <NewButton color={getThemeColor('SLEEP')}/> */}
+            {/* <View style={{ backgroundColor: '#fff' }}>
+                <NewButton type={NewButtonType.fill} color={getThemeColor('SLEEP')} title="hello world" onClick={()=>{}}/>
+                <NewButton type={NewButtonType.alpha} color={getThemeColor('SLEEP')} title="hello world" onClick={()=>{}}/>
+                <NewButton type={NewButtonType.fill} color={getThemeColor('SLEEP')} disable title="hello world" />
+                <NewButton type={NewButtonType.alpha} color={getThemeColor('SLEEP')} disable title="hello world" />
+                <NewButton type={NewButtonType.border} color={getThemeColor('SLEEP')} title="hello world" onClick={()=>{}}/>
+                <NewButton type={NewButtonType.border} color={getThemeColor('SLEEP')} disable title="hello world" />s
+            </View> */}
+
             <MainHistory type={type} />
             <View style={{ height: 2200 }} />
         </ScrollView>