feat: 优化小程序人生事件详情页、表单页和记录视图页样式
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -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: '瞬间' }
|
||||
|
||||
@@ -94,13 +94,13 @@
|
||||
<picker mode="date" :value="form.time" @change="e => setRangeStart(e.detail.value)">
|
||||
<view class="picker-field compact">
|
||||
<view class="calendar-icon"></view>
|
||||
<text>{{ formatDate(form.time) }}</text>
|
||||
<text class="range-date-text">{{ formatShortDate(form.time) }}</text>
|
||||
</view>
|
||||
</picker>
|
||||
<text class="range-line">至</text>
|
||||
<picker mode="date" :value="form.endTime" @change="e => setRangeEnd(e.detail.value)">
|
||||
<view class="picker-field compact">
|
||||
<text>{{ formatDate(form.endTime) }}</text>
|
||||
<text class="range-date-text">{{ formatShortDate(form.endTime) }}</text>
|
||||
<text class="chevron">›</text>
|
||||
</view>
|
||||
</picker>
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -95,8 +95,8 @@
|
||||
</view>
|
||||
<view class="event-card kos-card">
|
||||
<view class="date-box">
|
||||
<text class="date-month">{{ getMonth(event.time) }}</text>
|
||||
<text class="date-age">{{ getAgeText(event.time) }}</text>
|
||||
<text class="date-month">{{ getTimelineDate(event) }}</text>
|
||||
<text class="date-age">{{ getAgeText(event) }}</text>
|
||||
</view>
|
||||
<view class="event-divider"></view>
|
||||
<view class="event-body">
|
||||
@@ -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 = () => {
|
||||
|
||||
<style scoped>
|
||||
.record-view {
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 24rpx;
|
||||
padding-bottom: 22rpx;
|
||||
padding-bottom: 238rpx;
|
||||
}
|
||||
|
||||
.profile-card {
|
||||
@@ -602,6 +629,7 @@ const addFilter = () => {
|
||||
.timeline {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding-bottom: 32rpx;
|
||||
}
|
||||
|
||||
.timeline-item {
|
||||
@@ -762,18 +790,25 @@ const addFilter = () => {
|
||||
}
|
||||
|
||||
.create-fab {
|
||||
align-self: center;
|
||||
position: fixed;
|
||||
left: 50%;
|
||||
bottom: calc(124rpx + constant(safe-area-inset-bottom));
|
||||
bottom: calc(124rpx + env(safe-area-inset-bottom));
|
||||
z-index: 19;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 8rpx;
|
||||
transform: translateX(-50%);
|
||||
color: #caa6ff;
|
||||
font-size: 22rpx;
|
||||
font-weight: 800;
|
||||
text-shadow: 0 0 20rpx rgba(168, 85, 247, 0.72);
|
||||
}
|
||||
|
||||
.plus-core {
|
||||
width: 78rpx;
|
||||
height: 78rpx;
|
||||
width: 82rpx;
|
||||
height: 82rpx;
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@@ -781,6 +816,10 @@ const addFilter = () => {
|
||||
color: #fff;
|
||||
font-size: 46rpx;
|
||||
background: linear-gradient(135deg, #b348ff, #582cff);
|
||||
box-shadow: 0 0 38rpx rgba(171, 72, 255, 0.62);
|
||||
border: 2rpx solid rgba(235, 210, 255, 0.46);
|
||||
box-shadow:
|
||||
0 0 38rpx rgba(171, 72, 255, 0.68),
|
||||
0 12rpx 34rpx rgba(0, 0, 0, 0.38),
|
||||
inset 0 1rpx 0 rgba(255, 255, 255, 0.28);
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user