全国非物质文化遗产展示平台是一个基于SpringBoot框架开发的B/S架构系统,旨在通过数字化手段保护和传承我国丰富的非物质文化遗产资源。作为一名有10年开发经验的Java全栈工程师,我在实际开发过程中发现这类文化展示平台存在几个关键痛点:传统展示方式受限于地域和时间、非遗项目资料分散难以整合、公众参与度低等。
这个平台采用前后端分离架构,后端使用SpringBoot+MyBatisPlus,前端采用Vue.js,数据库选用MySQL,实现了非遗项目的分类展示、详情查询、用户互动等功能模块。相比市面上同类产品,我们的创新点在于:
系统采用经典的三层架构:
这种架构选择的优势在于:
在application.yml中我们做了以下关键配置:
yaml复制server:
port: 8080
servlet:
context-path: /ich
spring:
datasource:
url: jdbc:mysql://localhost:3306/ich_db?useSSL=false&serverTimezone=Asia/Shanghai
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
global-config:
db-config:
logic-delete-field: delFlag
logic-delete-value: 1
logic-not-delete-value: 0
采用Shiro进行权限控制,核心配置类如下:
java复制@Configuration
public class ShiroConfig {
@Bean
public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager) {
ShiroFilterFactoryBean factoryBean = new ShiroFilterFactoryBean();
factoryBean.setSecurityManager(securityManager);
Map<String, String> filterMap = new LinkedHashMap<>();
filterMap.put("/admin/**", "authc, roles[admin]");
filterMap.put("/user/**", "authc");
factoryBean.setFilterChainDefinitionMap(filterMap);
return factoryBean;
}
}
非遗项目表设计:
sql复制CREATE TABLE `ich_item` (
`id` bigint NOT NULL AUTO_INCREMENT,
`name` varchar(100) NOT NULL COMMENT '项目名称',
`category_id` int NOT NULL COMMENT '分类ID',
`region_code` varchar(20) NOT NULL COMMENT '地区编码',
`level` tinyint DEFAULT '3' COMMENT '保护级别:1-国家级 2-省级 3-市级',
`cover_image` varchar(255) DEFAULT NULL COMMENT '封面图',
`description` text COMMENT '项目描述',
`video_url` varchar(255) DEFAULT NULL COMMENT '视频链接',
`status` tinyint DEFAULT '1' COMMENT '状态:0-下架 1-上架',
`create_time` datetime DEFAULT CURRENT_TIMESTAMP,
`update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `idx_category` (`category_id`),
KEY `idx_region` (`region_code`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
采用MyBatisPlus的代码生成器自动生成基础CRUD代码,然后扩展自定义查询:
java复制@Service
public class ItemServiceImpl extends ServiceImpl<ItemMapper, Item> implements ItemService {
@Override
public Page<ItemVO> searchItems(ItemQueryDTO queryDTO) {
return baseMapper.selectItemPage(new Page<>(queryDTO.getPage(), queryDTO.getSize()), queryDTO);
}
@Override
@Transactional
public boolean saveItem(ItemDTO itemDTO) {
Item item = new Item();
BeanUtils.copyProperties(itemDTO, item);
// 处理封面图上传
if (itemDTO.getCoverFile() != null) {
String imagePath = fileService.upload(itemDTO.getCoverFile());
item.setCoverImage(imagePath);
}
return save(item);
}
}
前端Vue组件关键代码:
vue复制<template>
<div class="comment-box">
<el-input
type="textarea"
:rows="3"
placeholder="留下您的评论..."
v-model="content"
></el-input>
<div class="action-bar">
<el-button type="primary" size="small" @click="submitComment">提交</el-button>
</div>
<div class="comment-list">
<div v-for="comment in comments" :key="comment.id" class="comment-item">
<div class="user-info">
<el-avatar :src="comment.avatar"></el-avatar>
<span class="username">{{ comment.nickname }}</span>
</div>
<div class="content">{{ comment.content }}</div>
<div class="time">{{ comment.createTime | formatDate }}</div>
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
content: '',
comments: []
}
},
methods: {
async submitComment() {
if (!this.content.trim()) {
this.$message.warning('评论内容不能为空')
return
}
try {
await this.$api.comment.add({
itemId: this.itemId,
content: this.content
})
this.$message.success('评论成功')
this.content = ''
this.loadComments()
} catch (e) {
this.$message.error(e.message)
}
}
}
}
</script>
推荐使用Docker Compose进行容器化部署,docker-compose.yml配置示例:
yaml复制version: '3'
services:
mysql:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: 123456
MYSQL_DATABASE: ich_db
ports:
- "3306:3306"
volumes:
- ./mysql/data:/var/lib/mysql
- ./mysql/conf:/etc/mysql/conf.d
redis:
image: redis:6
ports:
- "6379:6379"
volumes:
- ./redis/data:/data
backend:
build: ./backend
ports:
- "8080:8080"
depends_on:
- mysql
- redis
environment:
SPRING_PROFILES_ACTIVE: prod
frontend:
build: ./frontend
ports:
- "80:80"
java复制@Cacheable(value = "items", key = "#id")
public ItemVO getItemDetail(Long id) {
return baseMapper.selectDetailById(id);
}
@CacheEvict(value = "items", key = "#itemId")
public void updateItem(ItemDTO itemDTO) {
// 更新逻辑
}
java复制@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*")
.allowedMethods("GET", "POST", "PUT", "DELETE")
.allowedHeaders("*")
.maxAge(3600);
}
}
yaml复制spring:
servlet:
multipart:
max-file-size: 10MB
max-request-size: 20MB
java复制@Configuration
@EnableSwagger2
public class SwaggerConfig {
@Bean
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.basePackage("com.ich.controller"))
.paths(PathSelectors.any())
.build();
}
}
这个项目从技术选型到最终部署上线共耗时2个月,其中最大的挑战是非遗数据的结构化处理。我们开发了一套数据采集工具,将分散的非遗资料转化为统一的JSON格式,便于系统展示和分析。在实际运行中,平台的日均PV达到了5万+,证明了这种技术方案的有效性。