title: Claude 驱动的全栈开发:Spring Boot + Vue 的 BS 架构实践
date: 2026-07-07
category: AI 开发工具
tags: Claude Code, 全栈开发, Spring Boot, Vue, BS架构
Claude 驱动的全栈开发:Spring Boot + Vue 的 BS 架构实践
从数据库建表到前端页面渲染,全流程用 Claude 完成。本篇演示如何让 Claude 同时操作前后端代码,实现一个完整的 CRUD 模块。
前言
前面 5 篇文章我们分别从前端入门、页面交互、API 联调、状态管理、多智能体协作的角度学习了 Claude Code。从今天开始,我们把所有技能串起来,做一个端到端的全栈实战:用 Claude 从一个空项目搭建起一个完整的 BS 架构应用。
假设需求是:开发一个"设备管理"模块------设备有增删改查、状态监控、故障记录关联。前端用 Vue 3 + Element Plus,后端用 Spring Boot + MyBatis-Plus,数据库用 MySQL。
一、项目初始化
1.1 后端初始化
用 Spring Boot 3.x + MyBatis-Plus + MySQL 初始化一个后端项目。
包结构:com.device.server
端口:8080
需要集成 Druid 数据源、Swagger 接口文档
Claude 会:
- 生成
pom.xml(Spring Boot 3.x、MyBatis-Plus、Druid、SpringDoc 依赖) - 创建
application.yml(数据源、端口、MyBatis-Plus 配置) - 搭建基础包结构(controller、service、mapper、entity、dto)
- 创建统一响应类
ApiResponse<T> - 配置 Swagger/OpenAPI
1.2 前端初始化
用 Vite + Vue 3 + TypeScript + Element Plus 初始化前端项目。
配置 Axios 封装和 Vite 代理,代理 /api 到 http://localhost:8080
Claude 会创建完整的前端脚手架,包括 HTTP 封装、路由、布局等基础结构。
1.3 数据库建表
设计设备管理的数据库表:
- device 表:id, name, code, type, status, location, departmentId, createTime, updateTime
- fault_record 表:id, deviceId, description, handler, solveTime, status
- 设备状态枚举:normal(正常)、warning(告警)、fault(故障)、offline(离线)
Claude 会生成:
sql
CREATE TABLE device (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100) NOT NULL COMMENT '设备名称',
code VARCHAR(50) NOT NULL UNIQUE COMMENT '设备编号',
type VARCHAR(50) NOT NULL COMMENT '设备类型',
status VARCHAR(20) NOT NULL DEFAULT 'normal' COMMENT '状态',
location VARCHAR(200) COMMENT '位置',
department_id BIGINT COMMENT '所属部门',
create_time DATETIME DEFAULT CURRENT_TIMESTAMP,
update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
INDEX idx_code (code),
INDEX idx_status (status)
) COMMENT '设备表';
CREATE TABLE fault_record (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
device_id BIGINT NOT NULL COMMENT '设备ID',
description TEXT NOT NULL COMMENT '故障描述',
handler VARCHAR(100) COMMENT '处理人',
solve_time DATETIME COMMENT '处理时间',
status VARCHAR(20) NOT NULL DEFAULT 'pending' COMMENT '处理状态',
create_time DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (device_id) REFERENCES device(id)
) COMMENT '故障记录表';
二、后端开发
2.1 Entity + Mapper
为 device 表生成 MyBatis-Plus 的 Entity 类和 Mapper 接口。
Entity 使用 @TableName 注解,Mapper 继承 BaseMapper。
Claude 生成:
java
@Data
@TableName("device")
public class Device {
@TableId(type = IdType.AUTO)
private Long id;
private String name;
private String code;
private String type;
private String status;
private String location;
private Long departmentId;
@TableField(fill = FieldFill.INSERT)
private LocalDateTime createTime;
@TableField(fill = FieldFill.INSERT_UPDATE)
private LocalDateTime updateTime;
}
@Mapper
public interface DeviceMapper extends BaseMapper<Device> {
}
2.2 Service 层
实现 DeviceService,包含:
- 分页查询(支持按名称、编号、状态筛选)
- 新增设备(编号唯一校验)
- 更新设备
- 删除设备(级联删除故障记录)
- 获取设备详情(含关联的故障记录列表)
Claude 生成 DeviceServiceImpl:
java
@Service
public class DeviceServiceImpl extends ServiceImpl<DeviceMapper, Device>
implements DeviceService {
@Autowired
private FaultRecordMapper faultRecordMapper;
@Override
public PageResult<DeviceVO> pageQuery(DeviceQuery query) {
LambdaQueryWrapper<Device> wrapper = new LambdaQueryWrapper<>();
wrapper.like(StringUtils.hasText(query.getName()), Device::getName, query.getName())
.like(StringUtils.hasText(query.getCode()), Device::getCode, query.getCode())
.eq(StringUtils.hasText(query.getStatus()), Device::getStatus, query.getStatus())
.orderByDesc(Device::getCreateTime);
Page<Device> page = new Page<>(query.getPageNum(), query.getPageSize());
Page<Device> devicePage = this.page(page, wrapper);
// 转换为 VO
return new PageResult<>(
devicePage.getRecords().stream()
.map(this::convertToVO)
.collect(Collectors.toList()),
devicePage.getTotal()
);
}
@Override
@Transactional
public void deleteById(Long id) {
// 级联删除故障记录
faultRecordMapper.delete(
new LambdaQueryWrapper<FaultRecord>().eq(FaultRecord::getDeviceId, id)
);
this.removeById(id);
}
private DeviceVO convertToVO(Device device) {
DeviceVO vo = BeanUtil.copyProperties(device, DeviceVO.class);
// 查询故障记录数量
long faultCount = faultRecordMapper.selectCount(
new LambdaQueryWrapper<FaultRecord>()
.eq(FaultRecord::getDeviceId, device.getId())
.eq(FaultRecord::getStatus, "pending")
);
vo.setPendingFaultCount((int) faultCount);
return vo;
}
}
2.3 Controller 层
生成 DeviceController,遵循 RESTful 风格。
所有接口返回 ApiResponse<T> 格式。
添加 Swagger 注解。
Claude 生成:
java
@RestController
@RequestMapping("/api/devices")
@Tag(name = "设备管理")
public class DeviceController {
@Autowired
private DeviceService deviceService;
@GetMapping
@Operation(summary = "分页查询设备列表")
public ApiResponse<PageResult<DeviceVO>> pageQuery(DeviceQuery query) {
return ApiResponse.success(deviceService.pageQuery(query));
}
@PostMapping
@Operation(summary = "创建设备")
public ApiResponse<Long> create(@Valid @RequestBody DeviceDTO dto) {
Long id = deviceService.create(dto);
return ApiResponse.success(id);
}
@PutMapping("/{id}")
@Operation(summary = "更新设备")
public ApiResponse<Void> update(@PathVariable Long id,
@Valid @RequestBody DeviceDTO dto) {
deviceService.update(id, dto);
return ApiResponse.success();
}
@DeleteMapping("/{id}")
@Operation(summary = "删除设备")
public ApiResponse<Void> delete(@PathVariable Long id) {
deviceService.deleteById(id);
return ApiResponse.success();
}
@GetMapping("/{id}")
@Operation(summary = "获取设备详情")
public ApiResponse<DeviceVO> detail(@PathVariable Long id) {
return ApiResponse.success(deviceService.getDetail(id));
}
}
2.4 全局异常处理
添加全局异常处理器,统一处理参数校验失败、设备不存在、编号重复等异常。
返回格式:{ code: 400/404, message: "错误信息", data: null }
Claude 会创建 GlobalExceptionHandler,用 @RestControllerAdvice 拦截各类异常。
三、前端对接
3.1 API 层
根据后端的 Controller 接口,生成前端的 API 调用函数。
路径、参数、返回值要和后端完全一致。
Claude 生成 src/api/device.ts:
typescript
import { get, post, put, del } from '@/utils/http'
import type { Device, DeviceQuery, DeviceDTO, PageResult } from '@/api/types'
export function getDeviceList(params: DeviceQuery) {
return get<PageResult<Device>>('/devices', { params })
}
export function createDevice(data: DeviceDTO) {
return post<number>('/devices', data)
}
export function updateDevice(id: number, data: DeviceDTO) {
return put<void>(`/devices/${id}`, data)
}
export function deleteDevice(id: number) {
return del<void>(`/devices/${id}`)
}
export function getDeviceDetail(id: number) {
return get<Device>(`/devices/${id}`)
}
3.2 页面组件
创建设备管理页面,复用之前学过的用户管理页面的交互模式:
搜索区 + 表格 + 分页 + 新增/编辑弹窗 + 删除确认
区别在于字段不同:设备有编号、类型、状态(带颜色标识)、位置
Claude 会基于之前的模式生成设备管理页面,字段和交互逻辑完全一致,只是数据模型变了。
3.3 状态标识
设备状态需要用不同颜色的 Tag 展示:
- normal → 绿色"正常运行"
- warning → 黄色"告警"
- fault → 红色"故障"
- offline → 灰色"离线"
Claude 会在表格列的 template #default 中用 computed 或辅助函数映射状态颜色和文字。
四、全栈联调
4.1 启动后端
启动后端 Spring Boot 应用,确认端口 8080
Claude 会执行 mvn spring-boot:run(或类似命令),确认启动成功后告诉你。
4.2 启动前端
启动前端开发服务器
Claude 执行 pnpm dev,确认 http://localhost:5173 可访问。
4.3 验证功能
在浏览器中打开设备管理页面,依次测试:
1. 列表加载是否正常
2. 搜索是否生效
3. 新增设备能否成功
4. 编辑能否保存
5. 删除是否有确认弹窗
如果任何一步出错,Claude 会读取浏览器控制台和网络面板的错误信息,定位到前后端的具体代码行并修复。
五、扩展:设备详情与故障记录
设备管理做完后,还需要一个子功能:点击设备查看详情,能看到关联的故障记录。
在设备列表的操作列加一个"详情"按钮。
点击后跳转到 /devices/:id 页面,展示设备基本信息 + 故障记录列表。
故障记录支持新增,填写故障描述后调用 POST /api/fault-records 接口。
Claude 会:
- 创建
src/views/DeviceDetail/index.vue - 添加动态路由
/:id - 创建故障记录的 API 和表单组件
- 用
el-tabs组织基本信息和故障记录两个面板
六、这一章的核心心得
- Claude 能同时操作前后端------不需要你分别开两个终端,一条指令搞定全栈
- 数据库设计 → Entity → Service → Controller → API → 页面,全自动------只要描述清楚字段和业务规则
- 前后端契约自动对齐------Claude 知道后端 Controller 的接口定义,生成的前端 API 调用天然匹配
- 联调出错时 Claude 是最佳调试搭档------它同时理解前后端代码,能快速定位问题在哪一层
- 增量开发是王道------先做 CRUD 主干,再逐步叠加详情、关联、统计等扩展功能
七、下一步
全栈开发我们已经打通了,但代码写完后还有大量工作:代码审查、性能优化、Bug 排查、部署上线。下一篇我们将进入工程化进阶,学习如何用 Claude 做代码审查、调试和性能优化。
系列目录:
- 初识 Claude Code:用自然语言打造第一个 Web 页面
- 页面级交互实战:表单、弹窗与数据联动
- 前后端联调:让 Claude 帮你打通 REST API
- 状态管理:Pinia 与复杂业务逻辑
- 深入 Claude Code:Agent 多智能体协作
- Claude 驱动的全栈开发:Spring Boot + Vue 的 BS 架构实践 ← 本篇
- 工程化进阶:代码审查、调试与性能优化(待写)
- 高级玩法:工作流编排与团队协作(待写)