[Feat/birthboard] 生日灯牌功能正式PR - #996
Conversation
生日祝福投放平台,包含投放记录、审核、确认、合约等功能,以及完整的模型、视图、定时任务、通知、管理命令与前端模板。 从 fork 的 develop 分支重建:丢弃了误操作的 merge 提交与对上游小程序 API (Yuanpei-Intelligence#966) 的 revert,并移除了误提交的测试凭证文件与调试输出文件。 Files changed: - birthboard/: 新增生日板应用(模型、视图、定时任务、通知、迁移等) - boot/config.py: 新增 shihannet 配置 - boot/settings.py: 注册 birthboard 应用 - boot/urls.py: 挂载 /birthboard/ 路由 - requirements.txt: 新增 playwright 与 ddddocr 依赖 - static/birthboard/: 新增字体资源 - templates/birthboard/: 新增页面模板
fix:消息函数已经改为notification_create
fix:解决一系列并发问题,加入一系列悲观锁。 feat:完善协议文件。 feat:在welcome页面加入入口。
- 新增 BirthboardLike 累计点赞模型与 like_count/like_add 接口,制作名单弹窗支持点赞并随机切换 14 种按钮图标 - 新增 BirthboardReminderSeen 模型与 reminder_seen 接口,今日提醒(happy/bless)改为服务端跨设备去重 - 制作名单弹窗视觉:hpbtd 风格背景、三列名单排版、按钮位置/描边、淡入 3s 淡出 1s 动画 - 页脚手机版缩小字号/宽度;新增 downbtn/textN/lddq、页脚提示卡片与遮罩样式 - 将 shihannet 配置从 boot/config.py 迁移到 birthboard/config.py,新增 birthboard contact_email 配置 - 协议页标题改用 h1;左侧导航加入"生日灯牌"入口 - 新增迁移 0012/0013 及对应测试(37 项全通过) Files changed: - birthboard/models.py: 新增 BirthboardLike、BirthboardReminderSeen 模型 - birthboard/views.py: 新增 like_count/like_add/reminder_seen 接口,提醒 seen 去重 - birthboard/urls.py: 注册三个新接口路由 - birthboard/tests.py: 新增点赞与提醒去重测试 - birthboard/jobs.py: shihannet 改为从 birthboard.config 导入 - birthboard/web_controller.py: shihannet 改为从 birthboard.config 导入 - birthboard/config.py: 新增 BirthboardConfig(contact_email) 与 shihannet 配置 - birthboard/migrations/0012_birthboardlike.py: BirthboardLike 迁移 - birthboard/migrations/0013_birthboardreminderseen.py: BirthboardReminderSeen 迁移 - boot/config.py: 移除 shihannet 配置 - config_template.json: 新增 birthboard.contact_email 占位 - static/birthboard/birthboard.css: 页脚/点赞弹窗/淡入淡出/提示卡片样式 - templates/birthboard/birthboard.html: 制作名单弹窗、点赞、提醒去重前端 - templates/birthboard/contract.html: 协议标题改用 h1 - templates/user_left_navbar.html: 左侧导航加入生日灯牌入口
- 制作名单弹窗改为相对视口固定居中,缩放不漂移、内容不换行;点赞按钮 固定尺寸,数字/横线/间距等改由 CSS 变量控制(桌面 :root 默认、 initPhoneLayers() 手机覆盖)。 - 制作名单的组织名称与姓名从模板硬编码迁入配置系统 (birthboard.contributor_orgs),由视图传入模板循环渲染,便于运营维护。 - 字体去重:思源黑体等 @font-face 统一收敛到 birthboard_fonts.css 并加 local() 本地优先;confirm/approve 页改为引用共享字体文件,避免重复下载。 Files changed: - birthboard/config.py: 新增 contributor_orgs 配置项(制作名单组织与姓名)。 - birthboard/views.py: 各渲染分支向模板传入 contributor_orgs。 - birthboard/tests.py: 新增 ContributorOrgsConfigTests 校验配置结构。 - config_template.json: birthboard 段新增 contributor_orgs 默认名单。 - static/birthboard/birthboard.css: 移除 @font-face,新增 --bb-clist-* 变量。 - static/birthboard/birthboard_approve.css: 移除 @font-face,引用共享字体文件。 - static/birthboard/birthboard_confirm.css: 移除 @font-face,引用共享字体文件。 - static/birthboard/birthboard_fonts.css: 新增共享字体声明(本地优先)。 - templates/birthboard/birthboard.html: likeModal 视觉重构 + 名单循环渲染。 - templates/birthboard/birthboard_approve.html: 引入共享字体样式。 - templates/birthboard/birthboard_confirm.html: 引入共享字体样式。 - templates/birthboard/contract.html: 引入共享字体样式。
Rebase 到 upstream/develop 后,generic 出现两个迁移分支叶子 (本分支 0005_alter_yqpointrecord_source_type 与 upstream 的 0007_merge_pending_auth_credentials)。新增 0008 merge 迁移统一迁移图。 Files changed: - generic/migrations/0008_merge_20260831_0208.py: 合并两个迁移分支叶子。
- birthboard_sign_contract / birthboard_like_add / 主视图 POST 补 @csrf_protect (项目禁用全局 CsrfViewMiddleware,所有登录态变更操作需显式 CSRF); like_add 前端 fetch POST 补 X-CSRFToken。 - 移除 views.py 的 from app.views_dependency import *,显式导入 login_required / render。 - BirthboardConfirmSeen.mark_seen 改用 save(update_fields=...)。 - birthboard.html 删除重复定义的 toggleAnon。 - forms.py 修正 mode=2 的投放模式文案(1000 -> 10000 元气值/1年)。 - api_yqpoint.py 装饰器顺序改为 login_required 在外层,符合规范。 Files changed: - birthboard/views.py: 补 csrf_protect;移除通配符导入;显式导入。 - birthboard/models.py: mark_seen 使用 update_fields。 - birthboard/forms.py: 修正 10000 元气值文案。 - birthboard/api_yqpoint.py: 调整装饰器顺序。 - templates/birthboard/birthboard.html: like_add 补 X-CSRFToken;删除重复 toggleAnon。
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 660f39a0f5
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
There was a problem hiding this comment.
Pull request overview
本 PR 为 YPPF 引入新的「生日灯牌(birthboard)」子系统:以 Django 模板页 + 后台任务为核心,打通生日祝福投放的用户流程,并与元气值(YQPoint)、通知、定时任务等模块对接,同时补充配置、依赖与迁移。
Changes:
- 新增
birthboardDjango app:路由、模型、任务(scheduler jobs)、通知、管理命令与测试用例。 - 扩展通用能力:YQPointRecord SourceType 增加 BIRTHBOARD;用户搜索索引返回值增加
pk字段。 - 增加前端模板与静态资源,并在左右侧导航栏加入入口;补充配置模板与依赖。
Reviewed changes
Copilot reviewed 40 out of 49 changed files in this pull request and generated 10 comments.
Show a summary per file
| File | Description |
|---|---|
| templates/user_left_navbar.html | 用户侧导航栏增加 birthboard 入口链接 |
| templates/org_left_navbar.html | 组织侧导航栏增加 birthboard 入口链接 |
| templates/birthboard/contract.html | 新增 birthboard 用户协议页面 |
| templates/birthboard/birthboard_approve.html | 新增 birthboard 审核台页面与筛选/弹窗交互 |
| templates/birthboard/birthboard_approve_denied.html | 新增无审核权限提示页 |
| static/birthboard/contract.css | 新增协议页样式 |
| static/birthboard/birthboard.css | 新增 birthboard 主页面样式(含大量定位/弹窗样式) |
| static/birthboard/birthboard_fonts.css | 新增 birthboard 共享字体声明样式 |
| static/birthboard/birthboard_confirm.css | 新增/调整确认页样式 |
| static/birthboard/birthboard_approve.css | 新增审核页样式 |
| static/birthboard/birthboard_approve_denied.css | 新增无权限页样式 |
| requirements.txt | 增加 birthboard 相关依赖(playwright、ddddocr) |
| generic/utils.py | to_search_indices 返回值增加 pk 字段以支持前端关联 |
| generic/models.py | YQPointRecord.SourceType 增加 BIRTHBOARD=8 |
| generic/migrations/0005_alter_yqpointrecord_source_type.py | 迁移:更新 YQPointRecord.source_type choices |
| generic/migrations/0008_merge_20260831_0208.py | 迁移:合并 generic 的迁移分支 |
| config_template.json | 增加 birthboard 配置段(contact_email、contributor_orgs) |
| boot/urls.py | 注册 /birthboard/ 路由到 birthboard.urls |
| boot/settings.py | 将 birthboard 加入应用配置列表 |
| birthboard/utils.py | 增加每人扣费计算与缩略图生成工具函数 |
| birthboard/urls.py | 新增 birthboard 页面与 JSON API 路由 |
| birthboard/tests.py | 新增较完整的单测覆盖(流程/任务/并发/提醒等) |
| birthboard/reminder.py | 新增审核提醒定时任务的排期/撤回逻辑 |
| birthboard/notify.py | 新增站内信 + 企业微信通知封装函数 |
| birthboard/models.py | 新增 birthboard 核心模型(记录、参与者、审核员、协议、已读、点赞、提醒去重等) |
| birthboard/migrations/0001_initial.py | birthboard 初始迁移 |
| birthboard/migrations/0002_alter_birthboardrecord_status_squashed_0011_add_thumbnail_field.py | squashed 迁移:扩展状态机/审核员/日志/协议/缩略图等 |
| birthboard/migrations/0012_birthboardlike.py | 增加点赞量模型迁移 |
| birthboard/migrations/0013_birthboardreminderseen.py | 增加提醒已读去重模型迁移 |
| birthboard/migrations/init.py | 迁移包初始化文件 |
| birthboard/management/init.py | management 包初始化 |
| birthboard/management/commands/init.py | commands 包初始化 |
| birthboard/management/commands/backfill_birthboard_thumbnails.py | 管理命令:历史记录缩略图回填 |
| birthboard/management/commands/run_birthboard_waiting_checks.py | 管理命令:手动触发等待提醒/超时处理 |
| birthboard/management/commands/simulate_birthboard_nightly_update.py | 管理命令:模拟 23:45 夜间更新任务 |
| birthboard/jobs.py | 定时任务:提醒/超时自动拒绝退款/夜间投放同步(Playwright)/过期兜底 |
| birthboard/forms.py | 新增表单:投放记录提交字段 |
| birthboard/config.py | 新增 birthboard + shihannet 配置封装 |
| birthboard/apps.py | 新增 Django AppConfig |
| birthboard/api_yqpoint.py | 新增 YQPoint 校验 API(按 senders/record 计算是否足够) |
| birthboard/admin.py | 新增审核员/二审员 admin 配置 |
| birthboard/init.py | app 包初始化文件 |
Suppressed comments (2)
birthboard/jobs.py:83
- 同一函数中字符串分支也把年档 cost 写成了 1000;应与年档 10000 保持一致,否则 mode 以字符串形式存储时同样会被错误推断为 1 天。
if isinstance(mode, str) and mode.isdigit():
m = int(mode)
cost_map = {35: 1, 60: 3, 1000: 365}
return cost_map.get(m, 1)
static/birthboard/birthboard_fonts.css:43
- 同文件后续两个
@font-face也使用了display: swap;(无效)。应统一改为font-display: swap;,避免只有部分字体族按预期加载。
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
修复 Codex/Copilot PR review 建议及后续自查发现的问题: - 撤销增加发起人/寿星所有权校验(行锁内),越权返回 forbidden - 审核/驳回全部移入锁定事务,避免并发一审/二审互相覆盖 - 外部投放屏更新失败时返回失败结果并回退夜间推进的状态 - birthboard_confirm/approve 补 CSRF 保护与 profile 门禁 - 修复年档成本 1000→10000(jobs 与审核页文案) - check_yqpoint 改为只查本人余额,补 logger 与通用错误消息 - 扣款成功通知移入 transaction.on_commit - 统一 datetime.now() 替代 timezone.now() - 补 __all__、models 显式时间常量、confirm 表单 CSRF token、文案统一 Files changed: - birthboard/views.py: 撤销所有权校验、锁事务范围、CSRF/门禁、on_commit、datetime、__all__ - birthboard/jobs.py: 年档、失败回退、datetime、__all__ - birthboard/api_yqpoint.py: 只查本人余额、logger、通用错误、CSRF - birthboard/models.py: 默认值显式常量、docstring - birthboard/notify.py: __all__ - birthboard/utils.py: __all__ - birthboard/forms.py: __all__ - birthboard/tests.py: 回归测试与适配 - boot/settings.py: 启用 csrf context processor - config_template.json: 补齐 shihannet 占位配置 - static/birthboard/*.css: font-display 修正、嵌套注释修复 - templates/birthboard/*.html: CSRF token、10000 文案、需要修改、forbidden 提示
|
完成修改,并按学院要求修改了部分措辞 |
|
增加了手机版的审核视图 |
小程序内嵌 webview 完整适配:登录跳板放行同源绝对 URL、会话过期登录页兜底、 退出/返回出口在小程序内回小程序、移动版审核入口与返回按钮;图片上传区新增 配置驱动的"模版下载"链接并与错误提示同槽位互斥。 Files changed: - utils/http/utils.py: safe_local_redirect_target 放行同源绝对 URL(P0-1) - generic/views.py: Index.visitor_get 对 miniProgram UA 渲染登录兜底页(P0-2) - generic/tests.py: 新增同源放行、webview 跳转与登录兜底测试 - birthboard/config.py: 新增 template_download_url 配置 - birthboard/views.py: birthboard 视图各 render 传入 template_download_url - config_template.json: birthboard 段新增 template_download_url - static/birthboard/birthboard_webview.js: 新增,小程序 UA 门控退出脚本 - templates/webview_expired.html: 新增,登录兜底页 - templates/birthboard/birthboard.html: 退出按钮 data-bb-exit、模版下载链接与联动、手机版审核入口 - templates/birthboard/birthboard_approve_mobile.html: 顶栏新增"返回投放板" - templates/birthboard/contract.html: 底部"返回首页" data-bb-exit
|
增加了微信小程序的适配,应该是最后一次改动了 |
- 完善发布、付款、确认、中止、撤销、审核及退款状态校验 - 强制一审二审分离,并禁止活动关联人员参与审核 - 增加违规限制、待下架持久化及投屏失败重试机制 - 加固海报访问、余额查询、POST/CSRF 与并发锁控制 - 修复夜间同步竞态、失败回退和补偿任务 - 补全数据库迁移与 birthboard 缺省配置兼容 - 升级开发容器至 Debian 12,支持 Playwright Chromium - 增加安全、审核、并发及投屏工作流回归测试
|
已根据 本次主要调整:
Docker 开发容器验证结果:
受现场条件限制,本次没有实际执行电子屏登录、素材上传、播单更新或下架。相关投屏流程通过 mock、失败回退、下架优先和定时重试测试验证,测试过程中未连接或操作真实投屏系统。 |
- 提交页:服务端表单错误回填到 #senders-error / #image-error 槽位; 前端对送出者人数上限做校验;人均费用计算与后端 calculate_per_cost 对齐。 - 驳回:限制发起人由自动改为弹窗勾选(restrict,默认不勾),并注册 BirthboardContract 到 admin,提供"解除限制参与"批量动作。 - 模板:修复确认页 tab 徽标定位与审核页移动端 onclick 嵌套引号语法。 Files changed: - birthboard/views.py: json_context 注入 max_senders;_reject_record_by_admin 增加 restrict 参数,仅勾选时设限。 - birthboard/forms.py: BirthboardRejectForm 增加 restrict 字段。 - birthboard/admin.py: 注册 BirthboardContract 及解除限制 action。 - birthboard/tests.py: 更新驳回限制测试并新增默认不设限回归测试。 - templates/birthboard/birthboard.html: 错误槽位渲染、前端人数上限校验、 人均费用计算对齐后端。 - templates/birthboard/birthboard_approve.html: 驳回弹窗增加限制勾选框。 - templates/birthboard/birthboard_approve_mobile.html: 驳回弹窗勾选框 + onclick 嵌套引号语法修复。 - templates/birthboard/birthboard_confirm.html: 修复 tab 徽标定位。
|
根据修改完善了部分逻辑和视图 |
- 通知发件人改由 config.birthboard.sender_username/sender_name 控制, notify.py 统一改用 record.log logger,避免发件人缺失时静默失败; 新增 ensure_birthboard_sender 幂等创建官方组织账号的命令。 - 一审/二审员新增 reminder_enabled 开关:关闭后仍可审核,但不再接收 自动重复审核提醒(notify_approval_reminder 只发给开启者)。 - 投放记录接入 admin:只读流程字段 + 参与者/变更记录只读内联,可改 date; 审核员/二审员管理页提供内联开关。 - 四个模型补充中文 verbose_name 并用序号前缀控制 admin 显示顺序。 - config_template.json:birthboard 段新增 sender_username/sender_name。 Files changed: - birthboard/config.py: 新增 sender_username/sender_name 配置项。 - birthboard/notify.py: 发件人读取 config(_sender_user),logger 换统一 logger;审核提醒按 reminder_enabled 过滤。 - birthboard/management/commands/ensure_birthboard_sender.py: 新增幂等创建发件人命令。 - birthboard/models.py: approver/second approver 新增 reminder_enabled;四个模型加中文 verbose_name。 - birthboard/admin.py: 审核员内联开关;投放记录只读 admin 与参与者/变更记录只读内联。 - birthboard/migrations/0015_*: 新增 reminder_enabled 字段。 - birthboard/migrations/0016_*: 模型 Meta 选项(verbose_name)变更。 - birthboard/tests.py: 通知发件人与提醒开关回归测试。 - config_template.json: birthboard 段新增发件人配置(sender_username/sender_name)。
4c335bc to
ea3d866
Compare
feat: 新增生日板(birthboard)模块——YQPoint 付费生日祝福投放系统
本 PR 新增生日板模块,打通"发起、凑份子付款、寿星确认、审核、定时投放"全流程,并与 YQPoint 积分、企业微信通知、定时任务深度集成。
核心功能:
页面与路由(挂载于 /birthboard/):主页面、协议页、确认页(参与/寿星/完成三 tab)、审核页、驳回页,以及余额查询、点赞、确认计数、提醒已读等 JSON API;左侧导航栏新增入口。
基础设施改动:
requirements.txt新增 playwright、ddddocr。config_template.json新增 birthboard.contact_email、birthboard.contributor_orgs、shihannet(外部投放屏账号,仅占位符)。测试:
birthboard/tests.py(718 行)覆盖发起、付款、审核、投放、退款主流程及超时、驳回、并发等边界场景。
部署与配置注意:
manage.pymigrate(含 generic 迁移分支合并)。