feat(ui): restore reference mini program and admin design

This commit is contained in:
2026-08-13 10:58:04 +08:00
parent 9622d249be
commit 58787e738a
26 changed files with 1027 additions and 329 deletions
+18 -6
View File
@@ -1,5 +1,15 @@
page {
/* 乐活公益公众端设计令牌:暖、可信、适老。 */
/* Primitive → semantic → component tokens. */
--primitive-orange-500: #ff6b35;
--primitive-orange-600: #e85220;
--primitive-orange-50: #fff5ef;
--primitive-green-500: #34ad50;
--primitive-blue-500: #2f91ed;
--primitive-gray-950: #1f2429;
--primitive-gray-600: #687078;
--primitive-gray-200: #e8ebee;
--primitive-gray-50: #f6f7f8;
--primitive-white: #ffffff;
--color-primary: #f05a28;
--color-primary-pressed: #d94718;
--color-primary-soft: #fff0e8;
@@ -12,16 +22,18 @@ page {
--color-warning: #b76e00;
--color-warning-soft: #fff6dd;
--color-danger: #b42318;
--color-text: #24211f;
--color-text-secondary: #6e6862;
--color-text: var(--primitive-gray-950);
--color-text-secondary: var(--primitive-gray-600);
--color-text-tertiary: #918a83;
--color-border: #e9e3dd;
--color-background: #f7f5f2;
--color-surface: #ffffff;
--color-border: var(--primitive-gray-200);
--color-divider: #f0f1f2;
--color-background: var(--primitive-gray-50);
--color-surface: var(--primitive-white);
--radius-sm: 16rpx;
--radius-md: 24rpx;
--radius-lg: 32rpx;
--shadow-card: 0 10rpx 32rpx rgba(91, 62, 45, 0.07);
--shadow-hero: 0 16rpx 38rpx rgba(231, 79, 29, 0.22);
min-height: 100%;
color: var(--color-text);
background: var(--color-background);
Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 81 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

@@ -0,0 +1,13 @@
/**
* 后续能力只在此登记扩展边界,不注册页面、不展示入口,也不产生模拟数据。
* 接入时必须完成独立产品评审、接口契约、权限、审计与迁移设计。
*/
export const FUTURE_CAPABILITIES = {
donation: { enabled: false, route: '' },
recurringDonation: { enabled: false, route: '' },
donationRecords: { enabled: false, route: '' },
materialOrders: { enabled: false, route: '' },
volunteerLearning: { enabled: false, route: '' },
volunteerCredentials: { enabled: false, route: '' },
volunteerTeams: { enabled: false, route: '' },
} as const;
@@ -2,10 +2,10 @@ Component({
data: {
selected: 0,
tabs: [
{ pagePath: '/pages/index/index', text: '首页', icon: '⌂' },
{ pagePath: '/pages/service-hub/service-hub', text: '服务', icon: '♡' },
{ pagePath: '/pages/public-welfare/public-welfare', text: '公益', icon: '◎' },
{ pagePath: '/pages/profile/profile', text: '我的', icon: '○' },
{ pagePath: '/pages/index/index', text: '首页', icon: 'home' },
{ pagePath: '/pages/service-hub/service-hub', text: '服务', icon: 'service' },
{ pagePath: '/pages/public-welfare/public-welfare', text: '发现', icon: 'discover' },
{ pagePath: '/pages/profile/profile', text: '我的', icon: 'profile' },
],
},
lifetimes: {
@@ -1,7 +1,7 @@
<view class="tab-bar">
<view class="tab-bar__inner">
<button wx:for="{{tabs}}" wx:key="pagePath" class="tab {{selected === index ? 'tab--active' : ''}}" data-index="{{index}}" bindtap="switchTab" aria-label="{{item.text}}">
<text class="tab__icon" aria-hidden="true">{{item.icon}}</text>
<view class="tab__icon tab__icon--{{item.icon}}" aria-hidden="true"><view class="tab__icon-core"></view></view>
<text class="tab__text">{{item.text}}</text>
</button>
</view>
@@ -1,45 +1,117 @@
.tab-bar {
position: fixed;
z-index: 100;
z-index: 90;
right: 0;
bottom: 0;
left: 0;
padding-bottom: env(safe-area-inset-bottom);
background: rgba(255, 255, 255, 0.98);
border-top: 2rpx solid #eee8e2;
box-shadow: 0 -8rpx 28rpx rgba(74, 55, 43, 0.06);
padding: 0 20rpx env(safe-area-inset-bottom);
}
.tab-bar__inner {
display: flex;
height: 112rpx;
align-items: stretch;
display: grid;
height: 106rpx;
padding: 8rpx 10rpx 4rpx;
grid-template-columns: repeat(4, 1fr);
border: 2rpx solid #eceff1;
border-bottom: 0;
border-radius: 28rpx 28rpx 0 0;
background: rgba(255, 255, 255, 0.97);
box-shadow: 0 -8rpx 30rpx rgba(31, 36, 41, 0.08);
box-sizing: border-box;
}
.tab {
display: flex;
min-width: 0;
margin: 0;
padding: 10rpx 4rpx 8rpx;
flex: 1;
padding: 4rpx;
flex-direction: column;
align-items: center;
justify-content: center;
color: #77716b;
gap: 5rpx;
color: #7b8288;
background: transparent;
font-size: 23rpx;
font-size: 21rpx;
line-height: 1;
}
.tab__icon {
height: 40rpx;
font-size: 38rpx;
font-weight: 700;
line-height: 40rpx;
}
.tab__text {
margin-top: 7rpx;
}
.tab--active {
color: #f05a28;
}
.tab--active .tab__text {
font-weight: 700;
}
.tab__icon {
position: relative;
width: 38rpx;
height: 38rpx;
color: currentColor;
}
.tab__icon::before,
.tab__icon::after,
.tab__icon-core {
position: absolute;
box-sizing: border-box;
content: '';
}
.tab__icon--home::before {
left: 6rpx;
bottom: 4rpx;
width: 27rpx;
height: 24rpx;
border: 4rpx solid currentColor;
border-top: 0;
border-radius: 3rpx;
}
.tab__icon--home::after {
left: 6rpx;
top: 4rpx;
width: 26rpx;
height: 26rpx;
border-top: 4rpx solid currentColor;
border-left: 4rpx solid currentColor;
transform: rotate(45deg);
}
.tab__icon--service::before {
left: 2rpx;
top: 10rpx;
width: 34rpx;
height: 22rpx;
border: 4rpx solid currentColor;
border-radius: 18rpx 18rpx 9rpx 9rpx;
transform: rotate(-10deg);
}
.tab__icon--service::after {
left: 9rpx;
top: 0;
width: 20rpx;
height: 17rpx;
border: 4rpx solid currentColor;
border-bottom: 0;
border-radius: 15rpx 15rpx 0 0;
}
.tab__icon--discover::before {
inset: 3rpx;
border: 4rpx solid currentColor;
border-radius: 50%;
}
.tab__icon--discover::after {
left: 15rpx;
top: 9rpx;
width: 9rpx;
height: 18rpx;
border-radius: 8rpx 8rpx 2rpx 2rpx;
background: currentColor;
transform: rotate(35deg);
}
.tab__icon--profile::before {
left: 12rpx;
top: 2rpx;
width: 15rpx;
height: 15rpx;
border: 4rpx solid currentColor;
border-radius: 50%;
}
.tab__icon--profile::after {
left: 5rpx;
bottom: 1rpx;
width: 29rpx;
height: 18rpx;
border: 4rpx solid currentColor;
border-radius: 18rpx 18rpx 4rpx 4rpx;
}
@@ -20,8 +20,7 @@
<block wx:else>
<view wx:if="{{step === 1}}" class="form-card">
<text class="form-title">需要什么帮助?</text>
<text class="form-hint">请选择最接近的一项,工作人员后续会进一步了解。</text>
<view class="application-banner"><text>请选择需要的服务类型</text><text>我们会认真了解并及时回应</text></view>
<button
wx:for="{{categories}}"
wx:key="code"
@@ -30,11 +29,15 @@
bindtap="selectCategory"
aria-label="{{item.label}}:{{item.description}}"
>
<image wx:if="{{item.code === 'OLD_AGE'}}" class="selection-photo" src="/assets/images/brand-elder-care.jpg" mode="aspectFill" />
<image wx:elif="{{item.code === 'WOMEN_CHILDREN'}}" class="selection-photo" src="/assets/images/brand-women-support.jpg" mode="aspectFill" />
<image wx:elif="{{item.code === 'DISABILITY'}}" class="selection-photo" src="/assets/images/brand-disability-support.jpg" mode="aspectFill" />
<view wx:else class="selection-photo selection-photo--fallback">公益服务</view>
<view class="selection-content">
<text class="selection-title">{{item.label}}</text>
<text class="selection-description">{{item.description}}</text>
</view>
<text class="selection-status">{{serviceCategory === item.code ? '已选择' : '选择'}}</text>
<text class="selection-status">{{serviceCategory === item.code ? '✓' : '›'}}</text>
</button>
</view>
@@ -235,3 +235,36 @@
transition: none;
}
}
.application-banner {
display: flex;
min-height: 126rpx;
margin: -32rpx -32rpx 24rpx;
padding: 28rpx 30rpx;
flex-direction: column;
justify-content: center;
border-radius: 30rpx 30rpx 16rpx 16rpx;
color: #e84e1e;
background: linear-gradient(120deg, #fff0e7, #fff8f3);
font-weight: 800;
}
.application-banner text:last-child {
margin-top: 7rpx;
color: #7b6257;
font-size: 24rpx;
font-weight: 400;
}
.selection-photo {
width: 148rpx;
height: 104rpx;
flex: 0 0 auto;
border-radius: 18rpx;
object-fit: cover;
}
.selection-photo--fallback {
display: flex;
align-items: center;
justify-content: center;
color: #7c6d65;
background: #f4f1ee;
font-size: 22rpx;
}
@@ -9,12 +9,10 @@ Page({
title: MINI_PROGRAM_TITLE,
canCollaborate: false,
serviceCategories: [
{ code: 'OLD_AGE', label: '关爱老人', icon: '人', tone: 'orange' },
{ code: 'WOMEN_CHILDREN', label: '妇女帮扶', icon: '爱', tone: 'rose' },
{ code: 'WOMEN_CHILDREN', label: '儿童关爱', icon: '苗', tone: 'green' },
{ code: 'DISABILITY', label: '残障帮扶', icon: '助', tone: 'blue' },
{ code: 'DIFFICULT_FAMILY', label: '生活困难', icon: '家', tone: 'gold' },
{ code: 'OTHER', label: '其他服务', icon: '心', tone: 'purple' },
{ code: 'OLD_AGE', label: '关爱老人', symbol: '老', tone: 'orange' },
{ code: 'WOMEN_CHILDREN', label: '困境儿童', symbol: '童', tone: 'green' },
{ code: 'WOMEN_CHILDREN', label: '妇女帮扶', symbol: '女', tone: 'rose' },
{ code: 'DISABILITY', label: '残障救助', symbol: '助', tone: 'blue' },
],
},
@@ -90,4 +88,7 @@ Page({
viewNotifications() {
void wx.navigateTo({ url: '/pages/notifications/notifications' });
},
apply() {
void wx.navigateTo({ url: '/pages/application-form/application-form?mode=SELF' });
},
});
@@ -1,37 +1,41 @@
<view class="page home-page">
<view class="home-hero">
<view class="hero-orb hero-orb--one"></view><view class="hero-orb hero-orb--two"></view>
<text class="hero-brand">乐活公益 ♡</text>
<text class="hero-title">用爱连接,让爱传递</text>
<text class="hero-copy">有需要,告诉我们;想帮忙,也欢迎加入。</text>
<view class="hero-trust"><text>公益服务</text><text>隐私保护</text><text>专人跟进</text></view>
<view class="brand-row">
<view class="brand-logo"><view class="brand-logo__heart"></view></view>
<view><text class="brand-name">乐活公益</text><text class="brand-slogan">用爱连接 · 让爱传递</text></view>
</view>
<view wx:if="{{authStatus === 'loading'}}" class="state-card" aria-live="polite"><view class="skeleton-line skeleton-line--wide"></view><view class="skeleton-line"></view><text class="state-text">正在安全登录,请稍候…</text></view>
<view wx:elif="{{authStatus === 'error'}}" class="state-card" aria-live="polite"><text class="state-title">暂时无法登录</text><text class="state-text">{{message}}</text><button class="secondary-button" bindtap="retryLogin">重新登录</button></view>
<view class="home-hero">
<view class="hero-glow hero-glow--one"></view><view class="hero-glow hero-glow--two"></view>
<text class="hero-title">用爱连接 让爱传递</text>
<text class="hero-copy">乐于助人 · 助人为乐 · 服务社会</text>
<button class="hero-action" bindtap="apply">立即申请服务 <text>›</text></button>
</view>
<view wx:if="{{authStatus === 'loading'}}" class="state-card"><view class="skeleton-line skeleton-line--wide"></view><text class="state-text">正在安全登录,请稍候…</text></view>
<view wx:elif="{{authStatus === 'error'}}" class="state-card"><text class="state-title">暂时无法登录</text><text class="state-text">{{message}}</text><button class="secondary-button" bindtap="retryLogin">重新登录</button></view>
<block wx:else>
<view class="primary-actions">
<button class="primary-action primary-action--warm" bindtap="applyForSelf"><view class="primary-action__icon">♡</view><view><text class="primary-action__title">我需要帮助</text><text class="primary-action__copy">为自己申请暖心服务</text></view><text class="primary-action__arrow">›</text></button>
<button class="primary-action primary-action--green" bindtap="applyForFamily"><view class="primary-action__icon">♧</view><view><text class="primary-action__title">帮家人申请</text><text class="primary-action__copy">替家人或他人说明需求</text></view><text class="primary-action__arrow">›</text></button>
<view class="quick-grid">
<button wx:for="{{serviceCategories}}" wx:key="label" class="quick-item" data-code="{{item.code}}" bindtap="applyForCategory"><view class="quick-icon quick-icon--{{item.tone}}"><text>{{item.symbol}}</text></view><text>{{item.label}}</text></button>
<button class="quick-item" bindtap="apply"><view class="quick-icon quick-icon--blue"><text>申</text></view><text>服务申请</text></button>
<button class="quick-item" bindtap="viewVolunteerCenter"><view class="quick-icon quick-icon--gold"><text>愿</text></view><text>志愿服务</text></button>
<button class="quick-item" bindtap="viewProjects"><view class="quick-icon quick-icon--green"><text>益</text></view><text>公益项目</text></button>
<button class="quick-item" bindtap="viewContent"><view class="quick-icon quick-icon--rose"><text>讯</text></view><text>公益动态</text></button>
</view>
<button class="progress-banner" bindtap="viewMyApplications"><view><text class="progress-banner__label">我的服务进度</text><text class="progress-banner__copy">查看申请受理与跟进情况</text></view><text class="progress-banner__arrow">查看 ›</text></button>
<button class="notice-strip" bindtap="viewContent"><text class="notice-badge">公告</text><text class="notice-text">查看乐活公益最新服务动态与温馨提示</text><text>›</text></button>
<view class="section-heading"><text class="section-title">我们能帮什么</text><text class="section-note">六类暖心服务</text></view>
<view class="service-grid">
<button wx:for="{{serviceCategories}}" wx:key="code" class="service-item service-item--{{item.tone}}" data-code="{{item.code}}" bindtap="applyForCategory"><text class="service-item__icon">{{item.icon}}</text><text class="service-item__label">{{item.label}}</text></button>
<view class="section-heading"><text class="section-title">公益项目</text><button class="section-link" bindtap="viewProjects">更多 ›</button></view>
<button class="feature-project" bindtap="viewProjects">
<image src="/assets/images/brand-elder-care.jpg" mode="aspectFill"></image>
<view class="feature-project__body"><text class="feature-project__title">持续关注身边的公益需要</text><text class="feature-project__copy">查看公开项目、服务范围与活动安排,选择合适的方式参与。</text><view class="feature-project__meta"><text>公益项目</text><text>查看详情 ›</text></view></view>
</button>
<view class="section-heading"><text class="section-title">便捷入口</text></view>
<view class="service-list">
<button bindtap="viewMyApplications"><view class="list-mark list-mark--orange">进</view><view><text class="list-title">服务进度</text><text class="list-copy">查看申请受理与跟进情况</text></view><text>›</text></button>
<button wx:if="{{canCollaborate}}" bindtap="viewAssignedCases"><view class="list-mark list-mark--blue">协</view><view><text class="list-title">协作任务</text><text class="list-copy">查看已授权的服务工单</text></view><text>›</text></button>
<button bindtap="viewActivities"><view class="list-mark list-mark--green">活</view><view><text class="list-title">公益活动</text><text class="list-copy">浏览活动并提交报名</text></view><text>›</text></button>
</view>
<view class="section-heading"><text class="section-title">一起参与公益</text><text class="section-note">每份行动都有温度</text></view>
<view class="participation-card">
<button class="participation-item" bindtap="viewProjects"><text class="participation-item__icon orange">◎</text><view><text class="participation-item__title">公益项目</text><text class="participation-item__copy">看见持续发生的改变</text></view><text>›</text></button>
<button class="participation-item" bindtap="viewActivities"><text class="participation-item__icon blue">◇</text><view><text class="participation-item__title">公益活动</text><text class="participation-item__copy">找到适合参与的活动</text></view><text>›</text></button>
<button class="participation-item" bindtap="viewVolunteerCenter"><text class="participation-item__icon green">♧</text><view><text class="participation-item__title">成为志愿者</text><text class="participation-item__copy">认证、报名与服务时长</text></view><text>›</text></button>
</view>
<view class="section-heading"><text class="section-title">乐活动态</text><text class="section-note">内容均经审核发布</text></view>
<view class="content-links"><button bindtap="viewContent">公益动态 <text>›</text></button><button bindtap="viewOrganization">了解乐活 <text>›</text></button></view>
<view class="safety-note"><text class="safety-note__title">紧急情况请先求助公共服务</text><text>如遇危及生命安全的情况,请及时联系 110 或 120。</text></view>
</block>
</view>
@@ -1,293 +1,282 @@
.home-page {
padding-top: 20rpx;
padding-top: 18rpx;
}
.brand-row {
display: flex;
align-items: center;
gap: 18rpx;
padding: 4rpx 8rpx 24rpx;
}
.brand-logo {
position: relative;
width: 68rpx;
height: 68rpx;
border-radius: 22rpx;
background: linear-gradient(145deg, #ff9d26, #ff5726);
transform: rotate(-8deg);
}
.brand-logo::after {
position: absolute;
right: 11rpx;
bottom: 10rpx;
width: 24rpx;
height: 37rpx;
border-radius: 20rpx 20rpx 4rpx 20rpx;
content: '';
background: #fff;
transform: rotate(35deg);
}
.brand-name,
.brand-slogan {
display: block;
}
.brand-name {
font-size: 38rpx;
font-weight: 800;
letter-spacing: 4rpx;
}
.brand-slogan {
margin-top: 2rpx;
color: var(--color-text-secondary);
font-size: 22rpx;
letter-spacing: 5rpx;
}
.home-hero {
position: relative;
margin-bottom: 24rpx;
padding: 40rpx 34rpx 34rpx;
min-height: 232rpx;
padding: 40rpx 34rpx;
overflow: hidden;
border-radius: 36rpx;
border-radius: 30rpx;
color: #fff;
background: linear-gradient(135deg, #ff7845 0%, #f05225 100%);
box-shadow: 0 16rpx 36rpx rgba(224, 75, 25, 0.22);
background: linear-gradient(125deg, #ff7b3e 0%, #ff5d23 55%, #ff8e4e 100%);
box-shadow: var(--shadow-hero);
box-sizing: border-box;
}
.hero-orb {
.hero-glow {
position: absolute;
border: 3rpx solid rgba(255, 255, 255, 0.25);
border: 3rpx solid rgba(255, 255, 255, 0.22);
border-radius: 50%;
}
.hero-orb--one {
.hero-glow--one {
width: 180rpx;
height: 180rpx;
right: -54rpx;
top: 30rpx;
right: -35rpx;
top: 20rpx;
}
.hero-orb--two {
width: 90rpx;
height: 90rpx;
right: 92rpx;
bottom: -32rpx;
.hero-glow--two {
width: 100rpx;
height: 100rpx;
right: 110rpx;
bottom: -38rpx;
}
.hero-brand,
.hero-title,
.hero-copy {
position: relative;
z-index: 1;
display: block;
}
.hero-brand {
font-size: 27rpx;
font-weight: 700;
}
.hero-title {
margin-top: 18rpx;
font-size: 46rpx;
font-weight: 700;
font-size: 42rpx;
font-weight: 800;
letter-spacing: 2rpx;
}
.hero-copy {
margin-top: 12rpx;
font-size: 28rpx;
margin-top: 10rpx;
font-size: 24rpx;
opacity: 0.92;
}
.hero-trust {
.hero-action {
position: relative;
z-index: 1;
display: flex;
margin-top: 28rpx;
width: max-content;
min-height: 58rpx;
margin: 24rpx 0 0;
padding: 8rpx 22rpx;
align-items: center;
gap: 12rpx;
}
.hero-trust text {
padding: 7rpx 14rpx;
border-radius: 999rpx;
background: rgba(255, 255, 255, 0.18);
color: #df4c1b;
background: #fff;
font-size: 25rpx;
font-weight: 700;
}
.quick-grid {
display: grid;
margin-top: 24rpx;
padding: 26rpx 8rpx 18rpx;
grid-template-columns: repeat(4, 1fr);
gap: 28rpx 10rpx;
border: 2rpx solid var(--color-border);
border-radius: 28rpx;
background: #fff;
box-shadow: var(--shadow-card);
}
.quick-item {
display: flex;
min-width: 0;
margin: 0;
padding: 0;
flex-direction: column;
align-items: center;
gap: 12rpx;
color: var(--color-text);
background: transparent;
font-size: 23rpx;
line-height: 1.25;
}
.quick-icon {
display: flex;
width: 68rpx;
height: 68rpx;
align-items: center;
justify-content: center;
border-radius: 24rpx;
color: #fff;
font-size: 26rpx;
font-weight: 800;
box-shadow: 0 8rpx 18rpx rgba(20, 30, 40, 0.1);
}
.quick-icon--orange,
.list-mark--orange {
background: linear-gradient(145deg, #ff8b4d, #ff5e2b);
}
.quick-icon--green,
.list-mark--green {
background: linear-gradient(145deg, #62ca58, #36ad43);
}
.quick-icon--rose {
background: linear-gradient(145deg, #ff8292, #ef556f);
}
.quick-icon--blue,
.list-mark--blue {
background: linear-gradient(145deg, #55aaf5, #2887e5);
}
.quick-icon--gold {
background: linear-gradient(145deg, #ffbd57, #f2942e);
}
.notice-strip {
display: grid;
width: 100%;
min-height: 70rpx;
margin: 20rpx 0 0;
padding: 12rpx 18rpx;
grid-template-columns: auto 1fr auto;
align-items: center;
gap: 14rpx;
border-radius: 18rpx;
color: var(--color-text-secondary);
background: #fff;
text-align: left;
font-size: 23rpx;
}
.primary-actions {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 18rpx;
.notice-badge {
color: var(--color-primary);
font-weight: 800;
}
.primary-action {
position: relative;
display: flex;
min-height: 190rpx;
.notice-text {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.section-heading {
margin-top: 32rpx;
}
.section-link {
min-height: 52rpx;
margin: 0;
padding: 26rpx 22rpx;
flex-direction: column;
align-items: flex-start;
color: #5e2715;
border: 2rpx solid #ffd2bd;
border-radius: 30rpx;
padding: 4rpx 0 4rpx 20rpx;
color: var(--color-text-secondary);
background: transparent;
font-size: 24rpx;
}
.feature-project {
width: 100%;
margin: 0;
padding: 0;
overflow: hidden;
border: 2rpx solid var(--color-border);
border-radius: 26rpx;
background: #fff;
text-align: left;
box-shadow: var(--shadow-card);
}
.feature-project image {
width: 100%;
height: 260rpx;
display: block;
}
.feature-project__body {
padding: 22rpx 24rpx;
}
.feature-project__title,
.feature-project__copy {
display: block;
}
.feature-project__title {
color: var(--color-text);
font-size: 31rpx;
font-weight: 800;
}
.feature-project__copy {
margin-top: 10rpx;
color: var(--color-text-secondary);
font-size: 25rpx;
line-height: 1.6;
}
.feature-project__meta {
display: flex;
margin-top: 18rpx;
justify-content: space-between;
color: var(--color-primary);
font-size: 23rpx;
font-weight: 700;
}
.service-list {
padding: 0 24rpx;
border: 2rpx solid var(--color-border);
border-radius: 26rpx;
background: #fff;
box-shadow: var(--shadow-card);
}
.service-list button {
display: grid;
width: 100%;
min-height: 112rpx;
margin: 0;
padding: 18rpx 0;
grid-template-columns: 58rpx 1fr auto;
align-items: center;
gap: 18rpx;
border-bottom: 2rpx solid var(--color-divider);
color: var(--color-text);
background: transparent;
text-align: left;
}
.primary-action--warm {
background: #fff2ea;
.service-list button:last-child {
border-bottom: 0;
}
.primary-action--green {
color: #185f37;
border-color: #cdebd9;
background: #edf9f1;
}
.primary-action__icon {
.list-mark {
display: flex;
width: 58rpx;
height: 58rpx;
width: 56rpx;
height: 56rpx;
align-items: center;
justify-content: center;
border-radius: 18rpx;
color: #fff;
background: #f05a28;
font-size: 35rpx;
}
.primary-action--green .primary-action__icon {
background: #35a864;
}
.primary-action__title,
.primary-action__copy {
display: block;
}
.primary-action__title {
margin-top: 18rpx;
font-size: 33rpx;
font-weight: 700;
}
.primary-action__copy {
margin-top: 6rpx;
color: #755447;
font-size: 24rpx;
line-height: 1.5;
font-weight: 800;
}
.primary-action--green .primary-action__copy {
color: #52705f;
}
.primary-action__arrow {
position: absolute;
right: 18rpx;
top: 20rpx;
font-size: 36rpx;
}
.progress-banner {
display: flex;
width: 100%;
min-height: 104rpx;
margin: 20rpx 0 0;
padding: 20rpx 26rpx;
align-items: center;
justify-content: space-between;
color: #235f91;
border-radius: 24rpx;
background: #edf6fd;
text-align: left;
}
.progress-banner__label,
.progress-banner__copy {
.list-title,
.list-copy {
display: block;
}
.progress-banner__label {
.list-title {
font-size: 28rpx;
font-weight: 700;
}
.progress-banner__copy {
margin-top: 4rpx;
color: #607b91;
font-size: 24rpx;
}
.progress-banner__arrow {
font-size: 26rpx;
font-weight: 700;
}
.service-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 16rpx;
}
.service-item {
display: flex;
min-height: 142rpx;
margin: 0;
padding: 20rpx 8rpx;
flex-direction: column;
align-items: center;
justify-content: center;
border: 2rpx solid #eee7e1;
border-radius: 26rpx;
background: #fff;
}
.service-item__icon {
display: flex;
width: 58rpx;
height: 58rpx;
align-items: center;
justify-content: center;
border-radius: 20rpx;
color: #fff;
background: #f47745;
font-size: 30rpx;
}
.service-item--green .service-item__icon {
background: #46a956;
}
.service-item--blue .service-item__icon {
background: #378fd6;
}
.service-item--purple .service-item__icon {
background: #8564cf;
}
.service-item--gold .service-item__icon {
background: #e69a31;
}
.service-item--rose .service-item__icon {
background: #e96878;
}
.service-item__label {
margin-top: 12rpx;
font-size: 26rpx;
font-weight: 600;
}
.participation-card {
padding: 0 26rpx;
border: 2rpx solid var(--color-border);
border-radius: 30rpx;
background: #fff;
box-shadow: var(--shadow-card);
}
.participation-item {
display: grid;
width: 100%;
min-height: 122rpx;
margin: 0;
padding: 20rpx 0;
grid-template-columns: 64rpx 1fr auto;
align-items: center;
gap: 18rpx;
color: var(--color-text);
border-bottom: 2rpx solid #f0ece8;
background: transparent;
text-align: left;
}
.participation-item:last-child {
border-bottom: 0;
}
.participation-item__icon {
display: flex;
width: 62rpx;
height: 62rpx;
align-items: center;
justify-content: center;
border-radius: 20rpx;
color: #fff;
font-size: 32rpx;
}
.orange {
background: #f47745;
}
.blue {
background: #378fd6;
}
.green {
background: #38a862;
}
.participation-item__title,
.participation-item__copy {
display: block;
}
.participation-item__title {
font-weight: 700;
}
.participation-item__copy {
.list-copy {
margin-top: 4rpx;
color: var(--color-text-secondary);
font-size: 25rpx;
}
.content-links {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 16rpx;
}
.content-links button {
display: flex;
min-height: 96rpx;
margin: 0;
padding: 20rpx 24rpx;
align-items: center;
justify-content: space-between;
color: #544d47;
border: 2rpx solid var(--color-border);
border-radius: 24rpx;
background: #fff;
font-weight: 600;
}
.safety-note {
display: flex;
margin-top: 30rpx;
padding: 24rpx;
flex-direction: column;
color: #735818;
border-radius: 22rpx;
background: #fff7df;
font-size: 26rpx;
line-height: 1.65;
}
.safety-note__title {
margin-bottom: 5rpx;
font-weight: 700;
font-size: 23rpx;
}
@@ -2,7 +2,7 @@
<view wx:if="{{loading}}" class="profile-skeleton"><view class="skeleton-card"></view><view class="skeleton-card"></view></view>
<view wx:elif="{{error}}" class="state-card"><text class="state-title">暂时无法打开个人中心</text><text class="state-text">{{error}}</text><button class="secondary-button" bindtap="load">重新加载</button></view>
<block wx:else>
<view class="profile-hero"><view class="avatar">乐</view><view><text class="profile-name">{{user.displayName || '乐活用户'}}</text><text class="profile-id">账号已安全登录</text></view><text class="profile-badge">{{isVolunteer ? '认证志愿者' : '公益伙伴'}}</text></view>
<view class="profile-hero"><view class="avatar">乐</view><view><text class="profile-name">{{user.displayName || '乐活用户'}}</text><text class="profile-id">账号已安全登录</text></view><text class="profile-badge">{{isVolunteer ? '认证志愿者' : '公益伙伴'}}</text><view class="profile-trust"><view><strong>隐私保护</strong><text>最少采集</text></view><view><strong>服务可查</strong><text>进度留痕</text></view><view><strong>消息可达</strong><text>及时通知</text></view></view></view>
<view class="summary-card"><button bindtap="applications"><text class="summary-card__icon orange">服</text><text class="summary-card__label">我的申请</text></button><button bindtap="volunteer"><text class="summary-card__icon green">愿</text><text class="summary-card__label">志愿服务</text></button><button bindtap="notifications"><text class="summary-card__icon blue">信</text><text class="summary-card__label">我的消息</text></button></view>
<view class="section-heading"><text class="section-title">我的服务</text></view>
<view class="menu-card"><button bindtap="applications"><text class="menu-icon orange">申</text><view><text class="menu-title">我的服务申请</text><text class="menu-copy">查看需求受理与服务进度</text></view><text class="menu-arrow">›</text></button><button bindtap="volunteer"><text class="menu-icon green">愿</text><view><text class="menu-title">志愿者中心</text><text class="menu-copy">资料认证、活动报名与服务时长</text></view><text class="menu-arrow">›</text></button><button wx:if="{{canCollaborate}}" bindtap="assignedCases"><text class="menu-icon blue">协</text><view><text class="menu-title">我的协作任务</text><text class="menu-copy">查看被指派的必要服务信息</text></view><text class="menu-arrow">›</text></button></view>
@@ -4,8 +4,8 @@
.profile-hero {
position: relative;
display: flex;
min-height: 170rpx;
padding: 32rpx;
min-height: 280rpx;
padding: 32rpx 32rpx 120rpx;
align-items: center;
gap: 22rpx;
border-radius: 34rpx;
@@ -13,6 +13,35 @@
background: linear-gradient(135deg, #39aa61, #24934d);
box-shadow: 0 14rpx 32rpx rgba(35, 139, 70, 0.18);
}
.profile-trust {
position: absolute;
right: 24rpx;
bottom: 22rpx;
left: 24rpx;
display: grid;
padding-top: 20rpx;
grid-template-columns: repeat(3, 1fr);
border-top: 2rpx solid rgba(255, 255, 255, 0.24);
text-align: center;
}
.profile-trust view {
border-right: 2rpx solid rgba(255, 255, 255, 0.22);
}
.profile-trust view:last-child {
border-right: 0;
}
.profile-trust strong,
.profile-trust text {
display: block;
}
.profile-trust strong {
font-size: 25rpx;
}
.profile-trust text {
margin-top: 3rpx;
font-size: 20rpx;
opacity: 0.8;
}
.avatar {
display: flex;
width: 92rpx;
@@ -1 +1 @@
<view class="page"><block wx:if="{{loading}}"><view class="skeleton-card"></view><view class="skeleton-card"></view></block><view wx:elif="{{message}}" class="state-card"><text class="state-title">项目暂时无法查看</text><text class="state-text">{{message}}</text></view><block wx:elif="{{project}}"><view class="project-cover"><text class="project-cover__heart">♡</text><text class="project-cover__status">{{project.statusLabel}}</text></view><view class="project-title-card"><text class="project-title">{{project.name}}</text><text class="project-summary">{{project.summary}}</text><view class="project-period"><text>项目周期</text><text>{{project.startDate}} 至 {{project.endDate}}</text></view></view><view class="detail-card"><text class="detail-section-title">项目介绍</text><text class="detail-copy" selectable>{{project.content}}</text></view><view class="detail-card"><text class="detail-section-title">参与说明</text><text class="detail-copy">查看项目关联活动,选择适合的时间报名参与。平台暂不提供公开募捐交易。</text></view><button class="primary-button" bindtap="activities">查看项目活动</button></block></view>
<view class="page project-page"><block wx:if="{{loading}}"><view class="skeleton-card"></view><view class="skeleton-card"></view></block><view wx:elif="{{message}}" class="state-card"><text class="state-title">项目暂时无法查看</text><text class="state-text">{{message}}</text></view><block wx:elif="{{project}}"><image class="project-visual" src="/assets/images/brand-elder-care.jpg" mode="aspectFill"/><view class="project-title-card"><view class="project-title-row"><text class="project-title">{{project.name}}</text><text class="status-pill">{{project.statusLabel}}</text></view><text class="project-summary">{{project.summary}}</text><view class="project-facts"><view><text>服务对象</text><strong>{{project.targetPeople || '以项目说明为准'}}</strong></view><view><text>活动数量</text><strong>{{project.activityCount}}</strong></view><view><text>服务工单</text><strong>{{project.serviceCaseCount}}</strong></view></view><view class="project-period"><text>项目周期</text><text>{{project.startDate}} 至 {{project.endDate}}</text></view></view><view class="detail-card"><text class="detail-section-title">项目介绍</text><text class="detail-copy" selectable>{{project.content}}</text></view><view class="detail-card"><text class="detail-section-title">参与说明</text><text class="detail-copy">查看项目关联活动,选择适合的时间报名参与;提交后可在志愿者中心查询审核与签到状态。</text></view><button class="primary-button sticky-action" bindtap="activities">查看项目活动</button></block></view>
@@ -83,3 +83,43 @@
line-height: 1.8;
white-space: pre-wrap;
}
.project-visual {
display: block;
width: 100%;
height: 360rpx;
border-radius: 28rpx 28rpx 0 0;
}
.project-title-row {
display: flex;
align-items: flex-start;
justify-content: space-between;
gap: 20rpx;
}
.project-facts {
display: grid;
margin: 26rpx 0;
padding: 22rpx 0;
grid-template-columns: repeat(3, 1fr);
border-top: 2rpx solid var(--color-divider);
border-bottom: 2rpx solid var(--color-divider);
text-align: center;
}
.project-facts view {
border-right: 2rpx solid var(--color-divider);
}
.project-facts view:last-child {
border-right: 0;
}
.project-facts text,
.project-facts strong {
display: block;
}
.project-facts text {
color: var(--color-text-secondary);
font-size: 22rpx;
}
.project-facts strong {
margin-top: 6rpx;
color: var(--color-primary);
font-size: 28rpx;
}