修复支付不跳转
This commit is contained in:
@@ -0,0 +1,81 @@
|
||||
package payment
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
beego "github.com/beego/beego/v2/server/web"
|
||||
)
|
||||
|
||||
// =============================================================
|
||||
// 渠道证书落盘路径解析
|
||||
//
|
||||
// 历史实现把证书存成相对路径(certs/payment/<渠道>/xxx.pem),
|
||||
// 该相对路径在「上传时」与「读取时」分别相对各自的进程工作目录解析。
|
||||
// 一旦服务的工作目录发生变化(例如从 /www/wwwroot/api.yunzer.cn 换到 /app),
|
||||
// 库里记的路径就指向不存在的文件,报 “The system cannot find the file specified”。
|
||||
//
|
||||
// 因此读取时统一做一次解析:
|
||||
// - 落盘:写入 payment_cert_dir(未配置时退回工作目录下的 certs/payment),入库仍存相对路径
|
||||
// (本地开发与线上可能共用同一个库,存绝对路径会互相覆盖对方环境);
|
||||
// - 读取:先按当前工作目录解析,再按配置的 payment_cert_dir 根目录兜底解析。
|
||||
// =============================================================
|
||||
|
||||
// legacyCertPrefix 历史相对路径前缀,用于把 certs/payment/<渠道>/xxx.pem 剥成 <渠道>/xxx.pem
|
||||
const legacyCertPrefix = "certs/payment/"
|
||||
|
||||
// CertBaseDir 渠道证书落盘根目录(各渠道目录的父目录)
|
||||
func CertBaseDir() string {
|
||||
dir, _ := beego.AppConfig.String("payment_cert_dir")
|
||||
dir = strings.TrimSpace(dir)
|
||||
if dir == "" {
|
||||
dir = filepath.Join("certs", "payment")
|
||||
}
|
||||
return dir
|
||||
}
|
||||
|
||||
// CertDir 某渠道的证书目录
|
||||
func CertDir(channel string) string {
|
||||
return filepath.Join(CertBaseDir(), filepath.Base(channel))
|
||||
}
|
||||
|
||||
// ResolveCertPath 把库中可能存的相对路径解析为当前可读的路径。
|
||||
// 依次尝试:绝对路径 -> 相对当前工作目录 -> 相对 payment_cert_dir 根目录(兼容历史相对路径)。
|
||||
// 都读不到时原样返回,让上层的 os.ReadFile 报出原始路径便于排查。
|
||||
func ResolveCertPath(p string) string {
|
||||
p = strings.TrimSpace(p)
|
||||
if p == "" {
|
||||
return ""
|
||||
}
|
||||
if filepath.IsAbs(p) {
|
||||
return p
|
||||
}
|
||||
// 相对当前工作目录(历史行为,能读到就不动)
|
||||
if certPathExists(p) {
|
||||
return p
|
||||
}
|
||||
// 兼容历史相对路径:剥掉 certs/payment 前缀后挂到配置的根目录下
|
||||
if cand := filepath.Join(CertBaseDir(), certRelative(p)); certPathExists(cand) {
|
||||
return cand
|
||||
}
|
||||
// 兜底:按文件名在根目录下找
|
||||
if cand := filepath.Join(CertBaseDir(), filepath.Base(p)); certPathExists(cand) {
|
||||
return cand
|
||||
}
|
||||
return p
|
||||
}
|
||||
|
||||
// certRelative 从历史相对路径中剥掉 certs/payment 前缀
|
||||
func certRelative(p string) string {
|
||||
norm := filepath.ToSlash(filepath.Clean(p))
|
||||
if i := strings.Index(norm, legacyCertPrefix); i >= 0 {
|
||||
norm = norm[i+len(legacyCertPrefix):]
|
||||
}
|
||||
return filepath.FromSlash(norm)
|
||||
}
|
||||
|
||||
func certPathExists(path string) bool {
|
||||
info, err := os.Stat(path)
|
||||
return err == nil && !info.IsDir()
|
||||
}
|
||||
@@ -221,6 +221,10 @@ func LoadChannelConfig(channel string) (*ChannelConfig, error) {
|
||||
}
|
||||
if row.CertJSON != nil && *row.CertJSON != "" {
|
||||
_ = json.Unmarshal([]byte(*row.CertJSON), &cfg.CertPaths)
|
||||
// 历史数据存的是相对路径,这里统一解析为当前可读路径,避免依赖进程工作目录
|
||||
for key, val := range cfg.CertPaths {
|
||||
cfg.CertPaths[key] = ResolveCertPath(val)
|
||||
}
|
||||
}
|
||||
return cfg, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user