大家好,我是羊仔,专注AI编程、智能体、AI工具。

今天带来一篇面向实战的AI编程,讲一个从零到交付的项目:书法课学生签到系统。

文章有点长,但耐心看完,相信你一定会有所收获。

图片

很多人觉得把软件交付到用户电脑上并一键运行是最难的那一步,羊仔想说:难,其实是因为我们没为「最后一公里」设计。

在这篇文章里,羊仔用一个真实项目——书法课学生签到系统,展示如何用AI开发,把功能做完整,把打包、端口、邮件配置和退出流程都打磨得用户友好,做到「解压即用、双击即跑、托盘可控」。

最重要的是,全程没写一行代码,没有任何技术门槛。

一、一堂课,一个系统,一个现实考验

一个偶然的机会和朋友聊起,书法班的老师希望记录学生的到课情况。

图片

最好能:

  • 快速维护学生信息:姓名、学号、校区、上课时间、星期几;

  • 每天按校区/时间查询当日班级、逐条签到;

  • 邮件通知,今后拓展短信或企业微信;

现实的考验来了:用户想要的是傻瓜式操作,像普通软件那样双击打开。

于是,这个需求变成了羊仔最在乎的事:能用、好用、易交付。

羊仔在电脑前沉思片刻,把这最后一公里拆成3件事:

1) 基于web开发,一次开发,电脑手机都能用,默认本地访问;

2) 打包成文件夹版,让用户能改配置文件,比如邮箱;

3) 做一个托盘驻留启动器,用户用右键菜单就能停止服务和打开网页。

功能 + 交付缺一不可,功能是产品的心脏,交付是产品的双脚。

二、功能效果:老师/家长真的会用

软件做好后效果如下:

1. 学生信息维护

  • 支持新增、编辑、删除

  • 校区枚举:避免用户随意填错

  • 时间选择器:type="time",避免手动输入格式错误

图片

2. 签到记录

  • 按日期、校区、星期几、时间筛选当日班级

图片

  • 一键签到,控制台模拟邮件发送,真实邮件可在配置里开启

图片

3. 交付与使用

  • 解压,双击 start.bat,系统自动在浏览器打开

图片

  • 托盘常驻,右键菜单:打开网页、停止服务(强制退出)、退出托盘

图片

  • stop.bat 也可一键结束服务,无需任务管理器

三、技术架构选型:稳、轻、易交付

了解一下,不懂也没关系:

  • 后端框架:Flask

    轻量、易上手、生态丰富

  • 数据库:SQLite(本地 database.db)

    免安装、适合轻量场景

  • 打包:PyInstaller(文件夹版)

    内置依赖、保留 templates/static/config.py

  • 托盘:pystray + Pillow(托盘图标与菜单)

    独立 tray_helper.exe,start.bat 启动服务同时启动托盘

  • 前端:Jinja2 模板 + Bootstrap

    简洁易用,用户学习成本低

图片

四、干货!手把手开发教程

羊仔和AI边聊边做,从需求澄清、到代码改动、到打包交付,每一步都有对话、有选择、有坑,但不用写一行代码。

希望你读完后,能在自己和AI的合作里,找到合适的姿势。

1. 最初的朴素请求

朋友的想法非常直接:

“我想有个简单的小网站,可以录学生信息、点签到、家长能收到通知邮件。”

听起来挺标准的管理后台型需求,于是我最开始的反应是:

“OK,那就 Spring Boot 起个服务,前后台分离,接口设计 RESTful……”

结果一句话把对方整懵了。

“我只想双击就能用啊。”

他不是技术人,只想用得安心,那种需要装 JDK、跑 Maven、连数据库、再开前后端端口的架构,对他来说太重了。

2. 需求确认的真正意义

我们技术人经常掉的坑就是——从技术出发,而不是从需求出发

我重新问他几个实际使用问题:

  • 你要多人同时使用吗?

  • 数据量会很大吗?

  • 有没有对外网访问的要求?

得到的答案是:

“五六个人用。几十个学生。能本地用、能发邮件通知最好。”

于是,所有过度设计的需求立刻烟消云散。

核心问题变成了:

怎样本地、易用、可维护。

3. 与AI决策

需求是重中之重!

羊仔整理了一份「AI编程需求专家」提示词,免费分享给大家,它会采用反问法补全信息,然后生成完整、规范的需求文档,省时省力!如果你需要的话,欢迎加羊仔微信(yangzaiai666)领取。

我把项目需求告诉GPT-5,当然你也可以用别的模型,比如Kimi等。

它先是反问我,让我补全确认一些问题:

图片

确认后,立马给出了完整的需求文档,包括完整的功能清单、技术选型,甚至表结构、接口都设计好了。

图片

这是我突然发现,技术选型需要修改,它给出的设计太重了。

图片

于是我们决定不前后端分离,采用一体化方案

AI列出几个技术方案:

图片

结果一眼定音:Flask

图片

一句命令跑起来,
一个 app.py 管到底,
一个 .db 文件干净保存所有数据。

不再有启动前端服务器的焦虑,也不用担心数据库没密码。

简单、优雅、足够用。

AI重新写了《Flask一体化签到系统需求说明》,中心思想只有一句话:

让用户不需要懂技术,也能上手用上系统。

图片

新建一个md文档,把这份需求复制进去,放在工程目录里,比如studentsign目录下。

4. 借助AI,光速开发

AI编程工具,现在有很多选择,像ClaudeCode、Cursor、Trae、Codex等等都可以,各有所长,羊仔这次用的是CodeBuddy,可以免费用GPT-5。

图片

用CodeBuddy打开studentsign目录,直接告诉AI:请根据需求说明生成完整可执行 Python 代码项目。

图片

很快几分钟就生成好了一整套可运行的代码:

图片

遇到第一坑:Windows上“python”是占位符,“python -V”命令执行没任何输出。

AI经过诊断后发现:这是 WindowsApp 的占位符问题。

统一使用“py”命令,先安装依赖,然后用 py 启动程序就行。

# 安装依赖
py -3 -m pip install -r requirements.txt# 开发模式启动,输出更详细
py -3 -X dev -u app.py

当浏览器成功打开 http://127.0.0.1:5000 的那刻,羊仔的焦虑掉了一半。

5. 交互优化

项目能跑后,开始优化交互与校验。

羊仔:校区是枚举值校区一、校区二,时间不能手输,要选时间。

AI:后端加枚举校验,前端把“校区”做下拉;时间用原生 time 选择器。

图片

这一段有个小插曲:羊仔刷新页面,还是看到时间输入框,而不是时间选择器。直接把问题扔给它。

AI判断:模板未热更新或服务没重启。于是开启模板自动重载,重启服务,并在页面地址加版本参数破缓存。

羊仔访问 http://127.0.0.1:5000/attendance?v=3 后,确实变成了时间选择器。

图片

6. 端口与打包策略:设计最后一公里

羊仔:端口5000冷门一点,避免被占用,就用5000吧;打包采用文件夹版,因为还要让客户自己配邮箱。

AI:同意。端口默认 5000,打包用 PyInstaller 文件夹版,把 templates/static/config.py 也带上,便于客户编辑配置。

打包命令(文件夹版):

# 清理旧产物if (Test-Path dist) { Remove-Item -Recurse -Force dist }if (Test-Path build) { Remove-Item -Recurse -Force build }if (Test-Path .\studentsign.spec) { Remove-Item -Force .\studentsign.spec }# 重新打包,内嵌模板与静态资源、配置py -3 -m PyInstaller --clean --noconfirm --noconsole `  --name studentsign `  --distpath dist --workpath build --specpath . `  --collect-all flask --collect-all flask_sqlalchemy --collect-all flask_mail `  --add-data "templates;templates" `  --add-data "static;static" `  --add-data "config.py;."  app.py

打包过程中,羊仔又踩了一个坑:dist\studentsign\instance\database.db 被占用导致清理失败。

AI提醒:先Stop-Process一键结束正在运行的进程,再清理重打包,顺利生成。

7. 托盘驻留:用户体验的加分项

这时候还没有推盘图标,想要结束程序需要到任务管理器里手动结束,很麻烦。

图片

让AI继续修改,它用 pystray 做托盘,Pillow 处理图标,单独做 tray_helper.exe,start.bat 同时启动服务与托盘。

当然这些技术细节都不用关心,AI都会帮你处理好。

图片

托盘菜单设计:打开网页、停止服务。

羊仔第一次用右键【停止服务】那一刻,自己很满意:这才是用户期待的交互。

8. 邮件安全配置:隐私留在用户手里

羊仔测试时填了自己的邮箱,交付前要清理。

AI:把发行包里的配置设为安全默认(ENABLE_MAIL=False),让用户自行开启与填写;源代码的 config.py 同样留空敏感项。

安全默认(片段):

config.py(发行包内)
ENABLE_MAIL = FalseMAIL_SERVER = ""MAIL_PORT = 0MAIL_USE_TLS = FalseMAIL_USERNAME = ""MAIL_PASSWORD = ""

同时在交付说明里明确告诉用户邮箱配置的详细步骤,当然这也是AI生成的:

图片

五、与AI协作的节奏

和AI一起开发,有几个关键节奏:

  • 需求颗粒度要小:一次只推进一个明确目标(端口、时间控件、打包、托盘、退出)。

  • 多用“读/改/验证”的闭环:先读取文件确认,再修改,再立即验证(浏览器、日志、页面源代码)。

  • 对话要有证据:让AI看到真实的终端输出或页面源代码,避免“猜测式修复”。

情绪上,羊仔其实也有焦虑:时间紧、细节多。

每当卡住,用 AI 的建议做一次最小验证,就能继续前进。

那种人机协作的流畅,是我们在新时代里最值得拥抱的力量。

六、真实交付体验,故事延续

把打包好的 studentsign.zip 文件发给用户,告诉电话那头的用户试着双击 start.bat。

听到那句“网页自动打开了”的惊喜,比把一堆功能讲得天花乱坠更有说服力。

羊仔终于松了口气:不是把技术塞进去,而是把技术变成实用的工具。

七、后续计划:让系统更懂班级

借助AI编程,原本看起来很难的功能,也变得很轻松,后续打算继续和AI一起完善:

  • 多账号与权限:老师、助教、家长不同权限;家长端只查看孩子签到情况。

  • 更丰富的通知:短信/企业微信/飞书机器人,统一抽象通知层。

  • 数据导出与统计:班级到课率、迟到统计、可视化图表。

  • 无后台自更新:后续考虑自动检查更新并增量替换(保持一键启动体验)。

八、羊仔说

羊仔想分享的不是技术有多炫,而是在AI的加持下,交付的细节如何让用户安心。

当一套系统能被非技术用户自然使用,技术的温度才会真正被感知。

愿这篇文章让更多开发者在最后一公里上发力,把好用的工具交到真正需要的人手里。

共勉!

欢迎关注羊仔,一起探索AI,成为超级个体!

如果你喜欢这篇文章,不妨点赞,在看,转发。

你的每一次互动,对羊仔来说都是莫大的鼓励。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐