“吃货联盟定餐系统”需求说明
现今已进入网络时代,网上购物、看新闻、交友等人们的日常生活已离不开网络。“只
要点点手指,就能送餐上门”,网上定餐越来越受到都市年轻人的青睐 现要求开发一个
网上订餐系统,其具体功能如下:
一、我要订餐
完成用户订餐,每条订单包含如下信息:
订餐人姓名:要求用户输入
订餐人手机号:要求用户输入
选择菜品及份数:显示三个菜单序号、名称、单价、点赞数,提示用户输入要
选择的菜品序号及份数
送餐时间:要求当天 10 到 20 点间整点送餐,要求用户输入 10~20 的整数,输
入错误,重复输入。
送餐地址:要求用户输入
状态:两种状态:0:已预定(默认状态) 1、已完成(订单已签收)
总金额:
总金额 = 菜品单价*份数-送餐费
(送餐费:当单笔订单金额达到 50 元时,免送餐费,否则,需交纳 6 元送餐费)
订餐成功后,显示订单信息。
二、 查看订单
遍历显示已有定单
内容包括:序号、订餐人姓名、订餐信息(菜品名和份数)、送餐时间、送餐地址、
状态(已预定或已完成)、总金额
三、 签收定单
将定单中状态改为已完成
四、删除定单
用户输入订单序号,如该序号定单为已完成状态,可以删除,其它情况给出相应提示信息
五、我要点赞
显示菜品序号、菜品名、单价、点赞数,提示用户输入要点赞的菜品序号完成对菜品的点赞。
六、退出系统
退出整个系统,显示“谢谢使用,欢迎下次光临”。
分析
总分析
首先该系统共分为两大类,一类是订餐信息,一类是商品信息。
订单信息类具有姓名,手机号,订餐的菜品名称…等属性,与此同时,商品信息类具有菜品名称,菜品单价,点赞量等信息。因此可创建两个类,分别存储订餐信息和商品信息。
package Order_System;
//菜品信息
public class Dishes {
//属性
private String dishes_Name;//菜品名称
private double dishes_Price;//菜品单价
private int like_Count;//点赞数量
private int inventory_Count;//库存数量
//方法
public Dishes() {
super();
}
public Dishes(String dishes_Name, double dishes_Price, int like_Count, int inventory_Count) {
super();
this.dishes_Name = dishes_Name;
this.dishes_Price = dishes_Price;
this.like_Count = like_Count;
this.inventory_Count = inventory_Count;
}
public String getDishes_Name() {
return dishes_Name;
}
public void setDishes_Name(String dishes_Name) {
this.dishes_Name = dishes_Name;
}
public double getDishes_Price() {
return dishes_Price;
}
public void setDishes_Price(double dishes_Price) {
this.dishes_Price = dishes_Price;
}
public int getLike_Count() {
return like_Count;
}
public void setLike_Count(int like_Count) {
this.like_Count = like_Count;
}
public int getInventory_Count() {
return inventory_Count;
}
public void setInventory_Count(int inventory_Count) {
this.inventory_Count = inventory_Count;
}
}
package Order_System;
//订餐信息类
public class Orders {
//属性
private String name;//顾客姓名
private String dihes_Name;//菜品名称
private int dishes_Count;//订餐菜品数量
private int time;//送餐时间
private String address;//送餐地址
private int Ooder_Status;//订单状态-0 1 2
private double orde_Price;//餐钱-总金额
private String phone_Number;//手机号
private long order_time;//用于记录用户顶餐的时间
//方法
public Orders() {
super();
}
public Orders(String name, String dihes_Name, int dishes_Count, int time, String address, int ooder_Status,
double orde_Price, String phone_Number, long order_time) {
super();
this.name = name;
this.dihes_Name = dihes_Name;
this.dishes_Count = dishes_Count;
this.time = time;
this.address = address;
Ooder_Status = ooder_Status;
this.orde_Price = orde_Price;
this.phone_Number = phone_Number;
this.order_time = order_time;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDihes_Name() {
return dihes_Name;
}
public void setDihes_Name(String dihes_Name) {
this.dihes_Name = dihes_Name;
}
public int getDishes_Count() {
return dishes_Count;
}
public void setDishes_Count(int dishes_Count) {
this.dishes_Count = dishes_Count;
}
public int getTime() {
return time;
}
public void setTime(int time) {
this.time = time;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public int getOoder_Status() {
return Ooder_Status;
}
public void setOoder_Status(int ooder_Status) {
Ooder_Status = ooder_Status;
}
public double getOrde_Price() {
return orde_Price;
}
public void setOrde_Price(double orde_Price) {
this.orde_Price = orde_Price;
}
public String getPhone_Number() {
return phone_Number;
}
public void setPhone_Number(String phone_Number) {
this.phone_Number = phone_Number;
}
public long getOrder_time() {
return order_time;
}
public void setOrder_time(long order_time) {
this.order_time = order_time;
}
//方法
}
功能分析
我要订餐
虽然需求中只要求存储用户输入的基本信息,但一个好的程序往往需要考虑各个方面,不只是局限于基本需求。我们可以对每份菜品的数量做出限制,增加一个库存量,同时还可以增加一个time变量,记录用户的订餐时间,为后续功能服务(后续会新增加一个取消功能)。其次对于细节也需要完善,例如输入的合法性判断,以及手机号的格式验证(正则分割)、库存数量的判断(如果菜品库存为0则提示不能点该菜品)等等。
注意:可设置一个全局变量t,记录顾客的个数
查看餐袋
遍历订餐类对象数组,打印即可,但值得注意的是,如果当前没有订餐信息,我们需要给出提示。
签收订单
遍历订餐对象数组,打印信息。然后根据选择的序号 ,根据序号判断当前操作的对象的状态是否为1 1表示已完成。已完成签收状态才能签收,否则不能签收。其次需要注意的是,对于已经签收的状态不能反复签收。
取消订单
该功能为扩展功能,考虑用户点餐后有可能不想吃了,从而设计一个取消功能。但取消也不是任意客户取消,如果订餐时间到取消订餐的时间差小于1分钟,则可免费取消,否则不能取消(不然商家出餐了,成本算谁?),于是此处便用到了“我要点餐”功能时设置time变量。、
注意:取消的订单,要将订餐的数量还原到商品库存中。
删除订单
对于已预定的订单不能删除,删除时,可采用前移,全局变量t-1。
我要点赞
根据订单中的信息选择需要点赞的订单序号,然后根据该序号中的菜品名称与商品信息中的名称进行匹配(遍历),从而实现对该菜品点赞。
注意:
只有状态为已完成的订餐,才能点赞,其次不能反复点赞。
对于菜品信息的打印,可以根据点赞数量降序打印,将点赞数量最高的第一时间呈现在用户眼前。
完整代码
package Order_System;
import java.util.Calendar;
import java.util.Date;
import java.util.Scanner;
//订餐系统
public class Ordes_System {
public static int t=0;//统计有多少个顾客点单-全局
public static void main(String[] args) {
Orders[] order=new Orders[10];//存储10个顾客订餐信息
Dishes[] dishe=new Dishes[5];//五个菜品信息
//菜品信息初始化
dishe[0]=new Dishes("红烧排骨",18,0,10);
dishe[1]=new Dishes("宫保鸡丁",15,2,30);
dishe[2]=new Dishes("鱼香肉丝",28,1,6);
dishe[3]=new Dishes("红烧带鱼",38,5,15);
dishe[4]=new Dishes("红烧猪蹄",58,0,20);
Scanner input=new Scanner(System.in);
do {
System.out.println("*****欢迎使用吃货联盟订餐系统*****");
System.out.println("\t1.我要订餐");
System.out.println("\t2.查看餐袋");
System.out.println("\t3.签收订单");
System.out.println("\t4.取消订单");
System.out.println("\t5.删除订单");
System.out.println("\t6.我要点赞");
System.out.println("\t7.退出系统");
System.out.println("*******************************");
System.out.print("请选择:");
int num=fun("主菜单",input);
String name,phone,address,dishe_name = null;//顾客姓名,电话,地址,菜品名称
int time,order_count = 0;//送餐时间 数量
double order_price;//总金额
switch(num) {
case 1:
do {
if(t==order.length) {
System.err.println("\n当前订餐信息已满,无法订餐!!");
System.out.print("输入0,返回:");
while(true) {
fun("返回",input);
break;
}
break;
}
System.out.println("\n****************我要订餐****************");
dishes_Strat(dishe);
System.out.print("请输入选择你要订餐的序号(0返回):");
do {
num=fun("订餐",input);
if(num==0) {
break;
}else if(dishe[num-1].getInventory_Count()==0) {
System.err.print("当前"+dishe[num-1].getDishes_Name()+"菜品库存数量不足,请重新选择菜品序号:");
}else {
dishe_name=dishe[num-1].getDishes_Name();
break;
}
}while(true);
if(num==0) {
break;
}
System.out.print("请输入姓名(0返回):");
name=input.next();
if(name.equals("0")) {
break;//直接退出
}
System.out.print("请输入手机号(0返回):");
do {
phone=input.next();
if(phone.equals("0")) {
break;//直接退出
}else if(phone.matches("^1[3-9]\\d{9}$")) {//正则分割
break;
}else {
System.err.print("手机格式错误,请重新输入:");
}
}while(true);
if(phone.equals("0")) {
break;
}
System.out.print("请输入需要购买"+dishe[num-1].getDishes_Name()+"的份量["+dishe[num-1].getInventory_Count()+"](0返回):");
int num_ber;
do {
if(input.hasNextInt()) {
num_ber=input.nextInt();
if(num_ber==0) {
break;
}else if(num_ber<0) {
System.err.print("订餐数量必须大于0,请重新输入:");
}else if(num_ber>dishe[num-1].getInventory_Count()) {
System.err.print("不能超出库存数量,请重新输入:");
}else {
order_count=num_ber;
break;
}
}else {
System.err.print("输入不合法,请重新输入:");
input.next();
}
}while(true);
if(num_ber==0) {
break;
}
System.out.print("请输入送餐时间(0返回):");
time=fun("送餐时间",input);
if(time==0) {
break;
}
System.out.print("请输入送餐地址(0返回):");
address=input.next();
if(address.equals("0")) {
break;
}
double price=dishe[num-1].getDishes_Price()*order_count;
if(price>=50) {//达到50元 减免配送费
order_price=price+6;//6元配送费
}else {
order_price=price;
}
Date date=new Date();
order[t]=new Orders(name,dishe_name,order_count,time,address,0,order_price,phone,date.getTime());
dishe[num-1].setInventory_Count(dishe[num-1].getInventory_Count()-order[t].getDishes_Count());
t++;//顾客数量+1
System.out.println("订餐成功!!!");
System.out.print("是否需要继续点单Y or N?:");
String str=input.next();
while(!str.equalsIgnoreCase("N")&&!str.equalsIgnoreCase("Y")) {
System.err.print("请输入Y或N:");
str=input.next();
}
if(str.equalsIgnoreCase("N")) {
break;
}
}while(true);
System.out.println();
break;//我要订餐
case 2:
if(fuCtion(input)) {//如果订餐信息为0
System.out.println();
break;
}
System.out.print("\n**************************************查看餐袋**************************************************");
order_print(order);//打印餐袋信息
System.out.print("请输入0,返回:");
fun("返回",input);
System.out.println();
break;//查看餐袋
case 3:
if(fuCtion(input)) {//如果订餐信息为0
System.out.println();
break;
}
do {
System.out.print("\n**************************************签收订单**************************************************");
order_print(order);//打印餐袋中的信息
System.out.print("请选择需要签收的订单序号(0返回):");
do {
if(input.hasNextInt()) {
num=input.nextInt();
if(num==0) {
break;
}else if(num<0||num>t) {
System.err.print("输入范围不合理,请重新选择(0返回):");
}else if(order[num-1].getOoder_Status()==3) {
System.err.print(num+"序号订单已取消,不能签收,请重新选择(0返回):");
}else if(order[num-1].getOoder_Status()==1||order[num-1].getOoder_Status()==2) {
System.err.print(num+"序号订单已签收,不能重复签收,请重新选择(0返回):");
}else {
order[num-1].setOoder_Status(1);//更新状态
System.out.println(num+"序号订单,签收成功!");
break;
}
}else {
System.err.print("输入非法,请重新选择(0返回):");
input.next();
}
}while(true);
if(num==0) {
break;
}
System.out.print("是否需要继续签收订单:Y or N?:");
String str=input.next();
while(!str.equalsIgnoreCase("N")&&!str.equalsIgnoreCase("Y")) {
System.err.print("请输入Y或N:");
str=input.next();
}
if(str.equalsIgnoreCase("N")) {
break;
}
}while(true);
System.out.println();
break;//签收订单
case 4:
if(fuCtion(input)) {//如果订餐信息为0
System.out.println();
break;
}
do {
System.out.print("\n**************************************取消订单**************************************************");
int count;
order_print(order);//打印餐袋中的信息
System.out.print("请选择你要取消的订单序号(0返回):");
do {
Date date=new Date();
long s=date.getTime();//获取系统当前的毫秒
if(input.hasNextInt()) {
count=input.nextInt();
if(count==0) {
break;
}else if(count<0||count>t) {
System.err.print("输入范围错误,请重新输入(0返回):");
}else if(order[count-1].getOoder_Status()==0) {//已预定状态
if((s-order[count-1].getOrder_time())<=60000) {
System.out.println(count+"订单序号,取消成功!");
for(int i=0;i<dishe.length;i++) {
if(dishe[i].getDishes_Name().equals(order[count-1].getDihes_Name())) {//将取消的库存量还原
dishe[i].setInventory_Count(dishe[i].getInventory_Count()+order[count-1].getDishes_Count());
}
}
order[count-1].setOoder_Status(3);
break;
}else {//订餐时间已超出1分钟 不能取消
long ms=order[count-1].getOrder_time()/1000;//获取秒数
long h=ms/(60*60),m=(ms/60)-h*60;//小时 分钟
s=s-(h*60*60)-(m*60);
System.err.print("你的订餐预定时间为:"+h+"点"+m+"分"+ms+"秒"+",已过1分钟,不能取消,请重新选择(0返回):");
}
}else if(order[count-1].getOoder_Status()==3){//已取消状态
System.err.print(count+"订单已取消,不能重复取消,请重新选择(0返回):");
}else {//已完成
System.err.print(count+"订单已完成,不能取消,请重新选择(0返回):");
}
}else {
System.err.print("非法输入,请重新输入(0返回):");
input.next();
}
}while(true);
if(count==0) {
break;
}
System.out.print("是否需要继续取消订单:Y or N?:");
String str=input.next();
while(!str.equalsIgnoreCase("N")&&!str.equalsIgnoreCase("Y")) {
System.err.print("请输入Y或N:");
str=input.next();
}
if(str.equalsIgnoreCase("N")) {
break;
}
}while(true);
System.out.println();
break;//取消订单
case 5:
do {
if(fuCtion(input)) {//如果订餐信息为0
System.out.println();
break;
}
System.out.print("\n**************************************删除订单**************************************************");
order_print(order);//打印餐袋中的信息
do {
System.out.print("请选择需要删除的订单序号(0返回):");
if(input.hasNextInt()) {
num=input.nextInt();
if(num==0) {//输入0返回
break;
}else if(num<0||num>t) {
System.err.println("输入范围错误,请重新选择!!!");
}else if(order[num-1].getOoder_Status()==0) {//未签收
System.err.println(num+"订单未签收,不能删除,请先签收!!!!");
}else {//已签收订单
for(int i=num-1;i<t-1;i++) {
Orders ordes=order[i];
order[i]=order[i+1];
order[i+1]=ordes;
}
order[t-1]=null;
t--;
System.out.println("删除成功!!!");
break;
}
}else {
System.err.println("输入非法,请重新选择:");
input.next();
}
}while(true);
if(num==0) {
break;
}
System.out.print("是否需要继续删除订单:Y or N?:");
String str=input.next();
while(!str.equalsIgnoreCase("N")&&!str.equalsIgnoreCase("Y")) {
System.err.print("请输入Y或N:");
str=input.next();
}
if(str.equalsIgnoreCase("N")) {
break;
}
}while(true);
System.out.println();
break;//删除订单
case 6:
if(fuCtion(input)) {//如果订餐信息为0
System.out.println();
break;
}
do {
System.out.print("\n**************************************我要点赞**************************************************");
order_print(order);
System.out.print("请选择你要点赞的订单序号(0返回):");
do {
if(input.hasNextInt()) {
num=input.nextInt();
if(num==0) {
break;
}else if(num<0||num>t) {
System.err.print("输入的范围不合理,请重新输入:");
}else if(order[num-1].getOoder_Status()==0){
System.err.print(num+"订单序号未签收,不能点赞,请重新选择(0返回):");
}else if(order[num-1].getOoder_Status()==3) {
System.err.print(num+"订单序号已取消,不能点赞,请重新选择(0返回):");
}else if(order[num-1].getOoder_Status()==2) {//2表示已签收并且已经做出评价-点赞
System.err.print(num+"订单序号已经点赞过啦,请重新选择(0返回):");
}else {
order[num-1].setOoder_Status(2);
for(Dishes dishes:dishe) {
if(dishes.getDishes_Name().equals(order[num-1].getDihes_Name())) {
dishes.setLike_Count(dishes.getLike_Count()+1);
System.out.println(num+"订单序号点赞成功,当前"+dishes.getDishes_Name()+"菜品有"+dishes.getLike_Count()+"个赞");
break;
}
}
break;
}
}else {
System.err.print("输入不合法,请重新选择(0返回):");
input.next();
}
}while(true);
if(num==0) {
break;
}
System.out.print("是否需要继续点赞:Y or N?:");
String str=input.next();
while(!str.equalsIgnoreCase("N")&&!str.equalsIgnoreCase("Y")) {
System.err.print("请输入Y或N:");
str=input.next();
}
if(str.equalsIgnoreCase("N")) {
break;
}
}while(true);
System.out.println();
break;//我要点赞
default:System.out.print("谢谢使用,欢迎下次光临!");System.exit(0);//退出系统
}
}while(true);
}
public static boolean fuCtion(Scanner input) {//判断有无订餐信息
if(t==0){
System.err.println("暂无订餐信息,请先添加订餐信息!!!");
return true;
}
return false;
}
public static void order_print(Orders[] order) {//打印餐袋信息
System.out.println("\n序号\t订餐人\t手机号\t\t餐品信息 数量\t\t送餐时间\t送餐地址\t配送费\t总金额\t订单状态");
for(int i=0;i<t;i++) {
System.out.println((i+1)+"\t"+order[i].getName()+"\t"+order[i].getPhone_Number()+"\t"+order[i].getDihes_Name()+" "+order[i].getDishes_Count()+"份\t\t"+order[i].getTime()+"点\t"+
order[i].getAddress()+"\t"+(order[i].getOrde_Price()-6>=44?"6":"0")+"元\t"+order[i].getOrde_Price()+"元\t"
+(order[i].getOoder_Status()==0?"已预定":(order[i].getOoder_Status()==1||order[i].getOoder_Status()==2)?"已完成":"已取消")
);
}
}
public static int dishes_Strat(Dishes[] dishes) {//菜品信息打印
System.out.print("序号\t菜品名称\t菜品单价\t库存数量\t点赞数量");
//排序 根据点赞数量降序
for(int i=0;i<dishes.length-1;i++) {
for(int j=0;j<dishes.length-1-i;j++) {
if(dishes[j].getLike_Count()<dishes[j+1].getLike_Count()) {
Dishes dishe=dishes[j];
dishes[j]=dishes[j+1];
dishes[j+1]=dishe;
}
}
}
System.out.println();
for(int i=0;i<dishes.length;i++) {
System.out.println((i+1)+"\t"+dishes[i].getDishes_Name()+"\t"+dishes[i].getDishes_Price()+"元\t"+dishes[i].getInventory_Count()
+"份\t"+dishes[i].getLike_Count()+"个");
}
return 0;//菜品信息打印
}
public static int fun(String str,Scanner input) {//部分合法性的判断
while(true) {
boolean flag=true;
int num;
if(str.equals("主菜单")||str.equals("订餐")||str.equals("送餐时间")||str.equals("返回")) {
if(input.hasNextInt()) {
num=input.nextInt();
if(str.equals("主菜单")&&(num<=0||num>7)||str.equals("订餐")&&(num<0||num>5)) {
flag=false;
System.err.print("输入范围错误,请重新输入:");
}else if(str.equals("送餐时间")&&num==0) {
return num;
}else if(str.equals("送餐时间")&&(num<10||num>20)) {
flag=false;
System.err.print("只支持10~20点,整点送餐,请重新输入:");
}else if(str.equals("返回")&&num!=0) {
flag=false;
System.err.print("输入0 返回,请重新输入:");
}else {
return num;
}
}
}
if(flag) {
System.err.print("输入非法,请重新输入:");
input.next();
}
}
}
}
运行结果