基于SpringBoot+VUE的宠物医院后台管理系统【源码开源】【建议收藏】
基于SpringBoot+VUE的宠物医院后台管理系统【源码开源】【建议收藏】
今天给大家开源一个基于SpringBoot+VUE的宠物医院后台管理系统,系统基于脚手架工程,花了大概1周时间做出来的。
该系统完全开源。
系统完美运行,无任何的bug,技术较多,可以当做
面试的项目或者作为毕设的项目。
通过本项目你可以学到:
项目是怎样前后端分离的vue 是如何用于后台管理的如何用MyBaitsPlus 代码生成器生成代码的单表增删改查(包括分页模糊查询)批量删除基于RBAC的权限管理是如何设计的菜单管理又是如何实现的文件上传的实现导入导出主从表的数据是如何在前端呈现的…获取源码的方式见文章底部。
为防止刷着刷着找不到,大家点赞、收藏文章。
具体的介绍如下所示。
1.技术介绍
核心技术:SpringBoot+MyBatis-Plus;
前端:vue+elementui;
开发工具:Idea,VS Code, Git;
数据库:mysql5.7;
2.系统设计
本系统考虑的应用场景是在宠物店或宠物医院里, 主要有预约管理、药品管理、订单管理、充值管理等功能。
主要分了用户、医生和管理员三个角色。每个角色登录系统会有不同的菜单功能呈现,页面中不同的角色有不同的权限。各角色可访问的菜单都由管理员进行配置。
2.1系统功能设计3.功能介绍
3.1登录或注册
没有账号可以注册账号,当前只开放 普通用户的注册。对于医生和管理员的注册,由系统管理员在管理段注册。(默认管理员的账号和密码都是 admin)
登录之后,后台会菜单和权限的配置生成相应数据告知前端,前端进入相应的模块。
4.用户端
4.1就诊预约用户可以查看所有医生信息,并根据宠物病情选择预约对应的医生预约排队(即添加预约信息)。
用户查看自己的预约信息,查看预约审核状态;并实现预约信息的添加,修改,删除,查询功能。
用户可以查询治疗宠物需要用到的所有药品或食品,针对自己宠物需要用到的商品可以进行订购(不能对商品实现添加,修改,删除功能)。
用户可以查看自己的所有商品订单,并实现修改,删除,查询功能,针未支付的订单可以进行支付,收到商品以后进行确认收货。
用户针对自己的账户进行余额充值。每笔充值记录及消费记录都可查询到。
用户可以查看自己的个人信息,并实现修改功能(例如:修改账号,密码等)。
5.医生端
医生的注册目前只能由管理员在管理员端进行注册,暂不开放自己注册。
5.1预约管理医生可以查询预约了自己的所有预约信息,实现预约信息的添加,修改,删除,查询功能。
针对每一个自己诊断的宠物进行记录,方便下次诊断时查询,实现就诊记录的添加,修改,删除,查询功能。
医生可以查看自己的个人信息,并实现修改功能(例如:修改账号,密码等)。
(截图可参见前面用户端的)
6.管理员端
6.1.用户管理查询所有普通用户信息,实现普通用户的添加,修改,删除,查询功能。
查询所有医生信息,实现医生的添加,修改,删除,查询功能。
查询所有治疗宠物的药品或食品信息,实现商品的添加,修改,删除,查询功能。
查询用户的所有订单,针对已经付款的订单进行发货处理,针对已经完成的订单,以及未支付的订单可以进行删除处理,不能修改用户订单。
查询科室信息,实现科室的添加,修改,删除,查询功能。
查询宠物种类信息,实现科室的添加,修改,删除,查询功能。
管理员查询自己的个人信息,并可以实现修改功能(例如:修改账号,密码等)。
(截图可参见前面用户端的)
7.核心代码
/** * <p> * 订单管理控制器 * </p> * * @author * @since 2023-04-24 */ @RestController @RequestMapping("/order") public class OrderController { @Resource private IOrderBaseService orderBaseService; @Resource private IOrderItemService orderItemService; @Resource private IDrugService drugService; @Resource private IUserService userService; private final String now = DateUtil.now(); // 新增或者更新 @PostMapping public 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(); } @GetMapping public 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(); } }
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336/** * <p> * 预约管理控制器 * </p> * * @author * @since 2023-04-23 */ @RestController @RequestMapping("/appointment") public class AppointmentController { @Resource private IAppointmentService appointmentService; @Resource private IUserService userService; @Resource private IDoctorService doctorService; private final String now = DateUtil.now(); // 新增或者更新 @PostMapping public 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(); } }
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821838.设计文档
提供需求说明和关键的业务数据库表字典,很难得喔。
9.源码获取
如果你喜欢这个项目的话, 给个一键三连,点赞越多,往后提高更多的开源项目, 谢谢大家,gitee链接附上。
后端:https://gitee.com/madifu/petHis-backend
前端:https://gitee.com/madifu/petHis-fontend-admin
10.后记
在开发这个系统时,遇到过几个坑,包括 VUE的,还有js 的,它们是怎么绕过去的,将另行文章做相关介绍。
相关知识
基于SpringBoot+Vue宠物医院数字化管理系统
基于SpringBoot+Vue的实现的宠物领养系统免费分享【附源码】
【JAVA程序设计】(C00047)基于springboot+vue的宠物服务管理系统
【毕设精选】基于SpringBoot和Vue的相关系统
开题报告+文档+源码】基于Java的宠物医院管理系统的设计与实现
Java基于的宠物医院系统(源码+mysql+文档)
基于微信小程序的宠物医院宠物健康管理系统(开题报告+源码)
基于SSM的宠物领养系统【源码开源】
基于SpringBoot+Vue的宠物社交平台设计和实现(源码+LW+部署讲解)
【开题报告】基于Springboot+vue基于微信小程序的宠物医院宠物健康管理系统(程序+源码+论文) 计算机毕业设计
网址: 基于SpringBoot+VUE的宠物医院后台管理系统【源码开源】【建议收藏】 https://www.mcbbbk.com/newsview288311.html
上一篇: 宠物管理PPT |
下一篇: 拓瑞宠物医院管理系统免费下载 |
推荐分享

- 1我的狗老公李淑敏33——如何 5096
- 2南京宠物粮食薄荷饼宠物食品包 4363
- 3家养水獭多少钱一只正常 3825
- 4豆柴犬为什么不建议养?可爱的 3668
- 5自制狗狗辅食:棉花面纱犬的美 3615
- 6狗交配为什么会锁住?从狗狗生 3601
- 7广州哪里卖宠物猫狗的选择性多 3535
- 8湖南隆飞尔动物药业有限公司宠 3477
- 9黄金蟒的价格 3396
- 10益和 MATCHWELL 狗 3352