草庐IT

day02-显示所有菜品&点餐功能

liyuelian 2023-04-18 原文

满汉楼02

4.功能实现04

4.6显示所有菜品

4.6.1思路分析

创建一个菜单表menu,在Domain层创建与菜单表对应的Javabean-Menu类,在DAO层创建MenuDAO,完成对menu表的增删改查,在Service层创建一个和menu表相关的service类,service类提供给界面层使用

4.6.2代码实现

1.创建menu表
-- 创建menu表(id,name,type,price)
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);
2.创建Menu类
package com.li.mhl.domain;

/**
 * @author 李
 * @version 1.0
 * 该类和menu表对应
 */
public class Menu {
    /**
     * Field   Type         Null    Key     Default  Extra
     * ------  -----------  ------  ------  -------  ----------------
     * id      int(11)      NO      PRI     (NULL)   auto_increment
     * name    varchar(50)  NO
     * type    varchar(50)  NO
     * price   double       NO              0
     */
    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;
    }

}
3.创建MenuDAO类
package com.li.mhl.dao;

import com.li.mhl.domain.Menu;

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

}
4.创建MenuService类
package com.li.mhl.service;

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

import java.util.List;

/**
 * @author 李
 * @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);
    }
}

5.修改MHLView

修改处1:定义属性

//定义MenuService属性
private MenuService menuService = new MenuService();

修改处2:编写方法

//显示所有菜品
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("============显示完毕============");
}

修改处3:在内层循环的二级菜单中调用该方法

4.6.3测试

测试通过

4.7点餐功能

4.7.1功能说明

4.7.2思路分析

功能如上图所示,分析如下:

  1. 在输入点餐桌号和菜品编号时都需要对其进行合理性校验,如果不合理,给出提示信息
  2. 当点餐成功之后,餐桌的状态state应该发生变化,由已经预定变为进餐中
  3. 一旦点餐,就应该生成账单

根据上述的分析,整体的框架应该如下:

4.7.3代码实现

1.创建bill表
-- 创建bill账单表(id,billId,menuId,nums,billDate,money,state,diningTableId)
#账单流水, 考虑可以分开结账, 并考虑将来分别统计各个不同菜品的销售情况
CREATE TABLE bill (
	id INT PRIMARY KEY AUTO_INCREMENT, #自增主键
	billId VARCHAR(50) NOT NULL DEFAULT '',#账单号可以按照自己规则生成 UUID
	menuId INT NOT NULL DEFAULT 0,#菜品的编号, 也可以使用外键
	nums SMALLINT 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;
2.创建Bill类
package com.li.mhl.domain;

import java.util.Date;

/**
 * @author 李
 * @version 1.0
 * 该类和 bill表对应
 */
public class Bill {
    /**
     * Field          Type         Null    Key     Default  Extra
     * -------------  -----------  ------  ------  -------  ----------------
     * id             int(11)      NO      PRI     (NULL)   auto_increment
     * billId         varchar(50)  NO
     * menuId         int(11)      NO              0
     * nums           smallint(6)  NO              0
     * money          double       NO              0
     * diningTableId  int(11)      NO              0
     * billDate       datetime     NO              (NULL)
     * state          varchar(50)  NO
     */
    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 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;
    }

    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;
    }
}
3.创建BillDAO类
package com.li.mhl.dao;

import com.li.mhl.domain.Bill;

/**
 * @author 李
 * @version 1.0
 */
public class BillDAO extends BasicDAO<Bill>{
}
4.创建BillService类
package com.li.mhl.service;

import com.li.mhl.dao.BillDAO;

import java.util.UUID;

/**
 * @author 李
 * @version 1.0
 * 处理和账单表bill相关的业务逻辑
 */
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表()
        //这里的金额money = 由menuId(菜品编号)查询出来的单价 * nums
        //因此,在MenuService类中编写方法getMenuById()查询菜品单价
        int update = billDAO.update("insert into bill values(null,?,?,?,?,?,now(),'未结账')",
                billID, menuId, nums, menuService.getMenuById(menuId).getPrice() * nums, diningTableId);
        if (update <= 0) {
            return false;
        }

        //需要更新对应的餐桌的状态
        //在DiningTableService类中编写方法updateDiningTableState()更新对应的餐桌的状态
        return diningTableService.updateDiningTableState(diningTableId, "就餐中");
    }
}
5.修改MenuService类

在该类中增加方法getMenuById()

//根据菜品id,返回Menu对象
public Menu getMenuById(int id) {
    return menuDAO.querySingle("select * from menu where id=?", Menu.class, id);
}
6.修改DiningTableService类

在该类中增加方法updateDiningTableState()

//需要提供一个更新 餐桌状态的方法
public boolean updateDiningTableState(int id, String state) {
    int update =
            diningTableDAO.update("update diningTable set state=? where id=?", state, id);
    return update > 0;
}
7.修改MHLView

修改处1:在该类中定义BillService属性

//定义BillService属性
private BillService billService = new BillService();

修改处2:在该类中增加方法

//完成点餐操作
public void orderMenu() {
    System.out.println("============点餐服务============");
    
    System.out.print("请输入点餐的桌号(-1退出): ");
    int orderDiningTableId = Utility.readInt();
    if (orderDiningTableId == -1) {
        System.out.println("============取消点餐============");
        return;
    }
    //验证餐桌号是否存在
    DiningTable diningTableById = diningTableService.getDiningTableById(orderDiningTableId);
    if (diningTableById == null) {
        System.out.println("============餐桌号不存在============");
        return;
    }

    
    System.out.print("请输入菜品编号(-1退出): ");
    int orderMenuId = Utility.readInt();
    if (orderMenuId == -1) {
        System.out.println("============取消点餐============");
        return;
    }
    //验证菜品编号是否存在
    Menu menuById = menuService.getMenuById(orderMenuId);
    if (menuById == null) {
        System.out.println("============菜品不存在============");
        return;
    }

    
    System.out.print("请输入菜品数量(0~99)(-1退出): ");
    int orderNums = Utility.readInt();
    if (orderNums == -1) {
        System.out.println("============取消点餐============");
        return;
    }
    if (orderNums <= 0) {
        System.out.println("============菜品数量不能小于等于0============");
        return;
    }

    
    //点餐
    if (billService.orderMenu(orderMenuId, orderNums, orderDiningTableId)) {
        System.out.println("============点餐成功============");
    } else {
        System.out.println("============点餐失败============");
    }

}

修改处3:在二级菜单中调用该方法

4.7.4测试

  • 正常数值输入
  • 非法数值判断


测试通过

有关day02-显示所有菜品&点餐功能的更多相关文章

  1. ruby-on-rails - rails : "missing partial" when calling 'render' in RSpec test - 2

    我正在尝试测试是否存在表单。我是Rails新手。我的new.html.erb_spec.rb文件的内容是:require'spec_helper'describe"messages/new.html.erb"doit"shouldrendertheform"dorender'/messages/new.html.erb'reponse.shouldhave_form_putting_to(@message)with_submit_buttonendendView本身,new.html.erb,有代码:当我运行rspec时,它失败了:1)messages/new.html.erbshou

  2. ruby-on-rails - 由于 "wkhtmltopdf",PDFKIT 显然无法正常工作 - 2

    我在从html页面生成PDF时遇到问题。我正在使用PDFkit。在安装它的过程中,我注意到我需要wkhtmltopdf。所以我也安装了它。我做了PDFkit的文档所说的一切......现在我在尝试加载PDF时遇到了这个错误。这里是错误:commandfailed:"/usr/local/bin/wkhtmltopdf""--margin-right""0.75in""--page-size""Letter""--margin-top""0.75in""--margin-bottom""0.75in""--encoding""UTF-8""--margin-left""0.75in""-

  3. ruby-on-rails - 'compass watch' 是如何工作的/它是如何与 rails 一起使用的 - 2

    我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t

  4. ruby-on-rails - Rails 编辑表单不显示嵌套项 - 2

    我得到了一个包含嵌套链接的表单。编辑时链接字段为空的问题。这是我的表格:Editingkategori{:action=>'update',:id=>@konkurrancer.id})do|f|%>'Trackingurl',:style=>'width:500;'%>'Editkonkurrence'%>|我的konkurrencer模型:has_one:link我的链接模型:classLink我的konkurrancer编辑操作:defedit@konkurrancer=Konkurrancer.find(params[:id])@konkurrancer.link_attrib

  5. ruby - 如何以所有可能的方式将字符串拆分为长度最多为 3 的连续子字符串? - 2

    我试图获取一个长度在1到10之间的字符串,并输出将字符串分解为大小为1、2或3的连续子字符串的所有可能方式。例如:输入:123456将整数分割成单个字符,然后继续查找组合。该代码将返回以下所有数组。[1,2,3,4,5,6][12,3,4,5,6][1,23,4,5,6][1,2,34,5,6][1,2,3,45,6][1,2,3,4,56][12,34,5,6][12,3,45,6][12,3,4,56][1,23,45,6][1,2,34,56][1,23,4,56][12,34,56][123,4,5,6][1,234,5,6][1,2,345,6][1,2,3,456][123

  6. ruby - 解析 RDFa、微数据等的最佳方式是什么,使用统一的模式/词汇(例如 schema.org)存储和显示信息 - 2

    我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i

  7. ruby-on-rails - 如何从 format.xml 中删除 <hash></hash> - 2

    我有一个对象has_many应呈现为xml的子对象。这不是问题。我的问题是我创建了一个Hash包含此数据,就像解析器需要它一样。但是rails自动将整个文件包含在.........我需要摆脱type="array"和我该如何处理?我没有在文档中找到任何内容。 最佳答案 我遇到了同样的问题;这是我的XML:我在用这个:entries.to_xml将散列数据转换为XML,但这会将条目的数据包装到中所以我修改了:entries.to_xml(root:"Contacts")但这仍然将转换后的XML包装在“联系人”中,将我的XML代码修改为

  8. ruby - 检查 "command"的输出应该包含 NilClass 的意外崩溃 - 2

    为了将Cucumber用于命令行脚本,我按照提供的说明安装了arubagem。它在我的Gemfile中,我可以验证是否安装了正确的版本并且我已经包含了require'aruba/cucumber'在'features/env.rb'中为了确保它能正常工作,我写了以下场景:@announceScenario:Testingcucumber/arubaGivenablankslateThentheoutputfrom"ls-la"shouldcontain"drw"假设事情应该失败。它确实失败了,但失败的原因是错误的:@announceScenario:Testingcucumber/ar

  9. ruby-on-rails - Rails 3.2.1 中 ActionMailer 中的未定义方法 'default_content_type=' - 2

    我在我的项目中添加了一个系统来重置用户密码并通过电子邮件将密码发送给他,以防他忘记密码。昨天它运行良好(当我实现它时)。当我今天尝试启动服务器时,出现以下错误。=>BootingWEBrick=>Rails3.2.1applicationstartingindevelopmentonhttp://0.0.0.0:3000=>Callwith-dtodetach=>Ctrl-CtoshutdownserverExiting/Users/vinayshenoy/.rvm/gems/ruby-1.9.3-p0/gems/actionmailer-3.2.1/lib/action_mailer

  10. ruby-on-rails - 如何优雅地重启 thin + nginx? - 2

    我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server

随机推荐