说明:代码编写时加入了保存账户数据到file和Redis中。
完整代码如下:
package utils
import (
"log"
"io/ioutil"
"os"
"fmt"
"strings"
)
//错误检查
func CheckError(err error) {
if err != nil {
log.Fatal(err)
panic(err)
}
}
//定义结构体familyAccount
type familyAccount struct {
//为了接收用户的输入选择,我们需要定义一个变量
key string
loop bool //使用loop 来控制是否继续显示菜单
money float64 //表示一次收支金额
balance float64 // 表示账号金额(余额)
details string // 拼接每次收支的情况
flag bool // 标识是否有收支
}
//工厂模拟返回familyAccount实例
func NewFamilyAccount() *familyAccount{
return &familyAccount{
key : "",
loop : true,
money : 0,
balance : 10000,
details : "收支\t账户金额\t收支金额\t说 明",
flag : false,
}
}
//显示主菜单
func (this *familyAccount) MainMenu() {
//使用for循环来显示菜单
for {
fmt.Println("-----------------家庭收支记账软件-----------------")
fmt.Println(" 1 收支明细")
fmt.Println(" 2 登记收入")
fmt.Println(" 3 登记支出")
fmt.Println(" 4 退 出")
fmt.Println(" 5 保存数据退出")
fmt.Println(" 6 恢复账户明细")
fmt.Print("请选择(1-6):")
//为了接收用户的输入选择,我们需要定义一个变量
fmt.Scanln(&this.key)
switch this.key {
case "1":
this.showDetails()
case "2":
this.income()
case "3":
this.pay()
case "4":
this.exit()
case "5":
this.saveExit()
case "6":
this.recoverInfor()
default :
fmt.Println("你的输入有误,请重新选择..")
}
//根据loop 来决定是否继续显示菜单
if !this.loop {
break
}
}
fmt.Println("你退出了该软件...")
}
//显示收支明细
func (this *familyAccount) showDetails() {
fmt.Println("-----------------当前收支明细记录-----------------")
if this.flag {
fmt.Println(this.details)
} else {
fmt.Println("当前没有收支明细... 来一笔吧!")
}
fmt.Print("\n\n")
}
//登记收入
func (this *familyAccount) income() {
this.flag = true
fmt.Println("本次收入金额:")
fmt.Scanln(&this.money)
//你的余额要变化
this.balance += this.money
fmt.Println("本次收入说明:")
note := ""
fmt.Scanln(¬e)
//拼接这个说明
this.details += fmt.Sprintf("\n收入\t%v\t%v\t%v", this.balance,
this.money, note)
fmt.Println("---------------------登记完成---------------------")
}
//支出登记
func (this *familyAccount) pay() {
this.flag = true
fmt.Println("本次支出金额:")
fmt.Scanln(&this.money)
if this.money > this.balance {
fmt.Println("你的余额不足..")
return
}
//你的余额要变化
this.balance -= this.money
fmt.Println("本次支出说明:")
note := ""
fmt.Scanln(¬e)
//拼接这个说明
this.details += fmt.Sprintf("\n支出\t%v\t%v\t%v", this.balance,
this.money, note)
fmt.Println("---------------------支出完成---------------------")
}
//退出
func (this *familyAccount) exit() {
// 这里加入 提示是否退出,并要求是y/n
fmt.Println("你确定要退出吗? y/n")
var choice string
for {
fmt.Scanln(&choice)
//判断choice 是不是 y/n [Y/n]
choice = strings.ToLower(choice)
if choice == "y" || choice == "n" {
break
}
fmt.Println("你确定要退出吗? y/n")
}
//这里再去判断choice
if choice == "y" {
this.loop = false
}
}
//保存数据退出
func (this *familyAccount) saveExit() {
// 这里加入 提示是否退出,并要求是y/n
fmt.Println("你确定要退出吗? y/n")
var choice string
for {
fmt.Scanln(&choice)
//判断choice 是不是 y/n [Y/n]
choice = strings.ToLower(choice)
if choice == "y" || choice == "n" {
break
}
fmt.Println("你确定要退出吗? y/n")
}
//这里再去判断choice
if choice == "y" {
this.loop = false
// saveFileData(this.details)
SaveDBData(this.details)
}
}
//恢复账户明细
func (this *familyAccount) recoverInfor() {
/*账户数据保存到本地File*/
// str := restoreFileData()
// fmt.Println(str)
/*账户数据保存到Redis*/
str := ReadDBData()
fmt.Println(str)
this.details = str
this.flag = true
}
func saveFileData(details string)(){
filePath := "user.txt"
//1、打开文件
file, err := os.OpenFile(filePath, os.O_RDWR | os.O_APPEND | os. O_CREATE,066) // For read access.
//2、关闭文件
defer file.Close()
CheckError(err)
// 3、写入数据
str := details
data := []byte(str)
err = ioutil.WriteFile(filePath,data,066)
CheckError(err)
}
func restoreFileData() (details string){
filePath := "user.txt"
//1、打开文件
file, err := os.OpenFile(filePath, os.O_RDWR | os.O_APPEND | os. O_CREATE,066) // For read access.
//2、关闭文件
defer file.Close()
CheckError(err)
//4、读取文件
res, err := ioutil.ReadFile(filePath)
CheckError(err)
// fmt.Println(string(res))
return string(res)
}
/*面向对象实现*/
func MyFamilyAccountOOP() {
familyAccount := NewFamilyAccount()
familyAccount.MainMenu()
}