Files
AskaEth 074ffc4ebf
CI / Backend (build / vet / test / cross-compile) (push) Has been cancelled
CI / Frontend (tsc + vite build) (push) Has been cancelled
docs(gateway): gateway 剩余文件注释改中文(逐行 1:1,代码零字节改动)
主人 2026-10-03 拍板「注释一律中文」;gateway 至此整包注释中文化完成(本会话共 3 批:
已推库 16 个文件 + 本批剩余文件)。
校验:机械校验(非注释改动行)= 空;剥注释后代码文本逐行比对全等(不一致文件数 0);
全树 go test ./... 58 包 ok / 0 FAIL;交叉编译绿。
2026-10-03 22:28:25 +08:00

63 lines
2.2 KiB
Go

package gateway
import "reflect"
// 本文件承载「适配器需要主人重新授权」这一可选能力,
// 由 GET /api/v1/admin/channels 浮现(v0.39)。它位于渠道摘要
// 本身之旁 —— 而非其内 —— 因为摘要列表是 admin.go 中较大的
// handler 之一,而拆包辅助函数可复用。
// rescanAware 是渠道适配器在会话需要主人重新授权、而重连
// 无法提供该授权时所暴露的可选能力。
// *weixin_ilink.Adapter 实现了它(RescanRequired):iLink 应答
// errcode=-14 意味着机器人 token 已失效,主人必须扫新的二维码。
// 核心的 adapter.PlatformAdapter 契约被刻意不扩展,因此不需要
// 该能力的适配器不受任何改动。
//
// 只有在适配器确实产出某值时才会报告它 —— 没有该能力的
// 平台保持字段省略,而不是送出一个猜测。
type rescanAware interface {
// RescanRequired 报告是否需要一次新的扫码登录,以及原因
// (不需要时 reason 为 "")。
RescanRequired() (required bool, reason string)
}
// asRescanAware 报告已注册的渠道值是否暴露 rescan 能力。
// 注册时会把适配器包进 cmd/cyrene 的 namedAdapter —— 一个内嵌
// adapter.PlatformAdapter 的未导出结构体 —— 它只提升接口的
// 方法,因此具体适配器多出的能力只能通过拆开被内嵌字段
// 才能抵达。直接的适配器值(测试、单账号注册)
// 按原样接受。
func asRescanAware(v any) (rescanAware, bool) {
if ra, ok := v.(rescanAware); ok {
return ra, true
}
inner, ok := unwrapNamedAdapter(v)
if !ok {
return nil, false
}
ra, ok := inner.(rescanAware)
return ra, ok
}
// unwrapNamedAdapter 返回注册包装器内嵌在其导出 PlatformAdapter
// 字段中的适配器。asKookAdmin 与 asWeixinLoginAdmin 为各自的
// 能力子集做同样的拆包,本可共用此辅助函数。
func unwrapNamedAdapter(v any) (any, bool) {
rv := reflect.ValueOf(v)
if !rv.IsValid() {
return nil, false
}
if rv.Kind() == reflect.Ptr {
rv = rv.Elem()
}
if rv.Kind() != reflect.Struct {
return nil, false
}
f := rv.FieldByName("PlatformAdapter")
if !f.IsValid() || !f.CanInterface() {
return nil, false
}
return f.Interface(), true
}