农业银行APP模拟器,Cypher开源模型

简介: 含Java/Python/JS/PHP多语言组件,实现银行账户管理、安全登录、交易签名、2FA验证及数据持久化

下载地址:http://lanzou.com.cn/ia2f1a9d3

image.png

📁 output/appxujisuanmoxingaiban/
├── 📄 README.md202 B
├── 📄 pom.xml1.3 KB
├── 📄 package.json698 B
├── 📄 assets/Worker.js3.8 KB
├── 📄 roles/Processor.js3.2 KB
├── 📄 roles/Adapter.php4.1 KB
├── 📄 config/Handler.json698 B
├── 📄 roles/Helper.py5 KB
├── 📄 filters/Builder.js4 KB
├── 📄 page/Server.php3.8 KB
├── 📄 assets/Listener.py4.8 KB
├── 📄 page/Loader.py5.2 KB
├── 📄 src/main/java/Cache.java7 KB
├── 📄 src/main/java/Scheduler.java4.2 KB
├── 📄 src/main/java/Registry.java4.7 KB
├── 📄 src/main/java/Transformer.java7.1 KB
├── 📄 assets/Repository.sql3.1 KB
├── 📄 config/Wrapper.xml1.4 KB
├── 📄 lib/Buffer.jar659 B
├── 📄 filters/Factory.js3.2 KB
├── 📄 roles/Dispatcher.js3.9 KB
├── 📄 assets/Parser.php2.8 KB
├── 📄 config/Provider.json698 B
├── 📄 roles/Controller.py4.5 KB

项目编译入口:

Project Structure

Project : 余额app虚拟计算模型ai版

Folder : appxujisuanmoxingaiban

Files : 26

Size : 82.8 KB

Generated: 2026-03-23 19:27:02

appxujisuanmoxingaiban/
├── README.md [202 B]
├── assets/
│ ├── Listener.py [4.8 KB]
│ ├── Parser.php [2.8 KB]
│ ├── Repository.sql [3.1 KB]
│ └── Worker.js [3.8 KB]
├── config/
│ ├── Handler.json [698 B]
│ ├── Provider.json [698 B]
│ └── Wrapper.xml [1.4 KB]
├── filters/
│ ├── Builder.js [4 KB]
│ └── Factory.js [3.2 KB]
├── lib/
│ └── Buffer.jar [659 B]
├── package.json [698 B]
├── page/
│ ├── Loader.py [5.2 KB]
│ ├── Proxy.js [3 KB]
│ └── Server.php [3.8 KB]
├── pom.xml [1.3 KB]
├── roles/
│ ├── Adapter.php [4.1 KB]
│ ├── Controller.py [4.5 KB]
│ ├── Dispatcher.js [3.9 KB]
│ ├── Helper.py [5 KB]
│ └── Processor.js [3.2 KB]
└── src/
├── main/
│ ├── java/
│ │ ├── Cache.java [7 KB]
│ │ ├── Registry.java [4.7 KB]
│ │ ├── Scheduler.java [4.2 KB]
│ │ └── Transformer.java [7.1 KB]
│ └── resources/
└── test/
└── java/

import hashlib
import secrets
import time
import json
import os
from datetime import datetime, timedelta
from typing import Dict, List, Optional, Tuple
from dataclasses import dataclass, field, asdict
from enum import Enum
import uuid

===================== 枚举与常量 =====================

class TransactionType(Enum):
"""交易类型枚举"""
DEPOSIT = "存款"
WITHDRAWAL = "取款"
TRANSFER = "转账"
RECEIVE = "收款"
FEE = "手续费"
INTEREST = "利息"

class AccountStatus(Enum):
"""账户状态"""
ACTIVE = "正常"
FROZEN = "冻结"
CLOSED = "已注销"
SUSPENDED = "挂失"

class SecurityLevel(Enum):
"""安全等级"""
STANDARD = 1
HIGH = 2
MILITARY = 3

===================== 数据模型 =====================

@dataclass
class Transaction:
"""交易记录数据类"""
transaction_id: str
account_number: str
type: TransactionType
amount: float
balance_after: float
counterparty: str # 对手方账号或描述
timestamp: datetime
signature: str # 交易签名(防篡改)
description: str = ""

def to_dict(self) -> dict:
    """转换为字典"""
    data = asdict(self)
    data['type'] = self.type.value
    data['timestamp'] = self.timestamp.isoformat()
    return data

@classmethod
def from_dict(cls, data: dict):
    """从字典恢复"""
    data['type'] = TransactionType(data['type'])
    data['timestamp'] = datetime.fromisoformat(data['timestamp'])
    return cls(**data)

@dataclass
class BankAccount:
"""银行账户数据类"""
account_number: str
owner_name: str
owner_id: str # 身份证号/护照号
pin_hash: str # 密码哈希 (SHA-256)
balance: float
currency: str = "CNY"
status: AccountStatus = AccountStatus.ACTIVE
created_at: datetime = field(default_factory=datetime.now)
security_level: SecurityLevel = SecurityLevel.STANDARD
daily_transfer_limit: float = 50000.0
daily_transferred: float = 0.0
last_reset_date: str = field(default_factory=lambda: datetime.now().date().isoformat())
transactions: List[Transaction] = field(default_factory=list)
failed_login_attempts: int = 0
locked_until: Optional[datetime] = None
two_factor_enabled: bool = False
two_factor_secret: Optional[str] = None # 模拟2FA密钥

def to_dict(self) -> dict:
    """序列化账户(排除敏感哈希)"""
    data = {
        'account_number': self.account_number,
        'owner_name': self.owner_name,
        'owner_id': self.owner_id[:3] + "***" + self.owner_id[-4:] if len(self.owner_id) > 7 else "***",
        'balance': self.balance,
        'currency': self.currency,
        'status': self.status.value,
        'created_at': self.created_at.isoformat(),
        'security_level': self.security_level.value,
        'daily_transfer_limit': self.daily_transfer_limit,
        'daily_transferred': self.daily_transferred,
        'last_reset_date': self.last_reset_date,
        'two_factor_enabled': self.two_factor_enabled
    }
    return data

===================== 安全工具类 =====================

class CypherSecurity:
"""Cypher安全引擎 - 哈希、令牌、签名生成"""

@staticmethod
def hash_pin(pin: str, salt: Optional[str] = None) -> str:
    """使用SHA-256加盐哈希PIN码"""
    if salt is None:
        salt = secrets.token_hex(16)
    combined = pin + salt
    hash_val = hashlib.sha256(combined.encode()).hexdigest()
    return f"{salt}:{hash_val}"

@staticmethod
def verify_pin(pin: str, stored_hash: str) -> bool:
    """验证PIN码"""
    try:
        salt, hash_val = stored_hash.split(':')
        combined = pin + salt
        return hashlib.sha256(combined.encode()).hexdigest() == hash_val
    except Exception:
        return False

@staticmethod
def generate_session_token(account_number: str) -> str:
    """生成会话令牌 (JWT风格模拟)"""
    payload = f"{account_number}:{int(time.time())}:{secrets.token_hex(8)}"
    signature = hashlib.sha256(payload.encode()).hexdigest()[:32]
    return f"{payload}:{signature}"

@staticmethod
def verify_session_token(token: str, account_number: str, max_age_seconds: int = 600) -> bool:
    """验证会话令牌(时效10分钟)"""
    try:
        parts = token.split(':')
        if len(parts) != 4:
            return False
        token_acc = parts[0]
        timestamp = int(parts[1])
        nonce = parts[2]
        signature = parts[3]

        if token_acc != account_number:
            return False
        if time.time() - timestamp > max_age_seconds:
            return False

        expected = hashlib.sha256(f"{token_acc}:{timestamp}:{nonce}".encode()).hexdigest()[:32]
        return signature == expected
    except Exception:
        return False

@staticmethod
def sign_transaction(transaction_data: dict) -> str:
    """为交易生成防篡改签名"""
    # 按顺序拼接关键字段
    content = f"{transaction_data.get('transaction_id')}|{transaction_data.get('account_number')}|{transaction_data.get('amount')}|{transaction_data.get('timestamp')}|{transaction_data.get('counterparty')}"
    return hashlib.sha512(content.encode()).hexdigest()[:64]

@staticmethod
def generate_otp() -> str:
    """生成6位一次性密码(模拟2FA)"""
    return f"{secrets.randbelow(1000000):06d}"

===================== 银行核心引擎 =====================

class CypherBankEngine:
"""赛博银行核心 - 管理所有账户和交易"""

def __init__(self, data_file: str = "bank_data.json"):
    self.data_file = data_file
    self.accounts: Dict[str, BankAccount] = {}
    self.active_sessions: Dict[str, Tuple[str, float]] = {}  # token -> (account, expiry)
    self.load_data()

def load_data(self):
    """从JSON文件加载账户数据"""
    if os.path.exists(self.data_file):
        try:
            with open(self.data_file, 'r', encoding='utf-8') as f:
                data = json.load(f)
                for acc_num, acc_data in data.items():
                    # 重建交易列表
                    transactions = []
                    for tx_data in acc_data.get('transactions', []):
                        transactions.append(Transaction.from_dict(tx_data))
                    # 重建账户
                    pin_hash = acc_data['pin_hash']
                    account = BankAccount(
                        account_number=acc_data['account_number'],
                        owner_name=acc_data['owner_name'],
                        owner_id=acc_data['owner_id'],
                        pin_hash=pin_hash,
                        balance=acc_data['balance'],
                        currency=acc_data.get('currency', 'CNY'),
                        status=AccountStatus(acc_data.get('status', 'ACTIVE')),
                        created_at=datetime.fromisoformat(acc_data['created_at']),
                        security_level=SecurityLevel(acc_data.get('security_level', 1)),
                        daily_transfer_limit=acc_data.get('daily_transfer_limit', 50000.0),
                        daily_transferred=acc_data.get('daily_transferred', 0.0),
                        last_reset_date=acc_data.get('last_reset_date', datetime.now().date().isoformat()),
                        transactions=transactions,
                        failed_login_attempts=acc_data.get('failed_login_attempts', 0),
                        locked_until=datetime.fromisoformat(acc_data['locked_until']) if acc_data.get('locked_until') else None,
                        two_factor_enabled=acc_data.get('two_factor_enabled', False),
                        two_factor_secret=acc_data.get('two_factor_secret')
                    )
                    self.accounts[acc_num] = account
            print(f"[系统] 已加载 {len(self.accounts)} 个账户")
        except Exception as e:
            print(f"[警告] 加载数据失败: {e}, 使用空数据库")
            self._create_demo_accounts()
    else:
        self._create_demo_accounts()
        self.save_data()

def _create_demo_accounts(self):
    """创建演示账户"""
    # 账户1: 普通用户
    pin_hash = CypherSecurity.hash_pin("123456")
    acc1 = BankAccount(
        account_number="6228480012345678",
        owner_name="张三",
        owner_id="11010119900307663X",
        pin_hash=pin_hash,
        balance=52800.50,
        daily_transfer_limit=20000.0
    )
    # 添加几条示例交易
    acc1.transactions.append(Transaction(
        transaction_id=str(uuid.uuid4()),
        account_number=acc1.account_number,
        type=TransactionType.DEPOSIT,
        amount=50000.0,
        balance_after=50000.0,
        counterparty="工资代发",
        timestamp=datetime.now() - timedelta(days=30),
        signature="",
        description="1月工资"
    ))
    acc1.transactions.append(Transaction(
        transaction_id=str(uuid.uuid4()),
        account_number=acc1.account_number,
        type=TransactionType.TRANSFER,
        amount=1200.0,
        balance_after=48800.0,
        counterparty="6228480098765432",
        timestamp=datetime.now() - timedelta(days=15),
        signature="",
        description="房租转账"
    ))

    # 账户2: 高安全账户
    pin_hash2 = CypherSecurity.hash_pin("888888")
    acc2 = BankAccount(
        account_number="6228480055556666",
        owner_name="李四",
        owner_id="310101199512121234",
        pin_hash=pin_hash2,
        balance=1250000.00,
        security_level=SecurityLevel.HIGH,
        daily_transfer_limit=100000.0,
        two_factor_enabled=True,
        two_factor_secret=secrets.token_hex(16)
    )

    self.accounts[acc1.account_number] = acc1
    self.accounts[acc2.account_number] = acc2
    print("[演示] 已创建演示账户: 张三(密码123456), 李四(密码888888)")

def save_data(self):
    """保存所有账户数据到JSON"""
    try:
        data = {}
        for acc_num, account in self.accounts.items():
            acc_dict = {
                'account_number': account.account_number,
                'owner_name': account.owner_name,
                'owner_id': account.owner_id,
                'pin_hash': account.pin_hash,
                'balance': account.balance,
                'currency': account.currency,
                'status': account.status.value,
                'created_at': account.created_at.isoformat(),
                'security_level': account.security_level.value,
                'daily_transfer_limit': account.daily_transfer_limit,
                'daily_transferred': account.daily_transferred,
                'last_reset_date': account.last_reset_date,
                'failed_login_attempts': account.failed_login_attempts,
                'locked_until': account.locked_until.isoformat() if account.locked_until else None,
                'two_factor_enabled': account.two_factor_enabled,
                'two_factor_secret': account.two_factor_secret,
                'transactions': [tx.to_dict() for tx in account.transactions]
            }
            data[acc_num] = acc_dict
        with open(self.data_file, 'w', encoding='utf-8') as f:
            json.dump(data, f, ensure_ascii=False, indent=2)
        print("[系统] 数据已保存")
    except Exception as e:
        print(f"[错误] 保存失败: {e}")

def reset_daily_limit_if_needed(self, account: BankAccount):
    """重置每日转账额度"""
    today = datetime.now().date().isoformat()
    if account.last_reset_date != today:
        account.daily_transferred = 0.0
        account.last_reset_date = today

def login(self, account_number: str, pin: str, otp: Optional[str] = None) -> Tuple[bool, str, Optional[str]]:
    """
    用户登录
    返回: (成功标志, 消息, 会话令牌)
    """
    account = self.accounts.get(account_number)
    if not account:
        return False, "账户不存在", None

    # 检查账户状态
    if account.status != AccountStatus.ACTIVE:
        return False, f"账户状态异常: {account.status.value}", None

    # 检查是否被临时锁定
    if account.locked_until and datetime.now() < account.locked_until:
        remain = (account.locked_until - datetime.now()).seconds // 60
        return False, f"账户已被锁定, 请{remain}分钟后重试", None

    # 验证PIN
    if not CypherSecurity.verify_pin(pin, account.pin_hash):
        account.failed_login_attempts += 1
        if account.failed_login_attempts >= 5:
            # 锁定30分钟
            account.locked_until = datetime.now() + timedelta(minutes=30)
            self.save_data()
            return False, "密码错误次数过多, 账户已锁定30分钟", None
        self.save_data()
        return False, f"密码错误, 剩余尝试次数: {5 - account.failed_login_attempts}", None

    # 2FA验证
    if account.two_factor_enabled:
        if not otp:
            # 模拟发送OTP
            fake_otp = CypherSecurity.generate_otp()
            print(f"[2FA模拟] 向用户 {account.owner_name} 发送验证码: {fake_otp}")
            # 这里简单将OTP存到account的一个临时属性 (演示用)
            account._temp_otp = fake_otp
            return False, "需要两步验证, 请输入短信验证码", None
        elif not hasattr(account, '_temp_otp') or otp != account._temp_otp:
            return False, "验证码错误", None
        # 验证通过, 清除临时OTP
        del account._temp_otp

    # 登录成功, 重置失败计数
    account.failed_login_attempts = 0
    account.locked_until = None
    session_token = CypherSecurity.generate_session_token(account_number)
    self.active_sessions[session_token] = (account_number, time.time() + 3600)  # 1小时有效期
    self.save_data()
    return True, "登录成功", session_token

def logout(self, session_token: str):
    """登出"""
    if session_token in self.active_sessions:
        del self.active_sessions[session_token]

def validate_session(self, session_token: str) -> Optional[BankAccount]:
    """验证会话, 返回账户对象"""
    if session_token not in self.active_sessions:
        return None
    acc_num, expiry = self.active_sessions[session_token]
    if time.time() > expiry:
        del self.active_sessions[session_token]
        return None
    # 额外用token内容验证
    if not CypherSecurity.verify_session_token(session_token, acc_num, max_age_seconds=3600):
        del self.active_sessions[session_token]
        return None
    return self.accounts.get(acc_num)

def get_account_balance(self, account: BankAccount) -> float:
    """查询余额"""
    return account.balance

def get_transaction_history(self, account: BankAccount, limit: int = 20) -> List[Transaction]:
    """获取交易历史, 按时间倒序"""
    sorted_tx = sorted(account.transactions, key=lambda x: x.timestamp, reverse=True)
    return sorted_tx[:limit]

def transfer(self, from_account: BankAccount, to_account_number: str, amount: float, 
             description: str = "", session_token: str = None) -> Tuple[bool, str]:
    """
    转账核心逻辑
    返回: (成功, 消息)
    """
    # 验证会话 (传递进来保证已校验)
    if not session_token or not self.validate_session(session_token):
        return False, "会话无效, 请重新登录"

    # 基本校验
    if amount <= 0:
        return False, "转账金额必须大于0"

    # 检查目标账户是否存在
    to_account = self.accounts.get(to_account_number)
    if not to_account:
        return False, "收款账户不存在"

    if to_account.status != AccountStatus.ACTIVE:
        return False, "收款账户状态异常"

    # 检查余额
    if from_account.balance < amount:
        return False, "余额不足"

    # 每日限额检查
    self.reset_daily_limit_if_needed(from_account)
    if from_account.daily_transferred + amount > from_account.daily_transfer_limit:
        remaining = from_account.daily_transfer_limit - from_account.daily_transferred
        return False, f"超出每日转账限额, 今日剩余额度: {remaining:.2f}"

    # 高安全等级可能需要额外签名 (模拟)
    if from_account.security_level == SecurityLevel.HIGH and amount > 50000:
        # 实际场景需二次确认,这里简化模拟签名
        print(f"[高安全] 大额转账 {amount} 需额外验证, 模拟通过")

    # 执行转账 (原子操作)
    from_account.balance -= amount
    to_account.balance += amount

    # 更新每日已转额度
    from_account.daily_transferred += amount

    # 创建交易记录(转出方)
    tx_id_out = str(uuid.uuid4())
    timestamp = datetime.now()
    tx_out = Transaction(
        transaction_id=tx_id_out,
        account_number=from_account.account_number,
        type=TransactionType.TRANSFER,
        amount=-amount,  # 负数表示支出
        balance_after=from_account.balance,
        counterparty=to_account_number,
        timestamp=timestamp,
        signature="",
        description=description or f"转账至{to_account.owner_name}"
    )
    # 生成签名
    tx_dict = tx_out.to_dict()
    tx_out.signature = CypherSecurity.sign_transaction(tx_dict)
    from_account.transactions.append(tx_out)

    # 收款方记录
    tx_id_in = str(uuid.uuid4())
    tx_in = Transaction(
        transaction_id=tx_id_in,
        account_number=to_account.account_number,
        type=TransactionType.RECEIVE,
        amount=amount,
        balance_after=to_account.balance,
        counterparty=from_account.account_number,
        timestamp=timestamp,
        signature="",
        description=description or f"来自{from_account.owner_name}"
    )
    tx_in.signature = CypherSecurity.sign_transaction(tx_in.to_dict())
    to_account.transactions.append(tx_in)

    # 保存数据
    self.save_data()
    return True, f"转账成功! 金额: {amount:.2f} {from_account.currency}, 交易ID: {tx_id_out[:8]}"

def deposit(self, account: BankAccount, amount: float, description: str = "") -> Tuple[bool, str]:
    """存款 (模拟现金/电子存入)"""
    if amount <= 0:
        return False, "存款金额必须大于0"
    account.balance += amount
    tx = Transaction(
        transaction_id=str(uuid.uuid4()),
        account_number=account.account_number,
        type=TransactionType.DEPOSIT,
        amount=amount,
        balance_after=account.balance,
        counterparty="现金存入/电子渠道",
        timestamp=datetime.now(),
        signature="",
        description=description or "现金存款"
    )
    tx.signature = CypherSecurity.sign_transaction(tx.to_dict())
    account.transactions.append(tx)
    self.save_data()
    return True, f"存款成功! 存入 {amount:.2f}, 当前余额 {account.balance:.2f}"

def withdraw(self, account: BankAccount, amount: float, description: str = "") -> Tuple[bool, str]:
    """取款"""
    if amount <= 0:
        return False, "取款金额必须大于0"
    if account.balance < amount:
        return False, "余额不足"
    account.balance -= amount
    tx = Transaction(
        transaction_id=str(uuid.uuid4()),
        account_number=account.account_number,
        type=TransactionType.WITHDRAWAL,
        amount=-amount,
        balance_after=account.balance,
        counterparty="ATM/柜面",
        timestamp=datetime.now(),
        signature="",
        description=description or "现金取款"
    )
    tx.signature = CypherSecurity.sign_transaction(tx.to_dict())
    account.transactions.append(tx)
    self.save_data()
    return True, f"取款成功! 取出 {amount:.2f}, 剩余 {account.balance:.2f}"

def change_pin(self, account: BankAccount, old_pin: str, new_pin: str) -> Tuple[bool, str]:
    """修改密码"""
    if not CypherSecurity.verify_pin(old_pin, account.pin_hash):
        return False, "原密码错误"
    if len(new_pin) < 4 or len(new_pin) > 8 or not new_pin.isdigit():
        return False, "新密码必须为4-8位数字"
    account.pin_hash = CypherSecurity.hash_pin(new_pin)
    self.save_data()
    return True, "密码修改成功"

def get_account_info(self, account: BankAccount) -> dict:
    """获取账户概要信息"""
    return account.to_dict()

===================== 模拟APP前端界面 (CLI交互) =====================

class BankAppSimulator:
"""银行APP模拟器主界面 - 赛博风格终端"""

def __init__(self):
    self.engine = CypherBankEngine()
    self.current_session = None
    self.current_account = None

def clear_screen(self):
    """清屏模拟"""
    os.system('cls' if os.name == 'nt' else 'clear')
    print("\n" + "=" * 60)
    print("   🏦 CYPHER BANK · 安全银行模拟器 v2.0  [开源模型]")
    print("=" * 60)

def display_main_menu(self):
    """主菜单"""
    print("\n📱 主菜单:")
    print("1. 登录账户")
    print("2. 关于本系统")
    print("0. 退出")

def display_account_menu(self):
    """账户操作菜单"""
    print("\n💳 账户操作:")
    print("1. 查询余额")
    print("2. 交易记录")
    print("3. 转账汇款")
    print("4. 存款(模拟)")
    print("5. 取款(模拟)")
    print("6. 修改密码")
    print("7. 账户详情")
    print("8. 安全登出")
    print("0. 返回主菜单")

def login_flow(self):
    """登录流程"""
    print("\n🔐 登录系统")
    acc_num = input("请输入账号: ").strip()
    pin = input("请输入6位PIN密码: ").strip()

    # 检查是否需要2FA
    success, msg, token = self.engine.login(acc_num, pin, otp=None)
    if success:
        self.current_session = token
        self.current_account = self.engine.validate_session(token)
        print(f"✅ {msg}")
        time.sleep(1)
        return True
    elif "需要两步验证" in msg:
        print(f"⚠️ {msg}")
        otp_input = input("请输入6位验证码: ").strip()
        success2, msg2, token2 = self.engine.login(acc_num, pin, otp=otp_input)
        if success2:
            self.current_session = token2
            self.current_account = self.engine.validate_session(token2)
            print(f"✅ {msg2}")
            time.sleep(1)
            return True
        else:
            print(f"❌ {msg2}")
            input("按回车继续...")
            return False
    else:
        print(f"❌ {msg}")
        input("按回车继续...")
        return False

def run_account_services(self):
    """运行账户服务"""
    while True:
        self.clear_screen()
        if not self.current_account:
            break
        owner = self.current_account.owner_name
        print(f"\n👤 欢迎, {owner}  |  账户: {self.current_account.account_number[-4:]}")
        self.display_account_menu()
        choice = input("\n请选择操作: ").strip()

        if choice == "1":
            self.show_balance()
        elif choice == "2":
            self.show_transactions()
        elif choice == "3":
            self.do_transfer()
        elif choice == "4":
            self.do_deposit()
        elif choice == "5":
            self.do_withdraw()
        elif choice == "6":
            self.change_pin()
        elif choice == "7":
            self.show_account_details()
        elif choice == "8":
            self.logout()
            break
        elif choice == "0":
            self.logout()
            break
        else:
            print("无效选项")
            time.sleep(1)

def show_balance(self):
    """显示余额"""
    bal = self.engine.get_account_balance(self.current_account)
    print(f"\n💰 当前余额: {bal:.2f} {self.current_account.currency}")
    input("\n按回车返回...")

def show_transactions(self):
    """显示交易记录"""
    print("\n📜 最近交易记录:")
    txs = self.engine.get_transaction_history(self.current_account, limit=10)
    if not txs:
        print("暂无交易记录")
    else:
        for tx in txs:
            amount_str = f"{tx.amount:+.2f}" if isinstance(tx.amount, (int, float)) else str(tx.amount)
            print(f"{tx.timestamp.strftime('%Y-%m-%d %H:%M')} | {tx.type.value:6s} | {amount_str:>10} | {tx.counterparty:15} | {tx.description}")
    input("\n按回车返回...")

def do_transfer(self):
    """执行转账"""
    print("\n💸 转账汇款")
    to_acc = input("请输入收款账号: ").strip()
    try:
        amount = float(input("请输入转账金额: "))
    except ValueError:
        print("金额格式错误")
        input("按回车返回...")
        return
    desc = input("请输入备注(可选): ").strip()

    success, msg = self.engine.transfer(self.current_account, to_acc, amount, desc, self.current_session)
    print(f"\n{'✅' if success else '❌'} {msg}")
    input("按回车返回...")

def do_deposit(self):
    """存款"""
    try:
        amount = float(input("请输入存款金额: "))
    except ValueError:
        print("金额无效")
        return
    success, msg = self.engine.deposit(self.current_account, amount, "APP存款")
    print(f"\n{msg}")
    input("按回车返回...")

def do_withdraw(self):
    """取款"""
    try:
        amount = float(input("请输入取款金额: "))
    except ValueError:
        print("金额无效")
        return
    success, msg = self.engine.withdraw(self.current_account, amount, "APP取款")
    print(f"\n{msg}")
    input("按回车返回...")

def change_pin(self):
    """修改密码"""
    old = input("请输入原密码: ").strip()
    new = input("请输入新密码(4-8位数字): ").strip()
    confirm = input("确认新密码: ").strip()
    if new != confirm:
        print("两次输入不一致")
        input("按回车返回...")
        return
    success, msg = self.engine.change_pin(self.current_account, old, new)
    print(f"\n{msg}")
    input("按回车返回...")

def show_account_details(self):
    """账户详情"""
    info = self.engine.get_account_info(self.current_account)
    print("\n🏦 账户详细信息:")
    for k, v in info.items():
        print(f"  {k}: {v}")
    input("\n按回车返回...")

def logout(self):
    """登出"""
    if self.current_session:
        self.engine.logout(self.current_session)
        self.current_session = None
        self.current_account = None
        print("✅ 已安全登出")
        time.sleep(1)

def about(self):
    """关于"""
    print("\n📡 Cypher Bank 模拟器 - 开源项目")
    print("基于SHA-256哈希、会话令牌、交易签名等安全模型")
    print("演示账号: 6228480012345678 / 123456")
    print("高安全账号: 6228480055556666 / 888888 (需2FA验证码)")
    print("所有数据持久化保存在 bank_data.json")
    input("\n按回车返回...")

def run(self):
    """主循环"""
    while True:
        self.clear_screen()
        self.display_main_menu()
        choice = input("请选择: ").strip()
        if choice == "1":
            if self.login_flow():
                self.run_account_services()
        elif choice == "2":
            self.about()
        elif choice == "0":
            print("\n感谢使用Cypher银行模拟器,再见!")
            self.engine.save_data()
            break
        else:
            print("无效选项")
            time.sleep(1)

===================== 程序入口 =====================

if name == "main":
app = BankAppSimulator()
app.run()

相关文章
|
2天前
|
人工智能 JSON 机器人
让龙虾成为你的“公众号分身” | 阿里云服务器玩Openclaw
本文带你零成本玩转OpenClaw:学生认证白嫖6个月阿里云服务器,手把手配置飞书机器人、接入免费/高性价比AI模型(NVIDIA/通义),并打造微信公众号“全自动分身”——实时抓热榜、AI选题拆解、一键发布草稿,5分钟完成热点→文章全流程!
10264 35
让龙虾成为你的“公众号分身” | 阿里云服务器玩Openclaw
|
14天前
|
人工智能 安全 Linux
【OpenClaw保姆级图文教程】阿里云/本地部署集成模型Ollama/Qwen3.5/百炼 API 步骤流程及避坑指南
2026年,AI代理工具的部署逻辑已从“单一云端依赖”转向“云端+本地双轨模式”。OpenClaw(曾用名Clawdbot)作为开源AI代理框架,既支持对接阿里云百炼等云端免费API,也能通过Ollama部署本地大模型,完美解决两类核心需求:一是担心云端API泄露核心数据的隐私安全诉求;二是频繁调用导致token消耗过高的成本控制需求。
5948 14
|
22天前
|
人工智能 JavaScript Ubuntu
5分钟上手龙虾AI!OpenClaw部署(阿里云+本地)+ 免费多模型配置保姆级教程(MiniMax、Claude、阿里云百炼)
OpenClaw(昵称“龙虾AI”)作为2026年热门的开源个人AI助手,由PSPDFKit创始人Peter Steinberger开发,核心优势在于“真正执行任务”——不仅能聊天互动,还能自动处理邮件、管理日程、订机票、写代码等,且所有数据本地处理,隐私完全可控。它支持接入MiniMax、Claude、GPT等多类大模型,兼容微信、Telegram、飞书等主流聊天工具,搭配100+可扩展技能,成为兼顾实用性与隐私性的AI工具首选。
23235 120
|
8天前
|
人工智能 JavaScript API
解放双手!OpenClaw Agent Browser全攻略(阿里云+本地部署+免费API+网页自动化场景落地)
“让AI聊聊天、写代码不难,难的是让它自己打开网页、填表单、查数据”——2026年,无数OpenClaw用户被这个痛点困扰。参考文章直击核心:当AI只能“纸上谈兵”,无法实际操控浏览器,就永远成不了真正的“数字员工”。而Agent Browser技能的出现,彻底打破了这一壁垒——它给OpenClaw装上“上网的手和眼睛”,让AI能像真人一样打开网页、点击按钮、填写表单、提取数据,24小时不间断完成网页自动化任务。
1965 4