DSI转来一份报价单:Software Asset Management,年费数千欧元。功能清单看完,作者决定自己写——PyQt5桌面应用,本地SQLite,100%离线运行。
这就是LiMa(License Manager)的诞生场景。不是反对SaaS,而是发现有些需求被过度包装了:一张存到期日的表,一个定时刷新的计算器,一层按天数触发通知的逻辑。核心代码不到200行。
第一块:动态计算,拒绝脏数据
表结构极简,两列:软件名、到期日。没有"剩余天数"字段——那个数字是算出来的,不是存进去的。
Python里一行减法:(date_expiration - datetime.now()).days。QTimer每分钟触发一次刷新,界面实时更新。早期版本设成1秒刷新一次,后来改成60秒:日期不会变得更快,省点资源。
行颜色跟着天数变,红阈值可配。没有后台任务写数据库,没有同步冲突要处理。
第二块:原生通知,分层提醒
plyer库调系统级通知。30天、14天、7天、3天、1天、过期,六级阈值,硬编码的if-elif链。没有"智能降噪算法",就是到点就弹。
作者坦承:SaaS的"smart alerting"可能更精致,但对于"别让我忘记续费"这个需求,分层硬规则够用。
第三块:月度邮件,SMTP直发
到期日汇总表,HTML表格渲染,smtplib投递。密码走系统keyring,不落地代码。定时用APScheduler,不是cron——Windows机器上cron不够原生。
邮件内容就是当前界面的快照,没有额外报表设计。
两年后的技术债
作者现在会换技术栈:PyQt6替代PyQt5,SQLAlchemy替代裸sqlite3,keyring标准化凭证管理。但核心设计不变——本地优先、计算派生、能省则省。
LiMa的启示在于边界判断:当SaaS的功能拆解后是"数据库+定时器+通知API",而你的团队有基础开发能力时,订阅费买的到底是功能,还是"不用自己维护"的安心感?
后者有时值这个价。但作者认为,至少值得先算一笔账:几百行代码 vs 每年 recurring 支出,维护成本 vs 供应商锁定,再做决定。
热门跟贴