# 咕咕嘎嘎论坛前端详细设计文档(v2.0) > **修订说明**:根据最新需求调整,底部导航变更为“首页”、“我的订单”、“我的信息”、“我的账户”。打赏支付仅使用钱包余额,采用即时扣款模式。细化帖子详情(专家信息、标签、往期命中)及订单状态逻辑。 --- ## 1. 引言 本文档为“咕咕嘎嘎论坛”用户端前端的详细设计,基于最新确认的需求编写,指导开发人员使用 Vue 3 + Element Plus 进行工程实现。文档覆盖项目架构、路由、组件拆分、状态管理、样式、接口对接及关键业务流程。 ## 2. 技术栈 | 类别 | 选型 | 说明 | | ------------ | ------------------------------- | --------------------------------------- | | 框架 | Vue 3 (Composition API) | 组合式 API,逻辑复用与类型推断 | | UI 组件库 | Element Plus | 提供统一的企业级 UI 组件 | | 状态管理 | Pinia | Vue 3 官方推荐,模块化、TypeScript 友好 | | 路由 | Vue Router 4 | SPA 路由管理 | | HTTP 客户端 | Axios | 拦截器封装、统一错误处理 | | CSS 预处理器 | SCSS | 变量、混入、嵌套 | | 图标库 | Element Plus Icons / 自定义 SVG | 导航及功能图标 | | 构建工具 | Vite | 快速开发与打包 | | 适配方案 | postcss-px-to-viewport (可选) | H5 移动端适配,按需启用 | ## 3. 项目结构 ## 4. 路由设计 底部导航四个主 Tab 对应路由,使用 `meta.tab` 标识: | 路径 | 页面组件 | Tab 标识 | 说明 | | ----------------- | ------------- | ------------- | ---------------------- | | `/` | Home | home | 首页(帖子列表、搜索) | | `/orders` | Orders | orders | 我的订单(打赏订单) | | `/notifications` | Notifications | notifications | 我的信息(系统消息) | | `/profile` | Profile | profile | 我的账户(个人中心) | | `/post/:id` | PostDetail | - | 帖子详情(从首页进入) | | `/wallet` | Wallet | - | 钱包(余额/充值/提现) | | `/edit-profile` | EditProfile | - | 修改个人信息 | | `/page/privacy` | StaticPage | - | 隐私协议 | | `/page/complaint` | StaticPage | - | 投诉反馈 | | `/page/contact` | StaticPage | - | 联系客服 | | `/page/faq` | StaticPage | - | 常见问题 | 注意:`PostDetail` 由首页点击进入,不在底部导航,返回时保留浏览位置。 ## 5. 全局状态管理(Pinia) ### userStore - **state**: `userInfo` (id, username, avatar, mobile, role, level, balance, isRealname), `token` - **actions**: `fetchUserInfo()`, `updateBalance(amount)`, `updateProfile(data)`, `logout()` - **getters**: `isLoggedIn`, `levelBadge` (黄金/钻石/大师) ### postStore - **state**: `posts`, `currentStatus` (全部/公开/在售/命中/未命中), `searchKeyword`, `pagination` - **actions**: `fetchPosts(status, keyword)`, `fetchPostDetail(id)`, `loadMore()` ### orderStore - **state**: `orders`, `activeFilter` (全部/未支付/已取消/已完成) - **actions**: `fetchOrders(filter)`, `createAndPayOrder(postId)` (创建并即时支付), `cancelOrder(id)` ### notificationStore - **state**: `messages`, `unreadCount` - **actions**: `fetchNotifications()`, `markRead(id)` ## 6. 组件设计 ### 6.1 公共组件 #### BottomNav.vue - 底部固定栏,四个入口:首页、我的订单、我的信息、我的账户。 - 图标使用 Element Plus Icons 或自定义 SVG,激活时高亮。 - 监听 `route.meta.tab` 切换激活样式。 #### PostCard.vue - **Props**: `post` { id, title, expertName, tags, price, publishTime, viewCount, status, isTodayNew } - **UI**: 卡片展示标题、发布专家(可点击)、帖子标签(`el-tag` 列表)、价格、发布时间(相对时间)、查看人数图标。当日帖子显示“最新”角标。 - 点击卡片跳转 `/post/:id`。 #### ExpertInfoCard.vue - **Props**: `expert` { name, avatar, level, realnameVerified, brief } - **UI**: 在详情页顶部展示专家头像、名称、等级徽章、实名认证标识、简介。可带关注按钮(暂不做)。 #### PayConfirm.vue - **Props**: `visible`, `postTitle`, `amount`, `balance` - **Events**: `@confirm`, `@cancel` - **UI**: `el-dialog` 模态框,标题“确认打赏”,展示内容:帖子标题、打赏金额、当前钱包余额。确认按钮带 loading,避免重复提交。不允许点击遮罩关闭。 #### CountdownTimer.vue - **Props**: `endTime` (时间戳) - **Events**: `@timeout` - **UI**: 显示 `mm:ss` 倒计时,归零触发事件。用于订单未支付倒计时(若存在)。 #### GlassBanner.vue - **Props**: `text` - **UI**: 毛玻璃效果欢迎语区域,背景半透明模糊。 #### MarqueeNotice.vue - **Props**: `noticeText` - **UI**: 水平滚动公告栏,点击弹出论坛声明弹窗(含“我已知晓”按钮)。 #### EmptyState.vue - **Props**: `description` - **UI**: 复用 `el-empty`,自定义图片与文字。 ### 6.2 页面组件 #### Home.vue - **布局**: 顶部 Logo 及论坛名(动态配置)→ 欢迎语(GlassBanner)→ 滚动公告(MarqueeNotice)→ 搜索栏与状态筛选 → 帖子列表(PostCard 列表) - **搜索栏**: `el-input` 支持标题关键字,`el-select` 选择状态(全部/公开/在售/命中/未命中),搜索按钮或回车触发。 - **帖子列表**: 滚动加载(`v-infinite-scroll`)或分页,空状态使用 `EmptyState`。 - **数据加载**: `onMounted` 调用 `postStore.fetchPosts`。 #### PostDetail.vue - **路由参数**: `id` - **布局**: 专家信息卡片 → 帖子详情(标题、内容简介、免责声明)→ 付费内容区域(未打赏显示遮罩与锁图标,已打赏显示完整内容)→ 立即打赏按钮(余额足够时)→ 往期帖子列表 - **专家信息**: 使用 `ExpertInfoCard` 展示。 - **立即打赏**: - 点击时校验余额 `userStore.balance >= post.price`,不足则 `ElMessage.warning('余额不足,请先充值')` 并引导去钱包。 - 余额充足则打开 `PayConfirm` 弹窗,确认后调用 `orderStore.createAndPayOrder(postId)`。 - 支付成功:关闭弹窗,刷新帖子详情(付费内容可见),更新余额,提示“打赏成功”。 - 支付失败(如并发余额不足):弹窗提示错误信息,关闭弹窗。 - **往期帖子列表**: 展示该专家所有已过时效的帖子,每个条目显示标题、日期及命中性标签(`el-tag`:已命中/未命中)。 #### Orders.vue (我的订单) - **筛选栏**: `el-radio-group` 或 `el-tabs`,选项:全部、未支付、已取消、已完成。 - **订单列表**: 每个订单卡片显示帖子标题、专家名、金额、状态、创建时间。对于状态为“未支付”且未超时的订单,可显示倒计时并提供“去支付”按钮(调用支付流程,但本项目打赏基本即时完成,此状态极少出现,保留以兼容未来扩展)。 - **空状态**: 无订单时使用 `EmptyState`。 - **订单过期处理**: 若存在未支付订单且已超时,自动显示“已过期”并置灰操作。 #### Notifications.vue (我的信息) - **消息类型**: 系统通知,包括打赏成功、充值成功/失败、提现发起/成功/失败等。 - **列表**: 按时间倒序,每条消息显示图标、标题、内容摘要、时间戳。未读显示红点。 - **交互**: 点击消息可标记已读,无跳转。 - **空状态**: 无消息时“暂无任何消息通知”。 #### Profile.vue (我的账户) - **用户信息卡片**: 头像(`el-avatar`)、用户名称、等级徽章、用户ID(右侧复制按钮,使用 `navigator.clipboard.writeText`)。 - **功能菜单**: - 钱包 → 路由 `/wallet` - 隐私协议 → `/page/privacy` - 投诉反馈 → `/page/complaint` - 联系客服 → `/page/contact` - 常见问题 → `/page/faq` - 修改我的信息 → `/edit-profile` - 设置(预留入口,可跳转至占位页面) - 使用 `el-cell-group` 构建菜单。 #### Wallet.vue - **余额展示**: 大号字体,`el-statistic` 组件。 - **充值/提现按钮**: 点击后弹出 `el-dialog`,输入金额(充值:模拟增加余额;提现:提交申请,需后台审核,前端仅展示交互)。 - **资金明细**: 列表/表格显示时间、金额、类型(充值/提现/打赏支出)。无记录时显示空状态。 - **充值/提现流程**: - 充值:输入金额 → 确认 → 调接口(模拟支付)→ 成功后更新余额并记录明细。 - 提现:输入金额 → 确认 → 调用提现申请接口 → 提示“提现申请已提交,等待处理”。 - 注意:钱包页面展示充值订单和提现记录,不展示打赏订单(打赏订单在“我的订单”页)。 #### EditProfile.vue - 表单字段:头像(可上传)、名称、手机号码、修改密码(原密码、新密码、确认密码)、实名认证(如未认证显示认证入口,已认证显示已认证状态)。 - 使用 `el-form`,提交后调用更新用户信息接口。 - 头像上传:使用 `el-upload` 组件,限制大小和格式。 #### StaticPage.vue - 动态路由参数 `type`,根据类型渲染不同静态内容(隐私协议等)。目前为占位,内容由后端配置或前端硬编码占位文本。 ## 7. 样式与主题 - **Element Plus 主题覆盖**: SCSS 变量修改主色、圆角、阴影等,论坛风格偏向暖色或深蓝,具体与 UI 设计对齐。 - **玻璃效果**: 通过 `backdrop-filter: blur(12px)` 配合半透明背景实现。 - **底部导航**: 高度 50px,图标大小 24px,安全区适配 (`padding-bottom: env(safe-area-inset-bottom)`)。 - **帖子卡片**: 轻微阴影 `box-shadow: 0 2px 8px rgba(0,0,0,0.08)`,圆角 8px。 - **响应式**: 最大宽度 750px 居中,适配移动端,PC 端显示居中窄版。 ## 8. 网络请求封装 (Axios) `api/request.ts`: - `baseURL` 来自环境变量。 - 请求拦截器添加 `Authorization` token。 - 响应拦截器:统一处理 `code`,非正常时 `ElMessage.error`;401 清除登录态并跳转登录页。 - 封装通用 `get/post/put/delete` 方法。 ## 9. 关键业务流程 ### 9.1 搜索与状态筛选 - 状态使用 `el-select`,选项:全部、公开、在售、命中、未命中。 - 关键字使用 `el-input`,支持防抖 (300ms)。 - 任一条件变化重新请求帖子列表,重置分页。 - URL 同步 query 参数:`?status=在售&keyword=xx`。 ### 9.2 打赏支付流程(钱包余额即时扣款) 1. 详情页点击“立即打赏” → 前端判断余额是否充足。 2. 充足则打开 `PayConfirm` 弹窗,展示价格和余额。 3. 用户确认 → 调用 `POST /api/orders/pay-direct` (或合并创建与支付) 传入 `postId`,请求头携带幂等键 `X-Request-Id`。 4. 后端原子操作:创建订单,扣减余额,记录流水,返回订单状态已完成。 5. 前端处理:更新余额,关闭弹窗,刷新帖子详情使付费内容可见,显示“打赏成功”。 6. 异常处理:余额不足或其他错误,后端返回 `code` 对应消息,前端提示,不关闭弹窗或关闭后提示。 > 由于是即时扣款,订单状态直接为“已完成”,不存在未支付状态,因此“订单过期时间”不适用。 ### 9.3 我的订单状态展示 - 筛选栏支持全部、未支付、已取消、已完成。 - 正常打赏订单为“已完成”。 - 若系统未来扩展其他支付方式或出现异常未支付订单,列表会包含相应状态。倒计时仅对未支付且有过期时间的订单显示。 - 点击订单可查看详情(暂定不可操作)。 ### 9.4 系统通知(我的信息) - 后端在某些操作后推送通知(如打赏成功、充值成功、提现状态变更)。 - 前端定期拉取或使用轮询(或 WebSocket 但初期可简化为接口拉取)。 - 未读消息数显示在底部导航“我的信息”Tab 上(`el-badge`)。 - 点击消息标记已读。 ### 9.5 钱包充值/提现 - 充值:输入金额 → 确认 → 调用模拟支付接口 → 成功则增加余额并生成资金明细。 - 提现:输入金额 → 确认 → 调用提现申请接口 → 后台审核,前端仅提示已提交。 - 资金明细接口返回流水列表,支持分页。 ### 9.6 “我已知晓”声明弹窗 - 首次进入首页时,若无 `localStorage` 标记,自动弹出声明弹窗;点击“我已知晓”后标记并关闭。 ## 10. 接口对接规范 所有接口返回统一结构:`{ code: 200, message: "success", data: {...} }` 关键接口列表: | 接口 | 方法 | 说明 | | ----------------------------- | ------- | ------------------------------------------------------------ | | `/api/posts` | GET | 获取帖子列表,参数:`status`, `keyword`, `page`, `size` | | `/api/posts/:id` | GET | 帖子详情,包含付费内容(如果已购买) | | `/api/posts/:id/pay` | POST | 创建订单并支付,请求体:`{ postId }` (可省略),header: `X-Request-Id` | | `/api/orders` | GET | 我的订单列表,参数:`status` (all/unpaid/cancelled/completed) | | `/api/notifications` | GET | 系统消息列表 | | `/api/notifications/:id/read` | PUT | 标记消息已读 | | `/api/user/profile` | GET/PUT | 获取/更新个人信息 | | `/api/user/balance` | GET | 获取余额 | | `/api/wallet/recharge` | POST | 充值,请求体:`{ amount }` | | `/api/wallet/withdraw` | POST | 提现申请,请求体:`{ amount }` | | `/api/wallet/transactions` | GET | 资金明细,参数:`page`, `size` | | `/api/config/site` | GET | 获取网站名称、logo、公告等动态配置 | 分页格式:`{ list: [], total: 100, page: 1, pageSize: 10 }` ## 11. 错误处理与状态展示 - **网络异常**: Axios 拦截器统一 `ElMessage.error('网络异常,请稍后重试')`。 - **业务错误**: 如余额不足,在 catch 中解析 `message` 并提示。 - **加载态**: 列表使用 `v-loading` 或骨架屏 `el-skeleton`;按钮点击后 `loading` 禁止重复提交。 - **空状态**: 所有列表和数据区域使用 `EmptyState` 组件。 - **认证失效**: 401 时清除 token 并跳转登录页(登录页需补充实现,假定需登录)。 --- **文档版本**:v2.0 **编写日期**:2026-06-14 **状态**:待评审