- main.go/auth_middleware: web 静态目录托管与 history 回退、Chrome DevTools 探测处理 - 新增 scripts/build_web.sh(缓存判断构建 web)与 scripts/dev.sh(一键构建+启动) - 删除已过时的 routes.sh(goframe 自动生成 api.json)与 split_db(数据库已拆分完毕) - docs: 补充联调与测试规范(测试必须用真实用户数据 wenwu901/123456)
58 lines
1.9 KiB
Go
58 lines
1.9 KiB
Go
package common
|
||
|
||
import (
|
||
"os"
|
||
"strings"
|
||
)
|
||
|
||
// webStaticDirs 候选前端静态目录(相对 server 工作目录,按序取第一个存在者):
|
||
// 1. 本地开发:直接服务 Flutter 构建产物 app/build/web(scripts/build_web.sh 或 dev.sh 构建)
|
||
// 2. Docker 镜像:Dockerfile web-builder 阶段产物(/app/web)
|
||
var webStaticDirs = []string{
|
||
"../app/build/web",
|
||
"web",
|
||
}
|
||
|
||
// WebStaticDir 返回可用的前端静态目录;全部不存在时返回 ""(仅 API 模式)
|
||
func WebStaticDir() string {
|
||
for _, dir := range webStaticDirs {
|
||
if _, err := os.Stat(dir); err == nil {
|
||
return dir
|
||
}
|
||
}
|
||
return ""
|
||
}
|
||
|
||
// apiPathPrefixes 后端 API 路径前缀,需与 RouteRegister 控制器注册的 kebab-case 保持一致。
|
||
// web 静态资源与 history 路由的识别都依赖它:带扩展名的路径视为静态资源,
|
||
// 无扩展名且命中 API 前缀的视为后端接口,其余视为前端 history 路由。
|
||
var apiPathPrefixes = []string{
|
||
"/user", "/user-photo", "/wardrobe", "/body-measurement", "/avatar",
|
||
"/hairstyle", "/outfit", "/partner-store", "/member", "/ad", "/cps",
|
||
"/workspace", "/api.json",
|
||
}
|
||
|
||
// IsAPIRequest 是否后端 API/受保护路径(不参与 web 静态与 history 回退)
|
||
func IsAPIRequest(path string) bool {
|
||
for _, p := range apiPathPrefixes {
|
||
if path == p || strings.HasPrefix(path, p+"/") {
|
||
return true
|
||
}
|
||
}
|
||
return false
|
||
}
|
||
|
||
// IsWebAsset web 静态资源:根路径或末段带扩展名(main.dart.js / assets/* / favicon.png),免鉴权放行
|
||
func IsWebAsset(path string) bool {
|
||
if path == "/" {
|
||
return true
|
||
}
|
||
base := path[strings.LastIndex(path, "/")+1:]
|
||
return strings.Contains(base, ".")
|
||
}
|
||
|
||
// IsWebHistoryRoute 前端 history 路由(无扩展名且非 API 路径),回退服务 index.html
|
||
func IsWebHistoryRoute(path string) bool {
|
||
return !IsWebAsset(path) && !IsAPIRequest(path)
|
||
}
|