2026-08-09 | 川川 & 思奕 · 暮光森屿
覆盖 2026-08-03 → 08-09,共 7 天
| 类别 | 产出 |
|---|---|
| 对外 | 电子请柬 H5(品牌册结构 · 含 RSVP 回收)、微信小程序「暮光森屿」1.0.3 已提交审核 |
| 内部 | 24 个筹备页面上线 ccopc.cn,含总控 / 预算 / 名单 / 联系推进 / 物料清单 / 游园会 |
| 数据 | 242 人邀请名单、240 人已打分、25 条真实回执自动入库 |
| 印刷 | 帆布袋印刷母版、红酒正标 ×3 方案 + 背标,全部真 300dpi |
| 内容 | 50 句文案定量打分、邀约话术 5 套、游园会 10 游戏(基于真实小红书互动量) |
| 基建 | wedding-api 后端(systemd 常驻)、nginx 反代、带口令保护的回执接口 |
整个项目最后长成了这个形状。不是设计出来的,是撞出来的。
① 事实层 ── 场地真实照片 / 合同数字 / 微信联系人截图 / 小红书真实互动量
↓
② 生产层 ── codex+GPT Image 2(画面) · Python/PIL(印刷排版) · HTML(网页)
↓
③ 发布层 ── ccopc.cn 静态站 · wedding-api 后端 · 微信小程序
↓
④ 回收层 ── 宾客填回执 → API 入库 → 自动匹配名单 → 圈层分组 → 排桌
关键在于①和④是闭环的:回执回来的人如果不在名单里,就补录进名单(#237–#242 就是这么来的),名单又反过来指导下一批发谁。
问题:GPT Image 2 写中文必错字,且最大 1536px,做成 30×35cm 印刷品只有 ~186dpi,印出来是糊的。厂家原话:「老板说我们给的图有点糊」。
解法:把一张印刷稿拆成两层,分开生产。
| 层 | 工具 | 为什么 |
|---|---|---|
| 画面层 | codex + GPT Image 2,提示词里写死 ABSOLUTELY NO TEXT | AI 只干它擅长的 |
| 文字层 | Python PIL + macOS 系统真字体,直接在 300dpi 画布上渲染 | 字体是矢量的,边缘绝对锐利;且物理上不可能错字 |
验证:帆布袋 2480×2496px @300dpi、酒标 1133×1487px @300dpi,都是这么出的。
这条最值钱 —— 它把「AI 做不了印刷品」这个结论直接推翻了。
踩过的坑:我把萬拾的 A 字堂画成了金色木质敞篷谷仓,连着错了三轮。真实建筑是深色锐利三角形,内嵌三个三角开口,完全不是一个东西。请柬上印脑补的场地,客人到现场会认不出来。
解法三件套:
1. 用真实照片当参考图:codex exec --image="真实照片.jpg" -- '提示词'
2. 在提示词里用几何语言复述建筑,不要指望模型看图就懂:
> "a SHARP DARK TRIANGLE, an A-frame, with nested triangular openings — one triangle high up and two lower, and a dark inverted triangle between them. It is NOT a golden barn, NOT an open timber frame."
3. 形容词无效,硬数字有效。说「叶子少一点」「稀疏一些」模型完全不理,改成:
> "EXACTLY EIGHT leaves — FOUR on the left stem, FOUR on the right. Count them before finishing."
这是这周最惨的教训。
名单页最初只存 localStorage,没有保存确认。川川把 236 个人全部打完分 —— 数据全丢。我翻了 Chrome 所有 profile(手写 snappy 解压读 leveldb)、Safari WebKit、微信 WebKit,一个字节都没捞回来,最后只从一张截图里救回 8 个分。
原话:「我全部的人都勾过的,只是你没有一个确认+存储的功能,所以数据全部都丢失了」
改造后的架构:
浏览器 ──POST──> nginx ──proxy──> 127.0.0.1:8801 (Python ThreadingHTTPServer)
↓
/var/lib/wedding/guests.json
(os.replace 原子写 + 按时间戳合并)
配套四件事,缺一不可:
· 可见的同步条:「已保存到云端 · 240/242 人已打分 · 最后同步 12:04」
· 改动行闪一下:让用户看见"这一下生效了"
· beforeunload + sendBeacon:关页面前把未推送的补上
· 手工值优先:云端合并时人填的永远盖过自动推的
原则固化:任何要用户投入劳动的界面,持久化和可见确认必须先于功能上线。
问题:回执填「张一」,被匹配到了 #24 Carina 张一杨,实际是 #143 人土土小妹(张一)。原因是循环按序号走,谁先包含这两个字算谁。
解法 —— 四级匹配,精确的永远先跑完:
1) 真实姓名完全相等 2) 微信名完全相等 3) 真实姓名互相包含 4) 微信名包含(最宽松,放最后)
外加一层人工认领表,机器搞不定的直接写死:
const RSVP_ALIAS = { '强老师':153, '张一':143, '豆豆':14, '表哥 表嫂':242, … };
匹配不上的不许猜 —— 全部列进「没匹配上」表,逐个问人。这周 25 条回执,问了 3 轮,最后 100% 对上号。
原来的回执用 1px GIF 打信标:rsvp.gif?d={"name":"张三",...},靠翻 nginx 日志收数据 —— 零后端,很聪明。
但加了手机号之后这条路必须废掉:明文手机号会落进服务器访问日志的 URL 里,日志会备份、会轮转、可能被别的程序读到。
改造:
| 姓名/人数/留言 | 手机号 | |
|---|---|---|
| 传输 | GIF 信标(保留做兜底) | POST 请求体 |
| 存储 | nginx 日志 + 接口 | /var/lib/wedding/rsvp.json |
| 读取 | 公开 | 必须带 token,否则 403 |
| 公开的 rsvp-data.json | 有 | 已剥离 |
永远不要一次生成全部。 帆布袋从戒指改到桉叶花环,中间迭代了 7 版;酒标先出 3 个概念再定 1 个。
配套两条:
· 每次交付附定量自评分 + 明确写出短板(酒标自评 87:印刷可用性 95、人物相似度 70、瓶身验证 60)
· 永不覆盖旧文件:新版本另存或归档,归档/、请柬存档/、小程序存档/ 都是这么来的
| # | 规矩 | 起因 |
|---|---|---|
| 1 | 产出必附链接,放回复开头 | 提了文件不给链接,等于没交付 |
| 2 | 先搜索再判断,不许自嗨 | 我凭直觉给婚礼游戏打分 → 「我让你去小红书搜索,别自嗨了,搜索条件就按互动量、阅读量」 |
| 3 | 是多少就多少,不许额外计算 | 我自己算了个「未分配 ¥8,611 超支」→ 「为啥超支了?是多少就多少不需要你额外计算」 |
| 4 | 不许把简单的事搞复杂 | 我追微信开发者工具 CLI 追了十几轮,上传按钮就在他工具栏上 |
| 5 | 改动只改被要求的,别自作主张 | 帆布袋「更简单和谐」被我理解成删元素,把两侧叶子改成了直线 → 「不喜欢,这个细节还原」 |
ccopc.cn 上线任何东西,四步一步不能少:
scripts/jargon-check.sh <文件> # 黑话检查,不过不让部署 scripts/deploy.sh <子路径> --dry-run # 先空跑 scripts/deploy.sh <子路径> # 真部署 # 验证:curl 200 + 本地 MD5 == 远程 MD5
MD5 比对是关键:curl 200 只能证明有东西,证明不了是新的那个。这周靠它抓到过缓存没刷新。
| 问题 | 状态 |
|---|---|
名单页密码还是 cc | 手机号入库了,但口令写在 JS 里,看源码就能拿到。要真锁上得换长口令 |
| 242 人里 234 人没分圈层 | 排桌的前提。建议先只分 5 分那批 |
| 小程序审核中 | 通过后还要手动点一次「发布」,微信不会替你做 |
| 小程序 web-view 改造 | 改成外壳装 H5,以后改内容不用重审。需要你在后台加业务域名 |
| 入席时间 | 已统一为 17:30(2026-08-09 川川定) |
| 酒标 5 项待酒庄填 | 葡萄品种 / 酒精度 / 生产商 / 地址电话 / SC 编号(没这个印出来是废的) |
1. 先定事实 场地真实照片 / 合同数字 / 时间地点 ← 一切的锚 2. 先搭回收 名单 + 打分 + 持久化 + 确认 ← 别让人白干活 3. 再做请柬 因为要先知道请谁、多少人 4. 边发边收 5分 → 4分 → 3分,看着容量往下放 5. 最后才印 人数定了才知道印多少
这周实际的顺序是 3 → 2 → 1 → 4,印刷和请柬都返过工。
这个项目真正的方法论只有一条:让机器做机器擅长的(生成画面、匹配名字、算容量),让人做人才能做的(认人、定调、拍板),中间用"可见的确认"和"真实的事实"把两边焊死。
出问题的每一次,都是这条被破坏了 —— 要么让 AI 猜了它不该猜的(脑补场地、猜谁是谁),要么让人干了活却没给他确认(236 个分丢了)。
← 回到内部筹备入口