diff --git a/mini-program/src/pages/life-event/detail.vue b/mini-program/src/pages/life-event/detail.vue
index 14ca723..9bf7d65 100644
--- a/mini-program/src/pages/life-event/detail.vue
+++ b/mini-program/src/pages/life-event/detail.vue
@@ -167,18 +167,65 @@ const profile = computed(() => store.userProfile || store.registrationData || {}
const bottomInset = computed(() => Math.max(0, safeAreaBottom.value))
const eventYear = computed(() => {
- const date = displayEvent.value.time || displayEvent.value.date || displayEvent.value.eventDate
- return date ? String(date).slice(0, 4) : '2025'
+ const event = displayEvent.value
+ const date = event.time || event.date || event.eventDate
+ if (date) return String(date).slice(0, 4)
+ if (!isInvalidDateText(event.eventDateText)) return String(event.eventDateText).slice(0, 4)
+ return '2025'
})
const dateRange = computed(() => {
- const date = displayEvent.value.time || displayEvent.value.date || displayEvent.value.eventDate
- if (!date) return '05/20 - 05/28'
- const month = String(date).slice(5, 7) || '05'
- const day = String(date).slice(8, 10) || '20'
- return `${month}/${day} - ${month}/${String(Math.min(28, Number(day) + 8)).padStart(2, '0')}`
+ return formatEventTime(displayEvent.value)
})
+const isInvalidDateText = (value) => {
+ return !value || String(value).includes('%')
+}
+
+const toDatePart = (value) => {
+ return value ? String(value).split('T')[0] : ''
+}
+
+const formatMonthDay = (value) => {
+ const date = toDatePart(value)
+ if (!date) return ''
+ const [, month = '', day = ''] = date.split('-')
+ return month && day ? `${month}/${day}` : ''
+}
+
+const formatEventTime = (event = {}) => {
+ const timeMode = event.timeMode || 'date'
+ const start = toDatePart(event.time || event.date || event.eventDate)
+ const end = toDatePart(event.endTime || event.eventEndDate)
+ const text = isInvalidDateText(event.eventDateText) ? '' : String(event.eventDateText || '')
+
+ if (timeMode === 'range') {
+ if (start && end) return `${formatMonthDay(start)} - ${formatMonthDay(end)}`
+ if (text) {
+ const normalized = text.replace(/\s*(至|到|~|—|-)\s*/g, ' - ')
+ const [rawStart, rawEnd] = normalized.split(' - ')
+ if (rawStart && rawEnd) return `${formatMonthDay(rawStart)} - ${formatMonthDay(rawEnd)}`
+ return text
+ }
+ }
+
+ if (timeMode === 'month') {
+ const value = text || start
+ return value ? String(value).slice(0, 7).replace('-', '.') : '2025.05'
+ }
+
+ if (timeMode === 'season') {
+ const value = text || `${String(start || '2025').slice(0, 4)}-spring`
+ const [year, season = 'spring'] = String(value).split('-')
+ const seasonMap = { spring: '春季', summer: '夏季', autumn: '秋季', winter: '冬季' }
+ return `${year} ${seasonMap[season] || '春季'}`
+ }
+
+ if (!start) return '05/20 - 05/28'
+ const first = formatMonthDay(start)
+ return first || '05/20'
+}
+
const primaryTag = computed(() => {
if (Array.isArray(displayEvent.value.tags) && displayEvent.value.tags.length) return displayEvent.value.tags[0]
const map = { childhood: '童年', highlight: '高光', valley: '低谷', daily_log: '瞬间' }
diff --git a/mini-program/src/pages/life-event/form.vue b/mini-program/src/pages/life-event/form.vue
index b4435b7..1eda382 100644
--- a/mini-program/src/pages/life-event/form.vue
+++ b/mini-program/src/pages/life-event/form.vue
@@ -94,13 +94,13 @@
setRangeStart(e.detail.value)">
- {{ formatDate(form.time) }}
+ {{ formatShortDate(form.time) }}
至
setRangeEnd(e.detail.value)">
- {{ formatDate(form.endTime) }}
+ {{ formatShortDate(form.endTime) }}
›
@@ -301,6 +301,11 @@ const formatDate = (value) => {
return `${year}年${month}月${day}日`
}
+const formatShortDate = (value) => {
+ if (!value) return '选择日期'
+ return String(value).replaceAll('-', '.')
+}
+
const formatMonth = (value) => {
const [year, month] = (value || form.time.slice(0, 7)).split('-')
return `${year}年${month}月`
@@ -617,7 +622,7 @@ const goBack = () => {
flex: 1;
height: 0;
min-height: 0;
- padding: 0 32rpx 28rpx;
+ padding: 0 28rpx 28rpx;
box-sizing: border-box;
}
@@ -625,7 +630,7 @@ const goBack = () => {
position: relative;
overflow: hidden;
border-radius: 30rpx;
- padding: 38rpx 30rpx 88rpx;
+ padding: 36rpx 26rpx 84rpx;
border: 2rpx solid rgba(145, 70, 255, 0.76);
background:
radial-gradient(circle at 52% 8%, rgba(126, 72, 255, 0.13), transparent 35%),
@@ -648,9 +653,9 @@ const goBack = () => {
}
.group-title {
- gap: 16rpx;
+ gap: 14rpx;
color: #d7bdff;
- font-size: 31rpx;
+ font-size: 29rpx;
font-weight: 900;
}
@@ -766,7 +771,7 @@ const goBack = () => {
align-items: center;
justify-content: center;
color: rgba(224, 214, 243, 0.78);
- font-size: 24rpx;
+ font-size: 22rpx;
font-weight: 600;
}
@@ -785,25 +790,31 @@ const goBack = () => {
border: 1rpx solid rgba(151, 111, 255, 0.28);
background: rgba(12, 15, 46, 0.74);
color: #fff;
- font-size: 27rpx;
+ font-size: 25rpx;
}
.picker-field {
height: 78rpx;
margin-top: 26rpx;
- padding: 0 24rpx;
+ padding: 0 22rpx;
display: flex;
align-items: center;
- gap: 18rpx;
+ gap: 14rpx;
}
.picker-field text:nth-child(2) {
flex: 1;
+ min-width: 0;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
}
.picker-field.compact {
margin-top: 0;
- min-width: 284rpx;
+ min-width: 0;
+ height: 72rpx;
+ padding: 0 16rpx;
}
.calendar-icon {
@@ -827,20 +838,34 @@ const goBack = () => {
.chevron {
flex: none !important;
color: rgba(224, 214, 243, 0.7);
- font-size: 50rpx;
+ font-size: 42rpx;
line-height: 1;
}
.range-fields {
margin-top: 26rpx;
- display: flex;
+ display: grid;
+ grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
align-items: center;
- gap: 12rpx;
+ gap: 10rpx;
+}
+
+.range-fields picker {
+ min-width: 0;
}
.range-line {
color: rgba(224, 214, 243, 0.7);
- font-size: 24rpx;
+ font-size: 22rpx;
+ font-weight: 700;
+}
+
+.range-date-text {
+ flex: 1;
+ min-width: 0;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
}
.divider {
@@ -853,7 +878,7 @@ const goBack = () => {
.optional,
.custom-tag {
color: #b58bff;
- font-size: 23rpx;
+ font-size: 22rpx;
font-weight: 600;
}
@@ -927,7 +952,7 @@ const goBack = () => {
align-items: center;
justify-content: center;
color: rgba(224, 214, 243, 0.74);
- font-size: 24rpx;
+ font-size: 22rpx;
border: 1rpx solid rgba(151, 111, 255, 0.2);
background: rgba(20, 22, 58, 0.58);
}
diff --git a/mini-program/src/pages/main/RecordView.vue b/mini-program/src/pages/main/RecordView.vue
index 0a2d162..dec12ad 100644
--- a/mini-program/src/pages/main/RecordView.vue
+++ b/mini-program/src/pages/main/RecordView.vue
@@ -95,8 +95,8 @@
- {{ getMonth(event.time) }}
- {{ getAgeText(event.time) }}
+ {{ getTimelineDate(event) }}
+ {{ getAgeText(event) }}
@@ -206,7 +206,33 @@ const getMonth = (date) => {
return String(date).slice(0, 7).replace('-', '.')
}
-const getAgeText = (date) => {
+const isInvalidDateText = (value) => {
+ return !value || String(value).includes('%')
+}
+
+const getTimelineDate = (event) => {
+ if (event?.timeMode === 'range') {
+ const start = event.time || ''
+ const end = event.endTime || ''
+ if (start && end) return `${getMonth(start)}-${getMonth(end)}`
+ if (!isInvalidDateText(event.eventDateText)) return String(event.eventDateText).replace(/\s*至\s*/, '-')
+ }
+
+ if (event?.timeMode === 'month' && !isInvalidDateText(event.eventDateText)) {
+ return String(event.eventDateText).slice(0, 7).replace('-', '.')
+ }
+
+ if (event?.timeMode === 'season' && !isInvalidDateText(event.eventDateText)) {
+ const [year, season] = String(event.eventDateText).split('-')
+ const seasonMap = { spring: '春', summer: '夏', autumn: '秋', winter: '冬' }
+ return `${year}.${seasonMap[season] || '春'}`
+ }
+
+ return getMonth(event?.time)
+}
+
+const getAgeText = (event) => {
+ const date = event?.time
if (!date) return ''
const year = Number(String(date).slice(0, 4))
if (!year || !profile.value.birthYear) return ''
@@ -261,10 +287,11 @@ const addFilter = () => {