1. 项目概述:古典舞在线交流平台的技术架构
这个基于Java SpringBoot+Vue3+MyBatis的古典舞交流平台,采用了典型的前后端分离架构。后端使用SpringBoot 2.7.x作为核心框架,配合MyBatis-Plus 3.5.x作为ORM层,MySQL 8.0作为主数据库。前端则采用Vue3组合式API开发,通过axios与后端进行RESTful API交互。
技术选型说明:选择SpringBoot 2.7而非最新的3.x系列,主要考虑国内企业生产环境仍以Java 8为主。Vue3的选用则看重其Composition API对复杂前端逻辑的组织能力。
系统主要包含以下核心模块:
- 用户中心(注册/登录/个人主页)
- 舞种百科(古典舞知识库)
- 视频交流区(上传/播放/评论)
- 活动预约系统(线上/线下活动管理)
- 私信聊天系统(WebSocket实时通信)
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 后端关键技术实现
2.1 SpringBoot应用骨架搭建
使用IDEA的Spring Initializr创建项目时,我推荐以下必选依赖:
xml复制<dependencies>
<!-- Web基础 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- MyBatis增强 -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.3.1</version>
</dependency>
<!-- MySQL驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<!-- 其他实用工具 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
2.2 MyBatis-Plus的深度应用
在舞蹈视频模块中,我们通过MyBatis-Plus实现了动态SQL构建:
java复制// VideoMapper.java
@Mapper
public interface VideoMapper extends BaseMapper<Video> {
@SelectProvider(type = VideoSqlProvider.class, method = "selectByDanceType")
List<Video> selectByDanceType(@Param("danceType") String danceType);
}
// 动态SQL构造器
public class VideoSqlProvider {
public String selectByDanceType(String danceType) {
return new SQL() {{
SELECT("*");
FROM("t_video");
if (StringUtils.isNotBlank(danceType)) {
WHERE("dance_type = #{danceType}");
}
ORDER_BY("create_time DESC");
}}.toString();
}
}
踩坑记录:MyBatis XML中特殊符号(如<>)必须使用CDATA包裹或转义。例如比较运算符应该写成
<和>。
2.3 文件上传与视频处理
对于舞蹈视频上传功能,采用分块上传策略:
java复制@PostMapping("/upload")
public Result uploadChunk(
@RequestParam MultipartFile file,
@RequestParam Integer chunkNumber,
@RequestParam Long totalSize) {
// 校验文件类型
String contentType = file.getContentType();
if (!Arrays.asList("video/mp4", "video/quicktime").contains(contentType)) {
throw new BizException("仅支持MP4/MOV格式");
}
// 分片存储逻辑
String chunkKey = "upload:" + userId + ":" + fileId + ":" + chunkNumber;
redisTemplate.opsForValue().set(chunkKey, file.getBytes());
// 合并检查
if (isAllChunksUploaded(fileId)) {
mergeChunks(fileId);
}
return Result.success();
}
3. 前端Vue3核心实现
3.1 组合式API实践
用户中心模块采用Vue3的setup语法:
vue复制<script setup>
import { ref, computed } from 'vue'
import { useUserStore } from '@/stores/user'
const userStore = useUserStore()
const editMode = ref(false)
const formData = ref({
nickname: userStore.nickname,
avatar: userStore.avatar,
bio: userStore.bio
})
const isDancer = computed(() => {
return userStore.roles.includes('dancer')
})
async function submitProfile() {
try {
await userStore.updateProfile(formData.value)
editMode.value = false
} catch (err) {
console.error('更新失败:', err)
}
}
</script>
3.2 视频播放器组件封装
基于video.js封装舞蹈视频播放器:
vue复制<template>
<div class="video-container">
<video
ref="videoPlayer"
class="video-js"
:poster="poster"
controls
preload="auto"
></video>
</div>
</template>
<script setup>
import { ref, onMounted, onUnmounted } from 'vue'
import videojs from 'video.js'
import 'video.js/dist/video-js.css'
const props = defineProps({
src: String,
poster: String
})
const videoPlayer = ref(null)
let player = null
onMounted(() => {
player = videojs(videoPlayer.value, {
controls: true,
autoplay: false,
fluid: true,
sources: [{
src: props.src,
type: 'video/mp4'
}]
})
})
onUnmounted(() => {
if (player) {
player.dispose()
}
})
</script>
4. 前后端交互关键设计
4.1 JWT认证方案
采用无状态JWT认证流程:
- 用户登录成功后,后端生成包含用户基本信息的JWT
- 前端将JWT存储在localStorage中
- 每次请求通过Authorization头携带token
- 后端通过拦截器校验token有效性
SpringSecurity配置示例:
java复制@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests()
.antMatchers("/api/auth/**").permitAll()
.antMatchers("/api/**").authenticated()
.and()
.addFilter(new JwtAuthenticationFilter(authenticationManager()))
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}
}
4.2 API响应规范
统一响应格式有助于前端处理:
java复制public class Result<T> implements Serializable {
private Integer code;
private String msg;
private T data;
private Long timestamp;
public static <T> Result<T> success(T data) {
Result<T> result = new Result<>();
result.setCode(200);
result.setMsg("success");
result.setData(data);
result.setTimestamp(System.currentTimeMillis());
return result;
}
// 其他工厂方法...
}
对应前端axios拦截器配置:
javascript复制// request拦截器
service.interceptors.request.use(config => {
const token = localStorage.getItem('token')
if (token) {
config.headers['Authorization'] = `Bearer ${token}`
}
return config
})
// response拦截器
service.interceptors.response.use(
response => {
const res = response.data
if (res.code !== 200) {
ElMessage.error(res.msg || 'Error')
return Promise.reject(new Error(res.msg || 'Error'))
}
return res.data
},
error => {
console.log('err' + error)
ElMessage.error(error.message)
return Promise.reject(error)
}
)
5. 数据库设计与优化
5.1 核心表结构
主要业务表设计如下:
| 表名 | 主要字段 | 说明 |
|---|---|---|
| t_user | id, username, password, salt, nickname, avatar | 用户基础表 |
| t_video | id, title, description, url, cover_url, dance_type, user_id | 舞蹈视频表 |
| t_comment | id, content, video_id, user_id, parent_id | 评论表(支持二级评论) |
| t_event | id, title, start_time, end_time, address, max_attendees | 线下活动表 |
5.2 索引优化实践
针对高频查询场景添加索引:
sql复制-- 视频表按舞种分类查询
ALTER TABLE t_video ADD INDEX idx_dance_type (dance_type);
-- 活动表按时间范围查询
ALTER TABLE t_event ADD INDEX idx_time_range (start_time, end_time);
-- 评论表按视频ID查询
ALTER TABLE t_comment ADD INDEX idx_video_id (video_id);
性能提示:对于视频表的like查询(如标题搜索),建议使用Elasticsearch等搜索引擎,而非直接使用MySQL的LIKE操作。
6. 部署与运维方案
6.1 多环境配置
SpringBoot的多环境配置示例:
yaml复制# application-dev.yml
server:
port: 8080
spring:
datasource:
url: jdbc:mysql://localhost:3306/dance_dev
username: devuser
password: dev123
# application-prod.yml
server:
port: 80
spring:
datasource:
url: jdbc:mysql://prod-db:3306/dance_prod
username: ${DB_USER}
password: ${DB_PASS}
redis:
host: redis-master
6.2 Docker容器化部署
后端Dockerfile示例:
dockerfile复制FROM openjdk:8-jdk-alpine
VOLUME /tmp
ARG JAR_FILE=target/*.jar
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java","-jar","/app.jar"]
前端Dockerfile示例:
dockerfile复制FROM nginx:alpine
COPY dist/ /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
配套的docker-compose.yml:
yaml复制version: '3'
services:
backend:
build: ./backend
ports:
- "8080:8080"
environment:
- SPRING_PROFILES_ACTIVE=prod
depends_on:
- mysql
- redis
frontend:
build: ./frontend
ports:
- "80:80"
mysql:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: root123
MYSQL_DATABASE: dance_prod
volumes:
- mysql_data:/var/lib/mysql
redis:
image: redis:alpine
volumes:
mysql_data:
7. 项目扩展与优化方向
在实际开发中,我发现以下几个值得深入优化的点:
-
视频转码服务:上传视频自动转码为自适应码率格式,可使用FFmpeg配合消息队列实现异步处理
-
内容审核机制:集成第三方审核API对用户上传内容进行涉黄涉暴检测
-
性能监控:接入Prometheus+Grafana监控JVM指标和API响应时间
-
CDN加速:静态资源和视频文件走CDN分发,减轻服务器压力
-
TypeScript迁移:逐步将前端代码迁移到TypeScript以获得更好的类型安全
这个项目完整展示了如何将SpringBoot+Vue3+MyBatis技术栈应用到实际业务场景中。在开发过程中,特别要注意前后端接口的版本管理、线上问题的快速定位以及性能瓶颈的持续优化。
