Java 第三阶段增强分析需求,代码实现能力【满汉楼】

发布于:2023-01-04 ⋅ 阅读:(405) ⋅ 点赞:(0)

代码链接:https://download.csdn.net/download/qq_52354698/86500681?spm=1001.2014.3001.5503

1. 项目演示

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2. 界面设计

1. 用户登录

在这里插入图片描述

2. 显示餐桌状态

在这里插入图片描述

3. 预定

在这里插入图片描述

4. 显示菜单

在这里插入图片描述

5. 点餐

在这里插入图片描述

6. 查看账单

在这里插入图片描述

7. 结账

在这里插入图片描述

3. 项目设计-程序框架图

在这里插入图片描述

4. 功能实现

1. 准备工具类Utility

Utility.class 处理各种情况的用户输入,并且能够按照程序员的需求,得到用户的控制台输入。

package com.qdu.mhl.utils;


/**
	工具类的作用:
	处理各种情况的用户输入,并且能够按照程序员的需求,得到用户的控制台输入。
*/

import java.util.*;
/**

	
*/
public class Utility {
	//静态属性。。。
    private static Scanner scanner = new Scanner(System.in);

    
    /**
     * 功能:读取键盘输入的一个菜单选项,值:1——5的范围
     * @return 1——5
     */
	public static char readMenuSelection() {
        char c;
        for (; ; ) {
            String str = readKeyBoard(1, false);//包含一个字符的字符串
            c = str.charAt(0);//将字符串转换成字符char类型
            if (c != '1' && c != '2' && 
                c != '3' && c != '4' && c != '5') {
                System.out.print("选择错误,请重新输入:");
            } else break;
        }
        return c;
    }

	/**
	 * 功能:读取键盘输入的一个字符
	 * @return 一个字符
	 */
    public static char readChar() {
        String str = readKeyBoard(1, false);//就是一个字符
        return str.charAt(0);
    }
    /**
     * 功能:读取键盘输入的一个字符,如果直接按回车,则返回指定的默认值;否则返回输入的那个字符
     * @param defaultValue 指定的默认值
     * @return 默认值或输入的字符
     */
    
    public static char readChar(char defaultValue) {
        String str = readKeyBoard(1, true);//要么是空字符串,要么是一个字符
        return (str.length() == 0) ? defaultValue : str.charAt(0);
    }
	
    /**
     * 功能:读取键盘输入的整型,长度小于2位
     * @return 整数
     */
    public static int readInt() {
        int n;
        for (; ; ) {
            String str = readKeyBoard(2, false);//一个整数,长度<=2位
            try {
                n = Integer.parseInt(str);//将字符串转换成整数
                break;
            } catch (NumberFormatException e) {
                System.out.print("数字输入错误,请重新输入:");
            }
        }
        return n;
    }
    /**
     * 功能:读取键盘输入的 整数或默认值,如果直接回车,则返回默认值,否则返回输入的整数
     * @param defaultValue 指定的默认值
     * @return 整数或默认值
     */
    public static int readInt(int defaultValue) {
        int n;
        for (; ; ) {
            String str = readKeyBoard(10, true);
            if (str.equals("")) {
                return defaultValue;
            }
			
			//异常处理...
            try {
                n = Integer.parseInt(str);
                break;
            } catch (NumberFormatException e) {
                System.out.print("数字输入错误,请重新输入:");
            }
        }
        return n;
    }

    /**
     * 功能:读取键盘输入的指定长度的字符串
     * @param limit 限制的长度
     * @return 指定长度的字符串
     */

    public static String readString(int limit) {
        return readKeyBoard(limit, false);
    }

    /**
     * 功能:读取键盘输入的指定长度的字符串或默认值,如果直接回车,返回默认值,否则返回字符串
     * @param limit 限制的长度
     * @param defaultValue 指定的默认值
     * @return 指定长度的字符串
     */
	
    public static String readString(int limit, String defaultValue) {
        String str = readKeyBoard(limit, true);
        return str.equals("")? defaultValue : str;
    }


	/**
	 * 功能:读取键盘输入的确认选项,Y或N
	 * 将小的功能,封装到一个方法中.
	 * @return Y或N
	 */
    public static char readConfirmSelection() {
        System.out.print("确认是否预订(Y/N): ");
        char c;
        for (; ; ) {//无限循环
        	//在这里,将接受到字符,转成了大写字母
        	//y => Y n=>N
            String str = readKeyBoard(1, false).toUpperCase();
            c = str.charAt(0);
            if (c == 'Y' || c == 'N') {
                break;
            } else {
                System.out.print("选择错误,请重新输入:");
            }
        }
        return c;
    }

    /**
     * 功能: 读取一个字符串
     * @param limit 读取的长度
     * @param blankReturn 如果为true ,表示 可以读空字符串。 
     * 					  如果为false表示 不能读空字符串。
     * 			
	 *	如果输入为空,或者输入大于limit的长度,就会提示重新输入。
     * @return
     */
    private static String readKeyBoard(int limit, boolean blankReturn) {
        
		//定义了字符串
		String line = "";

		//scanner.hasNextLine() 判断有没有下一行
        while (scanner.hasNextLine()) {
            line = scanner.nextLine();//读取这一行
           
			//如果line.length=0, 即用户没有输入任何内容,直接回车
			if (line.length() == 0) {
                if (blankReturn) return line;//如果blankReturn=true,可以返回空串
                else continue; //如果blankReturn=false,不接受空串,必须输入内容
            }

			//如果用户输入的内容大于了 limit,就提示重写输入  
			//如果用户如的内容 >0 <= limit ,我就接受
            if (line.length() < 1 || line.length() > limit) {
                System.out.print("输入长度(不能大于" + limit + ")错误,请重新输入:");
                continue;
            }
            break;
        }

        return line;
    }
}

JDBCUtilsByDruid.class 基于druid数据库连接池的工具类

package com.qdu.mhl.utils;

import com.alibaba.druid.pool.DruidDataSourceFactory;

import javax.sql.DataSource;
import java.io.FileInputStream;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;

/**
 * @author dell
 * @version 1.0
 * 基于druid数据库连接池的工具类
 */
public class JDBCUtilsByDruid {

    private static DataSource dataSource;

    //静态代码块加载时只会执行一次
    static {

        Properties properties = new Properties();
        try {
            properties.load(new FileInputStream("src\\druid.properties"));
            dataSource = DruidDataSourceFactory.createDataSource(properties);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

    }

    //得到连接
    public static Connection getConnection() throws SQLException {

        return dataSource.getConnection();

    }

    //关闭连接,在数据库连接池中,close 不是真的断掉连接,而是将使用的 connection对象重新放回连接池
    public static void close(ResultSet resultSet, Statement statement, Connection connection) {


        try {
            if (resultSet != null) {
                resultSet.close();
            }
            if (statement != null) {
                statement.close();
            }
            if (connection != null) {
                connection.close();
            }
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }


    }

}

druid.properties 配置文件

#key=value
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/mhl?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC&useSSL=false&rewriteBatchedStatements=true
username=root
password=root
#initial connection Size
initialSize=10
#min idle connecton size
minIdle=5
#max active connection size
maxActive=50
#max wait time (5000 mil seconds)
maxWait=5000

2. 显示主菜单、二级菜单和退出系统功能

在这里插入图片描述
在这里插入图片描述

    //显示主菜单
    public void mainMenu() {

        while (loop) {

            System.out.println("===============满汉楼===============");
            System.out.println("\t\t 1 登录满汉楼");
            System.out.println("\t\t 2 退出满汉楼");
            System.out.print("请输入你的选择:");
            key = Utility.readString(1);
            switch (key) {

                case "1":
                    System.out.print("请输入员工号:");
                    String id = Utility.readString(50);
                    System.out.print("请输入密  码:");
                    String pwd = Utility.readString(50);
                    //到数据库判断
                    if ("123".equals(pwd)){
                        System.out.println("===============登录成功===============\n");

                        //显示二级菜单
                        while (loop){
                            System.out.println("===============满汉楼(二级菜单)===============");
                            System.out.println("\t\t 1 显示餐桌状态");
                            System.out.println("\t\t 2 预定餐桌");
                            System.out.println("\t\t 3 显示所有菜品");
                            System.out.println("\t\t 4 点餐服务");
                            System.out.println("\t\t 5 查看菜单");
                            System.out.println("\t\t 6 结账");
                            System.out.println("\t\t 9 退出满汉楼");
                            System.out.print("请输入你的选择:");
                            key = Utility.readString(1);
                            switch (key){

                                case "1":
                                    System.out.println("显示餐桌状态");
                                    break;
                                case "2":
                                    System.out.println("预定餐桌");
                                    break;
                                case "3":
                                    System.out.println("显示所有菜品");
                                    break;
                                case "4":
                                    System.out.println("点餐服务");
                                    break;
                                case "5":
                                    System.out.println("查看菜单");
                                    break;
                                case "6":
                                    System.out.println("结账");
                                    break;
                                case "9":
                                    loop = false;
                                    break;
                                default:
                                    System.out.println("输入有误,请重新输入");
                                    break;

                            }
                        }

                    }else {
                        System.out.println("===============登录失败===============");
                    }
                    break;
                case "2":
                    loop = false;
                    break;
                default:
                    System.out.println("输入有误,请重新输入");
                    break;

            }

        }
        System.out.println("退出满汉楼系统~");

    }

3. 用户登录

创建数据库
这里的密码是用 MD5 进行的加密
在这里插入图片描述

CREATE TABLE employee (
id INT PRIMARY KEY AUTO_INCREMENT, #自增
empId VARCHAR(50) UNIQUE NOT NULL DEFAULT '', #员工号
pwd CHAR(32) NOT NULL DEFAULT '', #密码md5
NAME VARCHAR(50) NOT NULL DEFAULT '', #姓名
job VARCHAR (50) NOT NULL DEFAULT '' #岗位
) CHARSET=utf8;

INSERT INTO employee VALUES (NULL, '6668612', MD5('123456'), '张三丰', '经理');
INSERT INTO employee VALUES (NULL, '6668622', MD5('123456'), '小龙女', '服务员');
INSERT INTO employee VALUES (NULL, '6668633', MD5('123456'), '张无忌', '收银员') ;
INSERT INTO employee VALUES (NULL, '666666' , MD5('123456'), '老韩', '经理') ;

Emplyee类 一个javabean,与employee对应

package com.qdu.mhl.domain;

/**
 * @author dell
 * @version 1.0
 * 一个javabean,与employee对应
 * id INT PRIMARY KEY AUTO_INCREMENT, #自增
 * empId VARCHAR(50) NOT NULL DEFAULT '', #员工号
 * pwd CHAR(32) NOT NULL DEFAULT '', #密码md5
 * NAME VARCHAR(50) NOT NULL DEFAULT '', #姓名
 * job VARCHAR (50) NOT NULL DEFAULT '' #岗位
 */
public class Employee {

    private Integer id;
    private String empId;
    private String pwd;
    private String name;
    private String job;

    //无参构造器,后续的反射会用到
    public Employee(){

    }

    public Employee(Integer id, String empId, String pwd, String name, String job) {
        this.id = id;
        this.empId = empId;
        this.pwd = pwd;
        this.name = name;
        this.job = job;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getEmpId() {
        return empId;
    }

    public void setEmpId(String empId) {
        this.empId = empId;
    }

    public String getPwd() {
        return pwd;
    }

    public void setPwd(String pwd) {
        this.pwd = pwd;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getJob() {
        return job;
    }

    public void setJob(String job) {
        this.job = job;
    }
}

EmployeeDAO 类

package com.qdu.mhl.dao;

import com.qdu.mhl.domain.Employee;

/**
 * @author dell
 * @version 1.0
 */
public class EmployeeDAO extends BasicDAO<Employee>{

    //可以添加特有的操作

}

EmployeeService 类 完成对employee表的各种操作(通过调用employeeDAO对象完成)

package com.qdu.mhl.service;

import com.qdu.mhl.dao.EmployeeDAO;
import com.qdu.mhl.domain.Employee;

/**
 * @author dell
 * @version 1.0
 * 完成对employee表的各种操作(通过调用employeeDAO对象完成)
 */
public class EmployeeService {

    //定义一个EmployeeDAO属性
    private EmployeeDAO employeeDAO = new EmployeeDAO();

    //方法:根据empId和pwd返回一个Employee对象
    //如果查询不到,返回null
    public Employee getEmployeeByIdAndPwd(String empId, String pwd) {

        return employeeDAO.querySingle("select * from employee where empId = ? and pwd = md5(?)", Employee.class, empId, pwd);

    }

}

在登录时,通过输入的id和pwd在数据库中查找对于的用户,如果用户存在则登录成功,反之登录失败

4. 显示餐桌状态

创建diningTable表
在这里插入图片描述

CREATE TABLE diningTable (
id INT PRIMARY KEY AUTO_INCREMENT, #自增,表示餐桌编号
state VARCHAR(20) NOT NULL DEFAULT '', #餐桌的状态
orderName VARCHAR(50) NOT NULL DEFAULT '', #预订人的名字
orderTel VARCHAR(20) NOT NULL DEFAULT ''
) CHARSET=utf8;

INSERT INTO diningTable VALUES (NULL, '空', '', '');
INSERT INTO diningTable VALUES (NULL, '空', '', ''); 
INSERT INTO diningTable VALUES (NULL, '空', '', '');

DiningTable 类 一个javabean,与diningTable对应

package com.qdu.mhl.domain;

/**
 * @author dell
 * @version 1.0
 * 一个javabean,与diningTable对应
 * id INT PRIMARY KEY AUTO_INCREMENT, #自增,表示餐桌编号
 * state VARCHAR(20) NOT NULL DEFAULT '', #餐桌的状态
 * orderName VARCHAR(50) NOT NULL DEFAULT '', #预订人的名字
 * orderTel VARCHAR(20) NOT NULL DEFAULT ''
 */
public class DiningTable {

    private Integer id;
    private String state;
    private String orderName;
    private String orderTel;

    public DiningTable() {
    }

    public DiningTable(Integer id, String state, String orderName, String orderTel) {
        this.id = id;
        this.state = state;
        this.orderName = orderName;
        this.orderTel = orderTel;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getState() {
        return state;
    }

    public void setState(String state) {
        this.state = state;
    }

    public String getOrderName() {
        return orderName;
    }

    public void setOrderName(String orderName) {
        this.orderName = orderName;
    }

    public String getOrderTel() {
        return orderTel;
    }

    public void setOrderTel(String orderTel) {
        this.orderTel = orderTel;
    }
    @Override
    public String toString() {
        return id + "\t\t\t" + state;
    }
}

DiningTableDAO 类

package com.qdu.mhl.dao;

import com.qdu.mhl.domain.DiningTable;

/**
 * @author dell
 * @version 1.0
 */
public class DiningTableDAO extends BasicDAO<DiningTable>{
}

DiningTableService 类

package com.qdu.mhl.service;

import com.qdu.mhl.dao.DiningTableDAO;
import com.qdu.mhl.domain.DiningTable;

import java.util.List;

/**
 * @author dell
 * @version 1.0
 */
public class DiningTableService {

    //定义一个DiningTableDAO对象
    private DiningTableDAO diningTableDAO = new DiningTableDAO();

    //返回所有餐桌的信息
    public List<DiningTable> list(){

        return diningTableDAO.queryMulti("select id, state from dindingtable", DiningTable.class);

    }

}

显示层编写显示餐桌状态方法

    //方法:显示餐桌状态
    public void ListDiningTable() {
        List<DiningTable> list = diningTableService.list();
        System.out.println("\n餐桌编号\t\t餐桌状态");
        for (DiningTable diningTable : list) {
            System.out.println(diningTable);
        }
        System.out.println("===============显示完毕===============");
    }

5. 订座

  1. 要检查餐桌是否存在
  2. 要检查餐桌的状态

在service层编写方法

根据id查询对应的餐桌DiningTable对象
如果返回null,表示id编号对应的餐桌不存在

    public DiningTable getDiningTableById(int id) {

        return diningTableDAO.querySingle("select * from diningTable where id = ?", DiningTable.class, id);

    }

如果餐桌可以预定,调用方法,对其状态进行更新(预定人姓名、电话)

    public boolean orderDiningTable(int id, String orderName, String orderTel) {

        int update = diningTableDAO.update("update diningTable set state = '已预订', orderName = ?, orderTel = ? where id = ?", orderName, orderTel, id);
        return update > 0;

    }

在view层编写预定餐桌方法

    //完成订座
    public void orderDiningTable() {

        System.out.println("===============预定餐桌===============");
        System.out.print("请选择要预定的餐桌编号(-1退出):");
        int orderId = Utility.readInt();
        if (orderId == -1) {
            System.out.println("===============取消预定===============");
            return;
        }
        char key = Utility.readConfirmSelection();
        if (key == 'Y') {

            //根据orderId返回对应的DiningTable对象,如果为null,说明对象不存在
            DiningTable diningTable = diningTableService.getDiningTableById(orderId);
            if (diningTable == null){
                System.out.println("===============预定餐桌不存在===============");
                return;
            }
            //判断餐桌的状态是否 "空"
            if (!("空".equals(diningTable.getState()))){//说明当前餐桌的状态不是 "空"
                System.out.println("===============餐桌已经预定或者就餐中ing===============");
                return;
            }
            System.out.print("预定人的名字:");
            String orderName = Utility.readString(50);
            System.out.print("预订人的电话:");
            String orderTel = Utility.readString(50);
            //此时可以更新餐桌状态
            if (diningTableService.orderDiningTable(orderId, orderName, orderTel)){
                System.out.println("===============预定餐桌成功===============");
            }else {
                System.out.println("===============预定餐桌失败===============");
            }

        } else {
            System.out.println("===============取消预定===============");
        }

    }

6. 显示菜品

创建menu表
在这里插入图片描述

CREATE TABLE menu (
id INT PRIMARY KEY AUTO_INCREMENT, #自增主键,作为菜谱编号(唯一)
NAME VARCHAR(50) NOT NULL DEFAULT '', #菜品名称
TYPE VARCHAR(50) NOT NULL DEFAULT '', #菜品种类
price DOUBLE NOT NULL DEFAULT 0# 价格
) CHARSET=utf8;

INSERT INTO menu VALUES (NULL, '八宝饭', '主食', 10);
INSERT INTO menu VALUES (NULL, '叉烧包', '主食', 20);
INSERT INTO menu VALUES (NULL, '宫保鸡丁', '热菜', 30);
INSERT INTO menu VALUES (NULL, '山药拨鱼', '凉菜', 14);
INSERT INTO menu VALUES (NULL, '银丝卷', '甜食', 9);
INSERT INTO menu VALUES (NULL, '水煮鱼', '热菜', 26);
INSERT INTO menu VALUES (NULL, '甲鱼汤', '汤类', 100);
INSERT INTO menu VALUES (NULL, '鸡蛋汤', '汤类', 16);

Menu 类 一个javabean,与menu对应

package com.qdu.mhl.domain;

/**
 * @author dell
 * @version 1.0
 * 一个javabean,与menu对应
 * id INT PRIMARY KEY AUTO_INCREMENT, #自增主键,作为菜谱编号(唯一)
 * NAME VARCHAR(50) NOT NULL DEFAULT '', #菜品名称
 * TYPE VARCHAR(50) NOT NULL DEFAULT '', #菜品种类
 * price DOUBLE NOT NULL DEFAULT 0# 价格
 */
public class Menu {

    private Integer id;
    private String name;
    private String type;
    private Double price;

    public Menu() {
    }

    public Menu(Integer id, String name, String type, Double price) {
        this.id = id;
        this.name = name;
        this.type = type;
        this.price = price;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public Double getPrice() {
        return price;
    }

    public void setPrice(Double price) {
        this.price = price;
    }
    @Override
    public String toString() {
        return id + "\t\t\t" + name + "\t\t" + type + "\t\t" + price;
    }
}

MenuDAO 类

package com.qdu.mhl.dao;

import com.qdu.mhl.domain.Menu;

/**
 * @author dell
 * @version 1.0
 */
public class MenuDAO extends BasicDAO<Menu>{
}

MenuService 类 完成对menu表的各种操作(通过调用MenuDAO对象完成)

package com.qdu.mhl.service;

import com.qdu.mhl.dao.MenuDAO;
import com.qdu.mhl.domain.Menu;

import java.util.List;

/**
 * @author dell
 * @version 1.0
 * 完成对menu表的各种操作(通过调用MenuDAO对象完成)
 */
public class MenuService {

    //定义MenuDAO属性
    private MenuDAO menuDAO = new MenuDAO();

    //返回所有的菜品,返回给界面使用
    public List<Menu> list() {

        return menuDAO.queryMulti("select * from menu", Menu.class);

    }

}

在view层编写显示全部菜品的方法

    public void listMenu(){

        List<Menu> list = menuService.list();
        System.out.println("\n菜品编号\t\t菜品名\t\t类别\t\t价格");
        for (Menu menu : list) {
            System.out.println(menu);
        }
        System.out.println("===============显示完毕===============");

    }

7. 点餐

  1. 餐桌号、菜品编号检验
  2. 点餐成功,需要修改餐桌状态
  3. 生成账单

增加bill账单表
在这里插入图片描述

CREATE TABLE bill (
id INT PRIMARY KEY AUTO_INCREMENT, #自增主键
billId VARCHAR(50) NOT NULL DEFAULT '', #账单号可以按照自己规则生成UUID
menuId INT NOT NULL DEFAULT 0, #菜品的编号,也可以使用外键
nums INT NOT NULL DEFAULT 0, #份数
money DOUBLE NOT NULL DEFAULT 0, #金额
diningTableId INT NOT NULL DEFAULT 0, #餐桌
billDate DATETIME NOT NULL, #订 单日期
state VARCHAR(50) NOT NULL DEFAULT '' #状态'未结账','已经结账'.'挂单'...
) CHARSET=utf8;

Bill 类 一个javabean,与bill对应

package com.qdu.mhl.domain;

import java.util.Date;

/**
 * @author dell
 * @version 1.0
 * 一个javabean,与bill对应
 * id INT PRIMARY KEY AUTO_INCREMENT, #自增主键
 * billId VARCHAR(50) NOT NULL DEFAULT '', #账单号可以按照自己规则生成UUID
 * menuId INT NOT NULL DEFAULT 0, #菜品的编号,也可以使用外键
 * nums INT NOT NULL DEFAULT 0, #份数
 * money DOUBLE NOT NULL DEFAULT 0, #金额
 * diningTableId INT NOT NULL DEFAULT 0, #餐桌
 * billDate DATETIME NOT NULL, #订 单日期
 * state VARCHAR(50) NOT NULL DEFAULT '' #状态'未结账','已经结账'.'挂单'...
 */
public class Bill {

    private Integer id;
    private String billId;
    private Integer menuId;
    private Integer nums;
    private Double money;
    private Integer diningTableId;
    private Date billDate;
    private String state;

    public Bill() {
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getBillId() {
        return billId;
    }

    public void setBillId(String billId) {
        this.billId = billId;
    }

    public Integer getMenuId() {
        return menuId;
    }

    public void setMenuId(Integer menuId) {
        this.menuId = menuId;
    }

    public Integer getNums() {
        return nums;
    }

    public void setNums(Integer nums) {
        this.nums = nums;
    }

    public Double getMoney() {
        return money;
    }

    public void setMoney(Double money) {
        this.money = money;
    }

    public Integer getDiningTableId() {
        return diningTableId;
    }

    public void setDiningTableId(Integer diningTableId) {
        this.diningTableId = diningTableId;
    }

    public Date getBillDate() {
        return billDate;
    }

    public void setBillDate(Date billDate) {
        this.billDate = billDate;
    }

    public String getState() {
        return state;
    }

    public void setState(String state) {
        this.state = state;
    }

    public Bill(Integer id, String billId, Integer menuId, Integer nums, Double money, Integer diningTableId, Date billDate, String state) {
        this.id = id;
        this.billId = billId;
        this.menuId = menuId;
        this.nums = nums;
        this.money = money;
        this.diningTableId = diningTableId;
        this.billDate = billDate;
        this.state = state;
    }
}

BillDAO 类

package com.qdu.mhl.dao;

import com.qdu.mhl.domain.Bill;

/**
 * @author dell
 * @version 1.0
 */
public class BillDAO extends BasicDAO<Bill>{
}

BillService 类

package com.qdu.mhl.service;

import com.qdu.mhl.dao.BillDAO;

import java.util.UUID;

/**
 * @author dell
 * @version 1.0
 * 处理和账单相关的业务逻辑
 */
public class BillService {

    //定义BillDAO属性
    private BillDAO billDAO = new BillDAO();
    //定义MenuService属性
    private MenuService menuService = new MenuService();
    //定义DiningTableService对象
    private DiningTableService diningTableService = new DiningTableService();

    //编写点餐的方法
    //1.生成账单
    //2.更新对应餐桌的状态
    //3.如果成功返回true,否则返回false
    public boolean orderMenu(int menuId, int nums, int diningTableId){

        //生成一个账单好,UUID
        String billID = UUID.randomUUID().toString();
        //将账单生成到bill表,要求直接计算金额
        int update = billDAO.update("insert into bill values(null, ?, ?, ?, ?, ?, now(), '未结账')", billID, menuId, nums, menuService.getMenuById(menuId).getPrice() * nums, diningTableId);
        if (update <= 0) {
            return false;
        }

        //需要更新对应餐桌的状态
        return diningTableService.updateDiningTableState(diningTableId, "就餐中");

    }

}

在view层编写点餐方法

    public void orderMenu(){

        System.out.println("===============点餐服务===============");
        System.out.print("请输入点餐的桌号(-1退出):");
        int orderDiningTableId = Utility.readInt();
        if (orderDiningTableId == -1){
            System.out.println("===============取消点餐===============");
            return;
        }
        System.out.print("请输入点餐的菜品号(-1退出):");
        int orderMenuId = Utility.readInt();
        if (orderMenuId == -1){
            System.out.println("===============取消点餐===============");
            return;
        }
        System.out.print("请输入点餐的菜品量(-1退出):");
        int orderNums = Utility.readInt();
        if (orderNums == -1){
            System.out.println("===============取消点餐===============");
            return;
        }

        //验证桌号是否存在
        DiningTable diningTable = diningTableService.getDiningTableById(orderDiningTableId);
        if (diningTable == null){
            System.out.println("===============餐桌号不存在===============");
            return;
        }
        //验证菜品编号是否正确
        Menu menu = menuService.getMenuById(orderMenuId);
        if (menu == null){
            System.out.println("===============菜品号不存在===============");
            return;
        }

        //验证通过后,进行点餐
        if (billService.orderMenu(orderMenuId, orderNums, orderDiningTableId)){
            System.out.println("===============点餐成功===============");
        }else {
            System.out.println("===============点餐失败===============");
        }

    }

8. 查看账单

增添BillService方法

    public List<Bill> list(){

        return billDAO.queryMulti("select * from bill", Bill.class);

    }

在View层编写显示账单方法

    public void listBill(){

        List<Bill> allLists = billService.list();
        System.out.println("\n编号\t\t菜品号\t\t菜品量\t\t金额\t\t餐桌\t\t日期\t\t\t\t\t\t\t状态");
        for (Bill bill : allLists) {
            System.out.println(bill);
        }
        System.out.println("===============显示完毕===============");

    }

9. 结账

  1. 对餐桌号进行校验
  2. 修改bill表的state
  3. 修改diningTable信息

在BillService中添加方法

    public boolean payBill(int diningTableId, String payMode){

        //修改bill表
        int update =  billDAO.update("update bill set state = ? where diningTableId = ? and state = '未结账'", payMode, diningTableId);
        if (update <= 0) {
            return false;
        }

        //修改diningTable表
        if (!diningTableService.updateDiningTableStateToFree(diningTableId, "空")){
            return false;
        }
        return true;

    }

在view层添加结账方法

    public void payBill() {

        System.out.println("===============结账服务===============");
        System.out.print("请选择要结账的餐桌编号(-1退出):");
        int diningTableId = Utility.readInt();
        if (diningTableId == -1) {
            System.out.println("===============取消结账===============");
            return;
        }
        //验证餐桌是否存在
        DiningTable diningTable = diningTableService.getDiningTableById(diningTableId);
        if (diningTable == null) {
            System.out.println("===============结账的餐桌不存在===============");
            return;
        }
        //验证餐桌是否有需要结账的账单
        if (!billService.hasPayBillByDiningTableId(diningTableId)) {
            System.out.println("===============该餐位没有未结账的账单===============");
            return;
        }
        System.out.print("结账方式(现金/支付宝/微信)回车表示退出:");
        String payMode = Utility.readString(20, "");
        if ("".equals(payMode)) {
            System.out.println("===============取消结账===============");
            return;
        }
        char key = Utility.readConfirmSelection();
        if (key == 'Y') {

            if (billService.payBill(diningTableId, payMode)) {
                System.out.println("===============完成结账===============");
            } else {
                System.out.println("===============结账失败===============");
            }

        } else {
            System.out.println("===============取消结账===============");
        }
        System.out.println("");

    }