hookehuyr

feat: 新增资料列表页面并优化图标组件

- 新增 "资料列表" 页面 (`src/pages/material-list/index.vue`),包含搜索栏、资料列表展示及收藏功能
- 注册页面路由至 `src/app.config.js` 并添加页面配置文件
- 扩展 `IconFont` 组件,新增 `StarFill` 图标以支持收藏状态切换
- 更新 CHANGELOG.md 文档,记录新增功能与优化项
......@@ -5,6 +5,9 @@ All notable changes to this project will be documented in this file.
## [Unreleased]
### Changed
- 优化 "资料列表" 页面 (`src/pages/material-list`):
- 替换页面内所有静态图片资源为 NutUI 图标组件 (`IconFont`),提升加载性能与视觉一致性
- 扩展 `IconFont` 组件,新增 `StarFill` 图标支持
- 优化 "我的" 页面 (`src/pages/mine`):
- 重构页面布局,严格还原设计稿 (`docs/design/manulife-V1/我的`) 样式
- 引入用户卡片背景图,优化头像、姓名及工号展示布局
......@@ -38,6 +41,11 @@ All notable changes to this project will be documented in this file.
- 补充 `src/pages/feedback/index.vue``NavHeader` 组件的引用
### Added
- 新增 "资料列表" 页面 (`src/pages/material-list/index`):
- 实现基于 Design 的列表 UI,精确还原设计稿 (`docs/design/manulife-V1/资料列表`)
- 集成 `NavHeader``TabBar` 组件,保持全站导航一致性
- 使用 Tailwind CSS 进行样式开发,替代原有 CSS
- 注册路由至 `src/app.config.js`
- 新增 "我的" 页面 (`src/pages/mine`),包含用户信息展示、功能菜单列表
- 新增 "我的计划书" 页面 (`src/pages/plan`),实现计划书列表展示、搜索过滤、状态切换功能
- 新增 "我的收藏" 页面 (`src/pages/favorites`),实现文章/资料收藏列表及分类筛选功能
......
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
......@@ -15,6 +15,7 @@ const pages = [
'pages/onboarding/index',
'pages/family-office/index',
'pages/knowledge-base/index',
'pages/material-list/index',
'pages/signing/index',
'pages/mine/index',
'pages/plan/index',
......
<!--
* @Date: 2026-01-29 21:30:20
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2026-01-29 23:14:24
* @LastEditTime: 2026-01-30 15:29:14
* @FilePath: /manulife-weapp/src/components/IconFont.vue
* @Description: 图标字体组件
-->
......@@ -35,6 +35,7 @@ import {
Search,
Service,
Star,
StarFill,
Top,
Photograph,
Del
......@@ -83,6 +84,7 @@ const icons = {
Search,
Service,
Star,
StarFill,
Top,
Photograph,
Del
......
export default {
navigationBarTitleText: '资料列表',
enablePullDownRefresh: true,
backgroundColor: '#F9FAFB',
navigationStyle: 'custom'
}
<!--
* @Date: 2026-01-30
* @Description: 资料列表页
-->
<template>
<div class="min-h-screen bg-[#F9FAFB] pb-[calc(160rpx+env(safe-area-inset-bottom))]">
<!-- Navigation Header -->
<NavHeader title="资料列表" />
<!-- Search Bar -->
<div class="px-[32rpx] mt-[32rpx]">
<div class="bg-white rounded-[12rpx] flex items-center px-[32rpx] py-[24rpx]">
<IconFont name="Search" size="20" color="#9CA3AF" customClass="mr-[16rpx]" />
<input
v-model="searchValue"
type="text"
placeholder="搜索资料..."
class="flex-1 text-[28rpx] text-[#1F2937] placeholder-gray-400 bg-transparent outline-none"
@confirm="onSearch"
/>
</div>
</div>
<!-- Material List -->
<div class="px-[32rpx] mt-[40rpx]">
<div class="bg-white rounded-[32rpx] p-[32rpx] shadow-sm">
<div v-for="(item, index) in list" :key="index">
<div class="flex justify-between items-start pt-[32rpx] first:pt-0">
<div class="flex items-start flex-1 mr-[20rpx]">
<div class="w-[80rpx] h-[88rpx] mr-[24rpx] flex-shrink-0 flex items-center justify-center bg-blue-50 rounded-[12rpx]">
<IconFont :name="item.iconName || 'Order'" size="32" :color="item.iconColor || '#2563EB'" />
</div>
<div class="flex flex-col">
<span class="text-[#1F2937] text-[28rpx] font-normal leading-[1.2] mb-[14rpx] line-clamp-2">
{{ item.title }}
</span>
<span class="text-[#6B7280] text-[24rpx] leading-[1.3] line-clamp-1">
{{ item.desc }}
</span>
</div>
</div>
<!-- Action Icon (Download/Detail) -->
<IconFont name="Download" size="20" color="#9CA3AF" />
</div>
<div class="flex items-center mt-[16rpx] ml-[104rpx] pb-[32rpx]">
<span class="text-[#9CA3AF] text-[24rpx] mr-[40rpx]">{{ item.size }}</span>
<div class="flex items-center" @click="toggleCollect(item)">
<IconFont
:name="item.collected ? 'StarFill' : 'Star'"
size="12"
:color="item.collected ? '#F59E0B' : '#9CA3AF'"
customClass="mr-[8rpx]"
/>
<span :class="['text-[24rpx]', item.collected ? 'text-[#F59E0B]' : 'text-[#9CA3AF]']">
{{ item.collected ? '已收藏' : '收藏' }}
</span>
</div>
</div>
<!-- Divider -->
<div v-if="index < list.length - 1" class="h-[1px] bg-[#E5E7EB] w-full mb-[32rpx]"></div>
</div>
</div>
</div>
<!-- Tab Bar -->
<TabBar />
</div>
</template>
<script setup>
import { ref } from 'vue'
import NavHeader from '@/components/NavHeader.vue'
import TabBar from '@/components/TabBar.vue'
import IconFont from '@/components/IconFont.vue'
const searchValue = ref('')
const list = ref([
{
title: '2024年保险代理人考试大纲.pdf',
desc: '最新考试范围与重点解析',
size: '2.1MB',
iconName: 'Order',
iconColor: '#EF4444',
collected: true
},
{
title: '历年真题汇总及解析.pdf',
desc: '2019-2023年真题完整版',
size: '5.3MB',
iconName: 'Order',
iconColor: '#EF4444',
collected: false
},
{
title: '考试技巧与经验分享.pdf',
desc: '高分学员备考心得',
size: '1.8MB',
iconName: 'Order',
iconColor: '#EF4444',
collected: false
},
{
title: '保险基础知识速记手册.pdf',
desc: '核心知识点快速记忆',
size: '3.2MB',
iconName: 'Order',
iconColor: '#EF4444',
collected: false
},
{
title: '模拟试卷10套及答案.pdf',
desc: '考前冲刺模拟练习',
size: '4.5MB',
iconName: 'Order',
iconColor: '#EF4444',
collected: true
},
{
title: '法律法规重点条款解读.pdf',
desc: '保险相关法规详解',
size: '2.8MB',
iconName: 'Order',
iconColor: '#EF4444',
collected: false
},
{
title: '考试常见易错题分析.pdf',
desc: '高频错题归纳总结',
size: '1.5MB',
iconName: 'Order',
iconColor: '#EF4444',
collected: false
},
{
title: '案例分析题库及解答.pdf',
desc: '实务案例精选练习',
size: '3.9MB',
iconName: 'Order',
iconColor: '#EF4444',
collected: false
},
{
title: '考前冲刺复习资料.pdf',
desc: '最后一周复习要点',
size: '2.3MB',
iconName: 'Order',
iconColor: '#EF4444',
collected: false
},
{
title: '考场注意事项及答题技巧.pdf',
desc: '应试策略与时间分配',
size: '1.2MB',
iconName: 'Order',
iconColor: '#EF4444',
collected: false
}
])
/**
* Search handler
*/
const onSearch = () => {
console.log('Searching for:', searchValue.value)
}
/**
* Toggle collect status
* @param {Object} item
*/
const toggleCollect = (item) => {
item.collected = !item.collected
}
</script>