fix: 固定开发环境后端数据目录,避免 cwd 不同导致头像 404

从 cwd 向上解析 backend 根,并写入本地开发启动约定。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-09-16 05:13:58 +08:00
parent 833bcd33a1
commit b0170a99fd
10 changed files with 208 additions and 9 deletions

View File

@@ -20,11 +20,13 @@ type Config struct {
DevMode bool
}
// Parse 解析配置:环境变量 > app.ini > 默认值
// Parse 解析配置:环境变量 > app.ini > 默认值。
// 工作目录不跟 os.Getwd() 走:从 cwd 向上查找 backend 根(含 app.ini 或源码标记),
// 避免在仓库根 / cmd/jiang13 启动时把上传文件写进另一套 data/。
func Parse() (*Config, error) {
workPath, err := os.Getwd()
workPath, err := resolveWorkPath()
if err != nil {
return nil, fmt.Errorf("获取工作目录失败: %w", err)
return nil, err
}
// 默认值
@@ -83,6 +85,10 @@ func Parse() (*Config, error) {
cfg.DevMode = strings.EqualFold(v, "true") || v == "1"
}
if err := rejectStrayDataDir(cfg.DataDir); err != nil {
return nil, err
}
// 确保数据目录存在
if err := os.MkdirAll(cfg.DataDir, 0755); err != nil {
return nil, fmt.Errorf("创建数据目录失败: %w", err)
@@ -102,6 +108,68 @@ func Parse() (*Config, error) {
return cfg, nil
}
// resolveWorkPath 定位后端根目录(app.ini 与 data/ 所在处)。
// 优先级:JIANG13_WORK_PATH > 从 cwd 向上找 app.ini > 源码树 backend/ > cwd。
func resolveWorkPath() (string, error) {
if v := strings.TrimSpace(os.Getenv("JIANG13_WORK_PATH")); v != "" {
abs, err := filepath.Abs(v)
if err != nil {
return "", fmt.Errorf("解析 JIANG13_WORK_PATH 失败: %w", err)
}
return abs, nil
}
cwd, err := os.Getwd()
if err != nil {
return "", fmt.Errorf("获取工作目录失败: %w", err)
}
dir := cwd
for range 8 {
if hasAppIni(dir) {
return dir, nil
}
nested := filepath.Join(dir, "backend")
if hasAppIni(nested) {
return nested, nil
}
if isSourceBackendRoot(dir) {
return dir, nil
}
if isSourceBackendRoot(nested) {
return nested, nil
}
parent := filepath.Dir(dir)
if parent == dir {
break
}
dir = parent
}
return cwd, nil
}
func hasAppIni(dir string) bool {
_, err := os.Stat(filepath.Join(dir, "app.ini"))
return err == nil
}
func isSourceBackendRoot(dir string) bool {
_, e1 := os.Stat(filepath.Join(dir, "go.mod"))
_, e2 := os.Stat(filepath.Join(dir, "cmd", "jiang13"))
_, e3 := os.Stat(filepath.Join(dir, "app.ini.example"))
return e1 == nil && e2 == nil && e3 == nil
}
// rejectStrayDataDir 拦住把上传写进 cmd/jiang13/data 的错误 cwd。
func rejectStrayDataDir(dataDir string) error {
slash := filepath.ToSlash(dataDir)
if strings.Contains(slash, "/cmd/jiang13/") {
return fmt.Errorf("拒绝使用数据目录 %s:这是在 cmd/jiang13 下启动产生的错误路径。请在 backend/ 执行 go run ./cmd/jiang13,或设置 JIANG13_WORK_PATH 指向 backend 目录", dataDir)
}
return nil
}
func generateSecret(n int) string {
const chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
b := make([]byte, n)