Files
rikkei_simple_care/server/internal/qldt/client.go
PhuocNTB f5dce38e11
All checks were successful
Deploy on Master Change / deploy (push) Successful in 1m12s
add phep
2026-07-06 10:58:38 +07:00

264 lines
7.3 KiB
Go

package qldt
import (
"bytes"
"context"
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"strconv"
"strings"
"time"
)
type Client struct {
baseURL string
origin string
http *http.Client
}
func NewClient(baseURL, origin string) *Client {
baseURL = strings.TrimRight(baseURL, "/")
return &Client{
baseURL: baseURL,
origin: origin,
http: &http.Client{
Timeout: 45 * time.Second,
},
}
}
type StudentsResponse struct {
Message string `json:"message"`
StatusCode int `json:"statusCode"`
Data []StudentDTO `json:"data"`
Total int `json:"total"`
Page string `json:"page"`
PageSize string `json:"pageSize"`
}
type StudentDTO struct {
ID int64 `json:"id"`
StudentCode string `json:"studentCode"`
FullName string `json:"fullName"`
Phone *string `json:"phone"`
Email string `json:"email"`
DateOfBirth *string `json:"dateOfBirth"`
Gender *int `json:"gender"`
Status *string `json:"status"`
Location *string `json:"location"`
Avatar *string `json:"avatar"`
System *struct {
ID int64 `json:"id"`
Name string `json:"name"`
} `json:"system"`
}
type ClassesResponse struct {
Data []ClassDTO `json:"data"`
StatusCode int `json:"statusCode"`
}
type ClassDTO struct {
ID int64 `json:"id"`
Name string `json:"name"`
ClassCode string `json:"classCode"`
Type string `json:"type"`
StudentCount int `json:"studentCount"`
CreatedAt string `json:"createdAt"`
UpdatedAt *string `json:"updatedAt"`
Specializes *struct {
ID int64 `json:"id"`
Name string `json:"name"`
Systems *struct {
ID int64 `json:"id"`
SystemCode string `json:"systemCode"`
Name string `json:"name"`
} `json:"systems"`
} `json:"specializes"`
Courses []classCourseNestDTO `json:"courses"`
}
type classCourseNestDTO struct {
ID int64 `json:"id"`
Name string `json:"name"`
}
func (c *Client) GetStudents(ctx context.Context, token string, page, pageSize int) (*StudentsResponse, error) {
u, err := url.Parse(c.baseURL + "/students")
if err != nil {
return nil, err
}
q := u.Query()
q.Set("page", strconv.Itoa(page))
q.Set("pageSize", strconv.Itoa(pageSize))
u.RawQuery = q.Encode()
req, err := http.NewRequestWithContext(ctx, http.MethodGet, u.String(), nil)
if err != nil {
return nil, err
}
req.Header.Set("Authorization", "Bearer "+token)
if c.origin != "" {
req.Header.Set("Origin", c.origin)
req.Header.Set("Referer", c.origin+"/")
}
req.Header.Set("Accept", "application/json")
resp, err := c.http.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
if resp.StatusCode < 200 || resp.StatusCode >= 300 {
return nil, fmt.Errorf("qldt students http %d: %s", resp.StatusCode, string(body))
}
var out StudentsResponse
if err := json.Unmarshal(body, &out); err != nil {
return nil, err
}
if out.StatusCode != 0 && out.StatusCode != 200 {
return nil, fmt.Errorf("qldt statusCode %d: %s", out.StatusCode, out.Message)
}
return &out, nil
}
func (c *Client) GetClassesBySystem(ctx context.Context, token string, systemID int64) (*ClassesResponse, error) {
u := fmt.Sprintf("%s/classes/system/%d", c.baseURL, systemID)
req, err := http.NewRequestWithContext(ctx, http.MethodGet, u, nil)
if err != nil {
return nil, err
}
req.Header.Set("Authorization", "Bearer "+token)
if c.origin != "" {
req.Header.Set("Origin", c.origin)
req.Header.Set("Referer", c.origin+"/")
}
req.Header.Set("Accept", "application/json")
resp, err := c.http.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
if resp.StatusCode < 200 || resp.StatusCode >= 300 {
return nil, fmt.Errorf("qldt classes/system/%d http %d: %s", systemID, resp.StatusCode, string(body))
}
var outClasses ClassesResponse
if err := json.Unmarshal(body, &outClasses); err != nil {
return nil, err
}
if outClasses.StatusCode != 0 && outClasses.StatusCode != 200 {
return nil, fmt.Errorf("qldt classes statusCode %d", outClasses.StatusCode)
}
return &outClasses, nil
}
func (c *Client) GetClassDashboard(ctx context.Context, token string, classID, courseID int64) ([]byte, error) {
u := fmt.Sprintf("%s/classes/dashboard/%d/%d", c.baseURL, classID, courseID)
req, err := http.NewRequestWithContext(ctx, http.MethodGet, u, nil)
if err != nil {
return nil, err
}
req.Header.Set("Authorization", "Bearer "+token)
if c.origin != "" {
req.Header.Set("Origin", c.origin)
req.Header.Set("Referer", c.origin+"/")
}
req.Header.Set("Accept", "application/json")
resp, err := c.http.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
if resp.StatusCode < 200 || resp.StatusCode >= 300 {
return nil, fmt.Errorf("qldt classes/dashboard/%d/%d http %d: %s", classID, courseID, resp.StatusCode, string(body))
}
var probe struct {
StatusCode int `json:"statusCode"`
Message string `json:"message"`
}
if err := json.Unmarshal(body, &probe); err == nil {
if probe.StatusCode != 0 && probe.StatusCode != 200 {
return nil, fmt.Errorf("qldt classes/dashboard statusCode %d: %s", probe.StatusCode, probe.Message)
}
}
return body, nil
}
func (c *Client) GetLeaveRequests(ctx context.Context, token string, classID, courseID int64, date string) ([]byte, error) {
u := fmt.Sprintf("%s/request-leave?classId=%d&courseId=%d&date=%s", c.baseURL, classID, courseID, date)
req, err := http.NewRequestWithContext(ctx, http.MethodGet, u, nil)
if err != nil {
return nil, err
}
c.setAuthHeaders(req, token)
resp, err := c.http.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
if resp.StatusCode < 200 || resp.StatusCode >= 300 {
return nil, fmt.Errorf("qldt request-leave http %d: %s", resp.StatusCode, string(body))
}
return body, nil
}
func (c *Client) UpdateLeaveStatus(ctx context.Context, token string, leaveID int64, status string) ([]byte, error) {
payload := map[string]string{"status": status}
jsonData, _ := json.Marshal(payload)
u := fmt.Sprintf("%s/request-leave/%d/status", c.baseURL, leaveID)
req, err := http.NewRequestWithContext(ctx, http.MethodPatch, u, bytes.NewBuffer(jsonData))
if err != nil {
return nil, err
}
req.Header.Set("Content-Type", "application/json")
c.setAuthHeaders(req, token)
resp, err := c.http.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
if resp.StatusCode < 200 || resp.StatusCode >= 300 {
// Fallback to POST method if PATCH is Method Not Allowed or Not Found
if resp.StatusCode == http.StatusMethodNotAllowed || resp.StatusCode == http.StatusNotFound {
req2, err2 := http.NewRequestWithContext(ctx, http.MethodPost, u, bytes.NewBuffer(jsonData))
if err2 == nil {
req2.Header.Set("Content-Type", "application/json")
c.setAuthHeaders(req2, token)
resp2, errOr := c.http.Do(req2)
if errOr == nil {
defer resp2.Body.Close()
body2, _ := io.ReadAll(resp2.Body)
if resp2.StatusCode >= 200 && resp2.StatusCode < 300 {
return body2, nil
}
}
}
}
return nil, fmt.Errorf("qldt request-leave/%d/status http %d: %s", leaveID, resp.StatusCode, string(body))
}
return body, nil
}