✨ feat(manga,device): 漫画免签名兜底与 phone 注册身份选项

- /manga 设备池签名路线全部失败时自动降级 wkbrowser 免签名路线(materials/skeleton 三段策略收集原图直链,无需设备/签名/解密),响应附 source: wkbrowser
- 新增配置 fanqie.device_identity(默认 pad 保持现状;phone 对齐书源真机注册 payload:host_bit 64 + 补 hardware/device_device/fingerprint 字段)
- README 与 openapi.yaml 同步文档,新增 manga_fallback 解析测试
This commit is contained in:
chenxin committed 2026-10-12 14:53:08 +08:00
1 parent 84bd3238ab
commit 9aec09bb40
7 files changed
+301 -3

No files matched your search

+28 -1
View File
@@ -5,6 +5,7 @@ import (
"encoding/hex"
"encoding/json"
"fanqie/internal/common"
"fanqie/internal/config"
"fmt"
"math/big"
"net"
@@ -186,6 +187,22 @@ func generateIPv6List() []map[string]string {
}
}
// deviceIdentity 注册设备身份:pad(默认,历史行为)/ phone(对齐手机 App 书源注册 payload)
func deviceIdentity() string {
if cfg := config.GetConfig(); cfg != nil && cfg.Fanqie.DeviceIdentity == "phone" {
return "phone"
}
return "pad"
}
// deviceCustomFields 注册身份对应的 custom 字段
func deviceCustomFields() map[string]interface{} {
if deviceIdentity() == "phone" {
return map[string]interface{}{"host_bit": 64, "dragon_device_type": "phone"}
}
return map[string]interface{}{"host_bit": 32, "dragon_device_type": "pad"}
}
// GenerateFullRequestBody 生成完整的请求体数据
func GenerateFullRequestBody() map[string]interface{} {
rawData := map[string]interface{}{
@@ -214,7 +231,7 @@ func GenerateFullRequestBody() map[string]interface{} {
"sim_serial_number": []interface{}{},
"oaid_may_support": false,
"device_platform": "android",
"custom": map[string]interface{}{"host_bit": 32, "dragon_device_type": "pad"},
"custom": deviceCustomFields(),
"pre_installed_channel": "",
"is_system_app": 0,
"sdk_flavor": "china",
@@ -234,6 +251,16 @@ func GenerateFullRequestBody() map[string]interface{} {
}
header["ipv6_list"] = generateIPv6List()
// phone 身份补充真机指纹字段(对齐书源注册 payload,规避 pad 身份的差异化风控)
if deviceIdentity() == "phone" {
rom, _ := header["rom"].(string)
header["hardware"] = "qcom"
header["device_device"] = rom
header["fingerprint"] = fmt.Sprintf("%v/%v/%v:%v/%s/%s:user/release-keys",
header["device_brand"], header["device_model"], header["device_model"],
header["os_version"], rom, rom)
}
for k, v := range genTime {
rawData[k] = v
}