ATM 模拟器 Golang 程序--示例

发布于:2025-06-14 ⋅ 阅读:(21) ⋅ 点赞:(0)

 1.示例截图:

 2.功能说明

程序功能说明
这个 ATM 模拟器实现了以下核心功能:
用户账户管理:
初始化了几个测试账户用于演示
支持登录和登出功能
PIN 验证和锁定机制(尝试 3 次错误后锁定)
基本交易操作:
余额查询:显示当前账户余额
取款:从账户中提取现金
存款:向账户中存入现金
转账:向其他账户转账
交易记录:
记录每笔交易的详细信息
支持查看历史交易记录
使用方法
程序启动后,首先需要登录(使用测试账户)
卡号:1234567890,PIN:1234
卡号:0987654321,PIN:4321
卡号:5678901234,PIN:5678
登录后,可以选择各种交易操作:
查询余额
取款
存款
转账
查看交易记录
登出或退出
所有操作都会实时更新账户余额和交易记录

3.程序代码:

package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"
	"time"
)

// 账户结构
type Account struct {
	AccountNumber string
	Pin           string
	Balance       float64
	Transactions  []Transaction
}

// 交易记录结构
type Transaction struct {
	Type      string    // 交易类型:存款、取款、转账
	Amount    float64   // 交易金额
	Timestamp time.Time // 交易时间
	ToAccount string    // 转账目标账户(仅在转账时使用)
}

// ATM 结构
type ATM struct {
	Accounts       map[string]*Account // 账户映射表,键为卡号
	CurrentAccount *Account            // 当前登录的账户
}

// 创建新的 ATM
func NewATM() *ATM {
	// 初始化一些测试账户
	accounts := make(map[string]*Account)

	// 添加几个测试账户
	accounts["1234567890"] = &Account{
		AccountNumber: "1234567890",
		Pin:           "1234",
		Balance:       1000.00,
		Transactions:  []Transaction{},
	}

	accounts["0987654321"] = &Account{
		AccountNumber: "0987654321",
		Pin:           "4321",
		Balance:       5000.00,
		Transactions:  []Transaction{},
	}

	accounts["5678901234"] = &Account{
		AccountNumber: "5678901234",
		Pin:           "5678",
		Balance:       2500.00,
		Transactions:  []Transaction{},
	}

	return &ATM{
		Accounts: accounts,
	}
}

// 主菜单
func (atm *ATM) ShowMainMenu() {
	reader := bufio.NewReader(os.Stdin)

	for {
		if atm.CurrentAccount == nil {
			fmt.Println("\n===== ATM 模拟器 =====")
			fmt.Println("1. 登录")
			fmt.Println("2. 退出")
			fmt.Print("请选择操作: ")

			choice, err := reader.ReadString('\n')
			if err != nil {
				fmt.Println("读取输入错误:", err)
				continue
			}

			choice = strings.TrimSpace(choice)

			switch choice {
			case "1":
				atm.Login()
			case "2":
				fmt.Println("感谢使用,再见!")
				return
			default:
				fmt.Println("无效选择,请重试。")
			}
		} else {
			fmt.Println("\n===== 欢迎使用 ATM 服务 =====")
			fmt.Printf("当前账户: %s\n", atm.CurrentAccount.AccountNumber)
			fmt.Println("1. 查询余额")
			fmt.Println("2. 取款")
			fmt.Println("3. 存款")
			fmt.Println("4. 转账")
			fmt.Println("5. 查看交易记录")
			fmt.Println("6. 登出")
			fmt.Println("7. 退出")
			fmt.Print("请选择操作: ")

			choice, err := reader.ReadString('\n')
			if err != nil {
				fmt.Println("读取输入错误:", err)
				continue
			}

			choice = strings.TrimSpace(choice)

			switch choice {
			case "1":
				atm.CheckBalance()
			case "2":
				atm.Withdraw()
			case "3":
				atm.Deposit()
			case "4":
				atm.Transfer()
			case "5":
				atm.ShowTransactions()
			case "6":
				atm.Logout()
			case "7":
				fmt.Println("感谢使用,再见!")
				return
			default:
				fmt.Println("无效选择,请重试。")
			}
		}
	}
}

// 登录功能
func (atm *ATM) Login() {
	reader := bufio.NewReader(os.Stdin)

	fmt.Print("请输入卡号: ")
	accountNumber, err := reader.ReadString('\n')
	if err != nil {
		fmt.Println("读取输入错误:", err)
		return
	}
	accountNumber = strings.TrimSpace(accountNumber)

	account, exists := atm.Accounts[accountNumber]
	if !exists {
		fmt.Println("卡号不存在,请重试。")
		return
	}

	// 尝试3次PIN输入
	for attempts := 0; attempts < 3; attempts++ {
		fmt.Print("请输入PIN: ")
		pin, err := reader.ReadString('\n')
		if err != nil {
			fmt.Println("读取输入错误:", err)
			return
		}
		pin = strings.TrimSpace(pin)

		if pin == account.Pin {
			atm.CurrentAccount = account
			fmt.Println("登录成功!")
			return
		} else {
			fmt.Printf("PIN错误,还有%d次尝试机会。\n", 2-attempts)
		}
	}

	fmt.Println("尝试次数过多,账户已锁定。")
}

// 登出功能
func (atm *ATM) Logout() {
	atm.CurrentAccount = nil
	fmt.Println("已成功登出。")
}

// 查询余额
func (atm *ATM) CheckBalance() {
	if atm.CurrentAccount == nil {
		fmt.Println("请先登录。")
		return
	}

	fmt.Printf("当前余额: ¥%.2f\n", atm.CurrentAccount.Balance)
}

// 取款功能
func (atm *ATM) Withdraw() {
	if atm.CurrentAccount == nil {
		fmt.Println("请先登录。")
		return
	}

	reader := bufio.NewReader(os.Stdin)

	fmt.Print("请输入取款金额: ¥")
	amountStr, err := reader.ReadString('\n')
	if err != nil {
		fmt.Println("读取输入错误:", err)
		return
	}
	amountStr = strings.TrimSpace(amountStr)

	amount, err := strconv.ParseFloat(amountStr, 64)
	if err != nil {
		fmt.Println("请输入有效的金额。")
		return
	}

	if amount <= 0 {
		fmt.Println("取款金额必须大于0。")
		return
	}

	if amount > atm.CurrentAccount.Balance {
		fmt.Println("余额不足。")
		return
	}

	// 模拟取款过程
	fmt.Println("正在处理取款请求...")
	time.Sleep(1 * time.Second)

	atm.CurrentAccount.Balance -= amount

	// 添加交易记录
	atm.CurrentAccount.Transactions = append(atm.CurrentAccount.Transactions, Transaction{
		Type:      "取款",
		Amount:    amount,
		Timestamp: time.Now(),
	})

	fmt.Printf("取款成功!已取出 ¥%.2f\n", amount)
	fmt.Printf("当前余额: ¥%.2f\n", atm.CurrentAccount.Balance)
}

// 存款功能
func (atm *ATM) Deposit() {
	if atm.CurrentAccount == nil {
		fmt.Println("请先登录。")
		return
	}

	reader := bufio.NewReader(os.Stdin)

	fmt.Print("请输入存款金额: ¥")
	amountStr, err := reader.ReadString('\n')
	if err != nil {
		fmt.Println("读取输入错误:", err)
		return
	}
	amountStr = strings.TrimSpace(amountStr)

	amount, err := strconv.ParseFloat(amountStr, 64)
	if err != nil {
		fmt.Println("请输入有效的金额。")
		return
	}

	if amount <= 0 {
		fmt.Println("存款金额必须大于0。")
		return
	}

	// 模拟存款过程
	fmt.Println("正在处理存款请求...")
	time.Sleep(1 * time.Second)

	atm.CurrentAccount.Balance += amount

	// 添加交易记录
	atm.CurrentAccount.Transactions = append(atm.CurrentAccount.Transactions, Transaction{
		Type:      "存款",
		Amount:    amount,
		Timestamp: time.Now(),
	})

	fmt.Printf("存款成功!已存入 ¥%.2f\n", amount)
	fmt.Printf("当前余额: ¥%.2f\n", atm.CurrentAccount.Balance)
}

// 转账功能
func (atm *ATM) Transfer() {
	if atm.CurrentAccount == nil {
		fmt.Println("请先登录。")
		return
	}

	reader := bufio.NewReader(os.Stdin)

	fmt.Print("请输入目标账户卡号: ")
	targetAccountNumber, err := reader.ReadString('\n')
	if err != nil {
		fmt.Println("读取输入错误:", err)
		return
	}
	targetAccountNumber = strings.TrimSpace(targetAccountNumber)

	if targetAccountNumber == atm.CurrentAccount.AccountNumber {
		fmt.Println("不能向自己的账户转账。")
		return
	}

	targetAccount, exists := atm.Accounts[targetAccountNumber]
	if !exists {
		fmt.Println("目标账户不存在。")
		return
	}

	fmt.Print("请输入转账金额: ¥")
	amountStr, err := reader.ReadString('\n')
	if err != nil {
		fmt.Println("读取输入错误:", err)
		return
	}
	amountStr = strings.TrimSpace(amountStr)

	amount, err := strconv.ParseFloat(amountStr, 64)
	if err != nil {
		fmt.Println("请输入有效的金额。")
		return
	}

	if amount <= 0 {
		fmt.Println("转账金额必须大于0。")
		return
	}

	if amount > atm.CurrentAccount.Balance {
		fmt.Println("余额不足。")
		return
	}

	// 模拟转账过程
	fmt.Println("正在处理转账请求...")
	time.Sleep(1 * time.Second)

	atm.CurrentAccount.Balance -= amount
	targetAccount.Balance += amount

	// 添加交易记录
	atm.CurrentAccount.Transactions = append(atm.CurrentAccount.Transactions, Transaction{
		Type:      "转账",
		Amount:    amount,
		Timestamp: time.Now(),
		ToAccount: targetAccountNumber,
	})

	targetAccount.Transactions = append(targetAccount.Transactions, Transaction{
		Type:      "接收转账",
		Amount:    amount,
		Timestamp: time.Now(),
		ToAccount: atm.CurrentAccount.AccountNumber,
	})

	fmt.Printf("转账成功!已向账户 %s 转账 ¥%.2f\n", targetAccountNumber, amount)
	fmt.Printf("当前余额: ¥%.2f\n", atm.CurrentAccount.Balance)
}

// 显示交易记录
func (atm *ATM) ShowTransactions() {
	if atm.CurrentAccount == nil {
		fmt.Println("请先登录。")
		return
	}

	transactions := atm.CurrentAccount.Transactions
	if len(transactions) == 0 {
		fmt.Println("没有交易记录。")
		return
	}

	fmt.Println("\n===== 交易记录 =====")
	fmt.Println("序号\t类型\t\t金额\t\t时间\t\t\t目标账户")

	for i, tx := range transactions {
		target := ""
		if tx.ToAccount != "" {
			target = tx.ToAccount
		}

		fmt.Printf("%d\t%s\t\t¥%.2f\t\t%s\t%s\n",
			i+1, tx.Type, tx.Amount, tx.Timestamp.Format("2006-01-02 15:04:05"), target)
	}
}

func main() {
	fmt.Println("===== ATM 模拟器启动 =====")

	atm := NewATM()
	atm.ShowMainMenu()
}


网站公告

今日签到

点亮在社区的每一天
去签到