Files
bj_power/bj_power_wms/bj_power_wms.go
T

122 lines
3.3 KiB
Go
Raw Normal View History

2026-08-28 15:06:01 +08:00
package main
import (
"embed"
2026-08-28 15:06:01 +08:00
"flag"
"fmt"
"io/fs"
"net/http"
"os/exec"
"path"
"runtime"
"strings"
"time"
2026-08-28 15:06:01 +08:00
"bj_power_wms/internal/config"
"bj_power_wms/internal/handler"
"bj_power_wms/internal/logdaily"
"bj_power_wms/internal/svc"
"github.com/zeromicro/go-zero/core/conf"
"github.com/zeromicro/go-zero/core/logx"
"github.com/zeromicro/go-zero/rest"
)
// 前端静态资源(Vue 构建产物,由 frontend/ npm run build 输出到 web/static)。
// 原由 bj_power_wms_client(8891) 托管并反代 API2026-09-07 合并进主服务:
// 一个 exe、一个端口(8890)同时提供页面与 API。
//
//go:embed all:web/static
var webFS embed.FS
2026-08-28 15:06:01 +08:00
var configFile = flag.String("f", "etc/bj_power_wms-api.yaml", "the config file")
// newStaticHandler 嵌入式静态文件:命中则直接返回;未命中的非 /api 路径
// 回退到 index.htmlSPA history 路由),由浏览器端 Vue Router 接管。
func newStaticHandler(fsys embed.FS) http.Handler {
sub, err := fs.Sub(fsys, "web/static")
if err != nil {
panic(fmt.Sprintf("嵌入静态目录不可用: %v", err))
}
fileServer := http.FileServer(http.FS(sub))
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
name := strings.TrimPrefix(path.Clean(r.URL.Path), "/")
if name == "" {
name = "index.html"
}
if f, openErr := sub.Open(name); openErr == nil {
f.Close()
fileServer.ServeHTTP(w, r)
return
}
r2 := r.Clone(r.Context())
r2.URL.Path = "/"
fileServer.ServeHTTP(w, r2)
})
}
// openBrowser 调用系统默认浏览器打开 url(仅本机开发使用,服务器部署时 Web.OpenBrowser=false
func openBrowser(url string) {
var cmd *exec.Cmd
switch runtime.GOOS {
case "windows":
cmd = exec.Command("rundll32", "url.dll,FileProtocolHandler", url)
case "darwin":
cmd = exec.Command("open", url)
default:
cmd = exec.Command("xdg-open", url)
}
_ = cmd.Start()
}
2026-08-28 15:06:01 +08:00
func main() {
flag.Parse()
var c config.Config
conf.MustLoad(*configFile, &c)
// 日志按天存储:logs/bj_power_wms-2026-01-02.log,保留 30 天
if c.Log.Mode == "file" {
logx.SetUp(c.Log)
w := logdaily.New(c.Log.Path, c.Name, 30)
defer w.Close()
logx.SetWriter(logx.NewWriter(w))
}
staticHandler := newStaticHandler(webFS)
// 兜底路由:已注册的 /api/* 走正常匹配;未注册的非 /api 路径走嵌入式静态资源
//(/api 下未注册的路径仍返回 404,不回退页面)
notFound := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if strings.HasPrefix(r.URL.Path, "/api/") || r.URL.Path == "/api" {
http.NotFound(w, r)
return
}
staticHandler.ServeHTTP(w, r)
})
server := rest.MustNewServer(c.RestConf, rest.WithNotFoundHandler(notFound))
2026-08-28 15:06:01 +08:00
defer server.Stop()
ctx := svc.NewServiceContext(c)
handler.RegisterHandlers(server, ctx)
fmt.Printf("Starting bj_power_wms server at %s:%d...\n", c.Host, c.Port)
logx.Infof("Starting bj_power_wms server at %s:%d...", c.Host, c.Port)
// 服务起来后自动打开浏览器访问前端(本机开发便利;Web.OpenBrowser=false 关闭)
if c.Web.OpenBrowser {
go func() {
time.Sleep(time.Second)
host := c.Host
if host == "0.0.0.0" || host == "" {
host = "127.0.0.1"
}
openBrowser(fmt.Sprintf("http://%s:%d", host, c.Port))
}()
}
2026-08-28 15:06:01 +08:00
server.Start()
}