soso移动营业大厅(纯后端+MySQL数据库+JDBC)

一、项目需求

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

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

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

  • 超出的通话: 0.2元/分

  • 超出的短信:0.1元/条

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

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

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

二、项目需求分析

2.1 登陆

  1. 让用户输入手机号码, 密码,

  2. 根据手机号码,密码到数据库: tb_mobole_card查询

  3. 如果没有记录: 登录失败, 错误提示: 手机号码或者密码错误

  4. 如果有记录,但是状态是1(冻结): 登录失败, 错误提示: 该手机号码已冻结,请联系工作人员

  5. 登录成功, 进入到二级菜单

2.2 注册

  1. 查询所有可用卡 tb_card

  2. 查询所有的套餐类型, 用户选择套餐类型,

  3. 根据用户选择的套餐类型, 查询套餐信息

  4. 用户输入用户,密码. 输入充值金额

  5. 根据输入金额与用户选择套餐的月租比较, 输入金额小于月租, 错误提示, 用户再重新输入

  6. 如果大于等于, 往用户卡表(tb_mobole_card)插入一条记录

  7. 修改tb_card表,用户选择该手机号码的卡状态设置为不可用

  8. 往充值记录表中添加一条充值记录

  9. 显示办卡成功, 输出用户卡相关信息,以及套餐信息

  10. 跳转到一级菜单

​​​​2.3 使用soso

  1. 输入手机号码   查询到用户卡信息   查询套餐 2. 如果卡冻结状态, 无法使用嗖嗖 显示错误信息 3. 查询所有的场景, 随机一个场景进行模拟   得到场景类型,  数据

  2. 假设随机第一个场景, 通话场景, 打90分钟电话,

    剩余免费余量 = 套餐最大免费量 - 月消费当月消费量(查询月消费)

  3. 如果用户的卡的剩余免费余量 > =场景的数量, 不需要扣钱, 在月消费记录表, 当月增加使用量的值

  4. 如果用户的卡的剩余免费余量 < 场景的数量, 需要扣钱, 在月消费记录表, 当月增加使用量的值,超出的部分进行扣费, 修改的用户卡的余额

  5. 往消费记录表进行记录本次消费 消费记录表

2.4 套餐变更

  1. 查询所有的套餐类型

  2. 根据当前登录的手机号码, 查询当前用户卡信息

  3. 用户选择套餐类型,根据用户现在的套餐明细得到套餐类型

  4. 判断用户选择的套餐是否是用户卡现在套餐,如果是,提示,

  5. 如果不是,根据用户选择的套餐类型,查询对应的套餐明细

  6. 判断用户卡的余额是否满足该套餐的月租, 如果不满足, 提示

  7. 如果满足, 更换套餐, 修改用户卡信息(套餐,余额)

  8. 打印用户新套餐的明细

三、代码展示

1.系统大体结构

2.使用的jar包

commons-dbutils-1.7.jarmysql-connector-java-5.1.47.jar
提供了简化数据库操作的工具连接 MySQL 数据库的 JDBC 驱动程序

这两个 JAR 包通常用于 Java 应用程序中与数据库进行交互的过程中

hamcrest- 2.1jarjunit-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实现类

共同属性、方法进行封装:实体类的idDao接口的增删改查方法

工具类的编写:JDBCUtilDateUtil

4、IDEA Debug使用

由于项目代码量比较多功能模块较多,在程序编码中容易出bug,尤其NullPointerException

出现颇多,这时Debug可以帮我们节省大量时间,当然在日常编写也应该注意防止bug的出现。

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

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

相关文章

等离子环制作

免责声明 在您参考该博客制作等离子环前&#xff0c;请仔细阅读以下重要安全警告和免责说明。使用本文档即表示您已充分了解并同意以下条款&#xff1a; 等离子环的危险性&#xff1a;等离子环在运行时玻璃瓶身会产生高温&#xff0c;存在低温烧伤风险。任何时候都不建议用手…

C for Graphic:Sliced Circle Image

不做UI不知道&#xff0c;没想到时至今日&#xff0c;ugui居然没有sliced filled image模式&#xff0c;用circle做filled&#xff0c;不能用sliced九宫格图&#xff0c;导致每次使用这个效果必须一张新图&#xff0c;何其浪费资源。 原始功能如下&#xff1a; 我…

【C++】unordered_map,unordered_set模拟实现

unordered_map&#xff0c;unordered_set模拟实现 插入普通迭代器const迭代器unordered_map的[ ]接口实现查找修改哈希桶完整代码unordered_map完整代码unordered_set完整代码 喜欢的点赞&#xff0c;收藏&#xff0c;关注一下把&#xff01; 上一篇文章我们把unordered_map和u…

爬虫之Cookie获取:利用浏览器模拟一个cookie出来、面对反爬虫、加密的cookie的应对方法

爬虫之Cookie获取&#xff1a;利用浏览器模拟一个cookie出来、面对反爬虫、加密的cookie的应对方法 在爬虫或模拟请求时&#xff0c;特别是获取验证码的时候&#xff0c;反爬虫的网站的cookie或定期失效&#xff0c;复制出来使用是不行的为了应对这种方式&#xff0c;我们可能…

第十一站:多态练习ODU

实现动态切换 ODU.h #pragma once #include <iostream> using namespace std; #define ODU_TYPE_311_FLAG "311" #define ODU_TYPE_335_FLAG "335" enum class ODU_TYPE {ODU_TYPE_311,ODU_TYPE_335,ODU_TYPE_UNKNOW };class ODU{ public:ODU();//发…

Windows下载安装vcpkg并使用它来安装第三方库(visualstudio)

1.使用Git下载vcpkg仓库&#xff08;下载比较慢&#xff0c;个人比较喜欢打开下面网址然后用迅雷下载&#xff0c;速度飞快&#xff09; git clone "https://github.com/Microsoft/vcpkg.git"2.下载好之后解压打开文件夹&#xff0c;双击bootstrap-vcpkg.bat文件&…

中小企业如何快速融资-----股权融资的四种方式(上)

’在企业融资的多种手段中&#xff0c;股权质押融资、股权交易增值融资、股权增资扩股融资和股权的私募融资&#xff0c;逐渐成为中小企业利用股权实现融资的有效方式。随着市场体系和监管制度的完善&#xff0c;产权市场为投融资者搭建的交易平台日益成熟&#xff0c;越来越多…

ChatGPT 到 Word:使用 Writage 进行复制粘贴魔法

ChatGPT 到 Word&#xff1a;使用 Writage 进行复制粘贴魔法 写在前面Writage的使用 写在前面 随着ChatGPT的日益普及&#xff0c;越来越多的人每天依赖它来完成各种任务。无论是寻找信息、语言翻译、解决数学问题&#xff0c;还是精炼复杂的概念和文本&#xff0c;ChatGPT 都…

React里面table组件的时间轴的位置计算

如上图的时间轴位置计算 计算时间轴位置倒是容易&#xff0c;主要是React里面的antd的table组件怎么监听滚动是个问题 /*** &#xff08;月台/时间&#xff09;为150&#xff0c;时间为100&#xff0c;每个格子为120&#xff0c;120px/30分钟4px/分钟* 00:00分为250px* 00:…

muduo 网络库源码解析和使用

1. base 模块 1.1 API 1.1.1 eventfd int eventfd(unsigned int initval, int flags);&#xff08;1&#xff09;类似信号量&#xff1b;其内部保存了一个 uint64_t 计数器 count&#xff0c;使用 initval 初始化&#xff1b; &#xff08;2&#xff09;read 没有设置 EFD…

Suricata-7.0 源码分析之流表建立FlowWorker

一、什么是Flow&#xff1f; 二、Flow是怎么建立的&#xff1f; 三、Flow建立的具体过程是什么&#xff1f; 一、什么是Flow&#xff1f;   在Suricata 7.0中&#xff0c;流Flow是指所有相同五元组&#xff08;协议&#xff0c;源IP&#xff0c;目的IP&#xff0c;源端口&am…

makefile里面的变量使用,系统变量

文章目录 makefile里面的变量使用 makefile里面的变量使用 calc:add.o sub.o multi.ogcc add.o sub.o multi.o calc.cpp -o calcadd.o:add.cppgcc -c add.cpp -o add.osub.o:sub.cppgcc -c sub.cpp -o sub.omulti.o:multi.cppgcc -c multi.cpp -o multi.oclean:rm -rf *.o cal…

Linux第32步_编译ST公司的TF-A源码

正点原子STM32MP157开发板使用的CPU型号是STM32MP157DAA1&#xff0c;而开发板硬件参考了ST公司的STM32MP157 EVK开发板&#xff0c;因此我们在移植的时候需要关注“stm32mp157d-ev1”。 一、了解SDK 包 ST公司会从ARM官方下载TF-A软件包&#xff0c;然后将STM32MP1 芯片添加…

算法总结——单调栈

纵有疾风起&#xff0c;人生不言弃。本文篇幅较长&#xff0c;如有错误请不吝赐教&#xff0c;感谢支持。 文章目录 一、单调栈的定义二、单调栈的应用&#xff1a;寻找左边第一个比它小的数单调栈的思想&#xff08;重点&#xff09;&#xff1a;寻找左边第一个比它小的数的下…

Unity常用的优化技巧集锦

Unity性能优化是面试的时候经常被问道的一些内容&#xff0c;今天给大家分享一些常用的Unity的优化技巧和思路&#xff0c;方便大家遇到问题时候参考与学习。 对啦&#xff01;这里有个游戏开发交流小组里面聚集了一帮热爱学习游戏的零基础小白&#xff0c;也有一些正在从事游…

(C语言)编译和链接

前言͟͟͞͞&#x1f48c;&#xff1a;对于现在的各种编译器而言许多都是好多个功能的集成&#xff0c;那么我们的代码到底是如何去实现的呢&#xff1f;难道我们的计算机可以直接读懂我们所写的代码&#xff0c;并运行吗&#xff1f;对于很多细心的小伙伴们可能会想这样的问题…

Spring Security 优化鉴权注解:自定义鉴权注解的崭新征程

文章目录 1. 引言2. Spring Security基础2.1 Spring Security概述2.2 PreAuthorize注解 3. 自定义鉴权注解的优势3.1 业务语义更明确3.2 参数化鉴权更灵活3.3 可维护性更好 4. 实现自定义鉴权注解4.1 创建自定义注解4.2 实现鉴权逻辑4.3 注册自定义注解和逻辑4.4 使用自定义注解…

Divisibility Problem-codefordes

题目链接&#xff1a;Problem - A - Codeforces 解题思路&#xff1a; 如果 a 能被 b整除&#xff0c;就不需要进行改变&#xff0c;直接输出0&#xff0c;否则输出((a / b) 1) * b - a&#xff0c;找到最小的能被b整除的数。 下面是c代码&#xff1a; #include<iostrea…

探索JAVA神秘运行机制:揭秘JVM内存区域

目录 1. 前文回顾 2.内存区域的划分 2.1 存放类的方法区 2.2 程序计数器 2.3 Java虚拟机栈 2.4 Java堆内存 2.5 其他内存区域 3. 核心内存区域运行流程 4. 总结 1. 前文回顾 上一篇我们一起探索了Java的整体运行流程&#xff0c;类加载器以及类的加载机制&#xff0…

去了字节跳动,才知道年薪 30w 的测试工程师有这么多?

&#x1f525; 交流讨论&#xff1a;欢迎加入我们一起学习&#xff01; &#x1f525; 资源分享&#xff1a;耗时200小时精选的「软件测试」资料包 &#x1f525; 教程推荐&#xff1a;火遍全网的《软件测试》教程 &#x1f4e2;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1…