26.1.26新功能开发计划.md 16 KB

26.1.26 新功能开发计划

背景

为了增强用户在打卡列表的互动性和管理能力,需要在打卡卡片(CheckinCard)上增加更多操作选项,包括置顶、评论、海报分享以及展示评论列表。这些功能将通过环境变量开关进行控制,以便按需开启。

需求拆解

  1. 全局功能开关:在 .env 文件中通过变量控制各功能的开启/关闭。
  2. 置顶功能 (Top):允许将特定打卡内容置顶。
  3. 评论/评论功能 (Comment):允许对打卡内容进行评论(评论)。
  4. 打卡海报 (Poster):生成包含打卡内容的长图海报,支持分享。
  5. 评论列表 (Comment List):在打卡卡片下方显示该打卡的评论/评论记录。

环境变量规划

.env 中增加以下开关(默认 '0' 关闭,'1' 开启):

  • VITE_FEATURE_CHECKIN_TOP=1 (置顶功能)
  • VITE_FEATURE_CHECKIN_COMMENT=1 (评论功能)
  • VITE_FEATURE_CHECKIN_POSTER=1 (海报功能)
  • VITE_FEATURE_CHECKIN_COMMENT_LIST=1 (评论列表显示)

详细设计与逻辑流程

1. 入口改造 (CheckinCard)

  • 位置CheckinCard 组件底部右侧操作区(原点赞/更多按钮处)。
  • 交互:点击“...”图标,从底部弹出 ActionSheet(Vant 组件)。
  • 菜单项
    • 置顶:仅当 VITE_FEATURE_CHECKIN_TOP=1 时显示。若已置顶,显示“取消置顶”。
    • 评论:仅当 VITE_FEATURE_CHECKIN_COMMENT=1 时显示。
    • 海报:仅当 VITE_FEATURE_CHECKIN_POSTER=1 时显示。

2. 置顶功能 (Top)

  • 逻辑
    1. 点击“置顶”菜单。
    2. 弹出确认框 showConfirmDialog:“确定要置顶这条打卡吗?”。
    3. 用户确认 -> 调用 API teacherPinCheckinAPI(id)
    4. API 成功 -> Toast “置顶成功” -> 更新列表数据(将该项标记为置顶,或刷新列表)。
    5. 若已置顶 -> 点击“取消置顶” -> 确认 -> API teacherUnpinCheckinAPI(id) -> Toast “取消置顶成功” -> 更新状态。
  • 要点:这个功能属于教师端功能, 需要先判断这个用户的userinfo是否是老师, 使用is_teacher字段判断, 没有权限则不显示置顶菜单.
  • API
    • teacherPinCheckinAPI 老师置顶打卡 (参数: checkin_id)
    • teacherUnpinCheckinAPI 老师取消置顶打卡 (参数: checkin_id)

3. 评论功能 (Comment)

  • 逻辑
    1. 点击"评论"菜单。
    2. 弹出 评论输入弹窗(新建组件 CheckinCommentDialog)。
      • 包含:文本输入框(Textarea)、表情选择器按钮。
      • 表情选择器:点击表情图标,从底部弹出表情面板,支持常用 Emoji 表情符号(😊❤️👍🎉等)。
      • 输入验证:纯文本评论至少 5 个字符,允许表情符号作为补充。
      • 按钮:取消、提交。
    3. 点击表情图标 -> 弹出表情选择面板(底部 Popup)-> 选择表情 -> 插入到光标位置。
    4. 输入内容(文本 + 表情)-> 点击提交。
    5. 调用 API commentCheckin(id, content)
    6. API 成功 -> Toast "评论成功" -> 关闭弹窗 -> 刷新该打卡的评论列表。
  • 要点: - 这个功能属于用户端功能, 只能在/checkin/index打卡主页上的打卡卡片上显示出来。 - 表情选择器技术方案:自定义 Emoji 列表。 - 表情数据:使用原生 Unicode Emoji,无需图片资源,体积小且兼容性好。 - 常用表情建议:😊😂❤️👍🎉✨🙏💪🔥💯😍👏🤝🌟🎁
  • 组件CheckinCommentDialog.vue (基于 Vant Popup 封装,底部弹出)。
  • API (需 Mock/确认)
    • POST /checkin/comment (发表评论,参数: checkin_id, content)

4. 海报功能 (Poster)

  • 逻辑
    1. 点击“海报”菜单。
    2. 弹出 海报预览组件 (CheckinPoster,参考 SharePoster)。
    3. 渲染内容
      • 用户信息(头像、昵称)。
      • 打卡内容(文本、图片缩略图)。
      • 底部二维码(打卡主页的网址自动生成)。
      • 注:需支持长图,若内容过长,通过滚动查看,生成图片时需完整截取。
    4. 生成图片:使用 html2canvashtml-to-image 将 DOM 转为图片。
    5. 展示生成的图片,提示“长按保存”。
  • 组件CheckinPoster.vue
  • 技术点:处理跨域图片、长图渲染、字体加载。

5. 评论列表 (Comment List)

  • 位置CheckinCard 组件内部下方。
  • 显示条件VITE_FEATURE_CHECKIN_COMMENT_LIST=1post.comments 长度 > 0。
  • 样式:参考朋友圈评论区(灰色背景,每行 用户: 内容)。
  • 逻辑
    • 渲染评论列表,支持 Emoji 表情符号的显示。
    • 列车最多展示5条评论, 超过5条的评论需要点击"查看全部"才能看到.
    • 用户自己评论的右侧需要显示一个删除图标, 点击图标弹出确认框, 确认后调用删除接口删除该条评论.
    • 交互与操作
      • 回复:点击某一条评论,从屏幕底部弹出输入框(类似微信朋友圈),键盘自动升起。输入框同样支持表情选择器。输入内容后点击发送,即为回复该条评论。
        • 数据结构:使用 parent_id 标识父评论,reply_to_user_id 标识被回复用户。
        • 显示样式:用户A 回复 用户B: 评论内容
      • 删除:点击用户自己发布的评论,弹出 ActionSheet 或确认框,选项包含"删除"。确认后调用删除接口移除该评论。
      • 样式参考:整体交互逻辑和视觉风格严格参考微信朋友圈。
      • Emoji 渲染:评论内容中的 Emoji 符号直接使用原生 Unicode 渲染,无需特殊处理。
  • 组件CheckinCommentList.vue (复用 StudyCommentsSection.vue 的设计模式)。
  • API (需 Mock/确认)
    • GET /checkin/comments (获取评论列表,参数: checkin_id, page, page_size)
    • POST /checkin/comment (发表评论,参数: checkin_id, content)
    • POST /checkin/comment/reply (回复评论,参数: checkin_id, content, parent_id, reply_to_user_id)
    • DELETE /checkin/comment/:id (删除评论,参数: comment_id)

开发步骤

第 1 步:环境准备与 Mock API

  • .env 添加开关变量。
  • src/api 定义相关接口(Top, Comment),前期可使用 Mock 数据验证流程。

第 2 步:改造 CheckinCard 菜单

  • 引入 ActionSheet
  • 根据 Env 开关动态显示菜单项。
  • 实现基础点击事件处理。

第 3 步:实现置顶逻辑

  • 对接置顶/取消置顶 API。
  • 添加确认弹窗。
  • 处理列表状态更新。
  • 置顶视觉标记:在已置顶的打卡卡片上显示"📌 置顶"标记。

第 4 步:实现评论功能与列表

  • 创建 CheckinCommentDialog 组件。
    • 实现 van-field 文本输入框(支持多行)。
    • 实现表情选择器
      • 方案选择:自定义 Emoji 面板(不引入额外依赖,使用原生 Unicode Emoji)。
      • UI 实现:van-popup 底部弹出 + van-grid 展示表情符号。
      • 交互逻辑:点击表情 -> 插入到输入框光标位置 -> 自动关闭面板。
      • 常用表情列表:😊😂❤️👍🎉✨🙏💪🔥💯😍👏🤝🌟🎁😭😡🤔💭😴🎂🌈⭐🌙☀️🌺🌸🍀🎁🎈🎵🎶📱💻⚽🏀🎾🎯🎨🎬📷🎤🎧📚✏️📝💡🔔💬📧📞
    • 实现输入验证(文本至少 5 字,表情可作为补充)。
  • CheckinCard 中引入并调用评论弹窗。
  • 创建 CheckinCommentList 组件(/components/checkin/CheckinCommentList.vue)。
    • 参考 StudyCommentsSection.vue 的实现模式。
    • 支持评论列表展示(最多 5 条,超过则显示"查看全部")。
    • 支持 Emoji 符号的直接渲染。
    • 实现评论回复交互(底部输入框弹出,同样支持表情选择)。
    • 实现删除逻辑(仅显示自己评论的删除图标)。
  • 对接评论、回复、删除 API 和列表展示数据。

第 5 步:实现打卡海报

  • 创建 CheckinPoster 组件。
  • 实现布局(支持长内容)。
  • 集成 html2canvas 生成逻辑。
  • 对接 CheckinCard 菜单。

边界条件与注意点

  1. 权限控制

    • 置顶功能是否仅管理员可见?(前端暂通过 Env 控制全局,根据用户角色判断)。
    • 评论功能是否允许自己评论自己?(需后端确认,前端暂不做限制)。
  2. 表情输入处理

    • 字符计数:Emoji 符号在某些设备上可能占用 2 个字符位置(代理对),需使用 Array.from(text).length 计算真实字符数。
    • 输入限制:限制单条评论最多 200 个字符(包含 Emoji),前端实时提示剩余字数。
    • 兼容性:原生 Unicode Emoji 在 iOS/Android/微信内置浏览器中均能正常显示,无需降级方案。
    • 存储:后端需确保数据库字符集支持 UTF-8 MB4(MySQL 5.5.3+ 的 utf8mb4),否则部分 Emoji(如 🎁)会乱码。
  3. 海报生成

    • 图片跨域问题(需配置 useCORS: true 且 CDN 支持)。
    • 内容过长导致 Canvas 内存溢出(需限制最大高度或分段,第一版暂不考虑极端情况)。
  4. 列表更新

    • 操作后尽量避免全列表刷新,采用本地数据更新(Update Item)以提升体验。
  5. 评论回复数据结构

    • 建议使用扁平化结构(所有评论在同一层级,通过 parent_id 关联),便于分页和排序。
    • 示例: javascript { id: 1, checkin_id: 123, user_id: 456, content: "干得漂亮!🎉", parent_id: 0, // 0 表示一级评论 reply_to_user_id: null, // 一级评论为 null created_at: "2026-01-26 10:00:00" }
  6. CheckinCard 数据结构扩展

    • 现有 post 对象需要新增以下字段: javascript { id: 123, user: { name: "张三", avatar: "..." }, content: "今天完成了100天打卡!", images: [...], videoList: [...], audio: [...], likes: 10, is_liked: false, is_my: true, // 🆕 新增字段 is_pinned: false, // 是否置顶 pinned_at: null, // 置顶时间 comments_count: 0, // 评论总数(用于列表展示) comments: [] // 评论列表(最多5条) }
  7. 性能优化

    • 评论列表懒加载:仅在用户展开"查看全部"时才加载完整评论列表,首屏只加载前 5 条。
    • 图片懒加载:海报生成时使用 loading="lazy" 避免一次性加载所有图片。
    • 列表虚拟滚动:如果打卡列表超过 50 条,考虑使用 van-list 的虚拟滚动模式。
  8. 错误处理

    • 网络错误:API 调用失败时,显示 Toast 提示用户,并提供"重试"按钮。
    • 并发冲突:删除评论时,若该评论已被删除,提示"该评论不存在"。
  9. 测试计划

    • 单元测试:测试 CheckinCommentDialog 组件的输入验证、Emoji 插入逻辑。
    • 集成测试:测试评论发表、回复、删除的完整流程。
    • 边界测试:测试 200 字符限制、Emoji 字符计数、空评论提交等边界情况。
    • 兼容性测试:在 iOS Safari、Android Chrome、微信内置浏览器中测试 Emoji 显示。

待确认事项

与后端确认

  1. API 接口

    • GET /checkin/comments - 评论列表接口(是否支持分页?返回数据结构是否包含用户信息?)支持分页, 不包含用户信息.
    • POST /checkin/comment - 发表评论接口(是否需要敏感词过滤?返回值是什么?)不需要敏感词过滤, 返回值应该是评论ID.
    • POST /checkin/comment/reply - 回复评论接口(参数是否完整?)参数完整, 包含评论ID, 回复内容, 回复用户ID. 返回值应该是回复评论ID.
    • DELETE /checkin/comment/:id - 删除评论接口(是否有权限校验?)不需要校验, 列表会返回字段, 判断是否是自己的评论, 如果不是不会显示删除按钮.
    • teacherPinCheckinAPI / teacherUnpinCheckinAPI - 接口已实现.
  2. 数据字段

    • post.is_pinned - 置顶标记字段是否存在?
    • post.pinned_at - 置顶时间字段是否存在?
    • post.comments_count - 评论数字段是否存在?
    • post.comments - 评论列表字段是否存在?(预加载前5条)
    • user.is_teacher - 用户角色字段是否存在于 localStorage.user_info?在localStorage的currentUser中有存个人信息
  3. 权限控制

    • 置顶功能:是否仅教师可见?是否有更细粒度的权限控制?仅教师可以置顶打卡.
    • 删除评论:是否只能删除自己的评论?教师是否可以删除所有评论?
    • 评论功能:是否允许自己评论自己的打卡?允许.
  4. 业务规则

    • 评论字符限制:是 200 字还是其他数量?
    • 是否允许发送纯表情评论(无文字)?
    • 评论后是否需要通知打卡用户或被回复用户?
    • 置顶数量限制:是否限制同时置顶的打卡数量?

与产品确认

  1. 功能优先级

    • 4 个功能(置顶、评论、海报、评论列表)的开发优先级是什么?
    • 是否需要在第一版就全部完成,还是可以分阶段上线?
  2. 交互细节

    • 置顶的打卡是否需要特殊的视觉标记(如"📌 置顶"标签、置顶图标等)?
    • 评论删除是否需要二次确认?(计划中已确认需要)
    • 表情选择器是否需要分类(如"笑脸"、"手势"、"动物"等)?
    • 海报生成失败时,是否需要降级方案(如显示文字版分享链接)?
  3. 内容规范

    • 评论内容的敏感词过滤策略是什么?
    • 是否需要举报功能?
    • 是否需要审核机制(评论需审核后才能显示)?
  4. 数据统计

    • 是否需要统计评论数量、置顶数量等数据用于运营分析?

总结

✅ 计划完善度评估

总体评分:9/10 - 开发计划已经非常完善,涵盖了需求、设计、API、边界条件等各个方面。

优点:

  • ✅ 需求拆解清晰,环境变量开关设计灵活
  • ✅ 技术方案成熟可行(表情选择器、评论系统、海报生成)
  • ✅ API 设计完整,涵盖增删改查
  • ✅ 数据结构设计合理(扁平化评论结构)
  • ✅ 边界条件考虑充分(Emoji 字符计数、数据库 utf8mb4)
  • ✅ 参考现有代码库,复用性高
  • ✅ 开发步骤清晰,循序渐进
  • ✅ 性能优化、错误处理、测试计划都已考虑

需要改进的地方:

  • ⚠️ 部分业务规则需要与后端/产品确认(见"待确认事项")
  • ⚠️ 置顶视觉标记、评论通知等功能细节需要补充
  • ⚠️ 错误处理和降级方案可以更详细

🎯 建议的开发顺序

  1. 第 1 阶段:置顶功能(最简单,快速验证流程)
  2. 第 2 阶段:评论功能 + 评论列表(核心功能,投入最大)
  3. 第 3 阶段:海报功能(技术难度较高,可最后开发)

📝 下一步行动

  1. 与后端/产品确认"待确认事项"中的所有问题
  2. 确认开发优先级和里程碑节点
  3. 开始第 1 阶段开发(置顶功能)
  4. 同步准备 API Mock 数据,以便前端独立开发