package handlers import ( "encoding/json" "net/http" "strconv" "smart-customer-service/internal/models" ) // ResourceHandler 资源处理器 type ResourceHandler struct{} // Create 创建资源 func (h *ResourceHandler) Create(w http.ResponseWriter, r *http.Request) { var resource models.Resource if err := json.NewDecoder(r.Body).Decode(&resource); err != nil { http.Error(w, err.Error(), http.StatusBadRequest) return } // 验证必填字段 if resource.Name == "" || resource.Code == "" || resource.Type == "" { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusBadRequest) json.NewEncoder(w).Encode(map[string]string{ "error": "name, code, and type are required", }) return } // 验证资源类型 validTypes := map[string]bool{ "api": true, // API 端点 "page": true, // 页面 "button": true, // 按钮 "data": true, // 数据字段 } if !validTypes[resource.Type] { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusBadRequest) json.NewEncoder(w).Encode(map[string]string{ "error": "invalid resource type, must be one of: api, page, button, data", }) return } // 检查代码是否已存在 // if exists := checkResourceExists(resource.Code); exists { // http.Error(w, `{"error": "resource code already exists"}`, http.StatusConflict) // return // } // TODO: 保存到数据库 // db.Create(&resource) w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusCreated) json.NewEncoder(w).Encode(map[string]interface{}{ "message": "资源创建成功", "data": resource, }) } // List 获取资源列表 func (h *ResourceHandler) List(w http.ResponseWriter, r *http.Request) { page := getPageParam(r, 1) perPage := getPageParam(r, 20) // 获取过滤参数 tenantIDStr := r.URL.Query().Get("tenant_id") resourceType := r.URL.Query().Get("type") group := r.URL.Query().Get("group") isSystem := r.URL.Query().Get("is_system") // TODO: 查询数据库 // var resources []models.Resource // query := db.Where("tenant_id = ?", tenantID) // if resourceType != "" { // query = query.Where("type = ?", resourceType) // } // if group != "" { // query = query.Where("group = ?", group) // } // if isSystem == "true" { // query = query.Where("is_system = ?", true) // } // query.Order("sort_order").Find(&resources) var resources []models.Resource 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{ "type": resourceType, "group": group, "is_system": isSystem, }, "data": resources, }) } // Get 获取单个资源 func (h *ResourceHandler) 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 resource models.Resource // db.Preload("Roles").Preload("Parent").Preload("Children").First(&resource, id) var resource models.Resource if resource.ID == 0 { http.Error(w, `{"error": "resource not found"}`, http.StatusNotFound) return } w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(resource) } // Update 更新资源 func (h *ResourceHandler) 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 resource models.Resource if err := json.NewDecoder(r.Body).Decode(&resource); err != nil { http.Error(w, err.Error(), http.StatusBadRequest) return } // 不允许修改代码 (Code 是唯一索引) // resource.Code = "" // TODO: 更新数据库 // db.Model(&resource).Where("id = ?", id).Updates(resource) w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(map[string]interface{}{ "message": "资源更新成功", "data": resource, }) } // Delete 删除资源 func (h *ResourceHandler) 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 } // 检查是否有子资源 // childCount := countChildResources(id) // if childCount > 0 { // http.Error(w, `{"error": "cannot delete resource with children"}`, http.StatusBadRequest) // return // } // 检查是否有角色使用 // roleCount := countRolesWithResource(id) // if roleCount > 0 { // http.Error(w, `{"error": "cannot delete resource with associated roles"}`, 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, }) } // GetTree 获取资源树形结构 func (h *ResourceHandler) GetTree(w http.ResponseWriter, r *http.Request) { // 获取过滤参数 tenantIDStr := r.URL.Query().Get("tenant_id") groupBy := r.URL.Query().Get("group_by") // 按分组、类型等分组 // TODO: 查询数据库 // 1. 查询所有资源 // 2. 构建树形结构 // 3. 按分组分类返回 type ResourceTree struct { ID uint `json:"id"` Name string `json:"name"` Code string `json:"code"` Type string `json:"type"` Children []ResourceTree `json:"children,omitempty"` ParentID *uint `json:"parent_id,omitempty"` } var tree []ResourceTree w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(map[string]interface{}{ "tree": tree, }) } // GetResourceByCode 通过代码获取资源 func (h *ResourceHandler) GetResourceByCode(w http.ResponseWriter, r *http.Request) { code := r.URL.Query().Get("code") if code == "" { http.Error(w, `{"error": "code is required"}`, http.StatusBadRequest) return } // TODO: 查询数据库 // var resource models.Resource // db.Where("code = ?", code).First(&resource) var resource models.Resource if resource.ID == 0 { http.Error(w, `{"error": "resource not found"}`, http.StatusNotFound) return } w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(resource) } // CheckPermission 检查权限是否有效 func (h *ResourceHandler) CheckPermission(w http.ResponseWriter, r *http.Request) { type PermissionCheck struct { UserID uint `json:"user_id"` TenantID uint `json:"tenant_id"` ResourceCode string `json:"resource_code"` Action string `json:"action"` // create, read, update, delete, etc. } var req PermissionCheck if err := json.NewDecoder(r.Body).Decode(&req); err != nil { http.Error(w, err.Error(), http.StatusBadRequest) return } // TODO: 实现权限检查逻辑 // 1. 查询用户角色 // 2. 查询角色资源 // 3. 检查资源是否包含该操作 w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(map[string]interface{}{ "has_permission": false, "reason": "permission check not implemented", }) }