需求分析
系统概述
“只要动动手指,就能送餐上门”,网上订餐深受现代人青睐,现开发一个网上订餐系统,功能如下
1.我要订餐
2.查看餐袋
3.签收订单
4.删除订单
5.我要点赞
6.退出系统
系统开发步骤
开发思路
首先我们设计出一个小型餐厅
定义出菜单 例:
//餐厅菜单
String[] dishNames = {"红烧带鱼", "糖醋排骨", "清蒸大闸蟹", "糖醋鱼", "糖醋里脊", "拍黄瓜"};//菜品名称
double[] dishPrices = {29.9, 39.9, 59.9, 29.9, 19.9, 99.99};//菜品单价
有了餐厅,肯定是有订单的,假设Tom顾客在手机上下单,买了一份拍黄瓜,那么首先需要收集Tom的信息,然后记录在数据中。
现在的Tom信息为
注:订单状态为动态更新
订单状态为未签收时不可删除该订单
等待Tom切换到签收订单选择正确,那么订单状态切换为已签收,方可删除该订单。
Tom还可以删除他的订单记录,删除在这个项目中是比较有难度的
具体思路为:
我们利用后推前的原理,利用二重循环。例如,现在后台有3个订单,均为Tom购买,订单都有各自的编号,假设删除第1个订单,那么我们先将第二个订单中所有信息赋值给第一个订单,那么最后就多出来了一个,我们再将最后一个订单的所有信息赋值为null,就达到了我们想要的删除效果。
点赞功能的思路就简单了
先列出菜品名称以及点赞的数量
然后让Tom输入想要点赞的菜品序号,
将输入的序号录入点赞数组中
在这里下标需要--,因为数组下标是从0开始的,所以需要往前推一位。
到这里我们的思路就差不多了,
我们发现,一个订单中的信息有很多,单个的变量属实不方便,所以我们利用数组来完成这次项目的开发
我们获取到的信息为
订餐人姓名 订餐人地址 订单状态 订餐份数 送餐时间
菜品名称 菜品单价 点赞数量 总价
操作者为管理员类,我们录入多条订单信息,操作者来执行相应的操作
搭建框架
下面我们正式进入开发
我们首先搭建框架,代码示例如下:
DecimalFormat df = new DecimalFormat("####0.00");//配置double类型保留前两位小数
Scanner sca = new Scanner(System.in);//控制台输入工具
//数据主体,一组订单信息
String[] names = {"User1", "User2", null, null, null};//订餐人姓名
String[] addresses = {"村西头001", "村西头002", "", "", ""};//订餐地址
int[] states = {1, 0, 0, 0, 0};//订单状态 0:未签收 1:已签收
int[] nums = {2, 3, 0, 0, 0};//订餐份数
int[] times = {12, 19, 0, 0, 0};//送餐时间
//固定信息
String[] dishNames = {"红烧带鱼", "糖醋排骨", "清蒸大闸蟹", "糖醋鱼", "糖醋里脊", "拍黄瓜"};//菜品名称
double[] dishPrices = {29.9, 39.9, 59.9, 29.9, 19.9, 99.99};//菜品单价
int[] priaiseNums = {10, 10, 10, 10, 10, 10};//点赞数量
double[] sumMoney = {59.8, 119.7, 0, 0, 0};//总价格
boolean isExit = false;//标注用户是否退出系统 true:退出系统
System.err.println("欢迎来到吃货联盟订餐系统");
do{
System.out.println("***********************\n"
+ "1.我要订餐\n"
+ "2.查看订单\n"
+ "3.签收订单\n"
+ "4.删除订单\n"
+ "5.我要点赞\n"
+ "6.退出系统\n"
+ "***********************\n"
+ "请根据序号进行选择:");
switch(sca.next()){
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":
isExit = true;
break;
}
}while(!isExit);
if (isExit) {//判断是否成功退出系统
System.out.println("感谢使用,再见!");
}
sca.close();//关闭资源
项目基本框架搭建完毕,下面我们进入实现功能的代码编写。
编写功能
1.我要订餐功能
该功能简要概述:
首先我们需要通过循环来获取是否有空位可以订餐,默认数组长度为4,一旦数组中没有空位做出相应的提示,有空位就收集用户的信息。
代码如下:
case "1":
System.out.println("***我要订餐***");
int count = 0;//利用计数法判断存储空间是否存满 0:已存满 -1:未存满
for (int i = 0; i < names.length; i++) {
if (names[i] == null) {//找到空位,可以添加信息
System.out.println("请输入您的姓名:");
String name = sca.next();
System.out.println("菜品序号\t菜品名称\t菜品单价\t点赞数量");
for (int j = 0; j < dishNames.length; j++) {
System.out.println((j + 1) + "\t" +
dishNames[j] + "\t" + dishPrices[j]
+ "\t" + priaiseNums[j]);
}
System.out.println("请选择您要点的菜品序号:");
int choise = sca.nextInt();
System.out.println("请选择您要点的份数:");
int number = sca.nextInt();
double money = dishPrices[choise-1] * number;
double sum = money > 50 ? 0 : 10;//如果菜品总价大于50,无配送费,反之配送费10元
money += sum;//累加配送费
System.out.println("请输入配送时间(送餐时间10:00~20:00送餐):");
int time = sca.nextInt();
while (!(time > 10 && time < 20)) {
System.out.println("该时间点本店不送餐,请您重新输入:");
time = sca.nextInt();
}
System.out.println("请输入送餐地址:");
String addr = sca.next();
//添加数据
names[i] = name;
nums[i] = number;
dishPrices[i] = money;
times[i] = time;
addresses[i] = addr;
count = -1;
System.out.println("订餐成功~");
System.out.println("订餐人姓名:" + name
+ "\n所定菜品:" + dishNames[choise - 1]
+ "\n购买份数:" + number
+ "份\n送餐地址:" + addr
+ "配送费:" + sum
+ "共计:¥" + money);
System.out.println(dishNames[choise-1] + "菜品将在" + time + "点之前送达,请您注意短信提醒!");
break;
}
}
if (count == 0) {
System.out.println("存储空间已满,无法存储!");
}
break;
2.查看餐袋
简要概述:该功能实现就比较简单了,直接循环遍历信息即可,需要注意的是,订单状态不能显示出来数字(我们利用三目运算符来判断当前订单的状态) 0:未签收 1:已签收
case "2":
System.out.println("***查看订单***");
System.out.println("订单序号\t订单人\t所选菜品\t购买份数\t菜品单价\t送餐地址\t订单状态\t共计");
for (int i = 0; i < names.length; i++) {
if (names[i] != null) {
//利用三目运算符来判断当前订单的状态
String state = states[i] == 0 ? "未签收" : "已签收";
System.out.println((i + 1) + "\t" + names[i]
+ "\t" + dishNames[i] + "\t" + nums[i]
+ "\t¥" + dishPrices[i] + "\t" + addresses[i]
+ "\t" + state + "\t¥" + dishPrices[i]);
}
}
break;
3.签收订单
简要概述:我们首先循环遍历出来订单信息,然后让用户根据序号进行签收订单。
签收订单大概分为3种情况,
1.输入正确的序号且当前状态为未签收,这种情况可以签收
2.输入正确的序号且当前状态为已签收还未删除,这种情况须作出相应的提示
3.输入序号不存在。作出提示。
代码如下:
case "3":
System.out.println("***签收订单***");
int signCount = 0;
for (int i = 0; i < names.length; i++) {
if (names[i] != null) {
String state = states[i] == 0 ? "未签收" : "已签收";
System.out.println((i + 1) + "\t" + names[i]
+ "\t" + dishNames[i] + "\t" + state);
}
}
System.out.println("请输入要签收的订单序号:");
int signOrderId = sca.nextInt();
for (int i = 0; i < names.length; i++) {
if (names[i] != null && states[i] == 0 && signOrderId == i + 1) {
states[i] = 1;
signCount = -1;
System.out.println("签收成功~");
} else if (names[i] != null && states[i] == 1 && signOrderId == i + 1) {
System.out.println("您选择的订单已签收,不能再次签收!");
signCount = -1;
}
}
if (signCount == 0) {
System.out.println("您输入的编号不存在,签收失败!");
}
break;
4.删除订单
简要概述:该功能我们利用双重循环后推前的原理来实现,也是大概分为3种情况
1.输入正确的序号且当前状态为未签收,这种情况不可以删除
2.输入正确的序号且当前状态为已签收,这种情况可以删除
3.输入序号不存在。作出提示。
代码如下:
case "4":
System.out.println("***删除订单***");
for (int i = 0; i < names.length; i++) {
if (names[i] != null) {
String state = states[i] == 0 ? "未签收" : "已签收";
System.out.println((i + 1) + "\t" + names[i]
+ "\t" + dishNames[i] + "\t" + state);
}
}
System.out.println("请输入要删除的订单序号:");
int delId = sca.nextInt();
int delCount = 0;
for (int i = 0; i < names.length; i++) {
if (names[i] != null && states[i] == 1 && delId == i + 1) {
delCount = -1;
//执行删除操作,删除位置后的元素依次前移
for (int j = delId - 1; j < names.length-1; j++) {
names[j] = names[j+1];
dishNames[j] = dishNames[j+1];
dishPrices[j] = dishPrices[j+1];
sumMoney[j] = sumMoney[j+1];
states[j] = states[j+1];
times[j] = times[j+1];
nums[j] = nums[j+1];
addresses[j] = addresses[j+1];
}
names[names.length - 1] = null;
dishNames[dishNames.length - 1] = null;
dishPrices[dishPrices.length - 1] = 0;
sumMoney[sumMoney.length - 1] = 0;
states[states.length - 1] = 0;
times[times.length - 1] = 0;
nums[nums.length - 1] = 0;
addresses[addresses.length - 1] = null;
System.out.println("删除成功~");
break;
} else if (names[i] != null && states[i] == 0 && delId == i + 1) {
System.out.println("您选择的订单未签收,无法删除!");
}
}
if (delCount == 0) {
System.out.println("未找到该订单,您的输入有误,删除失败!");
}
break;
5.我要点赞
简要概述:为喜欢的菜品点赞,首先需展示出可以点赞的菜品列表,然后让用户输入要点赞的菜品序号,判断输入的序号是否出界,反之则点赞成功。
代码如下:
case "5":
System.out.println("***我要点赞***");
System.out.println("菜品序号\t菜品名称\t菜品单价\t点赞数量");
for (int i = 0; i < dishNames.length; i++) {
System.out.println((i + 1) + "\t" + dishNames[i]
+ "\t" + dishPrices[i] + "\t" + priaiseNums[i]);
}
System.out.println("请输入您要点赞的菜品序号:");
int priaise = sca.nextInt();
//判断输入的数字是否出界
if (priaise < 0 || priaise > dishNames.length) {
System.out.println("您输入的数字有误,点赞失败!");
} else {
//在这里输入的序号需要-1,因为数组是从0开始的,所以需要前进一位
priaiseNums[priaise-1] ++;
System.out.println("点赞成功~");
}
break;
项目总结
该项目用到的知识点为Java基础,主要锻炼基础的扎实程度及掌握的知识概念。
通过练习这次项目提高了基础的扎实,巩固知识,提高了自己的编程逻辑,可以掌握一些基础语法的使用及运用场景。
不熟练的可以多敲上几遍,熟能生巧,加油,我们共同进步,提升自己的编程知识!
过几天我会把这个Java基础面向对象版本的吃货联盟订餐系统详细分析发出来,希望大家多多支持,感谢!!!