Files
Qianandqian 501726b831 优化用户相关功能 (#8)
* improve(user):优化注册功能提示

* improve(user):优化邮箱大小写重复问题

* improve(user):添加密码强度指示器

* fix(setting):修复系统设置功能里面的数字转换问题

* feat(email):优化邮件发送功能

* chore(email):移除无用配置和日志

* fix(user):修复重置密码功能

* chore(ui):调整轮询间隔

* chore(ui):添加充值提示

* chore(ui):优化用户注册功能

* chore(sql):补充数据库变更文件

* fix(email):优化邮箱校验

---------

Co-authored-by: qian <wuchengqian5@163.com>
2026-06-17 22:47:26 +08:00

73 lines
2.0 KiB
Go

package common
import (
"database/sql"
"errors"
"strings"
"github.com/gogf/gf/v2/errors/gcode"
"github.com/gogf/gf/v2/errors/gerror"
"github.com/qianfree/team-api/internal/consts"
)
// NewBusinessError creates a business error with code and message.
func NewBusinessError(code int, message string) error {
return gerror.NewCode(gcode.New(code, message, nil), message)
}
// NewNotFoundError creates a 404 Not Found error.
func NewNotFoundError(resource string) error {
return gerror.NewCode(
gcode.New(consts.CodeNotFound, resource+"不存在", nil),
resource+"不存在",
)
}
// NewForbiddenError creates a 403 Forbidden error.
func NewForbiddenError(message string) error {
return gerror.NewCode(
gcode.New(consts.CodeForbidden, message, nil),
message,
)
}
// NewBadRequestError creates a 400 Bad Request error.
func NewBadRequestError(message string) error {
return gerror.NewCode(
gcode.New(consts.CodeBadRequest, message, nil),
message,
)
}
// NewUnauthorizedError creates a 401 Unauthorized error.
func NewUnauthorizedError(message string) error {
return gerror.NewCode(
gcode.New(consts.CodeUnauthorized, message, nil),
message,
)
}
// IgnoreScanNoRows normalizes sql.ErrNoRows to nil.
// GoFrame's Scan(&struct) returns sql.ErrNoRows when no record is found,
// but callers typically check the zero-value result afterwards.
func IgnoreScanNoRows(err error) error {
if err != nil && errors.Is(err, sql.ErrNoRows) {
return nil
}
return err
}
// IsDuplicateKeyError reports whether err is a PostgreSQL unique-constraint
// violation (SQLSTATE 23505). Used to convert race-condition insert failures
// into friendly business errors at the data layer's last line of defense.
//
// Uses string matching on the driver error message. Switch to a typed assertion
// (pq.Error / pgconn.PgError) if a Postgres driver becomes a direct dependency.
func IsDuplicateKeyError(err error) bool {
if err == nil {
return false
}
return strings.Contains(err.Error(), "23505") || strings.Contains(err.Error(), "duplicate key")
}