CyberChaos(さいばかおす)

プログラミング言語、トランスパイラ、RPA、ChatGPT、データマイニング、リバースエンジニアリングのための忘備録

GoとCockroach DBを用いたGUI勘定系システムの例

2025-03-02 03:01:52 | Golang、Go言語
以下は、Go言語とCockroachDBを使用したGUI勘定系システムの例です。このシステムは、ユーザーがカードを挿入し、暗証番号を入力して、残高確認、入金、出金、振込などの操作を行えるようにします。GUIには`fyne`ライブラリを使用し、データベースにはCockroachDBを使用します。

### 1. データベースの準備
まず、CockroachDBに`accounts`テーブルを作成します。

```sql
CREATE TABLE accounts (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
card_number TEXT NOT NULL UNIQUE,
pin TEXT NOT NULL,
balance DECIMAL(10, 2) NOT NULL
);
```

### 2. Goプロジェクトの設定
Goプロジェクトを作成し、必要なライブラリをインストールします。

```bash
go mod init account_system
go get fyne.io/fyne/v2
go get github.com/lib/pq
```

### 3. Goコードの実装
以下は、GoでGUI勘定系システムを実装するコード例です。

```go
package main

import (
"database/sql"
"fmt"
"log"
"strconv"

"fyne.io/fyne/v2"
"fyne.io/fyne/v2/app"
"fyne.io/fyne/v2/container"
"fyne.io/fyne/v2/dialog"
"fyne.io/fyne/v2/widget"
_ "github.com/lib/pq"
)

type Account struct {
ID string
CardNumber string
PIN string
Balance float64
}

var db *sql.DB

func main() {
// Initialize database connection
initDB()

// Create Fyne application
a := app.New()
w := a.NewWindow("Account Management System")
w.Resize(fyne.NewSize(400, 300))

// Card insertion
cardEntry := widget.NewEntry()
cardEntry.SetPlaceHolder("Insert your card number")

// PIN entry
pinEntry := widget.NewPasswordEntry()
pinEntry.SetPlaceHolder("Enter your 4-digit PIN")

// Login button
loginButton := widget.NewButton("Login", func() {
cardNumber := cardEntry.Text
pin := pinEntry.Text

account, err := authenticate(cardNumber, pin)
if err != nil {
dialog.ShowError(fmt.Errorf("Authentication failed"), w)
return
}

showMainMenu(w, account)
})

// Layout
loginContainer := container.NewVBox(
widget.NewLabel("Welcome to the Account Management System"),
cardEntry,
pinEntry,
loginButton,
)

w.SetContent(loginContainer)
w.ShowAndRun()
}

func initDB() {
var err error
connStr := "postgresql://root@localhost:26257/bank?sslmode=disable"
db, err = sql.Open("postgres", connStr)
if err != nil {
log.Fatal(err)
}

err = db.Ping()
if err != nil {
log.Fatal(err)
}

fmt.Println("Connected to CockroachDB")
}

func authenticate(cardNumber, pin string) (*Account, error) {
var account Account
query := `SELECT id, card_number, pin, balance FROM accounts WHERE card_number = $1 AND pin = $2`
err := db.QueryRow(query, cardNumber, pin).Scan(&account.ID, &account.CardNumber, &account.PIN, &account.Balance)
if err != nil {
return nil, err
}
return &account, nil
}

func showMainMenu(w fyne.Window, account *Account) {
// Main menu options
balanceButton := widget.NewButton("Check Balance", func() {
showBalance(w, account)
})

depositButton := widget.NewButton("Deposit", func() {
showDeposit(w, account)
})

withdrawButton := widget.NewButton("Withdraw", func() {
showWithdraw(w, account)
})

transferButton := widget.NewButton("Transfer", func() {
showTransfer(w, account)
})

// Layout
menuContainer := container.NewVBox(
widget.NewLabel("Main Menu"),
balanceButton,
depositButton,
withdrawButton,
transferButton,
)

w.SetContent(menuContainer)
}

func showBalance(w fyne.Window, account *Account) {
balanceLabel := widget.NewLabel(fmt.Sprintf("Your current balance is: $%.2f", account.Balance))

printButton := widget.NewButton("Print Statement", func() {
dialog.ShowInformation("Print", "Statement printed successfully", w)
w.Close()
})

noPrintButton := widget.NewButton("No Print", func() {
dialog.ShowInformation("Thank You", "Thank you for using our service", w)
w.Close()
})

// Layout
balanceContainer := container.NewVBox(
balanceLabel,
printButton,
noPrintButton,
)

w.SetContent(balanceContainer)
}

func showDeposit(w fyne.Window, account *Account) {
amountEntry := widget.NewEntry()
amountEntry.SetPlaceHolder("Enter deposit amount")

confirmButton := widget.NewButton("Confirm", func() {
amount, err := strconv.ParseFloat(amountEntry.Text, 64)
if err != nil {
dialog.ShowError(fmt.Errorf("Invalid amount"), w)
return
}

account.Balance += amount
updateBalance(account)

dialog.ShowInformation("Deposit", fmt.Sprintf("Deposit successful. New balance: $%.2f", account.Balance), w)
showMainMenu(w, account)
})

// Layout
depositContainer := container.NewVBox(
widget.NewLabel("Enter deposit amount:"),
amountEntry,
confirmButton,
)

w.SetContent(depositContainer)
}

func showWithdraw(w fyne.Window, account *Account) {
amountEntry := widget.NewEntry()
amountEntry.SetPlaceHolder("Enter withdrawal amount")

confirmButton := widget.NewButton("Confirm", func() {
amount, err := strconv.ParseFloat(amountEntry.Text, 64)
if err != nil {
dialog.ShowError(fmt.Errorf("Invalid amount"), w)
return
}

if amount > account.Balance {
dialog.ShowError(fmt.Errorf("Insufficient balance"), w)
return
}

account.Balance -= amount
updateBalance(account)

dialog.ShowInformation("Withdrawal", fmt.Sprintf("Withdrawal successful. New balance: $%.2f", account.Balance), w)
showMainMenu(w, account)
})

// Layout
withdrawContainer := container.NewVBox(
widget.NewLabel("Enter withdrawal amount:"),
amountEntry,
confirmButton,
)

w.SetContent(withdrawContainer)
}

func showTransfer(w fyne.Window, account *Account) {
bankEntry := widget.NewEntry()
bankEntry.SetPlaceHolder("Enter bank name")

branchEntry := widget.NewEntry()
branchEntry.SetPlaceHolder("Enter branch name")

accountTypeEntry := widget.NewEntry()
accountTypeEntry.SetPlaceHolder("Enter account type (普通 or 当座)")

accountNumberEntry := widget.NewEntry()
accountNumberEntry.SetPlaceHolder("Enter account number")

accountNameEntry := widget.NewEntry()
accountNameEntry.SetPlaceHolder("Enter account holder name")

amountEntry := widget.NewEntry()
amountEntry.SetPlaceHolder("Enter transfer amount")

confirmButton := widget.NewButton("Confirm", func() {
amount, err := strconv.ParseFloat(amountEntry.Text, 64)
if err != nil {
dialog.ShowError(fmt.Errorf("Invalid amount"), w)
return
}

if amount > account.Balance {
dialog.ShowError(fmt.Errorf("Insufficient balance"), w)
return
}

account.Balance -= amount
updateBalance(account)

dialog.ShowInformation("Transfer", fmt.Sprintf("Transfer successful. New balance: $%.2f", account.Balance), w)
showMainMenu(w, account)
})

// Layout
transferContainer := container.NewVBox(
widget.NewLabel("Enter transfer details:"),
bankEntry,
branchEntry,
accountTypeEntry,
accountNumberEntry,
accountNameEntry,
amountEntry,
confirmButton,
)

w.SetContent(transferContainer)
}

func updateBalance(account *Account) {
query := `UPDATE accounts SET balance = $1 WHERE id = $2`
_, err := db.Exec(query, account.Balance, account.ID)
if err != nil {
log.Fatal(err)
}
}
```

### 4. 実行方法
1. CockroachDBを起動し、`accounts`テーブルを作成します。
2. Goプロジェクトを設定し、必要なライブラリをインストールします。
3. 上記のGoコードをプロジェクトに追加し、`main.go`を実行します。

### 5. 動作確認
- カード番号と暗証番号を入力してログインします。
- ログイン後、残高確認、入金、出金、振込などの操作を選択できます。
- 各操作が正しくデータベースに反映されることを確認します。

この例は基本的な機能を実装していますが、実際のシステムではさらにエラーハンドリングやセキュリティ対策を強化する必要があります。


最新の画像もっと見る

コメントを投稿

ブログ作成者から承認されるまでコメントは反映されません。