基于Spring Boot+Vue的吉他社团系统设计和实现(协同过滤算法)
🎈系统亮点:协同过滤算法;
一.系统开发工具与环境搭建
1.系统设计开发工具
后端使用Java编程语言的Spring boot框架
项目架构:B/S架构
运行环境:win10/win11、jdk17
前端:
技术:框架Vue.js;UI库:ElementUI;
开发工具:Visual Studio Code;
后端:
技术:Java语言、mybatis plus、Spring boot框架;
开发工具:IDEA 2023.3.3版本;
数据库:
数据库:mysql5.7/8.0
数据库工具:Navicat12版本;
二.系统实现(部分截图)
1 用户模块的设计与实现
1.1 用户注册功能的实现
(1)功能设计思路
用户注册需要输入正确的账号、密码、邮箱、联系方式、姓名和图形验证码信息,所有的文本框都为必填,前端会通过正则表达式进行校验输入手机号是否正确,所有的文本是否有值,否则,会弹框提示错误提示文字。当前端验证通过后,将所有的信息通过Axios进行交互,传递给后端接口,后端进行校验用户信息,用户输入的姓名、邮箱、手机号,是否是唯一的,如果查询数据库中已存在该条数据,则报错,并明确告知用户错误原因。通过校验,则注册成功。前端页面跳转到登录界面,进行登录。
(2)实现代码
Long userCount = _AppUserMpper.selectCount(Wrappers.<AppUser>lambdaQuery() .eq(Extension.isNotNullOrEmpty(input.getUserName()),AppUser::getUserName, input.getUserName()));
if (userCount > 0) {throw new CustomException("该用户名已经存在!");
}
Long emailCount = _AppUserMpper.selectCount(Wrappers.<AppUser>lambdaQuery().eq(Extension.isNotNullOrEmpty(input.getUserName()), AppUser::getEmail, input.getEmail()));
if (emailCount > 0) {throw new CustomException("该邮箱已经存在!");
}
Long phoneCount = _AppUserMpper.selectCount(Wrappers.<AppUser>lambdaQuery().eq(Extension.isNotNullOrEmpty(input.getPhoneNumber()), AppUser::getPhoneNumber, input.getPhoneNumber()));
if (phoneCount > 0) {throw new CustomException("该手机号已经存在!");
}
return CreateOrEdit(input);
(3)用户注册展示界面
用户注册界面,用户需要正确的账号、密码、邮箱、联系方式、姓名和图形验证码信息,当通过前后端校验后,会弹框提示注册成功,并跳转到登录界面。
1.2 用户登录功能的实现
(1)功能设计思路
用户登录,用户需要输入已注册过的账号、密码、选择自己的角色信息和图形验证码信息,进行登录,前端会校验所有的文本框是否输入信息,当前端验证通过后,前端会将用户输入的信息通过Axios进行传递给后端接口,后端通过前端请求的url调用SignIn方法,通过账号、密码和角色查询用户表里是否存在该用户信息,不存在,则报错提示。存在,调用其getToken方法,传入包含用户 ID 和角色类型信息的map,生成一个 JWT 字符串,并将其存储在token变量中。最后,将生成的 JWT 返回,这个 JWT 会被用于后续的身份验证。
(2)功能实现代码
List<AppUser> items = _AppUserMpper.selectList(queryWrapper);
if (items.stream().count() == 0) {throw new CustomException("请检查登录的账号或者密码,角色是否都正确!");
}
Map<String, String> map = new HashMap<>();
map.put(SysConst.UserIdClaim, items.get(0).getId().toString());
map.put(SysConst.RoleTypeClaim, items.get(0).getRoleType().toString());
String token = JWTUtils.getToken(map);
return token;
(3) 用户登录展示界面
用户登录界面,用户需要输入存在已经注册过的的账号、密码、选择角色和输入图形验证码信息,当通过前后端校验后,会弹框提示登录成功,并跳转到网站首页界面。
2 社区模块的设计与实现
2.1 社区话题展示功能的实现
(1)功能设计思路
首页作为用户登录后的起始页面,用户展示各类话题。话题按类型进行区分。用户点击不同的类别标签展示该类别下的所有话题列表。话题以卡片形式呈现,每个卡片显示话题的标题及主图。当用户点击某个具体话题时,进入该话题的详情页面。详情页包含话题的完整标题、详细描述、发布者信息以及发布时间。页面底部设有评论区,用户可以阅读已有评论或发表新评论。提供“收藏”按钮,用户可收藏感兴趣的话题以便日后查看。
(2)功能实现代码
LambdaQueryWrapper<Topic> queryWrapper = Wrappers.<Topic>lambdaQuery().eq(input.getId() != null, Topic::getId, input.getId()).eq(input.getCreatorId() != null, Topic::getCreatorId, input.getCreatorId());
//如果传入了关键词
if (Extension.isNotNullOrEmpty(input.getKeyWord())) {queryWrapper = queryWrapper.and(q -> q.like(Topic::getTitle, input.getKeyWord()).or().like(Topic::getContent, input.getKeyWord()));
}
//构建一个分页查询的model
Page<Topic> page = new Page<>(input.getPage(), input.getLimit());
//从数据库进行分页查询获取话题数据
IPage<Topic> pageRecords = _TopicMpper.selectPage(page, queryWrapper);
//获取所有满足条件的数据行数
Long totalCount = _TopicMpper.selectCount(queryWrapper);
//把Topic实体转换成Topic传输模型
List<TopicDto> items = Extension.copyBeanList(pageRecords.getRecords(), TopicDto.class);
for (TopicDto item : items) {ProcessTopicDto(item);
}
return PagedResult.GetInstance(items, totalCount);
(3)社区展示界面
社区展示界面,用户可以通过关键字搜索查询自己想要的社区话题。也可以通过话题分类选择不同的话题,社区允许用户进行收藏和评论话题。对于收藏的话题可以在个人中心查看。
2.2 社区话题管理功能的实现
(1)功能设计思路
管理员拥有对社区话题进行管理的所有权限。提供了高级搜索功能,允许管理员根据话题的标题、类型条件快速定位到特定话题。提供一个“重置”按钮,用于清空搜索框中的所有信息,恢复到初始状态,方便重新输入新的搜索条件。点击任一话题可查看其详细信息。对于不恰当的话题,可以进行勾选多个话题后,选择批量删除。针对单个违规或不当话题,可直接从系统中移除。将优质或热门话题设为推荐,提高其在平台上的可见度。支持管理员手动添加新的话题,丰富平台内容。
(2)功能实现代码
Topic entity = _TopicMpper.selectById(input.getId());
_TopicMpper.deleteById(entity);_TopicCollectMapper.delete(Wrappers.<TopicCollect>lambdaQuery().eq(TopicCollect::getTopicId, input.getId()));
_TopicRecordMpper.delete(Wrappers.<TopicRecord>lambdaQuery().eq(TopicRecord::getTopicId, input.getId()));
(3)社区话题管理展示界面
管理员可以对社区话题进行管理,通过标题、类型搜索对应的话题,对单个话题进行删除,或者通过选择多个话题进行批量删除。允许管理员将某些话题设置为推荐状态,管理员可以对话题的内容、标题或其他相关信息进行修改。
3 二手乐器交易模块模块的设计与实现
3.1 二手乐器交易市场功能的实现
(1)功能设计思路
创建一个搜索框,允许用户输入关键字进行搜索。当用户点击搜索按钮或按下回车键时,将搜索参数传递给后端接口/Good/List。接收后端返回的分页结构数据,包括商品列表和总记录数。在页面上展示商品列表,每个商品显示图片、标题、价格等信息。为每个商品添加一个收藏按钮,用户可以点击收藏感兴趣的商品。在商品详情页面中,展示商品的详细描述、价格等详细信息。提供“我想要”按钮,让用户选择地址并点击支付按钮进行支付操作。
(2) 功能实现代码
if (currentUserDto != null && currentUserDto.getUserId() > 0) {Integer userId = currentUserDto.getUserId();CollaborativeFiltering collaborativeFiltering = new CollaborativeFiltering();List<OrderInfo> orderInfos = _OrderInfoMapper.selectList(null);List<Good> goods = _GoodMpper.selectList(null);for (OrderInfo orderInfo : orderInfos) {collaborativeFiltering.AddUserRating(orderInfo.getCreatorId(), orderInfo.getGoodId(), 1.00);}List<UserCalculateCosineSimilarity> userCalculateCosineSimilarityList = collaborativeFiltering.GetUserCalculateCosineSimilarity(userId);List<Integer> goodIds = userCalculateCosineSimilarityList.stream().flatMap(x -> x.getItemIds().stream()).toList();if (goodIds.size() == 0) {return PagedResult.GetEmptyInstance();}input.setGoodIds(goodIds);return List(input);
}
return PagedResult.GetEmptyInstance();
(3)二手交易市场展示界面
用户通过关键字搜索查询对应的吉他商品信息。将二手吉他按照不同的分类进行展示。当用户点击某个吉他商品时,显示商品的图片、详细描述、价格等。用户对感兴趣的吉他商品进行收藏。点击“我想要”按钮,选择地址,点击“支付”按钮,进行支付。
3.2 二手乐器交易市场管理功能的实现
(1)功能设计思路
提供筛选条件,如名称、审核状态等,以便管理员可以更精确地查找二手吉他商品信息。当管理员点击搜索按钮或按下回车键时,将搜索参数传递给后端接口/Good/List。接收后端返回的二手吉他商品列表数据,并在页面上进行分页展示。为每个商品添加一个删除按钮,管理员可以选择批量删除或单个删除商品。提供一个审核功能,管理员可以对商品进行审核操作,只有审核通过的商品才能被展示。在商品列表中显示商品的基本信息,如名称、价格、介绍内容等。
(2)功能实现代码
//构建where条件+排序
LambdaQueryWrapper<Good> queryWrapper = BuilderQuery(input);
//按创建时间从大到小排序 最新的显示在最前面
queryWrapper = queryWrapper.orderByDesc(Good::getCreationTime);
//构建一个分页查询的model
Page<Good> page = new Page<>(input.getPage(), input.getLimit());
//从数据库进行分页查询获取二手商品数据
IPage<Good> pageRecords = _GoodMpper.selectPage(page, queryWrapper);
//获取所有满足条件的数据行数
Long totalCount = _GoodMpper.selectCount(queryWrapper);
//把Good实体转换成Good传输模型
List<GoodDto> items = Extension.copyBeanList(pageRecords.getRecords(), GoodDto.class);
items = DispatchItem(items);
//返回一个分页结构给前端
return PagedResult.GetInstance(items, totalCount);
(3)二手乐器交易市场管理界面
管理员对二手乐器交易商品进行管理,可以通过名称、商品类型、审核状态等筛选条件进行查询特定的商品信息,对单个商品进行删除,或者通过选择多个话题进行批量删除。支持对新发布的商品进行审核。
4 吉他教学模块模块的设计与实现
4.1 吉他教学功能的实现
(1)功能设计思路
吉他教学功能,允许用户输入关键字进行搜索对应的教学视频当用户点击搜索按钮时,前端通过AJAX技术与后端进行异步通信,发送请求并接收响应。将搜索参数传递给后端接口/Teach/List。后端调用调用MyBatis-Plus的selectPage方法进行分页查询,获取满足条件的吉他教学视频数据。在页面上展示教学视频的主图、标题和发布人等信息。点击不同的分类,则向后端请求对应分类的教学视频数据,并展示不同分类的吉他教学。点击对应的吉他教学,可以进行查看吉他教学视频进行练习。
(2)功能实现代码
public TeachDto Get(TeachPagedInput input) {if (input.getId() == null) {return new TeachDto();}PagedResult<TeachDto> pagedResult = List(input);return pagedResult.getItems().stream().findFirst().orElse(new TeachDto());}
(3)吉他教学展示界面
点击吉他教学菜单栏,进入教学吉他模块,用户可以通过关键字搜索查询自己想要的吉他教学视频。也可以通过点击吉他教学分类进行查询不同分类的教学视频。点击教学视频,即可进行练习。
4.2 吉他教学管理功能的实现
(1)功能设计思路
创建标题、介绍两个搜索框,允许管理员输入关键字进行搜索,以便管理员可以更精确地查找吉他教学视频信息。将搜索参数传递给后端接口 /Teach/List,后端返回JSON格式的数据,返回给前端,进行展示数据。当管理员点击“修改”按钮时,允许管理员对吉他教学信息进行修改。当管理员点击“删除”按钮时,向后端发送删除请求,并接收删除结果。支持批量选择多个教学视频进行批量删除,减少管理员的操作工作量。允许管理员上传新的吉他教学视频。
(2)功能实现代码
public TeachDto CreateOrEdit(TeachDto input) {
//声明一个教学实体
Teach Teach = input.MapToEntity();
//调用数据库的增加或者修改方法
saveOrUpdate(Teach);
//把传输模型返回给前端
return Teach.MapToDto();
}
(3)吉他教学管理界面
管理员拥有对吉他教学进行管理的权限,可以为用户新增吉他教学知识。管理员可以对已有的吉他教学内容进行修改或删除。此外,管理员还支持批量删除功能,可以同时删除多个吉他教学内容。
5 谱曲作品模块模块的设计与实现
5.1 谱曲作品功能的实现
(1)功能设计思路
展示一个谱曲作品列表页面,展示所有用户上传的曲谱作品。在列表中显示曲谱的标题、作者、上传时间等信息。使用分页功能,根据后端传递的页码和每页数量进行分页查询,通过后端返回的JSON格式的数据,动态更新页面内容,展示曲谱作品列表。为每个曲谱作品添加“点评”和“评论”按钮。在点评和评论页面中,用户可以查看其他用户的点评和评论,并进行点赞或回复。
(2)功能实现代码
LambdaQueryWrapper<Writing> queryWrapper = BuilderQuery(input);
//按创建时间从大到小排序 最新的显示在最前面
queryWrapper = queryWrapper.orderByDesc(Writing::getCreationTime);
//构建一个分页查询的model
Page<Writing> page = new Page<>(input.getPage(), input.getLimit());
//从数据库进行分页查询获取作品数据
IPage<Writing> pageRecords = _WritingMpper.selectPage(page, queryWrapper);
//获取所有满足条件的数据行数
Long totalCount = _WritingMpper.selectCount(queryWrapper);
//把Writing实体转换成Writing传输模型
List<WritingDto> items = Extension.copyBeanList(pageRecords.getRecords(), WritingDto.class);
//计算表的数据
items = DispatchItem(items);
//返回一个分页结构给前端
return PagedResult.GetInstance(items, totalCount);
(3) 曲谱作品展示界面
展示所有用户上传的曲谱作品。其他用户可以对这些曲谱作品进行点评和评论,分享自己的观点和点评。同时,还可以通过关键字搜索功能来查找特定的曲谱作品。
5.2 谱曲作品管理功能的实现
(1)功能设计思路
对谱曲作品进行管理,允许管理员输入标题和标签等关键字进行搜索。当管理员点击搜索按钮时,将搜索参数传递给后端接口 /Writing/List,并接收返回的数据。允许管理员输入曲谱的标题、作者、上传文件等详细信息。当管理员填写完表单并点击提交按钮时,向后端发送添加请求,并接收添加结果。为每个曲谱作品添加“修改”和“删除”按钮。当管理员点击“修改”按钮时,根据视频ID查询详细的曲谱内容,并返回给前端。接收前端传递的修改后的曲谱信息,更新数据库中的记录。
(2)功能实现代码
async CreateOrEditForm() {
this.$refs.editModalForm.validate(async valid => {
if (valid) {
var { Success } = await this.$Post(`/Writing/CreateOrEdit`, this.formData);
if (Success) {
this.editorShow = false;
this.$refs.PaginationTableId.Reload(this.searchForm);
}
}
})
}
(4) 曲谱作品管理界面
管理员拥有对曲谱作品的管理权限,能够通过输入特定的信息来查询曲谱的详细信息。在查询到曲谱后,管理员可以对曲谱的信息进行修改。管理员还可以选择删除某个曲谱的信息,以便清理不再需要的曲谱。为了提高操作效率,系统还支持批量删除功能,允许管理员一次性删除多个曲谱信息。
6 活动公告模块模块的设计与实现
6.1 活动公告功能的实现
(1)功能设计思路
系统通知公告,包含一个抽屉组件(el-drawer),标题为“系统通知公告”,并根据visible属性进行同步显示或隐藏。抽屉的方向由direction属性决定,关闭前会调用handleClose方法。在抽屉内部,有一个分页组件(Pagination),用于从"/SysNotice/List"获取数据,并传递一个查询条件对象,其中AuditStatus为2。分页组件的内容部分使用了一个插槽(v-slot:content),用于自定义显示数据的方式。点击标题时,会触发ToDetail方法,并将当前的通知作为参数传递。
(2) 功能实现代码
<el-drawer title="系统通知公告" :visible.sync="drawer" :direction="direction" :before-close="handleClose">
<Pagination url="/SysNotice/List" :where="{ AuditStatus: 2 }">
<template v-slot:content="{ data }">
<div class="padding-lg">
<el-timeline>
<el-timeline-item v-for="(notice, index) in data" :key="index" color="#0bbd87"
:timestamp="notice.CreationTime">
<span @click="ToDetail(notice)"> {{ notice.Title }}</span>
<div style="color:red">发布人:{{ notice.CreatorAppUserDto.Name }}</div>
</el-timeline-item>
</el-timeline>
</div>
</template>
</Pagination>
</el-drawer>
(3)活动公告展示界面
用户点击“通知公告”菜单栏,则会在右边显示所有的系统通知公告,可以查看发布的标题、发布人及时间。当点击具体的系统通知公告时,会在网站中心部分展示详细的公告信息。
4.6.2 活动公告管理功能的实现
(1)功能设计思路
在前端页面中,为每个通知公告添加一个点击事件监听器。当用户点击某个通知公告时,触发该事件进行修改通知公告。后端API接收到请求后,根据提供的通知公告ID查询数据库或其他数据源,找到对应的通知公告详细信息。将查询到的详细信息作为响应返回给前端。前端接收到响应后,解析并展示通知公告的详细信息。管理员进行修改内容,提交成功后,返回列表,展示已经修改后的数据。
(2) 功能实现代码
async CreateOrEditForm() {
this.$refs.editModalForm.validate(async valid => {
if (valid) {
var { Success } = await this.$Post(`/SysNotice/CreateOrEdit`, this.formData);
if (Success) {
this.editorShow = false;
this.$refs.PaginationTableId.Reload(this.searchForm)
}
}
})
}
(3)活动公告管理界面
管理员有权限对活动公告进行操作,提交后的公告进入待审核状态,不会立即显示在前台界面上。对于不符合要求或违规的公告,管理员可以选择删除。如果公告需要调整,管理员可以直接在后台编辑并保存更改。
7.我发布的吉他
8.我买入的订单
9.我卖出的订单
三.需求分析
用户用例图:
管理员用例图:
1.用户管理模块
1.1用户注册:只允许注册用户,管理员账户为统一发放,
1.2用户登录:用于登录和管理用户账号。
1.3管理员登录:可以管理社区、用户、公告管理等模块。
1.4用户可以对自己的信息进行修改。
1.5用户信息分为公开信息,隐私信息和可以自由选择是否公开的信息,用户可以设置这部分信息他人是否可见。
2.社区模块
2.1显示所有已发布的所有帖子,包括其发布者、内容。
2.2管理员可以对帖子进行删除。并可以审核帖子内容是否合格,如果不合格则审核不通过,不允许发布。
2.3用户可以创建新的帖子,并在帖子中发布和吉他有关的内容,也可以评论他人的帖子。
2.4 用户可以查询对应的帖子。
3.二手乐器交易模块
3.1 用户可以将闲置的吉他进行出售。
3.2用户可以查找是否有心仪乐器。
3.3 管理员可以对商品进行审核,决定是否允许出售。
3.4显示订单信息,包括其订单编号、价格、下单日期、用户名等信息。
4.吉他教学模块
4.1用户可以发布吉他教程。用户发布教程时,可以添加分类和贴标签,方便其他用户搜索和筛选。
4.2用户可以分类查询相对应的吉他教程。
4.3用户可以根据标签查询吉他教程。
5.作品管理模块
5.1用户可以上传自己的曲谱,并打上相对应的标签。
5.2用户可以给曲谱进行评分。
5.3用户可以查找想要风格类型的曲谱。
6.活动公告模块
6.1管理员可以直接发布活动公告。普通用户需要进行确认。
6.2普通用户只有查看和确定收到活动公告的权限,但可以向管理员申请发布公告的权限后发布公告。
四.系统代码结构截图
1.后端
2.前端
3.数据库
五.源码获取
1.系统非商用,非开源,非无偿。
2.由本人开发,如需源码,请联系以下方式,koimibuff。
3.项目有很多,并未全部上传,如果未找到想要的,可直接咨询。