- 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
70 lines
2.0 KiB
Go
70 lines
2.0 KiB
Go
package handler
|
||
|
||
import (
|
||
"io/fs"
|
||
"net/http"
|
||
"path"
|
||
"strings"
|
||
)
|
||
|
||
// indexHandler 服务嵌入式前端首页 web/static/index.html。
|
||
func indexHandler(fsys fs.FS) http.HandlerFunc {
|
||
return func(w http.ResponseWriter, r *http.Request) {
|
||
b, err := fs.ReadFile(fsys, "index.html")
|
||
if err != nil {
|
||
http.Error(w, "前端页面尚未构建:请在 frontend 目录执行 pnpm build", http.StatusNotFound)
|
||
return
|
||
}
|
||
w.Header().Set("Content-Type", "text/html; charset=utf-8")
|
||
_, _ = w.Write(b)
|
||
}
|
||
}
|
||
|
||
// mimeFallback 构建产物常见静态资源的 Content-Type 兜底表
|
||
// (mime.TypeByExtension 在部分 Windows 环境依赖系统注册表,结果不稳定)。
|
||
var mimeFallback = map[string]string{
|
||
".html": "text/html; charset=utf-8",
|
||
".css": "text/css; charset=utf-8",
|
||
".js": "text/javascript; charset=utf-8",
|
||
".mjs": "text/javascript; charset=utf-8",
|
||
".json": "application/json; charset=utf-8",
|
||
".svg": "image/svg+xml",
|
||
".png": "image/png",
|
||
".jpg": "image/jpeg",
|
||
".jpeg": "image/jpeg",
|
||
".gif": "image/gif",
|
||
".ico": "image/x-icon",
|
||
".woff": "font/woff",
|
||
".woff2": "font/woff2",
|
||
".ttf": "font/ttf",
|
||
".webp": "image/webp",
|
||
}
|
||
|
||
// assetHandler 服务 vite 构建产物 /assets/<file>。
|
||
// 前端使用 hash 路由,静态托管只需覆盖根路径与扁平的 assets 目录。
|
||
func assetHandler(fsys fs.FS) http.HandlerFunc {
|
||
return func(w http.ResponseWriter, r *http.Request) {
|
||
name := strings.TrimPrefix(r.URL.EscapedPath(), "/assets/")
|
||
if name == "" || strings.ContainsAny(name, `/\`) || strings.Contains(name, "..") {
|
||
http.NotFound(w, r)
|
||
return
|
||
}
|
||
if _, err := fs.Stat(fsys, "assets/"+name); err != nil {
|
||
http.NotFound(w, r)
|
||
return
|
||
}
|
||
|
||
ct := mimeFallback[strings.ToLower(path.Ext(name))]
|
||
if ct == "" {
|
||
ct = "application/octet-stream"
|
||
}
|
||
w.Header().Set("Content-Type", ct)
|
||
w.Header().Set("Cache-Control", "public, max-age=31536000, immutable") // vite 产物带内容哈希
|
||
b, err := fs.ReadFile(fsys, "assets/"+name)
|
||
if err != nil {
|
||
return
|
||
}
|
||
_, _ = w.Write(b)
|
||
}
|
||
}
|