一、项目需求
中国移动,中国联通,中国电信是国内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);
//让这条数据有id
monthlyConsumptionRecords = 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转为double
rechargeRecord.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);
//让这条数据有id
monthlyConsumptionRecords = 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.accountNumber
String 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 + T
try {
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的出现。