- MES(B): 工单/BOM/备料/工序字典/PLC下发/拧紧/扫码报工/半成品/AGV/追溯逻辑,WMS与海康RCS客户端,看板Redis缓存API(概览/设备/进度/报警/趋势)+SSE - WMS(C): JWT滑动续签、Excel导入、盘点、内部API、种子数据、独立Postgres配置 - WMS客户端(E): Go网关8891反向代理+内嵌Vue3十页 - 工位终端(D): SQLite本地缓存+模拟拧紧源+内嵌Vue3页面 - Dashboard(A): 看板数据改接MES内部缓存API,SSE实时刷新+vite代理 - 清理各项目球形磨遗留代码,新增部署手册.md
85 lines
2.1 KiB
Go
85 lines
2.1 KiB
Go
package mes
|
||
|
||
import (
|
||
"bytes"
|
||
"encoding/json"
|
||
"fmt"
|
||
"io"
|
||
"net/http"
|
||
"net/url"
|
||
"strings"
|
||
"time"
|
||
)
|
||
|
||
// Client MES 内部 API HTTP 客户端。
|
||
// 自动携带请求头:X-API-TOKEN(写死的项目间 token)、Content-Type: application/json。
|
||
// Get/Post 返回原始响应体与响应头;任何非 2xx 状态返回包含响应体的错误信息。
|
||
type Client struct {
|
||
baseURL string
|
||
token string
|
||
httpClient *http.Client
|
||
}
|
||
|
||
func New(baseURL, token string) *Client {
|
||
return &Client{
|
||
baseURL: strings.TrimRight(baseURL, "/"),
|
||
token: token,
|
||
httpClient: &http.Client{Timeout: 10 * time.Second},
|
||
}
|
||
}
|
||
|
||
// Get 发送 GET 请求,query 为空则忽略。
|
||
func (c *Client) Get(path string, query url.Values) ([]byte, http.Header, error) {
|
||
u := c.baseURL + path
|
||
if len(query) > 0 {
|
||
u += "?" + query.Encode()
|
||
}
|
||
return c.do(http.MethodGet, u, nil)
|
||
}
|
||
|
||
// Post 发送 POST 请求,body 序列化为 JSON(body 为 nil 则不发送请求体)。
|
||
func (c *Client) Post(path string, body any) ([]byte, http.Header, error) {
|
||
var reader io.Reader
|
||
if body != nil {
|
||
b, err := json.Marshal(body)
|
||
if err != nil {
|
||
return nil, nil, fmt.Errorf("序列化请求体失败: %w", err)
|
||
}
|
||
reader = bytes.NewReader(b)
|
||
}
|
||
return c.do(http.MethodPost, c.baseURL+path, reader)
|
||
}
|
||
|
||
func (c *Client) do(method, u string, body io.Reader) ([]byte, http.Header, error) {
|
||
req, err := http.NewRequest(method, u, body)
|
||
if err != nil {
|
||
return nil, nil, err
|
||
}
|
||
req.Header.Set("X-API-TOKEN", c.token)
|
||
req.Header.Set("Content-Type", "application/json;charset=utf-8")
|
||
|
||
resp, err := c.httpClient.Do(req)
|
||
if err != nil {
|
||
return nil, nil, err
|
||
}
|
||
defer resp.Body.Close()
|
||
|
||
respBody, err := io.ReadAll(resp.Body)
|
||
if err != nil {
|
||
return nil, resp.Header, err
|
||
}
|
||
if resp.StatusCode < 200 || resp.StatusCode > 299 {
|
||
return respBody, resp.Header, fmt.Errorf("MES %s %s 返回 %d:%s",
|
||
method, u, resp.StatusCode, truncate(string(respBody), 200))
|
||
}
|
||
return respBody, resp.Header, nil
|
||
}
|
||
|
||
func truncate(s string, n int) string {
|
||
s = strings.TrimSpace(s)
|
||
if len(s) > n {
|
||
return s[:n] + "..."
|
||
}
|
||
return s
|
||
}
|