一、引言
在数字化时代,通信服务已成为我们日常生活的必需品。嗖嗖移动业务大厅,一个虚拟的通信运营商平台,为用户提供了全面的通信服务解决方案。本文将详细介绍嗖嗖移动业务大厅的功能、技术实现以及用户操作指南,带您体验高效便捷的一站式通信服务。
嗖嗖移动业务大厅概述
嗖嗖移动是一个假定的通信运营商,提供了三种品牌套餐:话痨套餐、网虫套餐和超人套餐,每种套餐针对不同用户群体的需求,提供了差异化的通话时长、上网流量、短信条数和月费用。除了基本套餐服务,嗖嗖移动还提供了新用户注册、账单查询、套餐余量查询、消费详情打印、套餐变更、退网办理、话费充值、消费记录查看和资费说明等增值服务。
二、用户操作指南
1.用户登录与注册
用户可以通过输入手机号码和密码登录系统,享受嗖嗖移动提供的各项服务。新用户需要注册,录入基本信息并选择套餐,预存足够的话费以支付第一个月的套餐费用。
2、账单查询与套餐余量检查
用户可以随时查询本月账单,了解套餐费用和实际消费金额。同时,用户可以检查套餐的余量,包括通话时长、短信条数和上网流量。
3、消费详情打印
用户可以打印详细的消费清单,系统会将用户的消费信息输出到文件,方便用户随时查阅。
4、套餐变更与退网办理
用户可以根据需要变更套餐类型,系统会自动计算变更后的套餐费用,并更新账户余额。如果用户决定退网,可以通过退网功能从系统中删除注册号码。
5、话费充值与流量共享
用户可以为卡号充值话费,确保账户余额充足。此外,嗖嗖移动还提供了流量共享服务,允许两个号码共享流量。
6、资费说明
用户可以查看嗖嗖移动提供的所有套餐的资费说明,包括通话时长、上网流量、短信条数和月费用等信息。
三、项目技术概览
嗖嗖移动业务大厅的实现采用了以下技术:
- 面向对象编程:利用封装、继承和多态性提高代码的可维护性和可扩展性。
- 异常处理:合理地处理潜在的运行时错误,增强程序的健壮性。
- 集合框架:使用Java集合框架管理数据集合,提高数据处理效率。
- I/O操作:通过输入输出流实现文件的读写操作,持久化用户数据。
- MySQL数据库:使用MySQL数据库存储用户信息和消费记录。
- JDBC:通过JDBC连接和操作MySQL数据库,实现数据的动态交互。
四、数据库表格设计文档
1. tb_card
表
字段名 | 数据类型 | 长度 | 默认值 | 备注 |
id | int | 11 | 主键 | |
cardNumber | char | 11 | 手机号码,唯一索引 | |
status | int | 1 | 0 | 状态:0-可用,1-禁用 |
2. tb_consuminfo
表
tb_consuminfo
tb_consuminfo
字段名 | 数据类型 | 长度 | 默认值 | 备注 |
id | int | 11 | 主键 | |
card_number | char | 11 | 手机号码,外键关联 | |
type | varchar | 50 | 消费类型 | |
consum_data | int | 11 | 消费数据 | |
consume_date | datetime | 消费日期 |
3. tb_mobole_card
表tb_mobole_card
字段名 | 数据类型 | 长度 | 默认值 | 备注 |
id | int | 11 | 主键 | |
card_number | char | 11 | 手机号码,外键关联 | |
username | varchar | 20 | 用户名 | |
password | varchar | 20 | 密码 | |
ser_package | int | 11 | 所属套餐,外键关联 | |
money | double | 7,2 | 账户余额 | |
status | int | 1 | 0 | 状态:0-正常,1-冻结 |
4. tb_monthly_consumption_records
表
字段名 | 数据类型 | 长度 | 默认值 | 备注 |
id | int | 11 | 主键 | |
card_number | char | 11 | 手机号码,外键关联 | |
consum_amount | double | 7,2 | 0.00 | 当月消费费 |
real_talk_time | int | 11 | 0 | 当月实际通话时长 |
real_SMS_count | int | 11 | 0 | 当月实际发送短信条数 |
real_flow | int | 0 | 当月实际上网流量 | |
consume_date | date | 日期 |
5. tb_recharge_record
表
字段名 | 数据类型 | 长度 | 备注 |
id | int | 11 | 主键 |
amount | double | 7,2 | 充值金额 |
recharge_date | datetime | 充值时间 | |
card_number | char | 11 | 手机号,外键关联 |
6. tb_scene
表
字段名 | 数据类型 | 长度 | 备注 |
id | int | 11 | 主键 |
type | varchar | 30 | 场景类型 |
data | int | 11 | 场景消费数据 |
description | varchar | 200 | 场景描述 |
7. tb_serpackage
表
字段名 | 数据类型 | 长度 | 备注 |
id | int | 11 | 主键,外键关联 |
talk_time | int | 11 | 通话时长 |
sms_count | int | 11 | 短信条数 |
price | double | 7,2 | 套餐月资费 |
flow | int | 11 | 上网流量 |
type | int | 11 | 套餐类型,外键关联 |
8. tb_serpackage_type
表
字段名 | 数据类型 | 长度 | 备注 |
id | int | 11 | 主键 |
name | varchar | 50 | 套餐类型名称 |
关联关系说明
tb_card
表中的cardNumber
字段与tb_consuminfo
,tb_mobole_card
,tb_monthly_consumption_records
,tb_recharge_record
表中的card_number
字段建立了外键关联。tb_mobole_card
表中的ser_package
字段与tb_serpackage
表中的id
字段建立了外键关联。tb_serpackage
表中的type
字段与tb_serpackage_type
表中的id
字段建立了外键关联。
五、数据库操作相关接口:
// 判断卡状态
int watchStatus(String num);
// 打印场景
List<Scene> ScenShow();
// 套餐余额查询
MoboleCard NumShow(String num);
// 套餐免费用量查询
SerPackage FreeShow(Integer type);
// 当月日期 查询这张表的当月消费记录,tb_monthly_consumption_records
List<monthlyConsumptionRecords> NowMonth(String num);
// 为空,增加消费数据
public boolean addFreeFee(String num);
//添加一条消费记录
public void addSunInfo(String num,String type,double money);
// 修改本月消费额度
public void uodateMonthSum(String num,double spendey,int m0,int m1,int m2);
//根据状态查询所有电话号码
public List<Card> showNumPage2();
//查询套餐类型
public SerPackage typeSao(SerPackageType serPackageType);
// * 查看套餐
public List<FeeShow> showFeePage();
// tb_mobole_card表添加电话号码 tb_card表也要添加
public boolean addSao(MoboleCard moboleCard);
public boolean uodqteSao2(double mon,String num);
// 根据号码查询CardMobel表的状态
// 用密码姓名登录进入二级系统并传入MoboleCard对象
public Map<String, MoboleCard> login3(String num, String password);
// 名字和密码返回MoboleCard类
public MoboleCard selectName(String name, String password);
// 根据号码返回MoboleCard类
// public MoboleCard selectName2(String name, String password);
// 添加充值时间、金额 RechargeRecord record
public void record(RechargeRecord record);
// 二级菜单:1,
// 根据传过来的的type在tb_serpackage中显示price套餐月资费,计算钱,
public SerPackage showFee1(Integer type);
//套餐名展示
public List<SerPackageType> mealShow();
// 根据号码查询消费数据
public ConsumInfo showFee2(String number);
// 查询月记录消费
public monthlyConsumptionRecords remainShow(String num);
// 根据Id返回SerPackage集合
public List<SerPackage> watchSelection(int id);
// 根据id和num修改套餐,并查询serPackages新套餐内容
List<SerPackage> upsetType(String num,int id);
// 更新两个表的状态信息
public boolean updateStatus(String num);
// 改 status=3,shareFlow
void UpdateShareSaoCard(String num);
void addShadeFlow(String numA,String numB,int shareFlow);
//查询共享流量
public int sharedFlow(String num);
功能实现:
菜单一级目录:
private static void firstShow() {
while (true) {
System.out.println("*********************欢迎使用嗖嗖移动大厅**************************");
System.out.println("1.用户登录 2.用户注册 3.使用嗖嗖 4.花费充值 5.资费说明 6.退出系统");
System.out.println("请选择:");
Scanner scanner1 = new Scanner(System.in);
int i = scanner1.nextInt();
switch (i) {
case 1:
doLogin(scanner1);
break;
case 2:
doRegist(scanner1);
break;
case 3:
MySaosao();
break;
case 4:
saveMoney(scanner1);
break;
case 5:
calrifySao();
break;
case 6:
System.exit(0);
break;
}
}
}
二级目录:
private static void secondShow(MoboleCard moboleCard) {
while(true){
System.out.println("*******************嗖嗖移动用户菜单**************************8");
System.out.println("1.本月菜单查询\n2.套餐余量查寻\n3.打印消费详情\n4.套餐变更\n5.流量共享\n6.办理退网\n请选择(输入1~5选择功能,其他键返回上一级):");
int z = scanner.nextInt();
switch (z) {
case 1:
chesckSao(moboleCard);
break;
case 2:
reaminCheck(moboleCard);
break;
case 3:
monthCheck(moboleCard);
break;
case 4:
updateSao(moboleCard);
break;
case 5:
shareFlow(moboleCard);
break;
case 6:
exitSao(moboleCard);
break;
default:
firstShow();
}
}
}
六、遇到的异常:
1、java.lang.InstantiationException:
JDBCFour.model.monthlyConsumptionRecords
Java 无法找到 monthlyConsumptionRecords类的构造函数
解决方法:创建构造函数
2、Exception in thread "main" java.lang.RuntimeException:
java.sql.SQLDataException: Unsupported conversion from LONG to java.sql.Date
在Java程序中,尝试将LONG类型(通常是时间戳)转换为java.sql.Date类型时出现了问题。
java.sql.Date是用来表示日期的,而LONG类型通常表示时间戳,即自1970年1月1日00:00:00 GMT以来的毫秒数。
解决方法:Date date=resultSet.getDate(3);
if (date != null) {
// 定义你想要的日期时间格式
SimpleDateFormatsdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String dateString = sdf.format(date);
consumInfo.setConsumeDate(dateString);
3.Exception in thread "main" java.lang.ClassCastException:
class java.util.ArrayList cannot be cast to class JDBCFour.model.
MoboleCard (java.util.ArrayList is in module java.base of loader 'bootstrap';
java.lang.ClassCastException指出在运行时尝试将一个 ArrayList对象
强制转换为 JDBCFour.model.MoboleCard类型时失败了。
这通常发生在以下情况:
类型不匹配:你尝试将一个 ArrayList强制转换为一个不兼容的类型。
模块化问题:错误信息中提到了模块化加载器的问题,这可能涉及到
类加载器的冲突。
4.Exception in thread "main" java.lang.NumberFormatException:
Cannot parse null string
NumberFormatException是一个在尝试将字符串转换为数字时,
如果字符串不是适当的格式,就会抛出的异常:
if(records.getReal_talk_time()!=null){
System.out.println("通话时长:" + (serPackage2.getTalkTime() –
Integer.parseInt(records.getReal_talk_time())));
}else{
System.out.println("通话时长:0" + (serPackage2.getTalkTime()));
}
七、总结
这个项目我前期写的很乱,就有些逻辑没有理清,然后整个代码规范性不是很好,注释也是后期才补不上的,那个适合用数据操作的工具类出了点麻烦,然后心态有点崩,就急着赶时间,后知后觉前面的省事操作给后面造成了大麻烦,以后写一个项目必须开头就不能马虎,写规范,逻辑理清楚再下笔,后面真的会省事很多。