Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
飞
飞鹤小程序
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
FH
飞鹤小程序
Commits
6bedfe80
Commit
6bedfe80
authored
Jul 17, 2025
by
spc
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
123
parent
75d186ae
Changes
11
Show whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
1244 additions
and
0 deletions
+1244
-0
pages.json
pages.json
+8
-0
demo.png
pages/feedingRecord/demo.png
+0
-0
feedingRecord.vue
pages/feedingRecord/feedingRecord.vue
+1236
-0
dropDown.png
static/feedingRecord/v1/dropDown.png
+0
-0
dropUp.png
static/feedingRecord/v1/dropUp.png
+0
-0
icon_analysis.png
static/feedingRecord/v1/icon_analysis.png
+0
-0
icon_arrow_yellow.png
static/feedingRecord/v1/icon_arrow_yellow.png
+0
-0
icon_fushi.png
static/feedingRecord/v1/icon_fushi.png
+0
-0
icon_muru.png
static/feedingRecord/v1/icon_muru.png
+0
-0
icon_naifen.png
static/feedingRecord/v1/icon_naifen.png
+0
-0
icon_pingwei.png
static/feedingRecord/v1/icon_pingwei.png
+0
-0
No files found.
pages.json
View file @
6bedfe80
...
@@ -78,6 +78,14 @@
...
@@ -78,6 +78,14 @@
"enablePullDownRefresh"
:
false
,
"enablePullDownRefresh"
:
false
,
"navigationStyle"
:
"custom"
"navigationStyle"
:
"custom"
}
}
},
{
"path"
:
"pages/feedingRecord/feedingRecord"
,
"style"
:
{
"navigationBarTitleText"
:
""
,
"navigationStyle"
:
"custom"
}
}
}
],
],
"globalStyle"
:
{
"globalStyle"
:
{
...
...
pages/feedingRecord/demo.png
0 → 100644
View file @
6bedfe80
65.1 KB
pages/feedingRecord/feedingRecord.vue
0 → 100644
View file @
6bedfe80
<
template
>
<view
class=
"feeding-record-page"
>
<!-- 状态栏占位 -->
<view
class=
"status-bar-placeholder"
></view>
<!-- 头部导航 -->
<view
class=
"header"
>
<view
class=
"nav-left"
>
<text
class=
"back-btn"
>
‹
</text>
<view
class=
"baby-info"
>
<text
class=
"baby-name"
>
小糖豆3123 ♂
</text>
<text
class=
"baby-age"
>
1岁24天
</text>
</view>
</view>
<view
class=
"nav-right"
>
<text
class=
"menu-btn"
>
⋯
</text>
</view>
</view>
<!-- 日期选择器和统计按钮 -->
<view
class=
"date-stats-row"
>
<view
class=
"date-selector"
>
<uni-datetime-picker
ref=
"datePickerRef"
v-model=
"currentSelectedDate"
type=
"date"
:start=
"earliestDateString"
:end=
"todayDateString"
@
change=
"onDateChange"
:clear-icon=
"false"
:border=
"false"
>
<view
class=
"date-display"
>
<text
class=
"date-text"
>
{{
formatCurrentDate
()
}}
</text>
</view>
</uni-datetime-picker>
</view>
<view
class=
"stats-section"
>
<text
class=
"stats-btn"
>
📊 统计
</text>
<text
class=
"dropdown-icon"
>
▼
</text>
</view>
</view>
<!-- 日历组件 -->
<view
class=
"calendar-wrapper"
>
<!-- 星期标题 -->
<view
class=
"weekday-row"
>
<view
class=
"weekday-cell"
v-for=
"day in weekdays"
:key=
"day"
>
{{
day
}}
</view>
</view>
<!-- 日期网格 -->
<view
class=
"date-grid"
:class=
"
{ 'collapsed': !isCalendarExpanded }">
<view
v-for=
"(date, index) in calendarDates"
:key=
"date.dateString"
class=
"date-cell"
:class=
"
{
'selected': date.isSelected,
'today': date.isToday,
'other-month': !date.isCurrentMonth,
'future': date.isFuture,
'past-with-record': date.isPast
&&
hasRecordOnDate(date.dateString)
&&
date.isCurrentMonth,
'past-no-record': date.isPast
&&
!hasRecordOnDate(date.dateString)
&&
date.isCurrentMonth,
'other-month-clickable': !date.isCurrentMonth
&&
!date.isFuture,
'disabled': date.isFuture
}" @click="selectDate(date)">
<text
class=
"date-text"
>
{{
date
.
isToday
?
'今'
:
date
.
day
}}
</text>
<view
v-if=
"hasRecordOnDate(date.dateString)"
class=
"record-indicator"
></view>
</view>
</view>
<!-- 选中日期指示器 -->
<!--
<view
v-if=
"!isCalendarExpanded"
class=
"date-indicator"
>
<view
class=
"triangle-down"
></view>
</view>
-->
<!-- 展开/收起按钮 -->
<view
class=
"expand-btn"
@
click=
"toggleCalendarExpand"
>
<image
:src=
"feedingRecordRes[isCalendarExpanded ? 'dropUp' : 'dropDown']"
class=
"expand-icon"
mode=
"aspectFit"
/>
</view>
</view>
<!-- 喂养记录列表 -->
<scroll-view
class=
"records-container"
scroll-y
>
<view
v-if=
"todayRecords.length === 0"
class=
"empty-state"
>
<text
class=
"empty-text"
>
当日暂无记录
</text>
</view>
<view
v-else
class=
"record-list"
>
<template
v-for=
"(record, index) in todayRecords"
:key=
"index"
>
<view
class=
"record-item"
>
<view
class=
"time-dot"
>
<view
class=
"dot"
:style=
"
{ backgroundColor: getRecordColor(record.type) }">
</view>
<text
class=
"time"
>
{{
record
.
time
}}
</text>
</view>
<view
class=
"record-content"
:style=
"
{ backgroundColor: getRecordBgColor(record.type) }">
<view
class=
"record-header"
>
<view
class=
"record-icon"
>
{{
getRecordIcon
(
record
.
type
)
}}
</view>
<text
class=
"record-type"
>
{{
record
.
type
}}
</text>
<text
class=
"edit-btn"
@
click=
"editRecord(index)"
>
修改
</text>
</view>
<view
class=
"record-details"
>
<view
v-if=
"record.leftDuration || record.rightDuration"
class=
"duration-info"
>
<text
v-if=
"record.leftDuration"
>
左
{{
record
.
leftDuration
}}
</text>
<text
v-if=
"record.rightDuration"
>
右
{{
record
.
rightDuration
}}
</text>
</view>
<view
v-if=
"record.amount"
class=
"amount-info"
>
<text>
总奶量 约
{{
record
.
amount
}}
</text>
</view>
<view
v-if=
"record.content"
class=
"content-info"
>
<text>
{{
record
.
content
}}
</text>
</view>
</view>
</view>
</view>
<!-- 在两个记录之间添加连接线 -->
<view
v-if=
"index
<
todayRecords
.
length
-
1
"
class=
"timeline-connector"
></view>
</
template
>
</view>
</scroll-view>
<!-- 底部添加按钮 -->
<view
class=
"bottom-add-btn"
@
click=
"addFeedingRecord"
>
<text
class=
"add-text"
>
添加记录
</text>
</view>
<!-- 添加记录弹窗 -->
<view
class=
"popup-mask"
v-if=
"showPopup"
@
click=
"closePopup"
>
<view
class=
"popup-content"
@
click
.
stop
>
<view
class=
"popup-title"
>
添加喂养记录
</view>
<view
class=
"form-item"
>
<text
class=
"label"
>
时间:
</text>
<picker
mode=
"time"
:value=
"newRecord.time"
@
change=
"onTimeChange"
>
<view
class=
"picker"
>
{{ newRecord.time || '请选择时间' }}
</view>
</picker>
</view>
<view
class=
"form-item"
>
<text
class=
"label"
>
类型:
</text>
<picker
:range=
"feedingTypes"
@
change=
"onTypeChange"
>
<view
class=
"picker"
>
{{ newRecord.type || '请选择类型' }}
</view>
</picker>
</view>
<view
class=
"form-item"
>
<text
class=
"label"
>
内容:
</text>
<input
class=
"input"
v-model=
"newRecord.content"
placeholder=
"请输入具体内容"
maxlength=
"50"
/>
</view>
<view
class=
"popup-buttons"
>
<button
class=
"cancel-btn"
@
click=
"closePopup"
>
取消
</button>
<button
class=
"confirm-btn"
@
click=
"saveRecord"
>
保存
</button>
</view>
</view>
</view>
</view>
</template>
<
script
setup
>
import
{
ref
,
computed
,
onMounted
,
watch
,
nextTick
}
from
'vue'
import
{
onLoad
}
from
'@dcloudio/uni-app'
const
version
=
'v1'
const
feedingRecordRes
=
{
dropDown
:
`/static/feedingRecord/
${
version
}
/dropDown.png`
,
dropUp
:
`/static/feedingRecord/
${
version
}
/dropUp.png`
,
icon_analysis
:
`/static/feedingRecord/
${
version
}
/icon_analysis.png`
,
icon_arrow_yellow
:
`/static/feedingRecord/
${
version
}
/icon_arrow_yellow.png`
,
icon_fushi
:
`/static/feedingRecord/
${
version
}
/icon_fushi.png`
,
icon_muru
:
`/static/feedingRecord/
${
version
}
/icon_muru.png`
,
icon_naifen
:
`/static/feedingRecord/
${
version
}
/icon_naifen.png`
,
icon_pingwei
:
`/static/feedingRecord/
${
version
}
/icon_pingwei.png`
,
}
// 响应式数据
const
currentSelectedDate
=
ref
(
''
)
const
showPopup
=
ref
(
false
)
const
isCalendarExpanded
=
ref
(
false
)
const
currentDate
=
ref
(
new
Date
())
const
datePickerRef
=
ref
(
null
)
// 添加一个强制更新标志
const
forceUpdate
=
ref
(
0
)
// 添加当前显示月份的字符串表示,确保响应性
const
currentMonthKey
=
ref
(
''
)
// 新记录表单
const
newRecord
=
ref
({
time
:
''
,
type
:
''
,
leftDuration
:
''
,
rightDuration
:
''
,
amount
:
''
,
content
:
''
})
// 喂养类型选项
const
feedingTypes
=
[
'母乳喂养'
,
'奶粉喂养'
,
'辅食'
,
'水果'
,
'其他'
]
// 星期标题
const
weekdays
=
[
'日'
,
'一'
,
'二'
,
'三'
,
'四'
,
'五'
,
'六'
]
// 喂养记录数据
const
feedingRecords
=
ref
({
'2025-06-03'
:
[
{
time
:
'06:20'
,
type
:
'母乳喂养'
,
leftDuration
:
'10min'
,
rightDuration
:
'10min'
},
{
time
:
'09:30'
,
type
:
'母乳喂养'
,
amount
:
'约50ml'
},
{
time
:
'13:50'
,
type
:
'奶粉喂养'
,
amount
:
'约50ml'
},
{
time
:
'17:25'
,
type
:
'辅食'
,
content
:
'小米粥、玉米、馒头、蒸面条、包子、奶粉...'
}
],
'2025-06-02'
:
[
{
time
:
'07:00'
,
type
:
'母乳喂养'
,
leftDuration
:
'12min'
,
rightDuration
:
'8min'
},
{
time
:
'11:30'
,
type
:
'奶粉喂养'
,
amount
:
'约80ml'
}
],
'2025-06-01'
:
[
{
time
:
'08:00'
,
type
:
'母乳喂养'
,
leftDuration
:
'15min'
,
rightDuration
:
'10min'
}
],
'2025-05-31'
:
[
{
time
:
'09:15'
,
type
:
'母乳喂养'
,
leftDuration
:
'8min'
,
rightDuration
:
'12min'
}
],
'2025-05-30'
:
[
{
time
:
'10:00'
,
type
:
'奶粉喂养'
,
amount
:
'约60ml'
}
],
'2025-07-01'
:
[
{
time
:
'08:30'
,
type
:
'母乳喂养'
,
leftDuration
:
'15min'
,
rightDuration
:
'12min'
}
],
'2025-04-25'
:
[
{
time
:
'14:00'
,
type
:
'辅食'
,
content
:
'苹果泥、香蕉'
}
]
})
// 计算属性 - 当前选中日期的记录
const
todayRecords
=
computed
(()
=>
{
if
(
!
currentSelectedDate
.
value
)
return
[]
return
feedingRecords
.
value
[
currentSelectedDate
.
value
]
||
[]
})
// 计算属性 - 今天的日期字符串(用于限制uni-datetime-picker)
const
todayDateString
=
computed
(()
=>
{
const
today
=
new
Date
()
const
dateStr
=
formatDateString
(
today
)
console
.
log
(
'uni-datetime-picker最大可选日期:'
,
dateStr
)
return
dateStr
})
// 计算属性 - 最早可选日期(往前一年)
const
earliestDateString
=
computed
(()
=>
{
const
today
=
new
Date
()
const
earliestDate
=
new
Date
(
today
.
getFullYear
()
-
1
,
today
.
getMonth
(),
today
.
getDate
())
const
dateStr
=
formatDateString
(
earliestDate
)
console
.
log
(
'uni-datetime-picker最早可选日期:'
,
dateStr
)
return
dateStr
})
// 获取日历数据
const
calendarDates
=
computed
(()
=>
{
// 依赖多个响应性值来确保更新
const
updateFlag
=
forceUpdate
.
value
const
monthKey
=
currentMonthKey
.
value
const
year
=
currentDate
.
value
.
getFullYear
()
const
month
=
currentDate
.
value
.
getMonth
()
console
.
log
(
`====== 重新计算日历数据 (
${
updateFlag
}
) ======`
)
console
.
log
(
`计算属性触发 - 年月:
${
year
}
-
${
month
+
1
}
, 月份键:
${
monthKey
}
`
)
console
.
log
(
`当前选中日期:
${
currentSelectedDate
.
value
}
`
)
console
.
log
(
`日历展开状态:
${
isCalendarExpanded
.
value
}
`
)
// 获取当月第一天
const
firstDay
=
new
Date
(
year
,
month
,
1
)
// 获取第一周的开始日期(周日为0)
const
startDate
=
new
Date
(
firstDay
)
startDate
.
setDate
(
firstDay
.
getDate
()
-
firstDay
.
getDay
())
const
dates
=
[]
// 如果是收起状态,只显示包含选中日期的那一周
if
(
!
isCalendarExpanded
.
value
&&
currentSelectedDate
.
value
)
{
const
selectedDate
=
new
Date
(
currentSelectedDate
.
value
)
const
selectedDayOfWeek
=
selectedDate
.
getDay
()
const
weekStartDate
=
new
Date
(
selectedDate
)
weekStartDate
.
setDate
(
selectedDate
.
getDate
()
-
selectedDayOfWeek
)
for
(
let
i
=
0
;
i
<
7
;
i
++
)
{
const
date
=
new
Date
(
weekStartDate
)
date
.
setDate
(
weekStartDate
.
getDate
()
+
i
)
dates
.
push
(
createDateObject
(
date
))
}
}
else
{
// 展开状态显示完整月份(6周)
for
(
let
i
=
0
;
i
<
42
;
i
++
)
{
const
date
=
new
Date
(
startDate
)
date
.
setDate
(
startDate
.
getDate
()
+
i
)
dates
.
push
(
createDateObject
(
date
))
}
}
return
dates
})
// 方法
function
createDateObject
(
date
)
{
const
today
=
new
Date
()
const
currentMonth
=
currentDate
.
value
.
getMonth
()
const
currentYear
=
currentDate
.
value
.
getFullYear
()
const
dateString
=
formatDateString
(
date
)
// 创建只包含日期部分的Date对象进行比较
const
dateOnly
=
new
Date
(
date
.
getFullYear
(),
date
.
getMonth
(),
date
.
getDate
())
const
todayOnly
=
new
Date
(
today
.
getFullYear
(),
today
.
getMonth
(),
today
.
getDate
())
const
isCurrentMonth
=
date
.
getMonth
()
===
currentMonth
&&
date
.
getFullYear
()
===
currentYear
const
isToday
=
isSameDay
(
date
,
today
)
const
isFuture
=
dateOnly
>
todayOnly
const
isPast
=
dateOnly
<
todayOnly
// 简化调试:只输出7月前几天的状态
if
(
date
.
getMonth
()
===
6
&&
date
.
getFullYear
()
===
2025
&&
date
.
getDate
()
<=
5
)
{
const
status
=
isToday
?
'今天'
:
isFuture
?
'未来'
:
'过去'
console
.
log
(
`7月
${
date
.
getDate
()}
日:
${
status
}
, 当月=
${
isCurrentMonth
}
`
)
// 检查bug
if
(
currentYear
===
2025
&&
currentMonth
===
6
&&
!
isCurrentMonth
)
{
console
.
error
(
`❌ BUG: 7月
${
date
.
getDate
()}
日被错误标记为非当月!`
)
}
}
return
{
date
:
new
Date
(
date
),
day
:
date
.
getDate
(),
dateString
,
isToday
,
isCurrentMonth
,
isSelected
:
currentSelectedDate
.
value
===
dateString
,
isFuture
,
isPast
}
}
function
selectDate
(
dateObj
)
{
// 只禁止选择未来日期
if
(
dateObj
.
isFuture
)
{
console
.
log
(
'不能选择未来日期:'
,
dateObj
.
dateString
)
return
}
console
.
log
(
'====== selectDate ======'
)
console
.
log
(
'点击日期:'
,
dateObj
.
dateString
,
'当月:'
,
dateObj
.
isCurrentMonth
)
// 选择日期
currentSelectedDate
.
value
=
dateObj
.
dateString
// 如果点击的是非当月日期,切换到该日期所在的月份
if
(
!
dateObj
.
isCurrentMonth
)
{
console
.
log
(
'切换到:'
,
dateObj
.
date
.
getFullYear
(),
'年'
,
dateObj
.
date
.
getMonth
()
+
1
,
'月'
)
// 直接设置新的日期和月份键
const
newCurrentDate
=
new
Date
(
dateObj
.
date
.
getFullYear
(),
dateObj
.
date
.
getMonth
(),
1
)
const
newMonthKey
=
`
${
dateObj
.
date
.
getFullYear
()}
-
${
dateObj
.
date
.
getMonth
()}
`
console
.
log
(
'设置新月份:'
,
newMonthKey
)
// 同步更新所有相关状态
currentDate
.
value
=
newCurrentDate
currentMonthKey
.
value
=
newMonthKey
forceUpdate
.
value
++
// 切换月份时,如果日历是收起状态,自动展开以显示完整月份
if
(
!
isCalendarExpanded
.
value
)
{
console
.
log
(
'自动展开日历'
)
isCalendarExpanded
.
value
=
true
}
console
.
log
(
'月份切换完成'
)
}
}
function
toggleCalendarExpand
()
{
isCalendarExpanded
.
value
=
!
isCalendarExpanded
.
value
}
function
onDateChange
(
event
)
{
if
(
event
)
{
console
.
log
(
'====== uni-datetime-picker变化 ======'
)
console
.
log
(
'选择的日期:'
,
event
)
// 验证选择的日期不能是未来日期
const
selectedDate
=
new
Date
(
event
)
const
today
=
new
Date
()
const
todayOnly
=
new
Date
(
today
.
getFullYear
(),
today
.
getMonth
(),
today
.
getDate
())
const
selectedOnly
=
new
Date
(
selectedDate
.
getFullYear
(),
selectedDate
.
getMonth
(),
selectedDate
.
getDate
())
if
(
selectedOnly
>
todayOnly
)
{
console
.
warn
(
'警告:尝试选择未来日期,已阻止'
)
uni
.
showToast
({
title
:
'不能选择未来日期'
,
icon
:
'none'
})
return
}
currentSelectedDate
.
value
=
event
// 计算新的月份(使用已声明的selectedDate变量)
const
newCurrentDate
=
new
Date
(
selectedDate
.
getFullYear
(),
selectedDate
.
getMonth
(),
1
)
const
newMonthKey
=
`
${
selectedDate
.
getFullYear
()}
-
${
selectedDate
.
getMonth
()}
`
console
.
log
(
'设置新月份:'
,
newMonthKey
)
// 同步更新所有相关状态
currentDate
.
value
=
newCurrentDate
currentMonthKey
.
value
=
newMonthKey
forceUpdate
.
value
++
console
.
log
(
'uni-datetime-picker月份切换完成'
)
}
}
function
formatCurrentDate
()
{
if
(
!
currentSelectedDate
.
value
)
return
''
const
date
=
new
Date
(
currentSelectedDate
.
value
)
const
year
=
date
.
getFullYear
()
const
month
=
String
(
date
.
getMonth
()
+
1
).
padStart
(
2
,
'0'
)
const
day
=
String
(
date
.
getDate
()).
padStart
(
2
,
'0'
)
return
`
${
year
}
年
${
month
}
月
${
day
}
日`
}
function
hasRecordOnDate
(
date
)
{
return
feedingRecords
.
value
[
date
]
&&
feedingRecords
.
value
[
date
].
length
>
0
}
function
getRecordIcon
(
type
)
{
const
icons
=
{
'母乳喂养'
:
'🤱'
,
'奶粉喂养'
:
'🍼'
,
'辅食'
:
'🥄'
,
'水果'
:
'🍎'
,
'其他'
:
'📝'
}
return
icons
[
type
]
||
'📝'
}
function
getRecordColor
(
type
)
{
// 统一使用 #d3a358 颜色
return
'#d3a358'
}
function
getRecordBgColor
(
type
)
{
const
colors
=
{
'母乳喂养'
:
'#FDF2F8'
,
'奶粉喂养'
:
'#F3F4F6'
,
'辅食'
:
'#FFFBEB'
,
'水果'
:
'#F0FDF4'
,
'其他'
:
'#FEF2F2'
}
return
colors
[
type
]
||
'#FEF2F2'
}
function
editRecord
(
index
)
{
// 编辑记录功能
uni
.
showToast
({
title
:
'编辑功能'
,
icon
:
'none'
})
}
function
addFeedingRecord
()
{
if
(
!
currentSelectedDate
.
value
)
{
uni
.
showToast
({
title
:
'请先选择日期'
,
icon
:
'none'
})
return
}
// 重置表单
newRecord
.
value
=
{
time
:
getCurrentTime
(),
type
:
''
,
content
:
''
}
showPopup
.
value
=
true
}
function
onTimeChange
(
event
)
{
newRecord
.
value
.
time
=
event
.
detail
.
value
}
function
onTypeChange
(
event
)
{
newRecord
.
value
.
type
=
feedingTypes
[
event
.
detail
.
value
]
}
function
closePopup
()
{
showPopup
.
value
=
false
}
function
saveRecord
()
{
// 验证表单
if
(
!
newRecord
.
value
.
time
||
!
newRecord
.
value
.
type
||
!
newRecord
.
value
.
content
)
{
uni
.
showToast
({
title
:
'请填写完整信息'
,
icon
:
'none'
})
return
}
// 添加记录
const
dateKey
=
currentSelectedDate
.
value
if
(
!
feedingRecords
.
value
[
dateKey
])
{
feedingRecords
.
value
[
dateKey
]
=
[]
}
feedingRecords
.
value
[
dateKey
].
push
({
time
:
newRecord
.
value
.
time
,
type
:
newRecord
.
value
.
type
,
content
:
newRecord
.
value
.
content
})
// 按时间排序
feedingRecords
.
value
[
dateKey
].
sort
((
a
,
b
)
=>
a
.
time
.
localeCompare
(
b
.
time
))
uni
.
showToast
({
title
:
'保存成功'
,
icon
:
'success'
})
closePopup
()
}
function
deleteRecord
(
index
)
{
uni
.
showModal
({
title
:
'确认删除'
,
content
:
'确定要删除这条喂养记录吗?'
,
success
:
(
res
)
=>
{
if
(
res
.
confirm
)
{
const
dateKey
=
currentSelectedDate
.
value
feedingRecords
.
value
[
dateKey
].
splice
(
index
,
1
)
// 如果没有记录了,删除整个日期键
if
(
feedingRecords
.
value
[
dateKey
].
length
===
0
)
{
delete
feedingRecords
.
value
[
dateKey
]
}
uni
.
showToast
({
title
:
'删除成功'
,
icon
:
'success'
})
}
}
})
}
function
getCurrentTime
()
{
const
now
=
new
Date
()
const
hours
=
String
(
now
.
getHours
()).
padStart
(
2
,
'0'
)
const
minutes
=
String
(
now
.
getMinutes
()).
padStart
(
2
,
'0'
)
return
`
${
hours
}
:
${
minutes
}
`
}
function
formatDateString
(
date
)
{
const
year
=
date
.
getFullYear
()
const
month
=
String
(
date
.
getMonth
()
+
1
).
padStart
(
2
,
'0'
)
const
day
=
String
(
date
.
getDate
()).
padStart
(
2
,
'0'
)
return
`
${
year
}
-
${
month
}
-
${
day
}
`
}
function
isSameDay
(
date1
,
date2
)
{
return
date1
.
getFullYear
()
===
date2
.
getFullYear
()
&&
date1
.
getMonth
()
===
date2
.
getMonth
()
&&
date1
.
getDate
()
===
date2
.
getDate
()
}
// 生命周期
onLoad
(()
=>
{
// 使用真实的今天日期
const
today
=
new
Date
()
const
todayString
=
formatDateString
(
today
)
currentSelectedDate
.
value
=
todayString
currentDate
.
value
=
new
Date
(
today
.
getFullYear
(),
today
.
getMonth
(),
1
)
// 当前月份的第一天
currentMonthKey
.
value
=
`
${
today
.
getFullYear
()}
-
${
today
.
getMonth
()}
`
// 设置月份键
console
.
log
(
'初始化今日日期:'
,
todayString
,
'当前月份:'
,
currentDate
.
value
,
'月份键:'
,
currentMonthKey
.
value
)
})
// 通用的月份切换处理函数
function
handleMonthChange
(
newDate
,
source
=
'unknown'
)
{
console
.
log
(
`====== 处理月份切换 (
${
source
}
) ======`
)
console
.
log
(
'新月份:'
,
newDate
.
getMonth
()
+
1
)
// 更新月份键,确保响应性
const
newMonthKey
=
`
${
newDate
.
getFullYear
()}
-
${
newDate
.
getMonth
()}
`
console
.
log
(
'更新月份键:'
,
currentMonthKey
.
value
,
'->'
,
newMonthKey
)
currentMonthKey
.
value
=
newMonthKey
// 强制更新
forceUpdate
.
value
++
// 使用nextTick确保DOM更新
nextTick
(()
=>
{
console
.
log
(
`
${
source
}
: nextTick后再次强制更新`
)
forceUpdate
.
value
++
})
}
// 监听currentDate变化
watch
(
currentDate
,
(
newDate
,
oldDate
)
=>
{
console
.
log
(
'====== currentDate变化监听 ======'
)
console
.
log
(
'旧值:'
,
oldDate
)
console
.
log
(
'新值:'
,
newDate
)
console
.
log
(
'新月份:'
,
newDate
.
getMonth
()
+
1
)
// 使用通用处理函数
handleMonthChange
(
newDate
,
'watch'
)
},
{
immediate
:
false
})
onMounted
(()
=>
{
// 组件挂载后的操作
})
</
script
>
<
style
lang=
"scss"
scoped
>
.feeding-record-page
{
min-height
:
100vh
;
background
:
#ffffff
;
position
:
relative
;
}
// 顶部间距占位
.status-bar-placeholder
{
height
:
75rpx
;
background
:
#fef6eb
;
width
:
100%
;
}
// 头部导航
.header
{
display
:
flex
;
justify-content
:
space-between
;
align-items
:
center
;
padding
:
20rpx
30rpx
;
background
:
#fef6eb
;
.nav-left
{
display
:
flex
;
align-items
:
center
;
.back-btn
{
font-size
:
48rpx
;
color
:
#333
;
margin-right
:
20rpx
;
}
.baby-info
{
display
:
flex
;
flex-direction
:
column
;
.baby-name
{
font-size
:
32rpx
;
font-weight
:
600
;
color
:
#333
;
}
.baby-age
{
font-size
:
24rpx
;
color
:
#666
;
margin-top
:
4rpx
;
}
}
}
.nav-right
{
display
:
flex
;
align-items
:
center
;
gap
:
20rpx
;
.menu-btn
{
font-size
:
32rpx
;
color
:
#666
;
}
.stats-btn
{
font-size
:
28rpx
;
color
:
#D4A574
;
font-weight
:
500
;
}
}
}
// 日期选择器和统计按钮行
.date-stats-row
{
display
:
flex
;
justify-content
:
space-between
;
align-items
:
center
;
background
:
#fef6eb
;
padding
:
24rpx
30rpx
;
.date-selector
{
cursor
:
pointer
;
.date-display
{
display
:
flex
;
align-items
:
center
;
}
.date-text
{
font-size
:
28rpx
;
font-weight
:
500
;
color
:
#333
;
}
}
.stats-section
{
display
:
flex
;
align-items
:
center
;
gap
:
8rpx
;
.stats-btn
{
font-size
:
28rpx
;
color
:
#D4A574
;
font-weight
:
500
;
}
.dropdown-icon
{
font-size
:
20rpx
;
color
:
#999
;
}
}
}
// 日历容器
.calendar-wrapper
{
background
:
#fef6eb
;
position
:
relative
;
.weekday-row
{
display
:
flex
;
padding
:
20rpx
30rpx
0
;
.weekday-cell
{
flex
:
1
;
text-align
:
center
;
font-size
:
22rpx
;
color
:
#999
;
height
:
40rpx
;
display
:
flex
;
align-items
:
center
;
justify-content
:
center
;
}
}
.date-grid
{
display
:
grid
;
grid-template-columns
:
repeat
(
7
,
1fr
);
padding
:
0
30rpx
;
transition
:
all
0
.3s
ease
;
&
.collapsed
{
grid-template-rows
:
repeat
(
1
,
1fr
);
overflow
:
hidden
;
max-height
:
80rpx
;
}
&
:not
(
.collapsed
)
{
grid-template-rows
:
repeat
(
6
,
1fr
);
max-height
:
480rpx
;
}
.date-cell
{
height
:
80rpx
;
display
:
flex
;
align-items
:
center
;
justify-content
:
center
;
position
:
relative
;
cursor
:
pointer
;
.date-text
{
font-size
:
28rpx
;
color
:
#333
;
// 默认为当月日期的颜色
font-weight
:
400
;
transition
:
all
0
.2s
ease
;
min-width
:
56rpx
;
height
:
56rpx
;
display
:
flex
;
align-items
:
center
;
justify-content
:
center
;
}
.record-indicator
{
position
:
absolute
;
bottom
:
18rpx
;
left
:
50%
;
transform
:
translateX
(
-50%
);
width
:
6rpx
;
height
:
6rpx
;
background
:
#D4A574
;
border-radius
:
50%
;
}
// 当月日期默认样式(确保优先级)
&
:not
(
.other-month
)
:not
(
.disabled
)
{
.date-text
{
color
:
#333
;
}
}
// 1. 置灰且禁用:未来日期
&
.disabled
{
cursor
:
not
-
allowed
;
.date-text
{
color
:
#ccc
;
}
.record-indicator
{
background
:
#ddd
;
}
}
// 非当月日期(可点击切换月份)
&
.other-month-clickable
{
cursor
:
pointer
;
.date-text
{
color
:
#b0b0b0
;
transition
:
all
0
.2s
ease
;
}
.record-indicator
{
background
:
#d0d0d0
;
}
&
:hover
{
.date-text
{
color
:
#888
;
background
:
rgba
(
212
,
165
,
116
,
0
.1
);
border-radius
:
50%
;
}
}
&
:active
{
.date-text
{
transform
:
scale
(
0
.95
);
}
}
}
// 2. 高亮带黄点:当月已过日期且有喂养记录
&
.past-with-record
:not
(
.selected
)
{
.date-text
{
color
:
#333
;
font-weight
:
500
;
}
}
// 3. 仅高亮无黄点:当月已过日期但无喂养记录
&
.past-no-record
:not
(
.selected
)
{
.date-text
{
color
:
#333
;
font-weight
:
500
;
}
}
// 4. 日期带黄圈:选中状态
&
.selected
{
.date-text
{
background
:
#D4A574
;
color
:
#fff
;
border-radius
:
50%
;
font-weight
:
600
;
}
.record-indicator
{
background
:
#fff
;
}
}
// 5. 当日显示【今】- 已在模板中处理
&
.today
:not
(
.selected
)
{
.date-text
{
background
:
#f5f5f5
;
border-radius
:
50%
;
font-weight
:
600
;
}
}
// 非当月未来日期样式(既是other-month又是future的情况)
&
.other-month.future
{
.date-text
{
color
:
#ddd
;
}
}
// 未来日期样式
&
.future
{
.date-text
{
color
:
#ccc
;
}
}
}
}
.date-indicator
{
position
:
absolute
;
bottom
:
20rpx
;
left
:
50%
;
transform
:
translateX
(
-50%
);
pointer-events
:
none
;
.triangle-down
{
width
:
0
;
height
:
0
;
border-left
:
8rpx
solid
transparent
;
border-right
:
8rpx
solid
transparent
;
border-top
:
8rpx
solid
#D4A574
;
}
}
.expand-btn
{
display
:
flex
;
justify-content
:
center
;
align-items
:
center
;
padding
:
20rpx
;
cursor
:
pointer
;
background
:
white
;
.expand-icon
{
width
:
32rpx
;
height
:
32rpx
;
transition
:
all
0
.3s
ease
;
}
}
}
// 记录容器
.records-container
{
flex
:
1
;
padding
:
20rpx
;
.empty-state
{
display
:
flex
;
justify-content
:
center
;
align-items
:
center
;
height
:
400rpx
;
.empty-text
{
font-size
:
28rpx
;
color
:
#999
;
}
}
.record-list
{
.timeline-connector
{
width
:
1rpx
;
height
:
156rpx
;
background
:
#d3a358
;
margin-left
:
4rpx
;
margin-top
:
-100rpx
;
margin-bottom
:
-60rpx
;
}
.record-item
{
display
:
flex
;
margin-bottom
:
40rpx
;
// 增加间距以容纳连接线
.time-dot
{
width
:
120rpx
;
display
:
flex
;
align-items
:
center
;
margin-right
:
20rpx
;
.dot
{
width
:
12rpx
;
height
:
12rpx
;
border-radius
:
50%
;
margin-right
:
12rpx
;
}
.time
{
font-size
:
24rpx
;
color
:
#666
;
white-space
:
nowrap
;
}
}
.record-content
{
flex
:
1
;
border-radius
:
16rpx
;
padding
:
24rpx
;
.record-header
{
display
:
flex
;
align-items
:
center
;
margin-bottom
:
16rpx
;
.record-icon
{
font-size
:
32rpx
;
margin-right
:
12rpx
;
}
.record-type
{
flex
:
1
;
font-size
:
28rpx
;
font-weight
:
600
;
color
:
#333
;
}
.edit-btn
{
font-size
:
24rpx
;
color
:
#999
;
padding
:
8rpx
16rpx
;
border
:
1rpx
solid
#e0e0e0
;
border-radius
:
20rpx
;
}
}
.record-details
{
.duration-info
{
display
:
flex
;
gap
:
20rpx
;
margin-bottom
:
8rpx
;
text
{
font-size
:
24rpx
;
color
:
#666
;
background
:
rgba
(
255
,
255
,
255
,
0
.8
);
padding
:
6rpx
12rpx
;
border-radius
:
12rpx
;
}
}
.amount-info
{
margin-bottom
:
8rpx
;
text
{
font-size
:
24rpx
;
color
:
#666
;
background
:
rgba
(
255
,
255
,
255
,
0
.8
);
padding
:
6rpx
12rpx
;
border-radius
:
12rpx
;
}
}
.content-info
{
text
{
font-size
:
24rpx
;
color
:
#666
;
line-height
:
1
.5
;
}
}
}
}
}
}
}
// 底部添加按钮
.bottom-add-btn
{
position
:
fixed
;
bottom
:
0
;
left
:
0
;
right
:
0
;
background
:
#D4A574
;
padding
:
30rpx
;
display
:
flex
;
justify-content
:
center
;
align-items
:
center
;
.add-text
{
font-size
:
32rpx
;
color
:
#fff
;
font-weight
:
600
;
}
&
:active
{
background
:
#c19660
;
}
}
// 弹窗样式
.popup-mask
{
position
:
fixed
;
top
:
0
;
left
:
0
;
right
:
0
;
bottom
:
0
;
background
:
rgba
(
0
,
0
,
0
,
0
.5
);
z-index
:
1000
;
display
:
flex
;
align-items
:
flex-end
;
}
.popup-content
{
background
:
#fff
;
width
:
100%
;
border-radius
:
20rpx
20rpx
0
0
;
padding
:
40rpx
30rpx
;
animation
:
slideUp
0
.3s
ease-out
;
max-height
:
80vh
;
overflow-y
:
auto
;
.popup-title
{
font-size
:
36rpx
;
font-weight
:
600
;
color
:
#333
;
text-align
:
center
;
margin-bottom
:
40rpx
;
}
.form-item
{
margin-bottom
:
30rpx
;
.label
{
font-size
:
28rpx
;
color
:
#333
;
margin-bottom
:
12rpx
;
display
:
block
;
}
.picker
,
.input
{
width
:
100%
;
padding
:
24rpx
;
background
:
#f8f9fa
;
border-radius
:
12rpx
;
font-size
:
28rpx
;
color
:
#333
;
border
:
1rpx
solid
#e9ecef
;
box-sizing
:
border-box
;
}
.picker
{
display
:
flex
;
align-items
:
center
;
min-height
:
88rpx
;
}
}
.popup-buttons
{
display
:
flex
;
gap
:
20rpx
;
margin-top
:
50rpx
;
button
{
flex
:
1
;
height
:
88rpx
;
border-radius
:
12rpx
;
font-size
:
32rpx
;
border
:
none
;
font-weight
:
600
;
&
.cancel-btn
{
background
:
#f8f9fa
;
color
:
#6c757d
;
border
:
1rpx
solid
#e9ecef
;
}
&
.confirm-btn
{
background
:
#D4A574
;
color
:
#fff
;
}
&
:active
{
opacity
:
0
.8
;
}
}
}
}
@keyframes
slideUp
{
from
{
transform
:
translateY
(
100%
);
}
to
{
transform
:
translateY
(
0
);
}
}
// uni-datetime-picker样式覆盖(与naming页面保持一致)
::v-deep
.uni-datetime-picker--btn
{
background-color
:
#D4A574
!
important
;
}
::v-deep
.uni-calendar-item--checked
{
background-color
:
#D4A574
!
important
;
}
::v-deep
.uni-datetime-picker-btn-text
{
color
:
#D4A574
!
important
;
}
</
style
>
static/feedingRecord/v1/dropDown.png
0 → 100644
View file @
6bedfe80
1.38 KB
static/feedingRecord/v1/dropUp.png
0 → 100644
View file @
6bedfe80
1.39 KB
static/feedingRecord/v1/icon_analysis.png
0 → 100644
View file @
6bedfe80
695 Bytes
static/feedingRecord/v1/icon_arrow_yellow.png
0 → 100644
View file @
6bedfe80
248 Bytes
static/feedingRecord/v1/icon_fushi.png
0 → 100644
View file @
6bedfe80
908 Bytes
static/feedingRecord/v1/icon_muru.png
0 → 100644
View file @
6bedfe80
662 Bytes
static/feedingRecord/v1/icon_naifen.png
0 → 100644
View file @
6bedfe80
611 Bytes
static/feedingRecord/v1/icon_pingwei.png
0 → 100644
View file @
6bedfe80
790 Bytes
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment