# 页面架构规划 — cz-web(auto-dev 阶段三产出) > 依据 `docs/PRD.md` 梳理。规范遵循 vue-project-structure skill:三层数据流(页面 → store → api)、四者同名(views/api/store/types)、less 样式、`@/` 别名。 ## 1. 页面清单表(模块 → 页面 → 功能点 → 数据字段) ### 模块 home(首页) | 页面 | 功能点 | 数据字段 | | --- | --- | --- | | 首页 `/` | 欢迎区、数据看板、快捷入口、业务服务卡片、案例精选、服务 Tab、页脚 | stats{pending,inProgress,total}、quickLinks[]、businessLines[]、cases[] | | 业务详情 `/business/:type` | 面包屑、业务介绍、服务内容富文本+视频、服务类型子 Tab | businessLine{id,name,slogan,serviceContent,serviceTypes[],video} | ### 模块 cases(案例库) | 页面 | 功能点 | 数据字段 | | --- | --- | --- | | 案例列表 `/cases` | 四维筛选(业务类型/行业/规模/完成时间)+关键字、已选条件回显、案例卡片网格、分页 | Case(见 PRD 4.1)、CaseQuery{category,industries[],scales[],dateRange,keyword,page} | | 案例详情 `/cases/:id` | 概览、收藏/分享、视频、富文本四段、一键填报类似案例 | Case 全量、isFavorite | ### 模块 demand(需求提报) | 页面 | 功能点 | 数据字段 | | --- | --- | --- | | 需求提报 `/demand` | 三步表单:业务类型单选→需求信息+附件→确认备注;立即提报/保存草稿/重置 | Demand(见 PRD 4.2) | ### 模块 login(认证) | 页面 | 功能点 | 数据字段 | | --- | --- | --- | | 登录 `/login` | 账号密码/手机验证码双模式、游客模式、协议勾选 | account,password,phone,smsCode,agreeTerms | | 注册 `/register` | 手机+验证码+密码(强度指示)+确认密码、协议勾选 | phone,smsCode,password,confirmPassword | | 找回密码 `/reset-password` | 手机+验证码+新密码+确认、确认修改 | phone,smsCode,newPassword,confirmPassword | ### 模块 project(项目中心) | 页面 | 功能点 | 数据字段 | | --- | --- | --- | | 项目列表 `/project` | 三维筛选+关键字、状态 Tab、项目表格、分页 | Project(PRD 4.3)、ProjectQuery{businessType,status,dateRange,keyword,page} | | 项目详情 `/project/:id` | 信息卡、项目团队、四 Tab(进度里程碑/项目文件/合同财务/售后信息) | Project 全量(milestones,team,files,paymentPlans,invoiceRecords,afterSales) | | 申请售后 `/project/:id/after-sales` | 三步表单(业务类型/问题描述+附件/备注)、提交生成工单 | AfterSales{type,description,attachments,remark} | ### 模块 contract(合同中心) | 页面 | 功能点 | 数据字段 | | --- | --- | --- | | 合同列表 `/contract` | 关键字搜索、合同表格、去签署/详情、分页 | Contract(PRD 4.4)、ContractQuery{keyword,page} | | 合同详情 `/contract/:id` | 合同信息只读表单、关联项目跳转、合同文件、返回 | Contract 全量 | | 签署合同 `/contract/:id/sign` | 支付宝扫码二维码(04:32 倒计时+刷新)、四步签署指引、完成自动跳转 | signQr{url,expiresAt} | ### 模块 finance(财务中心) | 页面 | 功能点 | 数据字段 | | --- | --- | --- | | 财务概览 `/finance` | 累计消费总额+月份/季度/年度切换、业务类型分布图、待支付角标、快捷入口 | financeStats{totalExpense,month,distribution[],pendingCount} | | 账单明细 `/finance/bills` | 状态 Tab、搜索、账单表格(多选)、汇总条、批量立即支付、分页 | Bill(PRD 4.5)、BillQuery{status,keyword,page} | | 账单详情 `/finance/bills/:id` | 订单信息卡、待支付/已支付/未到期三态展示、返回 | Bill 全量、Payment | | 扫码支付 `/finance/bills/:id/pay` | 支付二维码(倒计时+刷新)、微信/支付宝切换弹窗、订单明细、三步指引 | Payment{method,qrCode,expiresAt,amount} | | 支付结果 `/finance/bills/:id/pay/result` | 支付成功卡、支付信息、已支付订单列表 | Payment 结果 | | 发票申请 `/finance/invoices` | 默认抬头卡、状态 Tab、发票表格、申请开票/预览/下载/发送邮箱、分页 | Invoice(PRD 4.5) | | 发票抬头管理 `/finance/invoice-titles` | 抬头列表卡、新增/编辑/删除(二次确认)、设为默认 | InvoiceTitle(PRD 4.5) | ### 模块 message(消息中心) | 页面 | 功能点 | 数据字段 | | --- | --- | --- | | 消息中心 `/message` | 分类 Tab(全部/在线客服/状态通知/系统通知+未读数)、搜索、全部已读、消息列表、分页 | Message(PRD 4.6)、MessageQuery{type,keyword,page} | | 通知详情 `/message/:id` | 标题/发布时间/富文本正文/附件、返回 | Message 全量 | ### 模块 service(在线客服) | 页面 | 功能点 | 数据字段 | | --- | --- | --- | | 在线客服 `/service` | 聊天窗、历史消息分割线、未读标记、文本/文件消息、Enter 发送、拖拽上传 | ChatMessage{id,role,content,file?,time} | ### 模块 profile(个人中心,左菜单嵌套布局) | 页面 | 功能点 | 数据字段 | | --- | --- | --- | | 账号安全 `/profile/security` | 修改密码、绑定手机换绑、绑定/解绑邮箱、注销账号(条件校验→风险提示→身份验证→二次确认) | User(PRD 4.7) | | 地址管理 `/profile/address` | 地址卡列表、新增/编辑/删除(二次确认)、设为默认、分页 | Address(PRD 4.7) | | 收藏列表 `/profile/favorites` | 收藏案例卡片网格 + 筛选、分页 | Case[](复用 cases 实体) | | 资质列表 `/profile/qualifications` | 资质卡列表、新增/编辑/删除/重新上传、审核状态、分页 | Qualification(PRD 4.7) | | 意见反馈 `/profile/feedback` | 标题+描述+附件表单、提交反馈/重置 | Feedback{title,description,attachments} | | 帮助中心 `/profile/help` | FAQ 折叠组(三类 Q/A) | FaqGroup[](静态) | | 关于我们 `/profile/about` | 简介/使命/核心优势/联系信息/版本信息 | 静态+site 配置 | | 专属客服热线 `/profile/hotline` | 热线电话+工作时间 | 静态 | ## 2. 路由规划(`src/router/routes.ts`) ```ts export const routes = [ // ── 公开 ── { path: '/', name: 'Home', component: () => import('@/views/home'), meta: { title: '首页' } }, { path: '/business/:type', name: 'BusinessDetail', component: () => import('@/views/home/detail.vue'), meta: { title: '业务详情' } }, { path: '/cases', name: 'Cases', component: () => import('@/views/cases'), meta: { title: '成功案例库' } }, { path: '/cases/:id', name: 'CaseDetail', component: () => import('@/views/cases/detail.vue'), meta: { title: '案例详情' } }, { path: '/demand', name: 'Demand', component: () => import('@/views/demand'), meta: { title: '需求提报' } }, // ── 游客区 ── { path: '/login', name: 'Login', component: () => import('@/views/login'), meta: { title: '登录' } }, { path: '/register', name: 'Register', component: () => import('@/views/login/register.vue'), meta: { title: '注册' } }, { path: '/reset-password', name: 'ResetPassword', component: () => import('@/views/login/reset.vue'), meta: { title: '找回密码' } }, // ── 登录区(需守卫)── { path: '/project', name: 'Project', component: () => import('@/views/project'), meta: { title: '项目中心', requiresAuth: true } }, { path: '/project/:id', name: 'ProjectDetail', component: () => import('@/views/project/detail.vue'), meta: { title: '项目详情', requiresAuth: true } }, { path: '/project/:id/after-sales', name: 'AfterSales', component: () => import('@/views/project/after-sales.vue'), meta: { title: '申请售后', requiresAuth: true } }, { path: '/contract', name: 'Contract', component: () => import('@/views/contract'), meta: { title: '合同中心', requiresAuth: true } }, { path: '/contract/:id', name: 'ContractDetail', component: () => import('@/views/contract/detail.vue'), meta: { title: '合同详情', requiresAuth: true } }, { path: '/contract/:id/sign', name: 'ContractSign', component: () => import('@/views/contract/sign.vue'), meta: { title: '签署合同', requiresAuth: true } }, { path: '/finance', name: 'Finance', component: () => import('@/views/finance'), meta: { title: '财务中心', requiresAuth: true } }, { path: '/finance/bills', name: 'Bills', component: () => import('@/views/finance/bills.vue'), meta: { title: '账单明细', requiresAuth: true } }, { path: '/finance/bills/:id', name: 'BillDetail', component: () => import('@/views/finance/bill-detail.vue'), meta: { title: '账单详情', requiresAuth: true } }, { path: '/finance/bills/:id/pay', name: 'BillPay', component: () => import('@/views/finance/pay.vue'), meta: { title: '扫码支付', requiresAuth: true } }, { path: '/finance/bills/:id/pay/result', name: 'PayResult', component: () => import('@/views/finance/pay-result.vue'), meta: { title: '支付结果', requiresAuth: true } }, { path: '/finance/invoices', name: 'Invoices', component: () => import('@/views/finance/invoices.vue'), meta: { title: '发票申请', requiresAuth: true } }, { path: '/finance/invoice-titles', name: 'InvoiceTitles', component: () => import('@/views/finance/invoice-titles.vue'), meta: { title: '发票抬头', requiresAuth: true } }, { path: '/message', name: 'Message', component: () => import('@/views/message'), meta: { title: '消息中心', requiresAuth: true } }, { path: '/message/:id', name: 'MessageDetail', component: () => import('@/views/message/detail.vue'), meta: { title: '通知详情', requiresAuth: true } }, { path: '/service', name: 'Service', component: () => import('@/views/service'), meta: { title: '在线客服', requiresAuth: true } }, // ── 个人中心(左菜单布局嵌套)── { path: '/profile', component: () => import('@/views/profile'), meta: { title: '个人中心', requiresAuth: true }, children: [ { path: '', redirect: '/profile/security' }, { path: 'security', name: 'ProfileSecurity', component: () => import('@/views/profile/security.vue'), meta: { title: '账号安全', requiresAuth: true } }, { path: 'address', name: 'ProfileAddress', component: () => import('@/views/profile/address.vue'), meta: { title: '地址管理', requiresAuth: true } }, { path: 'favorites', name: 'ProfileFavorites', component: () => import('@/views/profile/favorites.vue'), meta: { title: '收藏列表', requiresAuth: true } }, { path: 'qualifications', name: 'ProfileQualifications', component: () => import('@/views/profile/qualifications.vue'), meta: { title: '资质列表', requiresAuth: true } }, { path: 'feedback', name: 'ProfileFeedback', component: () => import('@/views/profile/feedback.vue'), meta: { title: '意见反馈', requiresAuth: true } }, { path: 'help', name: 'ProfileHelp', component: () => import('@/views/profile/help.vue'), meta: { title: '帮助中心', requiresAuth: true } }, { path: 'about', name: 'ProfileAbout', component: () => import('@/views/profile/about.vue'), meta: { title: '关于我们', requiresAuth: true } }, { path: 'hotline', name: 'ProfileHotline', component: () => import('@/views/profile/hotline.vue'), meta: { title: '专属客服热线', requiresAuth: true } }, ], }, { path: '/:pathMatch(.*)*', name: 'NotFound', component: () => import('@/views/404.vue'), meta: { title: '页面不存在' } }, ] ``` > 路由守卫(`router/guard.ts`):`meta.requiresAuth` 未登录 → 重定向 `/login`;登录页已登录 → 重定向 `/`;切换路由时设置 `document.title`。 ## 3. 四者同名映射表(模块 → 文件) | 模块 | views/ | api/ | stores/modules/ | types/business/ | Store 名 | | --- | --- | --- | --- | --- | --- | | home | `views/home/`(index.vue + detail.vue) | `api/home.ts` | `stores/modules/home.ts` | `types/business/home.d.ts` | useHomeStore | | cases | `views/cases/`(index.vue + detail.vue) | `api/cases.ts` | `stores/modules/cases.ts` | `types/business/cases.d.ts` | useCasesStore | | demand | `views/demand/` | `api/demand.ts` | `stores/modules/demand.ts` | `types/business/demand.d.ts` | useDemandStore | | login | `views/login/`(index.vue + register.vue + reset.vue) | `api/auth.ts` | `stores/modules/user.ts` | `types/business/user.d.ts` | useUserStore | | project | `views/project/`(index.vue + detail.vue + after-sales.vue) | `api/project.ts` | `stores/modules/project.ts` | `types/business/project.d.ts` | useProjectStore | | contract | `views/contract/`(index.vue + detail.vue + sign.vue) | `api/contract.ts` | `stores/modules/contract.ts` | `types/business/contract.d.ts` | useContractStore | | finance | `views/finance/`(index.vue + bills.vue + bill-detail.vue + pay.vue + pay-result.vue + invoices.vue + invoice-titles.vue) | `api/finance.ts` | `stores/modules/finance.ts` | `types/business/finance.d.ts` | useFinanceStore | | message | `views/message/`(index.vue + detail.vue) | `api/message.ts` | `stores/modules/message.ts` | `types/business/message.d.ts` | useMessageStore | | service | `views/service/` | `api/service.ts` | `stores/modules/service.ts` | `types/business/service.d.ts` | useServiceStore | | profile | `views/profile/`(index.vue 布局 + 8 子页) | `api/profile.ts` | `stores/modules/profile.ts` | `types/business/profile.d.ts` | useProfileStore | | 站点公共 | — | — | `stores/modules/site.ts` | — | useSiteStore(全局 loading/站点配置) | ## 4. 复用性分析 ### 4.1 跨页面复用 → `src/components/` | 组件 | 复用范围 | 判定依据 | | --- | --- | --- | | AppHeader / AppFooter | 全站 | layout 挂载 | | AppButton / AppSwiper | 全站 | 通用基础件 | | CaseCard | 首页精选、案例库、收藏列表 | ≥3 页面 | | FilterPanel(含已选条件回显) | 案例库、项目中心、收藏列表 | ≥2 页面 | | SearchBar | 案例/项目/合同/账单/发票/消息 | ≥2 页面 | | PaginationBar | 所有列表页 | ≥2 页面 | | FileList + UploadArea | 需求填报、项目文件、售后、资质、意见反馈 | ≥2 页面 | | SmsCodeInput | 登录/注册/找回/换绑手机/换绑邮箱/注销验证 | ≥2 页面 | | PasswordStrength | 注册、修改密码 | ≥2 页面 | | QrCodePanel | 合同签署、扫码支付 | ≥2 页面 | | StatusTag | 项目/合同/账单/发票/资质状态 | ≥2 页面 | | ConfirmDialog | 删除/注销等二次确认 | ≥2 页面 | | StepForm 骨架 | 需求提报、申请售后 | ≥2 页面 | ### 4.2 页面独有 → `views//cpns/` 详见 `docs/PRD.md` 第 5.2 节组件清单。判定:仅 1 个页面使用即入 cpns/,严禁跨页面 import。 ### 4.3 逻辑复用 | 逻辑 | 归属 | 使用方 | | --- | --- | --- | | useCountDown(验证码倒计时/二维码失效倒计时) | composables/ | SmsCodeInput、QrCodePanel | | useLoading | composables/ | 各 store 请求态(可选) | | useScroll(吸顶/回到顶部) | composables/ | 长列表页 | | useIntersection(懒加载) | composables/ | 案例卡片图片 | | v-lazy / v-debounce / v-throttle | directives/ | 图片懒加载、搜索防抖 | | format.ts(金额/日期/千分位) | utils/ | 财务/项目展示 | | validate.ts(手机号/邮箱) | utils/ | 表单校验 | | storage.ts(token/草稿缓存) | utils/ | user store、需求草稿 | ## 5. 静态资源规划 ``` src/assets/ ├── images/ # 案例封面、业务卡片图、banner(原型导出切图后语义化命名) ├── icons/ # 业务类型图标、消息类型图标、状态图标 └── fonts/ # 如需自定义字体 ``` > 切图来源:蓝湖到位前使用原型占位图;到位后按蓝湖图层语义化命名替换。