1.案例需求
中国移动,中国联通,中国电信是国内3大通信运营商,每个运营商都提供了不同的品牌套餐来应对不同的用户群,比如北京移动主要有全球通,神州行,动感地带等3大品牌套餐,每种套餐的内容和费用不同,嗖嗖移动是一个假定的通信运营商,提供了话痨套餐,网虫套餐,超人套餐,各种套餐所包含的服务内容及费用如下表:
品牌套餐 | 话痨套餐 | 网虫套餐 | 超人套餐 |
---|---|---|---|
通话时长(分钟) | 600 | 0 | 300 |
上网流量 | 0 | 20 | 10 |
短信条数(条) | 100 | 0 | 50 |
费用(元/月) | 58 | 68 | 78 |
如实际使用中超出套餐内包含的通话时长,短信条数和上网流量,则按一下规则计费:
- 超出的通话: 0.2元/分
- 超出的短信:0.1元/条
- 超出的上网流量:0.1元/MB
2.编程思路
- 用户登录:用户输入手机号码和密码,经检验后在数据库找到对应的手机号和号码且号码的状态为可用,则提示用户登录成功并进入二级菜单列表。若状态的为禁用,则提示用户该卡号已被禁用,若不存在该手机号码和密码,则提示用户卡号或者密码错误。
- 用户注册:用户选择用户注册功能,提供两种卡号类型分别是普通卡号(注册此类型账号不需要额外费用)以及靓号(注册此类型账号需加100元),根据用户的选择展示响应的可选号码供用户选择,用户选择心仪的卡号以及对应的套餐,录入信息并开卡,用户输入的信息包括:输入用户名,密码以及预存话费金额(预存话费金额必须满足以支付所选套餐的一个月的费用以及选择相应卡号所需的额外费用),当满足条件时,提示用户注册成功,并展示卡号的相关信息
- 使用嗖嗖:用户输入手机号,系统检测该手机号是否存在,若存在则输出该卡号套餐中的剩余量,然后将几种使用场景展示出来供用户选择,根据用户的选择进行相应的操作,如果用户选择场景的消耗量小于该套餐的剩余量则直接减就好,如果用户选择场景的消耗量大于该套餐的剩余量,则超出的部分按照标准扣除用户账号的余额,若余额<0时会提醒用户先去充值,然后才能使用该功能。若手机号不存在则提示用户该卡号不存在,请重新输入!
- 话费充值:用户输入手机号,系统检测该手机号是否存在,若存在则输入充值金额并提示用户充值后卡上的余额,若手机号不存在,则提示用户该卡号不存在,请重新输入!
- 资费说明:提供各品牌套餐所包含的通话时长,上网流量,短信条数,月费用等
- 退出系统:用户退出本系统
- 本月账单查询:查询该卡号的套餐费用,实际消费金额,账户余额
- 套餐余量查询:查询该卡号套餐中通话时长、短信条数以及上网流量的余量
- 打印消费详情:用户选择该功能后,需要输入需要查询的月份,若该月份存在消费记录,则打印当前卡号用户本月的消费详单, 并使用输出流把用户信息输出到文件,若不存在则提示用户本卡号该月不存在消费记录。
- 套餐变更:用户选择该功能后,系统展示所有的套餐类型供用户选择,若用户选择变更的类型与用户当前的套餐类型相同,则提示用户已经是改套餐的用户,无需更换!否则先检查用户当前的余额是否能支付变更套餐的费用,若不能则提示用户先进行充值,否则更换套餐成功并输出新套餐的详情,同时变更后卡号话费余额需减去变更后的套餐费用
- 办理退网:用户选择该功能后可以从已注册的号码列表中删除本号码,并退出系统
- 分页查询电话号码充值记录:用户选择该功能后,输入一页想展示的最多数据条数,系统根据用户输入的最多数据条数将该号码的充值记录按照降序的顺序展示给用户,并提供上一页和下一页的选择供用户选择,当为第一页时如果选择上一页会提示用户该页已经是第一页,并退出该功能回到二级菜单目录,最后一页也同理。
3.数据库设计
4.案例使用嗖嗖部分view层源码
private void useSoso() {
System.out.println("*************使用soso*************");
System.out.print("请输入手机卡号:");
String cardnumber = scanner.next();
//查询号码是否存在
int i1 = sosoService.queryRechargeCard(cardnumber);
while (i1 == 1) {
System.out.println("【友情提示】:该卡号不存在,请重新输入!");
System.out.print("请输入手机卡号:");
cardnumber = scanner.next();
i1 = sosoService.queryRechargeCard(cardnumber);
}
if (i1 == 2) {
System.out.println("【友情提示】:该卡号已被禁用");
showFirstMenu();
}
//查询套餐内的剩余余额
String s = sosoService.queryPackageBalance(cardnumber);
System.out.println(s);
//展示所有场景
System.out.println("*************使用场景展示*************");
List<Scene> scenes = sosoService.queryAllScene();
for (int i = 0; i < scenes.size(); i++) {
System.out.println((i + 1) + "." + scenes.get(i).getDescription());
}
System.out.print("请选择使用场景:");
int choose = scanner.nextInt();
//判断choose是否在有效范围内
while (choose <= 0 || choose > scenes.size()) {
System.out.println("【友情提示】:您的选择超出范围了哦,请重新输入!");
System.out.print("请选择使用场景:");
choose = scanner.nextInt();
}
List<Scene> scenes1 = sosoService.queryConsumDataById(choose);//获取id为choose的场景(只有一条)
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String date = dateFormat.format(new Date());
//插入消费记录向tb_consuminfo表中
sosoService.insertTbConsuminfo(cardnumber, scenes1.get(0).getType(), scenes1.get(0).getData(), date);
//查询某号码的一列信息
List<MoboleCard> moboleCards = sosoService.queryMoboleByCardnum(cardnumber);
if (moboleCards.get(0).getMoney() <= 0) {
System.out.println("【友情提示】:你的账号余额以不足,请尽快充值!否则你无法使用该功能");
showFirstMenu();
}
//查询套餐类型的详情
// List<Serpackage> serpackages = sosoService.querySerpackage(serid);
//查询月消费记录是否存在,存在就修改,不存在就添加新的
List<MonthlyConsumptionRecords> monthlyConsumptionRecords = sosoService.queryMonConsumRecords(cardnumber);
//判断是否为空
if (monthlyConsumptionRecords.isEmpty()) {
//新增的
sosoService.insertMonConsumRecords(cardnumber);
}
int talktime = 0, smscount = 0, flow = 0;
if (scenes1.get(0).getType().equals("通话")) {
talktime += scenes1.get(0).getData();
} else if (scenes1.get(0).getType().equals("短信")) {
smscount += scenes1.get(0).getData();
} else {
flow += scenes1.get(0).getData();
}
//得到该号码的套餐类型id
Integer serid = moboleCards.get(0).getSer_package();
//根据id查询套餐类型的详情
List<Serpackage> serpackages = sosoService.querySerpackage(serid);
monthlyConsumptionRecords = sosoService.queryMonConsumRecords(cardnumber);
//判断余额,看是否产生费用,产生就扣tb_mobole里面mooney的钱,增加该号码月消费记录的
//剩余的talktime
double amount = 0;
int excesstalktime = serpackages.get(0).getTalk_time() - monthlyConsumptionRecords.get(0).getReal_talk_time();
int excesssmscount = serpackages.get(0).getSms_count() - monthlyConsumptionRecords.get(0).getReal_SMS_count();
int excessflow = serpackages.get(0).getFlow() - monthlyConsumptionRecords.get(0).getReal_flow();
if (excesstalktime <= 0) {
excesstalktime = 0;
}
if (excesssmscount <= 0) {
excesssmscount = 0;
}
if (excessflow <= 0) {
excessflow = 0;
}
if (scenes1.get(0).getType().equals("通话")) {
if (excesstalktime == 0) {
amount = amount + scenes1.get(0).getData() * 0.2;
} else {
excesstalktime = excesstalktime - scenes1.get(0).getData();
}
} else if (scenes1.get(0).getType().equals("短信")) {
if (excesssmscount == 0) {
amount = amount + (scenes1.get(0).getData() * 0.1);
} else {
excesssmscount = excesssmscount - scenes1.get(0).getData();
}
} else {
if (excessflow == 0) {
amount = amount + (scenes1.get(0).getData() * 0.1);
} else {
excessflow = excessflow - scenes1.get(0).getData();
}
}
//修改的
sosoService.updateMonConsumRecords(cardnumber, amount, talktime, smscount, flow);
//修改tb_mobole里面mooney的钱
sosoService.updateTbMoboleCardMony(cardnumber, amount);
//获取修改后的号码的详细信息看余额
moboleCards = sosoService.queryMoboleByCardnum(cardnumber);
System.out.println("***************************");
System.out.println("您使用的场景是:" + scenes1.get(0).getId() + "." + scenes1.get(0).getDescription() +
",\n这次使用,通话时间为" + talktime + "分钟,短信条数为:" + smscount + "条,流量为:" + flow + "MB," +
"\n您这次使用消耗的额外费用为:" + amount + "元," +
"你的账号余额为:" + moboleCards.get(0).getMoney() + "元");
//查询套餐内的剩余余额
String s1 = sosoService.queryPackageBalance(cardnumber);
System.out.println(s1);
System.out.println("***************************");
showFirstMenu();
5.小结
完成该项目回顾了面向对象中的封装,继承,多态与接口,异常处理,集合,MySQL与JDBC等知识点,收获颇丰