第 0 阶段:项目初始化

This commit is contained in:
yml
2026-05-22 15:05:28 +08:00
commit 8e7f1f17f0
55 changed files with 4519 additions and 0 deletions
+58
View File
@@ -0,0 +1,58 @@
package config
import (
"os"
"strconv"
)
type Config struct {
AppEnv string
AppAddr string
MySQLDSN string
RedisAddr string
RedisPassword string
RedisDB int
JWTSecret string
Storage StorageConfig
}
type StorageConfig struct {
Endpoint string
Bucket string
}
func Load() Config {
return Config{
AppEnv: getEnv("APP_ENV", "development"),
AppAddr: getEnv("APP_ADDR", ":8080"),
MySQLDSN: getEnv("MYSQL_DSN", "hfb:secret@tcp(127.0.0.1:3306)/hfb_sys?charset=utf8mb4&parseTime=True&loc=Local"),
RedisAddr: getEnv("REDIS_ADDR", "127.0.0.1:6379"),
RedisPassword: getEnv("REDIS_PASSWORD", ""),
RedisDB: getEnvInt("REDIS_DB", 0),
JWTSecret: getEnv("JWT_SECRET", "change-me"),
Storage: StorageConfig{
Endpoint: getEnv("STORAGE_ENDPOINT", "http://127.0.0.1:9000"),
Bucket: getEnv("STORAGE_BUCKET", "hfb-sys"),
},
}
}
func getEnv(key, fallback string) string {
value := os.Getenv(key)
if value == "" {
return fallback
}
return value
}
func getEnvInt(key string, fallback int) int {
value := os.Getenv(key)
if value == "" {
return fallback
}
parsed, err := strconv.Atoi(value)
if err != nil {
return fallback
}
return parsed
}
+10
View File
@@ -0,0 +1,10 @@
package database
import (
"gorm.io/driver/mysql"
"gorm.io/gorm"
)
func OpenMySQL(dsn string) (*gorm.DB, error) {
return gorm.Open(mysql.Open(dsn), &gorm.Config{})
}
+25
View File
@@ -0,0 +1,25 @@
package database
import (
"context"
"github.com/redis/go-redis/v9"
)
type RedisConfig struct {
Addr string
Password string
DB int
}
func OpenRedis(ctx context.Context, cfg RedisConfig) (*redis.Client, error) {
client := redis.NewClient(&redis.Options{
Addr: cfg.Addr,
Password: cfg.Password,
DB: cfg.DB,
})
if err := client.Ping(ctx).Err(); err != nil {
return nil, err
}
return client, nil
}
+24
View File
@@ -0,0 +1,24 @@
package handler
import (
"net/http"
"time"
"github.com/gin-gonic/gin"
)
type HealthHandler struct {
startedAt time.Time
}
func NewHealthHandler() *HealthHandler {
return &HealthHandler{startedAt: time.Now()}
}
func (h *HealthHandler) Check(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"status": "ok",
"service": "hfb-api",
"started_at": h.startedAt.Format(time.RFC3339),
})
}
@@ -0,0 +1,23 @@
package middleware
import (
"time"
"github.com/gin-gonic/gin"
"go.uber.org/zap"
)
func RequestLogger(logger *zap.Logger) gin.HandlerFunc {
return func(c *gin.Context) {
start := time.Now()
c.Next()
logger.Info("http request",
zap.String("method", c.Request.Method),
zap.String("path", c.Request.URL.Path),
zap.Int("status", c.Writer.Status()),
zap.Duration("latency", time.Since(start)),
zap.String("client_ip", c.ClientIP()),
)
}
}
+3
View File
@@ -0,0 +1,3 @@
# Auth Module
手机号短信登录、JWT、验证码限流。
@@ -0,0 +1,3 @@
# Dispute Module
纠纷举证、客服仲裁、裁决落账。
@@ -0,0 +1,3 @@
# Listing Module
账号发布、资产快照、审核、上下架。
+3
View File
@@ -0,0 +1,3 @@
# Order Module
订单状态机、账号交接、租期归还、超时处理。
@@ -0,0 +1,3 @@
# Wallet Module
押金冻结、租金结算、不可变资金流水。
+30
View File
@@ -0,0 +1,30 @@
package router
import (
"hfb_sys/backend/internal/config"
"hfb_sys/backend/internal/handler"
"hfb_sys/backend/internal/middleware"
"github.com/gin-gonic/gin"
"go.uber.org/zap"
)
func New(cfg config.Config, logger *zap.Logger) *gin.Engine {
if cfg.AppEnv == "production" {
gin.SetMode(gin.ReleaseMode)
}
engine := gin.New()
engine.Use(gin.Recovery())
engine.Use(middleware.RequestLogger(logger))
health := handler.NewHealthHandler()
engine.GET("/health", health.Check)
api := engine.Group("/api")
{
api.GET("/health", health.Check)
}
return engine
}