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]
func (c *AuthController) Login(ctx *gin.Context) {
var loginData models.LoginDTO
if err := ctx.ShouldBindJSON(&loginData); err != nil {
ctx.JSON(http.StatusBadRequest, gin.H{
"message": "无效的请求数据",
"error": err.Error(),
})
if !BindJSON(ctx, &loginData) {
return
}
user, err := c.authService.ValidateUser(loginData.Username, loginData.Password)
if err != nil {
ctx.JSON(http.StatusUnauthorized, gin.H{
"message": err.Error(),
})
ErrorResponse(ctx, http.StatusUnauthorized, err.Error())
return
}
token, err := c.authService.GenerateToken(user)
if err != nil {
ctx.JSON(http.StatusInternalServerError, gin.H{
"message": "令牌生成失败",
})
ErrorResponse(ctx, http.StatusInternalServerError, "令牌生成失败")
return
}

View File

@@ -2,12 +2,52 @@ package controllers
import (
"net/http"
"strings"
"github.com/gin-gonic/gin"
"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 从上下文中获取当前用户
// 如果用户未认证,返回 false 并返回 401 错误
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 {
if err := ctx.ShouldBindJSON(obj); err != nil {
ctx.JSON(http.StatusBadRequest, gin.H{
"message": "无效的请求数据",
"error": err.Error(),
"message": "提交数据格式不正确",
})
return false
}
@@ -48,8 +87,7 @@ func BindJSON(ctx *gin.Context, obj interface{}) bool {
func BindQuery(ctx *gin.Context, obj interface{}) bool {
if err := ctx.ShouldBindQuery(obj); err != nil {
ctx.JSON(http.StatusBadRequest, gin.H{
"message": "无效的查询参数",
"error": err.Error(),
"message": "查询参数不正确",
})
return false
}
@@ -58,11 +96,12 @@ func BindQuery(ctx *gin.Context, obj interface{}) bool {
// ErrorResponse 返回错误响应
func ErrorResponse(ctx *gin.Context, status int, message string, err ...error) {
friendly := friendlyMessage(message)
response := gin.H{
"message": message,
"message": friendly,
}
if len(err) > 0 && err[0] != nil {
response["error"] = err[0].Error()
response["error"] = friendlyMessage(err[0].Error())
}
ctx.JSON(status, response)
}

View File

@@ -3,6 +3,7 @@ package controllers
import (
"net/http"
"strconv"
"strings"
"github.com/gin-gonic/gin"
@@ -57,8 +58,20 @@ func (c *SerialsController) Generate(ctx *gin.Context) {
return
}
SuccessResponse(ctx, "成功生成 "+strconv.Itoa(len(serials))+" 个序列号", gin.H{
"serials": serials,
items := make([]gin.H, 0, len(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
}
SuccessResponse(ctx, "成功生成 "+strconv.Itoa(len(serials))+" 个序列号", gin.H{
"serials": serials,
items := make([]gin.H, 0, len(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
}
createdBy := ""
if serial.User != nil {
createdBy = serial.User.Name
}
status := "active"
if !serial.IsActive {
status = "disabled"
}
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
}
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{
"data": serials,
"data": items,
"pagination": gin.H{
"page": page,
"limit": limit,
@@ -237,8 +297,21 @@ func (c *SerialsController) Update(ctx *gin.Context) {
return
}
SuccessResponse(ctx, "序列号信息更新成功", gin.H{
"serial": serial,
createdBy := ""
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
}
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
result := database.DB.Where("username = ?", username).First(&user)
if result.Error != nil {
return nil, fmt.Errorf("验证用户失败: %w", errors.New("用户名或密码错误"))
return nil, errors.New("用户名或密码不正确")
}
err := bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(password))
if err != nil {
return nil, fmt.Errorf("密码验证失败: %w", errors.New("用户名或密码错误"))
return nil, errors.New("用户名或密码不正确")
}
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)
}
_ = database.DB.Preload("User").Where("serial_number = ?", serial.SerialNumber).First(&serial)
return &serial, nil
}

View File

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