feat: 优化管理后台页面UI、修复TS编译错误、新增人生事件模块

- 优化 AI 配置列表页面:重构统计卡片、搜索表单、表格列展示
- 修复 3 处 TypeScript TS6133 编译错误,恢复构建
- 新增管理员修改密码和重置密码功能
- 优化小程序多个页面样式和交互
- 人生事件模块完善

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-05-10 23:23:09 +08:00
parent 60c63850ee
commit 755059807a
62 changed files with 4661 additions and 3019 deletions
+141 -108
View File
@@ -66,7 +66,7 @@
</view>
<text class="section-subtitle">你的成长之路正在展开</text>
</view>
<view class="map-btn kos-pill">
<view class="map-btn kos-pill" @click="openMap">
<view class="map-icon"></view>
<text>轨迹地图</text>
</view>
@@ -81,7 +81,7 @@
:class="{ active: activeFilter === filter.value }"
@click="activeFilter = filter.value"
>{{ filter.label }}</text>
<text class="add-filter"></text>
<text class="add-filter" @click="addFilter"></text>
</view>
</scroll-view>
@@ -130,14 +130,16 @@ import { useAppStore } from '../../stores/app.js'
const store = useAppStore()
const activeFilter = ref('all')
const customFilters = ref([])
const filters = [
const baseFilters = [
{ label: '全部', value: 'all' },
{ label: '童年', value: 'childhood' },
{ label: '高光', value: 'highlight' },
{ label: '低谷', value: 'valley' },
{ label: '美好的瞬间', value: 'daily_log' }
]
const filters = computed(() => [...baseFilters, ...customFilters.value])
const sampleEvents = [
{
@@ -192,6 +194,10 @@ const avatar = computed(() => {
const displayEvents = computed(() => {
if (activeFilter.value === 'all') return events.value
if (activeFilter.value.startsWith('custom_')) {
const label = activeFilter.value.replace('custom_', '')
return events.value.filter(event => Array.isArray(event.tags) && event.tags.includes(label))
}
return events.value.filter(event => event.eventType === activeFilter.value || event.emotionType === activeFilter.value)
})
@@ -222,28 +228,50 @@ const createEvent = () => {
}
const openDetail = (event) => {
if (String(event.id || '').startsWith('sample-')) return
uni.setStorageSync('current_life_event', JSON.parse(JSON.stringify(event || {})))
if (!event?.id) return
uni.navigateTo({ url: `/pages/life-event/detail?id=${event.id}` })
}
const editProfile = () => {
uni.navigateTo({ url: '/pages/onboarding/index?edit=1' })
}
const openMap = () => {
uni.navigateTo({ url: '/pages/main/PathView' })
}
const addFilter = () => {
uni.showModal({
title: '新增筛选',
editable: true,
placeholderText: '输入标签名',
success: (res) => {
const value = String(res.content || '').trim()
if (!res.confirm || !value) return
const filter = { label: value, value: `custom_${value}` }
if (!customFilters.value.some(item => item.label === value)) {
customFilters.value.push(filter)
}
activeFilter.value = filter.value
}
})
}
</script>
<style scoped>
.record-view {
display: flex;
flex-direction: column;
gap: 28rpx;
padding-bottom: 34rpx;
gap: 24rpx;
padding-bottom: 22rpx;
}
.profile-card {
position: relative;
overflow: hidden;
border-radius: 34rpx;
padding: 40rpx 34rpx 32rpx;
padding: 34rpx 30rpx 28rpx;
}
.profile-card::after {
@@ -251,8 +279,8 @@ const editProfile = () => {
position: absolute;
right: -28rpx;
bottom: -20rpx;
width: 250rpx;
height: 180rpx;
width: 220rpx;
height: 156rpx;
background: radial-gradient(circle, rgba(122, 58, 255, 0.35), transparent 62%);
border: 1rpx solid rgba(158, 88, 255, 0.26);
border-radius: 50%;
@@ -269,18 +297,18 @@ const editProfile = () => {
.profile-top {
display: flex;
align-items: center;
gap: 24rpx;
gap: 22rpx;
}
.avatar-wrap {
position: relative;
flex-shrink: 0;
width: 134rpx;
height: 134rpx;
padding: 6rpx;
width: 112rpx;
height: 112rpx;
padding: 5rpx;
border-radius: 50%;
background: linear-gradient(135deg, #fff, #9b54ff 38%, #4a67ff);
box-shadow: 0 0 42rpx rgba(149, 89, 255, 0.56);
box-shadow: 0 0 34rpx rgba(149, 89, 255, 0.52);
}
.avatar {
@@ -292,10 +320,10 @@ const editProfile = () => {
.avatar-edit {
position: absolute;
right: -6rpx;
bottom: -6rpx;
width: 48rpx;
height: 48rpx;
right: -5rpx;
bottom: -5rpx;
width: 40rpx;
height: 40rpx;
border-radius: 50%;
background: linear-gradient(135deg, #8b4dff, #4a2cff);
box-shadow: 0 0 20rpx rgba(158, 91, 255, 0.6);
@@ -308,7 +336,7 @@ const editProfile = () => {
border-radius: 6rpx;
background: #fff;
transform: rotate(-45deg);
margin: 21rpx auto;
margin: 17rpx auto;
}
.profile-info {
@@ -324,33 +352,33 @@ const editProfile = () => {
.profile-name {
color: #fff;
font-size: 44rpx;
font-size: 36rpx;
line-height: 1.1;
font-weight: 800;
}
.star {
color: #ffd589;
font-size: 30rpx;
font-size: 26rpx;
}
.profile-subtitle {
display: block;
margin-top: 14rpx;
margin-top: 10rpx;
color: rgba(239, 232, 255, 0.78);
font-size: 27rpx;
font-size: 24rpx;
}
.edit-profile {
flex-shrink: 0;
height: 64rpx;
padding: 0 22rpx;
height: 56rpx;
padding: 0 18rpx;
border-radius: 999rpx;
display: flex;
align-items: center;
gap: 10rpx;
gap: 8rpx;
color: #dccbff;
font-size: 24rpx;
font-size: 22rpx;
}
.tiny-pen {
@@ -363,12 +391,12 @@ const editProfile = () => {
position: relative;
z-index: 1;
height: 1rpx;
margin: 32rpx 0 24rpx;
margin: 28rpx 0 20rpx;
background: rgba(180, 139, 255, 0.22);
}
.profile-divider.small {
margin: 24rpx 0;
margin: 20rpx 0;
}
.meta-grid {
@@ -380,23 +408,28 @@ const editProfile = () => {
min-width: 0;
display: flex;
align-items: center;
gap: 14rpx;
padding-right: 18rpx;
gap: 10rpx;
padding-right: 12rpx;
border-right: 1rpx solid rgba(180, 139, 255, 0.22);
}
.meta-item + .meta-item {
padding-left: 22rpx;
padding-left: 16rpx;
}
.meta-item.no-border {
border-right: 0;
}
.meta-item > view,
.hobby-row > view {
min-width: 0;
}
.meta-icon,
.heart {
color: #a855ff;
font-size: 42rpx;
font-size: 34rpx;
line-height: 1;
text-shadow: 0 0 24rpx rgba(168, 85, 255, 0.7);
}
@@ -404,35 +437,35 @@ const editProfile = () => {
.person-icon,
.job-icon {
position: relative;
width: 38rpx;
height: 38rpx;
width: 32rpx;
height: 32rpx;
flex-shrink: 0;
}
.person-icon::before {
content: '';
position: absolute;
left: 10rpx;
left: 8rpx;
top: 0;
width: 16rpx;
height: 16rpx;
border: 4rpx solid #a855ff;
width: 14rpx;
height: 14rpx;
border: 3rpx solid #a855ff;
border-radius: 50%;
}
.person-icon::after {
content: '';
position: absolute;
left: 2rpx;
left: 1rpx;
bottom: 0;
width: 30rpx;
height: 18rpx;
border: 4rpx solid #a855ff;
width: 28rpx;
height: 16rpx;
border: 3rpx solid #a855ff;
border-radius: 18rpx 18rpx 4rpx 4rpx;
}
.job-icon {
border: 5rpx solid #a855ff;
border: 4rpx solid #a855ff;
border-radius: 8rpx;
box-sizing: border-box;
}
@@ -440,11 +473,11 @@ const editProfile = () => {
.job-icon::before {
content: '';
position: absolute;
left: 10rpx;
top: -10rpx;
left: 8rpx;
top: -8rpx;
width: 12rpx;
height: 8rpx;
border: 4rpx solid #a855ff;
height: 7rpx;
border: 3rpx solid #a855ff;
border-bottom: 0;
border-radius: 8rpx 8rpx 0 0;
}
@@ -457,14 +490,14 @@ const editProfile = () => {
.meta-label {
color: rgba(219, 204, 247, 0.54);
font-size: 22rpx;
font-size: 20rpx;
}
.meta-value,
.hobby-text {
margin-top: 4rpx;
margin-top: 3rpx;
color: #fff;
font-size: 27rpx;
font-size: 23rpx;
font-weight: 600;
overflow: hidden;
text-overflow: ellipsis;
@@ -474,7 +507,7 @@ const editProfile = () => {
.hobby-row {
display: flex;
align-items: center;
gap: 28rpx;
gap: 22rpx;
}
.section-head {
@@ -486,12 +519,12 @@ const editProfile = () => {
.title-line {
display: flex;
align-items: center;
gap: 14rpx;
gap: 12rpx;
}
.section-title {
color: #fff;
font-size: 44rpx;
font-size: 40rpx;
line-height: 1.1;
font-weight: 800;
}
@@ -502,26 +535,26 @@ const editProfile = () => {
.section-subtitle {
display: block;
margin-top: 14rpx;
margin-top: 10rpx;
color: rgba(210, 194, 242, 0.68);
font-size: 26rpx;
}
.map-btn {
height: 64rpx;
padding: 0 24rpx;
border-radius: 999rpx;
display: flex;
align-items: center;
gap: 12rpx;
color: #caa9ff;
font-size: 24rpx;
}
.map-btn {
height: 56rpx;
padding: 0 20rpx;
border-radius: 999rpx;
display: flex;
align-items: center;
gap: 10rpx;
color: #caa9ff;
font-size: 22rpx;
}
.map-icon {
width: 28rpx;
height: 22rpx;
border: 4rpx solid currentColor;
width: 24rpx;
height: 20rpx;
border: 3rpx solid currentColor;
border-radius: 4rpx;
transform: skewY(-12deg);
}
@@ -533,21 +566,21 @@ const editProfile = () => {
.filter-row {
display: inline-flex;
gap: 18rpx;
gap: 16rpx;
align-items: center;
}
.filter-chip,
.add-filter {
height: 62rpx;
min-width: 104rpx;
padding: 0 30rpx;
height: 54rpx;
min-width: 92rpx;
padding: 0 24rpx;
border-radius: 999rpx;
display: inline-flex;
align-items: center;
justify-content: center;
color: rgba(224, 214, 243, 0.72);
font-size: 25rpx;
font-size: 22rpx;
font-weight: 600;
}
@@ -559,11 +592,11 @@ const editProfile = () => {
}
.add-filter {
min-width: 62rpx;
min-width: 56rpx;
padding: 0;
border: 2rpx dashed rgba(155, 112, 255, 0.45);
color: #c49cff;
font-size: 36rpx;
font-size: 32rpx;
}
.timeline {
@@ -573,8 +606,8 @@ const editProfile = () => {
.timeline-item {
display: grid;
grid-template-columns: 88rpx 1fr;
min-height: 188rpx;
grid-template-columns: 76rpx 1fr;
min-height: 170rpx;
}
.rail {
@@ -586,19 +619,19 @@ const editProfile = () => {
.node {
position: relative;
z-index: 2;
width: 52rpx;
height: 52rpx;
width: 46rpx;
height: 46rpx;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
border: 4rpx solid currentColor;
box-shadow: 0 0 28rpx currentColor;
box-shadow: 0 0 24rpx currentColor;
}
.node view {
width: 24rpx;
height: 24rpx;
width: 20rpx;
height: 20rpx;
border-radius: 50%;
background: currentColor;
}
@@ -610,7 +643,7 @@ const editProfile = () => {
.line {
position: absolute;
top: 56rpx;
top: 50rpx;
bottom: -6rpx;
width: 4rpx;
background: linear-gradient(180deg, currentColor, rgba(255,255,255,0.14));
@@ -618,14 +651,14 @@ const editProfile = () => {
}
.event-card {
min-height: 160rpx;
margin-bottom: 22rpx;
min-height: 146rpx;
margin-bottom: 18rpx;
border-radius: 28rpx;
display: grid;
grid-template-columns: 116rpx 1rpx 1fr 108rpx 24rpx;
grid-template-columns: 96rpx 1rpx 1fr 88rpx 20rpx;
align-items: center;
gap: 22rpx;
padding: 22rpx;
gap: 18rpx;
padding: 20rpx;
}
.date-box {
@@ -635,16 +668,16 @@ const editProfile = () => {
.date-month,
.date-age {
display: block;
font-size: 25rpx;
font-size: 23rpx;
}
.date-age {
margin-top: 8rpx;
margin-top: 6rpx;
}
.event-divider {
width: 1rpx;
height: 92rpx;
height: 82rpx;
background: rgba(180, 139, 255, 0.18);
}
@@ -655,17 +688,17 @@ const editProfile = () => {
.event-title {
display: block;
color: #fff;
font-size: 27rpx;
font-size: 24rpx;
line-height: 1.25;
font-weight: 800;
}
.event-tag {
display: inline-flex;
margin-top: 14rpx;
padding: 6rpx 14rpx;
margin-top: 10rpx;
padding: 5rpx 12rpx;
border-radius: 999rpx;
font-size: 20rpx;
font-size: 19rpx;
}
.tag-0 { color: #8effc7; background: rgba(50, 196, 128, 0.18); }
@@ -675,9 +708,9 @@ const editProfile = () => {
.event-summary {
display: -webkit-box;
margin-top: 12rpx;
margin-top: 9rpx;
color: rgba(226, 215, 246, 0.66);
font-size: 24rpx;
font-size: 22rpx;
line-height: 1.45;
overflow: hidden;
-webkit-line-clamp: 2;
@@ -685,14 +718,14 @@ const editProfile = () => {
}
.thumb {
width: 96rpx;
height: 96rpx;
border-radius: 22rpx;
width: 78rpx;
height: 78rpx;
border-radius: 20rpx;
display: flex;
align-items: center;
justify-content: center;
color: #fff;
font-size: 44rpx;
font-size: 36rpx;
font-weight: 900;
overflow: hidden;
}
@@ -704,7 +737,7 @@ const editProfile = () => {
.chevron {
color: rgba(223, 213, 245, 0.68);
font-size: 54rpx;
font-size: 46rpx;
}
.empty-card {
@@ -733,20 +766,20 @@ const editProfile = () => {
display: flex;
flex-direction: column;
align-items: center;
gap: 10rpx;
gap: 8rpx;
color: #caa6ff;
font-size: 24rpx;
font-size: 22rpx;
}
.plus-core {
width: 92rpx;
height: 92rpx;
width: 78rpx;
height: 78rpx;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
color: #fff;
font-size: 56rpx;
font-size: 46rpx;
background: linear-gradient(135deg, #b348ff, #582cff);
box-shadow: 0 0 38rpx rgba(171, 72, 255, 0.62);
}