sync: port tangguo_server upstream changes

Ported 7 commits (3a79d6a..3dcf693) from tangguo_server:
- 版本控制: comment out 2FA in admin.go
- 支付和广告调试: pay/ad refactor across appg/adser/rechargeser/pingctrl
- 对接统计: add bili_sync statistics endpoint
- 代码优化: ginUtil improvements
- 修改es/修改appID/代码调整: cumulative updates

Preserved hgmj-local differences:
- ES table prefix stays 91jd_ (not tangguo_)
- BillPlatformID stays 91短剧 (not 糖果短剧)
- admin googauth label stays @91短剧
- appg.go retains LouFengH5/DataBuriedPoint fields
- rechargeser.go retains reportser event reporting

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-10-08 17:18:41 +08:00
co-authored by Claude Opus 4.7
parent 625e89c15d
commit 97f679d130
18 changed files with 750 additions and 218 deletions
+22 -9
View File
@@ -87,9 +87,9 @@ func ServeJsonWithExtra(c *gin.Context, code stderr.Code, data interface{}, extr
log.Any("Code", code))
}
if !IsNilOrEmpty(data) && code == stderr.Success {
t := reflect.TypeOf(data)
if !(t.Kind() == reflect.Map || t.Kind() == reflect.Struct || t.Kind() == reflect.Slice) {
if kind, ok := isRespDataTypeValid(data); !ok {
log.WarnX(c, "[===TypeError===] Return Data Type error is not struct or slice",
log.Any("kind", kind),
log.Any("path", c.Request.URL.Path))
}
}
@@ -161,10 +161,9 @@ func ServeToJSON(c *gin.Context, code stderr.Code, data interface{}) {
log.Any("Code", code))
}
if !IsNilOrEmpty(data) && code == stderr.Success {
t := reflect.TypeOf(data)
if !(t.Kind() == reflect.Map || t.Kind() == reflect.Struct || t.Kind() == reflect.Slice || t.Kind() == reflect.Ptr) {
if kind, ok := isRespDataTypeValid(data); !ok {
log.WarnX(c, "[===TypeError===] Return Data Type error is not struct or slice",
log.Any("kind", t.Kind()),
log.Any("kind", kind),
log.Any("path", c.Request.URL.Path))
}
}
@@ -227,9 +226,9 @@ func serveJsonLogic(c *gin.Context, code stderr.Code, data interface{}, extra ma
log.Any("Code", code))
}
if !IsNilOrEmpty(data) && code == stderr.Success {
t := reflect.TypeOf(data)
if !(t.Kind() == reflect.Map || t.Kind() == reflect.Struct || t.Kind() == reflect.Slice) {
if kind, ok := isRespDataTypeValid(data); !ok {
log.WarnX(c, "[===TypeError===] Return Data Type error is not struct or slice",
log.Any("kind", kind),
log.Any("path", c.Request.URL.Path))
}
}
@@ -429,6 +428,20 @@ func IsNilOrEmpty(in interface{}) bool {
return in == nil || in == ""
}
// isRespDataTypeValid 返回数据是否为可直接下发的类型(map/结构体/切片),
// 指针先解引用再判断,避免返回 *struct 的接口被误报 TypeError。
func isRespDataTypeValid(data interface{}) (reflect.Kind, bool) {
t := reflect.TypeOf(data)
if t == nil {
return reflect.Invalid, false
}
for t.Kind() == reflect.Ptr {
t = t.Elem()
}
kind := t.Kind()
return kind, kind == reflect.Map || kind == reflect.Struct || kind == reflect.Slice
}
// GetIP 获取真实IP
func GetIP(ctx *gin.Context) string {
relIP, exists := ctx.Get(constant.CtxIP)
@@ -501,9 +514,9 @@ func ServeJsonWithExtraNoEncrypt(c *gin.Context, code stderr.Code, data interfac
log.Any("Code", code))
}
if !IsNilOrEmpty(data) && code == stderr.Success {
t := reflect.TypeOf(data)
if !(t.Kind() == reflect.Map || t.Kind() == reflect.Struct || t.Kind() == reflect.Slice) {
if kind, ok := isRespDataTypeValid(data); !ok {
log.WarnX(c, "[===TypeError===] Return Data Type error is not struct or slice",
log.Any("kind", kind),
log.Any("path", c.Request.URL.Path))
}
}