01项目概述.avi
02需求分析.avi
03概要设计.avi
04详细设计.avi
01项目概述
* A: 项目概述
* a: 对水果超市管理系统开发文档的简单介绍
02需求分析
* A: 需求分析
* a: 系统体系结构
* 基于CS结构进行开发
* b: 系统总体流程
* 详见day06_source文件夹中的"系统总体流程_1.jpg"图片
* c: 功能描述
* 对于本系统,用户一共分成两种,顾客与水果超市工作人员(以下称为管理员)。
项目通过控制台/DOS命令行执行。
* 顾客可以浏览水果,并且购买水果,打印水果购物票算购买完成一次。
管理员可以查看每日详细流水,和每日购物总价结算。并且可以增删改查水果种类。
* 详见day06_source文件夹中的"系统功能描述图_2.jpg"图片
* B: 系统界面
* a: 注意
* 我们将普通用户登录使用的功能叫做前台功能
* 我们将系统管理者管理系统的功能叫做后台功能
* 这里我们没有明确区分前后台操作,使用角色判断的方式完成区分。
* b: 首页
* 用来选择与区分角色。
* c: 顾客界面(前台界面)
* 顾客选择操作界面
* 物品展示与购买界面
* 付款,即打印小票界面
* d: 水果超市工作人员界面(管理员界面,后台页面)
* 管理员选择操作界面
* 流水查询界面
* 总收入查询界面
* 查看水果界面
* 增加水果界面
* 根据水果编号删除货物界面
* 根据水果编号修改货物界面
03概要设计
* A: 概要设计
* a: 运行环境
* 操作系统:Windows环境下命令行窗口/Eclipse控制台运行.
* 软件需求:JRE7u51
* b: 基本功能需求
* 顾客可以浏览水果
* 顾客可以指定水果输入数量购买水果
* 顾客可以打印水果购物票完成一个完整的购买动作。
* 管理员可以查看每日详细流水
* 管理员可以查看每日购物总价结算
* 管理员可以增删改查水果种类。
* c: 功能模块设计
* 不采用模块设计
* d: 程序流程图
* 无
* e: 数据库设计
* 由于目前还没有学习数据库,所以本例中数据存储的地方为ArrayList集合,虽然这带来了很多不便。
* f: ER图
* 无
* g: 表设计
* 无
04详细设计
* A: 系统设计
* a: 开发环境
* 开发本系统我们所使用的工具与技术有:
* Eclipse3.7.2 JDK7u51
* b: 架构设计
* 无
* B: 详细设计
* a: 详细设计作用
* 详细设计是用来设计多种多个不同文件的相互访问过程。由于制作本例时还没有学习面向对象,所以除业务模型以外没有分其他的类。
* 这里给出涉及到的功能方法。
* b: 主流程外相关方法
* 功能问题
* 无,异常不进行处理。
* 权限问题
* 对于顾客,不可以对水果进行增删改查与流水总价查询。
* 对于管理员,不可以购买水果。
* 工具方法
* public static int enterNumber() //录入整数
* public static String enterString() //录入字符串
* public static double enterDouble() //录入小数
* c: 首页
* 用户选择角色
* static ArrayList<FruitItem> list = new ArrayList<FruitItem>(); //定义集合用来存储水果数据
* public static void init() //营业开始前需要准备初始数据
* public static void doBusiness() //商店营业,用于选择客户
* d: 顾客功能(前台功能)
* 购物
* public static void purchase() //购物方法
* public static void buy() //买动作方法
* public static void showFruitList() { //购买前查看水果列表
* public static void printReceipt() //付款(打印小票)方法
* public static double doDiscount(double totalMoney) {
* //付款时总价打折方法
* public static void resetNumber() //复位水果购买数量
* e: 管理员功能(后台功能)
* 货物操作
* public static void check() //货物查询
* static ArrayList<Double> flowData =
* new ArrayList<Double>(); //定义流水集合,用来记录每次收入
* public static void showFlow() //展示超市流水
* public static void dailyIncome() //展示当日总收入
* public static void addFruitItem() //添加新水果
* public static void delFruitItem() //删除水果
* public static void updateFruitItem() //修改水果
* public static void showFruitList()
//查看水果列表,与购买时的水果列表是同一个方法
========================================第一阶段=============================
05业务模型实现.avi
06数据输入方法实现.avi
07业务逻辑架构实现.avi
08展示商品报价单功能实现.avi
09买方法功能实现.avi
10打印小票功能实现票头与票体.avi
11票脚与打折功能实现.avi
05业务模型实现
* A: 环境搭建
* a: 导入jar包
* 无需导包
* b: 建立package结构
* 无包结构
* B: 业务模型实现
* 定义业务模型FruitItem类
/*
* 定义水果项业务模型
*
* String name//商品名称
* String ID//商品编号
* double price//商品单价
* String unit//商品计价单位
* int number//商品数量
* double money//商品金额
*/
public class FruitItem {
String name;
int ID;
double price;
String unit;
int number;
double money;
}
06数据输入方法实现
* A: 数据输入方法实现
* a: 创建水果超市管理系统的主类FruitStore
* b: 在FruitStore类中添加数据输入的方法
* c: 案例代码
public class FruitStore {
public static void main(String[] args) {
}
// 录入整数
public static int enterNumber() {
Scanner sc = new Scanner(System.in);
int intResult = sc.nextInt();
return intResult;
}
// 录入小数
public static double enterDouble() {
Scanner sc = new Scanner(System.in);
return sc.nextDouble();
}
// 录入字符串
public static String enterString() {
Scanner sc = new Scanner(System.in);
return sc.nextLine();
}
}
07业务逻辑架构实现
* A: 业务逻辑架构实现
* a: 定义集合存储所有数据,所以要定义在成员位置
* b: 利用switch搭建项目的整体架构
* B: 案例代码
public class FruitStore {
// 成员位置定义集合,用于存储所有数据
static ArrayList<FruitItem> list = new ArrayList<FruitItem>();
public static void main(String[] args) {
// 调用数据初始化方法
init();
// 通过循环使得用户选择操作反复执行
while (true) {
// 用户的一次选择操作票
System.out.println();
System.out.println("欢迎欢迎!");
System.out
.println("请选择您要进行的操作:1、购买 2、结账(打印小票) 3、流水查询 4、总收入查询 5、添加新水果 6、删除水果 7、修改水果8、查看水果 9、退出");
// 接收用户输入的操作选项
int choose = enterNumber();
// 依据用户的操作选项执行对应方法
switch (choose) {
case 1:
break;
case 2:
break;
case 3:
break;
case 4:
break;
case 5:
break;
case 6:
break;
case 7:
break;
case 8:
break;
case 9:
System.out.println("欢迎下次光临!");
break;
default:
System.out.println("您输入的选项有误,请重新输入!");
break;
}
}
}
// 初始化数据方法init
public static void init() {
// 创建元素对象
FruitItem item = new FruitItem();
item.name = "泰国空运大榴莲";
item.ID = 9056;
item.price = 120;
item.unit = "个";
FruitItem item2 = new FruitItem();
item2.name = "山东大枣";
item2.ID = 9047;
item2.price = 2.5;
item2.unit = "斤";
FruitItem item3 = new FruitItem();
item3.name = "昌平草莓";
item3.ID = 9875;
item3.price = 18;
item3.unit = "斤";
// 将元素放入集合中
list.add(item);
list.add(item2);
list.add(item3);
}
// 录入整数
public static int enterNumber() {
Scanner sc = new Scanner(System.in);
int intResult = sc.nextInt();
return intResult;
}
// 录入小数
public static double enterDouble() {
Scanner sc = new Scanner(System.in);
return sc.nextDouble();
}
// 录入字符串
public static String enterString() {
Scanner sc = new Scanner(System.in);
return sc.nextLine();
}
}
08展示商品报价单功能实现
* A: 展示商品报价单功能实现
* a: 购买方法
* case 1: buy();
* 在buy方法中要先展示商品报价单,所以先定义查看水果列表的方法showFruitList()
* case 8:为查看水果,所以只需要再次调用查看水果列表的方法showFruitList()
* b: 案例代码
// 买方法
public static void buy() {
// 展示物品列表
showFruitList();
}
// 查看水果列表
public static void showFruitList() {
// 打印列表表头
System.out.println("编号 商品名称 商品单价 计价单位");
// 遍历成员位置存储所有数据的集合,依次获取当前集合中每一个水果项
for (int i = 0; i < list.size(); i++) {
FruitItem thisItem = list.get(i);
// 打印水果项
System.out.println("" + thisItem.ID + " " + thisItem.name + " "
+ thisItem.price + " " + thisItem.unit);
}
}
09买方法功能实现
* A: 买方法功能实现
* a: 案例代码
// 买方法
public static void buy() {
// 展示物品列表
showFruitList();
// 整个购买选编号的过程是一个死循环,使得用户可以反复输入不同编号的水果项
// 一次循环是选择一个编号的水果
while (true) {
// 用户自主选择商品及数量
System.out.println("请您选择要购买的水果编号,如果0代表购买结束");
int chooseID = enterNumber();
// 判断标志位,跳出购买
if (chooseID == 0) {
return;
}
// 如果没有输入0,代表要购买物品,匹配物品编号
// 遍历集合,依次获取每一个水果项对象 该循环表示:选择一个编号要完成多次循环
// 定义变量,记录是否有该编号的水果项
boolean flag = false;
for (int i = 0; i < list.size(); i++) {
FruitItem thisItem = list.get(i);
// 将当前水果项的编号与用户输入的编号对比
if (thisItem.ID == chooseID) {
// 如果匹配,说明找到了该编号的水果项,继续提示输入购买数量
System.out.println("请您输入要购买的水果数量:");
thisItem.number = enterNumber();
// 如果找到了匹配编号的水果并将数量赋值,就将是否有该编号这个布尔值置为true
flag = true;
}
}
// 根据是否有该编号,判断是否给错误提示
if (!flag) {
// 如果所有的水果项编号与输入的都不匹配,就提示输入有误
System.out.println("您输入的编号有误,请重新输入!");
}
}
}
10打印小票功能实现票头与票体
* A: 打印小票功能实现票头与票体
* a: 打印小票时有个数据是丢失的(money项没有值,可以在购买时赋值,也可以在打印小票时赋值都可以)
* 在购买方法buy()中添加一行代码 thisItem.money = thisItem.price * thisItem.number;
* b: switch中case 2 后调用结账、打印购物小票的方法printReceipt();
* c: printReceipt()方法代码
// 打印小票方法
public static void printReceipt() {
// 票头
System.out.println("这是您这次消费的购物小票:");
System.out.println("==============================================");
System.out.println("欢 迎 光 临");
System.out.println();
System.out.println("品名 售价 数量 金额");
System.out.println("--------------------------------------");
// 票体
// 遍历集合,依次获取每一个水果项对象
for (int i = 0; i < list.size(); i++) {
FruitItem thisItem = list.get(i);
// 判断当前水果项数量是否为0,如果为0,则不打印,说明用户没有买该商品
if (thisItem.number != 0) {
// 可以加入判断水果项名称是否超长(超过7个字,改为7个字+...) 本次不加入了
System.out.println(thisItem.name + "(" + thisItem.ID
+ ") " + thisItem.price + " * "
+ thisItem.number + "(" + thisItem.unit + ")"
+ " = " + thisItem.money);
}
}
}
11票脚与打折功能实现
* A: 票脚与打折功能实现
* a: 分析
* (1): 定义变量记录购买的水果项数(int itemNumber = 0)
* (2): 定义变量记录折前总金额(double totalMoney = 0)
* (3): 实现打折逻辑时,发现代码比较多,所以单独封装一个方法doDiscount()
* (4): 在用户购买时,要显示打折活动
* b: 案例代码
// 打印小票方法
public static void printReceipt() {
// 票头
System.out.println("这是您这次消费的购物小票:");
System.out.println("==============================================");
System.out.println("欢 迎 光 临");
System.out.println();
System.out.println("品名 售价 数量 金额");
System.out.println("--------------------------------------");
// 票体
// 定义变量,记录购买的水果项数
int itemNumber = 0;
// 定义变量,记录折前总金额
double totalMoney = 0;
// 遍历集合,依次获取每一个水果项对象
for (int i = 0; i < list.size(); i++) {
FruitItem thisItem = list.get(i);
// 判断当前水果项数量是否为0,如果为0,则不打印,说明用户没有买该商品
if (thisItem.number != 0) {
// 可以加入判断水果项名称是否超长(超过7个字,改为7个字+...) 本次不加入了
System.out.println(thisItem.name + "(" + thisItem.ID
+ ") " + thisItem.price + " * "
+ thisItem.number + "(" + thisItem.unit + ")"
+ " = " + thisItem.money);
// 当有一项商品数量不为0,代表买了一个新商品,商品项数+1,并且将金额加入到总金额中
itemNumber++;
totalMoney += thisItem.money;
}
}
// 票脚
// 打折
double afterTotalMoney = doDiscount(totalMoney);
System.out.println("--------------------------------------");
System.out.println(itemNumber + "项水果");
System.out.println("总计:" + afterTotalMoney + "元");
System.out.println("优惠活动让您节省了" + (totalMoney - afterTotalMoney) + "元");
System.out.println("==============================================");
}
public static double doDiscount(double totalMoney) {
// 判断总金额和榴莲两种数据是否满足打折条件,满足就打折
/*
* 如果商品总价超过300元,打95折 如果商品总价超过600元,打9折 如果商品总价超过1000元,总价打8折
* 如果商品总价超过1000元,并且榴莲购买超过10个, 则总价打8折后,立减50
*/
double afterTotalMoney = totalMoney;
// 满300打95折
if (totalMoney >= 300 && totalMoney < 600) {
afterTotalMoney = totalMoney * 0.95;
} else if (totalMoney >= 600 && totalMoney < 1000) {// 满600打9折
afterTotalMoney = totalMoney * 0.9;
} else if (totalMoney >= 1000) {// 满1000打8折
afterTotalMoney = totalMoney * 0.8;
}
// 满1000且榴莲超过10,打8折再立减50
if (totalMoney >= 1000 && list.get(0).number >= 10) {
afterTotalMoney = totalMoney * 0.8 - 50;
}
return afterTotalMoney;
}
===================================第二阶段===========================================
12流水查询总收入查询重置数据功能实现.avi
13添加水果项代码实现.avi
14删除水果项代码实现.avi
15修改水果项代码实现.avi
12流水查询总收入查询重置数据功能实现
* A: 流水查询总收入查询重置数据功能实现
* a: 分析
* (1): 先记录流水
* 成员位置定义集合,记录流水 static ArrayList<Double> flowData = new ArrayList<Double>();
* 在结账打完折后记录流水,在printReceipt方法的最后添加代码
// 将折后价记录到流水中
flowData.add(afterTotalMoney);
* (2): 再查询流水
* a: 在switch语句的case 3 后调用展示流水方法showFlow()
case 3:
// 流水查询:流水记录 流水查询
showFlow();
break;
* b: 在switch语句的case 4 后调用总价查询方法dailyIncome()
case 4:
// 调用查询总收入方法:遍历流水集合累加金额
dailyIncome();
break;
* (3): 在打印小票和退出时,需要将数据重置,否则会出现重复打印的现象
case 2:
// 结账,打印购物小票:票头(死数据打印) 票体(购买的水果项数据打印) 票脚(打折后打印所有汇总数据)
printReceipt();
// 结账后重置数据
resetNumber();
break;
* b: 案例代码
// 展示流水方法
public static void showFlow() {
// 如果没有开张,就提示没开张
if (flowData.size() == 0) {
System.out.println("sry!今天没开张!");
}
// 流水集合遍历
for (int i = 0; i < flowData.size(); i++) {
Double thisData = flowData.get(i);
System.out.println("第" + (i + 1) + "比交易:" + thisData);
}
}
// 总价查询
public static void dailyIncome() {
// 如果没有开张,就提示没开张
if (flowData.size() == 0) {
System.out.println("sry!今天没开张!");
}
// 定义变量,用于记录当前总收入
double sum = 0;
// 流水集合遍历
for (int i = 0; i < flowData.size(); i++) {
sum += flowData.get(i);
}
// 打印总收入
System.out.println("当前的总收入为:" + sum);
}
// 重置数据
public static void resetNumber() {
// 遍历集合,将所有元素的数量和金额置为0
for (int i = 0; i < list.size(); i++) {
FruitItem thisItem = list.get(i);
thisItem.number = 0;
thisItem.money = 0;
}
}
13添加水果项代码实现
* A: 添加水果项代码实现
* a: 分析
* 添加商品,就是向集合中添加新的元素
* 在switch语句的case 5 后调用添加商品的方法addFruitItem()
case 5:
// 调用添加商品方法:向集合中添加新的元素
addFruitItem();
break;
* b: 案例代码
// 添加水果
public static void addFruitItem() {
// 创建新添加的水果项对象
System.out.println("请输入您要添加的水果编号:");
int ID = enterNumber();
// 判断是否有已经存在的该编号水果
// 遍历集合,依次获取集合中每一个水果项对象
for (int i = 0; i < list.size(); i++) {
FruitItem thisItem = list.get(i);
// 获取当前水果项ID,直接与用户新添加的ID比较
if (thisItem.ID == ID) {
// 提示用户,出现重复编号
System.out.println("sry!已经存在这样的编号了!添加失败!");
// 结束添加动作
return;
}
}
// 如果整个循环都没有因为相同编号而方法结束,就说明没有这个编号的水果,可以添加这个水果
FruitItem newItem = new FruitItem();
newItem.ID = ID;
// 让用户接着输入编号后边的属性值
System.out.println("请输入商品名称:");
newItem.name = enterString();
System.out.println("请输入商品单价:");
newItem.price = enterDouble();
System.out.println("请输入商品计价单位:");
newItem.unit = enterString();
// 将新的水果项添加到集合中
list.add(newItem);
}
14删除水果项代码实现
* A: 删除水果项代码实现
* a: 分析
* 从集合中删除水果
* 在switch语句的case 6 后调用删除商品的方法delFruitItem()
case 6:
// 调用删除商品方法:从集合中删除元素
delFruitItem();
break;
* 案例代码
// 删除元素
public static void delFruitItem() {
System.out.println("请输入您要删除的水果编号:");
int ID = enterNumber();
// 判断是否有已经存在的该编号水果
// 遍历集合,依次获取集合中每一个水果项对象
for (int i = 0; i < list.size(); i++) {
FruitItem thisItem = list.get(i);
// 获取当前水果项ID,直接与用户要删除的ID比较
if (thisItem.ID == ID) {
// 从集合中删除该水果
list.remove(i);
// 提示用户删除成功
System.out.println("您指定编号的水果项已经删除!");
// 删除后,结束方法
return;
}
}
// 如果没有一个水果项匹配编号,说明用户输入了没有的编号,提示用户
System.out.println("您输入的编号有误,删除失败!");
}
15修改水果项代码实现
* A: 修改水果项代码实现
* a: 分析
* 从集合中获取该编号对应的水果,进行修改
* 在switch语句的case 7 后调用修改商品的方法updateFruitItem()
* b: 案例代码
// 修改方法
public static void updateFruitItem() {
System.out.println("请输入您要修改的水果编号:");
int ID = enterNumber();
// 判断是否有已经存在的该编号水果
// 遍历集合,依次获取集合中每一个水果项对象
for (int i = 0; i < list.size(); i++) {
FruitItem thisItem = list.get(i);
// 获取当前水果项ID,直接与用户要删除的ID比较
if (thisItem.ID == ID) {
// 让用户接着输入编号后边的属性值,修改当前对象的属性值
System.out.println("请输入商品名称:");
thisItem.name = enterString();
System.out.println("请输入商品单价:");
thisItem.price = enterDouble();
System.out.println("请输入商品计价单位:");
thisItem.unit = enterString();
// 提示修改成功
System.out.println("");
System.out.println("修改成功!");
System.out.println("");
return;
}
}
// 如果没有一个水果项匹配编号,说明用户输入了没有的编号,提示用户
System.out.println("您输入的编号有误,修改失败!");
}