~ / tech / projects / nfc-collectibles
nfc-collectibles/index.mdx
cat index.mdx
🔧

数字藏品系统 · NFC Collectibles

给国学社文创做的身份管理系统。每一件实物——NFC钥匙扣、线装书、明信片——都能在这里找到自己的数字身份,带校验码,可溯源。

status: ● Active
date: 2025-09
category: tool
Flask PostgreSQL NFC Vercel 文创
README.md

这个项目是什么

国学社这些年做了不少文创:黑胶唱片 NFC 钥匙扣、《南洋精选集》线装古籍、社员诗歌明信片——种类越来越多,但一直缺一个东西:怎么证明你手里这个是「正品第 N 号」?

这个系统就是干这个的。每件藏品在生产时会生成一个唯一的 8 位校验码,和实物绑定。用户拿到藏品后,通过手机号或校验码就能在线查到自己持有的是哪一件、第几号。NFC 钥匙扣更直接——碰一下手机就跳转到对应的查询页。

线上地址是 cang.sjtuguoxue.space,目前管理着三条产品线的藏品数据。

为什么做这个

灵感有一部分来自 Web3 那套数字藏品的叙事——每件东西都有唯一标识、可以溯源。但我们不需要区块链那套重型基础设施,国学社的文创是真实的线下实物,需要的只是一个轻量的系统把「数字身份」和「物理实体」连起来。

NFC 是一个有意思的选择。第一款产品是黑胶唱片造型的钥匙扣,碰一下手机就能打开网易云的社团歌单。这个载体上不应该出现二维码——那会破坏它作为一件「藏品」的质感。NFC 芯片藏在里面,干净,也更有仪式感。

后来《南洋精选集》线装书出来了,240 册限量——「南洋」取自上海交大的前身南洋公学。线装古籍,筒子页,单册成本 35 元,在社团经费里算是很重的投入。这么贵的东西,每本书得有自己的编号和校验码,贴在内封底,扫码就能验。于是这个系统从「给钥匙扣用的小工具」,变成了整个文创产品线的身份基础设施。

我做了什么

技术上很直接:Flask 写后端,PostgreSQL 存数据,部署在 Vercel 上。

核心功能三件套:

  • 藏品注册:线下活动时,工作人员选择产品型号、输入买家手机号、填邀请码,系统自动分配编号和校验码。校验码是 MD5 后 8 位——不优雅,但够用。
  • 藏品查询:用户凭手机号或校验码查自己的藏品,能看到产品名、编号、出品信息。NFC 钥匙扣直接碰手机跳转到查询结果。
  • 明信片档案查询:这条产品线比较特殊。社员诗歌明信片从 2021 年做到现在,20 多套、200 多款、流通超过 8000 张,每张都有自己的编码(年份+属性+套号+天干排序的套内号)。输入编码就能查到这张明信片上印的是哪首诗、谁写的、什么时候印的。如果有关联的诗歌图片,还会通过阿里云 CDN 签名 URL 展示出来。

关于邀请码——用了一组简单的固定码,印在工作手册上。目的很务实:不希望随便谁打开注册页就能注册藏品,但线下活动时工作人员是流动的,需要一个学习成本最低的方案。几个邀请码往手册上一印,谁都能用,但外人不知道。不算优雅,但解决了问题。

还有一个 admin 后台,做藏品数据的 CRUD 管理。以及一个标签生成脚本——给 240 册《南洋精选集》批量生成 A4 标签贴纸,每张贴纸上有 QR 码、编号和校验码,印出来贴在内封底。这算是从数字系统延伸到实物生产管理的一小步。

过程中的思考

这个项目最早是 vibe coding 出来的。PRD 写了两版,v1 只有 NFC 钥匙扣一个产品,v2 加了明信片查询,后面又加了线装书。每次有新产品线,就往上堆一层功能,没有做过大的架构调整。

有一次比较关键的迁移:从主站服务器搬到 Vercel。国学社主站跑在一台 2 核 2G 的云服务器上,资源本来就紧张,藏品系统挂在上面抢资源不太合适。迁移到 Vercel 的时机刚好和《南洋精选集》的上线同步——数据也从 CSV 文件迁到了 Vercel Postgres。写了个一次性迁移脚本,把 registered.csv明信片档案册.csv 导进数据库,之后就再也没碰过 CSV 了。

说实话,这个系统在整个国学社的生态里算是比较不温不火的角色。没加埋点,没做过数据分析,也没怎么操心维护。但我觉得它的价值会随着文创产品线的丰富慢慢浮现——当社团有了十几二十种不同的文创产品、每种都有编号可查的时候,这套基础设施就会变得不可或缺。现在算是在「种」的阶段。

Q&A

Q: 为什么不直接用二维码,非要上 NFC?

因为第一款产品是黑胶唱片造型的钥匙扣。你想象一下,一个精致的小唱片上印着一个黑白方块——那太破坏美感了。NFC 芯片藏在里面,表面什么都不用印,碰一下手机就跳出来。这个「碰一下」的交互本身也更有藏品的感觉,比「扫一下」高级一点。当然后面的线装书就用了 QR 码贴纸,因为书的内封底本来就是信息区,二维码放在那里很自然。

Q: 校验码用 MD5 后 8 位,不怕碰撞吗?

理论上 8 位十六进制有 4 亿多种组合,而我们的藏品总量撑死几千件。实际上在生成《南洋精选集》240 个校验码的时候,脚本里确实加了碰撞检测——跑完没报警,所以就用了。这个方案的核心目标不是密码学安全,而是给每件藏品一个人类可读的短标识。如果真的要防伪造,应该换一套签名方案,但目前这个场景下没必要。

Q: 社员诗歌明信片的编码系统是怎么设计的?

这套编码比藏品系统本身的历史还长。格式是「两位年份 + 一位属性代码 + 三位套号 + 天干」,比如 24A014甲 就是 2024 年个人专辑第 14 套的第一张。属性代码有六种:C 庆典、G 诗会社课、R 日常创作、A 个人专辑、S 特别主题、L 联动。套号是全局自增的,不按年份也不按属性清零。套内号用甲乙丙丁而不是 1234——毕竟是国学社,得有这个味道。

Q: 这个系统最大的局限是什么?

没有用户账号体系。现在的逻辑是:你买了藏品,工作人员帮你注册,绑定你的手机号,之后你凭手机号查询。这意味着如果你换了手机号,就查不到了。而且手机号作为唯一凭证,隐私保护也做得很粗糙——虽然查询结果里做了脱敏(中间四位打星号),但理想情况下应该有一个独立的用户 ID。不过对于一个社团内部的小系统来说,这个方案的简单性就是它最大的优点。

Q: 如果给你无限资源,这个系统你会做成什么样?

大概会做成一个完整的「文创护照」:每个社员有自己的收藏页,可以看到自己拥有的所有文创,每件的故事、来历、编号。明信片能翻看正面的诗和图,线装书能预览内页。再往远了说,也许可以和社团的其他系统打通——比如你参加了某次社课,社课的诗会明信片自动关联到你的收藏里。但现在嘛,先让每件东西都有自己的数字身份就够了。

cd .. · ← back to tech
~ — press / to open terminal