feat: 五项目业务实现并对接完成

- 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
This commit is contained in:
SunYF
2026-08-27 19:50:57 +08:00
parent c85c3bd6f1
commit a2afd2f6dc
335 changed files with 87495 additions and 7357 deletions
@@ -0,0 +1,84 @@
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
}