基于SpringBoot+VUE的宠物医院后台管理系统【源码开源】【建议收藏】

今天给大家开源一个基于SpringBoot+VUE的宠物医院后台管理系统,系统基于脚手架工程,花了大概1周时间做出来的。

该系统完全开源。

系统完美运行,无任何的bug,技术较多,可以当做
面试的项目或者作为毕设的项目。

通过本项目你可以学到:

  • 项目是怎样前后端分离的
  • vue 是如何用于后台管理的
  • 如何用MyBaitsPlus 代码生成器生成代码的
  • 单表增删改查(包括分页模糊查询)
  • 批量删除
  • 基于RBAC的权限管理是如何设计的
  • 菜单管理又是如何实现的
  • 文件上传的实现
  • 导入导出
  • 主从表的数据是如何在前端呈现的

获取源码的方式见文章底部。

为防止刷着刷着找不到,大家点赞、收藏文章。

具体的介绍如下所示。

1.技术介绍

核心技术:SpringBoot+MyBatis-Plus;

前端:vue+elementui;

开发工具:Idea,VS Code, Git;

数据库:mysql5.7;

2.系统设计

本系统考虑的应用场景是在宠物店或宠物医院里, 主要有预约管理、药品管理、订单管理、充值管理等功能。

主要分了用户、医生和管理员三个角色。每个角色登录系统会有不同的菜单功能呈现,页面中不同的角色有不同的权限。各角色可访问的菜单都由管理员进行配置。

2.1系统功能设计

2.2预约流程

2.3就诊流程

2.4商品流程

2.5充值流程

3.功能介绍

3.1登录或注册


没有账号可以注册账号,当前只开放 普通用户的注册。对于医生和管理员的注册,由系统管理员在管理段注册。(默认管理员的账号和密码都是 admin)

登录之后,后台会菜单和权限的配置生成相应数据告知前端,前端进入相应的模块。

4.用户端

4.1就诊预约

用户可以查看所有医生信息,并根据宠物病情选择预约对应的医生预约排队(即添加预约信息)。

4.2预约管理

用户查看自己的预约信息,查看预约审核状态;并实现预约信息的添加,修改,删除,查询功能。

4.3药品管理

用户可以查询治疗宠物需要用到的所有药品或食品,针对自己宠物需要用到的商品可以进行订购(不能对商品实现添加,修改,删除功能)。

4.4订单管理

用户可以查看自己的所有商品订单,并实现修改,删除,查询功能,针未支付的订单可以进行支付,收到商品以后进行确认收货。

4.5充值中心

用户针对自己的账户进行余额充值。每笔充值记录及消费记录都可查询到。

4.6个人中心

用户可以查看自己的个人信息,并实现修改功能(例如:修改账号,密码等)。

5.医生端

医生的注册目前只能由管理员在管理员端进行注册,暂不开放自己注册。

5.1预约管理

医生可以查询预约了自己的所有预约信息,实现预约信息的添加,修改,删除,查询功能。

5.2诊断管理

针对每一个自己诊断的宠物进行记录,方便下次诊断时查询,实现就诊记录的添加,修改,删除,查询功能。

5.3.个人中心

医生可以查看自己的个人信息,并实现修改功能(例如:修改账号,密码等)。
(截图可参见前面用户端的)

6.管理员端

6.1.用户管理

查询所有普通用户信息,实现普通用户的添加,修改,删除,查询功能。

6.2.医生管理

查询所有医生信息,实现医生的添加,修改,删除,查询功能。

6.3.药品管理

查询所有治疗宠物的药品或食品信息,实现商品的添加,修改,删除,查询功能。

6.4.订单管理

查询用户的所有订单,针对已经付款的订单进行发货处理,针对已经完成的订单,以及未支付的订单可以进行删除处理,不能修改用户订单。

6.5.科室管理

查询科室信息,实现科室的添加,修改,删除,查询功能。

6.6.宠物种类管理

查询宠物种类信息,实现科室的添加,修改,删除,查询功能。

6.7.个人中心

管理员查询自己的个人信息,并可以实现修改功能(例如:修改账号,密码等)。
(截图可参见前面用户端的)

7.核心代码

/*** <p>*  订单管理控制器* </p>** @author * @since 2023-04-24*/
@RestController
@RequestMapping("/order")
public class OrderController {@Resourceprivate IOrderBaseService orderBaseService;@Resourceprivate IOrderItemService orderItemService;@Resourceprivate IDrugService drugService;@Resourceprivate IUserService userService;private final String now = DateUtil.now();// 新增或者更新@PostMappingpublic Result save(@RequestBody OrderDTO orderDTO) {if (orderDTO.getItems() == null || orderDTO.getItems().size()<1) {return Result.error(Constants.CODE_400, "参数错误.订单缺少项目信息");}if (StringUtils.isEmpty(orderDTO.getReceiverPhone())) {return Result.error(Constants.CODE_400, "参数错误.请提供收货人电话");}if (StringUtils.isEmpty(orderDTO.getReceiverAddress())) {return Result.error(Constants.CODE_400, "参数错误.请提供收货人地址");}//判断用户是否存在QueryWrapper<User> queryWrapperCustom = new QueryWrapper<>();queryWrapperCustom.eq("username", orderDTO.getUserName());queryWrapperCustom.eq("role", RoleEnum.ROLE_USER.toString());User findUser = userService.getOne(queryWrapperCustom);if (null == findUser) {return Result.error(Constants.CODE_404, "用户不存在");}if (orderDTO.getRemark() == null) {orderDTO.setRemark("");}BigDecimal totalAmount = new BigDecimal(0);OrderBase orderBase = new OrderBase();orderBase.setStatus(OrderBase.OrderStatus.UN_PAY);orderBase.setPayMode(OrderBase.PayMode.UNKNOWN);orderBase.setPayVoucherNo("");orderBase.setUserId(findUser.getId());orderBase.setUserName(findUser.getUsername());orderBase.setReceiverPhone(orderDTO.getReceiverPhone());orderBase.setReceiverAddress(orderDTO.getReceiverAddress());orderBase.setRemark(orderDTO.getRemark());long oid = 0;if (orderDTO.getId() == null) {//添加操作OrderIdGenerator orderIdGenerator = new OrderIdGenerator();oid = orderIdGenerator.nextId(this);orderDTO.setId(oid);User currentUser = TokenUtils.getCurrentUser();orderBase.setCreateName(currentUser.getUsername());orderBase.setCreateBy(String.valueOf(currentUser.getId()));orderBase.setCreateRole(currentUser.getRole());orderBase.setCreateTime(new Date());}else {//更新操作oid = orderDTO.getId();//找出原订单信息OrderBase oldOrder = orderBaseService.getById(oid);if (null == oldOrder) {return Result.error(Constants.CODE_404, "订单记录不存在.id=" + oid);}//只有待支付状态的订单才 可以 修改if (oldOrder.getStatus() != OrderBase.OrderStatus.UN_PAY) {return Result.error(Constants.CODE_600, "只有待支付状态的订单才可以修改 .id=" + oid);}orderBase.setCreateName(oldOrder.getCreateName());orderBase.setCreateBy(oldOrder.getCreateBy());orderBase.setCreateRole(oldOrder.getCreateRole());orderBase.setCreateTime(oldOrder.getCreateTime());//删除原来项目 表的内容orderItemService.delByOrderId(oid);}//先保存项目表int seq = 0;String orderOverview = "" ; // 订单项目简要for (OrderItem orderItem: orderDTO.getItems() ) {orderItem.setOrderId(oid);//处理 序号seq++;orderItem.setSeq(seq);if (orderItem.getItemId() == null ) {return Result.error(Constants.CODE_400, "参数错误. 订单项目id为Null");};if (orderItem.getQty() == null ) {return Result.error(Constants.CODE_400, "参数错误. 订单项目数量为Null");}if (orderItem.getQty() <= 0 ) {return Result.error(Constants.CODE_400, "参数错误. 订单项目数量必须大于0");}//数据库中查找商品是否存在Drug drug = drugService.getById(orderItem.getItemId());if (null == drug) {return Result.error(Constants.CODE_400, "参数错误. 商品不存在. 项目id=" + orderItem.getItemId());}orderItem.setPrice(drug.getRetailPrice());orderItem.setName(drug.getName() + " " + drug.getProductName());orderItem.setUnit(drug.getUnit());orderOverview += "|";orderOverview += orderItem.getName();//计算合计totalAmount = totalAmount.add(orderItem.getPrice().multiply(new BigDecimal(orderItem.getQty())));if (!orderItemService.save(orderItem)) {return Result.error(Constants.CODE_600, "业务异常.无法保存某订单的项目.项目id=" + orderItem.getItemId());};}orderOverview += "|";if (orderOverview.length()>128) {orderOverview = orderOverview.substring(0,127);}orderBase.setId(oid);orderBase.setOverview(orderOverview);orderBase.setAmount(totalAmount);//再保存主表的if (orderBaseService.saveOrUpdate(orderBase)) {return Result.success();}else {return Result.error(Constants.CODE_600, "业务异常.保存订单主表失败" );}}@DeleteMapping("/{id}")public Result delete(@PathVariable Long id) {OrderBase orderBase = orderBaseService.getById(id);if (null == orderBase ){return Result.error(Constants.CODE_404, "订单不存在. 订单id=" + id );}//只能删除未支付或已签收的订单if (orderBase.getStatus()==OrderBase.OrderStatus.UN_PAY ||orderBase.getStatus()==OrderBase.OrderStatus.SIGN ) {;}else {return Result.error(Constants.CODE_600, "无效订单状态.只能删除未支付或已签收的订单");}//先删除项目表的记录orderItemService.delByOrderId(id);orderBaseService.removeById(id);return Result.success();}@PostMapping("/del/batch")public Result deleteBatch(@RequestBody List<Long> ids) {//先删除项目表的记录for (Long id: ids) {orderItemService.delByOrderId(id);}orderBaseService.removeByIds(ids);return Result.success();}@GetMappingpublic Result findAll() {return Result.success(orderBaseService.list());}@GetMapping("/{id}")public Result findOne(@PathVariable Long id) {return Result.success(orderBaseService.getById(id));}@GetMapping("/page")public Result findPage(@RequestParam(defaultValue = "") String userName,@RequestParam Integer pageNum,@RequestParam Integer pageSize) {QueryWrapper<OrderBase> queryWrapper = new QueryWrapper<>();queryWrapper.orderByDesc("create_time");if (!"".equals(userName)) {queryWrapper.like("user_name", userName);}User currentUser = TokenUtils.getCurrentUser();if (currentUser.getRole().equals(RoleEnum.ROLE_USER.toString())) {//普通用户只能查看自己的预约记录queryWrapper.eq("user_id", currentUser.getId());}Object object = orderBaseService.page(new Page<>(pageNum, pageSize), queryWrapper);return Result.success(object);//return Result.success(orderBaseService.page(new Page<>(pageNum, pageSize), queryWrapper));}@GetMapping("/items/{id}")public Result findOrderItems(@PathVariable Long id) {//查找订单项目列表QueryWrapper<OrderItem> queryWrapper = new QueryWrapper<>();queryWrapper.orderByDesc("seq");queryWrapper.eq("order_id", id);return Result.success(orderItemService.list(queryWrapper));}/*** 导出接口*/@GetMapping("/export")public void export(HttpServletResponse response) throws Exception {// 从数据库查询出所有的数据List<OrderBase> list = orderBaseService.list();// 在内存操作,写出到浏览器ExcelWriter writer = ExcelUtil.getWriter(true);// 一次性写出list内的对象到excel,使用默认样式,强制输出标题writer.write(list, true);// 设置浏览器响应的格式response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");String fileName = URLEncoder.encode("OrderBase信息表", "UTF-8");response.setHeader("Content-Disposition", "attachment;filename=" + fileName + ".xlsx");ServletOutputStream out = response.getOutputStream();writer.flush(out, true);out.close();writer.close();}/*** excel 导入* @param file* @throws Exception*/@PostMapping("/import")public Result imp(MultipartFile file) throws Exception {InputStream inputStream = file.getInputStream();ExcelReader reader = ExcelUtil.getReader(inputStream);// 通过 javabean的方式读取Excel内的对象,但是要求表头必须是英文,跟javabean的属性要对应起来List<OrderBase> list = reader.readAll(OrderBase.class);orderBaseService.saveBatch(list);return Result.success();}@PostMapping("/delivery/{id}")public Result delivery(@PathVariable Long id) {//发货//判断订单是否存在OrderBase orderBase = orderBaseService.getById(id);if (null == orderBase) {return Result.error(Constants.CODE_404, "订单不存在.订单id=" + id);}//判断订单是否已经支付if (orderBase.getStatus() == OrderBase.OrderStatus.PAYED){}else {return Result.error(Constants.CODE_600, "订单不是已支付状态, 不允许发货.");}if (orderBaseService.updateDeliveryInfo(id, OrderBase.OrderStatus.DELIVERED, new Date()) >0) {return Result.success(orderBaseService.getById(id));}else {return Result.error(Constants.CODE_600, "业务异常.更新订单发货信息失败" );}}@PostMapping("/sign/{id}")public Result sign(@PathVariable Long id) {//签收,//判断订单是否存在OrderBase orderBase = orderBaseService.getById(id);if (null == orderBase) {return Result.error(Constants.CODE_404, "订单不存在.订单id=" + id);}//判断订单是否已经支付if (orderBase.getStatus() == OrderBase.OrderStatus.DELIVERED){;}else {return Result.error(Constants.CODE_600, "订单不是已发货状态, 不允许签收.");}if (orderBaseService.updateSignInfo(id, OrderBase.OrderStatus.SIGN, new Date())>0) {return Result.success(orderBaseService.getById(id));}else {return Result.error(Constants.CODE_600, "业务异常.更新订单签收信息失败" );}}private User getUser() {return TokenUtils.getCurrentUser();}}
/*** <p>*  预约管理控制器* </p>** @author * @since 2023-04-23*/
@RestController
@RequestMapping("/appointment")
public class AppointmentController {@Resourceprivate IAppointmentService appointmentService;@Resourceprivate IUserService userService;@Resourceprivate IDoctorService doctorService;private final String now = DateUtil.now();// 新增或者更新@PostMappingpublic Result save(@RequestBody Appointment appointment) {if (appointment.getAppointmentTime() == null) {return Result.error(Constants.CODE_400, "参数错误:请提供预约时间");}//查找顾客信息QueryWrapper<User> queryWrapperCustom = new QueryWrapper<>();queryWrapperCustom.eq("username", appointment.getCustomName());queryWrapperCustom.eq("role", RoleEnum.ROLE_USER.toString());User findCustom = userService.getOne(queryWrapperCustom);if (null == findCustom) {return Result.error(Constants.CODE_404, "顾客不存在");}appointment.setCustomId(findCustom.getId());appointment.setCustomName(findCustom.getUsername());appointment.setCustomPhone(findCustom.getPhone());//查找医生信息QueryWrapper<User> queryWrapperDoctor = new QueryWrapper<>();queryWrapperDoctor.eq("username", appointment.getDoctorName());queryWrapperDoctor.eq("role", RoleEnum.ROLE_DOCTOR.toString());User findDoctor = userService.getOne(queryWrapperDoctor);if (null == findDoctor) {return Result.error(Constants.CODE_404, "医生不存在");}appointment.setDoctorId(findDoctor.getId());appointment.setDoctorName(findDoctor.getUsername());appointment.setDoctorPhone(findDoctor.getPhone());if (appointment.getRemark() == null) {appointment.setRemark("");}if (appointment.getId() == null) {//添加操作appointment.setStatus(Appointment.AppointmentStatus.WAIT_AUDIT);User currentUser = TokenUtils.getCurrentUser();appointment.setCreateName(currentUser.getUsername());appointment.setCreateBy(String.valueOf(currentUser.getId()));appointment.setCreateRole(currentUser.getRole());appointment.setCreateTime(new Date());}else {//更新操作if (appointment.getStatus() == null) {return Result.error(Constants.CODE_400, "参数错误:请提供预约状态");}//不更新原 创建人信息Appointment  oldAppointment = appointmentService.getById(appointment.getId());if (null==oldAppointment) {return Result.error(Constants.CODE_404, "预约记录不存在");}appointment.setCreateName(oldAppointment.getCreateName());appointment.setCreateBy(oldAppointment.getCreateBy());appointment.setCreateRole(oldAppointment.getCreateRole());appointment.setCreateTime(oldAppointment.getCreateTime());}appointmentService.saveOrUpdate(appointment);return Result.success();}@DeleteMapping("/{id}")public Result delete(@PathVariable Long id) {appointmentService.removeById(id);return Result.success();}@PostMapping("/del/batch")public Result deleteBatch(@RequestBody List<Long> ids) {appointmentService.removeByIds(ids);return Result.success();}//    @GetMapping
//    public Result findAll() {//        return Result.success(appointmentService.list());
//    }@GetMapping("/{id}")public Result findOne(@PathVariable Long id) {return Result.success(appointmentService.getById(id));}@GetMapping("/page")public Result findPage(@RequestParam Integer pageNum,@RequestParam Integer pageSize,@RequestParam(defaultValue = "") String customName,@RequestParam(defaultValue = "") String doctorName) {QueryWrapper<Appointment> queryWrapper = new QueryWrapper<>();queryWrapper.orderByDesc("id");if (!"".equals(customName)) {queryWrapper.like("custom_name", customName);}if (!"".equals(doctorName)) {queryWrapper.like("doctor_name", doctorName);}User currentUser = TokenUtils.getCurrentUser();if (currentUser.getRole().equals(RoleEnum.ROLE_USER.toString())) {//普通用户只能查看自己的预约记录queryWrapper.eq("create_by", currentUser.getId());}else if (currentUser.getRole().equals(RoleEnum.ROLE_DOCTOR.toString())) {//医生可以查看自己的记录和 别人约自己的queryWrapper.eq("create_by", currentUser.getId()).or().eq("doctor_id", currentUser.getId());}return Result.success(appointmentService.page(new Page<>(pageNum, pageSize), queryWrapper));}/*** 导出接口*/@GetMapping("/export")public void export(HttpServletResponse response) throws Exception {// 从数据库查询出所有的数据List<Appointment> list = appointmentService.list();// 在内存操作,写出到浏览器ExcelWriter writer = ExcelUtil.getWriter(true);// 一次性写出list内的对象到excel,使用默认样式,强制输出标题writer.write(list, true);// 设置浏览器响应的格式response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");String fileName = URLEncoder.encode("Appointment信息表", "UTF-8");response.setHeader("Content-Disposition", "attachment;filename=" + fileName + ".xlsx");ServletOutputStream out = response.getOutputStream();writer.flush(out, true);out.close();writer.close();}/*** excel 导入* @param file* @throws Exception*/@PostMapping("/import")public Result imp(MultipartFile file) throws Exception {InputStream inputStream = file.getInputStream();ExcelReader reader = ExcelUtil.getReader(inputStream);// 通过 javabean的方式读取Excel内的对象,但是要求表头必须是英文,跟javabean的属性要对应起来List<Appointment> list = reader.readAll(Appointment.class);appointmentService.saveBatch(list);return Result.success();}private User getUser() {return TokenUtils.getCurrentUser();}}

8.设计文档

提供需求说明和关键的业务数据库表字典,很难得喔。

9.源码获取

如果你喜欢这个项目的话, 给个一键三连,点赞越多,往后提高更多的开源项目, 谢谢大家,gitee链接附上。

后端:https://gitee.com/madifu/petHis-backend
前端:https://gitee.com/madifu/petHis-fontend-admin

10.后记

在开发这个系统时,遇到过几个坑,包括 VUE的,还有js 的,它们是怎么绕过去的,将另行文章做相关介绍。

基于SpringBoot+VUE的宠物医院后台管理系统【源码开源】【建议收藏】相关推荐

  1. java计算机毕业设计Vue框架电商后台管理系统源码+mysql数据库+系统+lw文档+部署

    java计算机毕业设计Vue框架电商后台管理系统源码+mysql数据库+系统+lw文档+部署 java计算机毕业设计Vue框架电商后台管理系统源码+mysql数据库+系统+lw文档+部署 本源码技术栈 ...

  2. java计算机毕业设计Vue框架电商后台管理系统源码+数据库+系统+lw文档

    java计算机毕业设计Vue框架电商后台管理系统源码+数据库+系统+lw文档 java计算机毕业设计Vue框架电商后台管理系统源码+数据库+系统+lw文档 本源码技术栈: 项目架构:B/S架构 开发语 ...

  3. springboot+vue+mysql外卖点餐管理系统源码(包安装+讲解)

     博主介绍:✌在职Java研发工程师.专注于程序设计.源码分享.技术交流.专注于Java技术领域和毕业设计✌ 项目名称 springboot+vue+mysql外卖点餐管理系统源码(包安装+讲解) 视 ...

  4. 【毕业设计专栏】基于SpringBoot+Vue学生综合测评系统【源码+论文+演示PPT视频】

    目录 1.效果演示 2.系统介绍 3. 系统的详细设计与展示 3.1 学生后台管理模块 3.2管理员功能模块 4.系统分析与设计 4.1可行性分析 4.1.1 技术可行性分析 4.1.2 经济可行性分 ...

  5. 计算机毕业设计Springboot+vue的宠物销售商城网站(源码+系统+mysql数据库+Lw文档)

    一.项目运行 开发语言:Java 开发工具:IDEA /Eclipse 数据库:MYSQL5.7 应用服务:Tomcat7/Tomcat8 使用框架:springboot+vue 宠物是人类最好的伙伴 ...

  6. [JAVA毕业设计]Vue框架电商后台管理系统源码获取和系统演示

    项目运行 环境配置: Jdk1.8 + Tomcat8.5 + Mysql + HBuilderX(Webstorm也行)+ Eclispe(IntelliJ IDEA,Eclispe,MyEclis ...

  7. springboot+vue宠物医院诊所管理系统源码

    开发环境及工具: 大等于jdk1.8,大于mysql5.5,idea(eclipse),nodejs,vscode(webstorm) 技术说明: springboot mybatis vue ele ...

  8. 基于springboot vue elementui的物品租赁系统源码

    开发环境及工具: 大等于jdk1.8,大于mysql5.5,idea(eclipse),vscode(webstorm) 技术说明: springboot mybatis vue elementui ...

  9. 基于SpringBoot+Vue 实现准妈妈孕期交流平台【源码+论文+演示视频+包运行成功】

    您好,我是码农飞哥(wei158556),感谢您阅读本文,欢迎一键三连哦.

最新文章

  1. DateGridView列的输出顺序反了
  2. 自学大数据需要从哪里入手 收藏了一份详细的学习路线图
  3. 数据库操作(使用FMDB)
  4. 线转hdmi为什么检测不到_为什么苹果MacBook这么保值?
  5. python网络通信的几种方式_python网络-计算机网络基础(23)
  6. 面试再也不怕问到HashMap(二)
  7. 优酷开放SDK之setOnTimeOutListener
  8. how is opportunity detail page display first item by default
  9. 【概率论】3-4:二维分布(Bivariate Distribution)
  10. Python脚本生成单个EXE文件
  11. ffmpeg处理RTMP流媒体的命令大全
  12. ElasticSearch分词近义词
  13. 服务器无线存储器,教你把无线路由器打造成网络存储器
  14. 第二关练习讲解(下部)
  15. 深入浅出 Docker
  16. iPhone 界面尺寸以及各种图表尺寸
  17. 第二章 预习导图 部署DNS服务
  18. shellcode转换
  19. 教务管理系统数据表关系图_浙江工商大学教务处
  20. thunderbird 登录网易邮箱

热门文章

  1. 介绍一款 MRICT 图像预处理强大工具--FSL
  2. 影视解析Xyplayer 3.95正式版
  3. C# Panel Graphic 绘图闪烁解决办法
  4. LAMP项目部署实战2
  5. 14.学习Camera之——camera基本知识
  6. oracle里IW和WW 区别
  7. 2013年软件考试报名
  8. 移动网络限速后,确实慢多了
  9. Python将形如”\xe4...的十六进制编码字符串恢复为中文
  10. 计算机基础 —— 海明码 (C++实现)