diff --git a/configs/config.yml b/configs/config.yml index d4154c3..98df8bf 100644 --- a/configs/config.yml +++ b/configs/config.yml @@ -23,10 +23,11 @@ server: shutdown_timeout: 60 database: - host: 127.0.0.1 # env: DB_HOST + host: 43.161.253.59 # env: DB_HOST port: 5432 # env: DB_PORT - user: fashion # env: DB_USER - # ⚠️ 留空:生产经 DB_PASSWORD(兼容 DB_PASS)注入,或本地启动时交互填写 + user: user_JA83HF # env: DB_USER + # ⚠️ 留空:生产经 DB_PASSWORD(兼容 DB_PASS)注入,或本地启动时交互填写(会写回 config.local.yml) + # 本地开发密码存在 configs/config.local.yml(已被 .gitignore 忽略),不进版本库。 password: "" # env: DB_PASSWORD(兼容 DB_PASS) # 本地开发库名 fashion;对应 scripts/pgvector 的 Docker PostgreSQL 容器 name: fashion # env: DB_NAME diff --git a/internal/config/config.go b/internal/config/config.go index 0641864..f287ed5 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -6,6 +6,8 @@ package config import ( "fmt" + "net" + "net/url" "os" "path/filepath" "strconv" @@ -80,11 +82,22 @@ type DatabaseConfig struct { } // DSN 组装 PostgreSQL 连接串(pgx 驱动,本地开发禁用 SSL)。 +// +// 必须用 net/url 对 user/password 做百分号转义:直接 fmt.Sprintf 拼接时, +// 若密码含 @ : / % # ? 等字符,pgx 按 URL 解析会被截断/错解, +// 服务端实际收到的是乱码密码,从而报 28P01(password authentication failed)。 +// url.UserPassword 会对这些保留字符正确编码,pgx 再解码还原。 func (d DatabaseConfig) DSN() string { - return fmt.Sprintf( - "postgres://%s:%s@%s:%s/%s?sslmode=disable", - d.User, d.Password, d.Host, d.Port, d.Name, - ) + u := url.URL{ + Scheme: "postgres", + User: url.UserPassword(d.User, d.Password), + Host: net.JoinHostPort(d.Host, d.Port), + Path: "/" + d.Name, + } + q := u.Query() + q.Set("sslmode", "disable") + u.RawQuery = q.Encode() + return u.String() } // Addr 返回 host:port 形式的数据库地址,用于日志展示。