hookehuyr

refactor(pages/index): 重构首页并移除离线功能相关代码

- 删除旧版首页 Less 样式文件,全面采用 Tailwind CSS
- 更新首页配置,将导航栏标题改为"臻奇智荟圈"
- 重构首页 Vue 组件,适配新设计稿并使用 Taro + Vue 3 Setup 语法
- 移除所有离线功能相关逻辑、网络状态监听和弱网缓存代码
- 清理应用配置文件,移除未使用的页面路由
- 更新 CHANGELOG 文档记录所有变更
- 添加设计稿相关资源文件
......@@ -8,3 +8,31 @@ All notable changes to this project will be documented in this file.
- 初始化项目 Git 仓库
- 创建 .gitignore 配置文件
- 创建并切换到 develop 分支
### Changed
- 暂时禁用授权模式功能 (`ENABLE_AUTH_MODE = false`)
- 拦截所有授权检查与自动跳转登录逻辑
- 禁用 401 自动续期拦截器
- 暂时禁用离线模式功能 (`ENABLE_OFFLINE_MODE = false`)
- 拦截所有离线缓存读写操作与轮询逻辑
- 修复 `src/pages/index/index.vue``ENABLE_OFFLINE_MODE` 引用缺失导致的报错
- 优化 `src/pages/index/index.vue` 减少不必要的网络监听资源消耗
- 重构首页 (`src/pages/index`),使用 Taro + Vue 3 Setup 语法实现
- 适配 `docs/design/manulife-V1/首页` 设计稿,精确还原 UI
- 转换 CSS 为 Less,并使用 `rpx` 单位适配小程序响应式布局
- 整合离线网络检测与状态管理逻辑
- 更新首页导航栏标题为 "臻奇智荟圈"
- 重构首页样式 (`src/pages/index`),全面采用 Tailwind CSS 替代 Less
- 替换静态图片资源为 Picsum 随机图源,提升演示灵活性
- 集成 NutUI 图标组件库,替换原有 SVG/图片图标
### Removed
- 删除项目所有离线功能相关逻辑
- 移除 `src/composables/useOfflineBookingCache.js``useOfflineBookingCachePolling.js`
- 清理 `src/app.js` 中的离线初始化代码
- 清理 `src/utils/request.js` 中的弱网缓存拦截与提示逻辑
- 清理 `src/pages/index/index.vue` 中的网络状态监听与离线模式代码
- 移除 `src/utils/uiText.js` 及相关引用
- 移除 `src/api/index.js` 中的离线专用接口定义
- 更新配置文件,移除 `ENABLE_OFFLINE_MODE` 开关
- 修复构建告警:移除首页残留的 `ENABLE_OFFLINE_MODE``@/utils/uiText` 引用
......
.page {
position: relative;
width: 393px;
height: 1194px;
overflow: hidden;
}
.box_1 {
background-color: rgba(30, 58, 138, 1);
width: 393px;
padding: 12px 20px 12px 20px;
}
.text_1 {
overflow-wrap: break-word;
color: rgba(255, 255, 255, 1);
font-size: 14px;
font-family: Helvetica, 'Microsoft YaHei', Arial, sans-serif;
font-weight: normal;
text-align: left;
white-space: nowrap;
line-height: 20px;
}
.image_1 {
width: 64px;
height: 20px;
}
.box_2 {
background-color: rgba(249, 250, 251, 1);
margin-top: 124px;
padding-top: 24px;
}
.group_1 {
box-shadow: 0px 2px 8px 0px rgba(0, 0, 0, 0.04);
background-color: rgba(255, 255, 255, 1);
border-radius: 16px;
align-self: center;
width: 353px;
padding: 20px 41px 23px 41px;
}
.grid_1 {
width: 272px;
height: 175px;
flex-wrap: wrap;
}
.image-text_1 {
width: 52px;
height: 78px;
margin: 0 58px 19px 0;
}
.image-text_1:nth-child(3n) {
margin-right: 0;
}
.image-text_1:nth-last-child(-n + 3) {
margin-bottom: 0;
}
.image_2 {
width: 52px;
height: 52px;
}
.text-group_1 {
width: 65px;
overflow-wrap: break-word;
color: rgba(31, 41, 55, 1);
font-size: 13px;
font-family: Helvetica, 'Microsoft YaHei', Arial, sans-serif;
font-weight: normal;
text-align: left;
white-space: nowrap;
line-height: 16px;
margin: 10px 7px 0 6px;
}
.group_2 {
box-shadow: 0px 2px 8px 0px rgba(0, 0, 0, 0.04);
background-color: rgba(255, 255, 255, 1);
border-radius: 16px;
width: 353px;
align-self: center;
margin-top: 12px;
padding: 16px 16px 16px 16px;
}
.text-wrapper_1 {
width: 321px;
}
.text_2 {
overflow-wrap: break-word;
color: rgba(31, 41, 55, 1);
font-size: 16px;
font-family: Helvetica, 'Microsoft YaHei', Arial, sans-serif;
font-weight: normal;
text-align: left;
white-space: nowrap;
line-height: 18px;
}
.text_3 {
overflow-wrap: break-word;
color: rgba(37, 99, 235, 1);
font-size: 13px;
font-family: Helvetica, 'Microsoft YaHei', Arial, sans-serif;
font-weight: normal;
text-align: left;
white-space: nowrap;
line-height: 16px;
margin-top: 2px;
}
.box_3 {
background-color: rgba(249, 250, 251, 1);
border-radius: 12px;
margin-top: 22px;
padding: 14px 15px 14px 14px;
}
.text_4 {
overflow-wrap: break-word;
color: rgba(31, 41, 55, 1);
font-size: 14px;
font-family: Helvetica, 'Microsoft YaHei', Arial, sans-serif;
font-weight: normal;
text-align: left;
white-space: nowrap;
line-height: 17px;
margin-right: 96px;
}
.grid_2 {
width: 225px;
height: 50px;
flex-wrap: wrap;
margin: 13px 67px 0 0;
}
.text-wrapper_2 {
background-color: rgba(254, 226, 226, 1);
border-radius: 4px;
height: 22px;
width: 75px;
margin: 0 6px 6px 0;
padding: 3px 8px 3px 8px;
}
.text_5 {
height: 16px;
overflow-wrap: break-word;
color: rgba(220, 38, 38, 1);
font-size: 11px;
font-family: Helvetica, 'Microsoft YaHei', Arial, sans-serif;
font-weight: normal;
text-align: left;
white-space: nowrap;
line-height: 13px;
}
.text-wrapper_3 {
background-color: rgba(254, 215, 170, 1);
border-radius: 4px;
height: 22px;
width: 56px;
margin: 0 6px 6px 0;
padding: 3px 8px 6px 8px;
}
.text_6 {
overflow-wrap: break-word;
color: rgba(234, 88, 12, 1);
font-size: 11px;
font-family: Helvetica, 'Microsoft YaHei', Arial, sans-serif;
font-weight: normal;
text-align: left;
white-space: nowrap;
line-height: 13px;
}
.text-wrapper_4 {
background-color: rgba(209, 250, 229, 1);
border-radius: 4px;
height: 22px;
margin-bottom: 6px;
width: 82px;
padding: 3px 8px 6px 8px;
}
.text_7 {
overflow-wrap: break-word;
color: rgba(5, 150, 105, 1);
font-size: 11px;
font-family: Helvetica, 'Microsoft YaHei', Arial, sans-serif;
font-weight: normal;
text-align: left;
white-space: nowrap;
line-height: 13px;
}
.text-wrapper_5 {
background-color: rgba(219, 234, 254, 1);
border-radius: 4px;
height: 22px;
margin-right: NaNpx;
margin-bottom: 6px;
width: 70px;
padding: 3px 8px 3px 8px;
}
.text_8 {
height: 16px;
overflow-wrap: break-word;
color: rgba(37, 99, 235, 1);
font-size: 11px;
font-family: Helvetica, 'Microsoft YaHei', Arial, sans-serif;
font-weight: normal;
text-align: left;
white-space: nowrap;
line-height: 13px;
}
.section_1 {
width: 292px;
margin-top: 12px;
}
.text-wrapper_6 {
background-color: rgba(255, 255, 255, 1);
border-radius: 8px;
border: 1px solid rgba(37, 99, 235, 1);
padding: 7px 44px 10px 44px;
}
.text_9 {
overflow-wrap: break-word;
color: rgba(37, 99, 235, 1);
font-size: 13px;
font-family: Helvetica, 'Microsoft YaHei', Arial, sans-serif;
font-weight: normal;
text-align: center;
white-space: nowrap;
line-height: 16px;
}
.text-wrapper_7 {
background-color: rgba(37, 99, 235, 1);
border-radius: 8px;
padding: 8px 51px 11px 52px;
}
.text_10 {
overflow-wrap: break-word;
color: rgba(255, 255, 255, 1);
font-size: 13px;
font-family: Helvetica, 'Microsoft YaHei', Arial, sans-serif;
font-weight: normal;
text-align: center;
white-space: nowrap;
line-height: 16px;
}
.box_4 {
background-color: rgba(249, 250, 251, 1);
border-radius: 12px;
margin-top: 12px;
padding: 14px 15px 14px 14px;
}
.text_11 {
overflow-wrap: break-word;
color: rgba(31, 41, 55, 1);
font-size: 14px;
font-family: Helvetica, 'Microsoft YaHei', Arial, sans-serif;
font-weight: normal;
text-align: left;
white-space: nowrap;
line-height: 17px;
margin-right: 110px;
}
.block_1 {
width: 198px;
margin: 13px 94px 0 0;
}
.text-wrapper_8 {
background-color: rgba(254, 226, 226, 1);
border-radius: 4px;
padding: 3px 8px 3px 8px;
}
.text_12 {
height: 16px;
overflow-wrap: break-word;
color: rgba(220, 38, 38, 1);
font-size: 11px;
font-family: Helvetica, 'Microsoft YaHei', Arial, sans-serif;
font-weight: normal;
text-align: left;
white-space: nowrap;
line-height: 13px;
}
.text-wrapper_9 {
background-color: rgba(254, 215, 170, 1);
border-radius: 4px;
padding: 3px 8px 6px 8px;
}
.text_13 {
overflow-wrap: break-word;
color: rgba(234, 88, 12, 1);
font-size: 11px;
font-family: Helvetica, 'Microsoft YaHei', Arial, sans-serif;
font-weight: normal;
text-align: left;
white-space: nowrap;
line-height: 13px;
}
.text-wrapper_10 {
background-color: rgba(209, 250, 229, 1);
border-radius: 4px;
padding: 3px 8px 6px 8px;
}
.text_14 {
overflow-wrap: break-word;
color: rgba(5, 150, 105, 1);
font-size: 11px;
font-family: Helvetica, 'Microsoft YaHei', Arial, sans-serif;
font-weight: normal;
text-align: left;
white-space: nowrap;
line-height: 13px;
}
.block_2 {
width: 292px;
margin-top: 12px;
}
.text-wrapper_11 {
background-color: rgba(255, 255, 255, 1);
border-radius: 8px;
border: 1px solid rgba(37, 99, 235, 1);
padding: 7px 44px 10px 44px;
}
.text_15 {
overflow-wrap: break-word;
color: rgba(37, 99, 235, 1);
font-size: 13px;
font-family: Helvetica, 'Microsoft YaHei', Arial, sans-serif;
font-weight: normal;
text-align: center;
white-space: nowrap;
line-height: 16px;
}
.text-wrapper_12 {
background-color: rgba(37, 99, 235, 1);
border-radius: 8px;
padding: 8px 51px 11px 52px;
}
.text_16 {
overflow-wrap: break-word;
color: rgba(255, 255, 255, 1);
font-size: 13px;
font-family: Helvetica, 'Microsoft YaHei', Arial, sans-serif;
font-weight: normal;
text-align: center;
white-space: nowrap;
line-height: 16px;
}
.group_3 {
box-shadow: 0px 2px 8px 0px rgba(0, 0, 0, 0.04);
background-color: rgba(255, 255, 255, 1);
border-radius: 16px;
width: 353px;
align-self: center;
margin-top: 16px;
padding: 16px 16px 16px 16px;
}
.text-wrapper_13 {
width: 321px;
}
.text_17 {
overflow-wrap: break-word;
color: rgba(31, 41, 55, 1);
font-size: 16px;
font-family: Helvetica, 'Microsoft YaHei', Arial, sans-serif;
font-weight: normal;
text-align: left;
white-space: nowrap;
line-height: 18px;
}
.text_18 {
overflow-wrap: break-word;
color: rgba(37, 99, 235, 1);
font-size: 13px;
font-family: Helvetica, 'Microsoft YaHei', Arial, sans-serif;
font-weight: normal;
text-align: left;
white-space: nowrap;
line-height: 16px;
margin-top: 2px;
}
.group_4 {
position: relative;
width: 321px;
margin-top: 22px;
padding: 41px 0 1px 102px;
}
.image-text_2 {
width: 72px;
margin-top: 1px;
}
.thumbnail_1 {
width: 12px;
height: 12px;
margin: 2px 0 3px 0;
}
.text-group_2 {
height: 17px;
overflow-wrap: break-word;
color: rgba(156, 163, 175, 1);
font-size: 12px;
font-family: Helvetica, 'Microsoft YaHei', Arial, sans-serif;
font-weight: normal;
text-align: left;
white-space: nowrap;
line-height: 15px;
}
.text_19 {
overflow-wrap: break-word;
color: rgba(37, 99, 235, 1);
font-size: 13px;
font-family: Helvetica, 'Microsoft YaHei', Arial, sans-serif;
font-weight: normal;
text-align: left;
white-space: nowrap;
line-height: 16px;
}
.image-text_3 {
position: absolute;
left: 0;
top: 0;
width: 288px;
height: 60px;
}
.image_3 {
width: 90px;
height: 60px;
}
.text-group_3 {
overflow-wrap: break-word;
color: rgba(31, 41, 55, 1);
font-size: 14px;
font-family: Helvetica, 'Microsoft YaHei', Arial, sans-serif;
font-weight: normal;
text-align: left;
white-space: nowrap;
line-height: 20px;
}
.image_4 {
width: 321px;
height: 1px;
margin-top: 14px;
}
.group_5 {
position: relative;
margin-top: 14px;
padding: 42px 147px 1px 102px;
}
.image-text_4 {
width: 72px;
}
.thumbnail_2 {
width: 12px;
height: 12px;
margin: 3px 0 2px 0;
}
.text-group_4 {
height: 17px;
overflow-wrap: break-word;
color: rgba(156, 163, 175, 1);
font-size: 12px;
font-family: Helvetica, 'Microsoft YaHei', Arial, sans-serif;
font-weight: normal;
text-align: left;
white-space: nowrap;
line-height: 15px;
}
.image-text_5 {
position: absolute;
left: 0;
top: 0;
width: 321px;
height: 60px;
}
.image_5 {
width: 90px;
height: 60px;
}
.text-group_5 {
}
.text_20 {
overflow-wrap: break-word;
color: rgba(31, 41, 55, 1);
font-size: 14px;
font-family: Helvetica, 'Microsoft YaHei', Arial, sans-serif;
font-weight: normal;
text-align: left;
white-space: nowrap;
line-height: 20px;
margin-right: 23px;
}
.text_21 {
height: 19px;
overflow-wrap: break-word;
color: rgba(37, 99, 235, 1);
font-size: 13px;
font-family: Helvetica, 'Microsoft YaHei', Arial, sans-serif;
font-weight: normal;
text-align: left;
white-space: nowrap;
line-height: 16px;
margin: 21px 0 0 191px;
}
.image_6 {
width: 321px;
height: 1px;
margin-top: 14px;
}
.group_6 {
position: relative;
width: 321px;
margin-top: 14px;
padding: 41px 0 1px 102px;
}
.image-text_6 {
width: 72px;
margin-top: 1px;
}
.thumbnail_3 {
width: 12px;
height: 12px;
margin: 2px 0 3px 0;
}
.text-group_6 {
height: 17px;
overflow-wrap: break-word;
color: rgba(156, 163, 175, 1);
font-size: 12px;
font-family: Helvetica, 'Microsoft YaHei', Arial, sans-serif;
font-weight: normal;
text-align: left;
white-space: nowrap;
line-height: 15px;
}
.text_22 {
overflow-wrap: break-word;
color: rgba(37, 99, 235, 1);
font-size: 13px;
font-family: Helvetica, 'Microsoft YaHei', Arial, sans-serif;
font-weight: normal;
text-align: left;
white-space: nowrap;
line-height: 16px;
}
.image-text_7 {
position: absolute;
left: 0;
top: 0;
width: 284px;
height: 60px;
}
.image_7 {
width: 90px;
height: 60px;
}
.text-group_7 {
overflow-wrap: break-word;
color: rgba(31, 41, 55, 1);
font-size: 14px;
font-family: Helvetica, 'Microsoft YaHei', Arial, sans-serif;
font-weight: normal;
text-align: left;
white-space: nowrap;
line-height: 20px;
}
.group_7 {
background-color: rgba(255, 255, 255, 1);
margin-top: 7px;
padding-bottom: 8px;
}
.image_8 {
width: 393px;
height: 1px;
}
.list_1 {
width: 289px;
height: 45px;
align-self: center;
margin-top: 9px;
justify-content: space-between;
}
.image-text_8 {
margin: 0 103px 2px 0;
}
.label_1 {
width: 24px;
height: 24px;
}
.text-group_8 {
width: 35px;
overflow-wrap: break-word;
font-size: 12px;
font-family: Helvetica, 'Microsoft YaHei', Arial, sans-serif;
font-weight: normal;
text-align: left;
white-space: nowrap;
line-height: 15px;
margin-top: 4px;
}
.image_9 {
width: 134px;
height: 5px;
align-self: center;
margin-top: 5px;
}
.box_5 {
position: absolute;
left: 0;
top: 44px;
width: 393px;
height: 136px;
background: url(https://lanhu-oss-2537-2.lanhuapp.com/SketchPnga686e6f82ccd9e11b8a596cdf8bab92f63b49a299048a9e4b8a59748f0495ebb)
100% no-repeat;
background-size: 100% 100%;
padding: 20px 20px 24px 20px;
}
.text_23 {
height: 22px;
overflow-wrap: break-word;
color: rgba(255, 255, 255, 1);
font-size: 22px;
font-family: Helvetica, 'Microsoft YaHei', Arial, sans-serif;
font-weight: normal;
text-align: center;
white-space: nowrap;
line-height: 26px;
align-self: center;
}
.box_6 {
background: url(https://lanhu-oss-2537-2.lanhuapp.com/SketchPngba3204d9119c95152a599037aa982624b235e9d764e91b8e429d9b1600b049f6)
100% no-repeat;
background-size: 100% 100%;
margin-top: 30px;
padding: 10px 173px 11px 14px;
}
.image-text_9 {
width: 166px;
}
.thumbnail_4 {
width: 18px;
height: 18px;
margin-top: 1px;
}
.text-group_9 {
overflow-wrap: break-word;
color: rgba(255, 255, 255, 0.7);
font-size: 14px;
font-family: Helvetica, 'Microsoft YaHei', Arial, sans-serif;
font-weight: normal;
text-align: left;
white-space: nowrap;
line-height: 17px;
}
<template>
<div class="page flex-col">
<div class="box_1 flex-row justify-between">
<span class="text_1">9:41</span>
<img
class="image_1"
referrerpolicy="no-referrer"
src="https://lanhu-oss-2537-2.lanhuapp.com/SketchPng41ebf05313566695702fdc28688b6ed52dbbba555ddd1f6c423593ff63b3f65e"
/>
</div>
<div class="box_2 flex-col">
<div class="group_1 flex-col">
<div class="grid_1 flex-row">
<div
class="image-text_1 flex-col"
v-for="(item, index) in loopData0"
:key="index"
>
<img
class="image_2"
referrerpolicy="no-referrer"
:src="item.lanhuimage0"
/>
<span class="text-group_1" v-html="item.lanhutext0"></span>
</div>
</div>
</div>
<div class="group_2 flex-col">
<div class="text-wrapper_1 flex-row justify-between">
<span class="text_2">热卖产品:</span>
<span class="text_3">查看更多</span>
</div>
<div class="box_3 flex-col">
<span class="text_4">家庭财富传承保障计划(分红)</span>
<div class="grid_2 flex-row">
<div class="text-wrapper_2 flex-col">
<span class="text_5">收益率3.5%</span>
</div>
<div class="text-wrapper_3 flex-col">
<span class="text_6">5年超值</span>
</div>
<div class="text-wrapper_4 flex-col">
<span class="text_7">保证收益万能</span>
</div>
<div class="text-wrapper_5 flex-col">
<span class="text_8">限时2.00%</span>
</div>
</div>
<div class="section_1 flex-row justify-between">
<div class="text-wrapper_6 flex-col">
<span class="text_9">产品资料</span>
</div>
<div class="text-wrapper_7 flex-col">
<span class="text_10">计划书</span>
</div>
</div>
</div>
<div class="box_4 flex-col">
<span class="text_11">儿童教育金储备方案(分红)</span>
<div class="block_1 flex-row justify-between">
<div class="text-wrapper_8 flex-col">
<span class="text_12">收益率4.2%</span>
</div>
<div class="text-wrapper_9 flex-col">
<span class="text_13">10年期</span>
</div>
<div class="text-wrapper_10 flex-col">
<span class="text_14">教育专属</span>
</div>
</div>
<div class="block_2 flex-row justify-between">
<div class="text-wrapper_11 flex-col">
<span class="text_15">产品资料</span>
</div>
<div class="text-wrapper_12 flex-col">
<span class="text_16">计划书</span>
</div>
</div>
</div>
</div>
<div class="group_3 flex-col">
<div class="text-wrapper_13 flex-row justify-between">
<span class="text_17">本周热门资料</span>
<span class="text_18">查看更多</span>
</div>
<div class="group_4 flex-row justify-between">
<div class="image-text_2 flex-row justify-between">
<img
class="thumbnail_1"
referrerpolicy="no-referrer"
src="https://lanhu-oss-2537-2.lanhuapp.com/SketchPngbbfb74181183949bab3fd24840ff57318c45a0419d0256444fd1c4ef1a79c138"
/>
<span class="text-group_2">256人学习</span>
</div>
<span class="text_19">78%</span>
<div class="image-text_3 flex-row justify-between">
<img
class="image_3"
referrerpolicy="no-referrer"
src="https://lanhu-oss-2537-2.lanhuapp.com/SketchPng1be951f3bd8f40d9a448b411caf782306928530c03c5da114f9ce990a51f9c12"
/>
<span class="text-group_3">2024年保险市场趋势分析报告</span>
</div>
</div>
<img
class="image_4"
referrerpolicy="no-referrer"
src="https://lanhu-oss-2537-2.lanhuapp.com/SketchPngf546c69e1a7b33e53d1d0acd31c237f7b1c75a5bd856058be438277083ae4271"
/>
<div class="group_5 flex-row">
<div class="image-text_4 flex-row justify-between">
<img
class="thumbnail_2"
referrerpolicy="no-referrer"
src="https://lanhu-oss-2537-2.lanhuapp.com/SketchPngbbfb74181183949bab3fd24840ff57318c45a0419d0256444fd1c4ef1a79c138"
/>
<span class="text-group_4">189人学习</span>
</div>
<div class="image-text_5 flex-row justify-between">
<img
class="image_5"
referrerpolicy="no-referrer"
src="https://lanhu-oss-2537-2.lanhuapp.com/SketchPng7ed1867c614047c5556036c68d3e0bc23adeec0a03a1f93504a92bd2429e78d2"
/>
<div class="text-group_5 flex-col">
<span class="text_20">高净值客户需求分析与产品匹配</span>
<span class="text_21">65%</span>
</div>
</div>
</div>
<img
class="image_6"
referrerpolicy="no-referrer"
src="https://lanhu-oss-2537-2.lanhuapp.com/SketchPngf546c69e1a7b33e53d1d0acd31c237f7b1c75a5bd856058be438277083ae4271"
/>
<div class="group_6 flex-row justify-between">
<div class="image-text_6 flex-row justify-between">
<img
class="thumbnail_3"
referrerpolicy="no-referrer"
src="https://lanhu-oss-2537-2.lanhuapp.com/SketchPngbbfb74181183949bab3fd24840ff57318c45a0419d0256444fd1c4ef1a79c138"
/>
<span class="text-group_6">142人学习</span>
</div>
<span class="text_22">52%</span>
<div class="image-text_7 flex-row justify-between">
<img
class="image_7"
referrerpolicy="no-referrer"
src="https://lanhu-oss-2537-2.lanhuapp.com/SketchPng6e0e05483dc698cbc4497f50b3bd13605c7a742843afd58d656615bf0f12c3c9"
/>
<span class="text-group_7">保险合同条款解读与风险提示</span>
</div>
</div>
</div>
<div class="group_7 flex-col">
<img
class="image_8"
referrerpolicy="no-referrer"
src="https://lanhu-oss-2537-2.lanhuapp.com/SketchPngbf3e746af52a38753bd540d5f486761a166161ff3c8f2985aa5e994a36349ea4"
/>
<div class="list_1 flex-row">
<div
class="image-text_8 flex-col"
v-for="(item, index) in loopData1"
:key="index"
>
<img
class="label_1"
referrerpolicy="no-referrer"
:src="item.lanhuimage0"
/>
<span
class="text-group_8"
:style="{ color: item.lanhufontColor0 }"
v-html="item.lanhutext0"
></span>
</div>
</div>
<img
class="image_9"
referrerpolicy="no-referrer"
src="https://lanhu-oss-2537-2.lanhuapp.com/SketchPngd87bce34194e46404c7ac21a64bed8e9f8454451baaf336c5201241680a20c9d"
/>
</div>
</div>
<div class="box_5 flex-col">
<span class="text_23">臻奇智荟圈</span>
<div class="box_6 flex-row">
<div class="image-text_9 flex-row justify-between">
<img
class="thumbnail_4"
referrerpolicy="no-referrer"
src="https://lanhu-oss-2537-2.lanhuapp.com/SketchPnge70b40998a55fd5afcd7af006a030581403739d95f19ae93ec445e2c7a3f394e"
/>
<span class="text-group_9">搜索培训资料、案例...</span>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
loopData0: [
{
lanhuimage0:
'https://lanhu-oss-2537-2.lanhuapp.com/SketchPng1d33b0dff470a17d9a986f1713e25a3bd12449943610bdd67a96ca95cccab96e',
lanhutext0: '计划书',
},
{
lanhuimage0:
'https://lanhu-oss-2537-2.lanhuapp.com/SketchPng850afb7cff66e9825b628363734d7a475c4664cf264679159b1dfd5124b73113',
lanhutext0: '入职相关',
},
{
lanhuimage0:
'https://lanhu-oss-2537-2.lanhuapp.com/SketchPngbe3ecbbad98de984b03f3b9ea90551034f64caaeb54fcb543509b2871f9e6e66',
lanhutext0: '签单相关',
},
{
lanhuimage0:
'https://lanhu-oss-2537-2.lanhuapp.com/SketchPngb50c7f823c501e2898b6f1ca071b3695e9fefc551f83ff7c3c9797c92626916f',
lanhutext0: '家办相关',
},
{
lanhuimage0:
'https://lanhu-oss-2537-2.lanhuapp.com/SketchPnge93be123da82ca55f1b40c63bcb07c7efd19985397de7666fcfa7d8202ca22df',
lanhutext0: '产品知识库',
},
{
lanhuimage0:
'https://lanhu-oss-2537-2.lanhuapp.com/SketchPngf249d43500cae9c683301328abadc586ef23a2e14f09f226a4209bf5ca874717',
lanhutext0: '工具箱',
},
],
loopData1: [
{
lanhuimage0:
'https://lanhu-oss-2537-2.lanhuapp.com/SketchPng720f91cb0b105e7be4aac241a0575bb0a7d3c26f39519a121ac7141bfe84c0c5',
lanhutext0: '首页',
lanhufontColor0: 'rgba(37,99,235,1.000000)',
},
{
lanhuimage0:
'https://lanhu-oss-2537-2.lanhuapp.com/SketchPng355fd7cd6d5c986d30655db577fe8e511f878d37c9506e77dc53be60228d6453',
lanhutext0: 'AI答疑',
lanhufontColor0: 'rgba(156,163,175,1.000000)',
},
{
lanhuimage0:
'https://lanhu-oss-2537-2.lanhuapp.com/SketchPng13ceb19b113cdc23fbf47e15ccf14d27aec044ad2c13f88539fc8459993ade6f',
lanhutext0: '我的',
lanhufontColor0: 'rgba(156,163,175,1.000000)',
},
],
constants: {},
};
},
methods: {},
};
</script>
<style src="./common.css" />
<style src="./index.css" />
/*
* @Date: 2025-06-28 10:33:00
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2026-01-14 21:35:58
* @FilePath: /xyxBooking-weapp/src/app.config.js
* @LastEditTime: 2026-01-29 18:17:31
* @FilePath: /manulife-weapp/src/app.config.js
* @Description: 小程序配置文件
*/
const pages = [
'pages/index/index',
'pages/auth/index',
'pages/notice/index',
'pages/booking/index',
'pages/submit/index',
'pages/addVisitor/index',
'pages/success/index',
'pages/bookingCode/index',
'pages/bookingList/index',
'pages/bookingDetail/index',
'pages/me/index',
'pages/search/index',
'pages/visitorList/index',
'pages/volunteerLogin/index',
'pages/verificationResult/index',
'pages/weakNetwork/index',
'pages/offlineBookingCode/index',
'pages/offlineBookingList/index',
'pages/offlineBookingDetail/index',
]
if (process.env.NODE_ENV === 'development') {
pages.push('pages/nfcTest/index')
pages.push('pages/tailwindTest/index')
// pages.push('pages/nfcTest/index')
// pages.push('pages/tailwindTest/index')
}
const subpackages = process.env.NODE_ENV === 'development'
? [
{
root: 'pages/demo',
pages: ['index'],
},
{
root: 'pages/examples',
pages: ['api-demo/index'],
},
// {
// root: 'pages/demo',
// pages: ['index'],
// },
]
: []
......
/*
* @Date: 2025-06-28 10:33:00
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2026-01-06 22:13:24
* @FilePath: /xyxBooking-weapp/src/pages/index/index.config.js
* @LastEditTime: 2026-01-29 17:51:21
* @FilePath: /manulife-weapp/src/pages/index/index.config.js
* @Description: 首页配置
*/
export default {
navigationBarTitleText: '西园寺预约'
navigationBarTitleText: '臻奇智荟圈'
}
......
/**
* index页面样式
*/
.index {
padding: 40rpx;
.nut-button {
margin-bottom: 40rpx;
}
}
<!--
* @Date: 2023-06-21 10:23:09
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2026-01-16 09:24:14
* @FilePath: /xyxBooking-weapp/src/pages/index/index.vue
* @Description: 预约页首页
-->
<template>
<view class="index-page" :class="{ 'is-offline': is_offline }" :style="page_style">
<view v-if="is_offline" class="offline-banner mx-6 mt-4 rounded-xl px-4 py-3">
<view class="flex items-center">
<IconFont name="tips" size="14" />
<text class="ml-2 font-medium">离线提示</text>
</view>
<view class="mt-1 text-sm opacity-80">{{ weak_network_banner_desc }}</view>
<view class="relative w-full min-h-screen overflow-y-auto overflow-x-hidden bg-[#F9FAFB] pb-[200rpx]">
<!-- Header Section -->
<view class="absolute left-0 top-0 w-full h-[544rpx] z-0">
<image class="w-full h-full" src="https://picsum.photos/seed/header/750/544" mode="aspectFill" />
<view class="absolute inset-0 bg-gradient-to-b from-blue-600/80 to-transparent"></view>
</view>
<view class="index-content">
<view style="height: 28vh;">
<swiper class="my-swipe" :autoplay="true" :interval="3000" indicator-dots indicator-color="white" :circular="true">
<swiper-item>
<image style="height: 28vh; width: 100vw;" :src="banner_url" />
</swiper-item>
</swiper>
</view>
<view ref="root" class="index-circular">
<view class="booking-wrapper">
<view class="booking" @tap="toBooking">
<view><image :src="icon_1" style="width: 96rpx; height: 96rpx;" /></view>
<view style="color: #FFF;">开始预约</view>
</view>
<view class="relative z-10 px-[32rpx] pt-[180rpx]">
<text class="block text-white text-[44rpx] font-bold mb-[40rpx]">臻奇智荟圈</text>
<!-- Search Bar -->
<view class="flex items-center w-full h-[88rpx] bg-white/20 backdrop-blur-md rounded-full px-[32rpx] border border-white/30">
<Search class="text-white/80 mr-[16rpx]" size="18" />
<text class="text-white/80 text-[28rpx]">搜索培训资料、案例...</text>
</view>
</view>
<view class="logo" :style="logo_style"></view>
</view>
<indexNav
:icons="nav_icons"
active="home"
position="absolute"
center_variant="raised"
@select="on_nav_select"
/>
</view>
</template>
<script setup>
import Taro, { getCurrentInstance, useDidShow, useShareAppMessage } from '@tarojs/taro'
import { IconFont } from '@nutui/icons-vue-taro'
import { ref, onMounted, onUnmounted, computed } from 'vue'
import { useGo } from '@/hooks/useGo'
import { get_network_type, is_usable_network } from '@/utils/network'
import { weak_network_text } from '@/utils/uiText'
import indexNav from '@/components/indexNav.vue'
import icon_1 from '@/assets/images/立即预约@2x.png'
import icon_3 from '@/assets/images/首页02@2x.png'
import icon_4 from '@/assets/images/二维码icon.png'
import icon_5 from '@/assets/images/我的01@2x.png'
const go = useGo();
const is_offline = ref(false)
const weak_network_banner_desc = weak_network_text.banner_desc
// 背景图版本号, 用于刷新背景图
const initial_t = Number(getCurrentInstance()?.router?.params?._t)
const bg_version = ref(Number.isFinite(initial_t) ? initial_t : 0)
let is_reloading = false
const reload_page = () => {
if (is_reloading) return
is_reloading = true
Taro.reLaunch({
url: `/pages/index/index?_t=${Date.now()}`,
})
}
const banner_url = computed(() => {
return `https://cdn.ipadbiz.cn/xys/booking/banner01.png?imageMogr2/thumbnail/500x/strip/quality/100&v=${bg_version.value}`
})
const normal_bg_url = computed(() => {
return `https://cdn.ipadbiz.cn/xys/booking/bg.jpg?imageMogr2/thumbnail/200x/strip/quality/50&v=${bg_version.value}`
})
const logo_url = computed(() => {
return `https://cdn.ipadbiz.cn/xys/booking/logo.png?imageMogr2/thumbnail/50x/strip/quality/50&v=${bg_version.value}`
})
/**
* 页面样式
* - 离线状态: 背景颜色 + 背景图片 (包含渐变)
* - 在线状态: 背景颜色 + 背景图片
*/
const page_style = computed(() => {
if (is_offline.value) {
return {
backgroundColor: '#F3EEE3',
backgroundImage: `linear-gradient(180deg, rgba(166, 121, 57, 0.10) 0%, rgba(255, 255, 255, 0.90) 60%, rgba(243, 238, 227, 1) 100%), url('${normal_bg_url.value}')`,
}
}
return {
backgroundColor: '#F3EEE3',
backgroundImage: `url('${normal_bg_url.value}')`,
}
})
const logo_style = computed(() => {
return {
backgroundImage: `url('${logo_url.value}')`,
}
})
/**
* 应用离线状态
* - 检查当前状态是否需要刷新
* - 更新 is_offline 状态
*/
<!-- Main Content -->
<view class="relative z-10 mt-[40rpx] px-[24rpx]">
<!-- Grid Icons -->
<view class="bg-white rounded-[32rpx] shadow-sm p-[40rpx] mb-[24rpx]">
<view class="flex flex-wrap">
<view
class="flex flex-col items-center w-1/3 mb-[40rpx]"
v-for="(item, index) in loopData0"
:key="index"
>
<view class="w-[88rpx] h-[88rpx] rounded-[24rpx] bg-blue-50 flex items-center justify-center mb-[16rpx]">
<component :is="item.icon" class="text-blue-600" size="24" />
</view>
<text class="text-gray-800 text-[26rpx]">{{ item.lanhutext0 }}</text>
</view>
</view>
</view>
const apply_offline_state = (next_offline) => {
if (is_offline.value === true && next_offline === false) {
reload_page()
return true
}
is_offline.value = next_offline
return false
}
<!-- Hot Products -->
<view class="bg-white rounded-[32rpx] shadow-sm p-[32rpx] mb-[24rpx]">
<view class="flex justify-between items-center mb-[24rpx]">
<text class="text-gray-900 text-[32rpx] font-bold">热卖产品:</text>
<view class="flex items-center text-blue-600">
<text class="text-[26rpx] mr-[4rpx]">查看更多</text>
<RectRight size="12" />
</view>
</view>
/**
* 刷新离线状态
* - 检查当前网络类型是否可用
*/
const refresh_offline_state = async () => {
try {
const network_type = await get_network_type()
const next_offline = !is_usable_network(network_type)
apply_offline_state(next_offline)
} catch (e) {
console.error('refresh_offline_state failed:', e)
}
}
<!-- Product Card 1 -->
<view class="bg-gray-50 rounded-[24rpx] p-[28rpx] mb-[24rpx]">
<text class="block text-gray-800 text-[28rpx] font-medium mb-[20rpx]">家庭财富传承保障计划(分红)</text>
<view class="flex flex-wrap gap-[12rpx] mb-[24rpx]">
<view class="bg-red-50 rounded-[8rpx] px-[16rpx] py-[6rpx]">
<text class="text-red-600 text-[22rpx]">收益率3.5%</text>
</view>
<view class="bg-orange-50 rounded-[8rpx] px-[16rpx] py-[6rpx]">
<text class="text-orange-600 text-[22rpx]">5年超值</text>
</view>
<view class="bg-green-50 rounded-[8rpx] px-[16rpx] py-[6rpx]">
<text class="text-green-600 text-[22rpx]">保证收益万能</text>
</view>
</view>
<view class="flex justify-between gap-[24rpx]">
<view class="flex-1 h-[64rpx] flex items-center justify-center border border-blue-600 rounded-[16rpx] bg-white">
<text class="text-blue-600 text-[26rpx]">产品资料</text>
</view>
<view class="flex-1 h-[64rpx] flex items-center justify-center bg-blue-600 rounded-[16rpx]">
<text class="text-white text-[26rpx]">计划书</text>
</view>
</view>
</view>
let has_network_listener = false
let network_listener = null
<!-- Product Card 2 -->
<view class="bg-gray-50 rounded-[24rpx] p-[28rpx]">
<text class="block text-gray-800 text-[28rpx] font-medium mb-[20rpx]">儿童教育金储备方案(分红)</text>
<view class="flex flex-wrap gap-[12rpx] mb-[24rpx]">
<view class="bg-red-50 rounded-[8rpx] px-[16rpx] py-[6rpx]">
<text class="text-red-600 text-[22rpx]">收益率4.2%</text>
</view>
<view class="bg-orange-50 rounded-[8rpx] px-[16rpx] py-[6rpx]">
<text class="text-orange-600 text-[22rpx]">10年期</text>
</view>
<view class="bg-green-50 rounded-[8rpx] px-[16rpx] py-[6rpx]">
<text class="text-green-600 text-[22rpx]">教育专属</text>
</view>
</view>
<view class="flex justify-between gap-[24rpx]">
<view class="flex-1 h-[64rpx] flex items-center justify-center border border-blue-600 rounded-[16rpx] bg-white">
<text class="text-blue-600 text-[26rpx]">产品资料</text>
</view>
<view class="flex-1 h-[64rpx] flex items-center justify-center bg-blue-600 rounded-[16rpx]">
<text class="text-white text-[26rpx]">计划书</text>
</view>
</view>
</view>
</view>
/**
* 设置网络状态变更监听器
* - 监听网络状态变化
* - 更新 is_offline 状态
*/
<!-- Hot Materials -->
<view class="bg-white rounded-[32rpx] shadow-sm p-[32rpx]">
<view class="flex justify-between items-center mb-[24rpx]">
<text class="text-gray-900 text-[32rpx] font-bold">本周热门资料</text>
<view class="flex items-center text-blue-600">
<text class="text-[26rpx] mr-[4rpx]">查看更多</text>
<RectRight size="12" />
</view>
</view>
const setup_network_listener = () => {
if (has_network_listener) return
has_network_listener = true
network_listener = (res) => {
try {
const is_connected = res?.isConnected !== false
const network_type = res?.networkType
if (typeof network_type === 'string' && network_type) {
// 有网, 检查是否可用
const next_offline = !(is_connected && is_usable_network(network_type))
// 检查是否需要刷新
const is_handled = apply_offline_state(next_offline)
if (is_handled) return
}
// 还没有网, 再次刷新
refresh_offline_state()
} catch (e) {
console.error('network_listener failed:', e)
}
}
Taro.onNetworkStatusChange(network_listener)
}
<!-- Material List -->
<view class="flex flex-col gap-[32rpx]">
<!-- Item 1 -->
<view class="flex gap-[24rpx]">
<image class="w-[200rpx] h-[140rpx] rounded-[12rpx] bg-gray-200" src="https://picsum.photos/seed/mat1/200/140" mode="aspectFill" />
<view class="flex-1 flex flex-col justify-between py-[4rpx]">
<text class="text-gray-800 text-[28rpx] leading-[40rpx] line-clamp-2">2024年保险市场趋势分析报告</text>
<view class="flex justify-between items-end">
<text class="text-gray-400 text-[24rpx]">256人学习</text>
<text class="text-blue-600 text-[26rpx]">78%</text>
</view>
</view>
</view>
<view class="h-[2rpx] bg-gray-100"></view>
<!-- Item 2 -->
<view class="flex gap-[24rpx]">
<image class="w-[200rpx] h-[140rpx] rounded-[12rpx] bg-gray-200" src="https://picsum.photos/seed/mat2/200/140" mode="aspectFill" />
<view class="flex-1 flex flex-col justify-between py-[4rpx]">
<text class="text-gray-800 text-[28rpx] leading-[40rpx] line-clamp-2">高净值客户需求分析与产品匹配</text>
<view class="flex justify-between items-end">
<text class="text-gray-400 text-[24rpx]">189人学习</text>
<text class="text-blue-600 text-[26rpx]">65%</text>
</view>
</view>
</view>
<view class="h-[2rpx] bg-gray-100"></view>
<!-- Item 3 -->
<view class="flex gap-[24rpx]">
<image class="w-[200rpx] h-[140rpx] rounded-[12rpx] bg-gray-200" src="https://picsum.photos/seed/mat3/200/140" mode="aspectFill" />
<view class="flex-1 flex flex-col justify-between py-[4rpx]">
<text class="text-gray-800 text-[28rpx] leading-[40rpx] line-clamp-2">保险合同条款解读与风险提示</text>
<view class="flex justify-between items-end">
<text class="text-gray-400 text-[24rpx]">142人学习</text>
<text class="text-blue-600 text-[26rpx]">52%</text>
</view>
</view>
</view>
</view>
</view>
</view>
/**
* 移除网络状态变更监听器
* - 移除网络状态变化监听
*/
<!-- Bottom Tab Bar -->
<view class="fixed bottom-0 left-0 w-full bg-white shadow-[0_-4rpx_16rpx_rgba(0,0,0,0.05)] pb-safe z-50">
<view class="flex h-[110rpx] items-center">
<view
class="flex-1 flex flex-col items-center justify-center"
v-for="(item, index) in loopData1"
:key="index"
@tap="handleTabClick(item)"
>
<component
:is="item.icon"
:class="[item.key === 'home' ? 'text-blue-600' : 'text-gray-400']"
size="24"
/>
<text
class="text-[20rpx] mt-[8rpx]"
:class="[item.key === 'home' ? 'text-blue-600' : 'text-gray-400']"
>{{ item.lanhutext0 }}</text>
</view>
</view>
<view class="w-[268rpx] h-[10rpx] mx-auto bg-gray-200 rounded-full mb-[10rpx]" />
</view>
</view>
</template>
const teardown_network_listener = () => {
if (!has_network_listener) return
has_network_listener = false
if (network_listener && typeof Taro.offNetworkStatusChange === 'function') {
try {
Taro.offNetworkStatusChange(network_listener)
} catch (e) {
console.error('offNetworkStatusChange failed:', e)
}
}
network_listener = null
}
<script setup>
import { ref } from 'vue';
import Taro, { useShareAppMessage } from '@tarojs/taro';
import { useGo } from '@/hooks/useGo';
import {
Search,
RectRight,
Order,
My,
Cart,
Home,
Category,
Star,
Service
} from '@nutui/icons-vue-taro';
useDidShow(() => {
refresh_offline_state()
})
// Data
const loopData0 = ref([
{
icon: Order,
lanhutext0: '计划书',
},
{
icon: My,
lanhutext0: '入职相关',
},
{
icon: Cart,
lanhutext0: '签单相关',
},
{
icon: Home,
lanhutext0: '家办相关',
},
{
icon: Category,
lanhutext0: '产品知识库',
},
{
icon: Star,
lanhutext0: '工具箱',
},
]);
onMounted(() => {
setup_network_listener()
})
const loopData1 = ref([
{
icon: Home,
lanhutext0: '首页',
key: 'home'
},
{
icon: Service,
lanhutext0: 'AI答疑',
key: 'ai'
},
{
icon: My,
lanhutext0: '我的',
key: 'me'
},
]);
onUnmounted(() => {
teardown_network_listener()
})
// Navigation
const go = useGo();
const toBooking = () => { // 跳转到预约须知
// 如果是离线模式,不跳转
if (is_offline.value) {
const handleTabClick = (item) => {
if (item.key === 'me') {
Taro.redirectTo({
url: '/pages/me/index'
});
} else if (item.key === 'ai') {
Taro.showToast({
title: weak_network_text.offline_mode_no_booking_toast,
title: '功能开发中',
icon: 'none'
})
return
});
}
go('/notice');
}
const toCode = () => { // 跳转到预约码
Taro.redirectTo({
url: '/pages/bookingCode/index'
})
}
const toMy = () => { // 跳转到我的
Taro.redirectTo({
url: '/pages/me/index'
})
}
const nav_icons = { home: icon_3, code: icon_4, me: icon_5 }
const on_nav_select = (key) => {
if (key === 'code') return toCode()
if (key === 'me') return toMy()
}
};
useShareAppMessage(() => {
return {
title: '西园寺预约',
title: '臻奇智荟圈',
path: '/pages/index/index'
}
})
};
});
</script>
<style lang="less">
.index-page {
position: relative;
min-height: 100vh;
background-repeat: no-repeat;
background-position: center;
background-size: cover; /* 确保背景覆盖 */
&.is-offline {
background-color: #F3EEE3;
}
.offline-banner {
position: absolute;
top: 24rpx;
left: 24rpx;
right: 24rpx;
z-index: 10;
background: rgba(255, 255, 255, 0.88);
color: #A67939;
border: 2rpx solid rgba(166, 121, 57, 0.25);
box-shadow: 0 12rpx 30rpx rgba(166, 121, 57, 0.12);
backdrop-filter: blur(6px);
}
.index-content {
height: calc(100vh - 134rpx - constant(safe-area-inset-bottom));
height: calc(100vh - 134rpx - env(safe-area-inset-bottom));
.index-control {
position: relative;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
margin-top: 130rpx;
// font-weight: bold;
font-size: 37rpx;
.booking {
display: flex;
justify-content: center;
align-items: center;
background-color: #A67939;
border-radius: 14rpx;
color: #FFFFFF;
padding: 22rpx 128rpx;
border: 2rpx solid #A67939;
}
.record {
display: flex;
justify-content: center;
align-items: center;
color: #A67939;
border-radius: 14rpx;
padding: 22rpx 128rpx;
border: 2rpx solid #A67939;
margin-top: 48rpx;
}
.search {
display: flex;
justify-content: center;
align-items: center;
color: #A67939;
border-radius: 14rpx;
padding: 22rpx 128rpx;
border: 2rpx solid #A67939;
margin-top: 48rpx;
}
}
.index-circular {
position: relative;
display: flex;
align-items: center;
justify-content: center;
margin-top: 130rpx;
// font-weight: bold;
font-size: 35rpx;
.booking-wrapper {
height: 260rpx;
width: 260rpx;
border-radius: 50%;
background-color: rgba(166, 121, 57, 0.26);
display: flex;
align-items: center;
justify-content: center;
.booking {
height: 230rpx;
width: 230rpx;
border-radius: 50%;
background-color: #A67939;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
}
}
}
.logo {
position: absolute;
right: 0;
bottom: 200rpx;
height: 400rpx;
width: 150rpx;
background-repeat: no-repeat;
background-size: contain;
background-position: center;
}
}
.my-swipe {
height: 400rpx;
swiper-item { /* Taro swiper-item 编译后 */
height: 400rpx;
width: 750rpx;
background-size: cover;
background-repeat: no-repeat;
background-position: center;
}
}
}
</style>
......