小程序码落图片库并返回绝对地址
码图原先落在 qrcode 私有目录且返回相对路径,后台无法统一管理、 换部署域名还要改数据。现迁到图片库 manifest/static/qrcode/, 与头像/封面/附件共用同一套 /static 路由,并登记附件表 (scene=qrcode)使后台附件管理可统一查看管理。 库内仍只存相对路径、域名由 absoluteURL 按配置统一拼,与既有 约定一致;按内容 md5 命名,重复生成同一张码不新增文件。 活动码与项目绑定码共用 saveQrcodeImage helper。 另修正 .gitignore 漏掉的仓库根二进制(go build -o 的产物)。
This commit is contained in:
@@ -83,24 +83,49 @@ func AdminEventQrcode(ctx context.Context, req *v1.EventQrcodeReq) (*v1.EventQrc
|
||||
return nil, gerror.Newf("生成小程序码失败:%d %s", we.ErrCode, we.ErrMsg)
|
||||
}
|
||||
|
||||
if err = gfile.Mkdir(QrCodeDir); err != nil {
|
||||
return nil, gerror.Newf("创建码图目录失败: %v", err)
|
||||
}
|
||||
fileName := "event_" + scene + "_" + gtime.Now().Format("YmdHis") + ".png"
|
||||
path := gfile.Join(QrCodeDir, fileName)
|
||||
if err = gfile.PutBytes(path, data); err != nil {
|
||||
return nil, gerror.Newf("写入码图失败: %v", err)
|
||||
// 🔴 落「图片库」而不是 qrcode 私有目录(迭代-2026-10-09):用户要求「小程序码能上传到
|
||||
// 图片库、并返回上传后的地址」。图片库 = manifest/static/(与头像/封面/附件同一套,
|
||||
// 由 /static 路由对外),落进去后台「附件管理」能统一看到/管理这些码图。
|
||||
relPath, absURL, err := saveQrcodeImage(ctx, "event_"+scene+".png", data)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 对外可访问地址(由 cmd.go 的静态路由 /qrcode 提供)
|
||||
codeUrl := "/qrcode/" + fileName
|
||||
// 对外返回**绝对 URL**(浏览器/后台可直接打开或下载)。
|
||||
// 库内仍只存相对路径(/static/...),域名由 absoluteURL 按 settings.site.base_url 统一拼 ——
|
||||
// 与头像/封面保持同一套约定,换域名不用改数据。
|
||||
if _, err = g.Model(consts.TableAnnualEvents).Where("id", event.Id).Data(g.Map{
|
||||
"code_url": codeUrl,
|
||||
"code_url": relPath,
|
||||
"updated_at": gtime.Now(),
|
||||
}).Update(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &v1.EventQrcodeRes{CodeUrl: codeUrl}, nil
|
||||
return &v1.EventQrcodeRes{CodeUrl: absURL}, nil
|
||||
}
|
||||
|
||||
// saveQrcodeImage 把小程序码二进制落进「图片库」并登记附件表。
|
||||
//
|
||||
// 🔴 为什么落图片库而不是 qrcode 私有目录(迭代-2026-10-09):用户要求码图「能上传到图片库、
|
||||
// 返回上传后的地址」。图片库 = manifest/static/(与头像/封面/附件同一套,由 /static 路由对外),
|
||||
// 落进去后台「附件管理」能统一看到并管理这些码图。
|
||||
//
|
||||
//去重:storeStatic 内部按内容 md5 命名 → 同一张码重复生成不会在图片库里堆垃圾
|
||||
// (微信对同一 scene/page 返回的码图是稳定字节,md5 一致即覆盖同一文件)。
|
||||
//
|
||||
// 返回:库内相对路径(/static/...)+ 对外绝对 URL。**库内一律存相对路径**,域名只在
|
||||
// absoluteURL 里出现(与头像/封面同一约定),换部署域名时不用改数据。
|
||||
func saveQrcodeImage(ctx context.Context, fileName string, data []byte) (relPath string, absURL string, err error) {
|
||||
// 兜底目录:/qrcode 静态路由在 cmd.go 注册时要求目录已存在(AddStaticPath 目录不存在会 FATAL)。
|
||||
// 这里继续保证它存在,避免 cmd.go 之外的调用路径(如单测)漏建。
|
||||
if err = gfile.Mkdir(QrCodeDir); err != nil {
|
||||
g.Log().Errorf(ctx, "[qrcode] 创建码图目录失败 dir=%s err=%v", QrCodeDir, err)
|
||||
}
|
||||
relPath, err = storeStatic(ctx, consts.AttachmentSceneQrcode, fileName, data)
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
recordAttachment(ctx, consts.AttachmentSceneQrcode, fileName, relPath, data, "admin", CtxAdminId(ctx))
|
||||
return relPath, absoluteURL(ctx, relPath), nil
|
||||
}
|
||||
|
||||
// isJsonBytes 判断响应是否为 JSON(微信失败时返回 JSON,成功返回 PNG)。
|
||||
|
||||
Reference in New Issue
Block a user