Vibe Coding:个人车辆管理系统

车主们如果用车上了年头,就会意识到车辆的很多部件其实是“耗材”,需要定期维修、更换,比如电瓶,空气滤、雨刮器等。有一些更事关安全,比如轮胎、刹车片。如果每次维修都在4S店,那么4S店通常会提供一个小程序,记录每次维修的明细,那倒也挺方便,然而4S店太贵了,同一个部件通常是正常市场价格的3-4倍,在经济下行的时代实在玩不起。

如果车在4S以外的地方维修、保养,那一个问题立即出现了:我们缺乏一个统一的管理车辆维修信息的工具。有些部件寿命较长,比如轮胎的寿命通常在6-8万公里,在汽修店告诉你“这个轮胎要换了”的时候,你可能想知道“现在这个轮胎已经用了多久”?汽修店有时候也会忽悠顾客,火花塞明明好好的,他却建议你更换,你如果记忆模糊“上次在哪儿换的?什么时候换的?”就很容易上当。

我原本以为,这么普遍的需求,Github上一定有好用的开源工具吧。然而找来找去,看上去还行的只有一个LubeLogger,安装倒是简单,但使用起来着实一言难尽。它有一种“传统”工具的通病:大而全,而且过于关注费用,用起来心理压力很大,试了一下很快放弃了。

看来只好亲自动手,来吧,继续Vibe Coding。

在动手之前,首先要在脑海中想清楚需求是什么,页面长什么样,彼此之间的逻辑是什么。总体并不复杂,但真正的含金量是“恰如其分、符合常识”。

经过几天的思考,感觉已经比较成熟,恰逢gpt-5.1-codex-max发布,于是开始第二次的Vide Coding之旅。下面我把过程中的Prompt分享出来,这样可以让从来没有进行过“氛围编程”的小伙伴们有一个直观的感受。我使用的是CLI模式,也就是本地模式,然后手动将文件上传到VPS上进行部署验证。

1、第1条Prompt

数据库:
采用SQlite,用php自动初始化
1、用户注册系统:用户表
2、车辆表,对应不同的用户,车牌号为必须
3、车辆基本信息表,对应车辆表中不同的车辆,包括:车牌号,车主姓名,购买时间,电车/油车,当前行驶总里程,备注(可选,用来填写车辆其他信息)
4、车辆部件表,对应每辆车,用户可以自定义:部件名称,预计寿命-里程(可选),预计寿命-时间(可选),备注(可选,用来描述部件是干什么的等等)
5、部件换新信息表,对应每辆车的每个部件,包括换新时间,维修地点,维修价格,预计寿命-里程(可选),预计寿命-时间(可选),备注(可选,用于描述这一次维修的其他信息)
6、注意,保养也可以算作一种“部件”,可以称之为“机油”
页面:
1、登录页,注意带有cookie功能,除非用户手动清除cookie,否则cookie永久有效。
2、注册页,第一个用户自动成为管理员
3、用户管理页,只有管理员有权限访问。只需要简单列出当前所有用户及每个用户名下的车辆
4、“我的车辆”页面,注册用户登录后首先显示此页。罗列用户名下的所有车辆,点击进入具体车辆首页。每辆车下方提供编辑按钮,点击进入具体车辆的基本信息编辑页。在已有车辆后提供+号,点击进入新车辆登记页。该页面也提供“退出登录”按钮。如果是管理员,提供“用户一览”链接,点击进入“用户管理页”。
5、新车辆登记页,这个页面兼作车辆基本信息编辑页。
6、车辆首页。这个是核心页面,用户的主要操作都在这里。
首先显示当前车辆,属于那个用户,车辆的基本信息。给一个编辑按钮打开该车辆基本信息编辑页。
该页面提供一个返回按钮以返回到“我的车辆”页面。提供“退出登录”按钮,用户可以直接退出登录清除cookie到登录页。
然后给出一个里程更新的模块,用户可以直接在这里更新当前车辆已经行驶的总里程。
然后读取车辆部件表显示出来。
第一列是部件名称,注意,当部件带有预计寿命时,部件名称后面括号写上寿命,前面显示一个竖向的色条,计算上次换新的日期与当前日期的差值,看看预期寿命还剩下多少,如果还有挺长时间,就显示为绿色,如果已经还剩1/4了,那就显示为橙色,如果只剩下1/10,则显示为红色。点击部件的名称可以进入部件属性编辑页。
第二列是上次换新的时间、价格、地点。也是超链接,点击进入部件换新信息修改页。
第三列是添加换新记录的操作按钮,点击进入部件换新信息登记页。
7、部件换新信息登记页。每次登记都在部件换新信息表中添加一个换新记录。注意,添加的预计寿命-里程(可选),预计寿命-时间(可选)这两项如果有,在添加到部件换新信息表中的同时,也要添加到车辆部件表中。该页面兼做部件换新信息修改页。
8、部件属性编辑页:用于修改部件的名称、两个预计寿命和备注。

第1条Prompt是非常重要的。由于此时啥文件都没有,你需要清晰地描述出整个构架,并用尽量准确的语言描述各个页面之间的关系。Prompt分为两部分,第一部分描述了数据库的结构,并要求AI提供一个php来自动创建数据库文件。第二部分则是各个页面和功能描述。

2、第2条Prompt

文件直接写入I:\Codex\cars
我稍后会在vps上部署它,而不是在本地运行它,所以你不用添加“在本地端口8000监听”这样的设置。
另外,为什么只有一个index.php?我明明要求了N个页面。
数据库初始化的php显然也应该是单独文件吧。因为我只会用它一次啊。

第一条我的失误在于,没有明确要求它直接在本地把文件创建出来,所以它只是在上下文窗口中列出了代码。于是我明确要求它,别怕,大胆地把你的文件写出来!然后又明确要求它,单独创建一个php文件用来创建数据库。

效果令人惊讶,Codex立即创建了18个php。我将文件部署到VPS,执行init_db.php,成功创建了一个SQlite数据库文件data\app.db。用SQLiteStudio打开一看,数据库创建完全正确。

此时的系统已经可以使用了,虽然界面很原始。

3、第3条Prompt

这是一个个人车辆信息管理系统,现在已经能用了。它的数据库使用的sqlite,位置为data/app.db,目前的具体结构请看init_db.php。
1、在service_form.php中,无论是编辑记录模式,还是添加新记录,都需要增加一项:维修时里程。这一项数据保存在部件换新信息表中。
2、为了第1条的目的,需要新建一个update_db.php,在数据库data\app.db中的part_services表结构中增加一列。之后我会单独执行update_db.php来对数据库结构进行更新。
3、在part_form.php页,需要显示出当前部件的最近一次换新信息中的日期和维修时里程,以及与车辆信息表的最新里程、当前日期。

进一步的测试发现,之前第1个Prompt还是有一个疏忽,忘记在添加部件维护信息时,应该同时添加对应维修时的里程。这是个关键数值,没有它就无法评估部件的剩余寿命。于是我要求Codex帮我生成一个update_db.php,在数据库中添加一列。同时对part_form.php进行相应修改。

4、第4条Prompt

非常好,it works well。
接下来,要优化一下vehicle.php。最下面的部件信息表,增加一列用来指示该部件的剩余寿命。由于寿命涉及到里程寿命和时间寿命,所以这一列中应该有两个横向指示条,一个前面是字母D,表示Distance;一个前面是字母T,表示Time。这个指示条的样式,我初步的想法是,一个灰色的底色,上面是较深的颜色,如果寿命还比较长,那么上面是绿色,如果寿命较短了,那上面就是橙色,如果寿命接近用尽,那么上面就是红色。

修改一次成功。我对Codex的表现给予了鼓励。接下来是一个核心的功能,即以直观的方式显示部件的剩余寿命。这里涉及到里程寿命和时间寿命,具体如何表达,我在输入这一条Prompt的时候才想的比较清晰。Codex准确地把握了我的意图,对vehicle.php文件进行了修改。

又进行一番测试,我发现所有的功能均已经符合预期。

5、第5、6条Prompt

第5条:好,非常棒!下面是考验你的审美的时候啦。 现在的所有页面都非常朴素,甚至可以说很丑。请逐个将它们修改成现代化的风格,并以适配手机界面为主。 当然,在修改成手机界面适配时,也要确保在PC上具有较好的操作性。
第6条:还有待进一步完善。
vehicle.php这个页面,由于信息量比较大,在手机上显示有较多问题。进一步修改:
1、“编辑车辆信息”这个按钮,可以直接与最前面的车牌号合二为一。“返回”可以删除,因为点击顶部的“我的车辆”也是一样的。
2、顶部菜单在手机上换行了,想办法再紧凑一点。这些不属于最常使用的功能,其实字体可以小一点的。 3、车辆信息,备注的字体完全可以小一点,可以与购车日期那个字体一致。 4、更新里程这个地方,里程这个框可以和“保存”按钮放在同一行嘛! 5、然后是下面最主要的部件信息表,四列横着在屏幕上溢出了。每个部件不一定一行,可以两行甚至3行嘛,不然手机上看太不方便了。

这两条主要是为网页增加样式。实际上第5条之后,它就已经做到了完美适配手机,并拿出了一套让我非常满意的style。第6条只是一些细节上的修改。

6、第7条Prompt

好。样式有了很大改善。但我发现一个逻辑上的问题。 部件寿命如果已经过期,它显然应该显示为红色,部件名称前面也应该是红色。
当前逻辑有点缺陷: 1、当剩余寿命大于0,但已经较少或非常少时,部件前面的那个小指示条的颜色也要跟着进度条变啊。小指示条的颜色,应该取D和T的(相对寿命更少的颜色)。
2、当剩余寿命小于0,等于已经过期,无论是里程还是时间寿命,这时候部件名称前面的小指示条当然是红色啦。

这时候我已经把一辆车的真实数据全部输入进去了,结果发现了一个小小的bug,当部件实际上已经过期时,显示不正确。于是要求Codex修改。

7、第8、9条Prompt

第8条:很好,修改正确。
还有一点,系统中所有页面的按钮,都太大了。在手机上和PC上都看上去太大。
第9条:vehicle.php: 1、页面顶部,备注下面那个当前里程似乎没必要显示,因为更新里程的那里其实已经显示了当前里程。 2、更新里程的输入框可以再短一点。里程数再怎么也不会超过100万的,没必要那么长。而且,“保存”里程按钮为什么和输入框不对齐?(当它们在同一行的时候)

继续调整页面细节。

8、第10条Prompt

这是一个个人车辆管理系统。具体功能结构详见“说明.txt”
现在需要对part_form.php页面进行修改,在下面增加一个表,显示该部件的历次维修记录,每页显示10个记录,超过的话自动分页。
注意风格样式保持一致。

在使用过程中,我意识到一个功能上的缺陷:没有一个地方可以显示部件维修历史,目前只显示最近一次。于是要求Codex在part_form.php页面上增加一个维修历史表。

9、第11条Prompt

part_form.php下面的维修记录表格需要调整。
1、每个记录一行,在手机上显示不理想。显示的方式和风格可以参考vehicle.php中对维修记录的显示方式。
2、在part_form.php中每个记录里,除了“编辑”按钮之外,再加上一个“删除”按钮。用来防止用户误操作。

把玩了一个晚上,突然意识到,“增删改查”,似乎缺少了“删”的功能。这个系统实际上不需要“查”,但“删”肯定是需要的。那么,是否要对每张表都提供删除功能呢?并不是的。车辆不需要删除,因为个人一般不会管理大量车辆,一辆车即使不用了,留在系统里也没有坏处。部件表也不需要删除,因为部件是客观存在的。如果名称写错了,也可以编辑它。所以,只需要对维修记录提供删除功能。

我觉得,类似这样的思考是非常重要的。

10、增加PWA

将上线的网站发给朋友,朋友说:能不能安装一个快捷方式到桌面上?当然可以,PWA就是用来干这个的。但Service Worker应该注册到哪个页面呢?显然不是index.php,它只是一个跳转入口;也不是“我的车辆”。为了便捷使用,显然应该注册在vehicle.php上。于是进一步修改vehicle.php,将title改为车牌号;用ChatGPT-5.1画了两个icon图标(512像素和192像素);然后请Codex编写manifest.json和sw.js。

结果Codex告诉我,由于vehicle.php具体到每一辆车时,车辆id不同,因此无法使用静态json。于是它改成用一个manifest.php来动态返回json内容。经过3轮Prompt迭代,PWA功能添加成功。

11、欢迎把玩

该网站已经上线:https://lab.lucyqin.cn/cars,也可以点击博客顶部的“杂货铺”进入。

手机界面如下:

欢迎测试使用。