欢迎光临
我们一直在努力

飞算JavaAI能省掉多少联调时间?用访客登记后台做一次对照

我是写 Java 后端的,前端只会改改样式。以前我们想自己弄个管理后台,卡点从来不在业务逻辑上,而在两件事:一是没人给设计稿,对着空白画布不知道从哪下手;二是前后端对接时,字段名、枚举值、时间格式总要来回对几轮,谁也不记得是谁先改的。

这次我拿园区访客预约做了个实测,对象是《访迹 · 智慧园区访客预约管理系统》(fangji)。先把我自己的记录说清楚:整轮开发约 6 小时,在一个工作日内完成;前后端字段错配带来的额外返工,这次是 0 分钟。原始时间记录在第四节,优点、不足和建议在第六节,值不值得参考你自己判断。

接下来就按我实际操作的五步走一遍,截图都是做实操时直接截的。先提醒一句:几分钟生成源码,和几分钟做完一个项目,完全是两回事。

速览结果
实测对象 访迹(fangji):访客预约 + 服务台核验/离园
环境 macOS 27.0 · IDEA 2026.2.3 · JDK 17 · Spring Boot 3.3.4 · Vue 3 + Vite
整轮耗时 约 6 小时(1 人,1 个工作日内,分项见第四节)
字段错配返工 0 分钟(确切含义见第四节)
自动化验证 契约静态检查 11/11 · 后端集成测试 7/7 · 前端类型检查与打包通过
主要不足 前端仍有演示回退分支 · Token 存在服务端内存 · 翻页与全量统计未做

一、先确定这次要跑通什么

1. 运行环境

先说环境,代码片段我都以本地运行版为准。

环境项配置与版本
操作系统 macOS 27.0
开发工具 IntelliJ IDEA 2026.2.3 Ultimate
核心插件 飞算 JavaAI,走的是截图里那个“智能引导”全栈入口
后端 OpenJDK 17.0.18、Spring Boot 3.3.4、Spring Data JPA、Maven 3.9.14
前端 Node.js 26.3.0、Vue 3、TypeScript、Vite、Tailwind CSS、Axios
本地数据库 H2 文件库,路径是启动工作目录下的 ./data/fangji_db
运行方式 前后端分别启动,或者把前端资源打进 app-6-1.0.0.jar 单包运行

工程里还放了 Docker Compose 和 MySQL 的配置模板。但这次跑出来的结果都来自本地环境,容器和 MySQL 那两条路我这次没实跑,得单独验证。

2. 六项主要功能

我把需求收在访客和服务台两个入口上,一共六项功能:

#功能谁在用
1 免登录填姓名、手机号、来访单位、接待人和部门、起止时间、来访事由 访客
2 预约成功后展示 VP 通行码和凭证信息 访客
3 登录后查看预约台账,按关键字和状态检索 服务台
4 录入通行码或预约手机号,核验入园 服务台
5 为在园访客办理离园,记录实际离开时间 服务台
6 对服务台列表、入园和离园接口做登录校验 系统

这里的“六项”是按功能算的,里面有表单、有弹窗、也有行内操作,并不是六个独立的路由页面。另外,业务状态其实只有三种,这一点后面反复用到:

PENDING → CHECKED_IN → DEPARTED

用中文说,就是待到访、在园中,以及已离园三种阶段。

后台会拒绝重复入园,也不允许未入园直接离园。还有一点要先讲明白:这次核验的是系统里的出入状态,没有接实体闸机。


二、跟着“智能引导”走一遍:从需求到能跑

飞算 JavaAI 的智能引导把过程分成五步:理解需求、设计接口、表结构设计、代码生成计划、生成源码。每一步我都能看到拆解结果,确认没问题再往下走,这也是我敢让它生成整套工程的前提。

输入:我这次用的需求

我把需求写得比较实,尤其是两端的边界和状态约束,都直接写在里面了:

请生成一个《智慧园区访客预约管理系统》(访迹)。
包含两个端:外部访客端和前台服务台端。

1. 外部访客端(公开免登):
– 支持访客自主提交到访预约申请(访客真实姓名、11位大陆手机号码、来访单位机构全称、对接员工姓名及所属部门、预计到访时间、预计离开时间、来访事由);
– 提交成功后自动生成专属核销通行码(VP开头唯一标识),并即时展示包含脱敏信息和出入指引的电子通行凭证卡。

2. 服务台端(前台操作员管控):
– 具备服务台接待人员与管理员安全登录认证体系(支持加盐安全哈希密码存储与 Token 鉴权);
– 提供服务台全景台账:支持关键字(姓名/手机号/通行码/对接人)实时检索与状态(全部、待到访、在园中、已离园)多维度筛选;
– 提供前台极速到访核销专用通道:接待员可录入或扫码枪输入通行码/手机号,一键核销准予入园,记录实际入园时间并流转状态至 CHECKED_IN;
– 访客离园时支持一键办理签退离园,记录实际离园时间并流转至 DEPARTED。

3. 工程约束与规范要求:
– 业务状态流转严谨:未到访不可直接离园、在园中不可重复核验入园,状态冲突返回统一业务异常(HTTP 422);
– 前后端采用统一信封响应(Result<T>),时间格式统一为 ISO 本地时间;
– 接口契约与前端模型强制对齐,开启严格反序列化校验(fail-on-unknown-properties: true),拒绝任何未定义或废弃的多余字段;
– 前端采用现代清新企业级中后台浅色主题(Vue 3 + TypeScript + Vite),后端采用 Spring Boot 3 + Spring Data JPA。

第 1 步:理解需求

第一轮拆解不到 2 分钟就出结果了。图 1 里,它把我的需求拆成了 9 个关键点,预约申请、通行码、电子凭证、登录认证、查询、入园、离园、统一响应和严格字段校验都有对应条目。

飞算 JavaAI 理解需求,将访客预约业务拆为 9 个关键点

这一步对我来说最有用的地方是查漏。公开预约和内部服务台有没有分开、离园前必须满足什么状态、哪些字段必填。这些先确认下来,后面看代码时我就有了检查依据。反过来说,这里要是含糊,代码写得再顺也白搭。

第 2 步:设计接口

接下来是接口方案。图 2 给的是 6 个:访客预约申请、电子通行凭证生成、服务台安全认证、访客预约台账查询、入园核销、离园签退。

飞算 JavaAI 接口设计页面中的 6 个业务接口方案

这一屏我主要看业务职责和输入输出要求,凭证那一条还专门写了姓名和手机号的脱敏要求(张*、138****1234)。不过具体地址不能只看业务名称就当验收完了,还得对着生成计划和运行代码核。

本地运行版里,核心接口是这样的,预约响应直接带着通行码,前端拿到就能渲染凭证:

方法与路径用途访问方式
POST /api/visitors/reserve 创建预约并返回通行码 公开
GET /api/visitors 分页查询预约台账 登录后
POST /api/visitors/check-in 按 codeOrPhone 核验入园 登录后
POST /api/visitors/{id}/check-out 按预约 ID 办理离园 登录后
POST /api/auth/login 登录并获取 Token 公开
POST /api/auth/logout、GET /api/auth/me 退出、读取当前用户 登录后

对字段的时候,我重点看创建请求这 8 个。下面是运行工程里的 TypeScript 请求类型,直接从 frontend/src/types/index.ts 抄的:

export interface ReservationCreateRequest {
visitorName: string
phone: string
visitCompany: string
hostName: string
hostDept: string
visitReason: string
expectedArrival: string
expectedDeparture: string
}

后端对应的是 ReservationCreateDto。同样,下面保留真实字段和校验注解,省略 import 和 getter/setter:

public class ReservationCreateDto {
@NotBlank(message = "访客姓名不能为空")
@Size(max = 64, message = "访客姓名不能超过64个字符")
private String visitorName;

@NotBlank(message = "手机号不能为空")
@Pattern(regexp = "^1[3-9]\\\\d{9}$", message = "联系手机格式不合法")
private String phone;

@NotBlank(message = "来访单位/机构名称不能为空")
@Size(max = 128, message = "来访单位/机构名称不能超过128个字符")
private String visitCompany;

@NotBlank(message = "被访员工姓名不能为空")
@Size(max = 64, message = "被访员工姓名不能超过64个字符")
private String hostName;

@NotBlank(message = "被访人所属部门不能为空")
@Size(max = 64, message = "被访人所属部门不能超过64个字符")
private String hostDept;

@NotBlank(message = "来访事由不能为空")
@Size(max = 255, message = "来访事由不能超过255个字符")
private String visitReason;

@NotNull(message = "预计到访时间不能为空")
@FutureOrPresent(message = "预计到访时间不能早于当前时间")
private LocalDateTime expectedArrival;

@NotNull(message = "预计离开时间不能为空")
@FutureOrPresent(message = "预计离开时间不能早于当前时间")
private LocalDateTime expectedDeparture;
}

前端把日期当本地时间字符串提交,后端解析成 LocalDateTime;到访状态两边都用 PENDING、CHECKED_IN、DEPARTED 这三个值。这一次我没有遇到字段拼写或枚举取值对不上的返工,但这不等于接口就没问题,日期、空值和业务错误的组合还是得用实际请求跑一遍。

第 3 步:表结构设计

然后是表结构。图 3 里设计的是 2 张表,数据库选的是 MySQL。用户表名叫 t_sys_user,字段有 username、password、salt、real_name、role_code、status,页面上能逐项检查类型、是否为空和唯一性,我在这里把密码字段确认成了加盐存储。

飞算 JavaAI 表结构设计,展示访客字段与 t_sys_user 用户表

那么设计归设计,运行工程里的名字是不一样的:表名是 visitor_reservation 和 sys_user,密码哈希字段叫 password_hash,角色字段叫 role。通行码靠数据库唯一约束防重复,这一点两版是一致的。

第 4 步:生成计划

到这一步就能看清它准备怎么实现了。图 4 列出了 Entity、Repository、通行码工具、脱敏工具、密码工具、Token 工具和控制器,也列了前端依赖(Element Plus、Vue Router、Axios、Pinia)。

飞算 JavaAI 代码生成计划,展示后端模块、接口路径与前端依赖

这里有个地方要留意:设计阶段的命名和最终跑起来的工程并不一致。我把它整理成一张对照表,不然截图和代码容易对不上。

对照项设计/生成计划(截图里)本地运行工程
后端包名 com.feisuan.fangji com.feisuan.visitorpass
创建预约 /api/visitor/appointment /api/visitors/reserve
核验入园 /api/reception/check-in /api/visitors/check-in
用户表 t_sys_user sys_user
统一响应体 Result<T>:code、message、data、timestamp Result<T>:多一个 requestId
认证实现 JwtUtil、JwtInterceptor TokenManager、AuthInterceptor,Token 存在服务端内存
前端方案 计划包含 Element Plus、Vue Router、Pinia 实际用 Vue 3、TypeScript、Tailwind CSS、Axios

也就是说,照着截图里的路径去调接口是调不通的,得用右列这一套。这一点有必要讲清楚,不然复现的人第一步就会卡住。

第 5 步:生成源码,然后把业务跑起来

按我的计时,源码生成阶段不到 3 分钟。这个时间只算生成,后面的启动、界面调整和检查都没算进去。

飞算 JavaAI 正在生成源码,右下角显示已生成 27 个文件

图 5 是生成过程中的一个时点,右下角显示已经生成 27 个文件,页面还在往外吐。左边打开的是 Result.java,所以这不是生成结束的样子。

生成完、调整完、启动起来之后,我先把预约、入园、离园这条链路跑通了。

访迹运行界面,展示登录状态、四个统计卡片与访客台账

图 6 是本地运行版的服务台,已经登录了管理员账号。8 条访客记录对应 3 条待到访、3 条在园、2 条已离园,正好和我初始化进去的数据对得上;台账里的手机号是掩码展示。

这里要说明一下数据来源:这 8 条记录是 data.sql 里预置的模拟数据,不是真实访客。编它们只是为了把待到访、在园、已离园三种状态凑齐,让台账像一套正在用的系统。

截图里的手机号在页面上做了掩码,姓名、单位、事由都是模拟的,所以能直接贴出来。你要是截的是真实系统的台账,记得先把姓名那一列打码再发。

访客那边的入口是这样:填完表单点提交,服务端创建预约后返回 VP 通行码。

访客到访预约申报表单,包含姓名、手机号、单位、接待人和起止时间

图 7 是提交之前的弹窗,能看到 8 个字段和底部的“确认提交并生成通行码”按钮,这时候还没有凭证。

入园之后,列表里的“核销入园”会换成“离园签退”,已离园的记录显示“已办结”。按钮是按状态条件渲染的,不是简单置灰。服务端还会再查一次状态,免得只依赖按钮可不可见。


三、跑通之后,我重点抠了这几处细节

1. 认证需求阶段就写了,真正生效的地方在服务端

我回头看了一遍:Prompt、图 1 和图 4 里都已经包含认证要求。从需求到生成计划,登录、密码校验和 Token 拦截一直是这条链路的一部分。运行时真正要核对的是公开接口和内部接口各自的边界。

运行版用的是 Bearer Token:/api/auth/login 和 /api/visitors/reserve 公开放行,服务台列表、核验和离园接口都要求有效 Token。前台接待员和管理员都有账号和角色信息,但两类操作员目前共用服务台权限,没有独立的管理员审计或运维模块,这一点别想多了。

还有个容易被自己骗过去的地方:设计计划里写的是 JwtUtil、JwtInterceptor,真跑到这个版本,Token 是放在服务端内存里的(一个 ConcurrentHashMap)。这处我是对着代码确认的,没看名字就下结论。它属于有状态的会话管理,应用重启就得重新登录。请求头写的是 Bearer,不等于无状态认证。

2. 密码这段我按真实实现贴

PasswordHelper.java 里盐值是从外部传进来的,盐和密码哈希在用户表里分两列存。算法是对 salt + ":" + rawPassword 做 SHA-256:

public final class PasswordHelper {
private PasswordHelper() {}

public static String hashPassword(String salt, String rawPassword) {
if (salt == null || rawPassword == null) {
throw new IllegalArgumentException("盐值与原始密码不可为空");
}
try {
MessageDigest md = MessageDigest.getInstance("SHA-256");
byte[] digest = md.digest(
(salt + ":" + rawPassword).getBytes(StandardCharsets.UTF_8));
StringBuilder sb = new StringBuilder();
for (byte b : digest) {
sb.append(String.format("%02x", b));
}
return sb.toString();
} catch (NoSuchAlgorithmException e) {
throw new IllegalStateException("当前运行环境未检测到 SHA-256 支持", e);
}
}

public static boolean matches(String rawPassword, String salt, String expectedHash) {
if (rawPassword == null || salt == null || expectedHash == null) {
return false;
}
return hashPassword(salt, rawPassword).equalsIgnoreCase(expectedHash);
}
}

这段代码既没有在方法内部生成随机盐,也没有把盐和哈希拼成一个字段存。它能解释当前系统怎么校验已有账号,但加盐 SHA-256 属于快哈希,拿它当密码存储方案是不够的,真要上线得换成 Argon2id 或者 bcrypt。OWASP 的密码存储指南里讲得很清楚,快哈希用在这里有什么局限。

还有一件事:data.sql 里预置的是 admin/admin123 和 receptionist/123456。本地样例够用,要是给别人用,第一件事就是改掉它俩。

3. 换文件库还不够,得看初始化脚本

本地默认数据源是 H2 文件库,核心 URL 是:

jdbc:h2:file:./data/fangji_db;DB_CLOSE_DELAY=-1

这里有个坑,我在做“写数据、重启、再查”的验证时才撞上。当时的想法很直接:内存库改成文件库,数据不就留下了?结果不是。真正让数据丢掉的,是工程里的建表脚本原来以 DROP TABLE IF EXISTS 开头,而初始化模式是 always,等于每次启动都把业务表删掉重建。

现在的做法是:schema.sql 全部用 CREATE TABLE IF NOT EXISTS,data.sql 按“记录不存在才插入”来写,这样重启既不会覆盖业务数据,也不会把已经改过的口令重置回初始值。项目的重启验证记录显示,本地文件库里的预约记录和修改过的口令都能保留。这个结论只针对本地单机重启,MySQL 模板不等于做过真实数据库演练。

另外,这 8 条模拟访客记录也写进了初始化 SQL,覆盖待到访、在园和已离园三种状态。图 6 里的手机号掩码是页面展示层的处理,数据本身就是模拟的,这两件事分开看就行。

4. 单包运行,少维护一个部署入口

工程里带了单包打包脚本,会把前端静态资源同步到 Spring Boot 的 static 目录,再打成可执行 JAR。在 fangji 根目录跑这两条:

bash scripts/build-release.sh
java -jar backend/target/app-6-1.0.0.jar

然后浏览器访问 http://localhost:8086 就能用完整的前后端。JAR 我这边量出来约 53.8 MB,具体体积会随打包变化。

对我这种小后台来说,单包托管确实省事,不用再单独维护一个 Nginx。但打包成功不等于验收完成。测试和类型检查得另外跑,下一节有命令。Docker Compose 文件我也放在工程里了,但配置文件存在和容器真的跑起来是两件事,我没把后者写成已经完成。


四、我这 6 小时花在哪:把“0 联调”说准确

时间是我自己记的,不是拿截图数量凑的。分项都是约数,用来看时间都花在哪了。

研发环节传统协作模式(按 Brief 参考口径拆分)本次飞算 JavaAI 实测记录
需求分析与交互设计 约 1.5 天 约 15 分钟
数据库与接口契约设计 约 1 天 约 10 分钟
后端核心功能开发 约 2 天 约 1 小时
前端界面与组件开发 约 3 天 约 1.5 小时
前后端字段错配定位与修复 约 2 天 本次额外返工为 0 分钟
认证检查、持久化与打包等收尾 约 0.5 天 约 2 小时
总体口径 约 10 人天,项目历时约 7 个工作日 1 人,整轮约 6 小时,在 1 个工作日内完成

左列不是我自己测出来的,是约稿 Brief 给的参考口径(前端 3 天、后端 2 天、联调 2 天,至少两人协作),我按环节拆开摆在这里而已,别把它当成我的对照实验数据。真要得出提效倍率,得再拉一条传统模式的代码线,还得有原始计时流水,这次没这个条件。

右列的分项相加是 4 小时 55 分钟,和我整轮记录的约 6 小时不是精确相等,每一段的数字都是约数。我只拿它看时间分布,不用它算百分比。

还有两个口径要分开:前面说需求拆解不到 2 分钟、源码生成不到 3 分钟,那说的是工具的生成阶段;这里的 15 分钟、1 小时,是包含我人工确认和实现调整在内的。不分开的话,很容易把“生成快”写成“活干完了”。

那么“0 联调”到底指什么?指的是这次没有出现前后端字段错配导致的额外返工,不是不用测试、也不是说任何项目都不会有接口问题。接口检查、业务操作、回归测试,该做的我一样没少做。


五、把跑通结果留成可重复的检查

1. 契约静态检查:11 项通过

在 fangji 项目根目录执行这条命令:

node scripts/verify-contract.mjs

图 8 就是它的输出,11 项全过:

终端契约检查结果,11 项源码检查全部通过

PASS frontend calls the /api visitor namespace
PASS Spring controller declares the reservation route
PASS both sides use codeOrPhone for check-in
PASS both sides keep the check-in and check-out routes
PASS reservation request validates future timestamps and phone format
PASS public response and frontend types exclude identity-card data
PASS unknown request fields fail instead of being silently ignored
PASS HTTP regression test rejects the legacy idCard field
PASS OpenAPI route is explicit and covered by the HTTP contract test
PASS auth controller and frontend api declare the login contract
PASS login request contract contains username and password on both sides
Contract source checks passed: 11/11

有个小细节顺带说一下:图 8 的终端提示符显示当前在 frontend 目录。这条命令在 frontend 下也能跑,因为 frontend/scripts/verify-contract.mjs 是指向根目录同名脚本的软链接,两边内容一致。根目录和 frontend 目录都行。

这个脚本做的是源码文本检查,好处是某个字段或路径被谁顺手改了,它立刻能发现。但它没有起真实浏览器,也没有把所有类型、日期、空值的组合都跑一遍。接口行为是否全都一致,它单独证明不了。

2. 后端集成测试:7 项通过

在后端目录执行:

cd backend
mvn test

Maven 测试报告,7 项测试通过,失败和错误均为 0

图 9 是结果:7 项通过,0 failure、0 error、0 skipped,BUILD SUCCESS。

7 个用例的覆盖范围是这样:

覆盖了没覆盖
登录成功与密码错误;未登录访问列表和核验接口(401);预约创建;正常入园与重复入园(422);非法手机号与时间;旧 idCard 字段(400);顺序重复预约;部分 OpenAPI 路径 浏览器端到端;离园成功与列表分页的成功用例;并发场景(重复预约是按顺序提交两次,不能算并发验证)

环境也要交代:跑在 MockMvc 加测试专用的内存 H2 上。人工跑通的业务步骤和自动化覆盖的范围,我会分开说。

前端还能单独跑类型检查和打包:

cd frontend
pnpm build


六、优点、不足和建议

按“三真实”的要求,优点和不足我都写,尽量写具体。

优点,我觉得有三条。

第一,接口契约是天生对齐的。前后端代码在同一份设计上下文里生成,字段名、类型、枚举值不需要我事后去撮合,这也是我这次能省掉“抓包对字段”那一轮的直接原因。

第二,它给的是可编译的工程,不是代码片段。Maven 和 Vite 的工程结构、依赖版本、配置文件、统一响应体都是齐的,我拿过来就能启动,不用先花半小时补齐依赖。

第三,它把“设计稿”这一步补上了。“智能引导”五步里,需求拆解和接口设计是能人工确认的,这一步对我来说价值最大。后端最怕的,就是对着空白画布凭空想界面。

不足也得说,有几条还挺关键。

  • 首版前端留着演示痕迹:登录弹窗里还有“快捷填入演示账号”的区域,App.vue 里也留着几处本地容错。登录接口报错时会用固定账号拼一个本地会话;预约提交失败时会降级生成一张模拟凭证卡,还提示“预约申请已成功受理”。演示时顺手,但会掩盖真实错误。我这次的跑通结论都以连接后端完成的操作为准,这些分支后面必须删掉。
  • 收尾那 2 小时基本是人工补的:认证通道的边界、初始化脚本这类问题,工具生成的首版不会替你考虑周全,得自己一项项过。
  • 持久化这件事工具没管住:默认给的是内存库,改完还要检查初始化脚本会不会清表。我就是在这儿踩了一次,详见第三节 3。
  • 契约检查是源码级的:挡得住“契约被改歪了”,挡不住“运行时行为不一致”,所以工程里同时留了 7 个集成测试,两者得一起看。

给我们这些写 Java、想一个人把中后台撑起来的同行,我的建议是三条。

  • Prompt 里先写清“角色与通道”。哪些页面对外免登、哪些操作必须登录后才行,写与不写,生成出来的路由和拦截逻辑差别很大。
  • 把“重启一次”写进验收清单。凡是跟持久化沾边的改动,都用“写数据 → 重启 → 查数据”三步过一遍。我这次的坑就是这么抓出来的,光看代码看不出来。
  • 别让打包成功掩盖验收。build-release.sh 只管打包;契约检查、集成测试、前端类型检查都得自己单独跑,三条都过才算这一轮有底。

七、一个后端,一天能做到哪一步?

回到最开始那个问题:我们写后端的,不先啃完一套前端框架,能不能把一个能用的后台做出来?

能。用飞算 JavaAI,加上人工确认、实现调整和验证,我在约 6 小时内跑通了访客预约、服务台登录、入园核验和离园登记,也整理出了一个可以单包运行的工程。

对我来说最直观的变化,是不用再等前端排期才能验证业务。界面和接口一起铺出来,我可以直接对着跑出来的记录检查表单、状态和操作结果。

不过我也得把话说全:这套工程现在还有演示回退分支、登录失效没有同步退出、翻页控件和全量统计也还没补。另外,除了“累计预约总量”取的是服务端分页总数,剩下三张卡片都是按当前已加载的这一页算的。这次展示的 8 条记录正好在一页内,数据量上去之后得重新验收。它对我来说是一个跑通的开始,不是可以收工的项目。

如果你也是写 Java 的,想独立撑起一个中后台,我建议先只挑一条业务链路跑通,把失败场景检查清楚,再决定要不要扩功能。我说的“一天”,就是这次这个项目的实测结果。

#飞算JavaAI #AI编程 #Java #全栈开发 #前后端分离 #后端开发 #前端开发 #IDEA插件 #程序员 #IDEA开发 #Java开发 #SpringBoot #程序员必备

赞(0)
未经允许不得转载:171主机测评 » 飞算JavaAI能省掉多少联调时间?用访客登记后台做一次对照
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址