This commit is contained in:
oneao committed 2026-04-24 22:37:52 +08:00
1 parent 46cbb2f50d
commit e3d765a9d4
15 files changed
+903 -190

No files matched your search

@@ -43,24 +43,40 @@ func InitPgsql(cfg *config.Config) (*pgxpool.Pool, error) {
}
// ======================
// 连接池配置
// 连接池配置(带默认值)
// ======================
// 最大连接数
// 默认最大连接数
maxConns := int32(20)
if pg.MaxOpenConns > 0 {
conf.MaxConns = int32(pg.MaxOpenConns)
maxConns = int32(pg.MaxOpenConns)
}
// 最小连接数(近似 idle)
// 默认最小连接数
minConns := int32(2)
if pg.MaxIdleConns > 0 {
conf.MinConns = int32(pg.MaxIdleConns)
minConns = int32(pg.MaxIdleConns)
}
// 连接最大生命周期
// 防止配置错误:min > max
if minConns > maxConns {
minConns = maxConns
}
// 应用配置
conf.MaxConns = maxConns
conf.MinConns = minConns
// 默认连接最大生命周期
if pg.ConnMaxLifetime > 0 {
conf.MaxConnLifetime = pg.ConnMaxLifetime
} else {
conf.MaxConnLifetime = time.Hour
}
// (推荐补充)空闲连接最大存活时间
conf.MaxConnIdleTime = 30 * time.Minute
// ======================
// 时区设置(正确方式 ⭐)
// ======================
@@ -3,6 +3,7 @@ package handle
import (
"allapp-go/internal/errors"
"allapp-go/internal/httpx"
"allapp-go/internal/middleware"
"allapp-go/internal/types"
"allapp-go/pkg/db"
"allapp-go/pkg/jwtx"
@@ -10,7 +11,9 @@ import (
"allapp-go/pkg/s3store"
"allapp-go/pkg/uniqueid"
"allapp-go/pkg/wechat"
"bytes"
"fmt"
"io"
"net/url"
"path/filepath"
"time"
@@ -161,6 +164,14 @@ func registerUser(
_ = stream.Close()
}()
// ✅ 只在这里转成可 seek
data, err := io.ReadAll(stream)
if err != nil {
return err
}
reader := bytes.NewReader(data)
// ✅ 从 avatar URL 获取扩展名(简化版)
u, _ := url.Parse(avatar)
ext := filepath.Ext(u.Path)
@@ -181,12 +192,12 @@ func registerUser(
// 上传到 S3
if err := s3store.UploadToRustFS(
c.Context(),
stream,
reader,
key,
size,
contentType,
); err != nil {
avatar = defaultAvatar
return errors.WithStack(err)
} else {
avatar = key
}
@@ -240,9 +251,160 @@ func registerUser(
return httpx.OK(c, vo)
}
// BindQq 绑定QQ
func BindQq(c fiber.Ctx) error {
var req types.LoginQqReq
if err := httpx.BindAndValidate(c, &req); err != nil {
return errors.WithStack(err)
}
dbClient := db.New()
// 检查 QQ 是否已经被其他账号绑定
var exist []map[string]any
_, err := dbClient.LoadDataBySQL(
c.Context(),
"SELECT id FROM b_user_oauth WHERE openid = ? AND type = 1",
[]any{req.Openid},
)
if err != nil {
return errors.WithStack(err)
}
if len(exist) > 0 {
return httpx.Fail(c, "该 QQ 已被其他账号绑定")
}
userID, ok := middleware.GetUserID(c.Context())
if !ok {
return httpx.Unauthorized(c, "账号异常")
}
var userBind []map[string]any
_, err = dbClient.LoadDataBySQL(
c.Context(),
"SELECT id FROM b_user_oauth WHERE user_id = ? AND type = 1",
[]any{userID},
)
if err != nil {
return errors.WithStack(err)
}
if len(userBind) > 0 {
return httpx.Fail(c, "该账号已绑定 QQ")
}
err = dbClient.WithTx(c.Context(), func(tx *db.Client) error {
err2 := tx.Insert(
c.Context(),
"b_user_oauth",
"id",
map[string]any{
"id": uniqueid.NextId(),
"user_id": userID,
"type": 1, // QQ
"openid": req.Openid,
"create_time": time.Now(),
"update_time": time.Now(),
},
)
if err2 != nil {
return err2
}
return nil
})
if err != nil {
return errors.WithStack(err)
}
return httpx.OK(c, "绑定成功")
}
// BindWechat 绑定微信
func BindWechat(c fiber.Ctx) error {
var req types.LoginWechatReq
if err := httpx.BindAndValidate(c, &req); err != nil {
return errors.WithStack(err)
}
dbClient := db.New()
// 2️⃣ 检查 微信 是否已经被其他账号绑定
var exist []map[string]any
_, err := dbClient.LoadDataBySQL(
c.Context(),
"SELECT id FROM b_user_oauth WHERE openid = ? AND type = 0",
[]any{req.Code},
)
if err != nil {
return errors.WithStack(err)
}
if len(exist) > 0 {
return httpx.Fail(c, "该 微信 已被其他账号绑定")
}
userID, ok := middleware.GetUserID(c.Context())
if !ok {
return httpx.Unauthorized(c, "账号异常")
}
var userBind []map[string]any
_, err = dbClient.LoadDataBySQL(
c.Context(),
"SELECT id FROM b_user_oauth WHERE user_id = ? AND type = 0",
[]any{userID},
)
if err != nil {
return errors.WithStack(err)
}
if len(userBind) > 0 {
return httpx.Fail(c, "该账号已绑定 微信")
}
openid, _, err := wechat.GetWechatAccess(req.Code)
if err != nil {
log.Errorw("微信获取Token失败", "code", req.Code, "error", err)
return httpx.Fail(c, "微信登录失败,请重试")
}
err = dbClient.WithTx(c.Context(), func(tx *db.Client) error {
err2 := tx.Insert(
c.Context(),
"b_user_oauth",
"id",
map[string]any{
"id": uniqueid.NextId(),
"user_id": userID,
"type": 0, // 微信
"openid": openid,
"create_time": time.Now(),
"update_time": time.Now(),
},
)
if err2 != nil {
return err2
}
return nil
})
if err != nil {
return errors.WithStack(err)
}
return httpx.OK(c, "绑定成功")
}
// ======================== DB 查询封装(去重复 SQL) ========================
func getUserByOpenID(dbClient *db.Client, c fiber.Ctx, openid string, loginType int16) (map[string]any, error) {
users, err := dbClient.LoadDataBySQL(
c.Context(),
`SELECT u.*
@@ -26,4 +26,8 @@ func SetupRouter(app *fiber.App, cfg *config.Config) {
// ==================== auth ====================
api.Post("/auth/login/qq", handle.LoginQq)
api.Post("/auth/login/wechat", handle.LoginWechat)
bind := api.Group("/bind", middleware.Auth())
bind.Post("/qq", handle.BindQq)
bind.Post("/wechat", handle.BindWechat)
}