今天给大家一个比较综合的项目:嗖嗖移动业务大厅。项目功能很多,概括的功能也很全面。吃透了这个项目,你的java基础部分已经非常棒了!!!


一 、 项目概述

  技能要求

   使用面向对象设计的思想
   合理运用异常处理
   使用集合框架存储数据,不使用数据库
   使用 I/O 操作实现对文件的读写


  开发工具

  JDK 7.0、MyEclipse。


  需求概述

  移动、联通、电信是国内三大通信运营商,每个运营商提供了不同的品牌套餐来应对不同的用户群,例如北京移动,主要有全球通、神州行、动感地带三大品牌套餐,每种套餐的内容和资费不同。现嗖嗖移动是一拟定的通信运营商,提供了话唠套餐、网虫套餐、超人套餐,各种套餐所包含的服务内容及资费如表 1 所示。

  如实际使用中,超出套餐内包含的通话时长、短信条数或上网流量时,按以下规则计费:

   超出的通话:0.2 元/分钟
   超出的短信:0.1 元/分钟
   超出的上网流量:0.1 元/MB
  本项目嗖嗖移动业务大厅提供了嗖嗖移动用户的日常常用功能,包括新用户注册、本月账单查询、套餐余量查询、打印消费详单、套餐变更、办理退网、话费充值、查看消费记录、查看资费说明功能,另外,还可以模拟用户通话、上网、发短信的场景进行相应的扣费并记录消费信息。各功能介绍如表 2 所示。

 二 、 项目业务流程描述

1.整体业务流程

嗖嗖移动项目的各个功能实际都是挂在功能菜单上的,其中主菜单包含 6 个功能,当用户输入 1~5 之间的功能编号后,验证卡号,如果该卡号已注册,执行相应功能后返回主菜单,否则,退出系统。如图 1 所示。

                                        图 1 主菜单

  当使用已注册用户登录并通过验证后,即显示二级菜单,包含 5 个功能,如图 2 所示。当输入 1~5 之外的功能编号时,返回主菜单。

                                         图 2 二级菜单

2. 用户注册

该功能可以看作是去营业厅办理新卡的过程。主要分成以下几个步骤:
1) 选择卡号(从随机生成的 9 个以“139”开头的卡号中选择一个,输入序号即可)。
2) 选择套餐(共 3 类套餐,选择其中一个,输入所对应的序号即可)。
3) 输入用户名、密码信息(相当于现在各营业厅的实名登录,输入用户名和密码即可)。
4) 输入预存话费金额:这里需保存预存的金额足以支付一个月的套餐费用,否则给出信息提示“您预存的话费金额不足以支付本月固定套餐资费,请重新充值!”。

5) 注册新卡
实现效果如图 3 所示。

                                        图 3 用户注册

3. 本月账单查询

本月账单可以显示以下信息:
 卡号。
 套餐月资费。
 合计(是套餐固定资费和超出套餐使用费用总和)。
 账户余额。
运行效果如图 4 所示。

                                      图 4 本月账单查询

4. 套餐余量查询

本功能用来显示该卡所属套餐内所剩余的免费通话时长、短信条数、上网流量,不同品牌套餐所支持的服务不同,因此显示的内容不同。运行效果如图 5 所示。

                                        图 5 套餐余量查询

5. 添加和打印消费清单

实现向消费记录中添加一条该卡的消费记录(该功能可在使用嗖嗖功能中调用),并实现打印该卡的消费记录,打印前先从消费记录中查找是否存在此卡的消费记录,如存在则提示“已添加一条消费记录。”,将消费记录输出到文本文件中,格式如图 5 所示。如不存在,提示用户相应信息,如图 6 所示。

                                      图 5 消费记录

                                    图 6 该卡不存在消费记录

6.使用嗖嗖

(1)随机进入某个场景

模拟嗖嗖用户使用卡的过程。选择该功能后,输入当前卡号,通过验证后,可随机进入表 3 所示的 6 个场景(当然还可以再设计其他场景),要求所进入的场景的服务类型是该卡所属套餐所支持的(例如网虫套餐只能进入服务类型为“上网”的场景)。

(2)模拟消费
进入该场景这之后,将按场景的描述要求消耗套餐余量,如套餐余量不足,需按套餐外的资费规则扣费,成功消费后,添加一条消费记录。效果如图 7 所示。

                                       图 7 使用嗖嗖成功

余额不足时,提示信息。如本场景通话时长为 30 分钟,当通话至 10 分钟时余额不足,抛出异常,并提示用户“本次已通话 10 分钟,您的余额不足,请充值后再使用!”如图 8所示

                                       图 8 余额不足的情况

(3)消费结束,添加消费记录
消费完毕,在消费列表中添加一条消费记录。并提示用户“已添加一条消费记录!”。按实际消费添加消费记录,除非没有消费。如图 8 的情况,则此条消费记录只需记录实际通话时长 10 分钟。

7. 办理退网
本功能可实现将当前卡用户从已注册用户列表中删除,删除后直接退出系统。运行效果如图 9 所示。

                                      图 9 办理退网

8. 套餐变更
本功能类似我们去营业厅变量套餐,可以充分体会到使用面向对象后,代码更加灵活,可维护性更强。
本项目中没有引入对日期的记录和处理,因此,这里默认套餐变更时间为本月的开始,选择变量后的套餐为当前套餐之外的其他类型,否则显示信息提示。如图 10 所示。

                                       图 10 选择套餐错误

选择套餐正确之后,还需判断当前余额是否足以支付一个月的套餐资费,如不足,提示错误信息。如图 11 所示。

                                      图 11 变更套餐余额不足

如上述两个条件都满足时,套餐变量成功,显示相应信息,如图 12 所示。当前卡实际使用数据清零,当前卡所属套餐修改为变量后的套餐类型,当前卡余额减去新套餐月资费,本月消费金额修改为新套餐月资费。

                                         图 12 套餐变更成功

9. 话费充值
可为指定卡号充值,要求充值金额最少 50 元。充值成功后提示信息。运行效果如图 13所示。

                                         图 13 充值成功

通过最少充值金额验证后,修改当前卡余额即可。

10. 查看资费说明
此功能需实现将文本文件(套餐资费说明.txt)中的信息显示到控制台。本功能需使用 I/O 操作实现文本文件的写入。


  以上是嗖嗖项目的整体需求概述,下面介绍如何搭建嗖嗖项目的框架结构:

一、 实体类(Entity)

 二、工具类 (utils)


  下面是项目的整体代码结构:

 实体类中的其中一个手机卡类:

  1 package cn.soso.entity;
2 /**
3 * 手机卡
4 *
5 */
6 public class MobileCard {
7 private String cardNumber; //卡号
8 private String userName; //用户名
9 private String passWord; //密码
10 private ServicePackage serPackage; //所属套餐
11 private double consumAmount; //当月消费金额
12 private double money; //账户余额
13 private int realTalkTime; //实际通话时长(分钟)
14 private int realSMSCount; //实际发送短信条数(条)
15 private int realFlow; //实际上网流量
16
17 public MobileCard(){}
18
19 public MobileCard(String userName, String passWord, String cardNumber,
20 ServicePackage serPackage, double consumAmount, double money) {
21 super();
22 this.userName = userName;
23 this.passWord = passWord;
24 this.cardNumber = cardNumber;
25 this.serPackage = serPackage;
26 this.consumAmount = consumAmount;
27 this.money = money;
28 }
29
30 public String getUserName() {
31 return userName;
32 }
33
34 public void setUserName(String userName) {
35 this.userName = userName;
36 }
37
38 public String getPassWord() {
39 return passWord;
40 }
41
42 public void setPassWord(String passWord) {
43 this.passWord = passWord;
44 }
45
46 public String getCardNumber() {
47 return cardNumber;
48 }
49
50 public void setCardNumber(String cardNumber) {
51 this.cardNumber = cardNumber;
52 }
53
54 public ServicePackage getSerPackage() {
55 return serPackage;
56 }
57
58 public void setSerPackage(ServicePackage serPackage) {
59 this.serPackage = serPackage;
60 }
61
62 public double getConsumAmount() {
63 return consumAmount;
64 }
65
66 public void setConsumAmount(double consumAmount) {
67 this.consumAmount = consumAmount;
68 }
69
70 public double getMoney() {
71 return money;
72 }
73
74 public void setMoney(double money) {
75 this.money = money;
76 }
77
78 public int getRealTalkTime() {
79 return realTalkTime;
80 }
81
82 public void setRealTalkTime(int realTalkTime) {
83 this.realTalkTime = realTalkTime;
84 }
85
86 public int getRealSMSCount() {
87 return realSMSCount;
88 }
89
90 public void setRealSMSCount(int realSMSCount) {
91 this.realSMSCount = realSMSCount;
92 }
93
94 public int getRealFlow() {
95 return realFlow;
96 }
97
98 public void setRealFlow(int realFlow) {
99 this.realFlow = realFlow;
100 }
101
102 /**
103 * 显示卡信息
104 */
105 public void showMeg(){
106 System.out.println("卡号:"+this.cardNumber+" 用户名:"+this.userName+" 当前余额:"+this.money+"元。");
107 this.serPackage.showInfo();
108 }
109 }

 整体业务流程类:

  1 package cn.soso.biz;
2
3 import java.util.Scanner;
4
5 import cn.soso.common.Common;
6 import cn.soso.entity.MobileCard;
7 import cn.soso.entity.ServicePackage;
8 import cn.soso.utils.CardUtil;
9
10 /**
11 * 业务类
12 *
13 *
14 */
15 public class SosoMgr {
16 Scanner input = new Scanner(System.in);
17 CardUtil utils = new CardUtil();
18
19 public static void main(String[] args) {
20 SosoMgr soso = new SosoMgr();
21 soso.mainMenu();
22 System.out.println("谢谢使用!");
23 }
24
25 /**
26 * 主流程
27 */
28 public void mainMenu() {
29 int menuChoose = 0;
30 String mobileNumber= "";
31 String password = "";
32 utils.init();
33 utils.initScenes();
34 //Common.typesInit();
35 do {
36 System.out.println("\n*************欢迎使用嗖嗖移动业务大厅***************");
37 System.out.println("1.用户登录 2.用户注册 3.使用嗖嗖 4.话费充值 5.资费说明 6.退出系统");
38 System.out.print("请选择:");
39 menuChoose = input.nextInt();
40 // 分支语句:根据功能编号执行相应功能
41 switch (menuChoose) {
42 case 1:
43 //用户登录
44 System.out.print("请输入手机卡号:");
45 mobileNumber = input.next();
46 System.out.print("请输入密码:");
47 password = input.next();
48 if (utils.isExistCard(mobileNumber, password)) {
49 cardMenu(mobileNumber);
50 }else{
51 System.out.println("对不起,您输入的信息有误,无法登录!");
52 }
53 continue;
54 case 2:
55 //用户注册
56 registCard();
57 continue;
58 case 3:
59
60 //使用嗖嗖
61 System.out.print("请输入手机卡号:");
62 mobileNumber = input.next();
63
64 if (utils.isExistCard(mobileNumber)) {
65 try {
66 /* System.out.println("****使用之前****");
67 utils.showRemainDetail(mobileNumber);
68 utils.showAmountDetail(mobileNumber);*/
69 utils.userSoso(mobileNumber);
70 } catch (Exception e) {
71 System.err.println(e.getMessage());
72 }
73 }else{
74 System.out.println("对不起,该卡号未注册,不能使用!");
75 }
76
77 /*System.out.println("****使用之后****");
78 utils.showRemainDetail(mobileNumber);
79 utils.showAmountDetail(mobileNumber);*/
80 continue;
81 case 4:
82 //话费充值
83 System.out.print("请输入充值卡号:");
84 mobileNumber = input.next();
85 if (utils.isExistCard(mobileNumber)) {
86 System.out.print("请输入充值金额:");
87 double money = input.nextDouble();
88 utils.chargeMoney(mobileNumber, money);
89 }else{
90 System.out.println("对不起,要充值的卡号未注册,无法充值!");
91 }
92 continue;
93 case 5:
94 System.out.println("\n*****资费说明******");
95 utils.showDescription();
96 continue;
97 case 6:
98 //退出系统
99 break;
100 default:
101 //选择其他数字退出系统
102 break;
103 }
104 break;
105 } while (true);
106 }
107
108 /**
109 * 手机卡功能菜单
110 *
111 * @param number
112 * @return
113 */
114 public int cardMenu(String mobileNumber) {
115 int menuChoose = 0;
116 do {
117 System.out.println("\n*****嗖嗖移动用户菜单*****");
118 System.out.println("1.本月账单查询");
119 System.out.println("2.套餐余量查询");
120 System.out.println("3.打印消费详单");
121 System.out.println("4.套餐变更");
122 System.out.println("5.办理退网");
123 System.out.print("请选择(输入1~5选择功能,其他键返回上一级):");
124 menuChoose = input.nextInt();
125 switch (menuChoose) {
126 case 1:
127 System.out.println("\n*****本月账单查询******");
128 utils.showAmountDetail(mobileNumber);
129 continue;
130 case 2:
131 System.out.println("\n*****套餐余量查询******");
132 utils.showRemainDetail(mobileNumber);
133 continue;
134 case 3:
135 System.out.println("\n*****消费详单查询******");
136 utils.printConsumInfo(mobileNumber);
137 continue;
138 case 4:
139 System.out.println("\n*****套餐变更******");
140 System.out.print("1.话唠套餐 2.网虫套餐 3.超人套餐 请选择(序号):");
141 utils.changingPack(mobileNumber, input.next());
142 continue;
143 case 5:
144 System.out.println("\n*****办理退网******");
145 utils.delCard(mobileNumber);
146 System.out.println("谢谢使用!");
147 System.exit(1); //办理退网后退出系统
148
149 }
150
151 break;
152 } while (true);
153 return menuChoose;
154 }
155
156 /**
157 * 注册新卡流程
158 */
159 public void registCard(){
160 String[] newNumbers = utils.getNewNumbers(9);
161 //显示可供选择的手机号列表
162 System.out.println("*****可选择的卡号*****");
163
164 for(int i=0;i<9;i++){
165 System.out.print((i+1)+"."+newNumbers[i]+"\t\t");
166 if((i+1)%3==0){
167 System.out.println();
168 }
169 }
170 //选择手机号
171 System.out.print("请选择卡号(输入1~9的序号):");
172 String number = newNumbers[input.nextInt()-1];
173
174 //选择套餐类型
175 System.out.print("1.话唠套餐 2.网虫套餐 3.超人套餐, ");
176 System.out.print("请选择套餐(输入序号):");
177 //utils.getPackList();
178 //获取套餐对象
179 ServicePackage pack = utils.createPack(input.nextInt());
180
181 //输入用户名
182 System.out.print("请输入姓名:");
183 String name = input.next();
184
185 //输入密码
186 System.out.print("请输入密码:");
187 String password = input.next();
188
189 //输入预存话费金额
190 double money = 0;
191 System.out.print("请输入预存话费金额:");
192 money = input.nextDouble();
193 while(money<pack.getPrice()){
194 System.out.print("您预存的话费金额不足以支付本月固定套餐资费,请重新充值:");
195 money = input.nextDouble();
196 }
197
198 //创建新卡对象并添加
199 MobileCard newCard = new MobileCard(name,password,number,pack,pack.getPrice(),money-pack.getPrice());
200 utils.addCard(newCard);
201 }
202 }

 手机卡工具类:

  1 package cn.soso.utils;
2
3 import java.io.FileReader;
4 import java.io.FileWriter;
5 import java.io.IOException;
6 import java.io.Reader;
7 import java.io.Writer;
8 import java.text.DecimalFormat;
9 import java.util.ArrayList;
10 import java.util.HashMap;
11 import java.util.Iterator;
12 import java.util.List;
13 import java.util.Map;
14 import java.util.Random;
15 import java.util.Set;
16
17 import cn.soso.common.Common;
18 import cn.soso.entity.ConsumInfo;
19 import cn.soso.entity.MobileCard;
20 import cn.soso.entity.NetPackage;
21 import cn.soso.entity.Scene;
22 import cn.soso.entity.ServicePackage;
23 import cn.soso.entity.SuperPackage;
24 import cn.soso.entity.TalkPackage;
25 import cn.soso.service.CallService;
26 import cn.soso.service.NetService;
27 import cn.soso.service.SendService;
28
29 /**
30 * 手机卡工具类
31 *
32 *
33 */
34 public class CardUtil {
35 Map<String, MobileCard> cards = new HashMap<String, MobileCard>(); // 所有手机卡的列表
36 Map<String, List<ConsumInfo>> consumInfos = new HashMap<String, List<ConsumInfo>>(); // 所有手机卡消费记录的列表
37 List<Scene> scenes = new ArrayList<Scene>();
38
39 // 初始化用户
40 public void init() {
41 MobileCard card1 = new MobileCard("何玲玲", "123", "13965756432",
42 new TalkPackage(), 58.0, 42.0);
43 MobileCard card2 = new MobileCard("黄露露", "123", "13956712467",
44 new NetPackage(), 68.0, 32.0);
45 MobileCard card3 = new MobileCard("朱蓉蓉", "123", "13911568956",
46 new SuperPackage(), 78.0, 22.0);
47 MobileCard card4 = new MobileCard("桃跑跑", "123", "13924221868",
48 new TalkPackage(), 78.0, 2.0);
49 card4.setConsumAmount(98.0);
50 card4.setRealTalkTime(500);
51 card4.setRealSMSCount(100);
52 cards.put("13965756432", card1);
53 cards.put("13956712467", card2);
54 cards.put("13911568956", card3);
55 cards.put("13924221868", card4);
56 }
57
58 /**
59 * 使用场景初始化
60 */
61 public void initScenes(){
62 scenes.add(new Scene("通话",90,"问候客户,谁知其如此难缠 通话90分钟"));
63 scenes.add(new Scene("通话",30,"询问妈妈身体状况 本地通话30分钟"));
64 scenes.add(new Scene("短信",5,"参与环境保护实施方案问卷调查 发送短信5条"));
65 scenes.add(new Scene("短信",50,"通知朋友手机换号,发送短信50条"));
66 scenes.add(new Scene("上网",1*1024,"和女友微信视频聊天 使用流量1G"));
67 scenes.add(new Scene("上网",2*1024,"晚上手机在线看韩剧,不留神睡着啦! 使用流量 2G"));
68 }
69
70 /**
71 * 是否存在此卡用户
72
73 *
74 * @param number
75 * @param passWord
76 * @return
77 */
78 public boolean isExistCard(String number, String passWord) {
79 Set<String> numbers = cards.keySet();
80 Iterator<String> it = numbers.iterator();
81 while (it.hasNext()) {
82 String searchNum = it.next();
83 if (searchNum.equals(number)
84 && (cards.get(searchNum)).getPassWord().equals(passWord)) {
85 return true;
86 }
87 }
88 return false;
89 }
90
91 /**
92 * 查找指定卡号是否已注册
93 *
94 * @param searchNumber
95 * @return 未注册:false 已注册:true
96 */
97 public boolean isExistCard(String searchNumber) {
98 Set<String> numbers = cards.keySet();
99 for (String number : numbers) {
100 if (number.equals(searchNumber)) {
101 return true;
102 }
103 }
104 return false;
105 }
106
107 /**
108 * 创建卡号(以139开头 11位)
109 *
110 * @return 生成的随机手机卡号
111 */
112 public String createNumber() {
113 Random random = new Random();
114 boolean isExist = false; // 记录现有用户中是否存在此卡号用户 是:true 否:false
115 String number = "";
116 int temp = 0;
117 do {
118 isExist = false; // 标志位重置为false,用于控制外重循环,当生成了
119 // 生成的随机数是8位 不能小于10000000,否则重新生成
120 do {
121 temp = random.nextInt(100000000);
122 } while (temp < 10000000);
123 // 生成之前,前面加“139”
124 number = "139" + temp;
125 // 和现有用户的卡号比较,不能是重复
126 Set<String> cardNumbers = cards.keySet();
127 for (String cardNumber : cardNumbers) {
128 if (number.equals(cardNumber)) {
129 isExist = true;
130 break;
131 }
132 }
133 } while (isExist);
134 return number;
135 }
136
137 /**
138 * 生成指定个数的新卡号列表
139 *
140 * @param count
141 * 指定个数
142 * @return 卡号列表
143 */
144 public String[] getNewNumbers(int count) {
145
146 String[] numbers = new String[count];
147 for (int i = 0; i < count; i++) {
148 numbers[i] = createNumber();
149 }
150 return numbers;
151 }
152
153 /**
154 * 添加新卡
155 *
156 * @param card
157 * 新卡
158 */
159 public void addCard(MobileCard card) {
160 cards.put(card.getCardNumber(), card);
161 System.out.print("注册成功!");
162 card.showMeg();
163 }
164
165 /**
166 * 指定卡号办理退网
167 *
168 * @param card
169 */
170 public void delCard(String delNumber) {
171 if (isExistCard(delNumber)) {
172 cards.remove(delNumber);
173 System.out.println("卡号" + delNumber + "办理退网成功!");
174 } else {
175 System.out.println("对不起,该卡号未注册,不能办退退网!");
176 }
177 }
178
179 /**
180 * 查询指定卡套餐余量
181 *
182 * @param number
183 */
184 public void showRemainDetail(String searchNumber) {
185 MobileCard card; // 要查询的卡
186 int remainTalkTime;
187 int remainSmsCount;
188 int remainFlow;
189 StringBuffer meg = new StringBuffer();
190 card = cards.get(searchNumber);
191 meg.append("您的卡号是" + searchNumber + ",套餐内剩余:\n");
192 ServicePackage pack = card.getSerPackage();
193 if (pack instanceof TalkPackage) {
194 //向下转型为话唠套餐对象
195 TalkPackage cardPack = (TalkPackage) pack;
196 // 话唠套餐,查询套餐内剩余的通话时长和短信条数
197 remainTalkTime = cardPack.getTalkTime() > card
198 .getRealTalkTime() ? cardPack.getTalkTime()
199 - card.getRealTalkTime() : 0;
200 meg.append("通话时长:" + remainTalkTime + "分钟\n");
201 remainSmsCount = cardPack.getSmsCount() > card
202 .getRealSMSCount() ? cardPack.getSmsCount()
203 - card.getRealSMSCount() : 0;
204 meg.append("短信条数:" + remainSmsCount + "条");
205 } else if (pack instanceof NetPackage) {
206 //向下转型为网虫套餐对象
207 NetPackage cardPack = (NetPackage) pack;
208 // 网虫套餐:查询套餐内剩余的上网流量
209 remainFlow = cardPack.getFlow() > card.getRealFlow() ? cardPack
210 .getFlow() - card.getRealFlow() : 0;
211 meg.append("上网流量:" + Common.dataFormat(remainFlow * 1.0 / 1024)
212 + "GB");
213 } else if (pack instanceof SuperPackage) {
214 //向下转型为超人套餐对象
215 SuperPackage cardPack = (SuperPackage) pack;
216 // 超人套餐:查询套餐内剩余的通话时长、短信条数、上网流量
217 remainTalkTime = cardPack.getTalkTime() > card
218 .getRealTalkTime() ? cardPack.getTalkTime()
219 - card.getRealTalkTime() : 0;
220 meg.append("通话时长:" + remainTalkTime + "分钟\n");
221 remainSmsCount = cardPack.getSmsCount() > card
222 .getRealSMSCount() ? cardPack.getSmsCount()
223 - card.getRealSMSCount() : 0;
224 meg.append("短信条数:" + remainSmsCount + "条\n");
225 remainFlow = cardPack.getFlow() > card.getRealFlow() ? cardPack
226 .getFlow() - card.getRealFlow() : 0;
227 meg.append("上网流量:" + Common.dataFormat(remainFlow * 1.0 / 1024)
228 + "GB");
229 }
230 System.out.println(meg);
231 }
232
233 /**
234 * 查询指定卡当月消费详单
235 *
236 * @param searchNumber
237 */
238 public void showAmountDetail(String searchNumber) {
239 MobileCard card; // 要查询的卡
240 StringBuffer meg = new StringBuffer();
241 card = cards.get(searchNumber);
242 meg.append("您的卡号:" + card.getCardNumber() + ",当月账单:\n");
243 meg.append("套餐资费:" + card.getSerPackage().getPrice() + "元\n");
244 meg.append("合计:" + Common.dataFormat(card.getConsumAmount()) + "元\n");
245 meg.append("账户余额:" + Common.dataFormat(card.getMoney()) + "元");
246 // 显示本月消费详细信息
247 System.out.println(meg);
248 }
249
250
251 /**
252 * 指定卡号换套餐
253 *
254 * @param number
255 * @param packType
256 */
257 public void changingPack(String number, String packNum) {
258 MobileCard card; // 指定的手机卡
259 ServicePackage pack; // 要换的套餐
260 if (isExistCard(number)) {
261 card = cards.get(number);
262 // 获取要换的套餐对象
263 switch (packNum) {
264 case "1":
265 pack = new TalkPackage();
266 break;
267 case "2":
268 pack = new NetPackage();
269 break;
270 default:
271 pack = new SuperPackage();
272 break;
273 }
274 if (!(card.getSerPackage().getClass().getName().equals(pack.getClass().getName()))) {
275 // 该卡余额中减去当月套餐资费
276 if (card.getMoney() >= pack.getPrice()) {
277 card.setMoney(card.getMoney() - pack.getPrice());
278 // 换套餐
279 card.setSerPackage(pack);
280 // 当月实际使用数据清零
281 card.setRealTalkTime(0);
282 card.setRealFlow(0);
283 card.setRealSMSCount(0);
284 // 当月消费金额设置为新套餐月资费
285 card.setConsumAmount(pack.getPrice());
286 System.out.print("更换套餐成功!");
287 pack.showInfo();
288 } else {
289 System.out.println("对不起,您的余额不足以支付新套餐本月资费,请充值后再办理更换套餐业务!");
290 return;
291 }
292 } else {
293 System.out.println("对不起,您已经是该套餐用户,无需换套餐!");
294 }
295
296 } else {
297 System.out.println("对不起,该卡号未注册,不能换套餐!");
298 }
299 }
300
301 /**
302 * 为指定手机卡充值
303 *
304 * @param number
305 * 指定充值的卡号
306 * @param money
307 * 充值金额
308 */
309 public void chargeMoney(String number, double money) {
310 MobileCard card; // 指定的手机卡
311 if (money < 50) {
312 System.out.println("对不起,最低充值金额为50元!");
313 return;
314 }
315 card = cards.get(number);
316 card.setMoney(card.getMoney() + money);
317 System.out.println("充值成功,当前话费余额为" + Common.dataFormat(card.getMoney()) + "元。");
318 }
319
320 /**
321 * 添加一条指定卡的消费记录
322 *
323 * @param number
324 * 要添加消费记录的卡
325 * @param info
326 * 要添加的消费记录
327 */
328 public void addConsumInfo(String number, ConsumInfo info) {
329 Set<String> numbers = consumInfos.keySet();
330 Iterator<String> it = numbers.iterator();
331 List<ConsumInfo> infos = new ArrayList<ConsumInfo>();
332 boolean isExist = false; // 现有消费列表中是否存在此卡号消费记录,是:true 否:false
333 while (it.hasNext()) {
334 if (it.next().equals(number)) {
335 // 消费集合中已有该卡号消费记录,则找到该卡号的消费记录集合,添加一条即可
336 infos = consumInfos.get(number);
337 infos.add(info);
338 isExist = true;
339 System.out.println("已添加一条消费记录。");
340 break;
341 }
342 }
343 // 该集合中没有此卡号消费记录,则添加
344 if (!isExist) {
345 infos.add(info);
346 consumInfos.put(number, infos);
347 System.out.println("不存在此卡的消费记录,已添加一条消费记录。");
348 }
349 }
350
351 //打印消费记录
352 public void printConsumInfo(String number){
353 Writer fileWriter = null;
354 try {
355 fileWriter = new FileWriter(number+"消费记录.txt");
356 Set<String> numbers = consumInfos.keySet();
357 Iterator<String> it = numbers.iterator();
358 List<ConsumInfo> infos = new ArrayList<ConsumInfo>();//存储指定卡所有消费记录
359 boolean isExist = false; // 现有消费列表中是否存在此卡号消费记录,是:true 否:false
360 while (it.hasNext()) {
361 if (it.next().equals(number)) {
362 infos = consumInfos.get(number);
363 isExist = true;
364 break;
365 }
366 }
367 if(isExist){
368 //存在 此卡消费记录,写入文本文件
369 StringBuffer content = new StringBuffer("******"+number+"消费记录******\n");
370 content.append("序号\t类型\t数据(通话(条)/上网(MB)/短信(条))\n");
371 for(int i=0;i<infos.size();i++){
372 ConsumInfo info = infos.get(i);
373 content.append((i+1)+".\t"+info.getType()+"\t"+info.getConsumData()+"\n");
374 }
375 fileWriter.write(content.toString());
376 fileWriter.flush();
377
378 System.out.println("消费记录打印完毕!");
379 }else{
380 System.out.println("对不起,不存在此号码的消费记录,不能打印!");
381 }
382 } catch (IOException e) {
383 e.printStackTrace();
384 }finally{
385 if(fileWriter!=null){
386 try {
387 fileWriter.close();
388 } catch (IOException e) {
389 e.printStackTrace();
390 }
391 }
392 }
393 }
394
395 /**
396 * 使用嗖嗖
397 * @param number 当前卡号
398 * @throws Exception
399 */
400 public void userSoso(String number) {
401 MobileCard card = cards.get(number); // 获取此卡对象
402 ServicePackage pack = card.getSerPackage(); // 获取此卡所属套餐
403 Random random = new Random();
404 int ranNum = 0;
405 int temp = 0; //记录各场景中实际消费数据
406 do{
407
408 ranNum = random.nextInt(6);// 生成一个0~5之前的随机数
409 Scene scene = scenes.get(ranNum); //获取该序号所对应的场景
410 switch (ranNum) {
411 //序号为0或1为通话场景
412 case 0:
413 case 1:
414 // 判断该卡所属套餐是否支持通话功能
415 if (pack instanceof CallService) {
416 // 执行通话方法
417 System.out.println(scene.getDescription());
418 CallService callService = (CallService) pack;
419 try {
420 temp = callService.call(scene.getData(), card);
421 } catch (Exception e) {
422 e.printStackTrace();
423 }
424 // 添加一条消费记录
425 addConsumInfo(number, new ConsumInfo(number,
426 scene.getType(), temp));
427 break;
428 } else {
429 // 如果该卡套餐不支持通话功能,则重新生成随机数选择其他场景
430 continue;
431 }
432 //序号为2或3为发短信场景
433 case 2:
434 case 3:
435 // 判断该卡所属套餐是否支持短信功能
436 if (pack instanceof SendService) {
437 // 执行发短信方法
438 System.out.println(scene.getDescription());
439 SendService sendService = (SendService) pack;
440 try {
441 temp = sendService.sendMessage(scene.getData(), card);
442 } catch (Exception e) {
443 e.printStackTrace();
444 }
445 // 添加一条消费记录
446 addConsumInfo(number, new ConsumInfo(number,
447 scene.getType(), temp));
448 break;
449 } else {
450 // 如果该卡套餐不支持发短信功能,则重新生成随机数选择其他场景
451 continue;
452 }
453 //序号为4或5为发上网场景
454 case 4:
455 case 5:
456 // 判断该卡所属套餐是否支持上网功能
457 if (pack instanceof NetService) {
458 System.out.println(scene.getDescription());
459 NetService netService = (NetService) pack;
460 // 执行上网方法
461 try {
462 temp = netService.netPlay(scene.getData(), card);
463 } catch (Exception e) {
464 e.printStackTrace();
465 }
466 // 添加一条消费记录
467 addConsumInfo(number, new ConsumInfo(number,
468 scene.getType(), temp));
469 break;
470 } else {
471 // 如果该卡套餐不支持上网功能,则重新生成随机数选择其他场景
472 continue;
473 }
474 }
475 break;
476 }while(true);
477 }
478
479 /**
480 * 根据套餐序号返回套餐对象
481 *
482 * @param packNum
483 * 套餐序号
484 * @return 套餐对象
485 */
486 public ServicePackage createPack(int packId) {
487 ServicePackage pack = null;
488 switch (packId) {
489 case 1:
490 pack = new TalkPackage();
491 break;
492 case 2:
493 pack = new NetPackage();
494 break;
495 case 3:
496 pack = new SuperPackage();
497 break;
498 }
499 return pack;
500 }
501
502 /**
503 * 显示资费说明
504 */
505 public void showDescription(){
506 Reader rd = null;
507 try {
508 rd = new FileReader("套餐资费说明.txt");
509 char[] content = new char[1024];
510 int len = 0;
511 StringBuffer sb = new StringBuffer();
512 while((len=rd.read(content))!=-1){
513 sb.append(content,0,len); //拼接字符串
514 }
515 System.out.println(sb);
516 } catch (IOException e) {
517 // TODO Auto-generated catch block
518 e.printStackTrace();
519 }
520 }
521
522 }

    各类各个接口的代码就不一一列举啦,有兴趣的朋友可以来+Q qun:609565759,喜欢前端、后端java开发的可以加+,有详细视频、资料、教程,文档!!!希望可以一起努力,加油ヾ(◍°∇°◍)ノ゙!!!

嗖嗖移动大厅 源代码 Java初级小项目的更多相关文章

  1. 迷你图书管理系统 源代码 Java初级小项目

    今天博主再给大家分享一个小项目:MiNi图书管理系统.用的是Java语言开发的,代码不多,大概260行左右吧,系统是实现图书的新增图书.删除图书.借阅图书.归还图书.查看图书等简单的功能(后附源代码) ...

  2. 吃货联盟订餐系统 源代码 Java初级小项目

    咳咳,今天博主给大家写一个小的项目:吃货联盟订餐系统.博主不是大神(互联网架构师的路上ing),也是小白一个,不过是刚入门的小白^_^.项目功能也很简单:只是模拟日常的订餐流程呦,所以有错误以及功能不 ...

  3. 小项目,吃货联盟,java初级小项目,源代码

    1:项目的实现效果.功能如图所示. 2:项目的源代码如下: import java.util.Scanner; /** * 吃货联盟订餐管理系统 * */ public class OrderingM ...

  4. 掷骰子游戏窗体实现--Java初级小项目

    掷骰子 **多线程&&观察者模式 题目要求:<掷骰子>窗体小游戏,在该游戏中,玩家初始拥有1000的金钱,每次输入押大还是押小,以及下注金额,随机3个骰子的点数,如果3个骰 ...

  5. java初学小项目-酒店客房管理系统

    最近初次接触JAVA,感觉之前学的C语言很有用,跟着视频做了一个小项目-酒店客房管理系统 /* 酒店客房管理系统 */ import java.util.Scanner;//通过键盘来输入命令需要的引 ...

  6. Java数据库小项目02--管家婆项目

    目录 项目要求 开发环境搭建 工具类JDBCUtils 创建管家婆数据表 项目分层 MainApp层 MainView层 ZhangWuController层 ZhangWuService层 Zhan ...

  7. java连连看小项目

    /* *本人也是刚入门,希望各位多多指教 *该项目主要代码在于连线 *1.2个连线没有拐弯 *2.2个连线有一个拐弯 *3.2个连线有2个拐弯 *采用递归算法 */ package llk; impo ...

  8. Java数据库小项目01--实现用户登录注册

    先实现数据库和数据表,检测正常后再做其他的 CREATE TABLE users( username ) NOT NULL, PASSWORD ) NOT NULL); INSERT INTO use ...

  9. Java数据库小项目00---基础知识

    目录 JDBC的简单使用 向JDBC注入攻击 防止注入攻击 自建JDBC工具类 自建工具类优化--使用配置文件 使用数据库连接池优化工具类 JDBC的简单使用 package Test; import ...

随机推荐

  1. Black-Lives-Matter-Resources

    下载 Black-Lives-Matter-ResourcesBlack-Lives-Matter-Resources 关于最近在美国发生的事件的资源列表 链接 描述 由于(可选) 插入链接 在这里插 ...

  2. CentOS7 执行 service iptables save 报错 The service command supports only basic LSB actions xxxxxx

    现象描述 在 CentOS 7.6.1810 下执行 service iptables save 命令,出现如下错误: [root@test ~]# service iptables save The ...

  3. vue点击切换样式,点击切换地址栏,点击显示或者隐藏

    1. vue点击显示切换 :class='{"span":index==0}' class原本是 类选择器 加上 :class就是绑定属性的意思 '{"span" ...

  4. 多测师讲解自动化测试 _RF关键字001_(上)_高级讲师肖sir

    讲解案例1: Open Browser http://www.baidu.com gc #打开浏览器 Maximize Browser Window #窗口最大化 sleep 2 #线程等待2秒 In ...

  5. CS61A Homework: Church Numerals

    Church Numerals Nagging 南大的 SICP 实际上是 Berkeley CS61A 的 clone ,所以我有幸做到了这个 Homework02. 此外要感谢选课系统,让我一个工 ...

  6. [论文阅读]阿里DIN深度兴趣网络之总体解读

    [论文阅读]阿里DIN深度兴趣网络之总体解读 目录 [论文阅读]阿里DIN深度兴趣网络之总体解读 0x00 摘要 0x01 论文概要 1.1 概括 1.2 文章信息 1.3 核心观点 1.4 名词解释 ...

  7. pytest文档49-命令行参数--tb的使用

    前言 pytest 使用命令行执行用例的时候,有些用例执行失败的时候,屏幕上会出现一大堆的报错内容,不方便快速查看是哪些用例失败. --tb=style 参数可以设置报错的时候回溯打印内容,可以设置参 ...

  8. spring-boot-route(十七)使用aop记录操作日志

    在上一章内容中--使用logback管理日志,我们详细讲述了如何将日志生成文件进行存储.但是在实际开发中,使用文件存储日志用来快速查询问题并不是最方便的,一个优秀系统除了日志文件还需要将操作日志进行持 ...

  9. 【UER #1】DZY Loves Graph

    UOJ小清新题表 题目内容 UOJ链接 DZY开始有\(n\)个点,现在他对这\(n\)个点进行了\(m\)次操作,对于第\(i\)个操作(从\(1\)开始编号)有可能的三种情况: Add a b: ...

  10. 【模拟】CF 796C Bank Hacking

    题目大意 洛谷链接 给定一棵带点权树,选出一个最佳的根节点,使得根节点的点权不变,它的儿子点权加1,其余点点权加2,并使最大点权最小,输出这个最小的最大点权. 其他见链接(懒). PS:原题面很不好总 ...