一、项目需求
中国移动,中国联通,中国电信是国内3大通信运营商,每个运营商都提供了不同的品牌套餐来应对不同的用户群,比如北京移动主要有全球通,神州行,动感地带等3大品牌套餐,每种套餐的内容和费用不同,嗖嗖移动是一个假定的通信运营商,提供了话痨套餐,网虫套餐,超人套餐,各种套餐所包含的服务内容及费用如下表:
品牌套餐 | 话痨套餐 | 网虫套餐 | 超人套餐 |
---|---|---|---|
通话时长(分钟) | 600 | 0 | 300 |
上网流量 | 0 | 20 | 10 |
短信条数(条) | 100 | 0 | 50 |
费用(元/月) | 58 | 68 | 78 |
如实际使用中超出套餐内包含的通话时长,短信条数和上网流量,则按一下规则计费:
-
超出的通话: 0.2元/分
-
超出的短信:0.1元/条
-
超出的上网流量:0.1元/MB
本任务实现的"嗖嗖移动业务大厅"提供了嗖嗖移动用户的常用功能,包括新用户注册,本月账单查询,套餐余量查询,打印消费详情,套餐变更,办理退网,话费充值,查看消费记录,查看话费说明等功能.另外,还可以模拟用户通话,上网,发送短信的场景进行相应的扣费并记录消费信息.各功能介绍如下表:
菜单级别 | 功能 | 描述 |
---|---|---|
主菜单 | 用户登录 | 输入正确的手机号码和密码进入二级菜单列表 |
主菜单 | 用户注册 | 录入信息并开卡,用户输入的信息包括:选择卡号,选择套餐类型,输入用户名和密码,预存话费金额(预存话费金额必须满足以支付所选套餐的一个月的费用) |
主菜单 | 使用嗖嗖 | 输入正确的手机号码和密码之后,随机进入本号码所属套餐可以支持的一个场景,消费套餐余量或者话费余额,并记录消费信息.当话费余额不足时,抛出异常提醒用户充值 |
主菜单 | 话费充值 | 输入正确的用户名和密码之后,可为该卡号充值 |
主菜单 | 资费说明 | 提供各品牌套餐所包含的通话时长,上网流量,短信条数,月费用等 |
主菜单 | 退出系统 | 提出本系统 |
二级菜单 | 本月账单查询 | 可查询该卡号的套餐费用,实际消费金额,账户余额 |
二级菜单 | 套餐余量查询 | 可查询该卡号的套餐余量 |
二级菜单 | 打印消费详情 | 输入正确的卡号和密码后,可打印当前卡号用户的消费详单, 使用输出流把用户信息输出到文件 |
二级菜单 | 套餐变更 | 可变更为其他套餐类型,变更后话费余额需减去变更后的套餐费用,余额不足时需要给出信息提示,套餐变更后重新统计卡中实际消费数据以及当月消费金额 |
二级菜单 | 办理退网 | 输入正确的卡号和密码后,可以从已注册的号码列表中删除本号码,并退出系统 |
二、项目需求分析
2.1 登陆
-
让用户输入手机号码, 密码,
-
根据手机号码,密码到数据库: tb_mobole_card查询
-
如果没有记录: 登录失败, 错误提示: 手机号码或者密码错误
-
如果有记录,但是状态是1(冻结): 登录失败, 错误提示: 该手机号码已冻结,请联系工作人员
-
登录成功, 进入到二级菜单
2.2 注册
-
查询所有可用卡 tb_card
-
查询所有的套餐类型, 用户选择套餐类型,
-
根据用户选择的套餐类型, 查询套餐信息
-
用户输入用户,密码. 输入充值金额
-
根据输入金额与用户选择套餐的月租比较, 输入金额小于月租, 错误提示, 用户再重新输入
-
如果大于等于, 往用户卡表(tb_mobole_card)插入一条记录
-
修改tb_card表,用户选择该手机号码的卡状态设置为不可用
-
往充值记录表中添加一条充值记录
-
显示办卡成功, 输出用户卡相关信息,以及套餐信息
-
跳转到一级菜单
2.3 使用soso
-
输入手机号码 查询到用户卡信息 查询套餐 2. 如果卡冻结状态, 无法使用嗖嗖 显示错误信息 3. 查询所有的场景, 随机一个场景进行模拟 得到场景类型, 数据
-
假设随机第一个场景, 通话场景, 打90分钟电话,
剩余免费余量 = 套餐最大免费量 - 月消费当月消费量(查询月消费)
-
如果用户的卡的剩余免费余量 > =场景的数量, 不需要扣钱, 在月消费记录表, 当月增加使用量的值
-
如果用户的卡的剩余免费余量 < 场景的数量, 需要扣钱, 在月消费记录表, 当月增加使用量的值,超出的部分进行扣费, 修改的用户卡的余额
-
往消费记录表进行记录本次消费 消费记录表
2.4 套餐变更
-
查询所有的套餐类型
-
根据当前登录的手机号码, 查询当前用户卡信息
-
用户选择套餐类型,根据用户现在的套餐明细得到套餐类型
-
判断用户选择的套餐是否是用户卡现在套餐,如果是,提示,
-
如果不是,根据用户选择的套餐类型,查询对应的套餐明细
-
判断用户卡的余额是否满足该套餐的月租, 如果不满足, 提示
-
如果满足, 更换套餐, 修改用户卡信息(套餐,余额)
-
打印用户新套餐的明细
三、代码展示
1.系统大体结构
2.使用的jar包
commons-dbutils-1.7.jar | mysql-connector-java-5.1.47.jar |
提供了简化数据库操作的工具 | 连接 MySQL 数据库的 JDBC 驱动程序 |
这两个 JAR 包通常用于 Java 应用程序中与数据库进行交互的过程中
hamcrest- 2.1jar | junit-4.12.jar |
提供更加灵活和可读性强的测试断言方式 | 用于编写和运行单元测试 |
这两个库通常会一起被用于编写高质量的测试代码,以确保代码的正确性和稳定性。
3.完整代码
1、常量类(constant包)
package com.lx.soso.constant;public interface SystemConstant {/*** 用户正常状态*/int MOBOLE_STATUS_NORMAL=0;/*** 用户冻结状态*/int MOBOLE_STATUS_FREEZE=1;/*** 手机卡的正常状态*/int CARD_STATUS_NORMAL = 0;/*** 手机卡卡号的禁用状态* 已被使用*/int CARD_STATUS_FREEZE = 1;/*** 一级管理员*/int FIRST_LEVEL_ADMINISTRATOR = 1;/*** 二级管理员*/int SECONDARY_LEVEL_ADMINISTRATOR = 2;/*** 已回复*/int REPLIED = 0;/*** 未回复*/int NOT_REPLIED = 1;
}
2、功能实现类(service包)
package com.lx.soso.service;import com.lx.soso.constant.SystemConstant;
import com.lx.soso.dao.*;
import com.lx.soso.dao.impl.*;
import com.lx.soso.entity.*;
import com.lx.soso.ui.SosoApp;
import com.lx.soso.util.DateUtil;
import com.lx.soso.util.JDBCUtil;import java.util.*;public class SoSoService {Scanner input = new Scanner(System.in);//private String number = null;/*** 登陆** @return*/public MoboleCard login() {System.out.print("请输入手机卡号:");String number = input.next();System.out.print("请输入密码:");String password = input.next();//实例化赋给接口//2.调用dao层类的方法MoboleCardDao moboleCardDao = new MoboleCardDaoImpl();MoboleCard moboleCard = moboleCardDao.queryByNumber(number);if (moboleCard == null) {//没有找到该手机号System.out.println("【友情提示:】卡号或者密码错误!");} else {//有该手机号 ,但可能状态异常和密码错误if (!moboleCard.getPassword().equals(password)) {//密码错误System.out.println("【友情提示:】卡号或者密码错误!");} else if (moboleCard.getStatus().intValue() == SystemConstant.MOBOLE_STATUS_FREEZE) {//状态异常(为1)System.out.println("【友情提示:】该手机号码已冻结,请联系工作人员!");} else {System.out.println("【友情提示:】登陆成功!");return moboleCard;}}return null;}/*** 注册*/public void register() {System.out.println("*********可选的卡号*********");CardDao cardDao = new CardDaoImpl();//查询所以可以注册的卡号List<Card> cards = cardDao.queryByStatus(SystemConstant.CARD_STATUS_NORMAL);if (cards == null) {//没有可用卡号时不可注册System.out.println("【友情提示:】暂时没有可用卡号,请稍后再试!");return;}for (int i = 0; i < cards.size(); i++) {System.out.print(i + 1 + "." + cards.get(i).getCardNumber() + "\t");if ((i + 1) % 3 == 0) {System.out.println();}}System.out.println();int cardsId = 0;do {System.out.print("请选择您需要办理的卡号序号:");cardsId = input.nextInt();if (cardsId <= 0 || cardsId >= cards.size()){System.out.println("【友情提示:】输入有误,请重新输入!");}} while (cardsId <= 0 || cardsId >= cards.size());String number = cards.get(cardsId - 1).getCardNumber();//查询所以套餐类型SerpackageTypeDao serpackageTypeDao = new SerpackageTypeDaoImpl();List<SerpackageType> serpackageTypes = serpackageTypeDao.queruAll();if (serpackageTypes == null) {//没有可用卡号时不可注册System.out.println("【友情提示:】没有套餐信息,更多套餐还在制作中。。。");return;}for (int i = 0; i < serpackageTypes.size(); i++) {System.out.print((i + 1) + "." + serpackageTypes.get(i).getName() + "\t");}System.out.println();System.out.print("请选择套餐:");int serpackageId = input.nextInt();SerpackageType serpackageType = serpackageTypes.get(serpackageId - 1);//根据选择的套餐获取详信息SerpackageDao serpackageDao = new SerpackageDaoImpl();Serpackage serpackage = serpackageDao.queryByType(serpackageId);//输入用户密码和姓名,还有充值金额System.out.print("请输入姓名:");String name = input.next();System.out.print("请输入密码:");String password = input.next();int money = 0;do {System.out.print("请输入预存话费金额:");money = input.nextInt();if (money < serpackage.getPrice()) {System.out.println("您预存的话费不足以支付您所选的套餐的本月资费,请重新输入!");}} while (money < serpackage.getPrice());//费用小于预存话费一种循环//费用大于所选套餐资费//修改选择的卡状态Card card = new Card();card.setCardNumber(number);card.setStatus(SystemConstant.CARD_STATUS_FREEZE);cardDao.update(card);//费用大于所选套餐资费//添加一个用户MoboleCard moboleCard = new MoboleCard();moboleCard.setCardNumber(number);moboleCard.setUsername(name);moboleCard.setPassword(password);moboleCard.setSerPackage(serpackageId);moboleCard.setMoney(money - serpackage.getPrice());moboleCard.setStatus(SystemConstant.MOBOLE_STATUS_NORMAL);MoboleCardDao moboleCardDao = new MoboleCardDaoImpl();moboleCardDao.insert(moboleCard);//费用大于所选套餐资费//添加一条充值记录RechargeRecord rechargeRecord = new RechargeRecord();rechargeRecord.setCardNumber(number);rechargeRecord.setAmount((double) money);rechargeRecord.setRechargeDate(new Date());RechargeRecordDao rechargeRecordDao = new RechargeRecordDaoImpl();rechargeRecordDao.rechargeByNumber(rechargeRecord);//System.out.println("您的个人信息:");System.out.println("用户名:" + moboleCard.getUsername() + "\t用户当前余额:" + moboleCard.getMoney());System.out.println("您所办理的套餐信息:");System.out.println("套餐名称 \t通话时长(分/月)\t短信条数(条/月)\t套餐月资费(元/月)\t上网流量(GB/月)");System.out.println(serpackageType.getName() + "\t\t" + serpackage.getTalkTime() + "\t\t\t\t" + serpackage.getSmsCount()+ "\t\t\t\t" + serpackage.getPrice() + "\t\t\t" + serpackage.getFlow());}/*** 使用嗖嗖*/public void useSoso() {System.out.print("请输入手机号码:");String number = input.next();//根据手机号码查用户信息MoboleCardDao moboleCardDao = new MoboleCardDaoImpl();MoboleCard moboleCard = moboleCardDao.queryByNumber(number);if (moboleCard == null) {System.out.println("【友情提示:】该手机号码为空号无法使用,请您注册后再使用!");} else if (moboleCard.getStatus() == SystemConstant.MOBOLE_STATUS_FREEZE) {System.out.println("【友情提示:】该手机号码已冻结,请联系工作人员!");} else {//获取随机场景信息SceneDao sceneDao = new SceneDaoImpl();List<Scene> scenes = sceneDao.queruAll();Random random = new Random();int i = random.nextInt(scenes.size());String type = scenes.get(i).getType();//获取随机的套餐类型Integer data = scenes.get(i).getData();//获取随机场景的消费数量String description = scenes.get(i).getDescription();//获取随机数据场景的内容//获取办理的套餐信息Integer id = moboleCard.getSerPackage();//获取当前号码办理的套餐编号SerpackageDao serpackageDao = new SerpackageDaoImpl();Serpackage serpackage = serpackageDao.queryByType(id);//所办理套餐信息//获取当月实际消费MonthlyConsumptionRecordsDao monthlyConsumptionRecordsDao = new MonthlyConsumptionRecordsDaoImpl();//List<MonthlyConsumptionRecords> monthlyConsumptionRecordsList = monthlyConsumptionRecordsDao.queryByNumber(number);Date firstDay = DateUtil.getMonthFirst(new Date());//获取当月一号日期MonthlyConsumptionRecords monthlyConsumptionRecords = monthlyConsumptionRecordsDao.queryByNumberAndDate(number, firstDay);//存储当月消费信息对象if (monthlyConsumptionRecords == null) {monthlyConsumptionRecords = new MonthlyConsumptionRecords();monthlyConsumptionRecords.setCardNumber(number);monthlyConsumptionRecords.setRealFlow(0);monthlyConsumptionRecords.setConsumAmount(0.0);monthlyConsumptionRecords.setRealTalkTime(0);monthlyConsumptionRecords.setRealSmsCount(0);monthlyConsumptionRecords.setConsumeDate(firstDay);//添加这条数据monthlyConsumptionRecordsDao.insert(monthlyConsumptionRecords);//让这条数据有idmonthlyConsumptionRecords = monthlyConsumptionRecordsDao.queryByNumberAndDate(number, firstDay);}//计算剩余随机到的消费类型免费余量int remainingFreeQuantity = 0;if (type.equals("通话")) {//计算的通话的余量remainingFreeQuantity = serpackage.getTalkTime() - monthlyConsumptionRecords.getRealTalkTime();monthlyConsumptionRecords.setRealTalkTime(monthlyConsumptionRecords.getRealTalkTime() + data);}else if (type.equals("短信")) {//计算的短信的余量remainingFreeQuantity = serpackage.getSmsCount() - monthlyConsumptionRecords.getRealSmsCount();monthlyConsumptionRecords.setRealSmsCount(monthlyConsumptionRecords.getRealSmsCount() + data);}else if (type.equals("上网")) {//计算的上网的余量remainingFreeQuantity = serpackage.getFlow() - monthlyConsumptionRecords.getRealFlow();monthlyConsumptionRecords.setRealFlow(monthlyConsumptionRecords.getRealFlow() + data);}//计算随机到的场景消费double consumption = 0.0;if (remainingFreeQuantity <= 0) {//没有免费余量,全额扣费consumption = costComputational(data, type);} else {if (remainingFreeQuantity < data) { //有费用,但费用不足超出部分扣费consumption = costComputational(data - remainingFreeQuantity, type);}}//修改用户余额moboleCard.setMoney(moboleCard.getMoney() - consumption);moboleCardDao.update(moboleCard);//添加一次消费记录ConsuminfoDao consuminfoDao = new ConsuminfoDaoImpl();Consuminfo consuminfo = new Consuminfo();consuminfo.setCardNumber(number);consuminfo.setType(type);consuminfo.setConsumData(data);consuminfo.setConsumeDate(new Date());consuminfoDao.insert(consuminfo);//根据随机到的场景类型// 修改当月消费类型数据monthlyConsumptionRecordsDao.updateType(monthlyConsumptionRecords, type);//修改实际消费金额System.out.println(description);}}/*** @param number* @param type* @return 计算费用*/private double costComputational(int number, String type) {double cost = 0;if (type.equals("通话")) {cost = number * 0.2;} else if (type.equals("短信")) {cost = number * 0.1;} else if (type.equals("上网")) {cost = number * 0.1;}return cost;}/*** 查询套餐信息* 资费说明** @return*/public boolean printSerpackage() {SerpackagesDao serpackageDao = new SerpackagesDaosImpl();Map<SerpackageType, Serpackage> serpackages = serpackageDao.querySerpackage();if (serpackages != null) {System.out.println("序号 \t套餐名称 \t通话时长(分/月)\t短信条数(条/月)\t套餐月资费(元/月)\t上网流量(GB/月)");serpackages.forEach((key, value) -> {System.out.println(key.getId() + "\t\t" + key.getName() + "\t\t" + value.getTalkTime() + "\t\t\t\t" + value.getSmsCount() + "\t\t\t\t" + value.getPrice() + "\t\t\t" + value.getFlow());});System.out.println("【友情提示:】查询成功!");return true;} else {System.out.println("【友情提示:】没有套餐信息,更多套餐还在制作中。。。");return false;}}/*** 话费充值* @return 添加成功*/public boolean Recharge() {System.out.println("******话费充值******");System.out.print("请输入要充值的卡号:");String number = input.next();System.out.print("请输入充值金额:");String amount = input.next();//根据号码获取用户信息MoboleCardDao moboleCardDao = new MoboleCardDaoImpl();MoboleCard moboleCard = moboleCardDao.queryByNumber(number);if (moboleCard == null){System.out.println("【友情提示:】没有该卡号!");return false;}else if (moboleCard.getStatus().intValue() ==SystemConstant.MOBOLE_STATUS_FREEZE){System.out.println("【友情提示:】该手机号码已冻结无法充值,请联系工作人员!");return false;}else {moboleCard.setMoney(moboleCard.getMoney()+Integer.parseInt(amount));int i = moboleCardDao.updateByMoney(moboleCard);if (i == 1) {//充值成功在进行添加充值记录操作//创建RechargeRecord(充值记录)对象RechargeRecord rechargeRecord = new RechargeRecord();rechargeRecord.setAmount(Double.valueOf(amount));//将传入的string转为doublerechargeRecord.setRechargeDate(new Date());rechargeRecord.setCardNumber(number);//创建dao进行添加操作RechargeRecordDao rechargeRecordDao = new RechargeRecordDaoImpl();rechargeRecordDao.rechargeByNumber(rechargeRecord);Double money = moboleCardDao.queryByNumber(number).getMoney();//查询修改后的余额值System.out.println("【友情提示:】充值成功,卡上余额:" + money + "元");return true;} else {System.out.println("【友情提示:】充值失败!");return false;}}}/*** 反馈功能*/public int feedback() {if (SosoApp.number == null) {System.out.print("请输入电话号码:");SosoApp.number = input.next();//13677478866;13666557788}System.out.println("反馈信息:");FeedbackDao feedbackDao = new FeedbackDaoImp();List<Feedback> notReplied = feedbackDao.queruReplied(SosoApp.number, SystemConstant.NOT_REPLIED);System.out.println("未回复("+notReplied.size()+")");List<Feedback> replied = feedbackDao.queruReplied(SosoApp.number, SystemConstant.REPLIED);System.out.println("已回复("+replied.size()+")");System.out.println("1.查看回复\t2.反馈\t3.返回上一级");System.out.print("选择操作(1~3):");int op = input.nextInt();switch (op){case 1:for (int i = 0; i < replied.size(); i++) {Feedback feedback = replied.get(i);System.out.println("------编号:"+(i+1)+"-----------");System.out.println("反馈时间:"+feedback.getFeedbackDate()+"\t反馈号码:"+feedback.getCardNumber()+"\n反馈内容:"+feedback.getFeedbackContent());System.out.println("回复信息:"+feedback.getAdministratorReply());System.out.println("回复人:"+feedback.getAdministratorName());System.out.println("-----------------------");System.out.println("下一个(输入1,其他退出查看)");int op1 = input.nextInt();boolean next = true;while (next){if (op1 == 1){if (i == replied.size()-1){System.out.println("【温馨提示:】没有回复了!");System.out.println("-----------------------");next = false;}}else {System.out.println("【友情提示】:输入有误,请重新输入");next = false;}}}//todo 操作管理员feedback();break;case 2:System.out.println("请输入反馈内容:");String reply = input.next();Feedback feedback = new Feedback();//new一个 Feedback(反馈信息)对象feedback.setCardNumber(SosoApp.number);//电话feedback.setFeedbackContent(reply);//反馈内容feedback.setFeedbackDate(new Date());//时间int insert = feedbackDao.insert(feedback);//添加反馈记录if (insert == 1){System.out.println("【温馨提示】反馈成功!");return insert;}feedback();break;//todo 操作管理员case 3://todo 操作管理员break;case 4://返回上级菜单System.out.println("【友情提示】:返回上一级菜单成功");break;default:System.out.println("【友情提示】:输入有误,请重新输入");break;}return 0;}//-------------------------二级菜单服务-------------------------------------/*** 本月账单查询*/public void queryMonthBill() {//number = "13677478866";System.out.println("你的卡号是:"+ SosoApp.number);System.out.println("当月账单:");//获取当月套餐资费MoboleCardDao moboleCardDao = new MoboleCardDaoImpl();Integer type = moboleCardDao.queryByNumber(SosoApp.number).getSerPackage();//套餐类型SerpackageDao serpackageDao = new SerpackageDaoImpl();Double price = serpackageDao.queryByType(type).getPrice();//办理的套餐资费System.out.println("套餐资费:"+price);//获取当月额外消费MonthlyConsumptionRecordsDao monthlyConsumptionRecordsDao = new MonthlyConsumptionRecordsDaoImpl();MonthlyConsumptionRecords monthlyConsumptionRecords = monthlyConsumptionRecordsDao.queryByNumberAndDate(SosoApp.number,DateUtil.getMonthFirst(new Date()));Double consumAmount = monthlyConsumptionRecords.getConsumAmount();//计算合计消费System.out.println("合计消费:"+(consumAmount+price));//打印账户余额System.out.println("账户余额:"+moboleCardDao.queryByNumber(SosoApp.number).getMoney());}/*** 套餐余量查询*/public void queryPackageBalance() {//number = "13652363333";//获取办理套餐信息MoboleCardDao moboleCardDao = new MoboleCardDaoImpl();Integer type = moboleCardDao.queryByNumber(SosoApp.number).getSerPackage();//套餐类型SerpackageDao serpackageDao = new SerpackageDaoImpl();Serpackage serpackage = serpackageDao.queryByType(type);Integer talkTime = serpackage.getTalkTime();//通话Integer smsCount = serpackage.getSmsCount();//短信Integer flow = serpackage.getFlow();//上网//获取当月实际用量MonthlyConsumptionRecordsDao monthlyConsumptionRecordsDao = new MonthlyConsumptionRecordsDaoImpl();MonthlyConsumptionRecords monthlyConsumptionRecords = monthlyConsumptionRecordsDao.queryByNumberAndDate(SosoApp.number,DateUtil.getMonthFirst(new Date()));if (monthlyConsumptionRecords == null) {monthlyConsumptionRecords = new MonthlyConsumptionRecords();monthlyConsumptionRecords.setCardNumber(SosoApp.number);monthlyConsumptionRecords.setRealFlow(0);monthlyConsumptionRecords.setConsumAmount(0.0);monthlyConsumptionRecords.setRealTalkTime(0);monthlyConsumptionRecords.setRealSmsCount(0);monthlyConsumptionRecords.setConsumeDate(DateUtil.getMonthFirst(new Date()));//添加这条数据monthlyConsumptionRecordsDao.insert(monthlyConsumptionRecords);//让这条数据有idmonthlyConsumptionRecords = monthlyConsumptionRecordsDao.queryByNumberAndDate(SosoApp.number, DateUtil.getMonthFirst(new Date()));}Integer realTalkTime = monthlyConsumptionRecords.getRealTalkTime();//通话Integer realSmsCount = monthlyConsumptionRecords.getRealSmsCount();//短信Integer realFlow = monthlyConsumptionRecords.getRealFlow();//上网Integer residueTalkTime = talkTime-realTalkTime;Integer residuesmsCount = smsCount-realSmsCount;Integer residueflow = flow - realFlow;if (residueTalkTime >=0){System.out.println("通话时间:"+realTalkTime+"分钟");}else {System.out.println("通话时间:0分钟");}if (residuesmsCount >=0){System.out.println("短信条数:"+residuesmsCount+"条");}else {System.out.println("短信条数:0条");}if (residueflow >=0){String format = String.format("%.2f", (double)residueflow / 1024);System.out.println("上网流量:"+format+"G");}else {System.out.println("上网流量:0G");}}/*** 打印消费详单*/public void printConsumptionDetails() {//String number = "13677478866";System.out.print("请输入本年需要查询的月份(1~12):");String month = input.next();ConsuminfoDao consuminfoDao = new ConsuminfoDaoImpl();List<Consuminfo> consuminfoList = consuminfoDao.queryByNumber(SosoApp.number);List <Consuminfo>ThisMonthConsuminfo = new ArrayList();//ThisMonthConsuminfo = null;if (consuminfoList == null){System.out.println("【友情提示】:对不起,您还没有使用过soso快去使用把。");}else {for (int i = 0; i < consuminfoList.size(); i++) {Date consumeDate = consuminfoList.get(i).getConsumeDate();int consumeMonth = DateUtil.getMonth(consumeDate);if (month.equals(String.valueOf(consumeMonth))){ThisMonthConsuminfo.add(consuminfoList.get(i));}}if (ThisMonthConsuminfo.size() > 0){System.out.println("序号\t\t类型\t\t数据\t\t日期");for (int i = 0; i < ThisMonthConsuminfo.size(); i++) {System.out.println((i+1)+"\t\t"+ThisMonthConsuminfo.get(i).getType()+"\t\t"+ThisMonthConsuminfo.get(i).getConsumData()+"\t\t"+ThisMonthConsuminfo.get(i).getConsumeDate());}}else {System.out.println("【友情提示】:对不起,不存在本卡号"+month+"月消费记录!");}}}/*** 套餐变更*/public void packageChanges() {SerpackageTypeDao serpackageTypeDao = new SerpackageTypeDaoImpl();List<SerpackageType> serpackageTypes = serpackageTypeDao.queruAll();if (serpackageTypes == null) {//没有可用卡号时不可注册System.out.println("【友情提示:】没有套餐信息,更多套餐还在制作中。。。");return;}for (int i = 0; i < serpackageTypes.size(); i++) {System.out.print((i + 1) + "." + serpackageTypes.get(i).getName() + "\t");}System.out.println();Integer serpackageId = 0;do {System.out.print("请选择套餐:");serpackageId = input.nextInt();if (serpackageId <= 0 || serpackageId >= serpackageTypes.size()){System.out.println("【友情提示:】输入有误,请重新输入!");}} while (serpackageId <= 0 || serpackageId >= serpackageTypes.size());//根据选择的套餐获取详信息SerpackageDao serpackageDao = new SerpackageDaoImpl();Serpackage serpackage = serpackageDao.queryByType(serpackageId);Double price = serpackage.getPrice();//套餐费用//查询用户信息MoboleCardDao moboleCardDao = new MoboleCardDaoImpl();MoboleCard moboleCard = moboleCardDao.queryByNumber(SosoApp.number);Double money = moboleCard.getMoney();Integer type = moboleCard.getSerPackage();//serpackageId.equals(type+"")if (serpackageId == type){System.out.println("【友情提示]】:您已经是改套餐的用户,无需更换!");}else {if (money < price){System.out.println("【友情提示】:对不起,您的余额不足以支付新套餐本月资费,请充值后办理变更套餐业务!");}else {moboleCard.setMoney(money - price);moboleCardDao.updateByMoney(moboleCard);moboleCardDao.updatebyNumberSerPackage(SosoApp.number, serpackageId);System.out.println("【友情提示】:更换"+serpackageTypes.get(serpackageId-1).getName()+"成功!");System.out.println("套餐信息:通话时长:"+ serpackage.getTalkTime()+"分钟/月,短信条数:"+serpackage.getSmsCount()+"条/月,上网流量:"+serpackage.getFlow()+"GB/月,月租:"+serpackage.getPrice()+"元/月");}}}/*** 办理退网*/public void logout() {//根据号码删除用户信息MoboleCardDao moboleCardDao = new MoboleCardDaoImpl();moboleCardDao.deleteByNumber(SosoApp.number);//修改电话卡表该卡状态Card card = new Card();card.setCardNumber(SosoApp.number);card.setStatus(SystemConstant.CARD_STATUS_NORMAL);CardDao cardDao = new CardDaoImpl();cardDao.update(card);List<Card> cards = cardDao.queryByStatus(SystemConstant.CARD_STATUS_NORMAL);long count = cards.stream().filter(str -> str.getStatus().equals(SystemConstant.CARD_STATUS_NORMAL)&str.getCardNumber().equals(SosoApp.number)).count();if (count == 1){System.out.println("用户卡号:"+SosoApp.number+"退网办理成功");}}/*-------------------------------------------------管理员操作------------------------------------------*//*** 管理员登陆* @return*/public Administrators ALogin() {System.out.println("***********管理员登陆***********");System.out.print("请输入账号:");String number = input.next();System.out.print("请输入密码:");String password = input.next();//实例化赋给接口//调用dao层类的方法AdministratorsDao administratorsDao = new AdministratorsDaoImpl();Administrators administrators = administratorsDao.queruByNumber(number);if (administrators == null) {//没有找到该账号System.out.println("【友情提示:】卡号或者密码错误!");} else {//有但密码错误if (!administrators.getPassword().equals(password)) {//密码错误System.out.println("【友情提示:】卡号或者密码错误!");} else {System.out.println("【友情提示:】登陆成功!");return administrators;}}return null;}public void viewFeedback(){FeedbackDao feedbackDao = new FeedbackDaoImp();List<Feedback> feedbackList = feedbackDao.queruAll();if (feedbackList.size() == 0){System.out.println("【温馨提示】暂时还没有未回复的反馈");}for (int i = 0; i < feedbackList.size(); i++) {Feedback feedback = feedbackList.get(i);System.out.println("------编号:"+(i+1)+"-----------");System.out.println("反馈时间:"+feedback.getFeedbackDate()+"\t反馈号码:"+feedback.getCardNumber()+"\n反馈内容:"+feedback.getFeedbackContent());System.out.println("-----------------------");System.out.println("是否处理(1.处理,2.跳过)");System.out.print("请选择:");int op = input.nextInt();boolean next = true;int op2 = 0;while (next){if (op == 1){MoboleCardDao moboleCardDao = new MoboleCardDaoImpl();MoboleCard moboleCard = moboleCardDao.queryByNumber(feedback.getCardNumber());//账户信息if (moboleCard == null){System.out.println("【温馨提示】非本运营商用户!");}SerpackageDao serpackageDao = new SerpackageDaoImpl();MonthlyConsumptionRecordsDao monthlyConsumptionRecordsDao = new MonthlyConsumptionRecordsDaoImpl();System.out.println("************反馈功能************");System.out.println("1.查看账户信息\t2.查看账户各项消费\t3.解除冻结\t4.回复\t5.下一个\t6.退出反馈");System.out.print("请选择操作:");op2 = input.nextInt();switch (op2){case 1:System.out.println("-----账户信息-----");if (moboleCard != null){String status = null;if (moboleCard.getStatus() == SystemConstant.MOBOLE_STATUS_FREEZE){status = "冻结";}else if (moboleCard.getStatus() == SystemConstant.MOBOLE_STATUS_NORMAL){status = "正常";}System.out.println("账户状态:"+status);//System.out.println("所属套餐:"+moboleCard.getSerPackage());System.out.println("账户余额:"+moboleCard.getMoney());}else {System.out.println("【温馨提示】非本运营商用户,没有消息!");}System.out.println("----------------");break;case 2:System.out.println("-----扣费情况-----");if (moboleCard != null){Serpackage serpackage = serpackageDao.queryByType(moboleCard.getSerPackage());//套餐信息MonthlyConsumptionRecords monthlyConsumptionRecords =monthlyConsumptionRecordsDao.queryByNumberAndDate(moboleCard.getCardNumber(), DateUtil.getMonthFirst(feedbackList.get(i).getFeedbackDate()));//实际消费if (monthlyConsumptionRecords.getRealTalkTime()>serpackage.getTalkTime()){//实际消费大于套餐if (serpackage.getTalkTime() == 0){System.out.print("套餐没有免费短信条数");}else {System.out.print("套餐使用超出,");}System.out.println("通话使用扣费");}else {System.out.println("通话未造成扣费");}if (monthlyConsumptionRecords.getRealSmsCount()>serpackage.getSmsCount()){//实际消费大于套餐if (serpackage.getTalkTime() == 0){System.out.print("套餐没有免费短信条数");}else {System.out.print("套餐使用超出,");}System.out.println("短信使用扣费");}else {System.out.println("短信未造成扣费");}if (monthlyConsumptionRecords.getRealFlow()>serpackage.getFlow()){//实际消费大于套餐if (serpackage.getTalkTime() == 0){System.out.print("套餐没有免费上网流量,");}else {System.out.print("套餐使用超出,");}System.out.println("上网使用扣费");}else {System.out.println("流量未造成扣费");}}else {System.out.println("【温馨提示】非本运营商用户,没有信息!");}System.out.println("------------------");break;case 3:if (moboleCard != null){moboleCardDao.updateByNumberStatus(moboleCard.getCardNumber());//解除冻结}else {System.out.println("【温馨提示】非本运营商用户,无法进行该项服务!");}break;case 4:System.out.println("请输入回复内容:");String reply = input.next();AdministratorsDao administratorsDao = new AdministratorsDaoImpl();Administrators administrators = administratorsDao.queruByNumber(SosoApp.accountName);//SosoApp.accountNumberString administratorName = administrators.getName();feedbackList.get(i).setAdministratorReply(reply);//讲回复内容添加到 处理的 feedback对象feedbackList.get(i).setAdministratorName(administratorName);//处理管理员姓名feedbackList.get(i).setState(SystemConstant.REPLIED);//回复后将反馈状态改为已回复//将回复修改int update = feedbackDao.update(feedbackList.get(i));if (update == 1){System.out.println("【温馨提示】回复成功");}break;case 5:if (i == feedbackList.size()-1){System.out.println("【温馨提示:】用户反馈查看完毕");}next = false;break;case 6:return;default:System.out.println("【友情提示】:输入有误,请重新输入");break;}}else if (op == 2){if (i == feedbackList.size()-1){//最后一条System.out.println("【温馨提示:】用户反馈查看完毕");}next = false;}else {System.out.println("【友情提示】:输入有误,请重新输入");}}}}/*** 修改级别*/public void aa(){AdministratorsDao administratorsDao = new AdministratorsDaoImpl();Administrators administrators1 = new Administrators();List<Administrators> administratorsList = administratorsDao.queruAll();int sum = 0;for (int i = 0; i < administratorsList.size(); i++) {/*if (administratorsList.get(i).getLevels() == SystemConstant.FIRST_LEVEL_ADMINISTRATOR){continue;}*///System.out.println(administratorsList.get(i));System.out.println((++sum)+"."+administratorsList.get(i).getName()+" 等级:"+administratorsList.get(i).getLevels());}System.out.print("请选择需要修改的人:");int name= input.nextInt();System.out.print("请选择需要的等级:");int levels= input.nextInt();sum = 0;for (int i = 0; i < administratorsList.size(); i++) {sum++;if (sum == name){//确定修改的人的名字administrators1.setName(administratorsList.get(i).getName());administrators1.setLevels(levels);}}administratorsDao.update(administrators1);System.out.println("【温馨提示】修改成功!");}/*** 添加管理员*/public void bb(){AdministratorsDao administratorsDao = new AdministratorsDaoImpl();System.out.println("请输入名字:");String name = input.next();System.out.println("请输入账号:");String accountNumber = input.next();System.out.println("请输入密码:");String password = input.next();System.out.println("请输入等级:");int level = input.nextInt();Administrators administrators = new Administrators();administrators.setName(name);administrators.setAccountNumber(accountNumber);administrators.setPassword(password);administrators.setLevels(level);int insert = administratorsDao.insert(administrators);System.out.println("【温馨提示】添加成功!");}/*** 删除管理员*/public void cc(){AdministratorsDao administratorsDao = new AdministratorsDaoImpl();List<Administrators> administrators = administratorsDao.queruAll();int sum = 1;for (int i = 0; i < administrators.size(); i++) {if (administrators.get(i).getLevels().equals(SystemConstant.FIRST_LEVEL_ADMINISTRATOR)){continue;}System.out.println((sum++)+"."+administrators.get(i).getName());}System.out.print("请选择需要删除的人:");int i = input.nextInt();//int update = administratorsDao.deleteById(sum);System.out.println("【温馨提示】删除成功!");}}
3、菜单类(ui包)
package com.lx.soso.ui;import com.lx.soso.constant.SystemConstant;
import com.lx.soso.entity.Administrators;
import com.lx.soso.entity.MoboleCard;
import com.lx.soso.service.SoSoService;import java.util.Scanner;public class SosoApp {Scanner input = new Scanner(System.in);//号码public static String number = null;//管理员账号public static String accountName = null;//public static String name = null;//管理员等级Integer levels = 2;private SoSoService soSoService = new SoSoService();public static void main(String[] args) {new SosoApp().showFirstMenu();}/*** 显示一级菜单*/public void showFirstMenu(){System.out.println("****************************欢迎使用嗖嗖移动业务大厅****************************");System.out.println("1.用户登录\t2.用户注册\t3.使用嗖嗖\t4.话费充值\t5.资费说明\t6.反馈\t7.退出系统\t8.管理员登陆");System.out.print("请选择(1~8)功能:");String choose = input.next();switch (choose){case "1":MoboleCard moboleCard = soSoService.login();if (moboleCard == null){showFirstMenu();}number = moboleCard.getCardNumber();showSecondMenu();break;case "2":soSoService.register();//用户注册showFirstMenu();break;case "3":soSoService.useSoso();//使用嗖嗖showFirstMenu();break;case "4":soSoService.Recharge();//话费充值showFirstMenu();break;case "5":soSoService.printSerpackage();//资费说明showFirstMenu();break;case "6":soSoService.feedback();//反馈showFirstMenu();break;case "7":System.out.println("欢迎使用本系统~~~");System.out.println("系统正在退出....");System.exit(0);break;case "8":Administrators administrators = soSoService.ALogin();//管理员登陆if (administrators == null){showFirstMenu();}accountName = administrators.getAccountNumber();levels = administrators.getLevels();name = administrators.getName();administratorsMenu();break;default:System.out.println("【友情提示】:输入有误,请重新输入");showFirstMenu();break;}}/*** 显示二级菜单*/public void showSecondMenu(){System.out.println("****************************嗖嗖移动用户菜单****************************");System.out.println("1.本月账单查询\t2.套餐余量查询\t3.打印消费详单\t4.套餐变更\t5.反馈\t6.办理退网\t7.返回上一级");System.out.print("请选择(1~6)功能:");String choose = input.next();switch (choose){case "1":soSoService.queryMonthBill();//本月账单查询showSecondMenu();break;case "2":soSoService.queryPackageBalance();//套餐余量查询showSecondMenu();break;case "3":soSoService.printConsumptionDetails();//打印消费详单showSecondMenu();break;case "4":soSoService.packageChanges();//套餐变更showSecondMenu();break;case "5":soSoService.feedback();showSecondMenu();// 反馈 反馈表:反馈号码、反馈内容、回复break;case "6":soSoService.logout();// 办理退网showFirstMenu();break;case "7"://返回上级菜单showFirstMenu();System.out.println("【友情提示】:返回上一级菜单成功");break;default:System.out.println("【友情提示】:输入有误,请重新输入");showSecondMenu();break;}}/*** 一级管理员菜单*/public void administratorsMenu(){String levelStr = null;String op = null;int ops = 2;if (levels == SystemConstant.FIRST_LEVEL_ADMINISTRATOR){levelStr = "一级";op = "\n3.操作管理员";ops+=1;}else {levelStr = "二级";}System.out.println("****************************"+levelStr+"管理员:"+name+"****************************");System.out.println("1.查看反馈\n2.返回上一级"+op);System.out.print("请选择(1~"+ops+")功能:");String choose = input.next();switch (choose){case "1":soSoService.viewFeedback();administratorsMenu();break;case "2"://返回上级菜单showFirstMenu();System.out.println("【友情提示】:返回上一级菜单成功");break;case "3":if (levels == SystemConstant.FIRST_LEVEL_ADMINISTRATOR){fist();}else {System.out.println("【友情提示】:输入有误,请重新输入");administratorsMenu();}break;default:System.out.println("【友情提示】:输入有误,请重新输入");administratorsMenu();break;}}public void fist(){System.out.println("*******************************************************");System.out.println("1.修改级别\t2.添加管理员\t3.删除管理员\t4.返回上一级");System.out.print("选择操作:");int op3 = input.nextInt();switch (op3){case 1:soSoService.aa();//todo 操作管理员fist();break;case 2:soSoService.bb();fist();//todo 操作管理员break;case 3:soSoService.cc();fist();//todo 操作管理员break;case 4://返回上级菜单System.out.println("【友情提示】:返回上一级菜单成功");administratorsMenu();break;default:System.out.println("【友情提示】:输入有误,请重新输入");fist();break;}}
}
4、工具类(util包)
4.1JDBC连接数据库
package com.lx.soso.util;import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;public class DateUtil {private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");private static SimpleDateFormat yearSdf = new SimpleDateFormat("yyyy-MM-dd");//Date date = new Date(System.currentTimeMillis());//获取当前时间戳/*** 将时间转化为规定的格式(yyyy-MM-dd HH:mm:ss格式字符串)* @param date* @return*/public static String formatDate(Date date){return sdf.format(date);}public static String yearFormatDate(Date date){return yearSdf.format(date);}//根据时间获取这个时间的当月1号日期public static Date getMonthFirst(Date date){Calendar ca = Calendar.getInstance();ca.setTime(date);ca.set(Calendar.DATE,1);Date time = ca.getTime();return time;}public static int getMonth(Date date){Calendar ca = Calendar.getInstance();ca.setTime(date);int i = ca.get(Calendar.MONTH);return i+1;}}
4.2时间格式化
package com.lx.soso.util;import java.io.IOException;
import java.io.InputStream;
import java.sql.*;
import java.util.Properties;/*** @author lx* @version 1.0* @title JDBCUtil* @description* @create 2024/1/8 9:48*/public class JDBCUtil {static Properties props = new Properties();static{// 包裹选中的代码, ctrl + alt + Ttry {InputStream in = JDBCUtil.class.getClassLoader().getResourceAsStream("db.properties");props.load(in);Class.forName(props.getProperty("jdbc.driver"));} catch (IOException e) {e.printStackTrace();} catch (ClassNotFoundException e) {e.printStackTrace();}}/*** 获取连接* @return*/public static Connection getConnection() throws SQLException {return DriverManager.getConnection(props.getProperty("jdbc.url"),props.getProperty("jdbc.username"),props.getProperty("jdbc.password"));}public static void close(Connection conn, Statement statement, ResultSet resultSet){//6.关闭资源 倒序关 先开的后关, 后开的先关try {if(resultSet!=null){resultSet.close();}if(statement!=null){statement.close();}if(conn!=null){conn.close();}} catch (SQLException throwables) {throwables.printStackTrace();}}
}
四、部分功能展示
登陆
注册
使用soso
话费充值 资费说明
本月账单查询 套餐余量查询
打印消费详单
用户反馈
查看回复
管理员回复
五、分析总结
1、Java基础
项目中用到了java中的属性,方法,集合,接口,随机数,if语句,switch语句,while循环等,涉及到的知识面相当广泛。巩固了之前的Java基础。
2、数据库
其中涉及到了数据库的知识,包括基础的增删查改sql语句的编写。还有JDBC操作数据库。这其实是这个项目的重点
3、项目结构
•Java Dao模式的运用(将数据库操作封装):一个实体类对应一个Dao接口和Dao实现类
•共同属性、方法进行封装:实体类的id、Dao接口的增删改查方法
•工具类的编写:JDBCUtil、DateUtil
4、IDEA Debug使用
由于项目代码量比较多功能模块较多,在程序编码中容易出bug,尤其NullPointerException
出现颇多,这时Debug可以帮我们节省大量时间,当然在日常编写也应该注意防止bug的出现。