项目编号:BS-098-XX
本系统前台面向的用户是客户,客户可以进行预约、浏览医院发布的文章、进入医院商城为宠物购物、如有疑问可以向官方留言、还可以查看关于自己的所有记录信息,如:看病记录、预约记录、疫苗注射记录等。后台面向的用户是医院人员,系统管理员拥有最高权限,可以对所有数据进行管理,为所有的角色分配权限以及创建角色;业务管理员的权限主要是对一些常用数据的维护;医生可以接受客户发布的预约医生的预约单以及处理属于自己的预约单,回答客户的问诊;美容师可以接受客户发布的预约美容的预约单以及处理属于自己的预约单。
本项目核心技术采用Spring Boot+Mybatis;开发工具idea;数据库MySQL5.6;模版引擎采用的是Thymeleaf;安全框架采用Shiro,实现了完整权限系统,Controller方法采用Shiro注解来实现有效的权限控制;前台界面采用了Bootstrap技术;后台界面采用了EasyUI技术;
#### 未注册用户
非注册用户(即游客身份)进入医院官网首页,可以浏览关于医院的宣传以及医院发布的文章,进入医院商城浏览正在发售的商品,搜索已发布的文章和商品,注册以及登录。
#### 已注册用户
注册用户可以修改个人信息和宠物信息,发布预约单(预约医生和美容师),在医院的商城购物,收藏商品,给官方留言,查看与自己相关的记录信息,如:病例记录、预约记录、问诊记录、订单记录等,注销退出系统。
#### 医生
医生可以查看并接受客户发布的未被处理的预约医生的预约单,结束属于自己的预约单,回复客户的网上问诊以及查看自己回复的问诊记录,修改个人密码,安全退出系统。
#### 美容师
美容师可以查看并接受客户发布的未被处理的预约美容师的预约单,结束属于自己的预约单。
#### 业务管理员
业务管理员具有进货管理(包括进货入库、退货出库、进货单据查询、退货单据查询以及当前库存查询)、销售管理(包括销售出库、客户退货入库、销售单据查询、退货单据查询)、库存管理(包括商品报损、商品报溢、库存报警、报损报溢记录查询)、查看统计数据(供应商进退货单统计、客户进退货单统计、按日统计销售利润、按月统计销售利润)、供应商管理、客户管理、商品管理、期初库存管理、前台轮播图管理、设备类型管理、设备管理、设备使用管理、设备使用记录管理、文章类型管理、文章管理、客户留言管理、医院用品管理、医院用品出入库管理、医院用品出入库记录管理、客户消息管理、客户订单处理、客户预约单管理、客户问诊记录管理、病历单管理、化验记录管理、疫苗注射记录管理、客户回访记录管理、寄养记录管理、修改密码、安全退出系统。
#### 系统管理员
系统管理员除了具备业务管理员的所有权限外,还有创建角色并赋予角色权限的功能,还可以查看系统操作日志。
#### 系统自身
系统每天0点自动创建明天的分别属于各个医生或美容师各个时间段的空预约单(未被客户接受的预约单)、每分钟自动筛选出5分钟后过期的空预约单并从数据库删除、每分钟自动筛选和取消客户提交的超过一天未支付的订单并释放库存、每天凌晨1点自动将发布日期超过3个月的商品的"新品"标签去掉、医院上班后(8点)系统自动给当天有预约的客户发送提醒消息
下面展示一下系统的整体功能:
前端首页
商城首页
前端用户登陆注册
个人中心
个人订单
预约医生
客户服务功能
添加到购物车
提交订单
支付订单
新闻文章
后台管理功能
进货管理
销售管理
库存管理
统计报表
基础数据管理
预约单管理
看病服务模块
系统管理模块
具体的角色就不再一一展示了,不同的用户可以根据后台设定不同的操作权限,整体系统的功能非常强大,几乎包含了宠物商城、宠物看病就医、宠物进销存等管理的所有功能模块,可以根据自己的需求选择一部分功能进行使用!
比如医生登陆后:
系统工程结构:
部分核心代码:
package com.ledao.controller; import com.ledao.entity.Article; import com.ledao.service.ArticleService; import com.ledao.service.ArticleTypeService; import com.ledao.util.PageUtil; import com.ledao.util.StringUtil; import org.springframework.stereotype.Controller; import org.springframework.validation.BindingResult; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.servlet.ModelAndView; import javax.annotation.Resource; import javax.validation.Valid; import java.util.HashMap; import java.util.List; import java.util.Map; /** * @author 指南针 * @company * @create 2022-01-27 19:04 */ @Controller @RequestMapping("/article") public class ArticleController { @Resource private ArticleService articleService; @Resource private ArticleTypeService articleTypeService; @RequestMapping("/search") public ModelAndView search(@Valid Article searchArticle, BindingResult bindingResult) { ModelAndView mav = new ModelAndView(); if (bindingResult.hasErrors()) { mav.addObject("error", bindingResult.getFieldError().getDefaultMessage()); mav.addObject("title", "首页"); mav.addObject("mainPage", "page/indexFirst"); } else { Map<String, Object> map = new HashMap<>(16); map.put("title", StringUtil.formatLike(searchArticle.getTitle())); List<Article> articleList = articleService.list(map); mav.addObject("articleList", articleList); mav.addObject("title", "关于(" + searchArticle.getTitle() + ")的文章"); mav.addObject("mainPage", "page/article/articleResult"); mav.addObject("mainPageKey", "#b"); mav.addObject("searchArticle", searchArticle); mav.addObject("total", articleList.size()); } mav.setViewName("index"); return mav; } /** * 分页分类查询文章信息 * * @param page * @param typeId * @return */ @RequestMapping("/list/{id}") public ModelAndView list(@PathVariable(value = "id", required = false) Integer page, @RequestParam(value = "typeId", required = false) Integer typeId) { ModelAndView mav = new ModelAndView(); Map<String, Object> map = new HashMap<>(16); String typeName = articleTypeService.findById(typeId).getName(); map.put("typeId", typeId); int pageSize = 7; map.put("start", (page - 1) * pageSize); map.put("size", pageSize); List<Article> articleList = articleService.list(map); Long total = articleService.getCount(map); mav.addObject("typeName", typeName); mav.addObject("title", "文章列表(" + typeName + ")"); mav.addObject("articleList", articleList); mav.addObject("total", total); mav.addObject("pageCode", PageUtil.genPagination("/article/list", total, page, pageSize, typeId)); mav.addObject("mainPage", "page/article/articleList"); mav.addObject("mainPageKey", "#b"); mav.setViewName("index"); return mav; } /** * 根据id获取文章详细信息 * * @param id * @return */ @RequestMapping("/{id}") public ModelAndView view(@PathVariable(value = "id", required = false) Integer id) { ModelAndView mav = new ModelAndView(); Article article = articleService.findById(id); article.setClick(article.getClick()+1); articleService.update(article); mav.addObject("typeName", articleTypeService.findById(article.getTypeId()).getName()); mav.addObject("article", article); mav.addObject("title", article.getTitle()); mav.addObject("pageCode", this.getLastAndNextArticle(articleService.getLast(id), articleService.getNext(id))); mav.addObject("mainPage", "page/article/articleView"); mav.addObject("mainPageKey", "#b"); mav.setViewName("index"); return mav; } /** * 获取上一篇文章和下一篇文章 * * @param lastArticle * @param nextArticle * @return */ private String getLastAndNextArticle(Article lastArticle, Article nextArticle) { StringBuffer pageCode = new StringBuffer(); if (lastArticle == null || lastArticle.getId() == null) { pageCode.append("<p>上一篇:没有了</p>"); } else { pageCode.append("<p>上一篇:<a href='/article/" + lastArticle.getId() + "'>" + lastArticle.getTitle() + "</a></p>"); } if (nextArticle == null || nextArticle.getId() == null) { pageCode.append("<p>下一篇:没有了</p>"); } else { pageCode.append("<p>下一篇:<a href='/article/" + nextArticle.getId() + "'>" + nextArticle.getTitle() + "</a></p>"); } return pageCode.toString(); } }
package com.ledao.controller; import com.ledao.entity.*; import com.ledao.service.*; import com.ledao.util.PageUtil; import com.ledao.util.StringUtil; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.servlet.ModelAndView; import javax.annotation.Resource; import javax.servlet.http.HttpSession; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; /** * 前台客户商品评论Controller层 * * @author 指南针 * @company * @create 2022-05-27 23:04 */ @Controller @RequestMapping("/comment") public class CommentController { @Resource private CommentService commentService; @Resource private GoodsService goodsService; @Resource private SaleListGoodsService saleListGoodsService; @Resource private ReturnListGoodsService returnListGoodsService; @Resource private GoodsTypeService goodsTypeService; @Resource private CustomerService customerService; @Resource private FavoriteService favoriteService; /** * 我的化验记录 * * @param page * @param session * @return */ @RequestMapping("/myComment/list/{id}") public ModelAndView myComment(@PathVariable(value = "id", required = false) Integer page, HttpSession session) { ModelAndView mav = new ModelAndView(); Map<String, Object> map = new HashMap<>(16); int pageSize = 4; map.put("start", (page - 1) * pageSize); map.put("size", pageSize); Customer currentCustomer = (Customer) session.getAttribute("currentCustomer"); map.put("customerId", currentCustomer.getId()); List<Comment> commentList = commentService.list(map); for (Comment comment : commentList) { comment.setGoods(goodsService.findById(comment.getGoodsId())); comment.setSaleListGoods(saleListGoodsService.findById(comment.getSaleListGoodsId())); comment.setSaleList(comment.getSaleListGoods().getSaleList()); } Long total = commentService.getCount(map); mav.addObject("commentList", commentList); mav.addObject("total", total); mav.addObject("pageCode", PageUtil.genPagination2("/comment/myComment/list", total, page, pageSize)); mav.addObject("title", "我的评论"); mav.addObject("mainPage", "page/comment/myComment"); mav.addObject("mainPageKey", "#b"); mav.setViewName("index"); return mav; } /** * 跳转到客户评价商品界面 * * @param saleListGoodsId * @return */ @RequestMapping("/commentPage") public ModelAndView commentPage(Integer saleListGoodsId) { ModelAndView mav = new ModelAndView(); SaleListGoods saleListGoods = saleListGoodsService.findById(saleListGoodsId); Goods goods = goodsService.findById(saleListGoods.getGoodsId()); mav.addObject("saleListGoods", saleListGoods); mav.addObject("goods", goods); mav.addObject("title", "评价商品"); mav.addObject("mainPage", "page/comment/commentPage"); mav.addObject("mainPageKey", "#b"); mav.setViewName("index"); return mav; } /** * 添加商品评价 * * @param comment * @return */ @RequestMapping("/save") public String save(Comment comment, HttpSession session) { Customer currentCustomer = (Customer) session.getAttribute("currentCustomer"); comment.setCustomerId(currentCustomer.getId()); commentService.add(comment); SaleListGoods saleListGoods = saleListGoodsService.findById(comment.getSaleListGoodsId()); saleListGoods.setStatus(1); saleListGoodsService.update(saleListGoods); return "redirect:/comment/myComment/list/1"; } /** * 查看评价详情 * * @param commentId * @return */ @RequestMapping("/commentDetails") public ModelAndView commentDetails(Integer commentId) { Comment comment = commentService.findById(commentId); comment.setGoods(goodsService.findById(comment.getGoodsId())); ModelAndView mav = new ModelAndView(); mav.addObject("comment", comment); mav.addObject("title", "查看评价详情"); mav.addObject("mainPage", "page/comment/commentDetails"); mav.addObject("mainPageKey", "#b"); mav.setViewName("index"); return mav; } @RequestMapping("/customerComment/list/{id}") public ModelAndView customerComment(@PathVariable(value = "id", required = false) Integer page, Integer goodsId, HttpSession session) { ModelAndView mav = new ModelAndView(); Map<String, Object> map = new HashMap<>(16); int pageSize = 4; map.put("start", (page - 1) * pageSize); map.put("size", pageSize); map.put("goodsId", goodsId); List<Comment> commentList = commentService.list(map); for (Comment comment : commentList) { comment.setCustomer(customerService.findById(comment.getCustomerId())); } Long total = commentService.getCount(map); List<GoodsType> goodsTypeList = goodsTypeService.findByParentId(1); for (GoodsType goodsType : goodsTypeList) { goodsType.setSmallGoodsTypeList(goodsTypeService.findByParentId(goodsType.getId())); } Map<String, Object> map2 = new HashMap<>(16); map.put("typeId", goodsService.findById(goodsId).getType().getId()); List<Goods> goodsList = goodsService.list(map2); Collections.shuffle(goodsList); goodsList.remove(goodsService.findById(goodsId)); Goods goods = goodsService.findById(goodsId); this.setGoodsFavorite(goods,session); mav.addObject("allSaleTotal", saleListGoodsService.getSaleCount(goods.getId()) - returnListGoodsService.getReturnCount(goods.getId())); mav.addObject("goodsTypeList", goodsTypeList); mav.addObject("goods", goods); mav.addObject("commentList", commentList); mav.addObject("recommendGoodsList", goodsList); mav.addObject("total", total); mav.addObject("pageCode", PageUtil.genPagination3("/comment/customerComment/list", total, page, pageSize,goodsId)); mav.addObject("title", "客户评价"); mav.addObject("mainPage", "page/comment/customerComment"); mav.addObject("mainPageKey", "#b"); mav.setViewName("index"); return mav; } /** * 给商品设置是否已收藏标签(0否,1是) * * @param goods */ private void setGoodsFavorite(Goods goods, HttpSession session) { Map<String, Object> map = new HashMap<>(16); map.put("customer", session.getAttribute("currentCustomer")); List<Favorite> favoriteList = favoriteService.list(map); for (Favorite favorite : favoriteList) { if (goods.getId().equals(favorite.getGoods().getId())) { goods.setIsFavorite(1); } } } }
package com.ledao.controller; import com.ledao.entity.Customer; import com.ledao.entity.Log; import com.ledao.entity.Pet; import com.ledao.service.CustomerService; import com.ledao.service.LogService; import com.ledao.service.PetService; import com.ledao.util.DateUtil; import com.ledao.util.PageUtil; import org.apache.commons.io.FileUtils; import org.apache.shiro.authz.annotation.RequiresPermissions; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Controller; import org.springframework.validation.BindingResult; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.multipart.MultipartFile; import org.springframework.web.servlet.ModelAndView; import javax.annotation.Resource; import javax.servlet.http.HttpSession; import javax.validation.Valid; import java.io.File; import java.util.HashMap; import java.util.List; import java.util.Map; /** * 前台客户Controller层 * * @author 指南针 * @company * @create 2022-01-30 14:57 */ @Controller @RequestMapping("/customer") public class CustomerController { @Value("${customerImageFilePath}") private String customerImageFilePath; @Resource private CustomerService customerService; @Resource private PetService petService; /** * 添加或者修改客户信息 * * @param customer * @return */ @RequestMapping("/save") public ModelAndView save(Customer customer, @RequestParam("customerImage") MultipartFile file, HttpSession session) throws Exception { if (!file.isEmpty()) { if (customer.getId() != null) { FileUtils.deleteQuietly(new File(customerImageFilePath + customerService.findById(customer.getId()).getImageName())); } // 获取上传的文件名 String fileName = file.getOriginalFilename(); // 获取文件的后缀 String suffixName = fileName.substring(fileName.lastIndexOf(".")); String newFileName = DateUtil.getCurrentDateStr2() + suffixName; FileUtils.copyInputStreamToFile(file.getInputStream(), new File(customerImageFilePath + newFileName)); customer.setImageName(newFileName); } if (customer.getId() == null) { customerService.add(customer); ModelAndView mav = new ModelAndView("redirect:/login"); mav.addObject("successRegister", true); mav.addObject("title", "用户登录"); mav.addObject("mainPage", "page/login"); mav.addObject("mainPageKey", "#b"); return mav; } else { customerService.update(customer); ModelAndView mav = new ModelAndView("redirect:/customer/personalCenter"); mav.addObject("successModify", true); mav.addObject("title", "个人中心"); mav.addObject("mainPage", "page/customer/personalCenterFirst"); customer.setImageName(customerService.findById(customer.getId()).getImageName()); session.setAttribute("currentCustomer", customer); mav.addObject("mainPageKey", "#b"); return mav; } } /** * 客户登录 * * @param customer * @param bindingResult * @param session * @return */ @RequestMapping("/login") public ModelAndView login(@Valid Customer customer, BindingResult bindingResult, HttpSession session) { ModelAndView mav = new ModelAndView(); if (bindingResult.hasErrors()) { mav.addObject("customer", customer); mav.addObject("error", bindingResult.getFieldError().getDefaultMessage()); mav.addObject("title", "用户登录"); mav.addObject("mainPage", "page/login"); } else { List<Customer> customerList = customerService.findByUserName(customer.getUserName()); if (customerList.size() != 0) { Customer currentCustomer = customerService.findByUserName(customer.getUserName()).get(0); if (currentCustomer.getPassword().equals(customer.getPassword())) { session.setAttribute("currentCustomer", currentCustomer); mav.addObject("successLogin", true); mav.addObject("title", "首页"); mav.addObject("mainPage", "page/indexFirst"); } else { mav.addObject("successLogin", false); mav.addObject("title", "用户登录"); mav.addObject("mainPage", "page/login"); } } else { mav.addObject("successLogin", false); mav.addObject("title", "用户登录"); mav.addObject("mainPage", "page/login"); } } mav.addObject("mainPageKey", "#b"); mav.setViewName("index"); return mav; } /** * 退出登录返回的页面 * * @param session * @return */ @RequestMapping("/logout") public ModelAndView logout(HttpSession session) { session.invalidate(); ModelAndView mav = new ModelAndView(""); mav.addObject("title", "用户登录"); mav.addObject("mainPage", "page/indexFirst"); mav.addObject("mainPageKey", "#b"); mav.setViewName("index"); return mav; } /** * 跳转到修改个人中心页面 * * @return */ @RequestMapping("/personalCenter") public ModelAndView personalCenter() { ModelAndView mav = new ModelAndView(); mav.addObject("title", "个人中心"); mav.addObject("mainPage", "page/customer/personalCenterFirst"); mav.addObject("mainPageKey", "#b"); mav.setViewName("index"); return mav; } /** * 跳转到修改个人信息页面 * * @return */ @RequestMapping("/personalCenter/ModifyMessage") public ModelAndView personalCenterModifyMessage() { ModelAndView mav = new ModelAndView(); mav.addObject("title", "修改个人信息"); mav.addObject("mainPage", "page/customer/personalCenterModifyMessage"); mav.addObject("mainPageKey", "#b"); mav.setViewName("index"); return mav; } /** * 客户注册时判断用户名是否已经存在 * * @param userName * @return */ @ResponseBody @RequestMapping("/existUserWithUserName") public Map<String, Object> existUserWithUserName(String userName) { Map<String, Object> resultMap = new HashMap<>(16); Long count = customerService.getCountByUserName(userName); if (count != 0) { resultMap.put("success", true); } else { resultMap.put("success", false); } return resultMap; } /** * 查看我的宠物 * * @return */ @RequestMapping("/myPet/list/{id}") public ModelAndView myPet(@PathVariable(value = "id", required = false) Integer page, HttpSession session) { ModelAndView mav = new ModelAndView(); Map<String, Object> map = new HashMap<>(16); int pageSize = 3; map.put("start", (page - 1) * pageSize); map.put("size", pageSize); map.put("customer", session.getAttribute("currentCustomer")); List<Pet> petList = petService.list(map); Long total = petService.getCount(map); mav.addObject("petList", petList); mav.addObject("total", total); mav.addObject("pageCode", PageUtil.genPagination2("/customer/myPet/list", total, page, pageSize)); mav.addObject("title", "我的宠物"); mav.addObject("mainPage", "page/customer/myPet"); mav.addObject("mainPageKey", "#b"); mav.setViewName("index"); return mav; } /** * 添加宠物信息页面 * * @return */ @RequestMapping("/petAdd") public ModelAndView petAdd() { ModelAndView mav = new ModelAndView(); mav.addObject("title", "添加宠物信息"); mav.addObject("mainPage", "page/customer/petAdd"); mav.addObject("mainPageKey", "#b"); mav.setViewName("index"); return mav; } /** * 修改宠物信息页面 * * @param petId * @return */ @RequestMapping("/petModify") public ModelAndView petModify(Integer petId) { Pet pet = petService.findById(petId); ModelAndView mav = new ModelAndView(); mav.addObject("pet", pet); mav.addObject("title", "修改宠物信息"); mav.addObject("mainPage", "page/customer/petModify"); mav.addObject("mainPageKey", "#b"); mav.setViewName("index"); return mav; } /** * 查看宠物信息页面 * * @param petId * @return */ @RequestMapping("/petDetails") public ModelAndView petDetails(Integer petId) { Pet pet = petService.findById(petId); ModelAndView mav = new ModelAndView(); mav.addObject("pet", pet); mav.addObject("title", "查看宠物信息"); mav.addObject("mainPage", "page/customer/petDetails"); mav.addObject("mainPageKey", "#b"); mav.setViewName("index"); return mav; } }