java每日一题——ATM系统编写(答案及编程思路)
前言:
基础语句学完,也可以编写一些像样的程序了,现在要做的是多加练习,巩固下知识点,打好基础,daydayup!
题目:模仿银行ATM系统,可以创建用户,存钱,转账,修改密码注销账户等操作
思路:利用面向对象编程:1,定义一个账户类Account,至少需要包含(卡号、姓名、性别、密码、余额、每次取现额度);2,定义一个ATM类,用来代表ATM系统,负责提供所有的业务需求;3,定义一个测试类Test,负责对我们开发的ATM系统进行测试。
1,创建实体类:
创建一个实体类,用来记录姓名、卡号、性别、密码、余额、每次取现额度等信息。
public class Account {private String card;private String username ;private char sex;private String password;private double money;private double limit;public Account() {}public String getCard() {return card;}public void setCard(String card) {this.card = card;}public String getUsername() {return username + (sex=='男'? "先生":"女士");}public void setUsername(String username) {this.username = username;}public char getSex() {return sex;}public void setSex(char sex) {this.sex = sex;}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 double getLimit() {return limit;}public void setLimit(double limit) {this.limit = limit;}
}
2,创建操作类:
1,创建界面
通过选择1,或选择2进入系统
public void start(){Scanner sc =new Scanner(System.in);while (true) {System.out.println("======欢迎来到ATM=======");System.out.println("1,用户登陆");System.out.println("2,用户开户");System.out.println("请选择");int id =sc.nextInt();switch (id){case 1://用户登陆login();break;case 2://用户开户Operator();break;default:System.out.println("请重新输入");}}}
2,用户开户
运用Scanner输入来记入需要记录的信息,值得一提的是:由于Scanner没办法记录char变量,所以使用charAt来取第一个值。
private void Operator(){Account acc = new Account();System.out.println("请输入姓名");String name = sc.next();acc.setUsername(name);while (true) {System.out.println("请输入性别(男/女)");char sex = sc.next().charAt(0);if (sex == '男'|| sex == '女'){acc.setSex(sex);break;}else{System.out.println("请输入(男/女)");}}while (true) {System.out.println("请设置你的密码");String password = sc.next();System.out.println("请再次输入你的密码");String okpassword = sc.next();if (password.equals(okpassword)){acc.setPassword(okpassword);break;}else{System.out.println("两次密码不一致,请重新输入");}}System.out.println("请设置每日取款限额");double limit = sc.nextDouble();acc.setLimit(limit);String id =card();acc.setCard(id);accounts.add(acc);System.out.println("恭喜"+acc.getUsername()+"开户成功,您的卡号为:"+acc.getCard());}
2.1系统输入卡号
由于卡号需要随机生成8位数字,并且不能与其他人的号码重复,所以需要建立两个方法来做调试。一个方法用于生成8位随机数字,一个方法用于检测号码是否重复
private String card(){Random r = new Random();while (true) {String id = "";for (int i = 0; i < 8; i++) {int data= r.nextInt(10);id +=data;}Account acc= vs(id);if (acc == null){return id;}}}private Account vs (String card){for (int i = 0; i <accounts.size(); i++) {Account acc= accounts.get(i);if (acc.getCard().equals(card)){return acc;}}return null;
这样一来,开户也就成功了。接下来是登陆的操作。
3,用户登陆
需要注意的是:当系统中没有账号时,要提示没有账号。登陆时需要注意号码的匹对。
private void login(){if (accounts.size()==0){System.out.println("请先创建账号");return;}while (true) {System.out.println("请输入卡号");String card = sc.next();Account acc = vs(card);if(acc == null){System.out.println("没有该账号,请重新输入");}else if(acc.getCard().equals(card)){while (true) {System.out.println("请输入密码");String password =sc.next();if (acc.getPassword().equals(password)){acco = acc;check();return;}else{System.out.println("密码不正确,请重新输入");}}}}}
4,业务界面
登陆成功后,便可进行业务选择。运用switch语句可以精准选择业务需求
private void check(){while (true) {System.out.println(acco.getUsername()+"你可以办理以下业务");System.out.println("1.查询账户");System.out.println("2.存款");System.out.println("3.取款");System.out.println("4.转账");System.out.println("5.修改密码");System.out.println("6.退出");System.out.println("7.注销账户");System.out.println("请选择");int check= sc.nextInt();switch (check){case 1:idcheck();break;case 2:moenycheck();break;case 3:moneyleave();break;case 4:transmoney();break;case 5:changepassword();return;case 6:System.out.println("你已经退出");return;case 7:if (deleteid());return;default:System.out.println("你输入的数字有误,请重新输入");}}}
4.1账户确认
建议独立一个方法,其他没什么需要注意的
private void idcheck(){System.out.println("号码:"+acco.getCard());System.out.println("性别:"+acco.getSex());System.out.println("存款:"+acco.getMoney());System.out.println("每日限额:"+acco.getLimit());}
4.2存款
熟用switch语句及死循环能够很好的解决问题
private void moenycheck() {while (true) {System.out.println("欢迎来到存款界面");System.out.println("存款请按1");System.out.println("退出请按2");int sd = sc.nextInt();switch (sd){case 1:System.out.println("请输入你要存多少");double money= sc.nextDouble();System.out.println("请问你确定要存入"+money+"么");System.out.println("确定请按1");System.out.println("返回请按2");int cc =sc.nextInt();switch (cc){case 1:acco.setMoney(acco.getMoney()+money);System.out.println("您的余额为"+acco.getMoney());break;case 2:return;default:System.out.println("请重新输入");}break;case 2:return;default:System.out.println("请重新输入");}}}
4.3取款
一连串的switch语句和if问句,解决每一项逻辑
private void moneyleave() {while (true) {System.out.println("欢迎来到取款界面");System.out.println("取款请按1");System.out.println("退出请按2");int sd = sc.nextInt();switch(sd){case 1:System.out.println("你目前的存款为" + acco.getMoney());if (acco.getMoney() < 100) {System.out.println("最低取款金额为100,您的余额不足");break;} else {System.out.println("请输入你要取走的金额");double money = sc.nextDouble();if (acco.getMoney()<money){System.out.println("您的余额不足,请重新输入");break;}else{if (money>acco.getLimit()){System.out.println("您已超过限额,请重新输入");break;}else{System.out.println("您已取走"+money+"元");acco.setMoney(acco.getMoney()- money);System.out.println("您的余额为:"+acco.getMoney());}}}break;case 2:return;default:System.out.println("请重新输入");}}}
4.4转账
选要注意的是:这里需要判断对方的姓氏,采用的方法为“*”加上第二位开始的名字。转账者需要填写姓氏后运用startwith语句进行匹配。
private void transmoney() {while (true) {System.out.println("欢迎来到转账界面");System.out.println("转账请按1");System.out.println("退出请按2");int sd = sc.nextInt();switch (sd){case 1:if (accounts.size()<2){System.out.println("当前系统中只有一个账号,请创建新的账号");break;}if (acco.getMoney()==0){System.out.println("您的余额不足,不能转账");break;}System.out.println("请输入对方的账号");String id =sc.next();Account acc =vs(id);if (acc == null){System.out.println("没有该账号,请重新输入");}else{String name ="*"+acc.getUsername().substring(1);System.out.println("请输入【"+name+"】的姓氏");String trname =sc.next();if (acc.getUsername().startsWith(trname)){System.out.println("请输入转账金额");double money =sc.nextDouble();if (acco.getMoney() >= money){acco.setMoney(acco.getMoney()-money);acc.setMoney(acc.getMoney()+ money);System.out.println("您已转账"+money+"元,您的余额为"+acco.getMoney());break;}else{System.out.println("您的余额不足,不能转账");}}else {System.out.println("姓氏认证有问题");}}break;case 2:return;}}}
4.5 更换密码
使用if语句询问即可,需要注意的是,最后要用return返回,不能用break,(return是退出方法,break是退出循环)
private void changepassword() {while (true) {System.out.println("欢迎来到更换密码界面");System.out.println("输入当前密码");String pass =sc.next();if (acco.getPassword().equals(pass)){System.out.println("输入新密码");String okpass =sc.next();System.out.println("再一次输入新密码");String okkpass =sc.next();if (okkpass.equals(okpass)){acco.setPassword(okkpass);System.out.println("修改密码成功");return;}else{System.out.println("密码有误");}}else {System.out.println("密码有误");}}}
4.6退出系统
用return即可
case 6:System.out.println("你已经退出");return;
4.7删除账户
删除当前账户即可。当前账户和创建账户的实体类是同一个地址,删除当前账户就是在ArrayList中删除了当前账户实体类的地址
private boolean deleteid() {while (true) {System.out.println("确定删除么(y/n)");String sd =sc.next();switch (sd){case "y":if (acco.getMoney()==0){accounts.remove(acco);return true;}else{System.out.println("还有存款,不能销户");return false;}default:System.out.println("删除失败");return false;}}}
操作完整版在这里
这样操作类就完成了,有需要的可以复制这个完整版
import java.util.ArrayList;
import java.util.Random;
import java.util.Scanner;public class ATMOperator {private ArrayList<Account> accounts = new ArrayList<>();private Scanner sc = new Scanner(System.in);private Account acco = new Account();public void start(){Scanner sc =new Scanner(System.in);while (true) {System.out.println("======欢迎来到ATM=======");System.out.println("1,用户登陆");System.out.println("2,用户开户");System.out.println("请选择");int id =sc.nextInt();switch (id){case 1://用户登陆login();break;case 2://用户开户Operator();break;default:System.out.println("请重新输入");}}}private void login(){if (accounts.size()==0){System.out.println("请先创建账号");return;}while (true) {System.out.println("请输入卡号");String card = sc.next();Account acc = vs(card);if(acc == null){System.out.println("没有该账号,请重新输入");}else if(acc.getCard().equals(card)){while (true) {System.out.println("请输入密码");String password =sc.next();if (acc.getPassword().equals(password)){acco = acc;check();return;}else{System.out.println("密码不正确,请重新输入");}}}}}private void check(){while (true) {System.out.println(acco.getUsername()+"你可以办理以下业务");System.out.println("1.查询账户");System.out.println("2.存款");System.out.println("3.取款");System.out.println("4.转账");System.out.println("5.修改密码");System.out.println("6.退出");System.out.println("7.注销账户");System.out.println("请选择");int check= sc.nextInt();switch (check){case 1:idcheck();break;case 2:moenycheck();break;case 3:moneyleave();break;case 4:transmoney();break;case 5:changepassword();return;case 6:System.out.println("你已经退出");return;case 7:if (deleteid());return;default:System.out.println("你输入的数字有误,请重新输入");}}}private void changepassword() {while (true) {System.out.println("欢迎来到更换密码界面");System.out.println("输入当前密码");String pass =sc.next();if (acco.getPassword().equals(pass)){System.out.println("输入新密码");String okpass =sc.next();System.out.println("再一次输入新密码");String okkpass =sc.next();if (okkpass.equals(okpass)){acco.setPassword(okkpass);System.out.println("修改密码成功");return;}else{System.out.println("密码有误");}}else {System.out.println("密码有误");}}}private boolean deleteid() {while (true) {System.out.println("确定删除么(y/n)");String sd =sc.next();switch (sd){case "y":if (acco.getMoney()==0){accounts.remove(acco);return true;}else{System.out.println("还有存款,不能销户");return false;}default:System.out.println("删除失败");return false;}}}private void transmoney() {while (true) {System.out.println("欢迎来到转账界面");System.out.println("转账请按1");System.out.println("退出请按2");int sd = sc.nextInt();switch (sd){case 1:if (accounts.size()<2){System.out.println("当前系统中只有一个账号,请创建新的账号");break;}if (acco.getMoney()==0){System.out.println("您的余额不足,不能转账");break;}System.out.println("请输入对方的账号");String id =sc.next();Account acc =vs(id);if (acc == null){System.out.println("没有该账号,请重新输入");}else{String name ="*"+acc.getUsername().substring(1);System.out.println("请输入【"+name+"】的姓氏");String trname =sc.next();if (acc.getUsername().startsWith(trname)){System.out.println("请输入转账金额");double money =sc.nextDouble();if (acco.getMoney() >= money){acco.setMoney(acco.getMoney()-money);acc.setMoney(acc.getMoney()+ money);System.out.println("您已转账"+money+"元,您的余额为"+acco.getMoney());break;}else{System.out.println("您的余额不足,不能转账");}}else {System.out.println("姓氏认证有问题");}}break;case 2:return;}}}private void moneyleave() {while (true) {System.out.println("欢迎来到取款界面");System.out.println("取款请按1");System.out.println("退出请按2");int sd = sc.nextInt();switch(sd){case 1:System.out.println("你目前的存款为" + acco.getMoney());if (acco.getMoney() < 100) {System.out.println("最低取款金额为100,您的余额不足");break;} else {System.out.println("请输入你要取走的金额");double money = sc.nextDouble();if (acco.getMoney()<money){System.out.println("您的余额不足,请重新输入");break;}else{if (money>acco.getLimit()){System.out.println("您已超过限额,请重新输入");break;}else{System.out.println("您已取走"+money+"元");acco.setMoney(acco.getMoney()- money);System.out.println("您的余额为:"+acco.getMoney());}}}break;case 2:return;default:System.out.println("请重新输入");}}}private void moenycheck() {while (true) {System.out.println("欢迎来到存款界面");System.out.println("存款请按1");System.out.println("退出请按2");int sd = sc.nextInt();switch (sd){case 1:System.out.println("请输入你要存多少");double money= sc.nextDouble();System.out.println("请问你确定要存入"+money+"么");System.out.println("确定请按1");System.out.println("返回请按2");int cc =sc.nextInt();switch (cc){case 1:acco.setMoney(acco.getMoney()+money);System.out.println("您的余额为"+acco.getMoney());break;case 2:return;default:System.out.println("请重新输入");}break;case 2:return;default:System.out.println("请重新输入");}}}private void idcheck(){System.out.println("号码:"+acco.getCard());System.out.println("性别:"+acco.getSex());System.out.println("存款:"+acco.getMoney());System.out.println("每日限额:"+acco.getLimit());}private void Operator(){Account acc = new Account();System.out.println("请输入姓名");String name = sc.next();acc.setUsername(name);while (true) {System.out.println("请输入性别(男/女)");char sex = sc.next().charAt(0);if (sex == '男'|| sex == '女'){acc.setSex(sex);break;}else{System.out.println("请输入(男/女)");}}while (true) {System.out.println("请设置你的密码");String password = sc.next();System.out.println("请再次输入你的密码");String okpassword = sc.next();if (password.equals(okpassword)){acc.setPassword(okpassword);break;}else{System.out.println("两次密码不一致,请重新输入");}}System.out.println("请设置每日取款限额");double limit = sc.nextDouble();acc.setLimit(limit);String id =card();acc.setCard(id);accounts.add(acc);System.out.println("恭喜"+acc.getUsername()+"开户成功,您的卡号为:"+acc.getCard());}private String card(){Random r = new Random();while (true) {String id = "";for (int i = 0; i < 8; i++) {int data= r.nextInt(10);id +=data;}Account acc= vs(id);if (acc == null){return id;}}}private Account vs (String card){for (int i = 0; i <accounts.size(); i++) {Account acc= accounts.get(i);if (acc.getCard().equals(card)){return acc;}}return null;}
}
最后测试:
public class ATMDemo {public static void main(String[] args) {ATMOperator de = new ATMOperator();de.start();}}
测试效果:
总结:完美运行,有些语句需要在加强,熟用if语句和switch可以完成精准操作
整理结束撒花!!!!
相关文章:

java每日一题——ATM系统编写(答案及编程思路)
前言: 基础语句学完,也可以编写一些像样的程序了,现在要做的是多加练习,巩固下知识点,打好基础,daydayup! 题目:模仿银行ATM系统,可以创建用户,存钱,转账&…...

《TrollStore巨魔商店》TrollStore2安装使用教程支持IOS14.0-16.6.1
TrollStore(巨魔商店) 简单的说就相当于一个永久的免费证书,它可以给你的iPhone和iPad安装任何你想要安装的App软件,而且不需要越狱,不用担心证书签名过期的问题,不需要个人签名和企业签名。 支持的版本: TrollStore安装和使用教…...

鸿鹄电子招投标系统源码实现与立项流程:基于Spring Boot、Mybatis、Redis和Layui的企业电子招采平台
随着企业的快速发展,招采管理逐渐成为企业运营中的重要环节。为了满足公司对内部招采管理提升的要求,建立一个公平、公开、公正的采购环境至关重要。在这个背景下,我们开发了一款电子招标采购软件,以最大限度地控制采购成本&#…...
力扣-三数之和
三数之和 给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i ! j、i ! k 且 j ! k ,同时还满足 nums[i] nums[j] nums[k] 0 。请你返回所有和为 0 且不重复的三元组。 注意:答案中不可以包含重复的三元组。…...

全罐喂养一个月多少钱?适合全罐喂养的猫罐头推荐
不少铲屎官一直没有办法get到猫罐头对猫咪的好处,或者get到了又觉得给猫咪买猫罐头好贵,看到其他铲屎官都开始全罐喂养了,但是自己却迟迟下不了手,犹犹豫豫的不知道全罐喂养一个月多少钱? 今天,铲龄15年的…...
js some方法的使用
JavaScript中的数组some()方法用于检查数组中是否至少有一个元素满足指定条件。该方法会遍历数组,并对每个元素应用指定的测试函数。如果有任何一个元素使得测试函数返回true,则some()方法返回true,否则返回false。 some()方法的语法如下&am…...

QT DAY5作业
1.QT基于TCP服务器端 头文件 #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QTcpServer> //服务器类 #include <QMessageBox> //消息对话框类 #include <QTcpSocket> //客户端类 #include <QList> //链表容器类namespace …...

Hello 2024补题
Wallet Exchange(Problem - A - Codeforces) 题目大意:A,B做游戏,它们的钱包里各有a,b个硬币,轮到它们操作时,它们可以扔掉自己或者对手钱包里的硬币,谁不能操作谁输,问…...
git权限问题导致的所有文件被修改问题
git忽略文件权限的修改 git config core.filemode false...
C语言经典算法之堆排序算法
目录 前言 建议 简介 A.建堆: B.排序 一、代码实现 二、时空复杂度 A.时间复杂度 B.空间复杂度 三、稳定性 四、现实中的应用 前言 建议 1.学习算法最重要的是理解算法的每一步,而不是记住算法。 2.建议读者学习算法的时候,自己…...
前端笔试题(一)
1.vue如何实现数据的双向绑定 利用v-model来实现双向数据绑定 通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调来渲染视图 2.使用vue渲染大量数据时,如何进行优化…...
Springboot开发的大学生寝室考勤系统刷脸进出宿舍系统技术文档
宿舍出入系统 1.2采集学生人脸信息和宿管人脸信息 前端使用navigator.mediaDevices.getUserMedia(考虑个浏览器的内核差异,此处以最新的标准API:navigator.mediaDevices.getUserMedia为例)获取用户浏览器的摄像头并开启视频,使用…...

网络共享服务
存储类型:直连式(DAS):距离最近,存储设备且直接连接到服务器上 存储区域网络(SAN):适用于大型应用或数据库系统,可以使用文件的空间, 以及管理空间…...

资本主义的市场竞争?IBM总监Jerry Chow 谈量子计算的未来
人物介绍:Jerry M.Chow博士在耶鲁大学取得物理博士学位。担任IBM量子系统总监,其研究重点是面向容错量子计算的多量子比特系统。他主要为IBM的量子系统路线图制定战略,与硬件团队领导者一起设定目标研究领域,同时也确保最佳的客…...

什么是残差矢量量化?
一、说明 基于残差矢量量化的神经音频压缩方法正在重塑现代音频编解码器的格局。在本指南中,了解 RVQ 背后的基本思想以及它如何增强神经压缩。 数据压缩在当今的数字世界中发挥着关键作用,促进信息的高效存储和传输。由于当今超过 80% 的互联网流量来自…...
计算机网络(第六版)复习提纲2
二、物理层 2.1 物理层基本概念 物理层协议常常成为物理层规程 物理层的主要任务为确定与传输媒体的接口有关的一些特性: 1.机械特性:指明接口所用接线器的尺寸等; 2.电气特性:指明接口电缆各条线上的电压范围; 3.功能…...
11k+star 开源笔记应用真香 centos部署教程
leanote binary installation on Mac and Linux (En) life edited this page on Jul 21, 2017 10 revisions Pages 26 Home How to develop leanote 如何开发leanote How to install leanote on Ubuntu? How to Upgrade Leanote Install Mongodb leanote api leanote …...

win下安装tensorflow
1首先ctrlaltdelete打开任务管理器查看GPU型号 2或者右键我的电脑然后如下方式查看显卡发现没有navida没有GPU...

SpringBoot 入门
1.SpringBoot介绍 1.1.什么是SpringBoot Spring Boot是由Pivotal团队提供的全新框架,其中“Boot”的意思就是“引导”,Spring Boot 并不是对 Spring 功能上的增强,而是提供了一种快速开发 Spring应用的方式。 1.2.Spring Boot 特点 • 嵌…...
使用WebFlux处理WebSocket连接的全生命周期案例
使用WebFlux处理WebSocket连接的全生命周期案例 简介: 在Web应用程序开发中,WebSocket是一种用于实现双向通信的协议。Spring WebFlux提供了对WebSocket的支持,使您能够轻松地处理WebSocket连接和消息。本博客将介绍如何使用WebFlux处理WebS…...

MPNet:旋转机械轻量化故障诊断模型详解python代码复现
目录 一、问题背景与挑战 二、MPNet核心架构 2.1 多分支特征融合模块(MBFM) 2.2 残差注意力金字塔模块(RAPM) 2.2.1 空间金字塔注意力(SPA) 2.2.2 金字塔残差块(PRBlock) 2.3 分类器设计 三、关键技术突破 3.1 多尺度特征融合 3.2 轻量化设计策略 3.3 抗噪声…...
数据链路层的主要功能是什么
数据链路层(OSI模型第2层)的核心功能是在相邻网络节点(如交换机、主机)间提供可靠的数据帧传输服务,主要职责包括: 🔑 核心功能详解: 帧封装与解封装 封装: 将网络层下发…...
Java入门学习详细版(一)
大家好,Java 学习是一个系统学习的过程,核心原则就是“理论 实践 坚持”,并且需循序渐进,不可过于着急,本篇文章推出的这份详细入门学习资料将带大家从零基础开始,逐步掌握 Java 的核心概念和编程技能。 …...

【JVM】Java虚拟机(二)——垃圾回收
目录 一、如何判断对象可以回收 (一)引用计数法 (二)可达性分析算法 二、垃圾回收算法 (一)标记清除 (二)标记整理 (三)复制 (四ÿ…...

Git 3天2K星标:Datawhale 的 Happy-LLM 项目介绍(附教程)
引言 在人工智能飞速发展的今天,大语言模型(Large Language Models, LLMs)已成为技术领域的焦点。从智能写作到代码生成,LLM 的应用场景不断扩展,深刻改变了我们的工作和生活方式。然而,理解这些模型的内部…...

tauri项目,如何在rust端读取电脑环境变量
如果想在前端通过调用来获取环境变量的值,可以通过标准的依赖: std::env::var(name).ok() 想在前端通过调用来获取,可以写一个command函数: #[tauri::command] pub fn get_env_var(name: String) -> Result<String, Stri…...
Vue 模板语句的数据来源
🧩 Vue 模板语句的数据来源:全方位解析 Vue 模板(<template> 部分)中的表达式、指令绑定(如 v-bind, v-on)和插值({{ }})都在一个特定的作用域内求值。这个作用域由当前 组件…...

篇章二 论坛系统——系统设计
目录 2.系统设计 2.1 技术选型 2.2 设计数据库结构 2.2.1 数据库实体 1. 数据库设计 1.1 数据库名: forum db 1.2 表的设计 1.3 编写SQL 2.系统设计 2.1 技术选型 2.2 设计数据库结构 2.2.1 数据库实体 通过需求分析获得概念类并结合业务实现过程中的技术需要&#x…...

针对药品仓库的效期管理问题,如何利用WMS系统“破局”
案例: 某医药分销企业,主要经营各类药品的批发与零售。由于药品的特殊性,效期管理至关重要,但该企业一直面临效期问题的困扰。在未使用WMS系统之前,其药品入库、存储、出库等环节的效期管理主要依赖人工记录与检查。库…...
文件上传漏洞防御全攻略
要全面防范文件上传漏洞,需构建多层防御体系,结合技术验证、存储隔离与权限控制: 🔒 一、基础防护层 前端校验(仅辅助) 通过JavaScript限制文件后缀名(白名单)和大小,提…...