嗖嗖移动业务大厅(Java版)

news2024/12/23 1:40:20

        首先对此项目说明一下,我只完成了项目的基本需求,另外增加了一个用户反馈的功能,但是可能项目中间使用嗖嗖这个功能还有一些需要完善的地方,或者还有一些小bug,就当给大家参考一下了,希望谅解。代码我也上传到顶部了,大家可以直接下载参考一下,不需要VIP的。

目录

1. 项目需求

2. 项目使用的技术

3.项目需求分析

3.1 实体类和接口(注意:属性名和数据库字段名保持一致)

3.2 各功能效果图

1. 菜单显示页面,以及登录

2. 用户注册

3. 本月账单查询

4. 套餐余量查询

5. 打印消费清单

6. 使用嗖嗖

7. 办理退网

8.套餐变更

9. 话费充值

10.查看资费说明

11.用户反馈

4.项目模块搭建视图

5.功能实现(思路)

5.1 用户登录

5.2 用户注册

5.3 使用嗖嗖

5.4 本月账单查询

5.5 套餐余量查询

5.6 打印消费详单

 5.7 套餐变更

5.8 办理退网

 5.9 话费充值

5.10 资费说明

 5.11 用户返回

  sql文件:

6.总结


1. 项目需求

        中国移动,中国联通,中国电信是国内3大通信运营商,每个运营商都提供了不同的品牌套餐来应对不同的用户群,比如北京移动主要有全球通,神州行,动感地带等3大品牌套餐,每种套餐的内容和费用不同,嗖嗖移动是一个假定的通信运营商,提供了话痨套餐,网虫套餐,超人套餐,各种套餐所包含的服务内容及费用如下表:

品牌套餐话痨套餐网虫套餐超人套餐
通话时长(分钟)6000300
上网流量02010
短信条数(条)100050
费用(元/月)586878

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

  • 超出的通话: 0.2元/分

  • 超出的短信:0.1元/条

  • 超出的上网流量:0.01元/MB

本任务实现的"嗖嗖移动业务大厅"提供了嗖嗖移动用户的常用功能,包括新用户注册,本月账单查询,套餐余量查询,打印消费详情,套餐变更,办理退网,话费充值,查看消费记录,查看话费说明等功能.另外,还可以模拟用户通话,上网,发送短信的场景进行相应的扣费并记录消费信息.各功能介绍如下表:

菜单级别功能描述
主菜单用户登录输入正确的手机号码和密码进入二级菜单列表
主菜单用户注册录入信息并开卡,用户输入的信息包括:选择卡号,选择套餐类型,输入用户名和密码,预存话费金额(预存话费金额必须满足以支付所选套餐的一个月的费用)
主菜单使用嗖嗖输入正确的手机号码和密码之后,随机进入本号码所属套餐可以支持的一个场景,消费套餐余量或者话费余额,并记录消费信息.当话费余额不足时,抛出异常提醒用户充值
主菜单话费充值输入正确的用户名和密码之后,可为该卡号充值
主菜单资费说明提供各品牌套餐所包含的通话时长,上网流量,短信条数,月费用等
主菜单退出系统提出本系统
二级菜单本月账单查询可查询该卡号的套餐费用,实际消费金额,账户余额
二级菜单套餐余量查询可查询该卡号的套餐余量
二级菜单打印消费详情输入正确的卡号和密码后,可打印当前卡号用户的消费详单, 使用输出流把用户信息输出到文件
二级菜单套餐变更可变更为其他套餐类型,变更后话费余额需减去变更后的套餐费用,余额不足时需要给出信息提示,套餐变更后重新统计卡中实际消费数据以及当月消费金额
二级菜单办理退网输入正确的卡号和密码后,可以从已注册的号码列表中删除本号码,并退出系统

使用嗖嗖

功能分析

1) 模拟嗖嗖用户使用卡的过程,选择该功能后,输入当前卡号,通过验证后,可随机进入如下表的6个场景,要求所进入的场景的服务类型是该卡所属套餐支持的(如网虫套餐只能进入服务类型为"上网"的场景)

序号服务类型描述
0通话问候客户,谁知其如此难缠,通话90分钟
1通话询问妈妈身体状况,本地通话30分钟
2短信参与环境保护实施方案问卷调查,发送短信5条
3短信同时朋友本人已换手机号码,发送短信50条
4上网和女朋友微信视频聊天,使用流量1GB
5上网晚上手机在线追剧,一不留神睡着了,使用流量2GB

模拟消费,进入场景之后,将按场景的描述要求消费套餐余量,如果套餐余量不足,则需要按套餐外的费用规则扣费,成功消费后,添加一条消费记录

2. 项目使用的技术

  • 面向对象的思想

  • 封装,继承,多态,接口的使用

  • 异常处理的合理使用

  • 集合框架的使用

  • I/O 操作实现对文件的写

  • MySQL数据

  • JDBC操作数据库

3.项目需求分析

3.1 实体类和接口(注意:属性名和数据库字段名保持一致)

  • Card(电话号码类)

    • cardNumber 卡号

    • status 状态

  • MoboleCard(嗖嗖移动卡类)

    • card_number 卡号

    • username 用户名

    • password 密码

    • ser_package 所属套餐

    • money 账户余额

    • status 状态

  • monthlyConsumptionRecords(月消费记录类)

    • card_number 卡号

    • consum_amount 当月消费金额

    • real_talk_time 当月实际通话时长

    • real_SMS_count 当月实际发送短信条数

    • real_flow 当月实际上网流量

    • consume_date 消费日期

  • 套餐类 SerPackage

    • talk_time 通话时长

    • sms_count 短信条数

    • price 套餐月资费

    • flow 上网流量

    • type 套餐类型

  • 套餐类型类 SerPackageType

    • name 套餐名称

  • ConsumInfo(消费信息类)

    • card_number 卡号

    • type 消费类型

    • consum_data 消费数据

    • consume_date 消费日期

  • Scene(使用场景类)

    • type 场景类型

    • data 场景消费数据

    • description 场景描述

  • RechargeRecord(充值记录类)

    • amount 充值金额

    • recharge_date 充值日期

    • card_number 卡号

  • SerPackageName(资费说明类)

    • id  编号

    • name 套餐名称

    • talk_time  通话时长

    • sms_count  短信条数

    • flow 流量剩余

3.2 各功能效果图

1. 菜单显示页面,以及登录

卡号或密码错误:

卡号被禁用:

登录成功:

2. 用户注册

3. 本月账单查询

4. 套餐余量查询

5. 打印消费清单

6. 使用嗖嗖

7. 办理退网

8.套餐变更

9. 话费充值

10.查看资费说明

11.用户反馈

4.项目模块搭建视图

        这里使用的是三层架构的搭建模式,dao层,service层,view层。由于类,代码比较多,我会把源代码上传一下。

5.功能实现(思路)

5.1 用户登录

    public static void userLogin() {
        System.out.print("请输入手机卡号:");
        String cardNumber = scanner.next();
        System.out.print("请输入密码:");
        String password = scanner.next();
        List<MoboleCard> moboleCards = moboleCardService.userLogin(cardNumber, password);
        if (moboleCards != null && !moboleCards.isEmpty()) {
            moboleCard = moboleCards.get(0);
            if (moboleCard.getStatus() == 1) {
                System.out.println("【友情提示】:该卡号已被禁用");
            } else {
                System.out.println("【友情提示】:登录成功");
                showSecondMenu();
            }
        } else {
            System.out.println("【友情提示】:卡号或者密码错误");
        }
    }

5.2 用户注册

    public static void userRegister() {
        System.out.println("*****可选择的卡号*****");
        List<Card> cards = cardService.queryByCard();
        for (int i = 0; i < cards.size(); i++) {
            if (cards.get(i).getStatus() == 0) {
                System.out.print(index + "." + cards.get(i).getCardNumber() + "\t");
                availableCards.add(cards.get(i));
                if (index % 3 == 0) {
                    System.out.println();
                }
                index++;
            }
        }
        if (index % 3 != 1) {
            System.out.println();
        }

        System.out.println();

        System.out.print("请选择你的卡号:");
        int cardIndex = scanner.nextInt();
        Card selectedCard = availableCards.get(cardIndex - 1);

        // 显示套餐类型
        SerPackageTypeService serPackageTypeService = new SerPackageTypeServiceImpl();
        List<SerPackageType> serPackageTypes = serPackageTypeService.querySerPackageType();
        for (int i = 0; i < serPackageTypes.size(); i++) {
            System.out.print((i + 1) + "." + serPackageTypes.get(i).getName() + "\t");
        }
        System.out.print("请选择套餐:");
        int serPackageTypeIndex = scanner.nextInt();

        // 根据选择的编号给id复制得到对应的套餐信息
        int id = 0;
        String serName = "";
        if (serPackageTypes.get(serPackageTypeIndex - 1).getName().equals("话痨套餐")) {
            id = 1;
            serName = "话痨套餐";
        } else if (serPackageTypes.get(serPackageTypeIndex - 1).getName().equals("网虫套餐")) {
            id = 2;
            serName = "网虫套餐";
        } else if (serPackageTypes.get(serPackageTypeIndex - 1).getName().equals("超人套餐")) {
            id = 3;
            serName = "超人套餐";
        }

        // 得到套餐的具体信息
        List<SerPackage> serPackages = serPackageService.queryByType(id);
        SerPackage serPackage = serPackages.get(0);

        System.out.print("请输入姓名:");
        String username = scanner.next();
        System.out.print("请输入密码:");
        String password = scanner.next();

        double amount = 0;
        boolean flag = true;

        // 判断预存金额是否大于套餐资费
        while (flag) {
            System.out.print("请输入预存话费金额:");
            amount = scanner.nextDouble();
            if (amount < serPackage.getPrice()) {
                System.out.print("您预存话费不足以支付本月套餐资费,请重新输入!\n");
            } else if (amount > serPackage.getPrice()) {
                flag = false;
            }
        }

        // 创建MoboleCard对象并设置属性
        MoboleCard moboleCard = new MoboleCard();
        moboleCard.setCard_number(selectedCard.getCardNumber());
        moboleCard.setUsername(username);
        moboleCard.setPassword(password);
        moboleCard.setSer_package(id);
        moboleCard.setMoney(amount - serPackage.getPrice());
        moboleCard.setStatus(0);

        // 将MoboleCard添加到用户信息数据库
        moboleCardService.executeUpdate(moboleCard);

        // 修改tb_card表的status状态
        selectedCard.setStatus(1);
        cardService.updateCardStatus(selectedCard.getStatus(), selectedCard.getCardNumber());

        // 往充值记录表里面添加一条充值记录
        RechargeRecord rechargeRecord = new RechargeRecord();
        rechargeRecord.setAmount(amount);
        rechargeRecord.setRecharge_date(new Date());
        rechargeRecord.setCard_number(selectedCard.getCardNumber());
        recordService.insertRecharge(rechargeRecord);

        System.out.print("【友情提示】:注册成功!");
        System.out.println("卡号:" + selectedCard.getCardNumber() + ",用户名:" + moboleCard.getUsername() + ",当前余额:" + moboleCard.getMoney());
        System.out.println(serName + "通话时长:" + serPackage.getTalk_time() + "分钟/月");
    }

5.3 使用嗖嗖

public static void userSoSo() {
        System.out.print("请输入手机卡号: ");
        String cardNumber = scanner.next();
        List<MoboleCard> moboleCards = moboleCardService.findByCardNumber(cardNumber);
        MoboleCard moboleCard = moboleCards.get(0);
        if (moboleCard == null || moboleCard.getStatus() == 1) {
            System.out.println("【友情提示】:卡号不存在或已被禁用");
            return;
        }

        // 获取用户套餐类型
        SerPackage serPackage = serPackageService.queryPackageById(moboleCard.getSer_package()).get(0);
        String serviceType = "";
        switch (serPackage.getType()) {
            case 1:
                serviceType = "通话";
                break;
            case 2:
                serviceType = "短信";
                break;
            case 3:
                serviceType = "上网";
                break;
        }

        // 根据套餐类型获取可用场景
        List<Scene> scenes = sceneService.queryScene();
        List<Scene> availableScenes = new ArrayList<>();
        for (Scene scene : scenes) {
            if (scene.getType().equals(serviceType)) {
                availableScenes.add(scene);
            }
        }

        // 判断是否有场景描述
        if (availableScenes.isEmpty()) {
            System.out.println("【友情提示】:没有可用的" + serviceType + "场景");
            return;
        }

        // 随机选择一个场景
        Scene selectedScene = availableScenes.get(new Random().nextInt(availableScenes.size()));

        // 查询或添加记录到tb_monthly_consumption_records表
        List<MonthlyConsumptionRecords> recordsList = mcRecordService.queryMonRecord(cardNumber);
        MonthlyConsumptionRecords records = null;

        double amount = 0;
        if (!recordsList.isEmpty()) {
            records = recordsList.get(0); // 根据id得到月消费记录
        } else {
            // 如果不存在记录,创建并添加新记录
            records = new MonthlyConsumptionRecords();
            records.setCard_number(cardNumber);
            records.setConsum_amount(0);
            records.setReal_talk_time(0);
            records.setReal_SMS_count(0);
            records.setReal_flow(0);
            records.setConsume_date(new Date());
            mcRecordService.insertMonRecord(records);
        }

        // 更新消费记录
        switch (selectedScene.getType()) {
            case "通话":
                double newTalkTime = records.getReal_talk_time() + selectedScene.getData();
                if (records.getReal_talk_time() > serPackage.getTalk_time()) {
                    amount = selectedScene.getData() * 0.2;
                } else if (newTalkTime > serPackage.getTalk_time()) {
                    amount = (newTalkTime - serPackage.getTalk_time()) * 0.2;
                }
                records.setReal_talk_time((int) newTalkTime);
                break;
            case "短信":
                int newSMSCount = records.getReal_SMS_count() + selectedScene.getData();
                if (records.getReal_SMS_count() > serPackage.getSms_count()) {
                    amount = selectedScene.getData() * 0.2;
                } else if (newSMSCount > serPackage.getSms_count()) {
                    amount = (newSMSCount - serPackage.getSms_count()) * 0.1;
                }
                records.setReal_SMS_count(newSMSCount);
                break;
            case "上网":
                double newFlow = records.getReal_flow() + selectedScene.getData();
                if (records.getReal_flow() > serPackage.getFlow()) {
                    amount = selectedScene.getData() * 0.2;
                } else if (newFlow > serPackage.getFlow()) {
                    amount = (newFlow - serPackage.getFlow()) * 0.01;
                }
                records.setReal_flow((int) newFlow);
                break;
        }

        // 更新月消费记录
        records.setConsum_amount((records.getConsum_amount() + amount));
        mcRecordService.updateMonRecord(records);

        // 添加数据到consuminfo表中
        ConsumInfo consumInfo = new ConsumInfo();
        consumInfo.setCard_number(cardNumber);
        consumInfo.setType(selectedScene.getType());
        consumInfo.setConsum_data(selectedScene.getData());
        consumInfo.setConsume_date(new Date());
        infoService.insertConsum(consumInfo);

        // 更新用户余额
        moboleCard.setMoney(moboleCard.getMoney() - amount);
        moboleCardService.updateMoney(moboleCard.getMoney(), cardNumber);

        System.out.println("【友情提示】:" + selectedScene.getDescription());
    }

5.4 本月账单查询

public static void monRecord() {
        System.out.println("********本月账单查询********");
        List<MonthlyConsumptionRecords> monRecord = mcRecordService.queryMonRecord(moboleCard.getCard_number());
        double price = 0;
        if (monRecord.isEmpty()) {
            System.out.println("【友情提示】:此卡号暂无月消费记录");
        } else {
            MonthlyConsumptionRecords records = monRecord.get(0);
            if (moboleCard.getSer_package() == 1) {
                price = 58;
            } else if (moboleCard.getSer_package() == 2) {
                price = 68;
            } else if (moboleCard.getSer_package() == 3) {
                price = 78;
            }
            System.out.println("您的卡号:" + moboleCard.getCard_number() + ",当月账单:");
            System.out.println("套餐资费:" + price + "元");
            System.out.println("合计:" + (price + records.getConsum_amount()) + "元");
            if (moboleCard.getMoney() <= 0) {
                System.out.println("账户余额:" + 0 + "元");
            } else {
                System.out.println("账户余额:" + moboleCard.getMoney() + "元");
            }
        }
    }

5.5 套餐余量查询

public static void packageMargin() {
        System.out.println("******套餐余量查询******");
        List<MonthlyConsumptionRecords> monRecord = mcRecordService.queryMonRecord(moboleCard.getCard_number());
        List<SerPackage> serPackages = serPackageService.queryPackageById(moboleCard.getSer_package());
        SerPackage serPackage = serPackages.get(0);
        if (monRecord.isEmpty()) {
            System.out.println("【友情提示】:此卡号暂无记录");
        } else {
            MonthlyConsumptionRecords records = monRecord.get(0);
            System.out.println("您的卡号是:" + moboleCard.getCard_number() + ",套餐内剩余:");
            System.out.println("通话时长:" + (serPackage.getTalk_time() - records.getReal_talk_time()) + "分钟");
            System.out.println("短信条数:" + (serPackage.getSms_count() - records.getReal_SMS_count()) + "条");
            System.out.println("上网流量:" + (serPackage.getFlow() - records.getReal_flow()) + "GB");
        }
    }

5.6 打印消费详单

public static void conDetails() {
        System.out.println("请输入本年需要查询的月份(1-12):");
        int month = scanner.nextInt();
        if (month < 1 || month > 12) {
            System.out.println("没有这个月份,请重新输入:");
            return;
        }
        List<ConsumInfo> consumInfos = infoService.queryConsumInfo(moboleCard.getCard_number(), month);
        if (consumInfos.isEmpty()) {
            System.out.println("【友情提示】:对不起,不存在本卡号" + month + "月消费记录");
        } else {
            System.out.println("序号\t类型\t消费数据\t日期");
            for (int i = 0; i < consumInfos.size(); i++) {
                ConsumInfo consumInfo = consumInfos.get(i);
                System.out.println((i + 1) + "\t" + consumInfo.getType() + "\t" + consumInfo.getConsum_data() + "\t" + consumInfo.getConsume_date());
            }
        }
    }

 5.7 套餐变更

public static void packageCharge() {
        System.out.println("******套餐变更******");
        SerPackageTypeService serPackageTypeService = new SerPackageTypeServiceImpl();
        List<SerPackageType> serPackageTypes = serPackageTypeService.querySerPackageType();
        for (int i = 0; i < serPackageTypes.size(); i++) {
            System.out.print((i + 1) + "." + serPackageTypes.get(i).getName() + "\t");
        }
        System.out.print("请选择套餐:");
        int serPackageTypeIndex = scanner.nextInt();

        // 根据卡号得到具体的用户信息(ser_package)
        List<MoboleCard> moboleCards = moboleCardService.findByCardNumber(moboleCard.getCard_number());
        MoboleCard moblecards = moboleCards.get(0);

        // 根据(ser_package)得到具体的套餐信息
        List<SerPackage> serPackages = serPackageService.queryPackageById(serPackageTypeIndex);
        SerPackage serPackage = serPackages.get(0);

        String SerType = "";
        switch (serPackage.getType()) {
            case 1:
                SerType = "话痨套餐";
                break;
            case 2:
                SerType = "网虫套餐";
                break;
            case 3:
                SerType = "超人套餐";
                break;
        }

        if (serPackageTypeIndex < 1 || serPackageTypeIndex > 3) {
            System.out.println("【友情提示】:所选已超出套餐范围!");
        } else {
            if (moblecards.getSer_package() == serPackageTypeIndex) {
                System.out.println("【友情提示】:您已是该套餐的用户,无需更换!");
            } else {
                if (moblecards.getMoney() < serPackage.getPrice()) {
                    System.out.println("【友情提示】:对不起,您的余额不足以支付新套餐本月资费,请充值后办理变更套餐业务!");
                } else {
                    moboleCardService.chargeSerType(serPackageTypeIndex, moboleCard.getCard_number());
                    List<SerPackage> packages = serPackageService.queryPackageById(serPackageTypeIndex);
                    SerPackage aPackage = packages.get(0);
                    int count = mcRecordService.deleteMonRecord(moboleCard.getCard_number());
                    if (count > 0) {
                        System.out.println("【友情提示】:更换套餐成功!" + SerType + ":通话时长:" + aPackage.getTalk_time() + "分钟/月,短信条数:" + aPackage.getSms_count() + "条/月,上网流量:" + aPackage.getFlow() + "GB/月,月租:" + aPackage.getPrice() + "元/月");
                    }
                }
            }
        }
    }

5.8 办理退网

public static void handleNet() {
        System.out.println("******办理退网******");
        int handledNet = moboleCardService.handleNet(moboleCard.getCard_number());
        if (handledNet > 0) {
            recordService.deleteRecharge(moboleCard.getCard_number());
            mcRecordService.deleteMonRecord(moboleCard.getCard_number());
            infoService.deleteConsumInfo(moboleCard.getCard_number());
            cardService.updateCardStatus(0, moboleCard.getCard_number());
            System.out.println("【友情提示】:卡号" + moboleCard.getCard_number() + "办理退网成功!");
        } else {
            System.out.println("【友情提示】:退网失败,请检查卡号是否正确!");
        }
    }

 5.9 话费充值

public static void recharge() {
        System.out.println("*******话费充值*******");
        System.out.print("请输入要充值卡号:");
        String cardNumber = scanner.next();
        System.out.print("请输入要充值的金额:");
        double amount = scanner.nextDouble();

        List<MoboleCard> byCardNumber = moboleCardService.findByCardNumber(cardNumber);
        MoboleCard moboleCard = byCardNumber.get(0);
        if (moboleCard != null) {
            moboleCard.setCard_number(cardNumber);
            moboleCard.setMoney(moboleCard.getMoney() + amount);
            moboleCardService.updateBalance(moboleCard);

            // 添加充值记录
            RechargeRecord rechargeRecord = new RechargeRecord();
            rechargeRecord.setAmount(amount);
            rechargeRecord.setRecharge_date(new Date());
            rechargeRecord.setCard_number(cardNumber);
            recordService.insertRecharge(rechargeRecord);

            System.out.println("【友情提示】:充值成功,卡上余额 :" + moboleCard.getMoney() + "元");
        } else {
            System.out.println("【友情提示】:充值失败,请检查卡号是否正确!");
        }
    }

5.10 资费说明

public static void tariffDes() {
        System.out.println("******套餐说明******");
        List<SerPackageName> serPackageNames = serPackageService.querySerPackages();
        System.out.println("序号\t套餐名称\t通话时长(分/月)\t短信条数(条/月)\t上网流量(GB/月)");
        for (SerPackageName serPackageName : serPackageNames) {
            System.out.println(serPackageName.getId() + "\t" + serPackageName.getName() + "\t\t" + serPackageName.getTalk_time() + "\t\t\t" + serPackageName.getSms_count() + "\t\t\t\t" + serPackageName.getFlow());
        }
    }

 5.11 用户返回

public static void socket() throws Exception {
        Scanner scanner = new Scanner(System.in);

        // 1.创建socket对象
        Socket socket = new Socket("127.0.0.1", 12345);

        // 2.创建 BufferedReader 从服务器接收文本数据
        BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));

        // 3.创建 PrintWriter 向服务器发送文本数据,并设置为自动刷新
        PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
        System.out.println("已连接到服务器");

        String inputLine;
        // 4.循环读取用户的输入直到用户输入 "END"
        while (scanner.hasNextLine()) {
            inputLine = scanner.nextLine();
            out.println(inputLine); // 发送数据

            if ("END".equalsIgnoreCase(inputLine)) {
                System.out.println("发送用户反馈结束请求");
                // 退出循环
                break;
            }

            // 5.接收服务器响应
            String response = in.readLine();

            if (response != null) {
                System.out.println("服务器响应:" + response);
            }
        }

        // 调用主菜单
        showMainMenu();

        if (in != null) {
            in.close();
        }
        if (out != null) {
            out.close();
        }
        if (socket != null) {
            socket.close();
        }
    }
}
public class Server {
    private static final String FILE_NAME = "feedback.txt";

    public static void main(String[] args) throws Exception {

        // 1.创建 ServerSocket 对象
        ServerSocket serverSocket = new ServerSocket(12345);
        System.out.println("服务器启动,端口:" + 12345);

        try (Socket clientSocket = serverSocket.accept()) { // 使用 try-with-resources 自动关闭资源
            System.out.println("接收到客户端连接");

            // 处理客户端请求
            handleClient(clientSocket);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private static void handleClient(Socket clientSocket) throws Exception {
        // 创建 BufferedReader 用于读取客户端发送的文本数据
        BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));

        // 创建 BufferedWriter 用于向客户端发送文本数据
        BufferedWriter out = new BufferedWriter(new OutputStreamWriter(clientSocket.getOutputStream()));
        String inputLine;
        while ((inputLine = in.readLine()) != null) {
            // 循环持续读取客户端发送的消息
            if ("END".equalsIgnoreCase(inputLine)) {
                System.out.println("客户端请求结束对话");
                out.write("对话结束,感谢您的反馈。");
                out.newLine();
                out.flush();
                break;
            } else {
                // 将数据保存到文件
                BufferedWriter fileOut = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(FILE_NAME, true)));
                fileOut.write(inputLine);
                fileOut.newLine();
                fileOut.flush();

                System.out.println("接收到用户的反馈:" + inputLine);
                // 发送确认消息给客户端
                out.write("已收到您的反馈:" + inputLine);
                out.newLine();
                out.flush();
            }
        }
    }
}

  sql文件:

/*
SQLyog Ultimate v12.08 (64 bit)
MySQL - 5.7.20 : Database - soso
*********************************************************************
*/


/*!40101 SET NAMES utf8 */;

/*!40101 SET SQL_MODE=''*/;

/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
CREATE DATABASE /*!32312 IF NOT EXISTS*/`soso` /*!40100 DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_bin */;

USE `soso`;

/*Table structure for table `tb_card` */

DROP TABLE IF EXISTS `tb_card`;

CREATE TABLE `tb_card` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
  `cardNumber` char(11) COLLATE utf8mb4_bin NOT NULL COMMENT '手机号码',
  `status` int(1) DEFAULT '0' COMMENT '状态: 0:可用 1:禁用',
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_card` (`cardNumber`)
) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;

/*Data for the table `tb_card` */

insert  into `tb_card`(`id`,`cardNumber`,`status`) values (1,'13652363333',1),(2,'15812346677',1),(3,'18890985868',1),(4,'13677478866',1),(5,'13666557788',1),(6,'13612476521',0),(7,'13609087438',0),(8,'13689011047',0),(9,'13698674344',0),(10,'13678239812',0),(11,'13677411438',0);

/*Table structure for table `tb_consuminfo` */

DROP TABLE IF EXISTS `tb_consuminfo`;

CREATE TABLE `tb_consuminfo` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
  `card_number` char(11) COLLATE utf8mb4_bin DEFAULT NULL COMMENT '手机号码',
  `type` varchar(50) COLLATE utf8mb4_bin DEFAULT NULL COMMENT '消费类型',
  `consum_data` int(11) DEFAULT NULL COMMENT '消费数据',
  `consume_date` datetime DEFAULT NULL COMMENT ' 消费日期',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=14 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;

/*Data for the table `tb_consuminfo` */

insert  into `tb_consuminfo`(`id`,`card_number`,`type`,`consum_data`,`consume_date`) values (6,'15812346677','通话',90,'2022-09-13 22:10:44'),(7,'15812346677','短信',5,'2022-09-13 22:12:04'),(12,'18890985868','短信',5,'2022-09-14 11:06:54'),(13,'13652363333','短信',50,'2022-09-14 11:15:18');

/*Table structure for table `tb_mobole_card` */

DROP TABLE IF EXISTS `tb_mobole_card`;

CREATE TABLE `tb_mobole_card` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
  `card_number` char(11) COLLATE utf8mb4_bin NOT NULL COMMENT '手机号码',
  `username` varchar(20) COLLATE utf8mb4_bin NOT NULL COMMENT '用户名',
  `password` varchar(20) COLLATE utf8mb4_bin NOT NULL COMMENT '密码',
  `ser_package` int(11) NOT NULL COMMENT '所属套餐',
  `money` double(7,2) DEFAULT NULL COMMENT '账户余额',
  `status` int(1) DEFAULT '0' COMMENT '状态:0:正常 1:冻结',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;

/*Data for the table `tb_mobole_card` */

insert  into `tb_mobole_card`(`id`,`card_number`,`username`,`password`,`ser_package`,`money`,`status`) values (1,'13677478866','zhangsan','123',1,10.00,0),(2,'13666557788','lisi','123456',3,10.00,1),(6,'13652363333','张三','123',2,21.00,0),(7,'15812346677','李四','123456',1,10.00,0),(8,'18890985868','王五','123',2,31.50,0);

/*Table structure for table `tb_monthly_consumption_records` */

DROP TABLE IF EXISTS `tb_monthly_consumption_records`;

CREATE TABLE `tb_monthly_consumption_records` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
  `card_number` char(11) COLLATE utf8mb4_bin NOT NULL COMMENT '手机号码',
  `consum_amount` double(7,2) DEFAULT '0.00' COMMENT '当月消费金额',
  `real_talk_time` int(11) DEFAULT '0' COMMENT '当月实际通话时长(单位:分钟)',
  `real_SMS_count` int(11) DEFAULT '0' COMMENT '当月实际发送短信条数',
  `real_flow` int(11) DEFAULT '0' COMMENT '当月实际上网流量',
  `consume_date` date DEFAULT NULL COMMENT '日期',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=19 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;

/*Data for the table `tb_monthly_consumption_records` */

insert  into `tb_monthly_consumption_records`(`id`,`card_number`,`consum_amount`,`real_talk_time`,`real_SMS_count`,`real_flow`,`consume_date`) values (1,'13677478866',0.00,590,80,0,'2022-09-01'),(12,'15812346677',0.00,90,5,0,'2022-09-01'),(13,'13677478866',10.00,650,50,0,'2022-08-01'),(17,'18890985868',0.00,0,0,0,'2022-09-01'),(18,'13652363333',5.00,0,50,0,'2022-09-01');

/*Table structure for table `tb_recharge_record` */

DROP TABLE IF EXISTS `tb_recharge_record`;

CREATE TABLE `tb_recharge_record` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
  `amount` double(7,2) NOT NULL COMMENT '充值金额',
  `recharge_date` datetime DEFAULT NULL COMMENT '充值时间',
  `card_number` char(11) COLLATE utf8mb4_bin NOT NULL COMMENT '手机号',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;

/*Data for the table `tb_recharge_record` */

insert  into `tb_recharge_record`(`id`,`amount`,`recharge_date`,`card_number`) values (1,50.00,'2022-08-30 18:19:28','13666557788'),(5,100.00,'2022-09-09 17:04:05','13652363333'),(6,100.00,'2022-09-09 17:10:05','15812346677'),(7,100.00,'2022-09-13 15:51:50','18890985868');

/*Table structure for table `tb_scene` */

DROP TABLE IF EXISTS `tb_scene`;

CREATE TABLE `tb_scene` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
  `type` varchar(30) COLLATE utf8mb4_bin DEFAULT NULL COMMENT '场景类型',
  `data` int(11) DEFAULT NULL COMMENT '场景消费数据',
  `description` varchar(200) COLLATE utf8mb4_bin DEFAULT NULL COMMENT '场景描述',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;

/*Data for the table `tb_scene` */

insert  into `tb_scene`(`id`,`type`,`data`,`description`) values (1,'通话',90,'问候客户,谁知其如此难缠,通话90分钟'),(2,'通话',30,'询问妈妈身体状况,本地通话30分钟'),(3,'短信',5,'参与环境保护实施方案问卷调查,发送短信5条'),(4,'短信',50,'告诉朋友本人已换手机号码,发送短信50条'),(5,'上网',1024,'和女朋友微信视频聊天,使用流量1GB'),(6,'上网',2048,'晚上手机在线追剧,一不留神睡着了,使用流量2GB');

/*Table structure for table `tb_serpackage` */

DROP TABLE IF EXISTS `tb_serpackage`;

CREATE TABLE `tb_serpackage` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
  `talk_time` int(11) DEFAULT NULL COMMENT '通话时长',
  `sms_count` int(11) DEFAULT NULL COMMENT '短信条数',
  `price` double(7,2) DEFAULT NULL COMMENT '套餐月资费',
  `flow` int(11) DEFAULT NULL COMMENT '上网流量',
  `type` int(11) DEFAULT NULL COMMENT '套餐类型',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;

/*Data for the table `tb_serpackage` */

insert  into `tb_serpackage`(`id`,`talk_time`,`sms_count`,`price`,`flow`,`type`) values (1,600,100,58.00,0,1),(2,0,0,68.00,20480,2),(3,300,50,78.00,10240,3);

/*Table structure for table `tb_serpackage_type` */

DROP TABLE IF EXISTS `tb_serpackage_type`;

CREATE TABLE `tb_serpackage_type` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
  `name` varchar(50) COLLATE utf8mb4_bin NOT NULL COMMENT '套餐类型名称',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;

/*Data for the table `tb_serpackage_type` */

insert  into `tb_serpackage_type`(`id`,`name`) values (1,'话痨套餐'),(2,'网虫套餐'),(3,'超人套餐');

/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;

6.总结

        以上就是嗖嗖移动大厅的主要功能的实现思路,可能还存在一些问题或者没完善的也没有充分考虑到的一些小逻辑,仅供大家参考一下思路,希望对大家有用,代码我也会打包放在这里,有需要的可以参考一下。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1975112.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

数据结构初阶之排序(下)

前言 上一期内容中我们了解了基本排序中的插入与选择排序&#xff0c;今天我将为大家带来剩下的几种排序算法 快速排序 快速排序是Hoare于1962年提出的⼀种⼆叉树结构的交换排序⽅法&#xff0c;其基本思想为&#xff1a;任取待排序元素序列中的某元素作为基准值&#xff0c;…

ARM 架构与技术综述

目录 认识 ARM ARM 发展历史 指令集 ARM 公司产品分类 ARM 体系结构 数据类型约定 处理器的 32 位和 64 位含义 指令集 ARM 处理器的工作模式 CPU (内核) 组成 寄存器 时钟 认识 ARM ARM 可以指&#xff1a; 一家公司。一种技术。一系列处理器。 架构&#xff1a;A…

定时任务框架 xxl-job

&#x1f353; 简介&#xff1a;java系列技术分享(&#x1f449;持续更新中…&#x1f525;) &#x1f353; 初衷:一起学习、一起进步、坚持不懈 &#x1f353; 如果文章内容有误与您的想法不一致,欢迎大家在评论区指正&#x1f64f; &#x1f353; 希望这篇文章对你有所帮助,欢…

算法通关:015:最小栈

文章目录 题目思路主要代码问题总结有时候提交不了可能是方法名的问题 题目 leetcode152 思路 主要代码 同一个思路&#xff0c;法一是用栈实现&#xff0c;法二是用数组实现 /*** Author: ggdpzhk* CreateTime: 2024-08-03* 最小栈 155*/ import java.util.Stack;public…

fonttools - 操作字体

文章目录 一、关于 fonttools二、安装贡献测试可选依赖 三、如何制作新版本四、工具五、库 一、关于 fonttools fontTools是一个用于操作字体的库&#xff0c;用Python编写。这 项目包括TTX工具&#xff0c;可以转换TrueType和OpenType XML文本格式之间的字体&#xff0c;也称…

cesium加载wms与arcgis服务

1、加载geoserver的wms服务 2、加载arcgis服务

idea使用free流程,2024idea、2023idea都可以安装免费使用

1.先到官网下载&#xff0c;这里选择win系统的&#xff0c;点击下图的.exe https://www.jetbrains.com/idea/download/?sectionwindows 2.下载好后基本上就是一直点击“下一步”到直到安装好&#xff0c;安装好后先打开软件后关闭退出 3.下载配配套资料 链接: https://pan.ba…

C++计算二维坐标欧式距离

1.何为欧式距离 在欧几里得空间中&#xff0c;点x (x1,…,xn)和 y (y1,…,yn)之间的欧氏距离为 2.C实现计算两点欧氏距离 point1(x1, y1): (1,3) point2(x2, y2): (2,6) #include <iostream> #include <cmath>using namespace std;int main() {struct point {…

【Android驱动08】Sensor传感器框架以及驱动移植和调试方法(Kernel层部分)

接续上一节&#xff0c;本文主要介绍驱动部分的客制化 1&#xff0c; hardware层 通过系统调用open,read,write对sys/class/sensor/m_acc_misc读写操作 路径&#xff1a;vendor/mediatek/proprietary/hardware/sensor/sensors-1.0/Acceleration.cpp 直接操作/sys/class/sensor…

pytorch基础模块:Tensorboard、Dataset、Transforms、Dataloader

Tensorboard、Dataset、Transforms、Dataloader 该文档主要参考【土堆】的视频教程&#xff1a;pytorch入门教程–土堆 一、Tensorboard 安装tensorboard&#xff1a;pip install tensorboard 使用步骤&#xff1a; 引入相关库&#xff1a;from torch.utils.tensorboard i…

DDL、DML、DQL、DCL具体实例与关系

一、DDL、DCL、DML、DQL 通过二维表的形式&#xff0c;更加清晰直观的学习、对比其关系。 DDL DCL DML DQL 英文释义 Data Defination Language 数据库定义语言 Data Control Language 数据库控制语言 Data Manipulation Language 数据操作语言 Data Query Language 数…

PyMuPDF-Guide

本文翻译整理自&#xff1a; https://pymupdf.readthedocs.io/en/latest/how-to-open-a-file.html 文章目录 一、打开文件1、支持的文件类型2、如何打开文件打开一个错误的文件扩展名 3、打开远程文件从云服务打开文件 4、以文本形式打开文件例子打开一个C#文件打开一个XML文件…

按摩行业的革新者:从挑战到辉煌的转型之路

在时代浪潮的推动下&#xff0c;一个勇于创新的团队于2018年毅然踏入按摩服务市场&#xff0c;创立了一家颠覆传统的按摩店。面对行业内的激烈竞争与瞬息万变的市场环境&#xff0c;他们凭借独树一帜的经营模式和不懈的努力&#xff0c;不仅稳固了市场地位&#xff0c;更在去年…

使用Greenhills生成Lib并使用Lib的两种方法

文章目录 前言GHS工程生成libmake方式生成liblib的使用总结 前言 在软件交付过程&#xff0c;如果不交付源代码&#xff0c;可以将源码编译之后生成lib文件提供给客户。本文介绍GHS中生成lib的两种方法&#xff0c;一种基于GHS工程&#xff0c;一种基于make文件。生成完lib后的…

uniapp自定义网格布局用于选择金额、输入框焦点事件以及点击逻辑实战

样式 <view class="withdraw-section"><text class="section-title">提现金额</text><view class="amount-options"><view v-for="(item, index) in list" :key="index" class="amount-opt…

使用Leaflet进行船舶航行警告区域绘制实战

目录 前言 一、坐标格式转换 1、数据初认识 2、将区域分割成多个点 3、数据转换 4、数据转换调用 二、WebGIS展示空间位置信息 1、定义底图 2、Polygon的可视化 3、实际效果 三、总结 前言 通常而言&#xff0c;海事部门如海事局&#xff0c;通常会在所述的管辖区域内…

Java从入门到精通(十五) ~ IO流

晚上好&#xff0c;愿这深深的夜色给你带来安宁&#xff0c;让温馨的夜晚抚平你一天的疲惫&#xff0c;美好的梦想在这个寂静的夜晚悄悄成长。 目录 前言 什么是IO流&#xff1f; IO流的作用&#xff1a; 一、基础流 1. 字节流 1.1 字节输入流 FileInputStream 1.2 字节…

找到第一个满足条件的格值

表格第1列是科目&#xff0c;之后几列是每次的考试成绩&#xff0c;顺序排列。 ABCDE1Art03.676.27.82History3.786.217.29.83Maths5.66.36.68.9 要求根据指定的科目和成绩&#xff0c;找到该科目中大于等于该成绩的第1个格值&#xff0c;比如参数是Maths、6.5时&#xff0c;…

element-ui简单入门1.0.0

第一篇&#xff1a;table标签速用 总结&#xff1a;建楼前&#xff0c;先打地基<el-table></el-table>&#xff0c;打完地基看高度&#xff0c;一层楼4米&#xff0c;80米20个<el-table-column></el-table-column>&#xff0c;每次楼的名字是label 第…

[翻译] Asset Administration Shells

关于资产管理外壳 (AAS) 资产管理外壳 (AAS) 是工业4.0中的关键概念&#xff0c;为产品、资源&#xff08;如设备&#xff09;和过程提供信息隐藏和更高层次的抽象。AAS 是技术和设备无关的机器可读描述&#xff0c;提供访问资产属性和功能的统一接口。与现有解决方案不同&…