基于Springboot+Vue的电子博物馆系统
前言:随着信息技术的不断发展,传统博物馆的参观方式逐渐向数字化、在线化转型。电子博物馆作为这一转型的重要组成部分,能够通过信息化手段为用户提供更丰富、更便捷的博物馆参观体验。本文基于Spring Boot和Vue.js框架,设计并实现了一个简单的电子博物馆系统,旨在展示数字化博物馆建设的技术架构及开发过程。
目录
- 前言
- 项目功能及技术
- 用户端
- 管理端
- API
- SpringBoot框架搭建
- 实体映射创建Mapper
- 接口封装
- 整合Swagger
- 常用字段类型
- 参考代码块
前言
项目功能及技术
用户端主要有首页、文创展示、浏览记录、网站公告、我的收藏、个人中心等模块。
管理端主要有用户管理、博物馆管理、文创管理、公告管理,博物馆视频管理。vue.js+layui+html+js:用户端界面。
SpringBoot框架+Java程序语言:用户端及后台管理系统API的实现。
Layui前端框架:web后台管理界面样式及数据渲染框架。
MySQL数据库:数据存储。
用户端
管理端
API
SpringBoot框架搭建
1.创建maven project,先创建一个名为SpringBootDemo的项目,选择【New Project】
然后在弹出的下图窗口中,选择左侧菜单的【New Project】
在project下创建module,点击右键选择【new】—【Module…】
左侧选择【Spring initializr】,通过idea中集成的Spring initializr工具进行spring boot项目的快速创建。窗口右侧:name可根据自己喜好设置,group和artifact和上面一样的规则,其他选项保持默认值即可,【next】
Developer Tools模块勾选【Spring Boot DevTools】,web模块勾选【Spring Web】,此时,一个Springboot项目已经搭建完成,可开发后续功能
实体映射创建Mapper
创建一个entity实体类文件夹,并在该文件夹下创建项目用到的实体类
package com.example.demo.entity;import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.Data;import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;@Data
public class User {@TableId(type = IdType.AUTO)private Long id;private String account;private String pwd;private String userDesc;private String userHead;private LocalDateTime createTime;private Long role;private String nickname;private String email;private String tags;
}
接口封装
由于我们使用mybatis-plus,所以简单的增删改查不用自己写,框架自带了,只需要实现或者继承他的Mapper、Service
创建控制器Controller
整合Swagger
添加依赖
先导入spring boot的web包
<!--swagger依赖-->
<dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger2</artifactId><version>2.9.2</version>
</dependency>
<dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger-ui</artifactId><version>2.9.2</version>
</dependency>
配置Swagger
创建一个swagger的配置类,命名为SwaggerConfig.java
/**用于定义API主界面的信息,比如可以声明所有的API的总标题、描述、版本*/private ApiInfo apiDemo() {return new ApiInfoBuilder()//用来自定义API的标题.title("SpringBoot项目SwaggerAPIAPI标题测试")//用来描述整体的API.description("SpringBoot项目SwaggerAPI描述测试")//创建人信息.contact(new Contact("测试员张三","http://localhost:8080/springboot/swagger-ui.html","xxxxxxxx@163.com"))//用于定义服务的域名//.termsOfServiceUrl("").version("1.0") //可以用来定义版本.build();}
接口测试
运行Spring Boot项目,默认端口8080,通过地址栏访问url
接口组定义
根据不同的业务区分不同的接口组,使用@API来划分
@Api(tags = "用户管理") // tags:组名称
@RestController
public class RoleController {
}
接口定义
使用@ApiModel来标注实体类,同时在接口中定义入参为实体类作为参数。
-
@ApiModel:用来标类
-
常用配置项:value:实体类简称;description:实体类说明
-
@ApiModelProperty:用来描述类的字段的含义。
常用字段类型
字段类型 | 所占字节 | 存储范围 | 最大存储值 | 使用场景 |
---|---|---|---|---|
TINYINT | 1 | -128~127 | 127 | 存储小整数 |
INT | 4 | -2147483648~2147483647 | 2147483647 | 存储大整数 |
BIGINT | 8 | -9223372036854775808~9223372036854775807 | 9223372036854775807 | 存储极大整数 |
DECIMAL | 可变长度 | 存储精度要求高的数值 | ||
CHAR | 固定长度 | 最多255字节 | 255个字符 | 存储长度固定的字符串 |
VARCHAR | 可变长度 | 最多65535字节 | 65535个字符 | 存储长度不固定的字符串 |
DATETIME | 8 | ‘1000-01-01 00:00:00’~‘9999-12-31 23:59:59’ | ‘9999-12-31 23:59:59’ | 存储日期和时间 |
参考代码块
<script type="text/javascript">layui.use(['laydate', 'form'], function() {var laydate = layui.laydate;var form = layui.form;// 监听全选});//轻量级框架var dataInfo = new Vue({el: "#content-page",//Vue的数据对象data: {timeSort: 'next', //发布时间排序viewVolumeSort: 'next', //浏览量排序arrayList: [], //数据列表title: null,dynasty: null,typeId: null,areaList: [],appointment: {},swiperSrc: '',indexSwiper: ['https://photo.16pic.com/00/53/26/16pic_5326792_b.jpg','https://img95.699pic.com/desgin_photo/40113/1735_list.jpg','https://file3.renrendoc.com/fileroot_temp3/2022-5/20/f16ee02b-429f-46ad-806f-f453cfb33b80/f16ee02b-429f-46ad-806f-f453cfb33b801.gif',],swiperIndexl: 0,bwgArray:[],}, //数据对象结束//方法methods: {GetAll: function(desc, desc1) {var me = this;me.swiperSrc = me.indexSwiper[0];let list = me.indexSwiper;var swiperIndexl = me.swiperIndexl;me.swiperSrc = list[swiperIndexl];setInterval(function() {me.swiperSrc = list[swiperIndexl];swiperIndexl = (swiperIndexl + 1) % list.length;}, 3000);if (sessionStorage.getItem('user') == null || sessionStorage.getItem('user') == undefined ||sessionStorage.getItem('user') == '') {location.href = "login/login.html"}$.ajax({url: "http://127.0.0.1:8085/exhibition/list",async: false,type: "POST",contentType: 'application/json',dataType: 'json',data: JSON.stringify({}),success: function(json) {me.bwgArray = json.data;}});},gobwgDetail(e) {sessionStorage.setItem("exhibition", JSON.stringify(e));window.location.href = "museumDetail.html";},goAreaDetail(item) {//console.log(id)sessionStorage.setItem("area", JSON.stringify(item));window.location.href = "areaDetail.html";},}, //方法结束created: function() {var vm = this;vm.GetAll('desc', 'desc');}, //初始加载方法结束}); //vue结束function GetQueryString(name) {var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)");var r = window.location.search.substr(1).match(reg);if (r != null) return unescape(r[2]);return null;}</script>
<body><div class="container-fluid" id="content-page"><div class="row top-header"><div class="col-md-1"> </div><div class="col-md-11"><div class="rightMenu"><img src="img/logo.png" class="logo" /><div class="logoTitle">数字博物馆</div><div class="menuBox"><div class="menuTitle"><a href="index.html" style="text-decoration: none;">首页</a></div><div class="menuTitle"><a href="surroundings.html" style="text-decoration: none;">文创展示</a></div><div class="menuTitle"><a href="news.html" style="text-decoration: none;">网站公告</a></div><div class="menuTitle"><a href="history.html" style="text-decoration: none;">浏览记录</a></div><div class="menuTitle"><a href="center.html" style="text-decoration: none;">个人中心</a></div><div class="menuTitle"><a href="./login/login.html" style="text-decoration: none;">退出登录</a></div></div></div></div></div><div class="row"><div class="col-md-1"> </div><div class="col-md-10 paramBox"><div class="displayBox"><div class="sortBox" >当前位置:网站公告<img src="img/news.png" class="sortImg" /></div></div></div><div class="col-md-1"> </div></div><div class="row"><div class="col-md-1"> </div><div class="col-md-10"><div class="iconTitle"><div class="iconParent"><div class="listIcon">网站公告</div></div><div class="topTitle"></div><div class="newTitle" v-for="item in arrayList" @click="goDetail(item)">· {{item.title}}</div></div></div><div class="col-md-1"> </div></div><div class="row"><div style="height:100px;"></div></div></div><script src="js/jquery.min.js"></script><script src="js/vue.js"></script><script src="js/utils.js"></script><script type="text/javascript">//轻量级框架var dataInfo = new Vue({el: "#content-page",//Vue的数据对象data: {timeSort: 'on', //发布时间排序viewVolumeSort: 'on', //浏览量排序arrayList: [], //数据列表}, //数据对象结束//方法methods: {GetAll: function() {var me = this;$.ajax({url: "http://127.0.0.1:8085/announcement/selectPageByUser",async: false,type: "POST",contentType: 'application/json',dataType: 'json',data: JSON.stringify({}),success: function(json) {me.arrayList = json.list;}});},goDetail(e){console.log(e);sessionStorage.setItem("ann",JSON.stringify(e));window.location.href="newsDetail.html";},}, //方法结束created: function() {var vm = this;vm.GetAll();}, //初始加载方法结束}); //vue结束function GetQueryString(name) {var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)");var r = window.location.search.substr(1).match(reg);if (r != null) return unescape(r[2]);return null;}</script>
<div class="container-fluid" id="content-page"><div class="row top-header"><div class="col-md-1"> </div><div class="col-md-11"><div class="rightMenu"><img src="img/logo.png" class="logo" /><div class="logoTitle">数字博物馆</div><div class="menuBox"><div class="menuTitle"><a href="index.html" style="text-decoration: none;">首页</a></div><div class="menuTitle"><a href="surroundings.html" style="text-decoration: none;">文创展示</a></div><div class="menuTitle"><a href="news.html" style="text-decoration: none;">网站公告</a></div><div class="menuTitle"><a href="history.html" style="text-decoration: none;">浏览记录</a></div><div class="menuTitle"><a href="center.html" style="text-decoration: none;">个人中心</a></div><div class="menuTitle"><a href="./login/login.html" style="text-decoration: none;">退出登录</a></div></div></div></div></div><div class="row"><div class="col-md-3"><div class="prevBox"><img src="img/prev.png" class="swiperChangeImg" v-on:click="prevImg" /></div></div><div class="col-md-6 "><div class="swiperBox"><img :src="showSrc" class="swiperItemImg" /></div></div><div class="col-md-3"><div class="nextBox"><img src="img/next.png" class="swiperChangeImg" v-on:click="nextImg"/></div></div></div><div class="row"><div class="col-md-2"> </div><div class="col-md-8"><div class="borerBox"></div></div><div class="col-md-2"> </div></div><div class="row"><div class="col-md-2"> </div><div class="col-md-8"><div class="wwDetailBox"><div class="wwDetailLeft"><div class="wwDetailTitle">名称与朝代</div><div class="wwDetailText">{{info.title}},{{info.dynasty}}</div><div class="wwDetailTitle">出土时间和地点</div><div class="wwDetailText">{{info.address}}</div><div class="wwDetailTitle">材质</div><div class="wwDetailText">{{info.materialQuality}}</div></div><div class="wwDetailRight"><div class="wwDetailTitle">历史文化背景</div><div class="wwDetailText">{{info.history}}</div></div></div></div><div class="col-md-2"> </div></div><div class="row"><div class="col-md-2"> </div><div class="col-md-8"><div style="margin: 20px 0 80px 0;"><video width="100%" height="400" controls><source :src="'http://127.0.0.1:8085/'+info.videoSrc" type="video/mp4"/></video></div></div><div class="col-md-2"> </div></div><!-- <div class="row"><div class="col-md-3"> </div><div class="col-md-6"><div class="wcTypeBox"><div><div class="wcTypeItem">生活用品</div></div></div></div><div class="col-md-3"> </div></div> --><div class="footer"><div class="row"><div class="col-md-4"> </div><div class="col-md-4 "><div class="footerLine1"><a href="javascript:void(0);" class="lineA">相关链接</a><a href="javascript:void(0);" class="lineA">影像授权</a><a href="javascript:void(0);" class="lineA">隐私政策</a><a href="javascript:void(0);" class="lineA">版权说明</a><a href="javascript:void(0);" class="lineA">联系我们</a><a href="javascript:void(0);" class="lineA">关于我们</a></div><div class="footerLine2"><span class="lineB">京公网安备 11010102004165151号</span><span class="lineB">京ICP备05067311号-1</span><span class="lineB">© 2023-至今</span></div></div><div class="col-md-4"> </div></div></div></div><script src="js/jquery.min.js"></script><script src="js/vue.js"></script><script src="js/utils.js"></script><script type="text/javascript">//轻量级框架var dataInfo = new Vue({el: "#content-page",//Vue的数据对象data: {info:{id:1,//名称与朝代name:'越王勾践剑',//出土时间和地点address:'出土时间是1965年12月,,出土于湖北省荆州市江陵县望山楚墓群1号墓',//材质materialQuality:'越王勾践剑的材质主要是青铜和锡的合金。这种合金使得剑身既坚硬又富有韧性,能够保持长久的锋利。同时,剑身上还镀有一层含铬的金属,这使得越王勾践剑在历经千年之后仍然能够保持光泽,不生锈蚀。',//历史文化背景history:'越王勾践剑在历史上的地位十分重要,它不仅是越国强大军事实力的象征,也体现了当时越国工匠的精湛技艺。这把剑见证了越王勾践卧薪尝胆、励精图治的历史故事,也反映了春秋战国时期诸侯争霸、文化交融的时代背景。关于越王勾践,最为人熟知的便是他卧薪尝胆的故事。在吴国战败后,勾践被俘为奴,但他并未放弃复国的信念。他卧薪尝胆,时刻提醒自己不忘国仇家恨,最终成功复仇并重建越国。越王勾践剑作为他的佩剑,见证了这一伟大历程,具有极高的历史价值。',//视频videoSrc:'http://vjs.zencdn.net/v/oceans.mp4',//朝代dynasty:'春秋晚期',//分类typeName:'青铜器',//封面图images:'https://www.chinakongzi.org/zhwh/tpjj/201708/W020170809353217008926.jpg',//轮播图bannerList: ['https://img.zcool.cn/community/015b76608697f511013e3b7dd2fd0d.jpg@1280w_1l_2o_100sh.jpg','https://img.zcool.cn/community/01f475608697f511013f47209e7be5.jpg@1280w_1l_2o_100sh.jpg','https://img.zcool.cn/community/015b3e608697f611013e3b7d0ca587.jpg@1280w_1l_2o_100sh.jpg','https://img.zcool.cn/community/01139e608697f511013f4720a66170.jpg@1280w_1l_2o_100sh.jpg','https://img.zcool.cn/community/0124cf608697f511013e3b7da76892.jpg@1280w_1l_2o_100sh.jpg'],},showSrc: '',currentIndex:0,}, //数据对象结束//方法methods: {GetAll: function() {var vm = this;var id=GetQueryString('id');$.ajax({url: "http://127.0.0.1:8085/question/selectById?id="+id,async: false,type: "POST",contentType: 'application/json',dataType: 'json',success: function(json) {vm.info=json.data;let list = vm.info.banners;var currentIndex = vm.currentIndex;vm.showSrc = "http://127.0.0.1:8085/"+list[currentIndex];setInterval(function() {vm.showSrc = "http://127.0.0.1:8085/"+list[currentIndex];currentIndex = (currentIndex + 1) % list.length;}, 3000);}});},//点击上一页prevImg(){var vm = this;let list = vm.info.banners;var currentIndex = vm.currentIndex;currentIndex = currentIndex-1;if(currentIndex<0){currentIndex = list.length-1;}vm.showSrc = "http://127.0.0.1:8085/"+list[currentIndex];vm.currentIndex =currentIndex;},//点击下一页nextImg(){var vm = this;let list = vm.info.banners;var currentIndex = vm.currentIndex;currentIndex = currentIndex+1;if(currentIndex==list.length){currentIndex = 0;}vm.showSrc = "http://127.0.0.1:8085/"+list[currentIndex];vm.currentIndex =currentIndex;},infoDetail(e) {window.location.href = "museumDetails.html";},}, //方法结束created: function() {var vm = this;vm.GetAll();}, //初始加载方法结束}); //vue结束function GetQueryString(name) {var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)");var r = window.location.search.substr(1).match(reg);if (r != null) return unescape(r[2]);return null;}</script>