192. go 简单项目 1-家庭收支记账软件项目
项目目录结构
familyaccount/main/main.go
package main
import (
utils "day01/familyaccount/utils"
"fmt"
)
func main() {
var name, pwd string
fmt.Println("请输入要注册的用户名和密码, 用空格隔开")
fmt.Scanf("%s %s\n", &name, &pwd)
a := utils.NewFamilyAccount(name, pwd)
a.Menu()
}
familyaccount/utils/main.go
package untils
import (
"fmt"
)
type Account struct {
Title string
Income float32
Desc string
Balance float32
}
type AccountRecord struct { // 这个结构体名称应该和上面换下, 但是应经写了这么多了不想换了
Name string
Pwd string
TotalAmount float32
Records []Account
Loop bool
Key string
}
func NewFamilyAccount(name, pwd string) (act *AccountRecord) {
for {
if len(pwd) < 6 {
fmt.Println("密码不能小于6位")
continue
}
act = &AccountRecord{
Name: name,
Pwd: pwd,
TotalAmount: 0,
Records: []Account{},
Loop: true,
}
if UserMgr == nil {
UserMgr = &UserManager{
Users: []*AccountRecord{},
}
}
UserMgr.Users = append(UserMgr.Users, act)
return
}
}
func (this *AccountRecord) Income() {
defer func() {
// 将异常处理掉, 不要让程序崩溃
err := recover()
if err != nil {
fmt.Println("err=", err)
}
}()
fmt.Println("请输入收入金额, 以及说明, 以空格隔开")
var title string = "收入"
var income float32
var desc string
_, err := fmt.Scanf("%f %s\n", &income, &desc)
if err != nil {
panic(err)
}
if income < 0 {
panic("你在开玩笑么")
}
this.TotalAmount += income
account := Account{
Title: title,
Balance: this.TotalAmount,
Income: income,
Desc: desc,
}
this.Records = append(this.Records, account)
// 收入完之后打印
this.Detail()
}
// Expenses 支出
func (this *AccountRecord) Expenses() {
defer func() {
// 将异常处理掉, 不要让程序崩溃
err := recover()
if err != nil {
fmt.Println("err=", err)
}
}()
fmt.Println("请输入支出金额以及说明,以空格隔开")
var title string = "支出"
var income float32
var desc string
_, err := fmt.Scanf("%f %s\n", &income, &desc)
if err != nil {
panic(err)
}
if income < 0 {
panic("你在开玩笑么")
}
if this.TotalAmount < income {
panic(fmt.Sprintf("你想贷款么穷逼看看你的余额:%.2f", this.TotalAmount))
}
this.TotalAmount -= income
account := Account{
Title: title,
Balance: this.TotalAmount,
Income: income,
Desc: desc,
}
this.Records = append(this.Records, account)
// 收入完之后打印
this.Detail()
}
// Detail 详情
func (this *AccountRecord) Detail() {
defer func() {
// 将异常处理掉, 不要让程序崩溃
err := recover()
if err != nil {
fmt.Println("err=", err)
}
}()
fmt.Println("--------------------------当前收支明细几率--------------------------")
fmt.Println("收支\t\t 账户金额\t\t 收支金额\t\t 说 明\t")
for _, val := range this.Records {
fmt.Printf("%v\t\t %v\t\t\t %v\t\t\t %v\t\n", val.Title, val.Balance, val.Income, val.Desc)
}
fmt.Println()
}
func (this *AccountRecord) Exit() {
fmt.Println("你确定要退出么? y/n")
choice := ""
for {
fmt.Scanln(&choice)
if choice == "y" || choice == "n" {
break
}
fmt.Println("输入错误,请重新输入 y/n")
}
if choice == "y" {
fmt.Println("退出程序")
this.Loop = false
}
}
func (this *AccountRecord) CheckUser() (isLogin bool) {
count := 3
var name, pwd string
isLogin = false
for {
fmt.Printf("请输入用户名以及密码使用空格隔开,你还有%d次机会\n", count)
_, err := fmt.Scanf("%s %s\n", &name, &pwd)
if err != nil {
// fmt.Println("程序出错, 请不要着急, 联系工作人员")
continue
}
if name == this.Name && this.Pwd == pwd {
isLogin = true
break
} else {
fmt.Println("输入错误, 请重新输入")
}
count -= 1
if count <= 0 {
fmt.Println("今日输入次数已耗尽, 请联系工作人员解锁")
break
}
}
return
}
func (this *AccountRecord) Menu() {
key := this.Key
// 如果用户名密码不匹配,直接退出程序
isLogin := this.CheckUser()
for isLogin {
fmt.Println("--------------------家庭收支记账软件---------------------")
fmt.Println("--------------------1. 收支明细---------------------")
fmt.Println("--------------------2. 等级收入---------------------")
fmt.Println("--------------------3. 等级支出---------------------")
fmt.Println("--------------------4. 显示当前系统注册的用户---------------------")
fmt.Println("--------------------5. 退出---------------------")
fmt.Println("--------------------请选择(1-4): 1---------------------")
fmt.Scanln(&key)
if len(key) == 0 {
key = "1"
}
switch key {
case "1":
fmt.Println("打印收支明细")
this.Detail()
case "2":
this.Income()
case "3":
this.Expenses()
case "4":
UserMgr.ShowUser()
case "5":
this.Exit()
default:
fmt.Println("输入错误,请重新输入")
}
if !this.Loop {
break
}
key = ""
}
}
familyaccount/utils/userMgr.go
package main
import (
utils "day01/familyaccount/utils"
"fmt"
)
func main() {
var name, pwd string
fmt.Println("请输入要注册的用户名和密码, 用空格隔开")
fmt.Scanf("%s %s\n", &name, &pwd)
a := utils.NewFamilyAccount(name, pwd)
a.Menu()
}
总结:
整体来说, 项目接口让我弄得比较混乱, 其中应该设计一个User struct存放用户数据, UserManager struct 存放注册了哪些用户;
不应该将用户信息和AccountRecord放在一起, 通过AccountRecord和Account名称应该对调, User struct中一样有一个字段关联这个用户的账户信息. 个人设计不合理导致项目混乱记录一下
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异