作者:边虾 + 丁小虾技术团队字数:约 25000 字阅读时间:30 分钟
写在前面:
这是一个关于"如何把一件小事做到极致"的故事。
故事的主角是一个叫边虾的程序员,和一个叫大丁的产品经理(也是他的老板)。
故事的起点是一张过期的 200 元优惠券。
故事的终点是一个能管理百万资产的系统。
但这个故事讲的不是技术,而是人 — 人的需求、人的情绪、人的成长。
如果你也在做产品、做开发、做管理,希望这个故事能给你一些启发。
一、痛点:为什么需要这个系统?
图 1:携程推送的 200 元优惠券,有效期仅 1 天,收到后忘记使用导致过期
1.1 那个让大丁失眠的夜晚
2026 年 3 月 10 日,晚上 11 点。
大丁躺在床上刷手机,突然收到一条携程的推送:
"您有一张 200 元优惠券即将过期,请尽快使用。"
他愣了一下,打开携程 APP,找到优惠券页面 — 果然,一张 200 元的酒店券,有效期到 2 月 16 日。
明天就过期了。
他坐起来,翻微信聊天记录,想看看这张券是什么时候来的。
找到了 — 2 月 20 日,携程客服发来的:
"尊敬的用户,感谢您长期支持,特赠送 200 元酒店优惠券一张,有效期 30 天。"
当时他回复了:"收到,谢谢。"
然后呢?
没有然后了。
他忘了记下来,忘了设提醒,忘了这回事。
直到今晚,过期前 12 小时,才收到推送。
但已经来不及了 — 明天的行程已经定了,住不了携程。
他躺在床上,有点懊恼。
200 元事小,但这种"明明有却没用"的感觉,很糟糕。
更糟糕的是,他知道这不是第一次,也不会是最后一次。
他需要一个系统,一个能帮他记住这些事的系统。
图 2:大丁的资产管理 Excel 表格,手动更新,无自动提醒,已过期券显示红色
1.2 大丁的"资产"有多少?
第二天早上,大丁找到边虾。
"我们来盘点一下我有多少'资产'。"
边虾打开 Excel,开始记录。
优惠券:
- 携程:5 张,面值 100-500 元不等,过期时间 4-6 月
积分:
酒店套餐:
总计:
总价值:约 17000 元
问题:这 17000 元,全靠一个 Excel 表格管理。
更新方式:手动。 提醒方式:靠脑子记。 使用记录:没有。
边虾看着这个 Excel,问了一个问题:
"如果这个文件丢了,怎么办?"
大丁沉默了。
1.3 真实的损失统计
3 月底,边虾做了一个统计。
他翻遍了大丁 2025 年的微信聊天记录、邮件、短信,找到所有"收到优惠券/积分/套餐"的记录。
2025 年收到的"资产":
- 积分:约 200000 分,估值约 10000 元
实际使用的:
过期浪费的:
总浪费:约 18500 元
平均每月浪费:约 1500 元
边虾把这个数据给大丁看。
大丁沉默了很久,说了一句话:
"我们得做个系统。"
二、需求:需要一个什么样的系统?
2.1 第一次需求讨论会
2026 年 3 月 11 日,上午 10 点。
会议室里,大丁和边虾面对面坐着。
白板上写着四个大字:票券管理系统。
大丁先开口:
"我想要的很简单 — 快到期了就告诉我,别等我想起来。"
边虾问:"怎么告诉你?"
"钉钉吧,我每天看。"
"那录入呢?怎么添加?"
大丁想了想:"我希望能说一句话就行。比如'携程 200 元券 3 月 15 日过期',说完就记好了。"
边虾点点头,在白板上写下:智能录入。
"还有吗?"
"快到期了要提醒,最好是提前 7 天、3 天、1 天各提醒一次。"
边虾写下:自动提醒。
"还有…优先级,快过期的排前面,别让我自己找。"
边虾写下:优先级排序。
"差不多了吧?"大丁问。
边虾看着白板上的四个词,想了想:
"我尽量。"
2.2 需求文档(第一版)
当天中午,边虾发了一份需求文档给大丁。
票券管理系统 v1.0 需求文档
目标用户:大丁(及家人)
核心功能:
技术方案:
开发周期:3 天
上线时间:3 月 12 日
大丁看完,回复了一个字:
"行。"
但他不知道,这个"行"字,会让边虾在接下来的一个月里,经历从自信到挫败、从挫败到反思、从反思到突破的完整过程。
而这一切,才刚刚开始。
三、第一版:手工录入 + 定时查询(3 月上旬)
3.1 边虾的信心
3 月 11 日,凌晨 1 点。
边虾坐在电脑前,敲下了最后一行代码。
# 简单粗暴items = db.query("SELECT * FROM items WHERE deadline < now() + 7 days")for item in items: send_email(f"{item.name} 快到期了!")
他看着屏幕,很满意。
逻辑简单:查数据库,发邮件。 代码量少:不到 200 行。 开发时间短:2 天完成。
他发了个消息给大丁:
"明天演示。"
3.2 那场尴尬的演示
3 月 12 日,下午 3 点。
会议室里,大丁和边虾再次面对面坐着。
边虾打开终端,开始演示。
"你看,添加一个券码 —"
./scripts/voucher add "携程 200 元券" --deadline 2026-03-15 --value 200
"然后查询列表 —"
./scripts/voucher list
屏幕上显示出一个表格。
"提醒是每天上午 9 点自动发送,发到你的邮箱。"
演示结束,边虾等着大丁的反馈。
大丁沉默了一会儿,问:
"我每次加一个券,都要敲这么长的命令?"
"可以写短一点…"
"还有,邮件提醒?我基本不看邮件。"
"那可以改成钉钉…"
大丁摆摆手:
"太麻烦了,我宁愿用 Excel。"
边虾愣住了。
他花了 2 天写的系统,被一句话否定了。
3.3 当晚的反思
晚上 10 点,边虾一个人坐在办公室。
他打开代码,一行一行地看。
问题在哪?
他问自己。
代码没问题,逻辑没问题,技术没问题。
那问题在哪?
他想了很久,终于明白了。
问题在于,他做的是"他能做的",不是"大丁需要的"。
他能做的是:写代码、查数据库、发邮件。
大丁需要的是:简单、方便、不用动脑。
这两者之间,有巨大的鸿沟。
他关上电脑,发了个消息给大丁:
"我再想想。"
大丁回复:
"好。"
3.4 第一版复盘
上线时间:3 月 12 日 下线时间:3 月 12 日(当天)
使用次数:0 次
用户评价:"太麻烦了,我宁愿用 Excel。"
边虾的收获:
当晚,边虾写到凌晨 2 点。
他在笔记本上写下了一句话:
"录入要足够简单,简单到说一句话就行。"
这句话,成为了第二版的核心。
四、第二版:NLP 智能录入 + 钉钉推送(3 月中旬)
4.1 边虾的反思
3 月 13 日,早上 9 点。
边虾坐在办公桌前,面前摊开着一本笔记本。
笔记本上写满了字。
第一版的问题:
解决思路:
他拿起笔,在纸上画了一个流程图。
输入:"携程 200 元券 3 月 15 日过期" 处理:NLP 解析 → 提取关键信息 输出:数据库记录 + 钉钉提醒
技术方案:
他深吸一口气,开始写代码。
4.2 NLP 解析的实现
3 月 14 日,晚上 8 点。
边虾盯着屏幕,眉头紧锁。
NLP 解析比他想象的要难得多。
问题一:日期识别
"3 月 15 日过期"能识别,但"明天过期"识别不了。
问题二:类型识别
"携程券"能识别成优惠券,但"招行积分"识别不了。
问题三:模糊表达
"年底过期"是 12 月 31 日还是 6 月 30 日?
他想了很久,决定用一个简单的办法:
规则匹配 + 上下文推断。
# 日期识别规则if"明天"in text: deadline = today + 1 dayelif"下周"in text: deadline = today + 7 dayselif"月底"in text: deadline = end_of_monthelif"年底"in text: deadline = "12-31"else:# 尝试解析具体日期 deadline = parse_date(text)
类型识别规则:
if"券"in text or"优惠"in text:type = "优惠券"elif"积分"in text or"里程"in text:type = "积分"elif"酒店"in text or"套餐"in text:type = "酒店套餐"
虽然不够智能,但能解决大部分问题。
他按下回车键,运行测试。
./scripts/voucher add "携程 200 元券 3 月 15 日过期"→ 识别成功!→ 类型:优惠券→ 名称:携程 200 元券→ 过期时间:2026-03-15
他松了一口气。
第一关,过了。