书籍接口与界面

This commit is contained in:
DelLevin-Home
2026-06-24 19:51:35 +08:00
parent e4ed73d604
commit 5b7823cb78
20 changed files with 4552 additions and 361 deletions

View File

@@ -2,6 +2,7 @@ import 'dart:convert';
import 'package:flutter/foundation.dart';
import 'package:http/http.dart' as http;
import 'package:package_info_plus/package_info_plus.dart';
import 'server_config.dart';
/// 更新日志数据模型
class ChangelogItem {
@@ -29,7 +30,7 @@ class ChangelogItem {
/// 版本更新检查服务
class ChangelogService {
static const _apiUrl = 'https://api.mooknote.iletter.top/api/changelog';
static final _apiUrl = '${ServerConfig.apiBase}/changelog';
/// 获取更新日志列表
static Future<List<ChangelogItem>> fetchChangelog() async {
@@ -69,6 +70,7 @@ class ChangelogService {
final rest = s.substring(dot + 1).replaceAll('.', ''); // "19" 或 "188"
return double.tryParse('$major$rest') ?? 0;
}
final aVal = toNum(a);
final bVal = toNum(b);
debugPrint('[Update] compare: "$a"→$aVal vs "$b"→$bVal');

View File

@@ -0,0 +1,16 @@
import 'package:flutter/foundation.dart';
/// 服务端地址配置
class ServerConfig {
ServerConfig._();
static final String baseUrl = kDebugMode
? 'http://192.168.31.48:27047'
: 'http://api.mooknote.iletter.top';
static final String apiBase = '$baseUrl/api';
static final String vipBaseUrl = kDebugMode
? 'http://192.168.31.48:8081'
: 'http://vipapi.mooknote.iletter.top';
}

View File

@@ -3,9 +3,9 @@ import 'dart:convert';
import 'dart:io' show Platform;
import 'dart:math';
import 'package:flutter/material.dart';
import 'package:flutter/foundation.dart';
import 'package:http/http.dart' as http;
import 'user_prefs.dart';
import 'server_config.dart';
/// 匿名用户统计服务(静默运行,对用户不可见)
///
@@ -18,9 +18,7 @@ class UsageStatsService with WidgetsBindingObserver {
final UserPrefs _prefs = UserPrefs();
/// 统计服务器地址debug 走局域网release 走线上
static String serverUrl = kDebugMode
? 'http://192.168.31.48:27047/'
: 'http://api.mooknote.iletter.top/';
static String serverUrl = '${ServerConfig.baseUrl}/';
Timer? _heartbeatTimer;
bool _started = false;

View File

@@ -133,6 +133,49 @@ class UserPrefs {
String get deviceId => prefs.getString('deviceId') ?? '';
Future<bool> setDeviceId(String value) => prefs.setString('deviceId', value);
// ========== 搜索历史 ==========
/// 搜索历史记录
List<String> get searchHistory => prefs.getStringList('searchHistory') ?? [];
Future<bool> setSearchHistory(List<String> value) => prefs.setStringList('searchHistory', value);
/// 添加搜索记录(最多 20 条)
Future<void> addSearchHistory(String keyword) async {
final list = searchHistory;
list.remove(keyword);
list.insert(0, keyword);
if (list.length > 50) { list.removeRange(50, list.length); }
await setSearchHistory(list);
}
/// 删除单条搜索记录
Future<void> removeSearchHistory(String keyword) async {
final list = searchHistory;
list.remove(keyword);
await setSearchHistory(list);
}
/// 清空搜索历史
Future<void> clearSearchHistory() => setSearchHistory([]);
// ========== 增强搜索 ==========
/// 是否开启增强搜索
bool get enhancedSearchEnabled => prefs.getBool('enhancedSearchEnabled') ?? false;
Future<bool> setEnhancedSearchEnabled(bool value) => prefs.setBool('enhancedSearchEnabled', value);
/// 影视增强搜索 Token
String get movieSearchToken => prefs.getString('movieSearchToken') ?? '';
Future<bool> setMovieSearchToken(String value) => prefs.setString('movieSearchToken', value);
/// 书籍增强搜索 Token
String get bookSearchToken => prefs.getString('bookSearchToken') ?? '';
Future<bool> setBookSearchToken(String value) => prefs.setString('bookSearchToken', value);
/// 上次搜索的 Tab: 0=影视, 1=书籍
int get lastSearchTab => prefs.getInt('lastSearchTab') ?? 0;
Future<bool> setLastSearchTab(int value) => prefs.setInt('lastSearchTab', value);
// ========== 版本更新 ==========
/// 已忽略的版本号(不再提示更新)