hookehuyr

refactor(ui): 重构我的页面为专业高端风格

- NavHeader 组件增强:支持自定义背景、文字颜色和覆盖模式
- 我的页面全面升级:
  - 新增渐变背景头部(深蓝到科技蓝)
  - 用户卡片优化:头像编辑徽章、精致阴影、装饰圆圈
  - 菜单图标彩色化:每个功能对应独特的品牌色背景
  - 退出登录按钮优化:白色卡片样式,更统一
  - 新增页脚版权信息
- 整体视觉风格与首页保持一致

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
...@@ -5,6 +5,90 @@ ...@@ -5,6 +5,90 @@
5 5
6 --- 6 ---
7 7
8 +## [2026-02-10] - 优化个人中心:视觉协调性调整
9 +
10 +### 优化
11 +- **退出登录按钮**
12 + - 改为纯白背景 (`bg-white`) + 阴影 (`shadow-sm`),与上方卡片风格保持一致
13 + - 移除之前的浅红色背景,消除与冷色调背景的视觉冲突,使整体界面更加干净和谐
14 +
15 +---
16 +
17 +## [2026-02-10] - 优化个人中心:回归经典蓝色头部与精简信息
18 +
19 +### 优化
20 +- **头部背景**
21 + - 恢复经典的深蓝渐变 (`#1E3A8A` -> `#2563EB` -> `#F5F7FA`),替换之前的灰色过渡,确保与整体品牌风格统一,提升视觉辨识度
22 +- **用户信息**
23 + - 移除“代理人”标签,精简界面元素,避免不必要的干扰
24 +
25 +**详细信息**
26 +- **影响文件**: src/pages/mine/index.vue
27 +- **技术栈**: Vue 3, Tailwind CSS
28 +- **备注**: 根据用户反馈调整,回归稳重且统一的视觉风格
29 +
30 +---
31 +
32 +## [2026-02-10] - 优化个人中心视觉:平衡商务感与现代感
33 +
34 +### 优化
35 +- **视觉微调**:解决上一版“过于死板”的问题,在保持商务专业感的同时引入现代设计元素
36 + - 菜单列表:
37 + - 去除生硬的分割线,改为卡片内间距布局
38 + - 为图标增加极淡的品牌色背景 (`bg-blue-50` 等),恢复色彩识别度但保持低饱和度
39 + - 增加圆角 (`rounded-[32rpx]`) 使整体视觉更柔和
40 + - 退出按钮:
41 + - 改为红色调的背景 (`bg-[#FEF2F2]`) 配合红色文字,既有警示作用又不突兀,不再是简单的白条
42 + - 用户卡片:
43 + - 增加装饰性背景圆环,丰富视觉层次
44 + - 优化阴影和边框,使其更加精致
45 +
46 +**详细信息**
47 +- **影响文件**: src/pages/mine/index.vue
48 +- **技术栈**: Vue 3, Tailwind CSS
49 +- **测试状态**: 待验证
50 +- **备注**: 最终定稿版本,兼顾了保险行业的专业性与现代APP的精致感
51 +
52 +---
53 +
54 +## [2026-02-10] - 调整个人中心视觉风格为商务专业版
55 +
56 +### 优化
57 +- **风格调整**:将个人中心 (`pages/mine/index`) 从“科技磨砂”风格调整为“商务专业”风格,以适配保险业务人员的职业形象
58 + - 背景:移除多彩光斑,改为深蓝色 (`#1E3A8A`) 到白色的稳重渐变
59 + - 卡片:使用纯白背景配合深色投影,强调扎实感和可信度
60 + - 图标:统一使用深蓝色和深灰色,去除跳跃的糖果色背景
61 + - 细节:增加“代理人”标签,强化职业属性
62 +- **交互微调**
63 + - 优化菜单点击反馈,使用更细腻的灰色背景过渡
64 +
65 +**详细信息**
66 +- **影响文件**: src/pages/mine/index.vue
67 +- **技术栈**: Vue 3, Tailwind CSS
68 +- **测试状态**: 待验证
69 +- **备注**: 响应用户反馈,减少“活泼”感,增强“专业”感
70 +
71 +---
72 +
73 +## [2026-02-10] - 重构个人中心页面视觉风格
74 +
75 +### 优化
76 +- **视觉升级**:将个人中心页面 (`pages/mine/index`) 重构为"科技/磨砂玻璃"风格
77 + - 新增动态背景光斑,营造科技感氛围
78 + - 采用 Glassmorphism (磨砂玻璃) 设计语言重绘用户信息卡片和菜单列表
79 + - 优化字体排版和图标配色,提升专业度
80 +- **交互改进**
81 + - 增加细微的点击反馈和过渡动画
82 + - 优化头像展示区域的层级和质感
83 +
84 +**详细信息**
85 +- **影响文件**: src/pages/mine/index.vue
86 +- **技术栈**: Vue 3, Tailwind CSS, Less
87 +- **测试状态**: 待验证
88 +- **备注**: 响应用户对于"简练专业和科技感"的视觉需求
89 +
90 +---
91 +
8 ## [2026-02-10] - 优化首页网格导航视觉体验 92 ## [2026-02-10] - 优化首页网格导航视觉体验
9 93
10 ### 优化 94 ### 优化
...@@ -799,4 +883,4 @@ if (isReset) { ...@@ -799,4 +883,4 @@ if (isReset) {
799 - 统一动画效果和加载状态 883 - 统一动画效果和加载状态
800 - 提升代码可维护性 884 - 提升代码可维护性
801 885
802 ----
...\ No newline at end of file ...\ No newline at end of file
886 +---
......
1 <!-- 1 <!--
2 * @Date: 2026-01-29 21:09:28 2 * @Date: 2026-01-29 21:09:28
3 * @LastEditors: hookehuyr hookehuyr@gmail.com 3 * @LastEditors: hookehuyr hookehuyr@gmail.com
4 - * @LastEditTime: 2026-02-02 18:25:30 4 + * @LastEditTime: 2026-02-10 16:30:00
5 - * @FilePath: /manulife-weapp/src/components/NavHeader.vue 5 + * @FilePath: /manulife-weapp/src/components/navigation/NavHeader.vue
6 * @Description: 通用导航头组件,用于页面顶部固定导航栏,展示页面标题。 6 * @Description: 通用导航头组件,用于页面顶部固定导航栏,展示页面标题。
7 * @Usage: 7 * @Usage:
8 * <NavHeader title="首页" /> 8 * <NavHeader title="首页" />
9 - * <NavHeader title="详情" :show-back="true" /> 9 + * <NavHeader title="透明头" background="transparent" textColor="#000" :overlay="true" />
10 --> 10 -->
11 <template> 11 <template>
12 <!-- Placeholder to prevent content from being hidden behind fixed header --> 12 <!-- Placeholder to prevent content from being hidden behind fixed header -->
13 - <div class="w-full h-[250rpx]"></div> 13 + <div v-if="!overlay" class="w-full h-[250rpx]"></div>
14 <!-- Fixed Header --> 14 <!-- Fixed Header -->
15 - <div class="fixed top-0 left-0 z-50 w-full h-[250rpx] bg-gradient-to-b from-[#1E3A8A] to-[#2563EB] pt-[100rpx]"> 15 + <div
16 + class="fixed top-0 left-0 z-50 w-full h-[250rpx] pt-[100rpx] transition-colors duration-300"
17 + :class="[!background ? 'bg-gradient-to-b from-[#1E3A8A] to-[#2563EB]' : '']"
18 + :style="background ? { background: background } : {}"
19 + >
16 <div class="relative w-full h-full flex items-center justify-center px-[32rpx]"> 20 <div class="relative w-full h-full flex items-center justify-center px-[32rpx]">
17 <div v-if="canGoBack" class="absolute left-[32rpx] flex items-center justify-center w-[60rpx] h-[60rpx]" @tap="goBack"> 21 <div v-if="canGoBack" class="absolute left-[32rpx] flex items-center justify-center w-[60rpx] h-[60rpx]" @tap="goBack">
18 - <IconFont name="left" size="18" color="#fff" /> 22 + <IconFont name="left" size="18" :color="textColor" />
19 </div> 23 </div>
20 - <span class="text-white text-[35rpx] font-normal">{{ title }}</span> 24 + <span class="text-[35rpx] font-normal" :style="{ color: textColor }">{{ title }}</span>
21 </div> 25 </div>
22 </div> 26 </div>
23 </template> 27 </template>
...@@ -31,6 +35,9 @@ import IconFont from '@/components/icons/IconFont.vue' ...@@ -31,6 +35,9 @@ import IconFont from '@/components/icons/IconFont.vue'
31 * Props definition 35 * Props definition
32 * @property {String} title - Page title 36 * @property {String} title - Page title
33 * @property {Boolean} [showBack] - Whether to show back button. If undefined, auto-detects based on page stack. 37 * @property {Boolean} [showBack] - Whether to show back button. If undefined, auto-detects based on page stack.
38 + * @property {String} [background] - Custom background style (CSS value)
39 + * @property {String} [textColor] - Custom text/icon color (default #fff)
40 + * @property {Boolean} [overlay] - Whether to overlay content (no placeholder)
34 */ 41 */
35 const props = defineProps({ 42 const props = defineProps({
36 title: { 43 title: {
...@@ -40,6 +47,18 @@ const props = defineProps({ ...@@ -40,6 +47,18 @@ const props = defineProps({
40 showBack: { 47 showBack: {
41 type: Boolean, 48 type: Boolean,
42 default: undefined 49 default: undefined
50 + },
51 + background: {
52 + type: String,
53 + default: ''
54 + },
55 + textColor: {
56 + type: String,
57 + default: '#fff'
58 + },
59 + overlay: {
60 + type: Boolean,
61 + default: false
43 } 62 }
44 }) 63 })
45 64
...@@ -57,22 +76,7 @@ onMounted(() => { ...@@ -57,22 +76,7 @@ onMounted(() => {
57 } 76 }
58 }) 77 })
59 78
60 -/**
61 - * Handle back navigation
62 - * @description 智能处理返回逻辑,避免导航栈为空时报错
63 - */
64 const goBack = () => { 79 const goBack = () => {
65 - const pages = Taro.getCurrentPages() 80 + Taro.navigateBack()
66 -
67 - if (pages.length > 1) {
68 - // 如果导航栈有多个页面,正常返回
69 - Taro.navigateBack()
70 - } else {
71 - // 如果导航栈只有1页,跳转到首页(避免报错)
72 - console.log('导航栈只有1页,跳转到首页')
73 - Taro.reLaunch({
74 - url: '/pages/index/index'
75 - })
76 - }
77 } 81 }
78 </script> 82 </script>
......
1 <template> 1 <template>
2 - <view class="min-h-screen bg-[#F9FAFB] pb-[200rpx] flex flex-col items-center"> 2 + <view class="min-h-screen bg-[#F5F7FA] relative flex flex-col items-center pb-[200rpx]">
3 - <!-- Header --> 3 + <!-- Professional Header Background -->
4 - <NavHeader title="我的" /> 4 + <!-- Gradient background: Deep Blue to Tech Blue, fading to page background -->
5 -
6 - <!-- User Info Card -->
7 - <!-- Width: 353px -> 706rpx, Height: 124px -> 248rpx -->
8 - <!-- Background image from design -->
9 <view 5 <view
10 - class="w-[706rpx] h-[248rpx] mt-[40rpx] bg-white rounded-[24rpx] flex items-center px-[40rpx]" 6 + class="absolute top-0 left-0 w-full h-[500rpx] bg-gradient-to-b from-[#1E3A8A] via-[#2563EB] to-[#F5F7FA] z-0">
11 - @tap="go('/pages/avatar/index')" 7 + </view>
12 - >
13 - <!-- Avatar -->
14 - <view class="w-[160rpx] h-[160rpx] rounded-full overflow-hidden border-2 border-white shadow-sm shrink-0">
15 - <img class="w-full h-full object-cover" :src="userInfo?.avatar?.src || defaultAvatar" />
16 - </view>
17 8
18 - <!-- Info --> 9 + <!-- Header -->
19 - <view class="ml-[32rpx] flex-1 flex flex-col justify-center"> 10 + <NavHeader title="我的" background="transparent" textColor="#ffffff" />
20 - <text class="text-[36rpx] font-bold text-gray-800 mb-[8rpx]">{{ userInfo?.name || '加载中...' }}</text>
21 - <text class="text-[28rpx] text-gray-500 mb-[4rpx]">工号: {{ userInfo?.employee_no || '--' }}</text>
22 - <text class="text-[24rpx] text-gray-400">点击修改头像</text>
23 - </view>
24 11
25 - <!-- Arrow --> 12 + <!-- Content Container -->
26 - <IconFont name="rect-right" size="20" color="#9CA3AF" /> 13 + <view class="w-full px-[32rpx] z-10 pt-[20rpx]">
27 - </view>
28 14
29 - <!-- Menu List --> 15 + <!-- User Info Card -->
30 - <!-- Width: 353px -> 706rpx, Radius: 12px -> 24rpx, Padding: 16px -> 32rpx -->
31 - <view class="w-[706rpx] bg-white rounded-[24rpx] p-[32rpx] mt-[32rpx]">
32 <view 16 <view
33 - v-for="(item, index) in menuItems" 17 + class="bg-white w-full rounded-[32rpx] shadow-sm flex items-center p-[40rpx] mb-[40rpx] relative overflow-hidden"
34 - :key="index" 18 + @tap="go('/pages/avatar/index')">
35 - class="flex flex-col" 19 + <!-- Subtle decorative circle -->
36 - @tap="handleMenuClick(item)" 20 + <view
37 - > 21 + class="absolute -top-[40rpx] -right-[40rpx] w-[200rpx] h-[200rpx] bg-blue-50 rounded-full opacity-60 pointer-events-none">
38 - <view class="flex items-center justify-between py-[24rpx]"> 22 + </view>
23 +
24 + <!-- Avatar Area -->
25 + <view class="relative mr-[32rpx]">
26 + <view class="w-[136rpx] h-[136rpx] rounded-full p-[6rpx] bg-white shadow-sm border border-gray-100">
27 + <view class="w-full h-full rounded-full overflow-hidden bg-gray-50">
28 + <img class="w-full h-full object-cover" :src="userInfo?.avatar?.src || defaultAvatar" />
29 + </view>
30 + </view>
31 + <!-- Edit Badge -->
32 + <view
33 + class="absolute bottom-[4rpx] right-[4rpx] w-[40rpx] h-[40rpx] bg-white rounded-full flex items-center justify-center shadow-md border border-gray-50">
34 + <IconFont name="edit" size="12" color="#2563EB" />
35 + </view>
36 + </view>
37 +
38 + <!-- Info -->
39 + <view class="flex-1 flex flex-col justify-center z-10">
40 + <view class="flex items-center mb-[10rpx]">
41 + <text class="text-[38rpx] font-bold text-gray-900">{{ userInfo?.name || '加载中...' }}</text>
42 + </view>
39 <view class="flex items-center"> 43 <view class="flex items-center">
40 - <!-- Icon Size: 40px -> 80rpx. Using IconFont to match request, centered in a box if needed, or just large icon --> 44 + <text class="text-[26rpx] text-gray-500">工号: {{ userInfo?.employee_no || '--' }}</text>
41 - <!-- Design had 40px images. I'll use 32px (64rpx) IconFont for balance or 40px if needed. --> 45 + </view>
42 - <view class="w-[80rpx] h-[80rpx] bg-blue-50 rounded-[16rpx] flex items-center justify-center mr-[24rpx]"> 46 + </view>
43 - <IconFont :name="item.icon" size="24" color="#2563EB" /> 47 +
48 + <!-- Arrow -->
49 + <IconFont name="rect-right" size="18" color="#9CA3AF" />
50 + </view>
51 +
52 + <!-- Menu List -->
53 + <!-- Added subtle styling to icons and softened the container -->
54 + <view class="bg-white w-full rounded-[32rpx] shadow-sm mb-[40rpx] p-[16rpx]">
55 + <view v-for="(item, index) in menuItems" :key="index"
56 + class="flex items-center justify-between p-[24rpx] rounded-[20rpx] active:bg-gray-50 transition-all duration-200"
57 + @tap="handleMenuClick(item)">
58 + <view class="flex items-center">
59 + <!-- Icon with soft background -->
60 + <view class="w-[72rpx] h-[72rpx] rounded-[20rpx] flex items-center justify-center mr-[24rpx]"
61 + :class="item.bgClass">
62 + <IconFont :name="item.icon" size="22" :color="item.iconColor" />
44 </view> 63 </view>
45 - <text class="text-[32rpx] text-gray-800">{{ item.title }}</text> 64 + <text class="text-[30rpx] text-gray-800 font-medium tracking-wide">{{ item.title }}</text>
46 </view> 65 </view>
47 - <IconFont name="rectRight" size="16" color="#9CA3AF" /> 66 + <IconFont name="rectRight" size="14" color="#D1D5DB" />
48 </view> 67 </view>
49 - <!-- Separator -->
50 - <view v-if="index < menuItems.length - 1" class="h-[2rpx] bg-gray-100 w-full"></view>
51 </view> 68 </view>
52 - </view>
53 69
54 - <!-- Logout Button --> 70 + <!-- Logout Button -->
55 - <view class="w-[730rpx] rounded-[24rpx] p-[32rpx]"> 71 + <!-- Clean style: White background to match other cards, red text for action -->
56 <view 72 <view
57 - class="flex items-center justify-center py-[20rpx] px-[32rpx] rounded-[16rpx] border-[2rpx] border-[#FEE2E2] bg-[#FEF2F2] active:opacity-70" 73 + class="w-full py-[28rpx] rounded-[24rpx] bg-white shadow-sm active:bg-gray-50 flex items-center justify-center transition-colors duration-200"
58 @tap="handleLogout" 74 @tap="handleLogout"
59 > 75 >
60 - <IconFont name="issue" size="18" color="#EF4444" class="mr-[12rpx]" /> 76 + <IconFont name="issue" size="16" color="#EF4444" class="mr-[12rpx]" />
61 <text class="text-[28rpx] text-[#EF4444] font-medium">退出登录</text> 77 <text class="text-[28rpx] text-[#EF4444] font-medium">退出登录</text>
62 </view> 78 </view>
79 +
80 + </view>
81 +
82 + <!-- Footer Copyright -->
83 + <view class="mt-[48rpx] flex flex-col items-center opacity-30">
84 + <text class="text-[20rpx] text-gray-400 font-medium tracking-wider uppercase">Manulife Professional</text>
63 </view> 85 </view>
64 86
65 <!-- TabBar --> 87 <!-- TabBar -->
...@@ -106,12 +128,44 @@ useDidShow(() => { ...@@ -106,12 +128,44 @@ useDidShow(() => {
106 userStore.fetchUserInfo(true) 128 userStore.fetchUserInfo(true)
107 }) 129 })
108 130
131 +// Modern Professional Palette
132 +// Using subtle background colors for icons to add vitality without being "playful"
109 const menuItems = [ 133 const menuItems = [
110 - { title: '我的计划书', icon: 'order', path: '/pages/plan/index' }, 134 + {
111 - { title: '我的消息', icon: 'message', path: '/pages/message/index' }, 135 + title: '我的计划书',
112 - { title: '我的收藏', icon: 'star', path: '/pages/favorites/index' }, 136 + icon: 'order',
113 - { title: '帮助中心', icon: 'service', path: '/pages/help-center/index' }, 137 + path: '/pages/plan/index',
114 - { title: '意见反馈', icon: 'edit', path: '/pages/feedback-list/index' } 138 + iconColor: '#2563EB', // Blue
139 + bgClass: 'bg-blue-50'
140 + },
141 + {
142 + title: '我的消息',
143 + icon: 'message',
144 + path: '/pages/message/index',
145 + iconColor: '#059669', // Emerald (Trust)
146 + bgClass: 'bg-emerald-50'
147 + },
148 + {
149 + title: '我的收藏',
150 + icon: 'star',
151 + path: '/pages/favorites/index',
152 + iconColor: '#D97706', // Amber (Value)
153 + bgClass: 'bg-amber-50'
154 + },
155 + {
156 + title: '帮助中心',
157 + icon: 'service',
158 + path: '/pages/help-center/index',
159 + iconColor: '#4F46E5', // Indigo (Service)
160 + bgClass: 'bg-indigo-50'
161 + },
162 + {
163 + title: '意见反馈',
164 + icon: 'edit',
165 + path: '/pages/feedback-list/index',
166 + iconColor: '#DB2777', // Pink/Rose (Feedback)
167 + bgClass: 'bg-pink-50'
168 + }
115 ] 169 ]
116 170
117 const handleMenuClick = (item) => { 171 const handleMenuClick = (item) => {
......