作者主页:编程千纸鹤
作者简介:Java、前端、Pythone开发多年,做过高程,项目经理,架构师
主要内容:Java项目开发、毕业设计开发、面试技术分类、最新技术共享
一、项目简介
随着互联网技术逐渐深入生活,人们的生活和消费习惯发生了很大的变化。就餐厅用餐而言,互联网技术和移动互联网技术的应用也相关普及。例如,几年前出现的餐厅订购系统通过信息技术取代了传统的纸质菜单订购方式。这种方式一是可以方便顾客实现点餐叫号,二是方便商家进行人单合一的统一管理,减少了报单出错率,提升了用户的体验,所以得以大面积的应用和普及。
移动互联网的出现,使智能手机更加广泛,腾讯微信及时推出微信小程序,使智能手机用户可以通过微信进行相应的信息管理和参与,如当前小程序商场的大面积应用,从传统的商业形式PC移动互联网直接植入互联网,这种轻量级APP应用对用户非常方便,通过微信给商家带来了大量流量。
微信小程序功能的推出极大地方便了全国2亿多微信用户,在这个生态系统上建立了一个最受欢迎的商业帝国,小程序开发的应用迅速渗透到各个行业。在餐饮业的信息应用中,也发生了系统的变化,如通过微信小程序实现用户自助订购功能,大大方便用户,减少订购距离限制,用户可以在餐厅打开手机微信小程序订购,也可以在去餐厅甚至在家订购,打破时空限制,更加灵活方便。经过调查和实地分析,基于微信小程序的研究,开发了这个微信小程序订购系统,为餐饮业的信息化建设做出了贡献。
根据以上对微信小程序订购系统功能需求的分析,设计了微信小程序订购系统的功能结构图,如下图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.1.前台用户购物车模块
微信小程序订购前台用户登录系统后,可以进入预订订购模块,将食品添加到购物车中。用户登录直接绑定用户微信账号登录非常方便。添加购物车的操作界面如下图3-3所示。
图3-3前台用户添加购物车操作界面
3.1.4 前台用户点餐支付模块
前台用户登录订购系统后,可以进入预订订购模块,在购物车上添加自己喜欢的食物,提交订单并付款购买。购买完食物并完成整个订单后,可以对食物进行相关评论。相关管理操作界面如下图3-4所示。
图3-4前台用户点餐支付界面
3.1.前台用户个人订单管理模块
在微信小程序订购前台用户登录系统后,管理个人订单管理模块中的个人订单信息。前端用户个人订单管理操作界面如下图3-5所示。
图3-5前台用户个人订单管理操作界面
3.2后台功能模块的显示
3.2.1用户登录功能
微信小程序点餐后台用户如果想要对餐厅的相关信息进行管理操作,首先要登录系统,才可展开相关的操作。输入手机号和密码后用户登陆界面如下图3-6所示。
3.2.2用户管理功能
微信小程序点餐系统管理员用户登陆系统后,可以进入用户管理菜单进行相应的管理员用户信息管理。用户管理操作界面如下图3-7、3-8所示:
3.2.3 后台餐品管理操作UI
微信小程序点餐管理员用户登陆系统后,可以进入餐品管理菜单进行相应的餐品信息管理。其中主要包含餐品的添加、修改、查询、下架操作等,添加餐品时可以指定餐品的图片进行展示。餐品信息管理操作界面如下图3-9、3-10所示。
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);
}
}
五,项目总结
微信小程序点餐系统的使用者主要包含两种用户角色,其一是管理员角色,其二是前台用户角色,这两个角色的具体功能如下:
管理员角色:管理员登录微信小程序点餐系统后台管理后可以进行相应的管理操作,主要包含:用户管理、餐品管理、订单管理、分类管理等操作;
前台用户角色:前台用户登录微信小程序点餐系统后可以进行餐品浏览、添加购物车、在线点餐、个人订单管理等操作。
系统整体功能完整,根据微信小程序点餐系统需求分析,进行了微信小程序点餐系统概要设计,并在此基础上进行详细设计。完成了整个项目的详细设计后,就开始了项目的编码阶段。