以下は、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. 動作確認
- カード番号と暗証番号を入力してログインします。
- ログイン後、残高確認、入金、出金、振込などの操作を選択できます。
- 各操作が正しくデータベースに反映されることを確認します。
この例は基本的な機能を実装していますが、実際のシステムではさらにエラーハンドリングやセキュリティ対策を強化する必要があります。