This commit is contained in:
oneao committed 2025-11-07 10:10:10 +08:00
1 parent be8eaae7c5
commit d6dd5b032d
11 files changed
+202 -112

No files matched your search

@@ -60,8 +60,7 @@ func loginDefault(c *router.Context) error {
// 获取请求体并校验必填字段
bodyData, err := c.GetBodyWithRequired("account", "password")
if err != nil {
c.AddError(err)
return err
return c.AddError(err)
}
account := bodyData.GetString("account")
@@ -74,7 +73,6 @@ func loginDefault(c *router.Context) error {
)
user, err := db.FindOne("user_info", userQuery)
if err != nil {
c.AddError(err)
return response.Success(c).Message("查询用户失败,请稍后重试").Send()
}
@@ -116,7 +114,7 @@ func loginDefault(c *router.Context) error {
func registerDefault(c *router.Context) error {
bodyData, err := c.GetBodyWithRequired("account", "password")
if err != nil {
return err
return c.AddError(err)
}
account := bodyData.GetString("account")
password := bodyData.GetString("password")
@@ -124,12 +122,12 @@ func registerDefault(c *router.Context) error {
// 构造查询条件,检查账号是否已存在
accountQuery := mapx.New().SetKV("account", account)
existingUsers, err := db.Find("user_info", accountQuery)
existingUsers, err := db.FindOne("user_info", accountQuery)
if err != nil {
return c.AddError(err)
}
if len(existingUsers) > 0 {
if existingUsers != nil {
return response.Fail(c).Message("该账号已被注册").Send()
}
@@ -143,7 +141,6 @@ func registerDefault(c *router.Context) error {
// 插入新用户
insertedRows, err := db.InsertOne("user_info", newUserData)
if err != nil {
return c.AddError(err)
}
if insertedRows != 1 {
return response.Fail(c).Message("注册失败").Send()
@@ -8,47 +8,47 @@ import (
// ---------------- 通用查询方法 ----------------
// GetOne 根据主键查询单条记录,返回 mapx.M
func GetOne(table string, pkColumn string, pkValue interface{}) (mapx.M, error) {
query := fmt.Sprintf("SELECT * FROM %s WHERE %s=$1", table, pkColumn)
row := mapx.New()
err := DB.Get(&row, query, pkValue)
// 执行查询,返回多条记录
func queryMaps(query string, args []interface{}) ([]mapx.M, error) {
rows, err := DB.Queryx(query, args...)
if err != nil {
return nil, err
}
return row, nil
defer rows.Close()
var result []mapx.M
for rows.Next() {
row := mapx.New()
if err := rows.MapScan(row); err != nil {
return nil, err
}
result = append(result, row)
}
return result, nil
}
// GetBatch 根据主键批量查询,返回 []mapx.M
func GetBatch(table string, pkColumn string, pkValues []interface{}) ([]mapx.M, error) {
if len(pkValues) == 0 {
return nil, nil
}
var rows []mapx.M
// 构建 IN 占位符
placeholders := make([]string, len(pkValues))
for i := range pkValues {
placeholders[i] = fmt.Sprintf("$%d", i+1)
}
query := fmt.Sprintf("SELECT * FROM %s WHERE %s IN (%s)", table, pkColumn, strings.Join(placeholders, ","))
err := DB.Select(&rows, query, pkValues...)
// 执行查询,返回单条记录
func queryMap(query string, args []interface{}) (mapx.M, error) {
rows, err := DB.Queryx(query, args...)
if err != nil {
return nil, err
}
defer rows.Close()
return rows, nil
}
// Find 根据条件查询多条记录,可选排序,返回 []mapx.M
func Find(table string, conditions map[string]interface{}, orderBy ...string) ([]mapx.M, error) {
if len(conditions) == 0 {
return nil, fmt.Errorf("查询条件不能为空")
if rows.Next() {
row := mapx.New()
if err := rows.MapScan(row); err != nil {
return nil, err
}
return row, nil
}
return nil, nil
}
// 构建 WHERE 条件
func buildWhere(conditions map[string]interface{}) (string, []interface{}) {
var whereParts []string
var values []interface{}
i := 1
@@ -57,8 +57,40 @@ func Find(table string, conditions map[string]interface{}, orderBy ...string) ([
values = append(values, v)
i++
}
return strings.Join(whereParts, " AND "), values
}
query := fmt.Sprintf("SELECT * FROM %s WHERE %s", table, strings.Join(whereParts, " AND "))
// ---------------- 公共查询方法 ----------------
// GetOne 根据主键查询单条记录
func GetOne(table string, pkColumn string, pkValue interface{}) (mapx.M, error) {
query := fmt.Sprintf("SELECT * FROM %s WHERE %s=$1", table, pkColumn)
return queryMap(query, []interface{}{pkValue})
}
// GetBatch 根据主键批量查询
func GetBatch(table string, pkColumn string, pkValues []interface{}) ([]mapx.M, error) {
if len(pkValues) == 0 {
return nil, nil
}
placeholders := make([]string, len(pkValues))
for i := range pkValues {
placeholders[i] = fmt.Sprintf("$%d", i+1)
}
query := fmt.Sprintf("SELECT * FROM %s WHERE %s IN (%s)", table, pkColumn, strings.Join(placeholders, ","))
return queryMaps(query, pkValues)
}
// Find 根据条件查询多条记录,可选排序
func Find(table string, conditions map[string]interface{}, orderBy ...string) ([]mapx.M, error) {
if len(conditions) == 0 {
return nil, fmt.Errorf("查询条件不能为空")
}
where, values := buildWhere(conditions)
query := fmt.Sprintf("SELECT * FROM %s WHERE %s", table, where)
order := "id DESC"
if len(orderBy) > 0 && orderBy[0] != "" {
@@ -66,16 +98,10 @@ func Find(table string, conditions map[string]interface{}, orderBy ...string) ([
}
query += " ORDER BY " + order
var rows []mapx.M
err := DB.Select(&rows, query, values...)
if err != nil {
return nil, err
}
return rows, nil
return queryMaps(query, values)
}
// FindAll 查询整个表,可选排序,返回 []mapx.M
// FindAll 查询整个表,可选排序
func FindAll(table string, orderBy ...string) ([]mapx.M, error) {
query := fmt.Sprintf("SELECT * FROM %s", table)
@@ -85,31 +111,17 @@ func FindAll(table string, orderBy ...string) ([]mapx.M, error) {
}
query += " ORDER BY " + order
var rows []mapx.M
err := DB.Select(&rows, query)
if err != nil {
return nil, err
}
return rows, nil
return queryMaps(query, nil)
}
// FindOne 根据条件查询单条记录,返回 mapx.M
// FindOne 根据条件查询单条记录,可选排序
func FindOne(table string, conditions map[string]interface{}, orderBy ...string) (mapx.M, error) {
if len(conditions) == 0 {
return nil, fmt.Errorf("查询条件不能为空")
}
var whereParts []string
var values []interface{}
i := 1
for k, v := range conditions {
whereParts = append(whereParts, fmt.Sprintf("%s=$%d", k, i))
values = append(values, v)
i++
}
query := fmt.Sprintf("SELECT * FROM %s WHERE %s", table, strings.Join(whereParts, " AND "))
where, values := buildWhere(conditions)
query := fmt.Sprintf("SELECT * FROM %s WHERE %s", table, where)
order := "id DESC"
if len(orderBy) > 0 && orderBy[0] != "" {
@@ -117,11 +129,5 @@ func FindOne(table string, conditions map[string]interface{}, orderBy ...string)
}
query += " ORDER BY " + order + " LIMIT 1"
row := mapx.New()
err := DB.Get(&row, query, values...)
if err != nil {
return nil, err
}
return row, nil
return queryMap(query, values)
}
@@ -180,6 +180,14 @@ func newConsoleEncoder(enableColor bool) zapcore.Encoder {
pid := os.Getpid()
enc.AppendString(fmt.Sprintf("[%d] [%d] %s", pid, routinex.CurGID(), caller.TrimmedPath()))
},
EncodeDuration: func(d time.Duration, enc zapcore.PrimitiveArrayEncoder) {
ms := d.Milliseconds()
if ms < 1000 {
enc.AppendString(fmt.Sprintf("%dms", ms))
} else {
enc.AppendString(fmt.Sprintf("%.2fs", d.Seconds()))
}
},
}
return zapcore.NewConsoleEncoder(cfg)
}
@@ -192,6 +200,17 @@ func newJSONEncoder() zapcore.Encoder {
}
cfg.EncodeLevel = zapcore.CapitalLevelEncoder
cfg.EncodeCaller = zapcore.ShortCallerEncoder
// 智能 duration 输出
cfg.EncodeDuration = func(d time.Duration, enc zapcore.PrimitiveArrayEncoder) {
ms := d.Milliseconds()
if ms < 1000 {
enc.AppendString(fmt.Sprintf("%dms", ms))
} else {
enc.AppendString(fmt.Sprintf("%.2fs", d.Seconds()))
}
}
return zapcore.NewJSONEncoder(cfg)
}
@@ -8,6 +8,7 @@ import (
"net/http"
)
// Result 响应结构
type Result struct {
Code int `json:"code"`
Message string `json:"message"`
@@ -15,6 +16,7 @@ type Result struct {
TrackId string `json:"trackId,omitempty"`
}
// HttpCode 响应状态码
var HttpCode = struct {
Success int
Unauthorized int
@@ -27,31 +29,37 @@ var HttpCode = struct {
RefreshToken: 402,
}
// Builder 响应构建器
type Builder struct {
c *router.Context
result Result
c *router.Context
result Result
statusCode int // 可自定义 HTTP 状态码
}
// Success 构造成功响应
func Success(c *router.Context) *Builder {
return &Builder{
c: c,
result: Result{
Code: HttpCode.Success,
Message: "请求成功",
},
c: c,
result: Result{Code: HttpCode.Success, Message: "请求成功"},
statusCode: http.StatusOK,
}
}
// Fail 构造失败响应
func Fail(c *router.Context) *Builder {
return &Builder{
c: c,
result: Result{
Code: HttpCode.Fail,
Message: "请求失败",
},
c: c,
result: Result{Code: HttpCode.Fail, Message: "请求失败"},
statusCode: http.StatusOK,
}
}
// Status 设置自定义 HTTP 状态码
func (b *Builder) Status(code int) *Builder {
b.statusCode = code
return b
}
func (b *Builder) Code(code int) *Builder {
b.result.Code = code
return b
@@ -67,6 +75,7 @@ func (b *Builder) Data(data interface{}) *Builder {
return b
}
// Send 发送响应
func (b *Builder) Send() error {
if b.result.Data == nil {
b.result.Data = ""
@@ -74,5 +83,5 @@ func (b *Builder) Send() error {
if trackId := routinex.Get(logx.TrackID); trackId != nil {
b.result.TrackId = strutil.ToString(trackId)
}
return b.c.JSON(http.StatusOK, b.result)
return b.c.JSON(b.statusCode, b.result)
}
@@ -1,13 +1,11 @@
package router
import (
"base-go-v2/internal/errs"
"base-go-v2/internal/utils/mapx"
"base-go-v2/internal/utils/validate"
"encoding/json"
"sync"
"github.com/valyala/fasthttp"
"sync"
)
// BodyCache 缓存 fasthttp 请求体
@@ -167,23 +165,23 @@ func (c *Context) AddError(err error) error {
}
if _, exists := c.keys["errors"]; !exists {
c.keys["errors"] = []*errs.StackError{}
c.keys["errors"] = []*StackError{}
}
// 统一生成堆栈
se := errs.WrapWithStack(err)
c.keys["errors"] = append(c.keys["errors"].([]*errs.StackError), se)
se := WrapWithStack(err)
c.keys["errors"] = append(c.keys["errors"].([]*StackError), se)
return err
}
// Errors 返回 []*utils.StackError
func (c *Context) Errors() []*errs.StackError {
func (c *Context) Errors() []*StackError {
if c.keys == nil {
return nil
}
if err, exists := c.keys["errors"]; exists {
return err.([]*errs.StackError)
if errs, exists := c.keys["errors"]; exists {
return errs.([]*StackError)
}
return nil
}
@@ -0,0 +1,42 @@
package router
import (
"errors"
"runtime/debug"
)
// StackError 保存原始错误和堆栈
type StackError struct {
err error
stack string
}
// 实现 error 接口
func (s *StackError) Error() string {
if s.err == nil {
return ""
}
return s.err.Error()
}
// StackTrace 返回堆栈信息
func (s *StackError) StackTrace() string {
return s.stack
}
// WrapWithStack 给错误附加堆栈,如果已经是 StackError 则直接返回
func WrapWithStack(err error) *StackError {
if err == nil {
return nil
}
var se *StackError
if errors.As(err, &se) {
return se
}
return &StackError{
err: err,
stack: string(debug.Stack()),
}
}