选择用户修改系统分类或隐藏/重命名:
- - - - - - - - +89 \ No newline at end of file diff --git a/code/base-project/base-go-v2/cmd/app/main.go b/code/base-project/base-go-v2/cmd/app/main.go index e151acb7..09211829 100644 --- a/code/base-project/base-go-v2/cmd/app/main.go +++ b/code/base-project/base-go-v2/cmd/app/main.go @@ -5,6 +5,7 @@ import ( "base-go-v2/internal/config" "base-go-v2/internal/db" "base-go-v2/internal/logx" + "base-go-v2/internal/utils/idgen" "fmt" "github.com/valyala/fasthttp" "log" @@ -30,6 +31,10 @@ func main() { log.Printf("✅ 服务器启动成功,端口%s", addr) + // 配置id + options := idgen.NewIdGeneratorOptions(1) + idgen.SetIdGenerator(options) + // 启动服务器(简洁写法) if err := fasthttp.ListenAndServe(addr, r.Handler); err != nil { log.Fatalf("❌ 服务器启动失败: %v", err) diff --git a/code/base-project/base-go-v2/go.mod b/code/base-project/base-go-v2/go.mod index b5f458ce..dcbbb701 100644 --- a/code/base-project/base-go-v2/go.mod +++ b/code/base-project/base-go-v2/go.mod @@ -13,7 +13,10 @@ require ( require ( github.com/andybalholm/brotli v1.2.0 // indirect + github.com/cespare/xxhash/v2 v2.3.0 // indirect + github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect github.com/fsnotify/fsnotify v1.9.0 // indirect + github.com/go-redis/redis/v8 v8.11.5 // indirect github.com/go-viper/mapstructure/v2 v2.4.0 // indirect github.com/klauspost/compress v1.18.1 // indirect github.com/pelletier/go-toml/v2 v2.2.4 // indirect @@ -26,6 +29,6 @@ require ( github.com/valyala/bytebufferpool v1.0.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect - golang.org/x/sys v0.37.0 // indirect + golang.org/x/sys v0.38.0 // indirect golang.org/x/text v0.30.0 // indirect ) diff --git a/code/base-project/base-go-v2/go.sum b/code/base-project/base-go-v2/go.sum index 54a58b43..1577e5fb 100644 --- a/code/base-project/base-go-v2/go.sum +++ b/code/base-project/base-go-v2/go.sum @@ -1,8 +1,14 @@ filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= github.com/andybalholm/brotli v1.2.0 h1:ukwgCxwYrmACq68yiUqwIWnGY0cTPox/M94sVwToPjQ= github.com/andybalholm/brotli v1.2.0/go.mod h1:rzTDkvFWvIrjDXZHkuS16NPggd91W3kUSvPlQ1pLaKY= +github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= +github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= +github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k= github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= +github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI= +github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo= github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg= github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs= github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= @@ -37,6 +43,8 @@ github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6Kllzaw github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/fasthttp v1.68.0 h1:v12Nx16iepr8r9ySOwqI+5RBJ/DqTxhOy1HrHoDFnok= github.com/valyala/fasthttp v1.68.0/go.mod h1:5EXiRfYQAoiO/khu4oU9VISC/eVY6JqmSpPJoHCKsz4= +github.com/yitter/idgenerator-go v1.3.3 h1:i6rzmpbCL0vlmr/tuW5+lSQzNuDG9vYBjIYRvnRcHE8= +github.com/yitter/idgenerator-go v1.3.3/go.mod h1:VVjbqFjGUsIkaXVkXEdmx1LiXUL3K1NvyxWPJBPbBpE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= @@ -45,6 +53,8 @@ go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= golang.org/x/sys v0.37.0 h1:fdNQudmxPjkdUTPnLn5mdQv7Zwvbvpaxqs831goi9kQ= golang.org/x/sys v0.37.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc= +golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= golang.org/x/text v0.30.0 h1:yznKA/E9zq54KzlzBEAWn1NXSQ8DIp/NYMy88xJjl4k= golang.org/x/text v0.30.0/go.mod h1:yDdHFIX9t+tORqspjENWgzaCVXgk0yYnYuSZ8UzzBVM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/code/base-project/base-go-v2/internal/api/auth/index.go b/code/base-project/base-go-v2/internal/api/auth/index.go index 5cc7188b..f3625ab9 100644 --- a/code/base-project/base-go-v2/internal/api/auth/index.go +++ b/code/base-project/base-go-v2/internal/api/auth/index.go @@ -1,14 +1,15 @@ package auth import ( + "base-go-v2/internal/api/money" "base-go-v2/internal/db" response "base-go-v2/internal/reponse" "base-go-v2/internal/router" "base-go-v2/internal/routinex" + "base-go-v2/internal/utils/idgen" "base-go-v2/internal/utils/jwtx" "base-go-v2/internal/utils/mapx" "base-go-v2/internal/utils/timex" - "base-go-v2/internal/utils/uid" ) func InitAuthRouter(r *router.Router) { @@ -85,7 +86,7 @@ func loginDefault(c *router.Context) error { Send() } - userId := user.GetInt("id") + userId := user.GetInt64("id") // 创建 Access Token 和 Refresh Token accessToken, err := jwtx.CreateAccessToken(userId) @@ -99,8 +100,8 @@ func loginDefault(c *router.Context) error { // 返回数据 respData := mapx.New(). - SetIntToString("userId", userId). SetKV( + "userId", userId, "username", user.GetString("username"), "seqNo", user.GetInt("seq_no"), "gender", user.GetInt("gender"), @@ -140,9 +141,10 @@ func registerDefault(c *router.Context) error { return response.Fail(c).Message("该账号已被注册").Send() } + userId := idgen.NextId() // 构造新用户数据 newUserData := mapx.New().SetKV( - "id", uid.NextID(), + "id", userId, "account", account, "password", password, ) @@ -150,10 +152,16 @@ func registerDefault(c *router.Context) error { // 插入新用户 insertedRows, err := db.InsertOne("user_info", newUserData) if err != nil { + return response.Fail(c).Message("注册失败").Send() } + if insertedRows != 1 { return response.Fail(c).Message("注册失败").Send() } + err = money.InitDefaultCategories(userId) + if err != nil { + return c.AddError(err) + } return response.Success(c).Message("注册成功").Send() } diff --git a/code/base-project/base-go-v2/internal/api/middleware/auth.go b/code/base-project/base-go-v2/internal/api/middleware/auth.go index faddcfb9..9fc39f41 100644 --- a/code/base-project/base-go-v2/internal/api/middleware/auth.go +++ b/code/base-project/base-go-v2/internal/api/middleware/auth.go @@ -21,7 +21,7 @@ func AuthMiddleware() router.HandlerFunc { // Access Token 有效 if tokenVerify.IsValid { - c.Set("user_id", tokenVerify.Claims.UserID) + c.SetUserID(tokenVerify.Claims.UserID) return nil } diff --git a/code/base-project/base-go-v2/internal/api/middleware/logger.go b/code/base-project/base-go-v2/internal/api/middleware/logger.go index 91013ad3..05e70c71 100644 --- a/code/base-project/base-go-v2/internal/api/middleware/logger.go +++ b/code/base-project/base-go-v2/internal/api/middleware/logger.go @@ -4,7 +4,7 @@ import ( "base-go-v2/internal/logx" "base-go-v2/internal/router" "base-go-v2/internal/routinex" - "base-go-v2/internal/utils/uid" + "base-go-v2/internal/utils/idgen" "time" ) @@ -20,7 +20,7 @@ func LoggerMiddleware() router.HandlerFunc { start := time.Now() // 记录开始时间 // 生成 trackID 并存入 routinex - trackID := uid.NextID() + trackID := idgen.NextId() routinex.Set(logx.TrackID, trackID) // 执行业务逻辑,并捕获错误 diff --git a/code/base-project/base-go-v2/internal/api/money/index.go b/code/base-project/base-go-v2/internal/api/money/index.go new file mode 100644 index 00000000..723d6a81 --- /dev/null +++ b/code/base-project/base-go-v2/internal/api/money/index.go @@ -0,0 +1,79 @@ +package money + +import ( + "base-go-v2/internal/db" + response "base-go-v2/internal/reponse" + "base-go-v2/internal/router" + "base-go-v2/internal/utils/idgen" + "base-go-v2/internal/utils/mapx" + "fmt" +) + +func InitMoneyRouter(r *router.Router) { + group := r.Group("money") + group.GET("/category", getUserCategory) + //group := r.Group("auth") +} + +// InitDefaultCategories 初始化系统默认分类到用户分类表 +func InitDefaultCategories(userID int64) error { + fmt.Println("进入 InitDefaultCategories ===") + + // 1. 查询系统分类表 + sysCategories, err := db.FindAll("money_sys_category", "sort_number") + if err != nil { + return err + } + + fmt.Printf("系统分类数量: %d\n", len(sysCategories)) + + // 2. 构建批量插入数据 + userCategories := make([]mapx.M, 0, len(sysCategories)) + for i, row := range sysCategories { + m := mapx.New().SetKV( + "id", idgen.NextId(), + "user_id", userID, + "name", row.GetString("name"), + "icon", row.GetString("icon"), + "type", row.GetInt("type"), + "sort_number", row.GetInt("sort_number"), + ) + fmt.Printf("用户分类 %d: %+v\n", i+1, m) + userCategories = append(userCategories, m) + } + + // 3. 批量插入到用户分类表 + if _, err := db.InsertBatch("money_user_category", userCategories); err != nil { + return err + } + + fmt.Println("初始化用户分类成功!") + return nil +} + +func getUserCategory(c *router.Context) error { + userId := c.GetUserID() + + // 查询当前用户的分类 + userCategories, err := db.Find("money_user_category", mapx.New().Set("user_id", userId), "sort_number ASC") + if err != nil { + return c.AddError(err) + } + + // 按 type 分组 + result := map[string][]mapx.M{ + "income": {}, + "expense": {}, + } + + for _, cat := range userCategories { + switch cat.GetInt("type") { + case 0: + result["income"] = append(result["income"], cat) + case 1: + result["expense"] = append(result["expense"], cat) + } + } + + return response.Success(c).Data(result).Send() +} diff --git a/code/base-project/base-go-v2/internal/api/router.go b/code/base-project/base-go-v2/internal/api/router.go index dccc8c0c..a03dd281 100644 --- a/code/base-project/base-go-v2/internal/api/router.go +++ b/code/base-project/base-go-v2/internal/api/router.go @@ -3,6 +3,7 @@ package api import ( "base-go-v2/internal/api/auth" "base-go-v2/internal/api/middleware" + "base-go-v2/internal/api/money" "base-go-v2/internal/config" "base-go-v2/internal/router" ) @@ -17,5 +18,7 @@ func InitAppRouter() *router.Router { r.Use(middleware.AuthMiddleware()).ExcludePaths("/auth/**") auth.InitAuthRouter(r) + money.InitMoneyRouter(r) + return r } diff --git a/code/base-project/base-go-v2/internal/db/insert.go b/code/base-project/base-go-v2/internal/db/insert.go index c1409f01..f833a030 100644 --- a/code/base-project/base-go-v2/internal/db/insert.go +++ b/code/base-project/base-go-v2/internal/db/insert.go @@ -3,12 +3,14 @@ package db import ( "fmt" "strings" + + "base-go-v2/internal/utils/mapx" ) // ---------------- 内部辅助函数 ---------------- // buildInsertSQL 构建插入 SQL 和参数 -func buildInsertSQL(table string, data map[string]interface{}, returning string) (string, []interface{}) { +func buildInsertSQL(table string, data mapx.M, returning string) (string, []interface{}) { columns := make([]string, 0, len(data)) placeholders := make([]string, 0, len(data)) values := make([]interface{}, 0, len(data)) @@ -34,7 +36,7 @@ func buildInsertSQL(table string, data map[string]interface{}, returning string) // ---------------- 公共方法 ---------------- // InsertOne 插入单条记录,返回受影响行数 -func InsertOne(table string, data map[string]interface{}) (int64, error) { +func InsertOne(table string, data mapx.M) (int64, error) { tx, err := DB.Beginx() if err != nil { return 0, err @@ -55,7 +57,7 @@ func InsertOne(table string, data map[string]interface{}) (int64, error) { } // InsertBatch 批量插入,返回总受影响行数 -func InsertBatch(table string, dataList []map[string]interface{}) (int64, error) { +func InsertBatch(table string, dataList []mapx.M) (int64, error) { if len(dataList) == 0 { return 0, nil } @@ -90,7 +92,7 @@ func InsertBatch(table string, dataList []map[string]interface{}) (int64, error) } // InsertOneReturnPK 插入单条记录,返回主键值 -func InsertOneReturnPK(table string, pkColumn string, data map[string]interface{}) (int64, error) { +func InsertOneReturnPK(table string, pkColumn string, data mapx.M) (int64, error) { tx, err := DB.Beginx() if err != nil { return 0, err @@ -113,7 +115,7 @@ func InsertOneReturnPK(table string, pkColumn string, data map[string]interface{ } // InsertBatchReturnPK 批量插入多条记录,返回主键数组 -func InsertBatchReturnPK(table string, pkColumn string, dataList []map[string]interface{}) ([]int64, error) { +func InsertBatchReturnPK(table string, pkColumn string, dataList []mapx.M) ([]int64, error) { if len(dataList) == 0 { return nil, nil } diff --git a/code/base-project/base-go-v2/internal/logx/log.go b/code/base-project/base-go-v2/internal/logx/log.go index 4fba5172..8448e579 100644 --- a/code/base-project/base-go-v2/internal/logx/log.go +++ b/code/base-project/base-go-v2/internal/logx/log.go @@ -3,8 +3,8 @@ package logx import ( "base-go-v2/internal/config" "base-go-v2/internal/routinex" + "base-go-v2/internal/utils/idgen" "base-go-v2/internal/utils/strutil" - "base-go-v2/internal/utils/uid" "fmt" "os" "path/filepath" @@ -63,7 +63,7 @@ func (c *trackCore) Check(entry zapcore.Entry, ce *zapcore.CheckedEntry) *zapcor func (c *trackCore) Write(entry zapcore.Entry, fields []zapcore.Field) error { val := routinex.Get(TrackID) if val == nil { - val = uid.NextID() + val = idgen.NextId() routinex.Set(TrackID, val) // 保证同一请求复用同一 trackID } diff --git a/code/base-project/base-go-v2/internal/router/context.go b/code/base-project/base-go-v2/internal/router/context.go index 2148a21a..8c6690f4 100644 --- a/code/base-project/base-go-v2/internal/router/context.go +++ b/code/base-project/base-go-v2/internal/router/context.go @@ -126,6 +126,32 @@ func (c *Context) Get(key string) (interface{}, bool) { return val, ok } +// SetUserID 存储 userId +func (c *Context) SetUserID(userID int64) { + c.Set("user_id", userID) +} + +// GetUserID 获取 userId +func (c *Context) GetUserID() int64 { + val, ok := c.Get("user_id") + if !ok || val == nil { + return 0 + } + + switch v := val.(type) { + case int64: + return v + case int: + return int64(v) + case uint64: + return int64(v) + case uint: + return int64(v) + default: + return 0 + } +} + // JSON 返回 JSON 响应,支持返回 error func (c *Context) JSON(statusCode int, data interface{}) error { c.RequestCtx.SetStatusCode(statusCode) diff --git a/code/base-project/base-go-v2/internal/utils/idgen/DefaultIdGenerator.go b/code/base-project/base-go-v2/internal/utils/idgen/DefaultIdGenerator.go new file mode 100644 index 00000000..826ac0bd --- /dev/null +++ b/code/base-project/base-go-v2/internal/utils/idgen/DefaultIdGenerator.go @@ -0,0 +1,83 @@ +package idgen + +import ( + "strconv" + "time" +) + +type DefaultIdGenerator struct { + Options *IdGeneratorOptions + SnowWorker ISnowWorker + IdGeneratorException IdGeneratorException +} + +func NewDefaultIdGenerator(options *IdGeneratorOptions) *DefaultIdGenerator { + if options == nil { + panic("dig.Options error.") + } + + // 1.BaseTime + minTime := int64(631123200000) // time.Now().AddDate(-30, 0, 0).UnixNano() / 1e6 + if options.BaseTime < minTime || options.BaseTime > time.Now().UnixNano()/1e6 { + panic("BaseTime error.") + } + + // 2.WorkerIdBitLength + if options.WorkerIdBitLength <= 0 { + panic("WorkerIdBitLength error.(range:[1, 21])") + } + if options.WorkerIdBitLength+options.SeqBitLength > 22 { + panic("error:WorkerIdBitLength + SeqBitLength <= 22") + } + + // 3.WorkerId + maxWorkerIdNumber := uint16(1<