package handlers import ( "fmt" "net/http" "strconv" "strings" "time" "github.com/gin-gonic/gin" "go_blog/models" "gorm.io/gorm" ) // userForm 是后台用户创建/更新接口的 JSON 请求体, // 同时供共享创建/编辑表单模板的渲染使用(IsEdit/Action/TitleText 非绑定字段)。 type userForm struct { ID uint `json:"-"` Username string `json:"username"` Password string `json:"password"` DisplayName string `json:"display_name"` Email string `json:"email"` Gender string `json:"gender"` Birthday string `json:"birthday"` // 来自日期输入的 YYYY-MM-DD Role string `json:"role"` Status int `json:"status"` IsEdit bool Action string TitleText string } // userListView 为 User 附加预渲染的标签/徽章, // 使模板绝不调用包装为 interface{} 的结构体上的方法。 type userListView struct { models.User RoleLabel string RoleBadge string StatusLabel string StatusBadge string } // parseUserFormJSON 绑定 JSON 请求体的用户字段并去除空白。 // 绑定失败时已写入 400 响应并返回 ok=false。ID 来自路由参数。 func parseUserFormJSON(c *gin.Context) (userForm, bool) { var f userForm if !bindJSON(c, &f) { return f, false } f.ID = uintFormID(c.Param("id")) f.Username = strings.TrimSpace(f.Username) f.DisplayName = strings.TrimSpace(f.DisplayName) f.Email = strings.TrimSpace(f.Email) f.Gender = strings.TrimSpace(f.Gender) f.Birthday = strings.TrimSpace(f.Birthday) f.Role = strings.TrimSpace(f.Role) return f, true } // uintFormID 将路由 :id 解析为 uint(不存在/非法时为 0)。 func uintFormID(s string) uint { if s == "" { return 0 } n, err := strconv.ParseUint(s, 10, 64) if err != nil { return 0 } return uint(n) } // applyUserFormToData 将表单值写入模板数据映射, // 使渲染时表单被重新填充(初次加载或校验错误)。 func applyUserFormToData(data gin.H, f userForm) { data["FormID"] = f.ID data["FormUsername"] = f.Username data["FormPassword"] = f.Password data["FormDisplayName"] = f.DisplayName data["FormEmail"] = f.Email data["FormGender"] = f.Gender data["FormBirthday"] = f.Birthday data["FormRole"] = f.Role data["FormStatus"] = f.Status data["FormIsEdit"] = f.IsEdit data["FormAction"] = f.Action data["FormTitleText"] = f.TitleText } // renderUserForm 使用给定的表单值和可选的错误消息渲染共享的用户表单模板。 func renderUserForm(c *gin.Context, f userForm, errMsg string) { tr := getTr(c) data := DefaultData(c) data["Title"] = f.TitleText if errMsg != "" { data["Error"] = errMsg } //