博主介绍:✌全网粉丝3W+,全栈开发工程师,从事多年软件开发,在大厂呆过。持有软件中级、六级等证书。可提供微服务项目搭建与毕业项目实战✌
博主作品:《微服务实战》专栏是本人的实战经验总结,《Spring家族及微服务系列》专注Spring、SpringMVC、SpringBoot、SpringCloud系列、Nacos等源码解读、热门面试题、架构设计等。除此之外还有不少文章等你来细细品味,更多惊喜等着你哦
🍅开源项目免费哦:点击这里克隆或者下载 🍅
🍅文末获取联系🍅精彩专栏推荐订阅👇🏻👇🏻 不然下次找不到哟
✨【微服务】Nacos为什么丢弃短连接(http)而选择拥抱长连接(gRPC)
目录
一、前言
二、系统设计
1、系统运行环境
2、系统架构设计编辑
3、管理员维护订单时序图设计:
三、功能性分析
2、功能模块
四、非功能性与可行性分析
五、功能截图
1、注册登录
2、图书
2.1、图书列表
2.2、添加图书
2.3、图书分类
2.4、出版社
2.5、书单专题
3、订单
3.1、订单列表
3.2、订单详情
4、权限
5、首页
6、点击书籍进来
6.1、需要登录,才能加入购物车成功
6.2、 去购买
6.3、立即下单展示订单信息
六、实现代码
1、角色控制器
2、服务接口
3、实现类
七、参考论文
八、获取源码
一、前言
本系统是基于SpringBoot+MyBatis+Vue+Uniapp的前后端完全分离的书店管理系统。值得一提的是前端使用了目前市场上较流行的组件elementui,在本系统里面对其进行了二次封装,使得页面更加的简洁与优雅,也提高了系统的可维护性。同时探究前端与后端是如何建立数据交互的,以及它为系统提供的服务和已经建好的多张表之间的关系。故课题研究的是这些技术的关联以及如何实现本系统,同时探究系统如何在Linux系统进行Docker容器化部署。
二、系统设计
1、系统运行环境
开发系统:Windows10
架构模式:MVC/前后端分离
JDK版本:Java JDK1.8
开发工具:IDEA
数据库版本: mysql5.7
数据库可视化工具: SQL yog或Navicat for MySQL
服务器:SpringBoot自带 apache tomcat
主要技术:Java、SpringBoot、MyBatis、SpringSecurity、MySQL、Redis、Html、Vue、Elementui等
2、系统架构设计
3、管理员维护订单时序图设计:
三、功能性分析
2、功能模块
这个项目总共分为两类人员,管理员和普通用户。下面对这两类人员的使用的功能进行介绍。
2.1管理员
-
图书管理
- 添加图书
- 删除图书(可批量删除)
- 修改图书
- 查看图书(分页查看)
- 图书上下架(可批量处理)
- 图书推荐(新品推荐、精品推荐,可批量处理)
-
出版社管理
- 新增出版社
- 删除出版社
- 修改出版社(基本信息、排序、启用状态,可分开处理)
- 查看出版社(分页查看)
-
图书分类管理(两级分类)
- 添加分类(两级分类,可自行添加一级分类和二级分类)
- 删除分类(删除一级分类的话所有二级分类也都会删除)
- 修改分类(基本信息和排序)
- 查看分类(分页查看一级分类,以及查看某个一级分类下的二级分类)
-
书单管理
- 添加一个书单专题
- 添加指定图书到书单专题中(可批量处理)
- 删除书单
- 移除书单中的指定图书
- 修改书单(基本信息、权重、上下架状态,可分开处理)
- 查看书单(分页查看)
- 查看指定书单的图书信息(分页查看)
-
订单管理
- 查看订单(分页查看)
- 查看指定订单详细信息(订单商品明细、费用详情、收货地址详情)
- 订单发货(手工填写订单号和快递公司之后确认发货)
- 删除订单
-
用户管理
- 查看注册用户(分页查看)
- 修改用户禁用状态
-
数据统计
- 根据选取时间段查看订单统计(图标显示)
- 其他各类数据的统计
2.2用户
-
页面浏览
- 首页图书的各级分类
- 首页书单的轮播图
- 点击轮播图可查看书单详情页
- 首页图书的各类展示(最新出版、精品推荐、新品推荐、以及图书的分类展示)
- 点击某个分类可查看对应的图书数据(分页展示)
- 图书详情页数据的展示
-
购物车
- 添加商品到购物车
- 删除购物车中指定商品
- 在购物车中修改商品数量
- 查看购物车商品
-
下单模块
- 在商品详情页下单
- 在图书分类展示和书单页面下单
- 在购物车中下单
- 点击下单后会跳转至购买页面进行地址选择,最后再下单确认
-
地址管理
- 添加收货地址信息
- 删除收货地址信息
- 修改收货地址信息
- 查看收货地址地址信息
-
订单管理
- 查看自己所下订单(可分类查看,已付款、未收货、订单回收站)
- 删除订单
- 确认收货
-
个人信息管理
- 个人信息查看
- 个人信息修改
- 密码修改
四、非功能性与可行性分析
2.5非功能性需求分析
非功能性需求:用户对软件质量属性、运行环境、资源约束、外部接口等方面的要求或期望,包括:
2.5.1性能需求:
用户在软件响应速度、结果精度、运行时资源消耗量等方面的要求。
2.5.2可行性需求:
用户在软件失效的频率、严重程度、易恢复性,以及故障可预测性等方面的要求。
2.5.3易用性需求:
用户在界面的易用性、美观性,以及对面向用户的文档和培训资料等方面的要求。
2.5.4安全性需求:
用户在身份证、授权控制、私密性等方面的要求。
2.5.5运行环境约束:
用户对软件系统运行环境的要求。
2.5.6外部接口:
用户对待开发软件系统与其它软件系统或设备之间的接口要求
2.6可行性分析
可行性分析是从不同的角度,对可能影响系统的各方面因素进行分析,确认系统在实际生活上是可行的。本系统只是单纯地从经济、法律、技术、操作可行性四个方面来分析说明。
2.6.1技术可行性
技术上的可行性分析主要分析技术条件能否顺利完成开发工作,软、硬件能否满足需要。本系统采用Vue+Elementui开发出友好美观的人机界面,便于用户理解、操作。数据库管理系统采用MySQL,它能够处理大量数据,同时保持数据的完整性、安全性和持久性。后端技术使用SpringBoot、MyBatis,这些技术在许多公司已经被商用了,因此本系统的开发平台已成熟可行。硬件方面,在科技飞速发展的今天,硬件更新速度越来越快,容量越来越大,可靠性越来越高,价格越来越便宜,因此硬件平台也能够满足本系统所需。
2.6.2经济可行性
项目放在阿里学生服务器或者本地虚拟机的linux环境,故可行。
2.6.3法律可行性
可行,自己写的项目,目的明确,没有违法违规。
2.6.4操作可行性
操作较为简单,而且当下信息科技发达,界面的设计也着实考虑到用户的体验,系统也是为用户而生。故操作是可行的,不存在难度大的操作。
五、功能截图
管理员登录:admin 123456
1、注册登录
首页
2、图书
2.1、图书列表
2.2、添加图书
1)填写书籍信息
2)上传图片等
2.3、图书分类
1)列表
2)查看下级
2.4、出版社
2.5、书单专题
3、订单
3.1、订单列表
3.2、订单详情
4、权限
点击管理系统右上角的首页退出到用户页面
用户登录: 123@qq.com 123456 还可以自己注册
5、首页
6、点击书籍进来
6.1、需要登录,才能加入购物车成功
点击加入购物车,然后到购物车查看
6.2、 去购买
6.3、立即下单展示订单信息
还有一些功能就不一一截图了。
六、实现代码
1、角色控制器
/**
* <p>
* 角色表 服务类
* </p>
*
* @author CeaM
* @since 2023-01-28
*/
public interface ICeamSysRoleService extends IService<CeamSysRole> {
IPage<CeaMSysRoleVO> pageCeaMSysRoleVO(PageableDTO pageable);
/**
* 获取用户权限信息
* @param userId 用户信息
* @return 权限信息
*/
Collection<SimpleGrantedAuthority> grantedAuthorities(Long userId);
/**
*
* @param userId 用户ID
* @return RoleItemVOs
*/
List<RoleDTO> listByUserId(Long userId);
void updateMenu(CeaMSysRoleDTO roleDTO, CeamSysRole role);
}
2、服务接口
/**
* <p>
* 角色表 服务实现类
* </p>
*
* @author CeaM
* @since 2023-01-28
*/
@Slf4j
@Service
@AllArgsConstructor
public class CeamSysRoleServiceImpl extends ServiceImpl<CeamSysRoleMapper, CeamSysRole> implements ICeamSysRoleService {
private ICeamSysMenuService ceamSysMenuService;
private ICeamRoleMenuService ceamRoleMenuService;
@Override
public IPage<CeaMSysRoleVO> pageCeaMSysRoleVO(PageableDTO pageable) {
LambdaQueryWrapper<CeamSysRole> queryWrapper = Wrappers.<CeamSysRole>lambdaQuery()
.eq(CeamSysRole::getDeleted, GlobalConstants.FALSE);
Page<CeamSysRole> page = new Page<>(pageable.getPage(), pageable.getSize());
// 手动设置当前页,不然分页失效
page.setCurrent((long)pageable.getPage() + GlobalConstants.ONE);
Page<CeamSysRole> ceamSysRolePage = page(page, queryWrapper);
IPage<CeaMSysRoleVO> ceaMSysRoleVOIPage = PageVOUtil.copyToPageVO(ceamSysRolePage, CeaMSysRoleVO.class);
for (CeaMSysRoleVO role : ceaMSysRoleVOIPage.getRecords()) {
List<MenuDTO> menuDTOS = ceamSysMenuService.findByRoleId(role.getId(), GlobalConstants.ZERO);
role.setMenus(menuDTOS);
}
return ceaMSysRoleVOIPage;
}
@Override
public Collection<SimpleGrantedAuthority> grantedAuthorities(Long userId) {
List<RoleDTO> roleItemDTOS = this.baseMapper.listByUserId(userId);
if (CollectionUtils.isEmpty(roleItemDTOS)) {
throw new ServiceException("没有分配角色");
}
List<MenuDTO> menuDTOS = ceamSysMenuService.findByRoles(roleItemDTOS, GlobalConstants.ZERO);
// 角色
Set<String> permissions = roleItemDTOS.stream()
.filter(role -> StringUtils.isNotBlank(role.getName()))
.map(RoleDTO::getName).collect(Collectors.toSet());
permissions.addAll(
menuDTOS.stream()
.filter(menu -> StringUtils.isNotBlank(menu.getPermission()))
.map(MenuDTO::getPermission).collect(Collectors.toSet())
);
return permissions.stream().map(SimpleGrantedAuthority::new)
.collect(Collectors.toList());
}
@Override
public List<RoleDTO> listByUserId(Long userId) {
return this.baseMapper.listByUserId(userId);
}
@Override
public void updateMenu(CeaMSysRoleDTO roleDTO, CeamSysRole role) {
if (roleDTO.getMenus().size() > 0) {
List<CeamRoleMenu> rolesMenusList = roleDTO.getMenus().stream().map(i -> {
CeamRoleMenu rolesMenus = new CeamRoleMenu();
rolesMenus.setRoleId(roleDTO.getId());
rolesMenus.setMenuId(i.getId());
return rolesMenus;
}).collect(Collectors.toList());
ceamRoleMenuService.remove(new LambdaQueryWrapper<CeamRoleMenu>()
.eq(CeamRoleMenu::getRoleId, roleDTO.getId()));
ceamRoleMenuService.saveBatch(rolesMenusList);
}
}
}
3、实现类
/**
* <p>
* 角色表 服务实现类
* </p>
*
* @author CeaM
* @since 2023-01-28
*/
@Slf4j
@Service
@AllArgsConstructor
public class CeamSysRoleServiceImpl extends ServiceImpl<CeamSysRoleMapper, CeamSysRole> implements ICeamSysRoleService {
private ICeamSysMenuService ceamSysMenuService;
private ICeamRoleMenuService ceamRoleMenuService;
@Override
public IPage<CeaMSysRoleVO> pageCeaMSysRoleVO(PageableDTO pageable) {
LambdaQueryWrapper<CeamSysRole> queryWrapper = Wrappers.<CeamSysRole>lambdaQuery()
.eq(CeamSysRole::getDeleted, GlobalConstants.FALSE);
Page<CeamSysRole> page = new Page<>(pageable.getPage(), pageable.getSize());
// 手动设置当前页,不然分页失效
page.setCurrent((long)pageable.getPage() + GlobalConstants.ONE);
Page<CeamSysRole> ceamSysRolePage = page(page, queryWrapper);
IPage<CeaMSysRoleVO> ceaMSysRoleVOIPage = PageVOUtil.copyToPageVO(ceamSysRolePage, CeaMSysRoleVO.class);
for (CeaMSysRoleVO role : ceaMSysRoleVOIPage.getRecords()) {
List<MenuDTO> menuDTOS = ceamSysMenuService.findByRoleId(role.getId(), GlobalConstants.ZERO);
role.setMenus(menuDTOS);
}
return ceaMSysRoleVOIPage;
}
@Override
public Collection<SimpleGrantedAuthority> grantedAuthorities(Long userId) {
List<RoleDTO> roleItemDTOS = this.baseMapper.listByUserId(userId);
if (CollectionUtils.isEmpty(roleItemDTOS)) {
throw new ServiceException("没有分配角色");
}
List<MenuDTO> menuDTOS = ceamSysMenuService.findByRoles(roleItemDTOS, GlobalConstants.ZERO);
// 角色
Set<String> permissions = roleItemDTOS.stream()
.filter(role -> StringUtils.isNotBlank(role.getName()))
.map(RoleDTO::getName).collect(Collectors.toSet());
permissions.addAll(
menuDTOS.stream()
.filter(menu -> StringUtils.isNotBlank(menu.getPermission()))
.map(MenuDTO::getPermission).collect(Collectors.toSet())
);
return permissions.stream().map(SimpleGrantedAuthority::new)
.collect(Collectors.toList());
}
@Override
public List<RoleDTO> listByUserId(Long userId) {
return this.baseMapper.listByUserId(userId);
}
@Override
public void updateMenu(CeaMSysRoleDTO roleDTO, CeamSysRole role) {
if (roleDTO.getMenus().size() > 0) {
List<CeamRoleMenu> rolesMenusList = roleDTO.getMenus().stream().map(i -> {
CeamRoleMenu rolesMenus = new CeamRoleMenu();
rolesMenus.setRoleId(roleDTO.getId());
rolesMenus.setMenuId(i.getId());
return rolesMenus;
}).collect(Collectors.toList());
ceamRoleMenuService.remove(new LambdaQueryWrapper<CeamRoleMenu>()
.eq(CeamRoleMenu::getRoleId, roleDTO.getId()));
ceamRoleMenuService.saveBatch(rolesMenusList);
}
}
}
七、参考论文
八、获取源码
大家点赞、收藏、关注、评论啦 、关注下方公众号获取联系方式👇🏻👇🏻
🍅开源项目免费下载🍅商业使用需授权:点击这里下载