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 @@ - {{ formatDate(form.time) }} + {{ formatShortDate(form.time) }} - {{ 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 = () => {