This commit is contained in:
oneao committed 2026-04-19 21:30:51 +08:00
1 parent b6415c0d65
commit 89aaef1d6b
29 files changed
+1118 -277

No files matched your search

@@ -5,6 +5,8 @@ import (
"allapp-go/internal/config"
"allapp-go/pkg/db"
"allapp-go/pkg/logger"
"allapp-go/pkg/s3store"
"allapp-go/pkg/wechat"
"github.com/jackc/pgx/v5/pgxpool"
)
@@ -27,6 +29,9 @@ func NewApp() (*App, error) {
// 日志
boots.InitLogger(cfg)
// S3
s3store.NewS3Client(cfg)
// 数据库
pgsql, err := boots.InitPgsql(cfg)
if err != nil {
@@ -38,6 +43,7 @@ func NewApp() (*App, error) {
// 其他组件
boots.InitUniqueId(cfg)
boots.InitJwt(cfg)
wechat.Init(cfg.Wechat.AppId, cfg.Wechat.AppSecret)
return &App{
Config: cfg,
@@ -8,6 +8,7 @@ type Config struct {
UniqueID UniqueIDConfig `mapstructure:"unique_id"`
Postgres PostgresConfig `mapstructure:"postgres"`
Wechat WechatConfig `mapstructure:"wechat"`
AwsS3 AwsS3Config `mapstructure:"aws_s3"`
}
type AppConfig struct {
@@ -43,3 +44,11 @@ type WechatConfig struct {
AppId string `mapstructure:"app_id"`
AppSecret string `mapstructure:"app_secret"`
}
type AwsS3Config struct {
Region string `mapstructure:"region"`
AccessKey string `mapstructure:"access_key"`
SecretKey string `mapstructure:"secret_key"`
Bucket string `mapstructure:"bucket"`
Endpoint string `mapstructure:"endpoint"`
}
@@ -94,8 +94,8 @@ func handleThirdLogin(
}
// ========= token =========
token, err := jwtx.CreateToken(c.Context(), map[string]any{
"id": id,
token, err := jwtx.CreateToken(c.Context(), jwtx.TokenData{
UserID: id,
})
if err != nil {
return errors.WithStack(err)
@@ -129,25 +129,24 @@ func registerUser(
err := dbClient.WithTx(c.Context(), func(tx *db.Client) error {
if err := tx.Insert(c.Context(), "user", "id", map[string]any{
if err := tx.Insert(c.Context(), "b_user", "id", map[string]any{
"id": userId,
"nickname": nickname,
"avatar": avatar,
"status": 1,
"create_time": "NOW()",
"update_time": "NOW()",
"created_at": "NOW()",
"updated_at": "NOW()",
"last_login_time": "NOW()",
}); err != nil {
return err
}
if err := tx.Insert(c.Context(), "user_oauth", "id", map[string]any{
"id": uniqueid.NextId(),
"user_id": userId,
"type": loginType,
"openid": openid,
"create_time": "NOW()",
"update_time": "NOW()",
if err := tx.Insert(c.Context(), "b_user_oauth", "id", map[string]any{
"id": uniqueid.NextId(),
"user_id": userId,
"type": loginType,
"openid": openid,
"created_at": "NOW()",
"updated_at": "NOW()",
}); err != nil {
return err
}
@@ -159,8 +158,8 @@ func registerUser(
return errors.WithStack(err)
}
token, err := jwtx.CreateToken(c.Context(), map[string]any{
"id": userId,
token, err := jwtx.CreateToken(c.Context(), jwtx.TokenData{
UserID: userId,
})
if err != nil {
return errors.WithStack(err)
@@ -179,7 +178,10 @@ func getUserByOpenID(dbClient *db.Client, c fiber.Ctx, openid string, loginType
users, err := dbClient.LoadDataBySQL(
c.Context(),
"SELECT u.* FROM user_oauth o JOIN user u ON u.id = o.user_id WHERE o.openid = ? AND o.type = ?",
`SELECT u.*
FROM b_user_oauth o
JOIN b_user u ON u.id = o.user_id
WHERE o.openid = $1 AND o.type = $2`,
[]any{openid, loginType},
)
@@ -196,6 +198,19 @@ func getUserByOpenID(dbClient *db.Client, c fiber.Ctx, openid string, loginType
// ======================== 类型工具(极简版) ========================
func toInt64(v any) int64 {
i, _ := v.(int64)
return i
switch val := v.(type) {
case int64:
return val
case int32:
return int64(val)
case int16:
return int64(val)
case int:
return int64(val)
case float64:
return int64(val)
default:
fmt.Printf("unknown type: %T, value=%v\n", v, v)
return 0
}
}
@@ -0,0 +1,79 @@
package handle
import (
"allapp-go/internal/errors"
"allapp-go/internal/httpx"
"allapp-go/pkg/s3store"
"fmt"
"mime/multipart"
"path/filepath"
"time"
"github.com/aws/aws-sdk-go-v2/service/s3"
"github.com/gofiber/fiber/v3"
"github.com/google/uuid"
)
func S3ListBuckets(c fiber.Ctx) error {
result, err := s3store.S3Client.ListBuckets(c.Context(), &s3.ListBucketsInput{})
if err != nil {
return errors.WithStack(err)
}
buckets := make([]string, 0, len(result.Buckets))
for _, b := range result.Buckets {
if b.Name != nil {
buckets = append(buckets, *b.Name)
}
}
return httpx.OK(c, buckets)
}
func S3UploadFile(c fiber.Ctx) error {
fileHeader, err := c.FormFile("file")
if err != nil {
return errors.WithStack(err)
}
file, err := fileHeader.Open()
if err != nil {
return errors.WithStack(err)
}
defer func(file multipart.File) {
_ = file.Close()
}(file)
// 日期目录
now := time.Now()
folderPath := fmt.Sprintf("%d/%02d/%02d",
now.Year(),
now.Month(),
now.Day(),
)
// UUID 文件名(保留后缀)
ext := filepath.Ext(fileHeader.Filename)
newName := fmt.Sprintf("%s%s", uuid.NewString(), ext)
// S3 object key
key := fmt.Sprintf("%s/%s", folderPath, newName)
// ContentType(防止前端乱传)
contentType := fileHeader.Header.Get("Content-Type")
// 调用存储层
err = s3store.UploadToRustFS(
c.Context(),
key,
file,
fileHeader.Size,
contentType,
)
if err != nil {
return errors.WithStack(err)
}
return httpx.OK(c, nil)
}
@@ -1,7 +1,10 @@
package middleware
import (
"allapp-go/internal/httpx"
"allapp-go/pkg/jwtx"
"context"
"strings"
"github.com/gofiber/fiber/v3"
)
@@ -11,20 +14,18 @@ const CtxUserIDKey = "user_id"
// Auth 登录校验中间件
func Auth() fiber.Handler {
return func(c fiber.Ctx) error {
//token := strings.TrimSpace(c.Get("Token"))
//
//if token == "" {
// return httpx.Unauthorized(c, "未登录")
//}
//
//verifyToken, ok := jwtx.VerifyToken(c.Context(), token)
//if !ok {
// return httpx.Unauthorized(c, "登录已过期")
//}
//
//c.Locals(CtxUserIDKey, verifyToken.Data["user_id"])
token := strings.TrimSpace(c.Get("Token"))
ctx := context.WithValue(c.Context(), CtxUserIDKey, int64(779895419121733))
if token == "" {
return httpx.Unauthorized(c, "未登录")
}
verifyToken, ok := jwtx.VerifyToken(c.Context(), token)
if !ok {
return httpx.Unauthorized(c, "登录已过期")
}
ctx := context.WithValue(c.Context(), CtxUserIDKey, verifyToken.Data.UserID)
c.SetContext(ctx)
return c.Next()
@@ -19,6 +19,10 @@ func SetupRouter(app *fiber.App, cfg *config.Config) {
data.Post("/saveData", handle.SaveData)
data.Post("/getUniqueId", handle.GetUniqueId)
s3 := api.Group("/s3", middleware.Auth())
s3.Post("/listBuckets", handle.S3ListBuckets)
s3.Post("/upload", handle.S3UploadFile)
// ==================== auth ====================
api.Post("/auth/login/qq", handle.LoginQq)
api.Post("/auth/login/wechat", handle.LoginWechat)