作者主页:编程千纸鹤
作者简介:Java、前端、Pythone开发多年,做过高程,项目经理,架构师
主要内容:Java项目开发、毕业设计开发、面试技术整理、最新技术分享
一,项目简介
随着互联网技术逐渐的深入到生活,人们的生活消费习惯,已经发生很大的变化。就餐厅用餐而言,互联网技术和移动互联网技术的应用也己相关普及,比如早几年前就出现的餐厅点餐系统,就通过信息化的技术手段代替原来纸质菜单点餐的传统方式。这种方式一是可以方便顾客实现点餐叫号,二是方便商家进行人单合一的统一管理,减少了报单出错率,提升了用户的体验,所以得以大面积的应用和普及。
而移动互联网的出现,让智能手机的赋能更大广泛,腾讯微信适时推出微信小程序,使得智能手机的用户可以通过微信进行相应的信息化管理和参与,比如目前大面积应用的小程序商城,就将商业的业态从传统的PC互联网直接植入手机移动互联网,这种轻量级的APP应用,极大的方便使用者,也给商家通过微信带了大量的流量。
微信小程序的功能推出,极大方便了全国2亿多的微信用户,在这个生态体系上构建了一个宠大的商业帝国,而小程序开发的应用,又快速的渗透到各个行业。在餐饮行业的信息化应用,也发生了一系统变化,比如通过微信小程序实现用户自助点餐功能,这就极大的方便了用户,减少了点餐的距离限制,用户可以在餐厅打开手机微信小程序进行点餐,也可以在去餐厅的途中或者甚至在家就可以点餐,打破了时空的限制,更加的灵活方便。经过调查和实地分析,基于对微信小程序的研究,开发了这套微信小程序点餐系统,为餐饮业的信息化建设添砖加瓦。
根据上述对微信小程序点餐系统的功能性需求分析,设计出了微信小程序点餐系统的功能结构图,如下图1-1所示。
图1-1 系统功能结构图
前台用户登陆小程序,采用微信账户绑定登陆实现。目前由于测试账户没开通此权限,只能用开发者的身份来进行测试进行。前台用户可以在手机小程序上浏览系统发布的餐品,实现完整的订餐流程。看中相应的餐品可以添加到购物车中,然后下单购买,并可以查看相关的订单信息。
后台用户必须登陆方可进行相应的操作,主要进行相应的业务数据管理。
用户管理:可以管理前端和后端的用户信息,进行相应的数据增删改查操作。
餐品管理:可以管理点餐系统发布的餐品信息,进行相应的数据增删改查操作。
订单管理:对前端用户的下单信息进行相应的管理操作。
分类管理:主要实现对前端点餐显示的餐品分类管理。
系统管理:主要可以实现对系统的相关基本信息的管理操作。
二,环境介绍
后台开发:
语言环境:Java: jdk1.8
数据库:Mysql: mysql5.7
应用服务器:Tomcat: tomcat8.5.31
开发工具:IDEA或eclipse
前端开发:
开发工具:微信开发者工具
开发技术:微信小程序
整体采用前后端分离开发,前后端单独测试
三,系统展示
3.1 微信小程序功能模块的展示
3.1.1 前台首页展示
微信小程序点餐前端主要就是实现点餐操作,主要包含预约点餐、菜单浏览、电话订餐、客服个模块。具体操作界面展示如下图4-1所示。
图3-1 前台首页界面
3.1.2 前台菜单浏览模块
用户进入微信点餐系统进入浏览菜单即可查看餐厅发布的餐品信息,具体如下图3-2所示:
图3-2 菜单浏览界面
3.1.3前台用户购物车模块
微信小程序点餐前台用户登陆系统后可以进入预约点餐模块将餐品添加到购物车。用户登陆直接绑定用户微信账户进行登陆,非常方便。添加购物车操作界面如下图3-3所示。
图3-3前台用户添加购物车操作界面
3.1.4 前台用户点餐支付模块
前台用户登陆点餐系统后,可以进入预约点餐模块将喜欢的餐品添加到购物车后提交订单并进行支付购买。完成餐品购买后并完成整个订单操作后,可以对餐品进行相关的评论。相关管理操作界面如下图3-4所示。
图3-4前台用户点餐支付界面
3.1.4前台用户个人订单管理模块
微信小程序点餐前台用户登陆系统后可以在我的模块中个人订单管理模块中管理个人的订单信息。前端用户个人订单管理操作界面如下图3-5所示。
图3-5前台用户个人订单管理操作界面
3.2后台功能模块的展示
3.2.1用户登录功能
微信小程序点餐后台用户如果想要对餐厅的相关信息进行管理操作,首先要登录系统,才可展开相关的操作。输入手机号和密码后用户登陆界面如下图3-6所示。
图3-6用户登录操作界面
3.2.2用户管理功能
微信小程序点餐系统管理员用户登陆系统后,可以进入用户管理菜单进行相应的管理员用户信息管理。用户管理操作界面如下图3-7、3-8所示:
图3-7后台用户管理功能界面图
图3-8后台用户新增界面图
3.2.3 后台餐品管理操作UI
微信小程序点餐管理员用户登陆系统后,可以进入餐品管理菜单进行相应的餐品信息管理。其中主要包含餐品的添加、修改、查询、下架操作等,添加餐品时可以指定餐品的图片进行展示。餐品信息管理操作界面如下图3-9、3-10所示。
图3-9后台餐品管理功能UI界面
图3-10后台餐品新增功能UI界面
3.2.4 后台餐品订单管理操作UI
微信小程序点餐系统管理员用户登陆系统后,可以进入餐品订单管理菜单进行相应的餐品订单信息管理。其中主要包含餐品订单的查询、订单明细的查看等,添加餐品时可以上传餐品的图片进行展示。订单信息管理操作界面如下图3-11、3-12所示。
图3-11后台订单管理功能UI界面
图3-12后台订单详情查看功能UI界面
四,核心代码展示
package com.imooc.controller; import com.imooc.constant.CookieConstant; import com.imooc.constant.RedisConstant; import com.imooc.dataobject.SellerInfo; import com.imooc.enums.ResultEnum; import com.imooc.exception.SellException; import com.imooc.form.SellerForm; import com.imooc.repository.SellerInfoRepository; import com.imooc.utils.CookieUtil; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.validation.BindingResult; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.servlet.ModelAndView; import java.util.List; import java.util.Map; import java.util.UUID; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.validation.Valid; import lombok.extern.slf4j.Slf4j; @RestController @RequestMapping("/admin") @Slf4j public class AdminUserController { @Autowired SellerInfoRepository repository; /** * 后台用户登陆操作 * @param phone * @param password * @param response * @return */ @GetMapping("/loginAdmin") public String loginAdmin(@RequestParam("phone") String phone, @RequestParam("password") String password, HttpServletResponse response) { SellerInfo sellerInfo = repository.findByPhone(phone); log.info("商家信息={}", sellerInfo); if (sellerInfo != null && sellerInfo.getPassword().equals(password)) { String token = UUID.randomUUID().toString(); log.info("登录成功的token={}", token); Integer expire = RedisConstant.EXPIRE; //3. 设置token至cookie CookieUtil.set(response, CookieConstant.TOKEN, token, expire); return "登录成功"; } else { throw new SellException(ResultEnum.LOGIN_FAIL); } } @GetMapping("/logout") public ModelAndView logout(HttpServletRequest request, HttpServletResponse response, Map<String, Object> map) { //1. 从cookie里查询 Cookie cookie = CookieUtil.get(request, CookieConstant.TOKEN); if (cookie != null) { //2. 清除cookie CookieUtil.set(response, CookieConstant.TOKEN, null, 0); } map.put("msg", ResultEnum.LOGOUT_SUCCESS.getMessage()); map.put("url", "/sell/seller/order/list"); return new ModelAndView("common/success", map); } /* * 页面相关 * */ @GetMapping("/list") public ModelAndView list(Map<String, Object> map) { List<SellerInfo> categoryList = repository.findAll(); map.put("categoryList", categoryList); return new ModelAndView("admin/list", map); } @GetMapping("/index") public ModelAndView index(@RequestParam(value = "sellerId", required = false) Integer sellerId, Map<String, Object> map) { SellerInfo sellerInfo = repository.findBySellerId(sellerId); map.put("category", sellerInfo); return new ModelAndView("admin/index", map); } /** * 保存/更新 */ @PostMapping("/save") public ModelAndView save(@Valid SellerForm form, BindingResult bindingResult, Map<String, Object> map) { log.info("SellerForm={}", form); if (bindingResult.hasErrors()) { map.put("msg", bindingResult.getFieldError().getDefaultMessage()); map.put("url", "/sell/admin/index"); return new ModelAndView("common/error", map); } SellerInfo sellerInfo = new SellerInfo(); try { if (form.getSellerId() != null) { sellerInfo = repository.findBySellerId(form.getSellerId()); } BeanUtils.copyProperties(form, sellerInfo); repository.save(sellerInfo); } catch (SellException e) { map.put("msg", e.getMessage()); map.put("url", "/sell/admin/index"); return new ModelAndView("common/error", map); } map.put("url", "/sell/admin/list"); return new ModelAndView("common/success", map); } }
package com.imooc.controller; import com.imooc.VO.ResultVO; import com.imooc.converter.OrderForm2OrderDTOConverter; import com.imooc.dto.OrderDTO; import com.imooc.enums.ResultEnum; import com.imooc.exception.SellException; import com.imooc.form.OrderForm; import com.imooc.service.BuyerService; import com.imooc.service.OrderService; import com.imooc.utils.ResultVOUtil; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.util.CollectionUtils; import org.springframework.util.StringUtils; import org.springframework.validation.BindingResult; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.validation.Valid; import lombok.extern.slf4j.Slf4j; /** * Created by znz */ @RestController @RequestMapping("/buyer/order") @Slf4j public class BuyerOrderController { @Autowired private OrderService orderService; @Autowired private BuyerService buyerService; //创建订单 @PostMapping("/create") public ResultVO<Map<String, String>> create(@Valid OrderForm orderForm, BindingResult bindingResult) { if (bindingResult.hasErrors()) { log.error("【创建订单】参数不正确, orderForm={}", orderForm); throw new SellException(ResultEnum.PARAM_ERROR.getCode(), bindingResult.getFieldError().getDefaultMessage()); } OrderDTO orderDTO = OrderForm2OrderDTOConverter.convert(orderForm); if (CollectionUtils.isEmpty(orderDTO.getOrderDetailList())) { log.error("【创建订单】购物车不能为空"); throw new SellException(ResultEnum.CART_EMPTY); } OrderDTO createResult = orderService.create(orderDTO); Map<String, String> map = new HashMap<>(); map.put("orderId", createResult.getOrderId()); return ResultVOUtil.success(map); } //订单列表 @GetMapping("/listByStatus") public ResultVO<List<OrderDTO>> listByStatus(@RequestParam("openid") String openid, @RequestParam(value = "orderStatus", defaultValue = "0") Integer orderStatus) { if (StringUtils.isEmpty(openid)) { log.error("【查询订单列表】openid为空"); throw new SellException(ResultEnum.PARAM_ERROR); } List<OrderDTO> orderList = buyerService.findOrderList(openid, orderStatus); return ResultVOUtil.success(orderList); } //订单详情 @GetMapping("/detail") public ResultVO<OrderDTO> detail(@RequestParam("openid") String openid, @RequestParam("orderId") String orderId) { OrderDTO orderDTO = buyerService.findOrderOne(openid, orderId); return ResultVOUtil.success(orderDTO); } //确认收货 @PostMapping("/sure") public ResultVO sure(@RequestParam("openid") String openid, @RequestParam("orderId") String orderId) { buyerService.cancelOrder(openid, orderId); return ResultVOUtil.success(); } //取消订单 @PostMapping("/cancel") public ResultVO cancel(@RequestParam("openid") String openid, @RequestParam("orderId") String orderId) { buyerService.cancelOrder(openid, orderId); return ResultVOUtil.success(); } }
package com.imooc.controller; import com.imooc.VO.ResultVO; import com.imooc.dataobject.Comment; import com.imooc.dataobject.OrderMaster; import com.imooc.dto.OrderDTO; import com.imooc.enums.OrderStatusEnum; import com.imooc.enums.ResultEnum; import com.imooc.exception.SellException; import com.imooc.repository.CommentRepository; import com.imooc.repository.OrderMasterRepository; import com.imooc.service.OrderService; import com.imooc.utils.ResultVOUtil; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.util.StringUtils; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import java.util.List; /** * desc:评论相关 */ @RestController public class CommentController { @Autowired private CommentRepository repository; @Autowired private OrderService orderService; @Autowired private OrderMasterRepository masterRepository; //订单详情 @PostMapping("/comment") public ResultVO<Comment> detail(@RequestParam("openid") String openid, @RequestParam("orderId") String orderId, @RequestParam("name") String name, @RequestParam("avatarUrl") String avatarUrl, @RequestParam("content") String content) { if (StringUtils.isEmpty(openid) || StringUtils.isEmpty(orderId)) { throw new SellException(ResultEnum.PARAM_ERROR); } //提交评论 Comment comment = new Comment(); comment.setName(name); comment.setAvatarUrl(avatarUrl); comment.setOpenid(openid); comment.setContent(content); Comment save = repository.save(comment); //修改订单状态 OrderDTO orderDTO = orderService.findOne(orderId); orderDTO.setOrderStatus(OrderStatusEnum.COMMENT.getCode()); OrderMaster orderMaster = new OrderMaster(); BeanUtils.copyProperties(orderDTO, orderMaster); OrderMaster updateResult = masterRepository.save(orderMaster); return ResultVOUtil.success(save); } //所有评论 @GetMapping("/commentList") public ResultVO<List<Comment>> commentList() { List<Comment> all = repository.findAll(); return ResultVOUtil.success(all); } //单个用户的所有评论 @GetMapping("/userCommentList") public ResultVO<List<Comment>> userCommentList(@RequestParam("openid") String openid) { List<Comment> all = repository.findAllByOpenid(openid); return ResultVOUtil.success(all); } }
五,项目总结
微信小程序点餐系统的使用者主要包含两种用户角色,其一是管理员角色,其二是前台用户角色,这两个角色的具体功能如下:
管理员角色:管理员登录微信小程序点餐系统后台管理后可以进行相应的管理操作,主要包含:用户管理、餐品管理、订单管理、分类管理等操作;
前台用户角色:前台用户登录微信小程序点餐系统后可以进行餐品浏览、添加购物车、在线点餐、个人订单管理等操作。
系统整体功能完整,根据微信小程序点餐系统需求分析,进行了微信小程序点餐系统概要设计,并在此基础上进行详细设计。完成了整个项目的详细设计后,就开始了项目的编码阶段。