Claude 驱动的全栈开发:Spring Boot + Vue 的 BS 架构实践


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 会:

  1. 生成 pom.xml(Spring Boot 3.x、MyBatis-Plus、Druid、SpringDoc 依赖)
  2. 创建 application.yml(数据源、端口、MyBatis-Plus 配置)
  3. 搭建基础包结构(controller、service、mapper、entity、dto)
  4. 创建统一响应类 ApiResponse<T>
  5. 配置 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 会:

  1. 创建 src/views/DeviceDetail/index.vue
  2. 添加动态路由 /:id
  3. 创建故障记录的 API 和表单组件
  4. el-tabs 组织基本信息和故障记录两个面板

六、这一章的核心心得

  1. Claude 能同时操作前后端------不需要你分别开两个终端,一条指令搞定全栈
  2. 数据库设计 → Entity → Service → Controller → API → 页面,全自动------只要描述清楚字段和业务规则
  3. 前后端契约自动对齐------Claude 知道后端 Controller 的接口定义,生成的前端 API 调用天然匹配
  4. 联调出错时 Claude 是最佳调试搭档------它同时理解前后端代码,能快速定位问题在哪一层
  5. 增量开发是王道------先做 CRUD 主干,再逐步叠加详情、关联、统计等扩展功能

七、下一步

全栈开发我们已经打通了,但代码写完后还有大量工作:代码审查、性能优化、Bug 排查、部署上线。下一篇我们将进入工程化进阶,学习如何用 Claude 做代码审查、调试和性能优化。


系列目录:

  1. 初识 Claude Code:用自然语言打造第一个 Web 页面
  2. 页面级交互实战:表单、弹窗与数据联动
  3. 前后端联调:让 Claude 帮你打通 REST API
  4. 状态管理:Pinia 与复杂业务逻辑
  5. 深入 Claude Code:Agent 多智能体协作
  6. Claude 驱动的全栈开发:Spring Boot + Vue 的 BS 架构实践 ← 本篇
  7. 工程化进阶:代码审查、调试与性能优化(待写)
  8. 高级玩法:工作流编排与团队协作(待写)
相关推荐
滴滴答答哒14 小时前
VUE3+element-plus MultiSelect 多选下拉组件
前端·javascript·vue.js
其美杰布-富贵-李14 小时前
04 watch 与 Vue 响应式数据流
前端·javascript·vue.js
工业设备方案笔记17 小时前
RK3588 vs RK3568:AI边缘计算项目到底应该如何选择芯片平台?
arm开发·人工智能·目标跟踪·架构·边缘计算
其美杰布-富贵-李17 小时前
03 ref、reactive 与 computed 响应式数据
前端·javascript·vue.js
嘟嘟071717 小时前
useRef + Web Worker:React 中的耗时计算不卡页面
javascript·vue.js
万敏18 小时前
Vue3 全栈实战第五周:Vitest 单元测试从零搭建实战记录
vue.js·node.js·全栈
xiaoqiMikko18 小时前
Dependabot 面板全绿,不代表你的 Tomcat 没洞
java·spring boot
一次旅行18 小时前
多智能体编排实战:拆解Plan-and-Execute范式+三层记忆架构,手写无依赖轻量Agent调度引擎
前端·javascript·架构
摇滚侠18 小时前
SpringBoot 官网 阅读笔记 启用生产就绪功能 端点
spring boot·笔记·后端
未来之窗软件服务18 小时前
商家自动化任务下一代架构混沌无界思维-东方仙盟
架构·自动化·仙盟创梦ide·东方仙盟·自动化任务