保留最新代码,清除历史记录

This commit is contained in:
vipg
2025-10-09 18:19:57 +08:00
commit b44e40f25d
77 changed files with 4115 additions and 0 deletions

View File

@@ -0,0 +1,162 @@
package main
import (
"database/sql"
"fmt"
"log"
"net/http"
"os"
"github.com/gin-gonic/gin"
_ "github.com/lib/pq"
"golang.org/x/crypto/bcrypt"
)
// LoginRequest 登录请求参数结构
type LoginRequest struct {
Account string `json:"account" binding:"required"`
Password string `json:"password" binding:"required"`
}
// LoginResponse 登录响应结构
type LoginResponse struct {
Success bool `json:"success"`
Message string `json:"message"`
Data struct {
UserID string `json:"user_id,omitempty"`
} `json:"data,omitempty"`
}
var db *sql.DB
func main() {
log.Println("开始初始化应用程序")
// 初始化Gin引擎
r := gin.Default()
log.Println("Gin引擎初始化完成")
// 从环境变量获取数据库配置
dbHost := os.Getenv("DB_HOST")
dbPort := os.Getenv("DB_PORT")
dbUser := os.Getenv("DB_USER")
dbPassword := os.Getenv("DB_PASSWORD")
dbName := os.Getenv("DB_NAME")
log.Printf("获取数据库配置: host=%s, port=%s, user=%s, dbname=%s", dbHost, dbPort, dbUser, dbName)
// 构建数据库连接字符串
connStr := fmt.Sprintf(
"host=%s port=%s user=%s password=%s dbname=%s sslmode=disable",
dbHost, dbPort, dbUser, dbPassword, dbName,
)
log.Printf("数据库连接字符串构建完成: %s", connStr)
var err error
db, err = sql.Open("postgres", connStr)
if err != nil {
log.Fatalf("无法连接数据库: %v", err)
panic(fmt.Sprintf("无法连接数据库: %v", err))
}
defer db.Close()
log.Println("数据库连接对象创建成功")
// 验证数据库连接
if err := db.Ping(); err != nil {
log.Fatalf("数据库连接失败: %v", err)
panic(fmt.Sprintf("数据库连接失败: %v", err))
}
log.Println("数据库连接验证成功")
// 登录接口
r.POST("/user/login", loginHandler)
log.Println("登录接口注册完成: POST /user/login")
// 启动服务监听80端口
log.Println("服务启动在80端口")
r.Run(":80")
}
// loginHandler 处理登录逻辑
func loginHandler(c *gin.Context) {
reqID := c.Request.Header.Get("X-Request-ID")
if reqID == "" {
reqID = fmt.Sprintf("%d", gin.Mode()) // 简单生成一个请求标识
}
log.Printf("[%s] 收到登录请求 from %s", reqID, c.ClientIP())
var req LoginRequest
// 绑定并验证请求参数
if err := c.ShouldBindJSON(&req); err != nil {
log.Printf("[%s] 请求参数绑定失败: %v, 请求体: %+v", reqID, err, c.Request.Body)
c.JSON(http.StatusBadRequest, LoginResponse{
Success: false,
Message: "账号或密码不能为空",
})
return
}
log.Printf("[%s] 请求参数绑定成功: 账号=%s", reqID, req.Account)
// 1. 判断账号和密码是否为空(双重保险)
if req.Account == "" || req.Password == "" {
log.Printf("[%s] 账号或密码为空: 账号=%s", reqID, req.Account)
c.JSON(http.StatusBadRequest, LoginResponse{
Success: false,
Message: "账号或密码不能为空",
})
return
}
// 2. 查询账号对应的密码和用户ID
var storedPassword string
var userID string
query := `
SELECT password, user_id
FROM user_account_password_view
WHERE account = $1 AND deleted = false
`
log.Printf("[%s] 执行查询: %s, 参数: %s", reqID, query, req.Account)
err := db.QueryRow(query, req.Account).Scan(&storedPassword, &userID)
switch {
case err == sql.ErrNoRows:
// 账号不存在或已被删除
log.Printf("[%s] 账号不存在或已删除: %s", reqID, req.Account)
c.JSON(http.StatusOK, LoginResponse{
Success: false,
Message: "账号不存在",
})
return
case err != nil:
log.Printf("[%s] 查询账号信息失败: %v, 账号=%s", reqID, err, req.Account)
c.JSON(http.StatusInternalServerError, LoginResponse{
Success: false,
Message: "查询账号信息失败",
})
return
}
log.Printf("[%s] 查询账号信息成功: 账号=%s, userID=%s", reqID, req.Account, userID)
// 3. 验证密码使用bcrypt比较原始密码和存储的加密密码
err = bcrypt.CompareHashAndPassword([]byte(storedPassword), []byte(req.Password))
if err != nil {
// 密码不匹配
log.Printf("[%s] 密码验证失败: 账号=%s, 错误=%v", reqID, req.Account, err)
c.JSON(http.StatusOK, LoginResponse{
Success: false,
Message: "密码错误",
})
return
}
log.Printf("[%s] 密码验证成功: 账号=%s", reqID, req.Account)
// 4. 登录成功
log.Printf("[%s] 登录成功: 账号=%s, userID=%s", reqID, req.Account, userID)
c.JSON(http.StatusOK, LoginResponse{
Success: true,
Message: "登录成功",
Data: struct {
UserID string `json:"user_id,omitempty"`
}{
UserID: userID,
},
})
}