构建VideoAgentTrek-ScreenFilter管理后台SpringBoot Vue.js全栈开发最近在做一个视频内容过滤相关的项目需要开发一个管理后台让运营人员能方便地上传视频、查看处理进度、下载结果。经过一番技术选型最终决定用SpringBoot搭后端Vue.js写前端走前后端分离的路线。今天就来聊聊这个后台是怎么一步步搭起来的希望能给有类似需求的同学一些参考。整个系统的核心流程很简单用户在前端上传视频后端接收后启动一个异步过滤任务处理完成后把结果文件存起来前端可以实时查看进度并下载处理好的视频。听起来不复杂但要把前后端配合、文件上传下载、任务状态管理这些都做好还是有不少细节要注意的。1. 项目整体设计与技术栈在动手写代码之前我们先得把整个项目的架子搭好想清楚前后端怎么分工、数据怎么流动。我选择的技术栈算是目前比较主流的组合上手快生态也丰富。后端用SpringBoot主要是看中了它开箱即用的特性不用花太多时间在配置上。像Web服务、数据库连接、安全认证这些SpringBoot都有成熟的starter引入依赖就能用。前端选了Vue.js一方面是因为它学习曲线平缓组件化的思想也很清晰另一方面Vue的生态里有Element Plus这样成熟的UI库能快速搭建出好看又实用的管理界面。前后端通信完全通过RESTful API进行数据格式用JSON。为了安全我加上了JWTJSON Web Token认证这样每次请求都能知道是谁发起的也能做权限控制。文件上传这块考虑到视频文件可能比较大后端做了分片上传和断点续传的支持避免网络不稳定导致上传失败要重头再来。数据库方面我用的是MySQL主要存用户信息、任务记录、文件路径这些元数据。至于处理后的视频文件则是直接存在服务器的硬盘上数据库里只记录文件的存储路径。整个项目的目录结构也提前规划好了把控制器、服务、数据访问层分得清清楚楚这样以后加功能或者改代码都方便。2. 后端SpringBoot服务搭建后端是整个系统的大脑负责接收请求、处理业务、存取数据。我用SpringBoot Initializr快速生成了一个项目骨架选上了Web、Security、JPA、MySQL这几个必要的依赖。2.1 核心数据模型与API设计首先得定义清楚系统里有哪些“东西”。我设计了三个主要的实体类User用户、VideoTask视频处理任务、ProcessedVideo处理后的视频。VideoTask是这个系统的核心它记录了任务的整个生命周期。// VideoTask 实体类示例 Entity Table(name video_task) public class VideoTask { Id GeneratedValue(strategy GenerationType.IDENTITY) private Long id; private String taskId; // 唯一任务标识 private String originalFileName; private String filePath; // 原始文件存储路径 private String status; // 如PENDING, PROCESSING, COMPLETED, FAILED private Integer progress; // 处理进度 0-100 private String filterType; // 应用的过滤类型 ManyToOne JoinColumn(name user_id) private User createdBy; private LocalDateTime createdAt; private LocalDateTime updatedAt; // ... 省略getter/setter }API的设计围绕任务管理展开。我规划了以下几个主要的接口POST /api/tasks提交一个新的视频处理任务。GET /api/tasks获取当前用户的任务列表支持分页和状态过滤。GET /api/tasks/{taskId}获取某个任务的详细信息包括实时进度。GET /api/tasks/{taskId}/result下载处理完成后的视频文件。POST /api/auth/login用户登录获取JWT令牌。每个接口的请求和响应格式都用DTOData Transfer Object对象来封装这样前后端约定好字段就不容易出错。2.2 文件上传与异步任务处理视频文件上传是第一个要解决的难点。我用了Spring提供的MultipartFile来接收文件但直接传大文件容易超时或失败。所以我在前端实现了文件分片后端对应地提供了合并分片的接口。PostMapping(/upload/chunk) public ResponseEntity? uploadChunk(RequestParam(file) MultipartFile file, RequestParam(chunkNumber) Integer chunkNumber, RequestParam(totalChunks) Integer totalChunks, RequestParam(identifier) String identifier) { // 1. 检查分片是否已存在实现秒传/断点续传 // 2. 将当前分片临时存储到指定目录 // 3. 如果是最后一个分片触发合并操作 String tempPath saveChunk(file, identifier, chunkNumber); if (chunkNumber.equals(totalChunks)) { mergeChunks(identifier, totalChunks); // 合并成功后创建VideoTask记录并触发异步处理 String finalFilePath mergeChunks(identifier, totalChunks); videoProcessingService.createAndProcessTask(finalFilePath, filterType); } return ResponseEntity.ok().build(); }文件上传成功后真正的视频过滤处理是个耗时操作不能阻塞HTTP请求线程。我用Spring的Async注解配合线程池把处理逻辑丢到后台异步执行。Service public class VideoProcessingService { Async(taskExecutor) public void processVideoTask(Long taskId) { VideoTask task taskRepository.findById(taskId).orElseThrow(); task.setStatus(PROCESSING); taskRepository.save(task); try { // 模拟耗时的视频处理过程 for (int i 0; i 100; i 10) { Thread.sleep(1000); // 模拟处理时间 task.setProgress(i); taskRepository.save(task); // 这里可以发送WebSocket消息通知前端进度更新 } task.setStatus(COMPLETED); // 保存处理后的视频文件信息到ProcessedVideo表 } catch (Exception e) { task.setStatus(FAILED); task.setErrorMessage(e.getMessage()); } finally { taskRepository.save(task); } } }为了让前端能实时看到进度我引入了WebSocket。当后台任务进度更新时就通过WebSocket主动推送给对应的前端页面这样用户就不用一直手动刷新了。2.3 安全认证与全局配置管理后台肯定不能谁都能访问所以安全认证是必须的。我整合了Spring Security和JJWT库来实现基于JWT的认证。核心逻辑是用户登录成功后后端生成一个JWT令牌返回给前端。前端后续的每次请求都在HTTP Header里带上这个令牌通常是Authorization: Bearer token。后端有一个过滤器JwtAuthenticationFilter会拦截请求验证令牌的有效性如果有效就把用户信息设置到安全上下文中这样控制器里就能通过AuthenticationPrincipal注解拿到当前用户了。此外我还配置了CORS跨域资源共享因为前端项目通常运行在另一个端口或域名下。在SpringBoot的配置类里可以指定允许跨域的来源、方法以及请求头。Configuration EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { Override protected void configure(HttpSecurity http) throws Exception { http.cors().and().csrf().disable() // 开发环境方便生产环境需谨慎 .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS) .and() .authorizeRequests() .antMatchers(/api/auth/**, /websocket/**).permitAll() // 登录和WebSocket连接放行 .anyRequest().authenticated() .and() .addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class); } Bean public CorsFilter corsFilter() { // 配置CORS规则 UrlBasedCorsConfigurationSource source new UrlBasedCorsConfigurationSource(); CorsConfiguration config new CorsConfiguration(); config.setAllowCredentials(true); config.addAllowedOrigin(http://localhost:8080); // 前端地址 config.addAllowedHeader(*); config.addAllowedMethod(*); source.registerCorsConfiguration(/**, config); return new CorsFilter(source); } }3. 前端Vue.js界面开发前端的目标是做一个清晰、易用的管理界面。我用Vue CLI创建了项目并引入了Element Plus作为UI组件库它提供的表格、表单、上传组件、进度条等正好符合后台管理的需求。3.1 项目初始化与路由配置首先安装好Vue Router用来管理页面跳转。我规划了几个主要的页面登录页 (/login)任务列表页 (/tasks)展示所有任务是默认主页。任务创建页 (/tasks/create)上传视频并提交新任务。任务详情页 (/tasks/:id)查看某个任务的详细进度和结果。在router/index.js里配置好这些路由并对需要认证的页面设置路由守卫检查用户是否已登录即本地是否有有效的JWT令牌如果没有就跳转到登录页。// router/index.js const routes [ { path: /login, component: Login, meta: { requiresAuth: false } }, { path: /tasks, component: TaskList, meta: { requiresAuth: true } }, { path: /tasks/create, component: CreateTask, meta: { requiresAuth: true } }, { path: /tasks/:id, component: TaskDetail, meta: { requiresAuth: true } }, { path: /, redirect: /tasks } ]; router.beforeEach((to, from, next) { const token localStorage.getItem(token); if (to.meta.requiresAuth !token) { next(/login); } else { next(); } });为了统一管理API请求我用了Axios库并创建了一个请求拦截器自动在每次请求的Header里加上JWT令牌。// utils/request.js import axios from axios; const service axios.create({ baseURL: process.env.VUE_APP_BASE_API, timeout: 15000 }); service.interceptors.request.use( config { const token localStorage.getItem(token); if (token) { config.headers[Authorization] Bearer token; } return config; }, error { return Promise.reject(error); } );3.2 核心功能页面实现任务列表页是用户进来后看到的主要界面。我用Element Plus的el-table来展示任务数据表格列包括任务ID、文件名、状态、进度、创建时间等。状态用标签el-tag显示不同状态配不同颜色比如进行中是蓝色成功是绿色失败是红色。进度则用el-progress组件展示一目了然。页面加载时会调用/api/tasks接口获取数据。任务创建页的核心是文件上传组件。我直接用了Element Plus的el-upload组件但开启了分片上传模式。在上传前前端会先把大文件切割成固定大小比如5MB的块Blob然后依次上传。这样即使网络中断下次也可以只传缺失的分片实现断点续传。上传过程中会显示一个总体的进度条。文件传完后用户可以选择过滤类型点击提交按钮调用后端的/api/tasks接口创建任务记录。任务详情页用于展示一个任务的细信息。除了展示任务的基本信息最关键的是实时进度展示。这里我建立了WebSocket连接监听后端推送的进度更新消息。当收到消息时就更新页面上的进度条和状态。如果任务已经完成页面会显示一个下载结果的按钮。3.3 状态管理与用户体验优化虽然这个项目不算特别复杂但我还是引入了Vuex来集中管理一些全局状态比如用户登录信息、全局的提示消息等。这样在不同组件间共享状态会方便很多。为了提升用户体验我做了几点优化文件上传优化除了分片和断点续传还做了文件格式和大小校验在上传前就提示用户。实时反馈任何操作比如提交成功、上传完成都会用Element Plus的ElMessage组件给用户一个即时的提示。加载状态在发起网络请求时按钮会显示加载中状态防止用户重复点击。错误处理对网络请求错误进行了统一拦截根据HTTP状态码给出友好的错误提示比如“登录已过期请重新登录”或者“服务器开小差了请稍后再试”。4. 前后端联调与部署代码写得差不多了就得把前后端跑起来看看它们能不能愉快地合作。联调过程中确实会遇到一些跨域、接口格式不对、文件路径之类的问题。4.1 联调常见问题与解决第一个拦路虎通常是跨域CORS。虽然后端已经配置了CORS但如果前端在开发服务器比如localhost:8080上请求后端比如localhost:8081浏览器还是会因为同源策略而拦截请求。确保后端的CORS配置里包含了前端的地址并且包含了必要的头信息如Authorization。第二个是文件上传。要特别注意Content-Type上传文件时通常是multipart/form-data。后端接收参数的注解RequestParam里的名字要和前端FormData里append的字段名对上。分片上传时前后端关于分片索引、文件唯一标识的约定也要一致。第三个是WebSocket连接。前端连接WebSocket的地址比如ws://localhost:8081/websocket要正确并且后端需要有对应的WebSocket配置端点。连接建立后前后端订阅和发布消息的频道也要约定好。4.2 项目打包与部署思路开发调试没问题后就可以准备部署了。前端部署运行npm run build命令Vue CLI会把项目打包成静态文件HTML、CSS、JS生成一个dist文件夹。你可以把这个文件夹里的所有文件扔到任何一个静态文件服务器上比如Nginx。然后在Nginx配置里把所有的前端路由请求都重定向到index.html这是单页应用的标准做法。后端部署SpringBoot项目打包成一个可执行的JAR文件非常方便。用mvn clean package命令打包后你会得到一个your-project.jar。部署到服务器上只需要确保服务器安装了合适版本的Java然后直接运行java -jar your-project.jar就行了。生产环境建议配置一下JVM参数比如堆内存大小。也可以用systemd或Docker来管理这个进程实现开机自启和自动重启。数据库和文件存储也需要考虑。MySQL需要单独安装和配置。处理后的视频文件建议存到一个独立的、空间充足的目录并在后端配置中指定这个路径。如果有多台服务器可能需要考虑使用分布式文件存储比如MinIO或FastDFS。整个项目从设计到实现走完一遍后感觉还是挺有成就感的。SpringBoot和Vue.js这套组合对于开发这类管理后台效率确实很高。后端专注于提供稳定可靠的API前端负责呈现友好的交互界面两者通过清晰的接口契约协作。过程中遇到的像大文件上传、实时进度通知这些挑战也都有比较成熟的解决方案可以借鉴。获取更多AI镜像想探索更多AI镜像和应用场景访问 CSDN星图镜像广场提供丰富的预置镜像覆盖大模型推理、图像生成、视频生成、模型微调等多个领域支持一键部署。