package httpapi import ( "errors" "log" "net/http" "strconv" "strings" "git.118im.com/im_team/olons_server/internal/support" ) type customerServiceSessionRequest struct { DeviceID string `json:"device_id"` Platform string `json:"platform"` AppVersion string `json:"app_version"` } func (a *API) customerServiceResource(w http.ResponseWriter, r *http.Request) { path := strings.Trim(strings.TrimPrefix(r.URL.Path, "/v1/customer-services/"), "/") parts := strings.Split(path, "/") if len(parts) != 2 || parts[1] != "session" { writeError(w, r, http.StatusNotFound, 30004, "RESOURCE_NOT_FOUND", "resource not found", nil) return } serviceID, err := strconv.ParseInt(parts[0], 10, 64) if err != nil || serviceID <= 0 { writeError(w, r, http.StatusNotFound, 30004, "RESOURCE_NOT_FOUND", "resource not found", nil) return } if r.Method != http.MethodPost { methodNotAllowed(w, r, http.MethodPost) return } principal, ok := a.authenticateMember(w, r) if !ok { return } if a.support == nil { writeSupportError(w, r, support.ErrIMUnavailable) return } var body customerServiceSessionRequest if !decodeBody(w, r, &body) { return } deviceID := strings.TrimSpace(body.DeviceID) if deviceID == "" { deviceID = principal.DeviceID } result, err := a.support.OpenSession(r.Context(), principal.TenantID, principal.MemberID, serviceID, support.SessionRequest{DeviceID: deviceID, Platform: body.Platform}) if err != nil { writeSupportError(w, r, err) return } writeSuccess(w, r, result) } func writeSupportError(w http.ResponseWriter, r *http.Request, err error) { log.Printf("customer service session failed request_id=%s err=%v", r.Header.Get("X-Request-ID"), err) switch { case errors.Is(err, support.ErrServiceNotFound): writeError(w, r, http.StatusNotFound, 41001, "CUSTOMER_SERVICE_NOT_FOUND", "customer service not found", nil) case errors.Is(err, support.ErrServiceNotBound): writeError(w, r, http.StatusConflict, 41002, "CUSTOMER_SERVICE_NOT_BOUND", "customer service account is not configured", nil) case errors.Is(err, support.ErrRelationPending): writeError(w, r, http.StatusConflict, 41003, "IM_RELATION_PENDING", "customer service relationship is pending", nil) case errors.Is(err, support.ErrRelationDenied): writeError(w, r, http.StatusForbidden, 41004, "IM_RELATION_NOT_ALLOWED", "customer service relationship is not allowed", nil) case errors.Is(err, support.ErrIMUnavailable): writeError(w, r, http.StatusServiceUnavailable, 41005, "IM_SERVICE_UNAVAILABLE", "IM service unavailable", nil) default: writeError(w, r, http.StatusBadGateway, 41006, "IM_SERVICE_UNAVAILABLE", "IM service unavailable", nil) } }