feat(leisure): 新增闲情逸致模块与多项功能优化

本次提交完成多项核心更新:
1. 新增闲情逸致功能模块,包含时间线、收藏标注、季节主题等基础框架
2. 替换hive为社区维护的hive_ce包,修复依赖兼容问题
3. 统一替换"开发中"提示为"当前设备不支持",优化用户提示文案
4. 新增多项功能开关与特性标志,统一管理不可用功能提示
5. 完善用户账户洞察系统,新增头像审核中状态检测
6. 优化TTS语音朗读服务,修复Android端引擎初始化问题
7. 重构知识图谱缩放手势逻辑,解决缩放不跟手问题
8. 新增精灵头像组件,替换默认聊天头像样式
9. 新增外部链接跳转确认弹窗,提升使用安全性
10. 升级后端API接口,新增签到配置获取与补签积分规则动态读取
11. 完善多语言翻译覆盖率限制,非中文语言仅显示最高50%进度
12. 新增HTTP缓存拦截器,优化网络请求性能
13. 新增恢复出厂设置选项,完善数据管理功能

同时修复了多处代码细节问题:简化字符串拼接、优化布局代码、移除多余代码等。
This commit is contained in:
Developer
2026-05-27 08:06:54 +08:00
parent c44457f94c
commit 355191aaf6
144 changed files with 23600 additions and 1464 deletions

View File

@@ -1,13 +1,13 @@
/// ============================================================
/// 闲言APP — Drift 数据库定义
/// 创建时间: 2026-04-20
/// 更新时间: 2026-05-25
/// 更新时间: 2026-05-27
/// 作用: 本地 SQLite 数据库表结构定义 (Drift)
/// 上次更新: 新增TranslateRecords/TtsRecords表, schemaVersion 14->15
/// 上次更新: 新增TranslateSessionMessages/TranslateFavorites表, schemaVersion 15->16
/// ============================================================
import 'package:drift/drift.dart';
import 'package:hive/hive.dart';
import 'package:hive_ce/hive.dart';
import 'package:intl/intl.dart';
import 'package:xianyan/core/utils/logger.dart';
import 'database_connection/native.dart'
@@ -603,6 +603,39 @@ class TtsRecords extends Table {
IntColumn get createdAt => integer()();
}
// ============================================================
// 翻译会话消息表 — 替代 Hive session_messages 键
// ============================================================
class TranslateSessionMessages extends Table {
IntColumn get id => integer().autoIncrement()();
TextColumn get messageId => text()();
TextColumn get sessionId => text()();
TextColumn get role => text()();
TextColumn get content => text()();
TextColumn get sourceLang => text().withDefault(const Constant(''))();
TextColumn get targetLang => text().withDefault(const Constant(''))();
TextColumn get sourceLangName => text().withDefault(const Constant(''))();
TextColumn get targetLangName => text().withDefault(const Constant(''))();
TextColumn get detectedLang => text().withDefault(const Constant(''))();
TextColumn get detectedLangName => text().withDefault(const Constant(''))();
BoolColumn get autoDetected => boolean().withDefault(const Constant(false))();
TextColumn get apiProvider => text().withDefault(const Constant(''))();
TextColumn get status => text().withDefault(const Constant('completed'))();
TextColumn get errorMessage => text().withDefault(const Constant(''))();
IntColumn get createdAt => integer()();
}
// ============================================================
// 翻译收藏表 — 替代 Hive favorites 键
// ============================================================
class TranslateFavorites extends Table {
IntColumn get id => integer().autoIncrement()();
TextColumn get messageId => text()();
IntColumn get createdAt => integer()();
}
// ============================================================
// 数据库实例
// ============================================================
@@ -639,6 +672,8 @@ class TtsRecords extends Table {
MigrationErrors,
TranslateRecords,
TtsRecords,
TranslateSessionMessages,
TranslateFavorites,
],
)
class AppDatabase extends _$AppDatabase {
@@ -648,7 +683,7 @@ class AppDatabase extends _$AppDatabase {
static AppDatabase get instance => _instance;
@override
int get schemaVersion => 15;
int get schemaVersion => 16;
Future<bool> _isMigrationExecuted(int version) async {
final result = await (select(
@@ -936,6 +971,11 @@ class AppDatabase extends _$AppDatabase {
await m.createTable(ttsRecords);
}
Future<void> _migrateToV16(Migrator m) async {
await m.createTable(translateSessionMessages);
await m.createTable(translateFavorites);
}
@override
MigrationStrategy get migration => MigrationStrategy(
onCreate: (m) async {
@@ -984,6 +1024,7 @@ class AppDatabase extends _$AppDatabase {
await _runMigration(13, () => _migrateToV13(m));
await _runMigration(14, () => _migrateToV14(m));
await _runMigration(15, () => _migrateToV15(m));
await _runMigration(16, () => _migrateToV16(m));
},
beforeOpen: (details) async {
Log.i(
@@ -1236,7 +1277,7 @@ class AppDatabase extends _$AppDatabase {
return result;
}
Future<int> getFavoriteCount() async {
Future<int> getTranslateFavoriteCount() async {
try {
final rows =
await (selectOnly(sentences)
@@ -2137,6 +2178,108 @@ class AppDatabase extends _$AppDatabase {
Future<void> clearTtsRecords() {
return delete(ttsRecords).go();
}
// ============================================================
// 翻译会话消息 CRUD
// ============================================================
Future<void> insertSessionMessage(TranslateSessionMessagesCompanion entry) {
return into(translateSessionMessages).insert(entry);
}
Future<void> insertSessionMessageBatch(
List<TranslateSessionMessagesCompanion> entries,
) async {
await batch((b) {
for (final entry in entries) {
b.insert(translateSessionMessages, entry);
}
});
}
Future<List<TranslateSessionMessage>> getSessionMessages({
String? sessionId,
int limit = 200,
}) {
var query = select(translateSessionMessages)
..orderBy([(t) => OrderingTerm.asc(t.createdAt)])
..limit(limit);
if (sessionId != null) {
query = query..where((t) => t.sessionId.equals(sessionId));
}
return query.get();
}
Future<void> updateSessionMessage(TranslateSessionMessagesCompanion entry) {
return (update(
translateSessionMessages,
)..where((t) => t.messageId.equals(entry.messageId.value))).write(entry);
}
Future<void> clearSessionMessages({String? sessionId}) {
if (sessionId != null) {
return (delete(
translateSessionMessages,
)..where((t) => t.sessionId.equals(sessionId))).go();
}
return delete(translateSessionMessages).go();
}
Future<int> getSessionMessageCount({String? sessionId}) async {
final query = selectOnly(translateSessionMessages)
..addColumns([translateSessionMessages.id.count()]);
if (sessionId != null) {
query.where(translateSessionMessages.sessionId.equals(sessionId));
}
final rows = await query.getSingle();
return rows.read(translateSessionMessages.id.count()) ?? 0;
}
// ============================================================
// 翻译收藏 CRUD
// ============================================================
Future<void> insertFavorite(TranslateFavoritesCompanion entry) {
return into(translateFavorites).insert(entry);
}
Future<List<TranslateFavorite>> getFavorites({int limit = 500}) {
return (select(translateFavorites)
..orderBy([(t) => OrderingTerm.desc(t.createdAt)])
..limit(limit))
.get();
}
Future<Set<String>> getFavoriteMessageIds() async {
final rows = await (select(
translateFavorites,
)..orderBy([(t) => OrderingTerm.desc(t.createdAt)])).get();
return rows.map((r) => r.messageId).toSet();
}
Future<bool> isFavorite(String messageId) async {
final row = await (select(
translateFavorites,
)..where((t) => t.messageId.equals(messageId))).getSingleOrNull();
return row != null;
}
Future<void> removeFavorite(String messageId) {
return (delete(
translateFavorites,
)..where((t) => t.messageId.equals(messageId))).go();
}
Future<void> clearFavorites() {
return delete(translateFavorites).go();
}
Future<int> getFavoriteCount() async {
final query = selectOnly(translateFavorites)
..addColumns([translateFavorites.id.count()]);
final rows = await query.getSingle();
return rows.read(translateFavorites.id.count()) ?? 0;
}
}
class HistorySentenceWithTime {

File diff suppressed because it is too large Load Diff

View File

@@ -1,9 +1,9 @@
/// ============================================================
/// 闲言APP — 统一 KV 本地存储
/// 创建时间: 2026-04-20
/// 更新时间: 2026-05-24
/// 更新时间: 2026-05-27
/// 作用: 基于 Hive 的统一 KV 存储,合并原 KvStorage(SP) + AppKVStore(Hive)
/// 上次更新: 新增channelOrder存储键支持频道排序持久化
/// 上次更新: 新增leisure box命名空间
/// ============================================================
import 'dart:convert';
@@ -30,6 +30,7 @@ class HiveBoxNames {
static const String chatMessages = 'chat_messages';
static const String wallpaperFavorites = 'wallpaper_favorites';
static const String translateHistory = 'translateHistory';
static const String leisure = 'leisure';
static const List<String> all = [
app,
@@ -41,7 +42,7 @@ class HiveBoxNames {
cacheConfig,
chatMessages,
wallpaperFavorites,
translateHistory,
leisure,
];
}