随着线上消费模式的发展,网上订餐系统作为典型的O2O应用越来越受到关注。本文将分享一个完整的网上订餐系统项目,从功能介绍、数据库设计、系统结构、到本地部署及常见问题,适合学生课设、实训项目及初学者入门实践。
网上订餐系统是一个基于 Java + MySQL 的 Web 项目,采用 SSM 框架(Spring、Spring MVC、MyBatis)进行开发。该系统分为用户端和管理员端,涵盖注册登录、菜品浏览、下单购物、订单管理、公告发布、权限控制等功能。
系统主要功能模块如下:
用户注册/登录/退出
浏览菜品(按分类)
菜品详情查看
添加购物车
提交订单
查看历史订单
收货地址、联系方式管理
登录后台管理系统
菜品管理(添加/修改/删除)
用户管理
公告管理
订单管理
系统日志查看(通过 Log4j)
项目结构如下:
├── src
│ ├── controller // 控制层
│ ├── service // 业务接口和实现
│ ├── dao // 数据访问层(接口)
│ ├── entity // 实体类(对应数据库表)
│ ├── interceptor // 拦截器
│ └── utils // 工具类
├── resources
│ ├── applicationContext.xml // Spring 配置
│ ├── springMVC.xml // MVC 配置
│ ├── sqlMapConfig.xml // MyBatis 配置
│ ├── mapper/*.xml // SQL 映射文件
│ └── log4j.properties // 日志配置
├── webapp
│ ├── public/admin // 后台资源
│ ├── public/images // 菜品图片
│ ├── qiantai // 前端页面
│ └── WEB-INF/web.xml // 项目入口配置
数据库表共包括以下核心内容(节选):
admin
字段 | 类型 | 描述 |
---|---|---|
id | int | 管理员用户id |
name | varchar | 姓名 |
pwd | varchar | 密码 |
authority | varchar | 权限 |
menus
字段 | 类型 | 描述 |
---|---|---|
id | int | 菜品id |
name | varchar | 菜品名 |
price | float | 市场价 |
price1 | float | 会员价 |
burden | varchar | 材料说明 |
imgpath | varchar | 图片路径 |
users
字段 | 类型 | 描述 |
---|---|---|
id | int | 用户id |
name | varchar | 用户名 |
realname | varchar | 真实姓名 |
phone | varchar | 联系方式 |
address | varchar | 地址 |
使用 IntelliJ IDEA 打开源码目录,等待 Maven 自动加载依赖。
(1)src/main/java/com/example/meal_ordering_system/controller/AdminController.java
package com.example.meal_ordering_system.controller;
import com.example.meal_ordering_system.entity.Admin;
import com.example.meal_ordering_system.entity.Menus;
import com.example.meal_ordering_system.entity.Types;
import com.example.meal_ordering_system.service.AdminService;
import org.apache.ibatis.annotations.Param;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.List;
/**
* (Admin)表控制层
*
* @author makejava
* @since 2021-02-04 12:51:19
*/
@Controller
@RequestMapping("admin")
public class AdminController {
/**
* 服务对象
*/
//自动注入业务层的AdminService类
@Autowired
@Qualifier("adminService")
private AdminService adminService;
//修改管理员信息
@RequestMapping("update")
public String update(Admin admin) {
adminService.update(admin);
return "/admin/menus";
}
@RequestMapping(value = "/login",method = RequestMethod.GET)
public String toLogin(){
return "/admin/index";
}
//login业务的访问位置为/admin/login
@RequestMapping(value = "/login",method = RequestMethod.POST)
public String login(Admin admin, HttpServletRequest request,HttpSession session){
//调用login方法来验证是否是注册用户
boolean loginType = adminService.login(admin.getName(),admin.getPwd());
if(loginType){
//如果验证通过,则将用户信息传到前台
request.setAttribute("admin",admin);
session.setAttribute("admin_session",admin);
//并跳转到success.jsp页面
return "/admin/main";
}else{
//若不对,则返回
request.setAttribute("message","用户名密码错误");
return "/admin/index";
}
}
//登出,地址/admin/logout
@RequestMapping("logout")
public String logout(HttpSession session){
//清除session
session.removeAttribute("admin_session");
//重定向到登录页面的跳转方法
return "/admin/index";
}
}
(2)src/main/java/com/example/meal_ordering_system/controller/MainController.java
package com.example.meal_ordering_system.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class MainController {
@RequestMapping("admin")
public String admin(Model model){
return "redirect:/admin/login";
}
@RequestMapping("qiantai")
public String qianTai(Model model){
return "redirect:/menus/qiantai/allMenus";
}
}
(4)src/main/java/com/example/meal_ordering_system/controller/MenusController.java
package com.example.meal_ordering_system.controller;
import com.example.meal_ordering_system.entity.Menus;
import com.example.meal_ordering_system.entity.Notice;
import com.example.meal_ordering_system.entity.Types;
import com.example.meal_ordering_system.service.MenusService;
import com.example.meal_ordering_system.service.NoticeService;
import com.example.meal_ordering_system.service.TypesService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.http.HttpRequest;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;
import javax.annotation.Resource;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.List;
/**
* (Menus)表控制层
*
* @author makejava
* @since 2021-02-04 12:51:20
*/
@Controller
@RequestMapping("menus")
public class MenusController {
/**
* 服务对象
*/
@Autowired
@Qualifier("menusService")
private MenusService menusService;
@Autowired
@Qualifier("typesService")
private TypesService typesService;
@Autowired
@Qualifier("noticeService")
private NoticeService noticeService;
//跳转至新增页面
@RequestMapping("/toAddPage")
public ModelAndView toAddPage(){
ModelAndView modelAndView = new ModelAndView("/admin/menus_add");
List typesList=typesService.queryAll();
modelAndView.addObject("typesList",typesList);
return modelAndView;
}
// 跳转至修改页面
@RequestMapping("/toUpdatePage")
public String toUpdatePage(Integer id,Model model){
Menus menus = menusService.queryById(id);
model.addAttribute("menu",menus);
List typesList=typesService.queryAll();
model.addAttribute("typesList",typesList);
return "/admin/menus_update";
}
// 查询全部菜单,前台用
@RequestMapping("/qiantai/allMenus")
public String menusList(Model model ){
List list = menusService.queryAll();
model.addAttribute("menusList",list);
List typesList=typesService.queryAll();
model.addAttribute("typesList",typesList);
List notices=noticeService.queryAll();
model.addAttribute("notices",notices);
return "/qiantai/index";
}
// 查询全部菜单,并且返回到菜单信息页面
@RequestMapping("/allMenus")
public String list(Model model ){
List list = menusService.queryAllByLimit(1, 10);
model.addAttribute("list",list);
List typesList=typesService.queryAll();
model.addAttribute("typesList",typesList);
return "/admin/menus";
}
// 插入一个菜单信息到数据库
@RequestMapping("/insert")
public String insert(Menus menus, @RequestPart("img")MultipartFile multipartFile, HttpSession session) throws IOException {
String realPath = session.getServletContext().getRealPath("");
if (!multipartFile.isEmpty()) {
String originalFilename = multipartFile.getOriginalFilename();
System.out.println("==================================================");
System.out.println(realPath);
multipartFile.transferTo(new File(realPath + "public\\img\\" + originalFilename));
menus.setImgpath("img//" + originalFilename);
}
menus.setSums(0);
menus.setSums1(0);
menusService.insert(menus);
return "/admin/menus_add";
}
//菜单信息修改
@RequestMapping("/update")
public void update(Menus menus,HttpServletRequest request,HttpServletResponse response) throws IOException, ServletException {
menusService.update(menus);
request.getRequestDispatcher("../menus/allMenus").forward(request,response);
}
//菜单信息删除
@RequestMapping("/delete")
public void delete(Integer id,HttpServletRequest request,HttpServletResponse response) throws IOException, ServletException {
menusService.deleteById(id);
request.getRequestDispatcher("../menus/allMenus").forward(request,response);
}
/**
* 通过主键查询单条数据
*
* @param id 主键
* @return 单条数据
*/
@GetMapping("selectOne")
public Menus selectOne(Object id) {
return this.menusService.queryById(id);
}
}
(5)src/main/java/com/example/meal_ordering_system/controller/NoticeController.java
package com.example.meal_ordering_system.controller;
import com.example.meal_ordering_system.entity.Notice;
import com.example.meal_ordering_system.service.NoticeService;
import org.apache.ibatis.annotations.Param;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
/**
* (Notice)表控制层
*
* @author makejava
* @since 2021-02-04 12:51:20
*/
@Controller
@RequestMapping("notice")
public class NoticeController {
/**
* 服务对象
*/
@Autowired
@Qualifier("noticeService")
private NoticeService noticeService;
/**
* 查询所有元素
* @param model
* @return
*/
@RequestMapping("queryAll")
public String queryAll(Model model){
List notices=noticeService.queryAll();
model.addAttribute("notices",notices);
return "admin/notice";
}
/**
* 查询所有公共并传送到前台
* @param model
* @return
*/
@RequestMapping("queryAlltoQiantai")
public String queryAlltoQiantai(Model model){
List notices=noticeService.queryAll();
model.addAttribute("notices",notices);
return "qiantai/index";
}
/**
* 根据id删除元素
* @param model
* @param id
* @return
*/
@RequestMapping("delete")
public String delete(Model model, @Param("id") Integer id){
this.noticeService.delete(id);
return queryAll(model);
}
/**
* 根据id查询元素
* @param model
* @param id
* @return
*/
@RequestMapping("queryById")
public String queryById(Model model,@Param("id") Integer id){
Notice notice=noticeService.queryById(id);
model.addAttribute("notice",notice);
return "admin/notice_update";
}
/**
* 根据id查询元素并传输到前台页面
* @param model
* @param id
* @return
*/
@RequestMapping("queryByIdtoQiantai")
public String queryByIdtoQiantai(Model model,@Param("id") Integer id){
Notice notice=noticeService.queryById(id);
model.addAttribute("notice",notice);
return "qiantai/notice";
}
/**
* 修改元素
* @param model
* @param id
* @param name
* @param content
* @param times
* @return
*/
@RequestMapping("update")
public String update(Model model,@Param("id") Integer id,@Param("name") String name,@Param("content") String content,@Param("times") String times){
noticeService.update(new Notice(id,name,content,times));
return queryAll(model);
}
/**
* 新增元素
* @param model
* @param name
* @param content
* @return
*/
@RequestMapping("insert")
public String insert(Model model,@Param("name") String name,@Param("content") String content){
Integer id=(int)(System.currentTimeMillis()%100);
SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String times=sdf.format(new Date());
noticeService.insert(new Notice(id,name,content,times));
return queryAll(model);
}
}
(6)src/main/java/com/example/meal_ordering_system/controller/OrdersController.java
package com.example.meal_ordering_system.controller;
import com.example.meal_ordering_system.entity.*;
import com.example.meal_ordering_system.service.MenusService;
import com.example.meal_ordering_system.service.OrdersService;
import com.example.meal_ordering_system.service.UsersService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.UnsupportedEncodingException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
* (Orders)表控制层
*
* @author makejava
* @since 2021-02-04 12:51:20
*/
@Controller
@RequestMapping("orders")
public class OrdersController {
/**
* 服务对象
*/
@Autowired
@Qualifier("ordersService")
private OrdersService ordersService;
@Autowired
@Qualifier("menusService")
private MenusService menusService;
@Autowired
@Qualifier("usersService")
private UsersService usersService;
//获取全部订单信息
@RequestMapping("ordergetall")
public String ordergetall( HttpServletRequest request) {
//传给前端
Pages page1=null;
//总页面
Integer totalCount=null;
//当前页面
String currentpages="1";
//获取上一页还是下一页标识
String s="";
//数据库操作页面
String pagess="1";
//前端页面总数
Integer allpage=null;
//如果不为空则获取currentpage
if(request.getParameter("currentpage")!=null){
currentpages=request.getParameter("currentpage");
totalCount= ordersService.pageCount();
allpage=totalCount/5;
if(totalCount%5!=0){
allpage++;
}
if(Integer.parseInt(currentpages)<=0){
currentpages="1";
}
if(Integer.parseInt(currentpages)>allpage){
currentpages=""+allpage;
}
//设置pagess的值
if(request.getParameter("s")!=null){
s=request.getParameter("s");
if(s.equals("up")){
pagess=""+(Integer.parseInt(currentpages)-4);
}else if(s.equals("down")){
pagess=""+((Integer.parseInt(currentpages)-1)*5-1);
}else if (s.equals("first")){
pagess="0";
}else if(s.equals("last")){
pagess=""+(totalCount-(totalCount%5)-1);
}else {
System.out.println("错误");
}
}
page1=new Pages(currentpages,allpage);
request.setAttribute("pages",page1);
}else{
totalCount= ordersService.pageCount();
allpage=totalCount/5;
if(ordersService.pageCount()%5!=0){
allpage++;
}
page1=new Pages("1", allpage);
request.setAttribute("pages",page1);
}
//判断操作数据库页面是否突破限制
if(Integer.parseInt(pagess)<=0){
pagess="0";
}
if(Integer.parseInt(pagess)>totalCount){
pagess=""+(totalCount-(totalCount%5)-1);
}
List list= ordersService.pageList(Integer.parseInt(pagess),5);
request.setAttribute("list",list);
System.out.println("pagess="+pagess);
System.out.println("currentpages="+currentpages);
return "/admin/order";
}
//确认订单 确认则将deliverys设置为一否则删除
@RequestMapping("OrderComfirm")
public String OrderComfirm( HttpServletRequest request){
int id=Integer.parseInt(request.getParameter("id"));
String reqtype=request.getParameter("reqtype");
if(reqtype.equals("delivery")){
ordersService.updatedeliveryById(id);
}else if(reqtype.equals("del")){
ordersService.deleteById(id);
}else{
System.out.println("错误");
}
return "redirect:/orders/ordergetall";
}
@RequestMapping("order_search")
public String order_search( HttpServletRequest request) {
return "/admin/order_search";
}
@RequestMapping("ordergetallbydelivery")
public String ordergetallbydelivery(HttpServletRequest request){
String delivery=request.getParameter("delivery");
Integer d=Integer.parseInt(delivery);
List list=ordersService.pageListByDelivery(d);
HttpSession session=request.getSession();
session.setAttribute("ordersearch", list);
return "/qiantai/order";
}
@RequestMapping(value="order_qiantai",method = RequestMethod.POST)
public String order_qiantai( HttpServletRequest request) throws UnsupportedEncodingException {
List list=null;
HttpSession session=request.getSession();
request.setCharacterEncoding("utf-8");
Integer id=null;
String menuname=null;
String day1=null;
if(request.getParameter("menuname")!=null&&(!request.getParameter("menuname").equals(""))){
menuname=request.getParameter("menuname");
list=ordersService.pageListByMenue(menuname);
}else if(request.getParameter("date")!=null&&(!request.getParameter("date").equals(""))){
day1=request.getParameter("date");
Integer a=Integer.parseInt(day1.substring(9,10));
String aa=""+(a+1);
StringBuilder day=new StringBuilder(day1);
day.replace(9,10,aa);
String day2=day.toString();
list=ordersService.pageListByDate(day1,day2);
}else {
System.out.println("未提交");
}
session.setAttribute("ordersearch", list);
System.out.println(id);
System.out.println(menuname);
System.out.println(day1);
return "/qiantai/order";
}
@RequestMapping(value="order_searchs",method = RequestMethod.POST)
public String order_searchs( HttpServletRequest request) throws UnsupportedEncodingException {
List list=null;
HttpSession session=request.getSession();
request.setCharacterEncoding("utf-8");
Integer id=null;
String menuname=null;
String day1=null;
if(request.getParameter("userid")!=null&&(!request.getParameter("userid").equals(""))){
id=Integer.parseInt(request.getParameter("userid"));
list=ordersService.pageListByID(id);
}else if(request.getParameter("menuname")!=null&&(!request.getParameter("menuname").equals(""))){
menuname=request.getParameter("menuname");
list=ordersService.pageListByMenue(menuname);
}else if(request.getParameter("date")!=null&&(!request.getParameter("date").equals(""))){
day1=request.getParameter("date");
Integer a=Integer.parseInt(day1.substring(9,10));
String aa=""+(a+1);
StringBuilder day=new StringBuilder(day1);
day.replace(9,10,aa);
String day2=day.toString();
list=ordersService.pageListByDate(day1,day2);
}else {
System.out.println("未提交");
}
session.setAttribute("ordersearch", list);
System.out.println(id);
System.out.println(menuname);
System.out.println(day1);
return "/admin/order_search";
}
//跳转到statistic页面
@RequestMapping("order_statistic")
public String order_statistic( HttpServletRequest request) throws UnsupportedEncodingException {
List list=null;
HttpSession session=request.getSession();
request.setCharacterEncoding("utf-8");
SimpleDateFormat formatter= new SimpleDateFormat("yyyy-MM-dd");
Date date = new Date(System.currentTimeMillis());
String day1=formatter.format(date);
Integer a=Integer.parseInt(day1.substring(9,10));
String aa=""+(a+1);
StringBuilder day=new StringBuilder(day1);
day.replace(9,10,aa);
String day2=day.toString();
System.out.println(a);
System.out.println(day1);
System.out.println(day2);
list=ordersService.pageListByDate(day1,day2);
session.setAttribute("orderstatistic", list);
return "/admin/order_statistic";
}
@RequestMapping("orderqiantai")
public String orderqiantai( HttpServletRequest request){
return "/qiantai/order";
}
//放入购物车
@RequestMapping("order_addshoppingcar")
public String order_addshoppingcar(HttpServletRequest request){
HttpSession session=request.getSession();
String menuId = request.getParameter("menuId");
Integer id=Integer.parseInt(menuId);
Integer sum=(Integer) session.getAttribute("sum");
if(sum==null){
sum=1;
session.setAttribute("sum",sum);
}
Menus menus = menusService.queryById(id);
String name=menus.getName();
float price=menus.getPrice1();
ShoppingCart shoppingCart1=new ShoppingCart(id,name,price,sum);
List shoppingCarts=new ArrayList();
if(session.getAttribute("shoppingcar")!=null){
shoppingCarts=(List)session.getAttribute("shoppingcar");
for (ShoppingCart shoppingCart:shoppingCarts) {
if(name.equals(shoppingCart.getName())){
sum=shoppingCart.getSums()+1;
shoppingCarts.remove(shoppingCart);
break;
}
}
shoppingCart1=new ShoppingCart(id,name,price,sum);
shoppingCarts.add(shoppingCart1);
session.setAttribute("shoppingcar",shoppingCarts);
}else{
shoppingCart1=new ShoppingCart(id,name,price,sum);
shoppingCarts.add(shoppingCart1);
session.setAttribute("shoppingcar",shoppingCarts);
}
return "redirect:/menus/qiantai/allMenus";
}
//购物车单个取消
@RequestMapping("order_shoppingcardel")
public String order_shoppingcardel(HttpServletRequest request){
HttpSession session=request.getSession();
List shoppingCarts=(List)session.getAttribute("shoppingcar");
Integer id=Integer.parseInt(request.getParameter("del"));
Integer i=0;
for (ShoppingCart shoppingCart:shoppingCarts) {
if(i.equals(id)){
shoppingCarts.remove(shoppingCart);
break;
}
i++;
}
return "redirect:/menus/qiantai/allMenus";
}
@RequestMapping("order_addshoppingcartoOrder")
//提交或取消订单
public String order_addshoppingcartoOrder(HttpServletRequest request) {
HttpSession session=request.getSession();
List shoppingCarts=(List)session.getAttribute("shoppingcar");
if(session.getAttribute("user_session")!=null) {
Users user = (Users) session.getAttribute("user_session");
Integer userid = usersService.queryByname(user.getName());
Integer delivery = 0;
String remove = request.getParameter("remove");
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date = new Date(System.currentTimeMillis());
String day = formatter.format(date);
Integer id = null;
if (shoppingCarts != null) {
for (ShoppingCart shoppingCart : shoppingCarts) {
Integer sums = shoppingCart.getSums();
Integer menuid = shoppingCart.getId();
Orders orders = new Orders(id, userid, menuid, sums, day, delivery);
ordersService.insert(orders);
}
session.removeAttribute("shoppingcar");
}
if(remove!=null) {
if (remove.equals("1")) {
session.removeAttribute("shoppingcar");
}
}
}else{
return "redirect:../public/qiantai/login.jsp";
}
return "redirect:/menus/qiantai/allMenus";
}
}
修改 applicationContext.xml
中的数据库地址为你的本地配置,如:
jdbc:mysql://127.0.0.1/apsfc?autoReconnect=true&useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai
执行建表 SQL(详见数据库表文档),完成后可运行项目。
运行 main()
方法或部署至 Tomcat,访问项目首页地址进行测试。
解决: 确认数据库地址配置是否正确,常见修正如下:
jdbc:mysql://127.0.0.1/apsfc?autoReconnect=true&useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai
解决: 使用拦截器进行权限控制,系统内已实现前后台未登录用户的访问拦截。