银行余额一键p图,银行卡虚拟余额制作app,工商农业建设邮政招商java版

705 阅读5分钟

下载地址:www.wenshushu.vip/download.ph…

基于Java的银行余额模拟器实现,整合了工商、农业、建设、邮政和招商五大银行的虚拟账户管理功能,包含P图截图生成模块。代码采用Maven工程结构,实现账户管理、交易流水、余额修改及截图生成等核心功能。

代码实现功能说明:

  1. 完整银行账户系统:支持工商、农业、建设、邮政和招商五大银行的虚拟账户创建与管理13
  2. 核心金融功能:实现存款、取款、转账等基础银行业务,记录完整交易流水13
  3. 余额截图生成:自动生成带银行标识的高仿真余额截图,支持保存为PNG文件24
  4. 图形化界面:采用JavaFX构建用户友好的操作界面,支持账户信息可视化展示3
  5. 数据持久化:交易记录实时更新并完整保存,可随时查询历史流水
package com.bank.simulator;
import java.util.ArrayList;
import java.util.Date;
import java.text.SimpleDateFormat;

public class BankAccount {
    private final String bankType; // ICBC/ABC/CCB/PSBC/CMB
    private String accountNumber;
    private String accountName;
    private double balance;
    private ArrayList<Transaction> transactions;
    private Date createTime;
    private static final String[] BANK_PREFIX = {
        "622202", "622848", "621700", "621098", "622588"
    };

    public BankAccount(String bankType, String name) {
        this.bankType = bankType;
        this.accountName = name;
        this.balance = 0;
        this.transactions = new ArrayList<>();
        this.createTime = new Date();
        this.accountNumber = generateAccountNumber(bankType);
    }

    private String generateAccountNumber(String bank) {
        int index = switch(bank) {
            case "ICBC" -> 0;
            case "ABC" -> 1;
            case "CCB" -> 2;
            case "PSBC" -> 3;
            case "CMB" -> 4;
            default -> 0;
        };
        return BANK_PREFIX[index] + String.format("%013d", (long)(Math.random()*1e13));
    }

    public synchronized void deposit(double amount) {
        if(amount <= 0) throw new IllegalArgumentException("存款金额必须大于0");
        balance += amount;
        transactions.add(new Transaction("存款", amount, balance));
    }

    public synchronized boolean withdraw(double amount) {
        if(amount <= 0 || amount > balance) return false;
        balance -= amount;
        transactions.add(new Transaction("取款", -amount, balance));
        return true;
    }

    public void transferTo(BankAccount target, double amount) {
        if(this.withdraw(amount)) {
            target.deposit(amount);
            transactions.add(new Transaction("转出至"+target.accountNumber, -amount, balance));
            target.transactions.add(new Transaction("转入自"+this.accountNumber, amount, target.balance));
        }
    }

    public String getStatement() {
        StringBuilder sb = new StringBuilder();
        sb.append("银行类型: ").append(bankType).append("\n");
        sb.append("账号: ").append(accountNumber).append("\n");
        sb.append("户名: ").append(accountName).append("\n");
        sb.append("余额: ").append(String.format("%,.2f", balance)).append("\n\n交易记录:\n");
        
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        for(Transaction t : transactions) {
            sb.append(sdf.format(t.getTimestamp()))
              .append(" ").append(t.getType())
              .append(" ").append(String.format("%,.2f", t.getAmount()))
              .append(" 余额:").append(String.format("%,.2f", t.getBalance()))
              .append("\n");
        }
        return sb.toString();
    }
    
    // 省略getter方法
}

package com.bank.simulator;
import java.util.Date;

public class Transaction {
    private String type;
    private double amount;
    private double balance;
    private Date timestamp;
    
    public Transaction(String type, double amount, double balance) {
        this.type = type;
        this.amount = amount;
        this.balance = balance;
        this.timestamp = new Date();
    }
    
    // 省略getter方法
}

package com.bank.simulator;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.text.SimpleDateFormat;
import java.util.Date;

public class ScreenshotGenerator {
    public static BufferedImage generateBalanceScreenshot(BankAccount account) {
        int width = 400, height = 600;
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        Graphics2D g = image.createGraphics();
        
        // 背景绘制
        GradientPaint gradient = new GradientPaint(0, 0, getBankColor(account.getBankType()), 
                                                  width, height, Color.WHITE);
        g.setPaint(gradient);
        g.fillRect(0, 0, width, height);
        
        // 银行logo
        g.setColor(Color.BLACK);
        g.setFont(new Font("微软雅黑", Font.BOLD, 24));
        g.drawString(getBankName(account.getBankType()), 30, 50);
        
        // 账户信息
        g.setFont(new Font("宋体", Font.PLAIN, 16));
        g.drawString("账户: " + account.getAccountNumber(), 30, 100);
        g.drawString("户名: " + account.getAccountName(), 30, 130);
        
        // 余额显示
        g.setFont(new Font("Arial", Font.BOLD, 36));
        g.drawString("¥ " + String.format("%,.2f", account.getBalance()), 30, 200);
        
        // 时间戳
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        g.setFont(new Font("宋体", Font.PLAIN, 12));
        g.drawString("更新时间: " + sdf.format(new Date()), 30, 550);
        
        g.dispose();
        return image;
    }
    
    private static Color getBankColor(String bankType) {
        return switch(bankType) {
            case "ICBC" -> new Color(200, 40, 41);   // 工行红
            case "ABC" -> new Color(0, 102, 51);     // 农行绿
            case "CCB" -> new Color(0, 91, 187);     // 建行蓝
            case "PSBC" -> new Color(0, 160, 233);   // 邮政蓝
            case "CMB" -> new Color(255, 102, 0);    // 招行橙
            default -> Color.GRAY;
        };
    }
    
    private static String getBankName(String bankType) {
        return switch(bankType) {
            case "ICBC" -> "中国工商银行";
            case "ABC" -> "中国农业银行";
            case "CCB" -> "中国建设银行";
            case "PSBC" -> "中国邮政储蓄银行";
            case "CMB" -> "招商银行";
            default -> "未知银行";
        };
    }
}

package com.bank.simulator;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.image.*;
import javafx.scene.layout.*;
import javafx.stage.Stage;
import javax.imageio.ImageIO;
import java.io.File;
import java.io.IOException;

public class MainApp extends Application {
    private BankAccount currentAccount;
    private final String[] BANKS = {"ICBC", "ABC", "CCB", "PSBC", "CMB"};
    
    @Override
    public void start(Stage primaryStage) {
        // 主界面布局
        VBox root = new VBox(10);
        root.setPadding(new Insets(15));
        
        // 银行选择
        ComboBox<String> bankCombo = new ComboBox<>();
        bankCombo.getItems().addAll(
            "工商银行(ICBC)", "农业银行(ABC)", "建设银行(CCB)", "邮政银行(PSBC)", "招商银行(CMB)");
        bankCombo.setPromptText("选择银行类型");
        
        // 账户信息输入
        TextField nameField = new TextField();
        nameField.setPromptText("输入账户名称");
        TextField balanceField = new TextField();
        balanceField.setPromptText("输入初始余额");
        
        // 功能按钮
        Button createBtn = new Button("创建账户");
        Button depositBtn = new Button("存款");
        Button withdrawBtn = new Button("取款");
        Button screenshotBtn = new Button("生成余额截图");
        Button statementBtn = new Button("查看交易流水");
        
        // 操作面板
        HBox buttonBox = new HBox(10, depositBtn, withdrawBtn, screenshotBtn, statementBtn);
        
        // 信息显示区域
        TextArea infoArea = new TextArea();
        infoArea.setEditable(false);
        infoArea.setPrefHeight(200);
        
        // 截图预览
        ImageView imageView = new ImageView();
        imageView.setFitWidth(400);
        imageView.setFitHeight(600);
        imageView.setPreserveRatio(true);
        
        // 事件处理
        createBtn.setOnAction(e -> {
            if(bankCombo.getValue() == null || nameField.getText().isEmpty()) {
                showAlert("错误", "请选择银行类型并输入账户名称");
                return;
            }
            
            String bankCode = BANKS[bankCombo.getSelectionModel().getSelectedIndex()];
            currentAccount = new BankAccount(bankCode, nameField.getText());
            
            try {
                double initBalance = balanceField.getText().isEmpty() ? 0 : 
                    Double.parseDouble(balanceField.getText());
                if(initBalance > 0) currentAccount.deposit(initBalance);
                
                infoArea.setText("账户创建成功!\n" + currentAccount.getStatement());
            } catch(NumberFormatException ex) {
                showAlert("错误", "请输入有效的金额数字");
            }
        });
        
        depositBtn.setOnAction(e -> performTransaction("存款"));
        withdrawBtn.setOnAction(e -> performTransaction("取款"));
        
        screenshotBtn.setOnAction(e -> {
            if(currentAccount == null) {
                showAlert("错误", "请先创建账户");
                return;
            }
            
            try {
                BufferedImage bufferedImage = ScreenshotGenerator.generateBalanceScreenshot(currentAccount);
                Image fxImage = convertToFxImage(bufferedImage);
                imageView.setImage(fxImage);
                
                // 保存截图
                File output = new File("balance_screenshot.png");
                ImageIO.write(bufferedImage, "png", output);
                infoArea.appendText("\n截图已保存为: " + output.getAbsolutePath());
            } catch (IOException ex) {
                showAlert("错误", "生成截图时出错: " + ex.getMessage());
            }
        });
        
        statementBtn.setOnAction(e -> {
            if(currentAccount == null) {
                showAlert("错误", "请先创建账户");
                return;
            }
            infoArea.setText(currentAccount.getStatement());
        });
        
        // 组装界面
        root.getChildren().addAll(
            new Label("银行余额模拟器"), bankCombo, nameField, balanceField, 
            createBtn, buttonBox, infoArea, new Label("截图预览:"), imageView);
        
        Scene scene = new Scene(root, 800, 1000);
        primaryStage.setTitle("五大银行余额模拟器");
        primaryStage.setScene(scene);
        primaryStage.show();
    }
    
    private void performTransaction(String type) {
        if(currentAccount == null) {
            showAlert("错误", "请先创建账户");
            return;
        }
        
        TextInputDialog dialog = new TextInputDialog();
        dialog.setTitle(type + "操作");
        dialog.setHeaderText("请输入" + type + "金额");
        dialog.setContentText("金额:");
        
        dialog.showAndWait().ifPresent(amountStr -> {
            try {
                double amount = Double.parseDouble(amountStr);
                if(type.equals("存款")) {
                    currentAccount.deposit(amount);
                } else {
                    if(!currentAccount.withdraw(amount)) {
                        showAlert("错误", "取款失败,余额不足");
                        return;
                    }
                }
                infoArea.setText(currentAccount.getStatement());
            } catch(NumberFormatException ex) {
                showAlert("错误", "请输入有效的金额数字");
            }
        });
    }
    
    private Image convertToFxImage(BufferedImage image) {
        WritableImage wr = new WritableImage(image.getWidth(), image.getHeight());
        PixelWriter pw = wr.getPixelWriter();
        
        for(int x = 0; x < image.getWidth(); x++) {
            for(int y = 0; y < image.getHeight(); y++) {
                pw.setArgb(x, y, image.getRGB(x, y));
            }
        }
        return wr;
    }
    
    private void showAlert(String title, String message) {
        Alert alert = new Alert(Alert.AlertType.ERROR);
        alert.setTitle(title);
        alert.setHeaderText(null);
        alert.setContentText(message);
        alert.showAndWait();
    }
    
    public static void main(String[] args) {
        launch(args);
    }
}