feat & refactor: 支持app端签名的请求,支持右键操作书架书籍,逻辑大幅重构,更改默认的设备逻辑为自动注册,支持载入某些书籍内置的CSS、支持跳转正文注释等等

This commit is contained in:
naiy committed 2026-08-03 16:17:49 +08:00
1 parent 2f2ee606c0
commit 3586b01dbb
47 files changed
+3594 -243

No files matched your search

+103
View File
@@ -0,0 +1,103 @@
import apiFetch from '../utils/request'
import { signRequest } from '../crypto/sign'
import config from '../config'
import { settings } from '../settings'
export const appBaseUrl = 'https://reading.snssdk.com/reading'
export const redcandleBaseUrl = 'https://api5-sinfonlinec.jxbhmy.com/reading'
export const appUserAgent = 'com.dragon.read'
export function buildAppQuery(extra?: Record<string, string>): URLSearchParams {
const c = config.currentConfig
return new URLSearchParams({
iid: c.install_id,
device_id: c.device_id,
ac: 'wifi',
channel: '43536163a',
aid: '1967',
app_name: 'novelapp',
version_code: '70132',
version_name: '7.0.1.32',
device_platform: 'android',
os: 'android',
ssmix: 'a',
os_version: '10',
device_type: c.device_type || 'P30',
device_brand: c.device_brand || 'realme',
...extra,
})
}
function isUsable(res: any): boolean {
if (!res || res.status !== 200) return false
try {
const j = res.json()
return !j || j.code === undefined || j.code === 0
} catch {
return false
}
}
async function requestApp(path: string, query?: Record<string, string>, headers?: Record<string, string>) {
const url = `${appBaseUrl}${path}?${buildAppQuery(query).toString()}`
const signed = await signRequest(url)
return apiFetch(url, {
method: 'GET',
headers: { ...signed, 'User-Agent': appUserAgent, ...headers },
})
}
async function requestRedcandle(path: string, query?: Record<string, string>, headers?: Record<string, string>) {
const url = `${redcandleBaseUrl}${path}?${buildAppQuery(query).toString()}`
return apiFetch(url, {
method: 'GET',
headers: { 'User-Agent': appUserAgent, ...headers },
})
}
export async function appGet(
path: string,
query?: Record<string, string>,
headers?: Record<string, string>,
): Promise<any> {
if (settings.apiPreference === 'redcandle') {
try {
const res = await requestRedcandle(path, query, headers)
if (isUsable(res)) return res
console.warn(`[fqa:api] 红烛接口数据不全,回落到番茄 APP: ${path}`)
} catch (e) {
console.warn(`[fqa:api] 红烛接口请求失败,回落到番茄 APP: ${path}`, e)
}
}
return requestApp(path, query, headers)
}
export async function appPost(
path: string,
body: string,
query?: Record<string, string>,
headers?: Record<string, string>,
): Promise<any> {
const url = `${appBaseUrl}${path}?${buildAppQuery(query).toString()}`
const signed = await signRequest(url, body)
console.log('---start--- APP POST ', url)
const res = await apiFetch(url, {
method: 'POST',
headers: {
...signed,
'User-Agent': appUserAgent,
'Content-Type': 'application/json; charset=utf-8',
...headers,
},
body,
})
console.log('---complete--- APP POST ', url, res)
return res
}