Bull's blog Bull's blog
Resume
  • Tools Home
  • Testing Toolbox
  • 测试文件下载中心
  • 图片测试文件下载
  • 音频测试文件下载
  • 视频测试文件下载
  • 文档测试文件下载
  • Pinyin Dictation Sheet
  • English Word Daily
  • Paper Games
  • Work Notes
  • Categories
  • Tags
  • Archives

Bull

Resume
  • Tools Home
  • Testing Toolbox
  • 测试文件下载中心
  • 图片测试文件下载
  • 音频测试文件下载
  • 视频测试文件下载
  • 文档测试文件下载
  • Pinyin Dictation Sheet
  • English Word Daily
  • Paper Games
  • Work Notes
  • Categories
  • Tags
  • Archives
  • superpowers
  • specs
wangyang
2026-04-08
目录

2026-04-08-message-board-design

# Message Board Design

# Goal

Add a reusable message board for collecting visitor feedback. It must work on the resume landing page and tools pages, while each page remains in control of whether the board is shown.

The first version should reuse the existing Flask message-board API in pywork/statistics_index.py. It should not introduce a new backend, new database, or third-party comment system.

# Existing Context

The site is a VuePress 1 + vdoing static blog. Tools live under docs/07.工具/, and the resume page uses docs/index.md with pageComponent.name: ResumeLanding.

There is already message-board functionality embedded in docs/.vuepress/components/PinyinDictationTool.vue:

  • It posts messages to https://wangmouren.online:9000/api/message-board/messages.
  • It lists messages by pageKey.
  • It displays author replies.
  • It derives the message-board base URL from the existing tracking endpoint.

The backend in pywork/statistics_index.py already provides:

  • POST /api/message-board/messages
  • GET /api/message-board/messages?pageKey=...&limit=...
  • POST /api/message-board/reply
  • SQLite storage in message_board_entries
  • Feishu notification on submit and reply

# Recommended Approach

Create a reusable MessageBoard.vue component and make page owners opt in explicitly.

This keeps the implementation small and avoids touching the global vdoing layout. It also lets the custom resume page and normal tool pages use the same behavior without duplicating form, fetch, state, and styles.

# Component API

Create docs/.vuepress/components/MessageBoard.vue.

Props:

  • enabled: Boolean, default true
  • pageKey: String, required for API calls
  • source: String, default message-board
  • title: String, default 留言板
  • description: String, default 欢迎反馈使用体验。
  • endpointBase: String, default derived from https://wangmouren.online:9000
  • limit: Number, default 50

Behavior:

  • If enabled is false, render nothing.
  • If pageKey is empty, show a local error instead of calling the API.
  • On mount, load recent messages for the given pageKey.
  • On submit, send pageKey, nickname, message, and source.
  • After a successful submit, clear the form and reload messages.
  • Show loading, success, and error states.
  • Display nickname, creation time, message body, and optional author reply.

# Page Control

Each page controls display through either component props or frontmatter.

For the resume page, add frontmatter to docs/index.md:

messageBoard:
  enabled: true
  pageKey: resume-home
  source: resume-landing
  title: 给我留言
  description: 如果你对我的经历、项目或合作方向有问题,可以在这里留言。
1
2
3
4
5
6

ResumeLanding.vue reads this.$page.frontmatter.messageBoard and passes those values into MessageBoard.vue. If the frontmatter object is missing or enabled is not true, the resume page does not show the board.

For tool components, use explicit props where the board is needed:

<MessageBoard
  page-key="pinyin-helper"
  source="pinyin-helper-tool"
  title="留言板"
  description="欢迎反馈使用体验,我会在飞书收到留言并可通过接口回复。"
/>
1
2
3
4
5
6

This avoids adding the board globally to every tool by accident.

# Pinyin Tool Migration

Refactor PinyinDictationTool.vue to remove its embedded message-board form, state, API helpers, and styles. Replace that section with the reusable MessageBoard component using the same pageKey and source.

The migration should preserve current behavior for the pinyin page:

  • Existing pinyin-helper messages remain visible because the pageKey stays pinyin-helper.
  • Submissions still trigger the existing backend and Feishu notification.
  • Author replies still render under the original message.

# Resume Placement

Place the resume message board after the contact section, still inside the resume landing page. This keeps it near the direct contact options without interrupting the hero, case studies, or technical summary.

Use resume-local spacing styles only for the outer section. Keep form and message-list styles inside MessageBoard.vue so tools and resume pages share the same interaction behavior.

# Backend

Do not change backend routes in V1.

The current backend already validates pageKey and message, truncates long values, stores IP and user agent, returns serialized messages, and supports replies protected by MESSAGE_BOARD_REPLY_TOKEN when configured.

One known limitation remains: public submissions do not have captcha or rate limiting. That is acceptable for this iteration because the goal is to reuse the existing lightweight feedback flow. If spam appears later, add backend throttling or a honeypot field as a separate change.

# Error Handling

Frontend handling:

  • Empty message: show 请输入留言内容.
  • Missing pageKey: show 留言板配置缺少 pageKey.
  • Failed list call: show 留言加载失败.
  • Failed submit call: show the backend info message when available, otherwise 提交失败.

Network failures should not block the rest of the page. The message board should fail locally and leave the resume or tool content usable.

# Testing

Add or update focused wiring tests to verify:

  • MessageBoard.vue exists and calls /api/message-board/messages.
  • PinyinDictationTool.vue imports and renders MessageBoard.
  • PinyinDictationTool.vue no longer contains duplicate message-board API methods.
  • ResumeLanding.vue imports and renders MessageBoard.
  • docs/index.md includes messageBoard.enabled: true and pageKey: resume-home.

Manual verification:

  • Start the VuePress dev server.
  • Open /tools/pinyin-helper/, verify existing messages load and submit works.
  • Open /, verify the resume board appears when enabled.
  • Set messageBoard.enabled: false in docs/index.md, verify the resume board disappears.
  • Confirm the rest of the resume and tool pages still render if the message-board API is unavailable.
上次更新: 2026/04/08, 16:52:17
最近更新
01
2026-04-07-paper-game-generator
04-07
02
2026-04-07-paper-game-generator-design
04-07
03
2026-04-07-english-word-daily
04-07
更多文章>
Theme by Vdoing | Copyright © 2018-2026 Evan Xu | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式