demand.md 15 KB

咕咕嘎嘎论坛前端详细设计文档(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-groupel-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
状态:待评审