Re-migrate code

This commit is contained in:
2026-03-02 10:41:43 +08:00
parent 1cc3097d9b
commit 6070df659a
6 changed files with 139 additions and 29 deletions

View File

@@ -34,27 +34,19 @@ func NewAuthController() *AuthController {
// @Router /auth/login [post] // @Router /auth/login [post]
func (c *AuthController) Login(ctx *gin.Context) { func (c *AuthController) Login(ctx *gin.Context) {
var loginData models.LoginDTO var loginData models.LoginDTO
if err := ctx.ShouldBindJSON(&loginData); err != nil { if !BindJSON(ctx, &loginData) {
ctx.JSON(http.StatusBadRequest, gin.H{
"message": "无效的请求数据",
"error": err.Error(),
})
return return
} }
user, err := c.authService.ValidateUser(loginData.Username, loginData.Password) user, err := c.authService.ValidateUser(loginData.Username, loginData.Password)
if err != nil { if err != nil {
ctx.JSON(http.StatusUnauthorized, gin.H{ ErrorResponse(ctx, http.StatusUnauthorized, err.Error())
"message": err.Error(),
})
return return
} }
token, err := c.authService.GenerateToken(user) token, err := c.authService.GenerateToken(user)
if err != nil { if err != nil {
ctx.JSON(http.StatusInternalServerError, gin.H{ ErrorResponse(ctx, http.StatusInternalServerError, "令牌生成失败")
"message": "令牌生成失败",
})
return return
} }

View File

@@ -2,12 +2,52 @@ package controllers
import ( import (
"net/http" "net/http"
"strings"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"git.beifan.cn/trace-system/backend-go/models" "git.beifan.cn/trace-system/backend-go/models"
) )
func friendlyMessage(message string) string {
if message == "" {
return "请求失败,请稍后重试"
}
msg := strings.TrimSpace(message)
friendlyMap := []struct {
key string
val string
}{
{"用户名或密码错误", "用户名或密码不正确"},
{"当前密码错误", "当前密码不正确"},
{"令牌生成失败", "登录失败,请稍后重试"},
{"未认证", "请先登录"},
{"用户信息无效", "登录状态无效,请重新登录"},
{"序列号不存在", "序列号不存在"},
{"企业不存在", "企业不存在"},
{"序列号已过期", "序列号已过期"},
{"序列号已被禁用", "序列号已禁用"},
{"序列号已被吊销", "序列号已吊销"},
{"企业名称已存在", "企业名称已存在"},
{"无效的请求数据", "提交数据格式不正确"},
{"无效的查询参数", "查询参数不正确"},
}
for _, item := range friendlyMap {
if strings.Contains(msg, item.key) {
return item.val
}
}
if strings.Contains(msg, "record not found") {
return "数据不存在"
}
return msg
}
// GetCurrentUser 从上下文中获取当前用户 // GetCurrentUser 从上下文中获取当前用户
// 如果用户未认证,返回 false 并返回 401 错误 // 如果用户未认证,返回 false 并返回 401 错误
func GetCurrentUser(ctx *gin.Context) (models.User, bool) { func GetCurrentUser(ctx *gin.Context) (models.User, bool) {
@@ -35,8 +75,7 @@ func GetCurrentUser(ctx *gin.Context) (models.User, bool) {
func BindJSON(ctx *gin.Context, obj interface{}) bool { func BindJSON(ctx *gin.Context, obj interface{}) bool {
if err := ctx.ShouldBindJSON(obj); err != nil { if err := ctx.ShouldBindJSON(obj); err != nil {
ctx.JSON(http.StatusBadRequest, gin.H{ ctx.JSON(http.StatusBadRequest, gin.H{
"message": "无效的请求数据", "message": "提交数据格式不正确",
"error": err.Error(),
}) })
return false return false
} }
@@ -48,8 +87,7 @@ func BindJSON(ctx *gin.Context, obj interface{}) bool {
func BindQuery(ctx *gin.Context, obj interface{}) bool { func BindQuery(ctx *gin.Context, obj interface{}) bool {
if err := ctx.ShouldBindQuery(obj); err != nil { if err := ctx.ShouldBindQuery(obj); err != nil {
ctx.JSON(http.StatusBadRequest, gin.H{ ctx.JSON(http.StatusBadRequest, gin.H{
"message": "无效的查询参数", "message": "查询参数不正确",
"error": err.Error(),
}) })
return false return false
} }
@@ -58,11 +96,12 @@ func BindQuery(ctx *gin.Context, obj interface{}) bool {
// ErrorResponse 返回错误响应 // ErrorResponse 返回错误响应
func ErrorResponse(ctx *gin.Context, status int, message string, err ...error) { func ErrorResponse(ctx *gin.Context, status int, message string, err ...error) {
friendly := friendlyMessage(message)
response := gin.H{ response := gin.H{
"message": message, "message": friendly,
} }
if len(err) > 0 && err[0] != nil { if len(err) > 0 && err[0] != nil {
response["error"] = err[0].Error() response["error"] = friendlyMessage(err[0].Error())
} }
ctx.JSON(status, response) ctx.JSON(status, response)
} }

View File

@@ -3,6 +3,7 @@ package controllers
import ( import (
"net/http" "net/http"
"strconv" "strconv"
"strings"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
@@ -57,8 +58,20 @@ func (c *SerialsController) Generate(ctx *gin.Context) {
return return
} }
SuccessResponse(ctx, "成功生成 "+strconv.Itoa(len(serials))+" 个序列号", gin.H{ items := make([]gin.H, 0, len(serials))
"serials": serials, for _, serial := range serials {
items = append(items, gin.H{
"serialNumber": serial.SerialNumber,
"companyName": serial.CompanyName,
"validUntil": serial.ValidUntil,
"isActive": serial.IsActive,
"createdAt": serial.CreatedAt,
"createdBy": userModel.Name,
})
}
SuccessResponse(ctx, "成功生成"+strconv.Itoa(len(serials))+"个序列号", gin.H{
"serials": items,
}) })
} }
@@ -98,8 +111,20 @@ func (c *SerialsController) GenerateWithPrefix(ctx *gin.Context) {
return return
} }
SuccessResponse(ctx, "成功生成 "+strconv.Itoa(len(serials))+" 个序列号", gin.H{ items := make([]gin.H, 0, len(serials))
"serials": serials, for _, serial := range serials {
items = append(items, gin.H{
"serialNumber": serial.SerialNumber,
"companyName": serial.CompanyName,
"validUntil": serial.ValidUntil,
"isActive": serial.IsActive,
"createdAt": serial.CreatedAt,
"createdBy": userModel.Name,
})
}
SuccessResponse(ctx, "成功生成"+strconv.Itoa(len(serials))+"个序列号", gin.H{
"serials": items,
}) })
} }
@@ -168,8 +193,26 @@ func (c *SerialsController) Query(ctx *gin.Context) {
return return
} }
createdBy := ""
if serial.User != nil {
createdBy = serial.User.Name
}
status := "active"
if !serial.IsActive {
status = "disabled"
}
SuccessResponse(ctx, "查询成功", gin.H{ SuccessResponse(ctx, "查询成功", gin.H{
"serial": serial, "serial": gin.H{
"serialNumber": serial.SerialNumber,
"companyName": serial.CompanyName,
"validUntil": serial.ValidUntil,
"status": status,
"isActive": serial.IsActive,
"createdAt": serial.CreatedAt,
"createdBy": createdBy,
},
}) })
} }
@@ -197,8 +240,25 @@ func (c *SerialsController) FindAll(ctx *gin.Context) {
return return
} }
items := make([]gin.H, 0, len(serials))
for _, serial := range serials {
createdBy := ""
if serial.User != nil {
createdBy = serial.User.Name
}
items = append(items, gin.H{
"serialNumber": serial.SerialNumber,
"companyName": serial.CompanyName,
"validUntil": serial.ValidUntil,
"isActive": serial.IsActive,
"createdAt": serial.CreatedAt,
"createdBy": createdBy,
})
}
SuccessResponse(ctx, "获取序列号列表成功", gin.H{ SuccessResponse(ctx, "获取序列号列表成功", gin.H{
"data": serials, "data": items,
"pagination": gin.H{ "pagination": gin.H{
"page": page, "page": page,
"limit": limit, "limit": limit,
@@ -237,8 +297,21 @@ func (c *SerialsController) Update(ctx *gin.Context) {
return return
} }
SuccessResponse(ctx, "序列号信息更新成功", gin.H{ createdBy := ""
"serial": serial, if serial.User != nil {
createdBy = serial.User.Name
}
SuccessResponse(ctx, "序列号更新成功", gin.H{
"serial": gin.H{
"serialNumber": serial.SerialNumber,
"companyName": serial.CompanyName,
"validUntil": serial.ValidUntil,
"isActive": serial.IsActive,
"createdAt": serial.CreatedAt,
"updatedAt": serial.UpdatedAt,
"createdBy": createdBy,
},
}) })
} }
@@ -264,5 +337,9 @@ func (c *SerialsController) Revoke(ctx *gin.Context) {
return return
} }
SuccessResponse(ctx, "序列号吊销成功") SuccessResponse(ctx, "序列号吊销", gin.H{
"data": gin.H{
"serialNumber": strings.ToUpper(serialNumber),
},
})
} }

View File

@@ -21,12 +21,12 @@ func (s *AuthService) ValidateUser(username string, password string) (*models.Us
var user models.User var user models.User
result := database.DB.Where("username = ?", username).First(&user) result := database.DB.Where("username = ?", username).First(&user)
if result.Error != nil { if result.Error != nil {
return nil, fmt.Errorf("验证用户失败: %w", errors.New("用户名或密码错误")) return nil, errors.New("用户名或密码不正确")
} }
err := bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(password)) err := bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(password))
if err != nil { if err != nil {
return nil, fmt.Errorf("密码验证失败: %w", errors.New("用户名或密码错误")) return nil, errors.New("用户名或密码不正确")
} }
return &user, nil return &user, nil

View File

@@ -244,6 +244,8 @@ func (s *SerialsService) Update(serialNumber string, updateData models.UpdateSer
return nil, fmt.Errorf("更新序列号失败: %w", result.Error) return nil, fmt.Errorf("更新序列号失败: %w", result.Error)
} }
_ = database.DB.Preload("User").Where("serial_number = ?", serial.SerialNumber).First(&serial)
return &serial, nil return &serial, nil
} }

View File

@@ -160,5 +160,5 @@ func TestLoginFailed(t *testing.T) {
var response map[string]interface{} var response map[string]interface{}
err := json.Unmarshal(w.Body.Bytes(), &response) err := json.Unmarshal(w.Body.Bytes(), &response)
assert.NoError(t, err) assert.NoError(t, err)
assert.Contains(t, response["message"], "用户名或密码错误") assert.Contains(t, response["message"], "用户名或密码不正确")
} }