package handlers import ( "encoding/json" "net/http" "strconv" "strings" "smart-customer-service/internal/models" ) // UserHandler 用户处理器 type UserHandler struct{} // Create 创建用户 func (h *UserHandler) Create(w http.ResponseWriter, r *http.Request) { var user models.User if err := json.NewDecoder(r.Body).Decode(&user); err != nil { http.Error(w, err.Error(), http.StatusBadRequest) return } // 验证必填字段 if user.Username == "" || user.Email == "" { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusBadRequest) json.NewEncoder(w).Encode(map[string]string{ "error": "username and email are required", }) return } // 密码不能为空 if user.Password == "" { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusBadRequest) json.NewEncoder(w).Encode(map[string]string{ "error": "password is required", }) return } // TODO: 密码加密、保存到数据库 // user.Password = bcrypt.GenerateFromPassword(password) // db.Create(&user) w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusCreated) json.NewEncoder(w).Encode(map[string]interface{}{ "message": "用户创建成功", "data": user, }) } // List 获取用户列表 func (h *UserHandler) List(w http.ResponseWriter, r *http.Request) { // 获取分页参数 page := getPageParam(r, 1) perPage := getPageParam(r, 20) // 获取过滤参数 tenantIDStr := r.URL.Query().Get("tenant_id") status := r.URL.Query().Get("status") keyword := r.URL.Query().Get("keyword") // TODO: 查询数据库 // var users []models.User // query := db.Where("tenant_id = ?", tenantID) // if status != "" { // query = query.Where("status = ?", status) // } // if keyword != "" { // query = query.Where("username LIKE ? OR email LIKE ? OR full_name LIKE ?", "%"+keyword+"%", "%"+keyword+"%", "%"+keyword+"%") // } // query.Count(&total).Offset((page-1)*perPage).Limit(perPage).Preload("Tenant").Find(&users) var users []models.User w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(map[string]interface{}{ "total": 0, "page": page, "per_page": perPage, "total_pages": 0, "filters": map[string]string{ "tenant_id": tenantIDStr, "status": status, "keyword": keyword, }, "data": users, }) } // Get 获取单个用户 func (h *UserHandler) Get(w http.ResponseWriter, r *http.Request) { idStr := r.URL.Query().Get("id") if idStr == "" { http.Error(w, `{"error": "id is required"}`, http.StatusBadRequest) return } id, err := strconv.ParseUint(idStr, 10, 32) if err != nil { http.Error(w, `{"error": "invalid id"}`, http.StatusBadRequest) return } // TODO: 查询数据库 (包含关联数据) // var user models.User // db.Preload("Tenant").Preload("Roles").First(&user, id) var user models.User if user.ID == 0 { http.Error(w, `{"error": "user not found"}`, http.StatusNotFound) return } w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(user) } // Update 更新用户 func (h *UserHandler) Update(w http.ResponseWriter, r *http.Request) { idStr := r.URL.Query().Get("id") if idStr == "" { http.Error(w, `{"error": "id is required"}`, http.StatusBadRequest) return } id, err := strconv.ParseUint(idStr, 10, 32) if err != nil { http.Error(w, `{"error": "invalid id"}`, http.StatusBadRequest) return } var user models.User if err := json.NewDecoder(r.Body).Decode(&user); err != nil { http.Error(w, err.Error(), http.StatusBadRequest) return } // 不允许修改用户名和租户 ID user.Username = "" user.TenantID = 0 // TODO: 更新数据库 // db.Model(&user).Where("id = ?", id).Updates(user) w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(map[string]interface{}{ "message": "用户更新成功", "data": user, }) } // Delete 删除用户 func (h *UserHandler) Delete(w http.ResponseWriter, r *http.Request) { idStr := r.URL.Query().Get("id") if idStr == "" { http.Error(w, `{"error": "id is required"}`, http.StatusBadRequest) return } id, err := strconv.ParseUint(idStr, 10, 32) if err != nil { http.Error(w, `{"error": "invalid id"}`, http.StatusBadRequest) return } // TODO: 软删除 // db.Where("id = ?", id).Update("deleted_at", time.Now()) w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(map[string]interface{}{ "message": "用户删除成功", "id": id, }) } // ChangePassword 修改密码 func (h *UserHandler) ChangePassword(w http.ResponseWriter, r *http.Request) { idStr := r.URL.Query().Get("id") if idStr == "" { http.Error(w, `{"error": "id is required"}`, http.StatusBadRequest) return } type passwordChange struct { OldPassword string `json:"old_password"` NewPassword string `json:"new_password"` ConfirmPassword string `json:"confirm_password"` } var req passwordChange if err := json.NewDecoder(r.Body).Decode(&req); err != nil { http.Error(w, err.Error(), http.StatusBadRequest) return } // 验证新密码 if req.NewPassword != req.ConfirmPassword { http.Error(w, `{"error": "new passwords do not match"}`, http.StatusBadRequest) return } // 密码最小长度验证 if len(req.NewPassword) < 8 { http.Error(w, `{"error": "password must be at least 8 characters"}`, http.StatusBadRequest) return } // TODO: 验证旧密码、更新新密码 // 1. 查询用户旧密码 // 2. bcrypt.CompareHashAndPassword // 3. 更新密码 w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(map[string]string{ "message": "密码修改成功", }) } // AssignRoles 分配角色 func (h *UserHandler) AssignRoles(w http.ResponseWriter, r *http.Request) { idStr := r.URL.Query().Get("id") if idStr == "" { http.Error(w, `{"error": "id is required"}`, http.StatusBadRequest) return } type roleAssignment struct { RoleIDs []uint `json:"role_ids"` } var req roleAssignment if err := json.NewDecoder(r.Body).Decode(&req); err != nil { http.Error(w, err.Error(), http.StatusBadRequest) return } // TODO: 分配角色 // 1. 查询角色是否存在 // 2. 更新 user_roles 关联表 w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(map[string]interface{}{ "message": "角色分配成功", "data": req, }) } // 辅助函数:获取分页参数 func getPageParam(r *http.Request, defaultVal int) int { strVal := r.URL.Query().Get("page") if strVal == "" { return defaultVal } val, err := strconv.Atoi(strVal) if err != nil || val < 1 { return defaultVal } return val }