- Java锁的逻辑(结合对象头和ObjectMonitor)
- 还在用饼状图?来瞧瞧这些炫酷的百分比可视化新图形(附代码实现)⛵
- 自动注册实体类到EntityFrameworkCore上下文,并适配ABP及ABPVNext
- 基于Sklearn机器学习代码实战
对于加油卡而言,圈存是将 用户账户 中已存入的资金划转到所持的加油卡上后方可使用。通俗一点的说法就是您在网点把钱存入主卡中,再分配到下面的副卡,由于副卡都在使用车辆的驾驶员手中,需要在加油的时候在加油站让加油站员工划一下即可,就是所谓的圈存.
如下图所示,圈存机圈存的主要流程就是:插卡→输入密码→按圈存→可选的小票操作→退卡.
已经了解了圈存业务大致内容。现在使用Java基础课程所学习的知识,模拟开发一下这个圈存系统的功能。因为是模拟开发,所以有些细节会相应的做些调整.
比如:
对此,我们给系统设计两个功能体系,一个是用户的圈存查询功能,一个是管理员的后台核心管理功能.
整体流程图概览如下:
【细节说明】
油卡需要的属性的:卡号,用户姓名 userName ,卡密码,油卡余额,积分,账户余额 。
cardId
:卡号不能位空,长度9位的数值,首位不为0。 password
:需要验证密码长度,进行空值判断,但此处不做过多限制,只需长度大于0就好了,以及管理员密码可以自己直接设置,此处我直接设置为”1“。 money
:油卡中可以用于加油的余额。浮点类型 integral
:使用油卡获得的积分,由管理员进行充值,整型 wallet
:个人账户的余额,是用来充值油卡余额的钱,浮点型 圈存系统需要的成员变量:指定的系统的账号 sysCardId 和密码 sysPassword ,方便使用;当前登入的账户对象 curUserCard ;存储用户卡信息的集合 fuelCardList 。
圈存系统需要加入:控制台输入对象用于交互,随机数对象用于生成卡号。设置一个有参构造,参数是 duelCardList ,用于测试;同时设置一个无参构造,用于生成对象,方便调用.
涉及到的主要方法:
主页面:用于提示用户操作,输入账号密码等 。
管理员功能界面:查询所有卡片信息,新增油卡,账户余额充值,积分充值.
用户功能:圈存功能和查询功能 。
测试类只需要加入main方法,然后声明圈存系统类的对象,通过该对象调用启动方法,作为程序的入口。可以设计一个用户对象,方便测试时使用,不用每次测试都登入管理员账户新增用户.
代码如下:
package org.example;
public class FuelCard {
// 分析: 需要哪些属性:
// id: 唯一性,卡号 (cardId)
private String cardId;
// 姓名 userName
private String userName;
// 密码 password
private String password;
// 钱(油卡里的金额) 带小数 money (amount)
private double money;
// 积分 Integral (只用整数,1个积分1块钱)
private int integral;
// 账户的金额(钱包的金额) wallet 带小数
private double wallet;
public FuelCard() {
}
public FuelCard(String cardId, String userName, String password, double money, int integral, double wallet) {
this.cardId = cardId;
this.userName = userName;
this.password = password;
this.money = money;
this.integral = integral;
this.wallet = wallet;
}
public String getCardId() {
return cardId;
}
public void setCardId(String cardId) {
this.cardId = cardId;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public double getMoney() {
return money;
}
public void setMoney(double money) {
this.money = money;
}
public int getIntegral() {
return integral;
}
public void setIntegral(int integral) {
this.integral = integral;
}
public double getWallet() {
return wallet;
}
public void setWallet(double wallet) {
this.wallet = wallet;
}
}
启动器需要启动提示语,提示用户输入卡号。输入卡号后,调用校验卡号的方法,校验卡号是否符合卡号要求,如长度是九位数,并且是否包含非法字符.
校验成功后,验证账号类型,判断账号属于管理员账号还是用户账号。如果属于管理员账号则跳转管理员登入界面,如果属于用户账号则加入当前登入用户的成员变量 curUserCard 中,并跳转用户登入界面 。
start() 方法,代码如下:
public void systemStart() {
while (true) {
// 启动提示
System.out.println("请输入你的卡号");
String cardId = sc.next();
// 卡号校验-->长度,内容
if (!checkCardId(cardId)) {
System.out.println("卡号错误!请重新输入您的卡号");
continue;
}
// 管理员账号校验
if (isSystemCardId(cardId)) {
// 系统模块
goSystem();
} else {
// 普通用户模块
// 查找用户卡号数据 --> 已存在cardId且不是管理员账户。判断是否存在这张用户卡
FuelCard userCard = getFuelCardByCardId(cardId);
// 找不到则提示
if (userCard == null) {
System.out.println("当前用户不存在,请充值输入!");
continue;
}
// 找到后加入当前登入账号(成员变量)
curUserCard = userCard;
goUserSystem();
}
}
}
卡号校验功能,对输入的卡号进行长度和内容的判断,判断卡号是否符合要求,返回true和false共外部调用 。
/**
* 卡号校验
*/
private boolean checkCardId(String cardId) {
// 卡号校验-->长度,内容
if (cardId == null) {
return false;
}
if (cardId.length() != 9) {
return false;
}
for (int i = 0; i < cardId.length(); i++) {
if (cardId.charAt(i) < '0' || cardId.charAt(i) > '9') {
return false;
}
}
return true;
}
}
验证账号密码是否是管理员角色,代码如下:
/**
* 管理员账号校验
*/
private boolean isSystemCardId(String cardId) {
return sysCardId.equals(cardId);
}
验证为管理员账号后进入管理员登入系统,进入后,提示管理员用户输入密码,判断密码输入是否正确,是否和设置的密码相同,若密码不同则重新输入,并且限制输入密码的次数。密码错误超过限制次数,返回开始页面,提示用户重新输入账号。密码正确则进入管理员的操作页面.
private void goSystem() {
System.out.println("====管理员系统模块====");
// 密码校验(次数限制)三次
int count = 3;
for (int i = 0; i < count; i++) {
// 输入密码
System.out.println("请输入密码:");
String inputPassword = sc.next();
if (sysPassword.equals(inputPassword)) {
break;
} else {
System.out.println("密码输入错误,还剩" + (count - i - 1) + "次机会");
}
if (count == (i + 1)) {
return;
}
}
// 密码正确,进入交互界面
sysWelcome();
}
代码如下:
/**
* 管理员系统欢迎界面
*/
private void sysWelcome() {
while (true) {
System.out.println("====欢迎进入加油卡圈存后台管理系统====");
System.out.println("1. 查询(按1键)");
System.out.println("2. 添加油卡(按2键)");
System.out.println("3. 积分充值(按3键)");
System.out.println("4. 钱包充值(按4键)");
System.out.println("按e键返回(不区分大小写)");
String input = sc.next();
switch (input) {
case "1":
// 查询:展示系统卡里的所有信息,打印出来
listAllCard();
break;
case "2":
// 添加油卡
addCard();
break;
case "3":
// 积分充值
addIntegral();
break;
case "4":
// 钱包充值
addWallet();
break;
case "e":
case "E":
// 做个友好提示,然后就return结束方法
System.out.println("拜~");
return;// 后面就可以不用break,直接结束方法了
default:
System.out.println("输入有误,请重新输入");
break;
}
}
}
进入管理员操作界面后,可以执行管理员操作,包括查看所有油卡信息,新增卡号,积分充值,钱包充值四个功能 。
对存储账号信息的集合 fuelCardList 进行判空,如果集合为空则提示管理员,暂无账户信息。否则遍历集合,输出相关账户信息,由于密码属于私人信息,不能输出密码信息.
展示账户内容代码如下:
/**
* 展示账户内容
*/
private void listAllCard() {
// 打印用户集合信息 fuelCards
if (fuelCardList == null || fuelCardList.isEmpty()) {
System.out.println("暂无账户信息数据,请添加后查询");
}
for (int i = 0; i < fuelCardList.size(); i++) {
FuelCard fuelCard = fuelCardList.get(i);
System.out.println("卡号:" + fuelCard.getCardId());
System.out.println("用户:" + fuelCard.getUserName());
System.out.println("卡余额:" + fuelCard.getMoney());
System.out.println("钱包金额:" + fuelCard.getWallet());
System.out.println("积分:" + fuelCard.getIntegral());
System.out.println("------------------------------");
}
}
新增卡号,创建油卡对象,填写相关的用户信息,包括用户名,用户密码;用户密码需要输入两次,确认密码,如果两次密码都相同,则通过,否则提示重新输入;账户(电子钱包)金额,只能输入大于0的金额。卡号调用生成卡号的方法生成,而油卡余额和积分,此处为新增油卡,因此无需过多关注.
设置完对象的这些属性后,将油卡对象添加到油卡对象集合中 。
代码如下:
/**
* 添加新油卡信息
*/
private void addCard() {
// 新建油卡对象
FuelCard newCard = new FuelCard();
System.out.println("请输入用户名:");
String userName = sc.next();
newCard.setUserName(userName);
// 密码校验(确认密码)
while (true) {
System.out.println("请输入密码:");
String password = sc.next();
System.out.println("请确认密码:");
String comfirmPassword = sc.next();
if (password.equals(comfirmPassword)) {
newCard.setPassword(password);
break;
}
System.out.println("两次密码不相同,请重新输入");
}
// 钱包金额
while (true) {
System.out.println("请输入钱包金额:");
double money = sc.nextDouble();
if (money > 0) {
newCard.setWallet(money);
break;
}
System.out.println("输入的金额必须大于 0,请重新输入!");
}
// 积分 新卡没有积分
// 余额 新卡没有
// 生成卡号
String cardId = createCardId();
newCard.setCardId(cardId);
// 添加到集合中
fuelCardList.add(newCard);
}
生成的卡号,要求9位数,开头不能为0,且唯一(用户账号和管理员账户也不能重复) 。
/**
* 生成卡号
*/
public String createCardId() {
while (true) {
String newCardId = "";
// 第一次直接生成
newCardId += (r.nextInt(9) + 1);///首位不能为0
for (int i = 0; i < 8; i++) {
newCardId += (r.nextInt(10));
}
// [补充bug修复] 不能和系统账号重复,即使重复的可能性很小
if (sysCardId.equals(newCardId)) {
continue;
}
// 生成后判断是否唯一,存在就继续生成,不存在则返回生成的id
FuelCard fuelCard = getFuelCardByCardId(newCardId);
if (fuelCard == null) {
return newCardId;
}
}
}
根据卡号查找油卡对象,存在则返回油卡对象,否则返回null.
这个方法在积分充值,钱包充值,用户登录都需要用到。就是根据油卡id查出集合中的油卡对象。外部调用方法根据是否为null进行相应的判断.
根据卡号查找油卡对象代码如下:
/**
* 根据cardId查找油卡对象
*/
private FuelCard getFuelCardByCardId(String cardId) {
if (cardId == null) {
return null;
}
for (int i = 0; i < fuelCardList.size(); i++) {
if (cardId.equals(fuelCardList.get(i).getCardId())) {
return fuelCardList.get(i);
}
}
return null;
}
积分充值,检测油卡集合中是否存在油卡对象,如果没有则退出充值方法,否则一直查找不到油卡对象导致方法无法退出(也可以通过增加退出按钮,完成业务需求)。输入需要充值的油卡id,调用 getFuelCardByCardId 方法,根据油卡id找到油卡对象,若卡号不存在则提示重新输入。否则对油卡对象的积分属性做增加积分处理。并且对增加的积分进行校验,积分需要大于零.
积分充值代码如下:
private void addIntegral() {
// 验证
if (fuelCardList == null || fuelCardList.isEmpty()) {
System.out.println("系统中没有用户,无法充值");
return;
}
while (true) {
// 1.界面提示
System.out.println("=======积分充值=======");
// 1.1.请输入卡号 ---> 判断卡号是否正确]
System.out.println("请输入卡号:");
String cardId = sc.next();
FuelCard card = getFuelCardByCardId(cardId);
if (card == null) {
System.out.println("卡号输入错误,请重新输入!");
continue;
}
while (true) {
// 充值积分
System.out.println("请输入充值的积分:");
int integral = sc.nextInt();
// 校验积分 积分要大于0,和原来的积分相加
if (integral > 0) {
card.setIntegral(card.getIntegral() + integral);
System.out.println("充值成功,充值 " + integral + ",积分余额为:" + card.getIntegral());
return;
}
System.out.println("输入错误!请输入大于0的积分!");
}
}
}
钱包充值和积分充值处理方法类似,可以直接复制粘贴,注意修改有出入的地方 。
钱包充值,检测油卡集合中是否存在油卡对象,如果没有则退出充值方法,否则一直查找不到油卡对象导致方法无法退出。输入需要充值的油卡id,根据油卡id找到油卡对象,若卡号不存在则提示重新输入。否则对油卡对象的钱包(wallet)属性做增加钱包余额处理。并且对增加的金额进行校验,积分需要大于零.
钱包充值代码如下:
/**
* 钱包充值
*/
private void addWallet() {
// 验证
if (fuelCardList == null || fuelCardList.isEmpty()) {
System.out.println("系统中没有用户,无法充值");
return;
}
while (true) {
// 1.界面提示
System.out.println("=======钱包充值=======");
// 1.1.请输入卡号 ---> 判断卡号是否正确
System.out.println("请输入卡号:");
String cardId = sc.next();
FuelCard card = getFuelCardByCardId(cardId);
if (card == null) {
System.out.println("卡号输入错误,请重新输入!");
continue;
}
while (true) {
// 充值钱钱
System.out.println("请输入充值的金额:");
double wallet = sc.nextDouble();
// 校验金额 金额要大于0,和原来的金额相加
if (wallet > 0) {
card.setWallet(card.getWallet() + wallet);
System.out.println("充值成功,充值 " + wallet + ",余额为:" + card.getWallet());
return;
}
System.out.println("输入错误!请输入大于0的金额!");
}
}
}
至此,管理员业务 完成 。
验证为普通用户账号后进入普通用户登入系统,进入后,提示普通用户输入密码,判断密码输入是否正确,是否和对象中设置的密码相同,若密码不同则重新输入,并且限制输入密码的次数。密码错误超过限制次数,返回开始页面,提示用户重新输入账号。密码正确则进入普通用户的操作页面.
代码如下:
/**
* 普通用户模块
*/
private void goUserSystem() {
System.out.println("====用户系统模块");
// 校验密码,限制三次
int count = 3;
for (int i = 1; i <= count; i++) {
System.out.println("请输入你的密码:");
String password = sc.next();
if (curUserCard.getPassword().equals(password)) {
break;
} else {
System.out.println("密码输入错误,还剩" + (count - i) + "次机会");
}
if (count == i) {
return;
}
}
// 成功后进入用户的操作界面
userWelcome();
}
/**
* 用户欢迎界面(用户操作界面)
*/
private void userWelcome() {
while (true) {
System.out.println("=====欢迎使用加油卡圈存系统=====");
System.out.println("1. 圈存(按1键)");
System.out.println("2. 查询(按2键)");
System.out.println("按《退卡键》退卡(按e键)(不区分大小写)");
String input = sc.next();
switch (input) {
case "1":
// 用户圈存
userTransfer();
break;
case "2":
// 用户查询
userFind();
break;
case "e":
case "E":
// 做个友好提示,然后就return结束方法
System.out.println("拜~");
return;// 后面就可以不用break,直接结束方法了
default:
System.out.println("输入有误,请重新输入");
break;
}
}
}
进入用户操作界面后,可以执行用户相关操作,包括用户查询和用户圈存两个功能 。
打印提示语句,让用户选择查询操作,退卡操作直接使用return关键字结束方法即可.
private void userFind() {
while (true) {
System.out.println("=====查询=====");
System.out.println("1. 账户余额查询");
System.out.println("2. 积分查询");
System.out.println("按《退卡键》退卡(按e键)(不区分大小写)");
String input = sc.next();
switch (input) {
case "1":
// 钱包查询
System.out.println("当前余额为:" + curUserCard.getWallet());
break;
case "2":
// 积分查询
System.out.println("当前账户积分为:" + curUserCard.getIntegral());
break;
case "e":
case "E":
// 做个友好提示,然后就return结束方法
System.out.println("拜~");
return;// 后面就可以不用break,直接结束方法了
default:
System.out.println("输入有误,请重新输入");
break;
}
}
}
个人认为,根据流程图写的方法, 不如直接查询全部信息,也符合正常业务流程并且代码量相对较少.
代码如下:
/**
* 用户查询
*/
private void userFind() {
// 不如直接查询全部信息
System.out.println("=====查询=====");
System.out.println("当前油卡余额为:" + curUserCard.getMoney());
System.out.println("当前账户积分为:" + curUserCard.getIntegral());
System.out.println("当前账户余额为:" + curUserCard.getWallet());
}
判断用户账户余额是否大于0,小于等于0则无法进行圈存业务.
判断结束后提示用户操作,根据输入的操作,执行。对输入的金额(积分)进行判断,只能输入大于0的金额(积分);还要对输入的金额(积分)是否小于账户余额(积分)进行判断,只有小于账户余额(积分)才能进行圈存。圈存成功,减少账户余额(积分),怎加油卡余额,并提示圈存成功,返回操作界面 。
/**
* 用户圈存
*/
private void userTransfer() {
// 判断用户账户余额是否大于0,小于0则无法充值
if (curUserCard.getWallet() <= 0) {
return;
}
while (true) {
System.out.println("======= 请选择圈存方式 =======");
System.out.println("1、积分圈存");
System.out.println("2、电子钱包圈存");
System.out.println("按e键返回(不区分大小写)");
String op = sc.next();
switch (op) {
case "1":
System.out.println("当前积分余额为:" + curUserCard.getIntegral());
if (curUserCard.getIntegral() <= 0) {
System.out.println("积分不足,无法圈存");
break;
}
//可以封装成方法,选中,快捷键ctrl + alt + M
while (true) {
System.out.println("请输入圈存金额:");
int money = sc.nextInt();
if (money <= 0) {
System.out.println("请输入大于0的数!");
continue;
}
if (money > curUserCard.getIntegral()) {
System.out.println("输入的金额大于积分,无法充值!");
continue;
}
curUserCard.setMoney(curUserCard.getMoney() + money);
curUserCard.setIntegral(curUserCard.getIntegral() - money);
System.out.println("圈存成功!当前余额为:" + curUserCard.getMoney() + ",当前剩余积分为:" + curUserCard.getIntegral());
return;
}
case "2":
System.out.println("当前账户余额为:" + curUserCard.getWallet());
if (curUserCard.getWallet() <= 0) {
System.out.println("账户余额不足,无法圈存");
}
while (true) {
System.out.println("请输入圈存金额:");
int money = sc.nextInt();
if (money <= 0) {
System.out.println("请输入大于0的数!");
continue;
}
if (money > curUserCard.getWallet()) {
System.out.println("输入的金额大于账户余额,无法充值!");
continue;
}
curUserCard.setMoney(curUserCard.getMoney() + money);
curUserCard.setWallet(curUserCard.getWallet() - money);
System.out.println("圈存成功!当前余额为:" + curUserCard.getMoney() + ",当前账户余额为:" + curUserCard.getWallet());
return;
}
case "e":
case "E":
// 做个友好提示,然后就return结束方法
System.out.println("拜~");
return;
default:
System.out.println("输入有误,请重新输入");
break;
}
}
}
可以将积分圈存操作和账户余额圈存操作封装成方法,代码会更加整洁.
至此加油卡圈存系统基本完成 。
public static void main( String[] args )
{
//为了方便测试可以先增加一个用户进行测试
//ArrayList<FuelCard> testDate = new ArrayList<>();
//FuelCard fuelCard = new FuelCard("111222333","duoduo测试","2",20.0,1120,10000.0);
//testDate.add(fuelCard);
//FuelCardSys fuelCardSys = new FuelCardSys(testDate);
FuelCardSys fuelCardSys = new FuelCardSys();
fuelCardSys.systemStart();
}
最后此篇关于Java基础实现加油站圈存机系统的文章就讲到这里了,如果你想了解更多关于Java基础实现加油站圈存机系统的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我有这个代码: System.err.print("number of terms = "); System.out.println(allTerms.size()); System.err
我有以下问题:在操作系统是 Linux 的情况下和在操作系统是 MacOs 的情况下,我必须执行不同的操作。 所以我创建了以下 Ant 脚本目标: /u
我正在调用 system("bash ../tools/bashScript\"This is an argument!\"&"),然后我正在调用 close(socketFD) 直接在 system
使用最初生成的随机元素来约束随机数组的连续元素是否有效。 例如:我想生成一组 10 个 addr、size 对来模拟典型的内存分配例程并具有如下类: class abc; rand bit[5:0
我正在创建一个必须使用system(const char*)函数来完成一些“繁重工作”的应用程序,并且我需要能够为用户提供粗略的进度百分比。例如,如果操作系统正在为您移动文件,它会为您提供一个进度条,
我即将编写一些项目经理、开发人员和业务分析师会使用的标准/指南和模板。目标是更好地理解正在开发或已经开发的解决方案。 其中一部分是提供有关记录解决方案的标准/指南。例如。记录解决/满足业务案例/用户需
在开发使用压缩磁盘索引或磁盘文件的应用程序时,其中部分索引或文件被重复访问(为了论证,让我们说一些类似于 Zipfian 分布的东西),我想知道什么时候足够/更好地依赖操作系统级缓存(例如,Debia
我们编写了一个 powershell 脚本,用于处理来自内部系统的图像并将其发送到另一个系统。现在,业务的另一部分希望加入其中,对数据进行自己的处理,并将其推送到另一个系统。打听了一下,公司周围有几个
我正在尝试朗姆酒我的应用程序,但我收到以下错误:System.Web.HttpUnhandledException:引发了“System.Web.HttpUnhandledException”类型的异
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 要求我们推荐或查找工具、库或最喜欢的场外资源的问题对于 Stack Overflow 来说是偏离主题的,
所以我在其他程序中没有收到此错误,但我在这个程序中收到了它。 这个程序是一个我没有收到错误的示例。 #include int main() { system("pause"); } // en
我在 c# System.URI.FormatExption 中遇到问题 为了清楚起见,我使用的是 Segseuil 的 Matlab 方法,并且它返回一个图片路径 result。我想为其他用户保存此
我正在尝试像这样设置文本框的背景色: txtCompanyName.BackColor = Drawing.Color.WhiteSmoke; 它不喜欢它,因为它要我在前面添加系统,例如: txtCo
请帮助我解决 System.StackOverflowException我想用 .aspx 将记录写入数据库我使用 4 层架构来实现这一切都正常但是当我编译页面然后它显示要插入数据的字段时,当我将数据
我使用了一些通常由系统调用的API。 因此,我将 android:sharedUserId="android.uid.system" 添加到 manifest.xml, 并使用来自 GIT 的 And
我正在尝试创建一个小型应用程序,它需要对/system 文件夹进行读/写访问(它正在尝试删除一个文件,并创建一个新文件来代替它)。我可以使用 adb 毫无问题地重新挂载该文件夹,如果我这样做,我的应用
我想从没有 su 的系统 priv-app 将/system 重新挂载为 RW。如何以编程方式执行此操作?只会用 Runtime.getruntime().exec() 执行一个 shell 命令吗
我正在尝试制作一个带有登录系统的程序我对此很陌生,但我已经连续工作 8 个小时试图解决这个问题。这是我得到的错误代码 + ServerVersion 'con.ServerVersion' threw
当我“构建并运行”Code::Blocks 中的程序时,它运行得非常好!但是当我从“/bin”文件夹手动运行它时,当它试图用 system() 调用“temp.bat”时,它会重置。这是为什么?它没有
我想使用 system/pipe 命令来执行具有特殊字符的命令。下面是示例代码。通过系统/管道执行命令后,它通过改变特殊字符来改变命令。我很惊讶地看到系统命令正在更改作为命令传递的文本。 run(ch
我是一名优秀的程序员,十分优秀!