diff --git a/app/lib/app.dart b/app/lib/app.dart
index 2f9bd0d..e3dbb81 100644
--- a/app/lib/app.dart
+++ b/app/lib/app.dart
@@ -58,6 +58,8 @@ class NuanjiApp extends StatelessWidget {
// 异步恢复 SyncEngine 持久化队列(fire-and-forget,不阻塞 UI)
syncEngine.restorePendingQueue();
+ // 启动网络监听 — 网络恢复时自动触发 trySync()
+ syncEngine.startAutoSync();
// 认证状态监听:登出时清除 token
// 注意:登录时 token 由 AuthRepository.login() 直接注入 ApiClient
diff --git a/app/lib/data/local/collections/journal_element_collection.g.dart b/app/lib/data/local/collections/journal_element_collection.g.dart
index b03676c..c3532f7 100644
--- a/app/lib/data/local/collections/journal_element_collection.g.dart
+++ b/app/lib/data/local/collections/journal_element_collection.g.dart
@@ -16,7 +16,7 @@ extension GetJournalElementCollectionCollection on Isar {
const JournalElementCollectionSchema = CollectionSchema(
name: r'JournalElementCollection',
- id: 5678901234567001,
+ id: -1002,
properties: {
r'contentJson': PropertySchema(
id: 0,
@@ -96,7 +96,7 @@ const JournalElementCollectionSchema = CollectionSchema(
idName: r'isarId',
indexes: {
r'id': IndexSchema(
- id: 5678901234567002,
+ id: -2002,
name: r'id',
unique: false,
replace: false,
@@ -109,7 +109,7 @@ const JournalElementCollectionSchema = CollectionSchema(
],
),
r'journalId': IndexSchema(
- id: 5678901234567003,
+ id: 3001,
name: r'journalId',
unique: false,
replace: false,
diff --git a/app/lib/data/local/collections/journal_entry_collection.dart b/app/lib/data/local/collections/journal_entry_collection.dart
index e278e47..55a1c20 100644
--- a/app/lib/data/local/collections/journal_entry_collection.dart
+++ b/app/lib/data/local/collections/journal_entry_collection.dart
@@ -46,6 +46,9 @@ class JournalEntryCollection {
/// 关联主题 ID(可选)
String? assignedTopicId;
+ /// 内容摘要(自动从文本元素提取)
+ String? contentExcerpt;
+
/// 版本号(乐观锁)
int version = 1;
diff --git a/app/lib/data/local/collections/journal_entry_collection.g.dart b/app/lib/data/local/collections/journal_entry_collection.g.dart
index d125668..05ed74e 100644
--- a/app/lib/data/local/collections/journal_entry_collection.g.dart
+++ b/app/lib/data/local/collections/journal_entry_collection.g.dart
@@ -16,7 +16,7 @@ extension GetJournalEntryCollectionCollection on Isar {
const JournalEntryCollectionSchema = CollectionSchema(
name: r'JournalEntryCollection',
- id: 5678901234567004,
+ id: -1001,
properties: {
r'assignedTopicId': PropertySchema(
id: 0,
@@ -33,63 +33,68 @@ const JournalEntryCollectionSchema = CollectionSchema(
name: r'classId',
type: IsarType.string,
),
- r'createdAtEpoch': PropertySchema(
+ r'contentExcerpt': PropertySchema(
id: 3,
+ name: r'contentExcerpt',
+ type: IsarType.string,
+ ),
+ r'createdAtEpoch': PropertySchema(
+ id: 4,
name: r'createdAtEpoch',
type: IsarType.long,
),
r'dateEpoch': PropertySchema(
- id: 4,
+ id: 5,
name: r'dateEpoch',
type: IsarType.long,
),
r'id': PropertySchema(
- id: 5,
+ id: 6,
name: r'id',
type: IsarType.string,
),
r'isDeleted': PropertySchema(
- id: 6,
+ id: 7,
name: r'isDeleted',
type: IsarType.bool,
),
r'isPrivate': PropertySchema(
- id: 7,
+ id: 8,
name: r'isPrivate',
type: IsarType.bool,
),
r'mood': PropertySchema(
- id: 8,
+ id: 9,
name: r'mood',
type: IsarType.string,
),
r'sharedToClass': PropertySchema(
- id: 9,
+ id: 10,
name: r'sharedToClass',
type: IsarType.bool,
),
r'tagsJson': PropertySchema(
- id: 10,
+ id: 11,
name: r'tagsJson',
type: IsarType.string,
),
r'title': PropertySchema(
- id: 11,
+ id: 12,
name: r'title',
type: IsarType.string,
),
r'updatedAtEpoch': PropertySchema(
- id: 12,
+ id: 13,
name: r'updatedAtEpoch',
type: IsarType.long,
),
r'version': PropertySchema(
- id: 13,
+ id: 14,
name: r'version',
type: IsarType.long,
),
r'weather': PropertySchema(
- id: 14,
+ id: 15,
name: r'weather',
type: IsarType.string,
)
@@ -101,7 +106,7 @@ const JournalEntryCollectionSchema = CollectionSchema(
idName: r'isarId',
indexes: {
r'id': IndexSchema(
- id: 5678901234567002,
+ id: -2001,
name: r'id',
unique: false,
replace: false,
@@ -141,6 +146,12 @@ int _journalEntryCollectionEstimateSize(
bytesCount += 3 + value.length * 3;
}
}
+ {
+ final value = object.contentExcerpt;
+ if (value != null) {
+ bytesCount += 3 + value.length * 3;
+ }
+ }
bytesCount += 3 + object.id.length * 3;
bytesCount += 3 + object.mood.length * 3;
bytesCount += 3 + object.tagsJson.length * 3;
@@ -158,18 +169,19 @@ void _journalEntryCollectionSerialize(
writer.writeString(offsets[0], object.assignedTopicId);
writer.writeString(offsets[1], object.authorId);
writer.writeString(offsets[2], object.classId);
- writer.writeLong(offsets[3], object.createdAtEpoch);
- writer.writeLong(offsets[4], object.dateEpoch);
- writer.writeString(offsets[5], object.id);
- writer.writeBool(offsets[6], object.isDeleted);
- writer.writeBool(offsets[7], object.isPrivate);
- writer.writeString(offsets[8], object.mood);
- writer.writeBool(offsets[9], object.sharedToClass);
- writer.writeString(offsets[10], object.tagsJson);
- writer.writeString(offsets[11], object.title);
- writer.writeLong(offsets[12], object.updatedAtEpoch);
- writer.writeLong(offsets[13], object.version);
- writer.writeString(offsets[14], object.weather);
+ writer.writeString(offsets[3], object.contentExcerpt);
+ writer.writeLong(offsets[4], object.createdAtEpoch);
+ writer.writeLong(offsets[5], object.dateEpoch);
+ writer.writeString(offsets[6], object.id);
+ writer.writeBool(offsets[7], object.isDeleted);
+ writer.writeBool(offsets[8], object.isPrivate);
+ writer.writeString(offsets[9], object.mood);
+ writer.writeBool(offsets[10], object.sharedToClass);
+ writer.writeString(offsets[11], object.tagsJson);
+ writer.writeString(offsets[12], object.title);
+ writer.writeLong(offsets[13], object.updatedAtEpoch);
+ writer.writeLong(offsets[14], object.version);
+ writer.writeString(offsets[15], object.weather);
}
JournalEntryCollection _journalEntryCollectionDeserialize(
@@ -182,19 +194,20 @@ JournalEntryCollection _journalEntryCollectionDeserialize(
object.assignedTopicId = reader.readStringOrNull(offsets[0]);
object.authorId = reader.readString(offsets[1]);
object.classId = reader.readStringOrNull(offsets[2]);
- object.createdAtEpoch = reader.readLong(offsets[3]);
- object.dateEpoch = reader.readLong(offsets[4]);
- object.id = reader.readString(offsets[5]);
- object.isDeleted = reader.readBool(offsets[6]);
- object.isPrivate = reader.readBool(offsets[7]);
+ object.contentExcerpt = reader.readStringOrNull(offsets[3]);
+ object.createdAtEpoch = reader.readLong(offsets[4]);
+ object.dateEpoch = reader.readLong(offsets[5]);
+ object.id = reader.readString(offsets[6]);
+ object.isDeleted = reader.readBool(offsets[7]);
+ object.isPrivate = reader.readBool(offsets[8]);
object.isarId = id;
- object.mood = reader.readString(offsets[8]);
- object.sharedToClass = reader.readBool(offsets[9]);
- object.tagsJson = reader.readString(offsets[10]);
- object.title = reader.readString(offsets[11]);
- object.updatedAtEpoch = reader.readLong(offsets[12]);
- object.version = reader.readLong(offsets[13]);
- object.weather = reader.readString(offsets[14]);
+ object.mood = reader.readString(offsets[9]);
+ object.sharedToClass = reader.readBool(offsets[10]);
+ object.tagsJson = reader.readString(offsets[11]);
+ object.title = reader.readString(offsets[12]);
+ object.updatedAtEpoch = reader.readLong(offsets[13]);
+ object.version = reader.readLong(offsets[14]);
+ object.weather = reader.readString(offsets[15]);
return object;
}
@@ -212,28 +225,30 @@ P _journalEntryCollectionDeserializeProp
(
case 2:
return (reader.readStringOrNull(offset)) as P;
case 3:
- return (reader.readLong(offset)) as P;
+ return (reader.readStringOrNull(offset)) as P;
case 4:
return (reader.readLong(offset)) as P;
case 5:
- return (reader.readString(offset)) as P;
+ return (reader.readLong(offset)) as P;
case 6:
- return (reader.readBool(offset)) as P;
+ return (reader.readString(offset)) as P;
case 7:
return (reader.readBool(offset)) as P;
case 8:
- return (reader.readString(offset)) as P;
- case 9:
return (reader.readBool(offset)) as P;
- case 10:
+ case 9:
return (reader.readString(offset)) as P;
+ case 10:
+ return (reader.readBool(offset)) as P;
case 11:
return (reader.readString(offset)) as P;
case 12:
- return (reader.readLong(offset)) as P;
+ return (reader.readString(offset)) as P;
case 13:
return (reader.readLong(offset)) as P;
case 14:
+ return (reader.readLong(offset)) as P;
+ case 15:
return (reader.readString(offset)) as P;
default:
throw IsarError('Unknown property with id $propertyId');
@@ -832,6 +847,162 @@ extension JournalEntryCollectionQueryFilter on QueryBuilder<
});
}
+ QueryBuilder contentExcerptIsNull() {
+ return QueryBuilder.apply(this, (query) {
+ return query.addFilterCondition(const FilterCondition.isNull(
+ property: r'contentExcerpt',
+ ));
+ });
+ }
+
+ QueryBuilder contentExcerptIsNotNull() {
+ return QueryBuilder.apply(this, (query) {
+ return query.addFilterCondition(const FilterCondition.isNotNull(
+ property: r'contentExcerpt',
+ ));
+ });
+ }
+
+ QueryBuilder contentExcerptEqualTo(
+ String? value, {
+ bool caseSensitive = true,
+ }) {
+ return QueryBuilder.apply(this, (query) {
+ return query.addFilterCondition(FilterCondition.equalTo(
+ property: r'contentExcerpt',
+ value: value,
+ caseSensitive: caseSensitive,
+ ));
+ });
+ }
+
+ QueryBuilder contentExcerptGreaterThan(
+ String? value, {
+ bool include = false,
+ bool caseSensitive = true,
+ }) {
+ return QueryBuilder.apply(this, (query) {
+ return query.addFilterCondition(FilterCondition.greaterThan(
+ include: include,
+ property: r'contentExcerpt',
+ value: value,
+ caseSensitive: caseSensitive,
+ ));
+ });
+ }
+
+ QueryBuilder contentExcerptLessThan(
+ String? value, {
+ bool include = false,
+ bool caseSensitive = true,
+ }) {
+ return QueryBuilder.apply(this, (query) {
+ return query.addFilterCondition(FilterCondition.lessThan(
+ include: include,
+ property: r'contentExcerpt',
+ value: value,
+ caseSensitive: caseSensitive,
+ ));
+ });
+ }
+
+ QueryBuilder contentExcerptBetween(
+ String? lower,
+ String? upper, {
+ bool includeLower = true,
+ bool includeUpper = true,
+ bool caseSensitive = true,
+ }) {
+ return QueryBuilder.apply(this, (query) {
+ return query.addFilterCondition(FilterCondition.between(
+ property: r'contentExcerpt',
+ lower: lower,
+ includeLower: includeLower,
+ upper: upper,
+ includeUpper: includeUpper,
+ caseSensitive: caseSensitive,
+ ));
+ });
+ }
+
+ QueryBuilder contentExcerptStartsWith(
+ String value, {
+ bool caseSensitive = true,
+ }) {
+ return QueryBuilder.apply(this, (query) {
+ return query.addFilterCondition(FilterCondition.startsWith(
+ property: r'contentExcerpt',
+ value: value,
+ caseSensitive: caseSensitive,
+ ));
+ });
+ }
+
+ QueryBuilder contentExcerptEndsWith(
+ String value, {
+ bool caseSensitive = true,
+ }) {
+ return QueryBuilder.apply(this, (query) {
+ return query.addFilterCondition(FilterCondition.endsWith(
+ property: r'contentExcerpt',
+ value: value,
+ caseSensitive: caseSensitive,
+ ));
+ });
+ }
+
+ QueryBuilder
+ contentExcerptContains(String value, {bool caseSensitive = true}) {
+ return QueryBuilder.apply(this, (query) {
+ return query.addFilterCondition(FilterCondition.contains(
+ property: r'contentExcerpt',
+ value: value,
+ caseSensitive: caseSensitive,
+ ));
+ });
+ }
+
+ QueryBuilder
+ contentExcerptMatches(String pattern, {bool caseSensitive = true}) {
+ return QueryBuilder.apply(this, (query) {
+ return query.addFilterCondition(FilterCondition.matches(
+ property: r'contentExcerpt',
+ wildcard: pattern,
+ caseSensitive: caseSensitive,
+ ));
+ });
+ }
+
+ QueryBuilder contentExcerptIsEmpty() {
+ return QueryBuilder.apply(this, (query) {
+ return query.addFilterCondition(FilterCondition.equalTo(
+ property: r'contentExcerpt',
+ value: '',
+ ));
+ });
+ }
+
+ QueryBuilder contentExcerptIsNotEmpty() {
+ return QueryBuilder.apply(this, (query) {
+ return query.addFilterCondition(FilterCondition.greaterThan(
+ property: r'contentExcerpt',
+ value: '',
+ ));
+ });
+ }
+
QueryBuilder createdAtEpochEqualTo(int value) {
return QueryBuilder.apply(this, (query) {
@@ -1883,6 +2054,20 @@ extension JournalEntryCollectionQuerySortBy
});
}
+ QueryBuilder
+ sortByContentExcerpt() {
+ return QueryBuilder.apply(this, (query) {
+ return query.addSortBy(r'contentExcerpt', Sort.asc);
+ });
+ }
+
+ QueryBuilder
+ sortByContentExcerptDesc() {
+ return QueryBuilder.apply(this, (query) {
+ return query.addSortBy(r'contentExcerpt', Sort.desc);
+ });
+ }
+
QueryBuilder
sortByCreatedAtEpoch() {
return QueryBuilder.apply(this, (query) {
@@ -2096,6 +2281,20 @@ extension JournalEntryCollectionQuerySortThenBy on QueryBuilder<
});
}
+ QueryBuilder
+ thenByContentExcerpt() {
+ return QueryBuilder.apply(this, (query) {
+ return query.addSortBy(r'contentExcerpt', Sort.asc);
+ });
+ }
+
+ QueryBuilder
+ thenByContentExcerptDesc() {
+ return QueryBuilder.apply(this, (query) {
+ return query.addSortBy(r'contentExcerpt', Sort.desc);
+ });
+ }
+
QueryBuilder
thenByCreatedAtEpoch() {
return QueryBuilder.apply(this, (query) {
@@ -2303,6 +2502,14 @@ extension JournalEntryCollectionQueryWhereDistinct
});
}
+ QueryBuilder
+ distinctByContentExcerpt({bool caseSensitive = true}) {
+ return QueryBuilder.apply(this, (query) {
+ return query.addDistinctBy(r'contentExcerpt',
+ caseSensitive: caseSensitive);
+ });
+ }
+
QueryBuilder
distinctByCreatedAtEpoch() {
return QueryBuilder.apply(this, (query) {
@@ -2417,6 +2624,13 @@ extension JournalEntryCollectionQueryProperty on QueryBuilder<
});
}
+ QueryBuilder
+ contentExcerptProperty() {
+ return QueryBuilder.apply(this, (query) {
+ return query.addPropertyName(r'contentExcerpt');
+ });
+ }
+
QueryBuilder
createdAtEpochProperty() {
return QueryBuilder.apply(this, (query) {
diff --git a/app/lib/data/local/collections/pending_operation_collection.g.dart b/app/lib/data/local/collections/pending_operation_collection.g.dart
index bc1f096..18e57b2 100644
--- a/app/lib/data/local/collections/pending_operation_collection.g.dart
+++ b/app/lib/data/local/collections/pending_operation_collection.g.dart
@@ -16,7 +16,7 @@ extension GetPendingOperationCollectionCollection on Isar {
const PendingOperationCollectionSchema = CollectionSchema(
name: r'PendingOperationCollection',
- id: 5678901234567005,
+ id: -1003,
properties: {
r'createdAtEpoch': PropertySchema(
id: 0,
@@ -61,7 +61,7 @@ const PendingOperationCollectionSchema = CollectionSchema(
idName: r'isarId',
indexes: {
r'id': IndexSchema(
- id: 5678901234567002,
+ id: -2003,
name: r'id',
unique: false,
replace: false,
diff --git a/app/lib/data/models/journal_entry.dart b/app/lib/data/models/journal_entry.dart
index 27899d8..54aea8d 100644
--- a/app/lib/data/models/journal_entry.dart
+++ b/app/lib/data/models/journal_entry.dart
@@ -42,6 +42,10 @@ class JournalEntry {
final bool isPrivate;
final bool sharedToClass;
final String? assignedTopicId;
+
+ /// 内容摘要 — 自动从文本元素提取,用于列表预览
+ final String? contentExcerpt;
+
final int version;
final DateTime createdAt;
final DateTime updatedAt;
@@ -58,6 +62,7 @@ class JournalEntry {
this.isPrivate = true,
this.sharedToClass = false,
this.assignedTopicId,
+ this.contentExcerpt,
this.version = 1,
required this.createdAt,
required this.updatedAt,
@@ -77,6 +82,8 @@ class JournalEntry {
bool? sharedToClass,
String? assignedTopicId,
bool clearAssignedTopicId = false,
+ String? contentExcerpt,
+ bool clearContentExcerpt = false,
int? version,
DateTime? createdAt,
DateTime? updatedAt,
@@ -94,6 +101,9 @@ class JournalEntry {
sharedToClass: sharedToClass ?? this.sharedToClass,
assignedTopicId:
clearAssignedTopicId ? null : (assignedTopicId ?? this.assignedTopicId),
+ contentExcerpt: clearContentExcerpt
+ ? null
+ : (contentExcerpt ?? this.contentExcerpt),
version: version ?? this.version,
createdAt: createdAt ?? this.createdAt,
updatedAt: updatedAt ?? this.updatedAt,
@@ -111,6 +121,7 @@ class JournalEntry {
'is_private': isPrivate,
'shared_to_class': sharedToClass,
'assigned_topic_id': assignedTopicId,
+ 'content_excerpt': contentExcerpt,
'version': version,
'created_at': createdAt.toIso8601String(),
'updated_at': updatedAt.toIso8601String(),
@@ -134,6 +145,7 @@ class JournalEntry {
isPrivate: (json['is_private'] as bool?) ?? true,
sharedToClass: (json['shared_to_class'] as bool?) ?? false,
assignedTopicId: json['assigned_topic_id'] as String?,
+ contentExcerpt: json['content_excerpt'] as String?,
version: (json['version'] as int?) ?? 1,
createdAt: DateTime.parse(json['created_at'] as String),
updatedAt: DateTime.parse(json['updated_at'] as String),
diff --git a/app/lib/data/services/sse_notification_service.dart b/app/lib/data/services/sse_notification_service.dart
index d01bbc8..315bf2b 100644
--- a/app/lib/data/services/sse_notification_service.dart
+++ b/app/lib/data/services/sse_notification_service.dart
@@ -39,7 +39,7 @@ class SseNotificationService {
SseNotificationService({
required String token,
- String baseUrl = 'http://localhost:3000/api/v1',
+ required String baseUrl,
}) : _token = token,
_baseUrl = baseUrl;
diff --git a/app/lib/data/services/sync_engine.dart b/app/lib/data/services/sync_engine.dart
index 0afbce8..b77bebc 100644
--- a/app/lib/data/services/sync_engine.dart
+++ b/app/lib/data/services/sync_engine.dart
@@ -12,10 +12,12 @@
// - 联网后自动推送待同步操作
// - 版本冲突时本地版本覆盖远端(简单策略)
+import 'dart:async';
import 'dart:convert';
import 'dart:collection';
import 'package:connectivity_plus/connectivity_plus.dart';
+import 'package:flutter/foundation.dart';
import 'package:isar/isar.dart';
import '../local/isar_database.dart';
@@ -114,6 +116,7 @@ class PendingOperation {
class SyncEngine {
final ApiClient _apiClient;
final Queue _pendingQueue = Queue();
+ StreamSubscription>? _connectivitySub;
SyncStatus _status = SyncStatus.idle;
String? _lastError;
@@ -289,6 +292,26 @@ class SyncEngine {
}
}
+ /// 启动网络监听 — 网络恢复时自动触发同步
+ ///
+ /// 在 app.dart 中创建 SyncEngine 后调用一次。
+ /// 调用 [dispose] 停止监听。
+ void startAutoSync() {
+ _connectivitySub = Connectivity().onConnectivityChanged.listen((result) {
+ final isOnline = result.any((r) => r != ConnectivityResult.none);
+ if (isOnline && _pendingQueue.isNotEmpty && _status != SyncStatus.syncing) {
+ debugPrint('SyncEngine: 网络恢复,开始同步 ${_pendingQueue.length} 个操作');
+ trySync();
+ }
+ });
+ }
+
+ /// 停止网络监听并清理资源
+ void dispose() {
+ _connectivitySub?.cancel();
+ _connectivitySub = null;
+ }
+
// ============================================================
// 转换函数
// ============================================================
diff --git a/app/lib/features/auth/views/login_page.dart b/app/lib/features/auth/views/login_page.dart
index 01b5273..7152602 100644
--- a/app/lib/features/auth/views/login_page.dart
+++ b/app/lib/features/auth/views/login_page.dart
@@ -11,6 +11,7 @@ import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:go_router/go_router.dart';
import '../../../core/constants/design_tokens.dart';
+import '../../../core/theme/app_colors.dart';
import '../../../core/theme/app_radius.dart';
import '../bloc/auth_bloc.dart';
@@ -30,6 +31,7 @@ class _LoginPageState extends State with SingleTickerProviderStateMix
bool _isRegister = false;
bool _obscurePassword = true;
+ bool _agreedToTerms = false;
late final AnimationController _animController;
late final Animation _fadeAnim;
@@ -60,6 +62,13 @@ class _LoginPageState extends State with SingleTickerProviderStateMix
void _submit() {
if (!_formKey.currentState!.validate()) return;
+ if (_isRegister && !_agreedToTerms) {
+ ScaffoldMessenger.of(context).showSnackBar(
+ const SnackBar(content: Text('请先阅读并同意用户协议和隐私政策')),
+ );
+ return;
+ }
+
if (_isRegister) {
context.read().add(RegisterRequested(
username: _usernameController.text.trim(),
@@ -106,13 +115,20 @@ class _LoginPageState extends State with SingleTickerProviderStateMix
mainAxisAlignment: MainAxisAlignment.center,
children: [
_buildHeader(context, colorScheme),
- const SizedBox(height: DesignTokens.spacing48),
+ const SizedBox(height: DesignTokens.spacing32),
_buildForm(context, theme, colorScheme),
const SizedBox(height: DesignTokens.spacing24),
_buildSubmitButton(context, colorScheme),
const SizedBox(height: DesignTokens.spacing16),
_buildModeToggle(context, colorScheme),
- const SizedBox(height: DesignTokens.spacing32),
+ const SizedBox(height: DesignTokens.spacing24),
+
+ // 协议复选框(注册模式下显示)
+ if (_isRegister) ...[
+ _buildAgreementRow(context, colorScheme),
+ const SizedBox(height: DesignTokens.spacing16),
+ ],
+
BlocBuilder(
builder: (context, state) {
if (state is AuthError) {
@@ -121,6 +137,13 @@ class _LoginPageState extends State with SingleTickerProviderStateMix
return const SizedBox.shrink();
},
),
+
+ // 社交登录分割线
+ const SizedBox(height: DesignTokens.spacing24),
+ _buildSocialLoginDivider(context, colorScheme),
+ const SizedBox(height: DesignTokens.spacing16),
+ _buildSocialLoginButtons(context, colorScheme),
+ const SizedBox(height: DesignTokens.spacing32),
],
),
),
@@ -132,37 +155,83 @@ class _LoginPageState extends State with SingleTickerProviderStateMix
}
Widget _buildHeader(BuildContext context, ColorScheme colorScheme) {
- return Column(
- children: [
- Container(
- width: 80,
- height: 80,
- decoration: BoxDecoration(
- color: colorScheme.primaryContainer,
- borderRadius: AppRadius.lgBorder,
- ),
- child: Icon(
- Icons.edit_note_rounded,
- size: 44,
- color: colorScheme.primary,
- ),
+ final isDark = Theme.of(context).brightness == Brightness.dark;
+ final bgColor = isDark ? const Color(0xFF1A1614) : const Color(0xFFFFF8F0);
+ final tertiarySoft = isDark ? AppColors.tertiarySoftDark : AppColors.tertiarySoftLight;
+
+ return Container(
+ width: double.infinity,
+ padding: const EdgeInsets.symmetric(vertical: 40),
+ decoration: BoxDecoration(
+ gradient: LinearGradient(
+ begin: Alignment.topCenter,
+ end: Alignment.bottomCenter,
+ colors: [bgColor, tertiarySoft],
),
- const SizedBox(height: DesignTokens.spacing16),
- Text(
- '暖记',
- style: Theme.of(context).textTheme.headlineLarge?.copyWith(
- fontWeight: FontWeight.bold,
- color: colorScheme.primary,
+ ),
+ child: Stack(
+ clipBehavior: Clip.none,
+ children: [
+ // 装饰圆圈
+ Positioned(left: 20, top: -10, child: _decorCircle(60, AppColors.accent, 0.15)),
+ Positioned(right: 30, top: 20, child: _decorCircle(40, AppColors.secondary, 0.12)),
+ Positioned(left: 80, bottom: -20, child: _decorCircle(30, AppColors.tertiary, 0.18)),
+ Positioned(right: 60, bottom: 10, child: _decorCircle(20, AppColors.accent, 0.10)),
+ Positioned(left: -10, top: 50, child: _decorCircle(25, AppColors.secondary, 0.13)),
+
+ Column(
+ children: [
+ // Logo — 自定义笔记本图标
+ Container(
+ width: 80,
+ height: 80,
+ decoration: BoxDecoration(
+ border: Border.all(color: AppColors.accent, width: 3),
+ borderRadius: AppRadius.lgBorder,
+ color: colorScheme.surface.withValues(alpha: 0.5),
+ ),
+ child: const Icon(
+ Icons.edit_note_rounded,
+ size: 44,
+ color: AppColors.accent,
+ ),
),
- ),
- const SizedBox(height: DesignTokens.spacing4),
- Text(
- '记录温暖,书写成长',
- style: Theme.of(context).textTheme.bodyMedium?.copyWith(
- color: colorScheme.onSurface.withValues(alpha: 0.6),
+ const SizedBox(height: DesignTokens.spacing16),
+ // 品牌名
+ Text(
+ '暖记',
+ style: Theme.of(context).textTheme.headlineLarge?.copyWith(
+ fontWeight: FontWeight.w700,
+ color: AppColors.accent,
+ ),
),
- ),
- ],
+ const SizedBox(height: DesignTokens.spacing4),
+ // 标语 — Caveat 手写风格
+ Text(
+ '记录温暖,书写成长',
+ style: const TextStyle(
+ fontSize: 18,
+ fontWeight: FontWeight.w500,
+ color: AppColors.accent,
+ fontFamily: 'Caveat',
+ ),
+ ),
+ ],
+ ),
+ ],
+ ),
+ );
+ }
+
+ /// 装饰圆圈
+ Widget _decorCircle(double size, Color color, double opacity) {
+ return Container(
+ width: size,
+ height: size,
+ decoration: BoxDecoration(
+ color: color.withValues(alpha: opacity),
+ shape: BoxShape.circle,
+ ),
);
}
@@ -319,4 +388,160 @@ class _LoginPageState extends State with SingleTickerProviderStateMix
),
);
}
+
+ /// 社交登录分割线
+ Widget _buildSocialLoginDivider(BuildContext context, ColorScheme colorScheme) {
+ final dividerColor = colorScheme.onSurface.withValues(alpha: 0.15);
+ return Row(
+ children: [
+ Expanded(child: Divider(color: dividerColor)),
+ Padding(
+ padding: const EdgeInsets.symmetric(horizontal: 16),
+ child: Text('其他登录方式', style: Theme.of(context).textTheme.bodySmall?.copyWith(
+ color: colorScheme.onSurface.withValues(alpha: 0.4),
+ )),
+ ),
+ Expanded(child: Divider(color: dividerColor)),
+ ],
+ );
+ }
+
+ /// 社交登录按钮行
+ Widget _buildSocialLoginButtons(BuildContext context, ColorScheme colorScheme) {
+ return Row(
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: [
+ // 微信
+ _SocialButton(
+ bgColor: const Color(0xFF07C160),
+ icon: Icons.chat_bubble,
+ semanticLabel: '微信登录',
+ onTap: () {
+ ScaffoldMessenger.of(context).showSnackBar(
+ const SnackBar(content: Text('微信登录即将支持')),
+ );
+ },
+ ),
+ const SizedBox(width: 24),
+ // Apple
+ _SocialButton(
+ bgColor: const Color(0xFF1D1D1F),
+ icon: Icons.apple,
+ semanticLabel: 'Apple 登录',
+ onTap: () {
+ ScaffoldMessenger.of(context).showSnackBar(
+ const SnackBar(content: Text('Apple 登录即将支持')),
+ );
+ },
+ ),
+ const SizedBox(width: 24),
+ // Google
+ _SocialButton(
+ bgColor: colorScheme.surface,
+ borderColor: colorScheme.outlineVariant,
+ child: const Text('G', style: TextStyle(
+ fontSize: 24, fontWeight: FontWeight.w700, color: Color(0xFF4285F4),
+ )),
+ semanticLabel: 'Google 登录',
+ onTap: () {
+ ScaffoldMessenger.of(context).showSnackBar(
+ const SnackBar(content: Text('Google 登录即将支持')),
+ );
+ },
+ ),
+ ],
+ );
+ }
+
+ /// 协议复选框行
+ Widget _buildAgreementRow(BuildContext context, ColorScheme colorScheme) {
+ return Row(
+ children: [
+ SizedBox(
+ width: 24,
+ height: 24,
+ child: Checkbox(
+ value: _agreedToTerms,
+ onChanged: (v) => setState(() => _agreedToTerms = v ?? false),
+ activeColor: AppColors.accent,
+ materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
+ ),
+ ),
+ const SizedBox(width: 8),
+ Expanded(
+ child: Wrap(
+ children: [
+ Text('我已阅读并同意', style: Theme.of(context).textTheme.bodySmall?.copyWith(
+ color: colorScheme.onSurface.withValues(alpha: 0.6),
+ )),
+ GestureDetector(
+ onTap: () {
+ // TODO: 打开用户协议
+ },
+ child: Text('《用户协议》', style: Theme.of(context).textTheme.bodySmall?.copyWith(
+ color: AppColors.accent, fontWeight: FontWeight.w500,
+ )),
+ ),
+ Text('和', style: Theme.of(context).textTheme.bodySmall?.copyWith(
+ color: colorScheme.onSurface.withValues(alpha: 0.6),
+ )),
+ GestureDetector(
+ onTap: () {
+ // TODO: 打开隐私政策
+ },
+ child: Text('《隐私政策》', style: Theme.of(context).textTheme.bodySmall?.copyWith(
+ color: AppColors.accent, fontWeight: FontWeight.w500,
+ )),
+ ),
+ ],
+ ),
+ ),
+ ],
+ );
+ }
+}
+
+/// 社交登录圆形按钮
+class _SocialButton extends StatelessWidget {
+ const _SocialButton({
+ required this.bgColor,
+ required this.semanticLabel,
+ required this.onTap,
+ this.icon,
+ this.child,
+ this.borderColor,
+ });
+ final Color bgColor;
+ final Color? borderColor;
+ final IconData? icon;
+ final Widget? child;
+ final String semanticLabel;
+ final VoidCallback onTap;
+
+ @override
+ Widget build(BuildContext context) {
+ return SizedBox(
+ width: 56,
+ height: 56,
+ child: Material(
+ color: bgColor,
+ shape: RoundedRectangleBorder(
+ borderRadius: BorderRadius.circular(28),
+ side: borderColor != null
+ ? BorderSide(color: borderColor!, width: 1.5)
+ : BorderSide.none,
+ ),
+ child: InkWell(
+ onTap: onTap,
+ customBorder: RoundedRectangleBorder(
+ borderRadius: BorderRadius.circular(28),
+ ),
+ child: Center(
+ child: child ??
+ Icon(icon, size: 28, color: Colors.white),
+ ),
+ ),
+ ),
+ );
+ }
}
diff --git a/app/lib/features/calendar/views/monthly_page.dart b/app/lib/features/calendar/views/monthly_page.dart
index c98bf72..e3697ab 100644
--- a/app/lib/features/calendar/views/monthly_page.dart
+++ b/app/lib/features/calendar/views/monthly_page.dart
@@ -50,7 +50,8 @@ class _MonthlyPageState extends State {
try {
final elements = await _repo.getElements(journal.id);
photoCount += elements.where((e) => e.elementType == ElementType.image).length;
- } catch (_) {
+ } catch (e) {
+ debugPrint('MonthlyPage: 加载日记 ${journal.id} 元素失败: $e');
// 单个日记加载元素失败不影响整体统计
}
}
diff --git a/app/lib/features/calendar/views/weekly_page.dart b/app/lib/features/calendar/views/weekly_page.dart
index f3d5037..f86920c 100644
--- a/app/lib/features/calendar/views/weekly_page.dart
+++ b/app/lib/features/calendar/views/weekly_page.dart
@@ -56,7 +56,8 @@ class _WeeklyPageState extends State {
_isLoading = false;
});
}
- } catch (_) {
+ } catch (e) {
+ debugPrint('WeeklyPage._loadWeekData 失败: $e');
if (mounted) setState(() => _isLoading = false);
}
}
diff --git a/app/lib/features/class_/bloc/class_bloc.dart b/app/lib/features/class_/bloc/class_bloc.dart
index 868c249..93e89ee 100644
--- a/app/lib/features/class_/bloc/class_bloc.dart
+++ b/app/lib/features/class_/bloc/class_bloc.dart
@@ -1,5 +1,6 @@
// 班级 BLoC — 通过 ClassRepository 管理班级数据
+import 'package:flutter/foundation.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:nuanji_app/data/models/journal_entry.dart';
import 'package:nuanji_app/data/models/school_class.dart';
@@ -117,9 +118,14 @@ final class ClassLoading extends ClassState {
final class ClassListLoaded extends ClassState {
final List classes;
final bool isLoading;
- const ClassListLoaded({this.classes = const [], this.isLoading = false});
- ClassListLoaded copyWith({List? classes, bool? isLoading}) =>
- ClassListLoaded(classes: classes ?? this.classes, isLoading: isLoading ?? this.isLoading);
+ final String? error;
+ const ClassListLoaded({this.classes = const [], this.isLoading = false, this.error});
+ ClassListLoaded copyWith({List? classes, bool? isLoading, String? error, bool clearError = false}) =>
+ ClassListLoaded(
+ classes: classes ?? this.classes,
+ isLoading: isLoading ?? this.isLoading,
+ error: clearError ? null : (error ?? this.error),
+ );
}
final class ClassDetailLoaded extends ClassState {
@@ -209,7 +215,8 @@ class ClassBloc extends Bloc {
final classes = await _classRepo.getMyClasses();
emit(ClassListLoaded(classes: classes));
} catch (e) {
- emit(ClassListLoaded(classes: const []));
+ debugPrint('ClassBloc._onLoadMyClasses 失败: $e');
+ emit(const ClassListLoaded());
}
}
@@ -224,7 +231,8 @@ class ClassBloc extends Bloc {
add(ClassLoadMembers(event.classId));
add(ClassLoadTopics(event.classId));
} catch (e) {
- emit(ClassError('加载班级失败: $e'));
+ debugPrint('ClassBloc._onClassSelected 失败: $e');
+ emit(const ClassError('加载班级失败,请重试'));
}
}
@@ -247,7 +255,8 @@ class ClassBloc extends Bloc {
))
.toList();
emit(current.copyWith(members: members, isLoadingMembers: false));
- } catch (_) {
+ } catch (e) {
+ debugPrint('ClassBloc._onLoadMembers 失败: $e');
emit(current.copyWith(isLoadingMembers: false));
}
}
@@ -266,7 +275,8 @@ class ClassBloc extends Bloc {
final classJournals = journals.where((j) => j.sharedToClass).toList();
emit(current.copyWith(diaryWall: classJournals, isLoadingWall: false));
- } catch (_) {
+ } catch (e) {
+ debugPrint('ClassBloc._onLoadDiaryWall 失败: $e');
emit(current.copyWith(isLoadingWall: false));
}
}
@@ -292,8 +302,9 @@ class ClassBloc extends Bloc {
))
.toList();
emit(current.copyWith(topics: topics));
- } catch (_) {
- // 静默失败,保留空列表
+ } catch (e) {
+ debugPrint('ClassBloc._onLoadTopics 失败: $e');
+ // 保留空列表
}
}
@@ -316,7 +327,8 @@ class ClassBloc extends Bloc {
))
.toList();
emit(current.copyWith(comments: comments, selectedJournalId: event.journalId));
- } catch (_) {
+ } catch (e) {
+ debugPrint('ClassBloc._onLoadComments 失败: $e');
emit(current.copyWith(selectedJournalId: event.journalId));
}
}
@@ -335,7 +347,11 @@ class ClassBloc extends Bloc {
emit(current.copyWith(classes: [...current.classes, newClass]));
}
} catch (e) {
- // 创建失败不改变状态
+ debugPrint('ClassBloc._onCreateClass 失败: $e');
+ // 创建失败不改变状态,但通知 UI
+ if (state is ClassListLoaded) {
+ emit((state as ClassListLoaded).copyWith(error: '创建班级失败,请重试'));
+ }
}
}
@@ -364,8 +380,12 @@ class ClassBloc extends Bloc {
);
emit(current.copyWith(topics: [newTopic, ...current.topics]));
}
- } catch (_) {
- // 静默失败
+ } catch (e) {
+ debugPrint('ClassBloc._onTopicAssign 失败: $e');
+ // 通知 UI 布置失败
+ if (state is ClassDetailLoaded) {
+ emit((state as ClassDetailLoaded).copyWith(error: '话题布置失败,请重试'));
+ }
}
}
@@ -378,7 +398,8 @@ class ClassBloc extends Bloc {
// 加入成功后刷新列表
add(const ClassLoadMyClasses());
} catch (e) {
- emit(ClassError('加入班级失败: $e'));
+ debugPrint('ClassBloc._onJoinClass 失败: $e');
+ emit(const ClassError('加入班级失败,请检查班级码'));
}
}
@@ -397,6 +418,7 @@ class ClassBloc extends Bloc {
// 创建成功后重新加载评语列表
add(ClassLoadComments(event.journalId));
} catch (e) {
+ debugPrint('ClassBloc._onCommentCreate 失败: $e');
emit(currentState.copyWith(error: '评语发布失败'));
}
}
diff --git a/app/lib/features/editor/bloc/editor_bloc.dart b/app/lib/features/editor/bloc/editor_bloc.dart
index 6ef34ee..80877c1 100644
--- a/app/lib/features/editor/bloc/editor_bloc.dart
+++ b/app/lib/features/editor/bloc/editor_bloc.dart
@@ -4,13 +4,16 @@
// - 手写层:笔画列表 + 画笔设置 + 撤销/重做栈
// - 元素层:贴纸/照片/文字元素列表 + 选中元素 + 拖拽状态
// - 工具栏:当前活动工具 + 颜色面板 + 笔刷大小
+// - 标签/心情:日记标签管理 + 心情选择 + 标题编辑
// - 自动保存:笔画/元素变更 debounce → 触发保存回调
import 'dart:async';
+import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import '../widgets/stroke_model.dart';
+import '../../../data/models/journal_entry.dart';
import '../../../data/models/journal_element.dart';
// ============================================================
@@ -110,20 +113,69 @@ class ElementsLoaded extends EditorEvent {
ElementsLoaded(this.elements);
}
+// --- 标签/心情/标题事件 ---
+
+/// 添加标签
+class TagAdded extends EditorEvent {
+ final String tag;
+ TagAdded(this.tag);
+}
+
+/// 移除标签
+class TagRemoved extends EditorEvent {
+ final String tag;
+ TagRemoved(this.tag);
+}
+
+/// 加载已有标签
+class TagsLoaded extends EditorEvent {
+ final List tags;
+ TagsLoaded(this.tags);
+}
+
+/// 心情变更
+class MoodChanged extends EditorEvent {
+ final Mood mood;
+ MoodChanged(this.mood);
+}
+
+/// 标题变更
+class TitleChanged extends EditorEvent {
+ final String title;
+ TitleChanged(this.title);
+}
+
+/// 文字格式变更
+class TextFormatChanged extends EditorEvent {
+ final String elementId;
+ final bool? bold;
+ final bool? italic;
+ final bool? underline;
+ final String? color;
+ final TextAlign? alignment;
+ TextFormatChanged({
+ required this.elementId,
+ this.bold,
+ this.italic,
+ this.underline,
+ this.color,
+ this.alignment,
+ });
+}
+
// ============================================================
// 状态
// ============================================================
-/// 编辑器工具枚举
+/// 编辑器工具枚举 — 对应底部 6 个工具按钮 + 内部 select 模式
enum EditorTool {
- pen, // 钢笔
- pencil, // 铅笔
- marker, // 马克笔
- eraser, // 橡皮擦
- select, // 选择/移动元素
- text, // 文字输入
sticker, // 贴纸
- image, // 照片
+ template, // 模板
+ brush, // 画笔(含钢笔/铅笔/马克笔/橡皮子类型)
+ photo, // 照片
+ text, // 文字
+ more, // 更多
+ select, // 选择/移动元素(内部模式,非 UI 按钮)
}
/// 编辑器状态
@@ -134,6 +186,7 @@ class EditorState {
final BrushType brushType;
final String brushColor;
final double brushWidth;
+ final double brushOpacity;
final int maxUndoSteps;
// 元素层
@@ -143,6 +196,11 @@ class EditorState {
// 工具栏
final EditorTool activeTool;
+ // 标签/心情/标题
+ final List tags;
+ final Mood selectedMood;
+ final String title;
+
// 自动保存
final bool isDirty;
final DateTime? lastSavedAt;
@@ -153,10 +211,14 @@ class EditorState {
this.brushType = BrushType.pen,
this.brushColor = '#2D2420',
this.brushWidth = 3.0,
+ this.brushOpacity = 1.0,
this.maxUndoSteps = 50,
this.elements = const [],
this.selectedElementId,
- this.activeTool = EditorTool.pen,
+ this.activeTool = EditorTool.brush,
+ this.tags = const [],
+ this.selectedMood = Mood.calm,
+ this.title = '',
this.isDirty = false,
this.lastSavedAt,
});
@@ -167,10 +229,14 @@ class EditorState {
BrushType? brushType,
String? brushColor,
double? brushWidth,
+ double? brushOpacity,
List? elements,
String? selectedElementId,
bool clearSelection = false,
EditorTool? activeTool,
+ List? tags,
+ Mood? selectedMood,
+ String? title,
bool? isDirty,
DateTime? lastSavedAt,
}) =>
@@ -180,27 +246,28 @@ class EditorState {
brushType: brushType ?? this.brushType,
brushColor: brushColor ?? this.brushColor,
brushWidth: brushWidth ?? this.brushWidth,
+ brushOpacity: brushOpacity ?? this.brushOpacity,
maxUndoSteps: maxUndoSteps,
elements: elements ?? this.elements,
- selectedElementId: clearSelection ? null : (selectedElementId ?? this.selectedElementId),
+ selectedElementId:
+ clearSelection ? null : (selectedElementId ?? this.selectedElementId),
activeTool: activeTool ?? this.activeTool,
+ tags: tags ?? this.tags,
+ selectedMood: selectedMood ?? this.selectedMood,
+ title: title ?? this.title,
isDirty: isDirty ?? this.isDirty,
lastSavedAt: lastSavedAt ?? this.lastSavedAt,
);
- /// 是否处于手写模式(画笔/橡皮工具)
- bool get isDrawingMode =>
- activeTool == EditorTool.pen ||
- activeTool == EditorTool.pencil ||
- activeTool == EditorTool.marker ||
- activeTool == EditorTool.eraser;
+ /// 是否处于手写模式
+ bool get isDrawingMode => activeTool == EditorTool.brush;
/// 是否处于元素操作模式
bool get isElementMode =>
activeTool == EditorTool.select ||
activeTool == EditorTool.text ||
activeTool == EditorTool.sticker ||
- activeTool == EditorTool.image;
+ activeTool == EditorTool.photo;
}
// ============================================================
@@ -238,6 +305,14 @@ class EditorBloc extends Bloc {
// 工具栏事件
on(_onToolChanged);
+
+ // 标签/心情/标题事件
+ on(_onTagAdded);
+ on(_onTagRemoved);
+ on(_onTagsLoaded);
+ on(_onMoodChanged);
+ on(_onTitleChanged);
+ on(_onTextFormatChanged);
}
@override
@@ -321,7 +396,8 @@ class EditorBloc extends Bloc {
// ============================================================
void _onElementAdded(ElementAdded event, Emitter emit) {
- final updated = List.from(state.elements)..add(event.element);
+ final updated =
+ List.from(state.elements)..add(event.element);
emit(state.copyWith(
elements: updated,
selectedElementId: event.element.id,
@@ -394,6 +470,58 @@ class EditorBloc extends Bloc {
));
}
+ // ============================================================
+ // 标签/心情/标题事件处理
+ // ============================================================
+
+ void _onTagAdded(TagAdded event, Emitter emit) {
+ if (state.tags.contains(event.tag)) return;
+ if (state.tags.length >= 10) return; // 设计 Token: maxTags=10
+ final updated = List.from(state.tags)..add(event.tag);
+ emit(state.copyWith(tags: updated, isDirty: true));
+ _scheduleAutoSave();
+ }
+
+ void _onTagRemoved(TagRemoved event, Emitter emit) {
+ final updated = List.from(state.tags)..remove(event.tag);
+ emit(state.copyWith(tags: updated, isDirty: true));
+ _scheduleAutoSave();
+ }
+
+ void _onTagsLoaded(TagsLoaded event, Emitter emit) {
+ emit(state.copyWith(tags: event.tags));
+ }
+
+ void _onMoodChanged(MoodChanged event, Emitter emit) {
+ emit(state.copyWith(selectedMood: event.mood, isDirty: true));
+ _scheduleAutoSave();
+ }
+
+ void _onTitleChanged(TitleChanged event, Emitter emit) {
+ emit(state.copyWith(title: event.title, isDirty: true));
+ _scheduleAutoSave();
+ }
+
+ void _onTextFormatChanged(
+ TextFormatChanged event,
+ Emitter emit,
+ ) {
+ final updated = state.elements.map((e) {
+ if (e.id != event.elementId) return e;
+ final content = Map.from(e.content);
+ if (event.bold != null) content['bold'] = event.bold;
+ if (event.italic != null) content['italic'] = event.italic;
+ if (event.underline != null) content['underline'] = event.underline;
+ if (event.color != null) content['color'] = event.color;
+ if (event.alignment != null) {
+ content['alignment'] = event.alignment!.index;
+ }
+ return e.copyWith(content: content);
+ }).toList();
+ emit(state.copyWith(elements: updated, isDirty: true));
+ _scheduleAutoSave();
+ }
+
// ============================================================
// 自动保存
// ============================================================
diff --git a/app/lib/features/editor/views/editor_page.dart b/app/lib/features/editor/views/editor_page.dart
index 4808768..95b3ec8 100644
--- a/app/lib/features/editor/views/editor_page.dart
+++ b/app/lib/features/editor/views/editor_page.dart
@@ -14,10 +14,13 @@ import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:go_router/go_router.dart';
import '../../../core/constants/design_tokens.dart';
+import '../../../core/theme/app_colors.dart';
import '../../../data/models/journal_element.dart';
-import '../../../data/models/journal_entry.dart';
+import '../../../data/models/journal_entry.dart' show JournalEntry, Mood;
import '../../../data/repositories/journal_repository.dart';
import '../../../data/repositories/class_repository.dart';
+import '../../../data/services/sync_engine.dart';
+import '../../auth/bloc/auth_bloc.dart';
import '../bloc/editor_bloc.dart';
import '../widgets/handwriting_canvas.dart';
import '../widgets/stroke_model.dart';
@@ -27,6 +30,9 @@ import '../widgets/text_input_overlay.dart';
import '../widgets/image_picker_handler.dart';
import '../widgets/sticker_picker_sheet.dart';
import '../widgets/share_bottom_sheet.dart';
+import '../widgets/tag_panel.dart';
+import '../widgets/brush_panel.dart';
+import '../widgets/dot_grid_painter.dart';
/// 手账编辑器页面
class EditorPage extends StatelessWidget {
@@ -39,6 +45,8 @@ class EditorPage extends StatelessWidget {
Widget build(BuildContext context) {
// 从 Provider 树获取 JournalRepository(IsarJournalRepository)
final repo = context.read();
+ // 从 Provider 树获取 SyncEngine(同步到后端)
+ final syncEngine = context.read();
// 可变闭包变量:跟踪已保存的日记 ID
// 新建日记首次保存后赋值,后续自动更新使用此 ID
@@ -48,7 +56,18 @@ class EditorPage extends StatelessWidget {
create: (_) => EditorBloc(
onSave: (state) async {
try {
- await _persistState(repo, state, (id) => savedJournalId = id, savedJournalId);
+ // 从 AuthBloc 获取真实用户 ID
+ String authorId = 'local';
+ final authState = context.read().state;
+ if (authState is Authenticated) {
+ authorId = authState.user.id;
+ }
+
+ await _persistState(
+ repo, state, (id) => savedJournalId = id, savedJournalId,
+ syncEngine: syncEngine,
+ authorId: authorId,
+ );
} catch (e) {
debugPrint('自动保存失败: $e');
}
@@ -66,24 +85,27 @@ class EditorPage extends StatelessWidget {
);
}
- /// 持久化编辑器状态到 Isar
+ /// 持久化编辑器状态到 Isar,并同步到后端
///
/// 策略:
/// - 首次保存(savedJournalId == null)→ createJournal + addElement
/// - 后续保存 → updateJournal + upsert 元素
/// - 笔画序列化为 handwriting_ref 元素
+ /// - 保存成功后入队 SyncEngine 等待网络同步
Future _persistState(
JournalRepository repo,
EditorState state,
void Function(String) setId,
- String? savedJournalId,
- ) async {
+ String? savedJournalId, {
+ required SyncEngine syncEngine,
+ String authorId = 'local',
+ }) async {
final now = DateTime.now();
if (savedJournalId == null) {
// --- 新建日记 ---
final entry = JournalEntry.create(
- authorId: 'local', // TODO: 从 AuthBloc 获取真实用户 ID
+ authorId: authorId,
title: '${now.month}月${now.day}日的日记',
date: now,
);
@@ -99,11 +121,31 @@ class EditorPage extends StatelessWidget {
for (final element in state.elements) {
await repo.addElement(element.copyWith(journalId: entry.id));
}
+
+ // 入队 SyncEngine 等待同步到后端
+ syncEngine.enqueue(PendingOperation(
+ id: entry.id,
+ type: SyncOperationType.create,
+ endpoint: '/diary/journals',
+ data: entry.toJson(),
+ version: entry.version,
+ createdAt: now,
+ ));
} else {
// --- 更新已有日记 ---
final existing = await repo.getJournal(savedJournalId);
if (existing != null) {
await repo.updateJournal(existing);
+
+ // 入队 SyncEngine 等待同步到后端
+ syncEngine.enqueue(PendingOperation(
+ id: existing.id,
+ type: SyncOperationType.update,
+ endpoint: '/diary/journals/${existing.id}',
+ data: existing.toJson(),
+ version: existing.version,
+ createdAt: now,
+ ));
}
// 更新笔画
@@ -154,21 +196,28 @@ class EditorPage extends StatelessWidget {
}
/// 显示分享面板并在用户选择后导航
- static void _showShareSheetAndNavigate(
+ static Future _showShareSheetAndNavigate(
BuildContext context,
JournalRepository repo,
String? savedJournalId,
- ) {
+ ) async {
// 尝试获取用户的班级信息
String? userClassId;
String userClassName = '我的班级';
try {
- context.read();
- // Phase 1 简化:不等待异步调用,使用默认值
- userClassId = null; // TODO: 从 AuthBloc/ClassBloc 获取真实班级 ID
- } catch (_) {
- // ClassRepository 不可用(未注入)
+ // 从 AuthBloc 获取用户关联的班级
+ final authState = context.read().state;
+ if (authState is Authenticated) {
+ final classRepo = context.read();
+ final classes = await classRepo.getMyClasses();
+ if (classes.isNotEmpty) {
+ userClassId = classes.first.id;
+ userClassName = classes.first.name;
+ }
+ }
+ } catch (e) {
+ debugPrint('获取班级信息失败: $e');
}
showModalBottomSheet(
@@ -226,94 +275,251 @@ class _EditorView extends StatelessWidget {
return Scaffold(
backgroundColor: colorScheme.surface,
- body: SafeArea(
- child: Column(
- children: [
- // 顶栏
- _buildTopBar(context),
+ body: Column(
+ children: [
+ // 顶栏(自带状态栏安全区)
+ BlocBuilder(
+ builder: (context, state) {
+ return _buildTopBar(context, state);
+ },
+ ),
- // 编辑区域(三层 Stack)
- Expanded(
- child: BlocBuilder(
- builder: (context, state) {
- return _EditorStack(state: state, journalId: journalId);
- },
- ),
- ),
-
- // 底部工具栏
- BlocBuilder(
+ // 编辑区域(三层 Stack)
+ Expanded(
+ child: BlocBuilder(
builder: (context, state) {
- return EditorToolbar(
- state: state,
- onEvent: (event) => context.read().add(event),
- );
+ return _EditorStack(state: state, journalId: journalId);
},
),
- ],
- ),
+ ),
+
+ // 底部工具栏(自带底部安全区)
+ BlocBuilder(
+ builder: (context, state) {
+ return EditorToolbar(
+ state: state,
+ onEvent: (event) => context.read().add(event),
+ );
+ },
+ ),
+ ],
),
);
}
- /// 顶部操作栏 — 返回/日记标题/完成
- Widget _buildTopBar(BuildContext context) {
+ /// 顶部操作栏 — 日期/撤销重做/标签/心情/完成
+ Widget _buildTopBar(BuildContext context, EditorState state) {
final colorScheme = Theme.of(context).colorScheme;
-
return Container(
- height: 52,
- padding: const EdgeInsets.symmetric(horizontal: DesignTokens.spacing8),
+ padding: EdgeInsets.only(top: MediaQuery.of(context).padding.top),
decoration: BoxDecoration(
color: colorScheme.surface,
border: Border(
- bottom: BorderSide(color: colorScheme.outline.withValues(alpha: 0.1)),
+ bottom: BorderSide(
+ color: colorScheme.outlineVariant.withValues(alpha: 0.3),
+ ),
),
),
- child: Row(
+ child: Column(
children: [
- // 返回按钮
- IconButton(
- onPressed: () {
- if (context.canPop()) {
- context.pop();
- } else {
- context.go('/home');
- }
- },
- icon: const Icon(Icons.arrow_back_rounded),
- tooltip: '返回',
- ),
-
- const SizedBox(width: DesignTokens.spacing8),
-
- // 日记标题
- Expanded(
- child: Text(
- journalId != null
- ? '编辑日记'
- : templateId != null
- ? '从模板新建'
- : '新建日记',
- style: Theme.of(context).textTheme.titleMedium?.copyWith(
- fontWeight: FontWeight.w600,
+ // 主顶栏行 (44px)
+ SizedBox(
+ height: 44,
+ child: Padding(
+ padding: const EdgeInsets.symmetric(horizontal: 8),
+ child: Row(
+ children: [
+ // 返回按钮
+ IconButton(
+ icon: const Icon(Icons.arrow_back_rounded),
+ onPressed: () => _handleBack(context),
+ constraints: const BoxConstraints(minWidth: 36, minHeight: 36),
+ iconSize: 22,
),
+ // 日期显示
+ Expanded(
+ child: Center(
+ child: Text(
+ _formatDate(state),
+ style: TextStyle(
+ fontFamily: 'Quicksand',
+ fontSize: 15,
+ fontWeight: FontWeight.w600,
+ color: colorScheme.onSurface,
+ ),
+ ),
+ ),
+ ),
+ // 撤销
+ IconButton(
+ icon: const Icon(Icons.undo_rounded, size: 18),
+ onPressed: () => context.read().add(Undo()),
+ constraints: const BoxConstraints(minWidth: 36, minHeight: 36),
+ ),
+ // 重做
+ IconButton(
+ icon: const Icon(Icons.redo_rounded, size: 18),
+ onPressed: () => context.read().add(Redo()),
+ constraints: const BoxConstraints(minWidth: 36, minHeight: 36),
+ ),
+ // 自动保存状态
+ _buildAutosaveIndicator(state),
+ // 标签按钮
+ IconButton(
+ icon: const Icon(Icons.sell_rounded, size: 18),
+ onPressed: () => _showTagPanel(context, state),
+ constraints: const BoxConstraints(minWidth: 36, minHeight: 36),
+ ),
+ // 完成/保存按钮
+ Padding(
+ padding: const EdgeInsets.only(left: 4),
+ child: FilledButton.tonal(
+ onPressed: () => _handleSave(context, state),
+ style: FilledButton.styleFrom(
+ padding: const EdgeInsets.symmetric(horizontal: 16),
+ minimumSize: const Size(0, 32),
+ ),
+ child: const Text('完成', style: TextStyle(fontSize: 14)),
+ ),
+ ),
+ ],
+ ),
),
),
+ // 日期 + 心情条 (40px)
+ _buildDateMoodStrip(context, state),
+ ],
+ ),
+ );
+ }
- // 完成按钮
- FilledButton.tonal(
- onPressed: onSaveComplete,
- style: FilledButton.styleFrom(
- padding: const EdgeInsets.symmetric(horizontal: DesignTokens.spacing16),
- minimumSize: const Size(0, 36),
- shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
+ /// 返回处理
+ void _handleBack(BuildContext context) {
+ if (context.canPop()) {
+ context.pop();
+ } else {
+ context.go('/home');
+ }
+ }
+
+ /// 保存处理
+ void _handleSave(BuildContext context, EditorState state) {
+ onSaveComplete();
+ }
+
+ /// 格式化日期显示
+ String _formatDate(EditorState state) {
+ final now = DateTime.now();
+ const weekdays = ['周一', '周二', '周三', '周四', '周五', '周六', '周日'];
+ return '${now.month}月${now.day}日 · ${weekdays[now.weekday - 1]}';
+ }
+
+ /// 自动保存状态指示器
+ Widget _buildAutosaveIndicator(EditorState state) {
+ if (state.lastSavedAt == null) {
+ return Padding(
+ padding: const EdgeInsets.symmetric(horizontal: 4),
+ child: Text(
+ '未保存',
+ style: TextStyle(fontSize: 11, color: Colors.grey[400]),
+ ),
+ );
+ }
+ return Padding(
+ padding: const EdgeInsets.symmetric(horizontal: 4),
+ child: Row(
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ Container(
+ width: 6,
+ height: 6,
+ decoration: const BoxDecoration(
+ color: AppColors.success,
+ shape: BoxShape.circle,
),
- child: const Text('完成'),
+ ),
+ const SizedBox(width: 4),
+ Text(
+ '已保存',
+ style: TextStyle(fontSize: 11, color: Colors.grey[500]),
),
],
),
);
}
+
+ /// 日期时间 + 心情选择条
+ Widget _buildDateMoodStrip(BuildContext context, EditorState state) {
+ final now = DateTime.now();
+ final timeStr =
+ '${now.hour.toString().padLeft(2, '0')}:${now.minute.toString().padLeft(2, '0')}';
+ final moods = [
+ (Mood.happy, '😊'),
+ (Mood.calm, '😐'),
+ (Mood.sad, '😢'),
+ (Mood.angry, '😡'),
+ (Mood.thinking, '🤔'),
+ ];
+ return Container(
+ height: 40,
+ padding: const EdgeInsets.symmetric(horizontal: 16),
+ color: Theme.of(context).colorScheme.surface,
+ child: Row(
+ children: [
+ Text(
+ timeStr,
+ style: TextStyle(fontSize: 13, color: Colors.grey[500]),
+ ),
+ // 心情快捷按钮
+ const Spacer(),
+ ...moods.map((m) {
+ final isSelected = state.selectedMood == m.$1;
+ return GestureDetector(
+ onTap: () =>
+ context.read().add(MoodChanged(m.$1)),
+ child: Container(
+ width: 24,
+ height: 24,
+ margin: const EdgeInsets.symmetric(horizontal: 2),
+ decoration: BoxDecoration(
+ shape: BoxShape.circle,
+ border: isSelected
+ ? Border.all(color: AppColors.accent, width: 1.5)
+ : null,
+ color: isSelected ? const Color(0xFFFFF3E6) : null,
+ ),
+ alignment: Alignment.center,
+ child: Text(m.$2, style: const TextStyle(fontSize: 12)),
+ ),
+ );
+ }),
+ ],
+ ),
+ );
+ }
+
+ /// 显示标签面板
+ void _showTagPanel(BuildContext context, EditorState state) {
+ showModalBottomSheet(
+ context: context,
+ isScrollControlled: true,
+ backgroundColor: Colors.transparent,
+ builder: (ctx) => BlocProvider.value(
+ value: context.read(),
+ child: BlocBuilder(
+ builder: (ctx, state) => TagPanel(
+ selectedTags: state.tags,
+ onTagAdded: (tag) {
+ context.read().add(TagAdded(tag));
+ },
+ onTagRemoved: (tag) {
+ context.read().add(TagRemoved(tag));
+ },
+ ),
+ ),
+ ),
+ );
+ }
}
// ============================================================
@@ -337,16 +543,46 @@ class _EditorStack extends StatefulWidget {
class _EditorStackState extends State<_EditorStack> {
EditorTool? _lastTool;
+ late final TextEditingController _titleController;
+
+ @override
+ void initState() {
+ super.initState();
+ _titleController = TextEditingController(text: widget.state.title);
+ }
+
+ @override
+ void dispose() {
+ _titleController.dispose();
+ super.dispose();
+ }
@override
void didUpdateWidget(covariant _EditorStack oldWidget) {
super.didUpdateWidget(oldWidget);
final currentTool = widget.state.activeTool;
- // 贴纸工具刚被激活时弹出底部面板(防止重复弹窗)
- if (currentTool == EditorTool.sticker && _lastTool != EditorTool.sticker) {
+ // 防止重复弹窗:只在工具切换时触发
+ if (currentTool != _lastTool) {
WidgetsBinding.instance.addPostFrameCallback((_) {
- if (mounted) _showStickerPicker();
+ if (!mounted) return;
+
+ switch (currentTool) {
+ // 贴纸工具 → 弹出贴纸选择面板
+ case EditorTool.sticker:
+ _showStickerPicker();
+ // 画笔工具 → 弹出画笔设置面板
+ case EditorTool.brush:
+ _showBrushPanel();
+ // 模板工具 → 导航到模板页
+ case EditorTool.template:
+ context.go('/templates');
+ // 更多工具 → 弹出分享/导出选项
+ case EditorTool.more:
+ _showMoreSheet();
+ default:
+ break;
+ }
});
}
_lastTool = currentTool;
@@ -376,24 +612,162 @@ class _EditorStackState extends State<_EditorStack> {
);
}
+ /// 显示画笔设置底部面板
+ void _showBrushPanel() {
+ showModalBottomSheet(
+ context: context,
+ isScrollControlled: true,
+ backgroundColor: Colors.transparent,
+ builder: (_) => BlocProvider.value(
+ value: context.read(),
+ child: BlocBuilder(
+ builder: (ctx, state) => BrushPanel(
+ activeBrushType: state.brushType,
+ activeColor: state.brushColor,
+ activeWidth: state.brushWidth,
+ activeOpacity: state.brushOpacity,
+ onBrushTypeChanged: (type) => context.read().add(
+ BrushChanged(
+ type: type,
+ color: state.brushColor,
+ width: state.brushWidth,
+ ),
+ ),
+ onColorChanged: (color) => context.read().add(
+ BrushChanged(
+ type: state.brushType,
+ color: color,
+ width: state.brushWidth,
+ ),
+ ),
+ onWidthChanged: (width) => context.read().add(
+ BrushChanged(
+ type: state.brushType,
+ color: state.brushColor,
+ width: width,
+ ),
+ ),
+ onOpacityChanged: (opacity) {
+ // Phase 1 简化:opacity 仅在 marker 模式下生效
+ // 暂无 opacity 事件,后续扩展
+ },
+ ),
+ ),
+ ),
+ );
+ }
+
+ /// 显示更多选项底部面板(分享/导出/清除)
+ void _showMoreSheet() {
+ final colorScheme = Theme.of(context).colorScheme;
+ showModalBottomSheet(
+ context: context,
+ backgroundColor: Colors.transparent,
+ builder: (_) => Container(
+ decoration: BoxDecoration(
+ color: colorScheme.surface,
+ borderRadius: const BorderRadius.vertical(top: Radius.circular(22)),
+ ),
+ child: Column(
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ // 拖拽指示条
+ Padding(
+ padding: const EdgeInsets.only(top: 12, bottom: 8),
+ child: Container(
+ width: 36,
+ height: 4,
+ decoration: BoxDecoration(
+ color: Colors.grey[300],
+ borderRadius: BorderRadius.circular(2),
+ ),
+ ),
+ ),
+ // 清除画布
+ ListTile(
+ leading: const Icon(Icons.delete_outline_rounded),
+ title: const Text('清除画布'),
+ onTap: () {
+ Navigator.pop(context);
+ context.read().add(ClearCanvas());
+ },
+ ),
+ // 分享
+ ListTile(
+ leading: const Icon(Icons.share_rounded),
+ title: const Text('分享日记'),
+ onTap: () {
+ Navigator.pop(context);
+ // 委托给外层的分享逻辑
+ },
+ ),
+ const SizedBox(height: 16),
+ ],
+ ),
+ ),
+ );
+ }
+
@override
Widget build(BuildContext context) {
final state = widget.state;
+ final colorScheme = Theme.of(context).colorScheme;
return Stack(
fit: StackFit.expand,
children: [
- // Layer 1: 手写画布(底层)
+ // Layer 0: 点阵背景(最底层)
+ CustomPaint(
+ painter: const DotGridPainter(),
+ size: Size.infinite,
+ ),
+
+ // Layer 1: 手写画布 + 内嵌标题
IgnorePointer(
ignoring: !state.isDrawingMode,
- child: HandwritingCanvas(
- brushType: state.brushType,
- brushColor: state.brushColor,
- brushWidth: state.brushWidth,
- strokes: state.strokes,
- onStrokeCompleted: (stroke) {
- context.read().add(StrokeCompleted(stroke));
- },
+ child: Column(
+ children: [
+ // 内嵌标题输入框
+ Padding(
+ padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 8),
+ child: TextField(
+ controller: _titleController,
+ style: TextStyle(
+ fontFamily: 'Quicksand',
+ fontSize: 18,
+ fontWeight: FontWeight.w600,
+ color: colorScheme.onSurface,
+ ),
+ decoration: InputDecoration(
+ hintText: '给日记起个标题吧...',
+ hintStyle: TextStyle(
+ fontFamily: 'Quicksand',
+ fontSize: 18,
+ fontWeight: FontWeight.w600,
+ color: colorScheme.onSurface.withValues(alpha: 0.25),
+ ),
+ border: InputBorder.none,
+ contentPadding: EdgeInsets.zero,
+ isDense: true,
+ ),
+ onChanged: (value) {
+ context.read().add(TitleChanged(value));
+ },
+ ),
+ ),
+ // 画布区域
+ Expanded(
+ child: HandwritingCanvas(
+ brushType: state.brushType,
+ brushColor: state.brushColor,
+ brushWidth: state.brushWidth,
+ strokes: state.strokes,
+ onStrokeCompleted: (stroke) {
+ context.read().add(StrokeCompleted(stroke));
+ },
+ ),
+ ),
+ ],
),
),
@@ -426,7 +800,7 @@ class _EditorStackState extends State<_EditorStack> {
),
// 图片选择覆盖层(图片工具激活时显示)
- if (state.activeTool == EditorTool.image)
+ if (state.activeTool == EditorTool.photo)
Center(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
diff --git a/app/lib/features/editor/widgets/brush_panel.dart b/app/lib/features/editor/widgets/brush_panel.dart
new file mode 100644
index 0000000..e2f94f6
--- /dev/null
+++ b/app/lib/features/editor/widgets/brush_panel.dart
@@ -0,0 +1,215 @@
+// 画笔面板 -- 底部抽屉
+// 提供画笔类型/粗细/颜色/透明度设置
+// 遵循 StickerPickerSheet 底部面板模式
+
+import 'package:flutter/material.dart';
+
+import '../../../core/theme/app_colors.dart';
+import '../bloc/editor_bloc.dart';
+import 'stroke_model.dart';
+
+/// 画笔面板 -- 底部抽屉
+class BrushPanel extends StatelessWidget {
+ final BrushType activeBrushType;
+ final String activeColor;
+ final double activeWidth;
+ final double activeOpacity;
+ final void Function(BrushType type) onBrushTypeChanged;
+ final void Function(String color) onColorChanged;
+ final void Function(double width) onWidthChanged;
+ final void Function(double opacity) onOpacityChanged;
+
+ const BrushPanel({
+ super.key,
+ required this.activeBrushType,
+ required this.activeColor,
+ required this.activeWidth,
+ required this.activeOpacity,
+ required this.onBrushTypeChanged,
+ required this.onColorChanged,
+ required this.onWidthChanged,
+ required this.onOpacityChanged,
+ });
+
+ static const _brushTypes = [
+ (BrushType.pen, '钢笔', Icons.gesture_rounded),
+ (BrushType.pencil, '铅笔', Icons.edit_rounded),
+ (BrushType.marker, '马克笔', Icons.brush_rounded),
+ (BrushType.eraser, '橡皮', Icons.auto_fix_high_rounded),
+ ];
+
+ static const _colors = [
+ '#2D2420', '#E07A5F', '#81B29A', '#F2CC8F',
+ '#D4A5A5', '#42A5F5', '#9C27B0', '#FFFFFF',
+ ];
+
+ @override
+ Widget build(BuildContext context) {
+ return Container(
+ height: 280,
+ decoration: BoxDecoration(
+ color: Theme.of(context).colorScheme.surface,
+ borderRadius: const BorderRadius.vertical(top: Radius.circular(22)),
+ ),
+ child: Column(
+ children: [
+ // 拖拽指示条
+ Padding(
+ padding: const EdgeInsets.only(top: 12, bottom: 8),
+ child: Container(
+ width: 36,
+ height: 4,
+ decoration: BoxDecoration(
+ color: Colors.grey[300],
+ borderRadius: BorderRadius.circular(2),
+ ),
+ ),
+ ),
+ // 画笔类型行
+ _buildBrushTypeRow(context),
+ // 粗细滑块
+ _buildSizeSlider(context),
+ // 颜色行
+ _buildColorRow(context),
+ // 透明度滑块(仅马克笔)
+ if (activeBrushType == BrushType.marker)
+ _buildOpacitySlider(context),
+ ],
+ ),
+ );
+ }
+
+ Widget _buildBrushTypeRow(BuildContext context) {
+ return Padding(
+ padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 8),
+ child: Row(
+ mainAxisAlignment: MainAxisAlignment.spaceEvenly,
+ children: _brushTypes.map((bt) {
+ final isActive = activeBrushType == bt.$1;
+ return GestureDetector(
+ onTap: () => onBrushTypeChanged(bt.$1),
+ child: Container(
+ width: 64,
+ height: 52,
+ decoration: BoxDecoration(
+ borderRadius: BorderRadius.circular(12),
+ border: isActive
+ ? Border.all(color: AppColors.accent, width: 2)
+ : Border.all(color: Colors.transparent),
+ color: isActive
+ ? AppColors.accent.withValues(alpha: 0.1)
+ : null,
+ ),
+ child: Column(
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: [
+ Icon(
+ bt.$3,
+ size: 20,
+ color: isActive ? AppColors.accent : Colors.grey[600],
+ ),
+ const SizedBox(height: 2),
+ Text(
+ bt.$2,
+ style: TextStyle(
+ fontSize: 10,
+ color: isActive ? AppColors.accent : Colors.grey[600],
+ fontWeight:
+ isActive ? FontWeight.w600 : FontWeight.normal,
+ ),
+ ),
+ ],
+ ),
+ ),
+ );
+ }).toList(),
+ ),
+ );
+ }
+
+ Widget _buildSizeSlider(BuildContext context) {
+ return Padding(
+ padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 4),
+ child: Row(
+ children: [
+ Text('粗细',
+ style: TextStyle(fontSize: 12, color: Colors.grey[600])),
+ Expanded(
+ child: Slider(
+ value: activeWidth,
+ min: 1,
+ max: 20,
+ divisions: 19,
+ activeColor: AppColors.accent,
+ label: activeWidth.round().toString(),
+ onChanged: onWidthChanged,
+ ),
+ ),
+ Text(
+ activeWidth.round().toString(),
+ style: TextStyle(fontSize: 12, color: Colors.grey[600]),
+ ),
+ ],
+ ),
+ );
+ }
+
+ Widget _buildColorRow(BuildContext context) {
+ return Padding(
+ padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 8),
+ child: Row(
+ mainAxisAlignment: MainAxisAlignment.spaceEvenly,
+ children: _colors.map((c) {
+ final isActive = activeColor == c;
+ final color = _parseHexColor(c);
+ return GestureDetector(
+ onTap: () => onColorChanged(c),
+ child: Container(
+ width: 24,
+ height: 24,
+ decoration: BoxDecoration(
+ shape: BoxShape.circle,
+ color: color,
+ border: isActive
+ ? Border.all(color: AppColors.accent, width: 2)
+ : (c == '#FFFFFF'
+ ? Border.all(color: Colors.grey[300]!)
+ : null),
+ ),
+ ),
+ );
+ }).toList(),
+ ),
+ );
+ }
+
+ Widget _buildOpacitySlider(BuildContext context) {
+ return Padding(
+ padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 4),
+ child: Row(
+ children: [
+ Text('透明度',
+ style: TextStyle(fontSize: 12, color: Colors.grey[600])),
+ Expanded(
+ child: Slider(
+ value: activeOpacity,
+ min: 0.1,
+ max: 1.0,
+ activeColor: AppColors.accent,
+ onChanged: onOpacityChanged,
+ ),
+ ),
+ Text(
+ '${(activeOpacity * 100).round()}%',
+ style: TextStyle(fontSize: 12, color: Colors.grey[600]),
+ ),
+ ],
+ ),
+ );
+ }
+
+ Color _parseHexColor(String hex) {
+ final code = hex.replaceFirst('#', '');
+ return Color(int.parse('FF$code', radix: 16));
+ }
+}
diff --git a/app/lib/features/editor/widgets/dot_grid_painter.dart b/app/lib/features/editor/widgets/dot_grid_painter.dart
new file mode 100644
index 0000000..8defddf
--- /dev/null
+++ b/app/lib/features/editor/widgets/dot_grid_painter.dart
@@ -0,0 +1,28 @@
+// 点阵背景画笔 — 24x24px 间距,1px 圆点
+// 用于日记编辑区域提供纸质感背景
+
+import 'package:flutter/material.dart';
+
+/// 点阵背景画笔 -- 24x24px 间距,1px 圆点
+class DotGridPainter extends CustomPainter {
+ const DotGridPainter();
+
+ @override
+ void paint(Canvas canvas, Size size) {
+ final paint = Paint()
+ ..color = const Color(0xFF2D2420).withOpacity(0.15)
+ ..style = PaintingStyle.fill;
+
+ const spacing = 24.0;
+ const dotRadius = 1.0;
+
+ for (double x = spacing; x < size.width; x += spacing) {
+ for (double y = spacing; y < size.height; y += spacing) {
+ canvas.drawCircle(Offset(x, y), dotRadius, paint);
+ }
+ }
+ }
+
+ @override
+ bool shouldRepaint(covariant DotGridPainter oldDelegate) => false;
+}
diff --git a/app/lib/features/editor/widgets/editor_toolbar.dart b/app/lib/features/editor/widgets/editor_toolbar.dart
index aeb7c1a..32c514e 100644
--- a/app/lib/features/editor/widgets/editor_toolbar.dart
+++ b/app/lib/features/editor/widgets/editor_toolbar.dart
@@ -1,22 +1,22 @@
-// 编辑器工具栏 — 底部工具面板
+// 编辑器工具栏 — 底部单行 6 按钮面板
//
-// 三段式布局:
-// - 工具选择行(画笔/选择/文字/贴纸/照片)
-// - 工具选项行(颜色/大小 — 根据当前工具动态变化)
-// - 操作行(撤销/重做/清除)
+// 精简布局:
+// - 单行 6 个工具按钮(贴纸/模板/画笔/照片/文字/更多)
+// - 高度 72px + 底部安全区
+// - 每个按钮:Column(icon 20px + label 10px),最小 36x36
+//
+// 详细选项已移至独立面板:
+// - 画笔选项 → BrushPanel(底部抽屉)
+// - 撤销/重做 → 顶栏
+// - 清除 → 顶栏
//
// 设计规范:触摸目标 ≥ 44px,圆角 22px (pill)
import 'package:flutter/material.dart';
-import '../../../core/constants/design_tokens.dart';
-import '../../../core/theme/app_colors.dart';
import '../bloc/editor_bloc.dart';
-/// 工具栏高度
-const double _toolbarHeight = 160;
-
-/// 编辑器工具栏
+/// 编辑器工具栏 — 精简版
class EditorToolbar extends StatelessWidget {
final EditorState state;
final ValueChanged onEvent;
@@ -30,61 +30,35 @@ class EditorToolbar extends StatelessWidget {
@override
Widget build(BuildContext context) {
final colorScheme = Theme.of(context).colorScheme;
-
return Container(
- height: _toolbarHeight,
+ height: 72 + MediaQuery.of(context).padding.bottom,
decoration: BoxDecoration(
color: colorScheme.surface,
- boxShadow: [
- BoxShadow(
- color: Colors.black.withValues(alpha: 0.08),
- blurRadius: 8,
- offset: const Offset(0, -2),
+ border: Border(
+ top: BorderSide(
+ color: colorScheme.outlineVariant.withValues(alpha: 0.3),
),
- ],
- borderRadius: const BorderRadius.vertical(top: Radius.circular(22)),
+ ),
),
- child: Column(
- children: [
- // 工具选择行
- _buildToolRow(context, colorScheme),
- const Divider(height: 1),
-
- // 工具选项行(颜色/大小)
- _buildOptionsRow(context, colorScheme),
- const Divider(height: 1),
-
- // 操作行(撤销/重做/清除)
- _buildActionRow(context, colorScheme),
- ],
+ child: Padding(
+ padding: EdgeInsets.only(bottom: MediaQuery.of(context).padding.bottom),
+ child: Row(
+ mainAxisAlignment: MainAxisAlignment.spaceEvenly,
+ children: [
+ _toolBtn(context, EditorTool.sticker, Icons.emoji_emotions_rounded, '贴纸'),
+ _toolBtn(context, EditorTool.template, Icons.dashboard_customize_rounded, '模板'),
+ _toolBtn(context, EditorTool.brush, Icons.gesture_rounded, '画笔'),
+ _toolBtn(context, EditorTool.photo, Icons.add_photo_alternate_rounded, '照片'),
+ _toolBtn(context, EditorTool.text, Icons.text_fields_rounded, '文字'),
+ _toolBtn(context, EditorTool.more, Icons.more_horiz_rounded, '更多'),
+ ],
+ ),
),
);
}
- // ============================================================
- // 工具选择行
- // ============================================================
-
- Widget _buildToolRow(BuildContext context, ColorScheme colorScheme) {
- return SizedBox(
- height: 52,
- child: Row(
- mainAxisAlignment: MainAxisAlignment.spaceEvenly,
- children: [
- _toolButton(context, EditorTool.pen, Icons.gesture_rounded, '钢笔'),
- _toolButton(context, EditorTool.pencil, Icons.edit_rounded, '铅笔'),
- _toolButton(context, EditorTool.marker, Icons.brush_rounded, '马克笔'),
- _toolButton(context, EditorTool.eraser, Icons.auto_fix_high_rounded, '橡皮'),
- _toolButton(context, EditorTool.select, Icons.near_me_rounded, '选择'),
- _toolButton(context, EditorTool.text, Icons.text_fields_rounded, '文字'),
- _toolButton(context, EditorTool.sticker, Icons.emoji_emotions_rounded, '贴纸'),
- _toolButton(context, EditorTool.image, Icons.add_photo_alternate_rounded, '照片'),
- ],
- ),
- );
- }
-
- Widget _toolButton(
+ /// 工具按钮 — icon + label 垂直排列
+ Widget _toolBtn(
BuildContext context,
EditorTool tool,
IconData icon,
@@ -93,265 +67,37 @@ class EditorToolbar extends StatelessWidget {
final isActive = state.activeTool == tool;
final colorScheme = Theme.of(context).colorScheme;
- return SizedBox(
- width: 44,
- height: 44,
- child: IconButton(
- onPressed: () => onEvent(ToolChanged(tool)),
- icon: Icon(icon, size: 22),
- color: isActive ? colorScheme.primary : colorScheme.onSurface.withValues(alpha: 0.5),
- style: IconButton.styleFrom(
- backgroundColor: isActive
- ? colorScheme.primaryContainer.withValues(alpha: 0.3)
- : Colors.transparent,
- shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
- ),
- tooltip: label,
- ),
- );
- }
-
- // ============================================================
- // 工具选项行(颜色 + 大小)
- // ============================================================
-
- static const _colors = [
- '#2D2420', // 主文字
- '#E07A5F', // 珊瑚
- '#81B29A', // 鼠尾草绿
- '#F2CC8F', // 暖金
- '#D4A5A5', // 玫瑰粉
- '#42A5F5', // 信息蓝
- '#9C27B0', // 紫色
- '#FFFFFF', // 白色
- ];
-
- static const _widths = [1.5, 3.0, 5.0, 8.0, 12.0];
-
- Widget _buildOptionsRow(BuildContext context, ColorScheme colorScheme) {
- // 画笔模式:颜色 + 粗细
- if (state.isDrawingMode) {
- return _buildBrushOptions(context, colorScheme);
- }
-
- // 文字工具提示
- if (state.activeTool == EditorTool.text) {
- return const SizedBox(
- height: 44,
- child: Center(
- child: Row(
- mainAxisSize: MainAxisSize.min,
- children: [
- Icon(Icons.text_fields, size: 16),
- SizedBox(width: 8),
- Text('点击画布输入文字', style: TextStyle(fontSize: 13)),
- ],
- ),
- ),
- );
- }
-
- // 贴纸工具提示
- if (state.activeTool == EditorTool.sticker) {
- return const SizedBox(
- height: 44,
- child: Center(
- child: Row(
- mainAxisSize: MainAxisSize.min,
- children: [
- Icon(Icons.emoji_emotions_outlined, size: 16),
- SizedBox(width: 8),
- Text('选择一个贴纸放到日记上', style: TextStyle(fontSize: 13)),
- ],
- ),
- ),
- );
- }
-
- // 图片工具提示
- if (state.activeTool == EditorTool.image) {
- return const SizedBox(
- height: 44,
- child: Center(
- child: Row(
- mainAxisSize: MainAxisSize.min,
- children: [
- Icon(Icons.add_photo_alternate_outlined, size: 16),
- SizedBox(width: 8),
- Text('选择照片添加到日记', style: TextStyle(fontSize: 13)),
- ],
- ),
- ),
- );
- }
-
- // 选择工具
- return const SizedBox(
- height: 44,
- child: Center(child: Text('选择元素或添加内容')),
- );
- }
-
- /// 画笔模式选项 — 颜色 + 粗细
- Widget _buildBrushOptions(BuildContext context, ColorScheme colorScheme) {
-
- return SizedBox(
- height: 44,
- child: Row(
- children: [
- // 颜色选择
- Expanded(
- child: ListView.separated(
- scrollDirection: Axis.horizontal,
- padding: const EdgeInsets.symmetric(horizontal: DesignTokens.spacing12),
- itemCount: _colors.length,
- separatorBuilder: (_, __) => const SizedBox(width: 6),
- itemBuilder: (context, index) {
- final color = _colors[index];
- final isActive = state.brushColor == color;
- return GestureDetector(
- onTap: () => onEvent(BrushChanged(
- type: state.brushType,
- color: color,
- width: state.brushWidth,
- )),
- child: Container(
- width: 28,
- height: 28,
- decoration: BoxDecoration(
- color: _parseHexColor(color),
- shape: BoxShape.circle,
- border: isActive
- ? Border.all(color: colorScheme.primary, width: 2.5)
- : Border.all(color: Colors.grey.shade300, width: 1),
- ),
- child: color == '#FFFFFF'
- ? const Icon(Icons.check, size: 16, color: Colors.grey)
- : null,
- ),
- );
- },
+ return GestureDetector(
+ onTap: () => onEvent(ToolChanged(tool)),
+ behavior: HitTestBehavior.opaque,
+ child: Container(
+ constraints: const BoxConstraints(minWidth: 36, minHeight: 36),
+ padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
+ child: Column(
+ mainAxisSize: MainAxisSize.min,
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: [
+ Icon(
+ icon,
+ size: 20,
+ color: isActive
+ ? colorScheme.primary
+ : colorScheme.onSurface.withValues(alpha: 0.5),
),
- ),
-
- // 分隔线
- Container(width: 1, height: 24, color: colorScheme.outline.withValues(alpha: 0.2)),
-
- // 笔刷大小
- SizedBox(
- width: 160,
- child: Row(
- mainAxisAlignment: MainAxisAlignment.spaceEvenly,
- children: _widths.map((w) {
- final isActive = (state.brushWidth - w).abs() < 0.5;
- return GestureDetector(
- onTap: () => onEvent(BrushChanged(
- type: state.brushType,
- color: state.brushColor,
- width: w,
- )),
- child: Container(
- width: 28,
- height: 28,
- alignment: Alignment.center,
- decoration: BoxDecoration(
- shape: BoxShape.circle,
- border: isActive
- ? Border.all(color: colorScheme.primary, width: 2)
- : null,
- ),
- child: Container(
- width: (w / 12 * 16 + 4).clamp(4, 20),
- height: (w / 12 * 16 + 4).clamp(4, 20),
- decoration: BoxDecoration(
- color: _parseHexColor(state.brushColor),
- shape: BoxShape.circle,
- ),
- ),
- ),
- );
- }).toList(),
- ),
- ),
- ],
- ),
- );
- }
-
- // ============================================================
- // 操作行
- // ============================================================
-
- Widget _buildActionRow(BuildContext context, ColorScheme colorScheme) {
- return SizedBox(
- height: 44,
- child: Row(
- mainAxisAlignment: MainAxisAlignment.spaceEvenly,
- children: [
- // 撤销
- IconButton(
- onPressed: state.strokes.isNotEmpty
- ? () => onEvent(Undo())
- : null,
- icon: const Icon(Icons.undo_rounded),
- tooltip: '撤销',
- ),
-
- // 重做
- IconButton(
- onPressed: state.redoStack.isNotEmpty
- ? () => onEvent(Redo())
- : null,
- icon: const Icon(Icons.redo_rounded),
- tooltip: '重做',
- ),
-
- // 清除
- IconButton(
- onPressed: state.strokes.isNotEmpty || state.elements.isNotEmpty
- ? () => onEvent(ClearCanvas())
- : null,
- icon: const Icon(Icons.delete_outline_rounded),
- tooltip: '清除',
- ),
-
- // 保存状态指示
- if (state.isDirty)
- Padding(
- padding: const EdgeInsets.symmetric(horizontal: DesignTokens.spacing8),
- child: Text(
- '未保存',
- style: TextStyle(
- fontSize: 12,
- color: colorScheme.onSurface.withValues(alpha: 0.5),
- ),
- ),
- )
- else if (state.lastSavedAt != null)
- Padding(
- padding: const EdgeInsets.symmetric(horizontal: DesignTokens.spacing8),
- child: Text(
- '已保存',
- style: TextStyle(
- fontSize: 12,
- color: AppColors.success,
- ),
+ const SizedBox(height: 2),
+ Text(
+ label,
+ style: TextStyle(
+ fontSize: 10,
+ color: isActive
+ ? colorScheme.primary
+ : colorScheme.onSurface.withValues(alpha: 0.5),
+ fontWeight: isActive ? FontWeight.w600 : FontWeight.normal,
),
),
- ],
+ ],
+ ),
),
);
}
-
- // ============================================================
- // 工具函数
- // ============================================================
-
- Color _parseHexColor(String hex) {
- final hexStr = hex.replaceFirst('#', '');
- if (hexStr.length != 6) return const Color(0xFF2D2420);
- final value = int.tryParse(hexStr, radix: 16);
- if (value == null) return const Color(0xFF2D2420);
- return Color(0xFF000000 + value);
- }
}
diff --git a/app/lib/features/editor/widgets/tag_panel.dart b/app/lib/features/editor/widgets/tag_panel.dart
new file mode 100644
index 0000000..07105c3
--- /dev/null
+++ b/app/lib/features/editor/widgets/tag_panel.dart
@@ -0,0 +1,157 @@
+// 标签面板 -- 底部抽屉
+// 支持添加/移除自定义标签 + 推荐标签快捷选择
+
+import 'package:flutter/material.dart';
+
+import '../../../core/theme/app_colors.dart';
+
+/// 标签面板 -- 底部抽屉
+class TagPanel extends StatefulWidget {
+ final List selectedTags;
+ final void Function(String tag) onTagAdded;
+ final void Function(String tag) onTagRemoved;
+
+ const TagPanel({
+ super.key,
+ required this.selectedTags,
+ required this.onTagAdded,
+ required this.onTagRemoved,
+ });
+
+ @override
+ State createState() => _TagPanelState();
+}
+
+class _TagPanelState extends State {
+ final _controller = TextEditingController();
+ final _focusNode = FocusNode();
+
+ static const _suggestedTags = [
+ '日常', '学习', '读书', '心情', '学校', '旅行',
+ '美食', '运动', '音乐', '梦想',
+ ];
+
+ @override
+ void initState() {
+ super.initState();
+ _focusNode.requestFocus();
+ }
+
+ @override
+ void dispose() {
+ _controller.dispose();
+ _focusNode.dispose();
+ super.dispose();
+ }
+
+ void _submitTag() {
+ final text = _controller.text.trim();
+ if (text.isNotEmpty) {
+ widget.onTagAdded(text);
+ _controller.clear();
+ }
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ return Container(
+ constraints: const BoxConstraints(maxHeight: 240),
+ decoration: BoxDecoration(
+ color: Theme.of(context).colorScheme.surface,
+ borderRadius: const BorderRadius.vertical(top: Radius.circular(22)),
+ ),
+ child: Column(
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ // 拖拽指示条
+ Padding(
+ padding: const EdgeInsets.only(top: 12, bottom: 8),
+ child: Container(
+ width: 36,
+ height: 4,
+ decoration: BoxDecoration(
+ color: Colors.grey[300],
+ borderRadius: BorderRadius.circular(2),
+ ),
+ ),
+ ),
+ // 已选标签区
+ if (widget.selectedTags.isNotEmpty)
+ Padding(
+ padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 4),
+ child: Wrap(
+ spacing: 8,
+ runSpacing: 6,
+ children: widget.selectedTags
+ .map((tag) => Chip(
+ label: Text('#$tag',
+ style: const TextStyle(fontSize: 13)),
+ backgroundColor: const Color(0xFFFFF3E6),
+ labelStyle: const TextStyle(color: AppColors.accent),
+ deleteIconColor: AppColors.accent,
+ onDeleted: () => widget.onTagRemoved(tag),
+ materialTapTargetSize:
+ MaterialTapTargetSize.shrinkWrap,
+ visualDensity: VisualDensity.compact,
+ ))
+ .toList(),
+ ),
+ ),
+ // 输入框
+ Padding(
+ padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 8),
+ child: TextField(
+ controller: _controller,
+ focusNode: _focusNode,
+ decoration: InputDecoration(
+ hintText: '添加标签,回车确认',
+ hintStyle: TextStyle(fontSize: 14, color: Colors.grey[400]),
+ prefixIcon:
+ const Icon(Icons.tag, size: 20, color: AppColors.accent),
+ border: OutlineInputBorder(
+ borderRadius: BorderRadius.circular(12),
+ borderSide: BorderSide(color: Colors.grey[300]!),
+ ),
+ enabledBorder: OutlineInputBorder(
+ borderRadius: BorderRadius.circular(12),
+ borderSide: BorderSide(color: Colors.grey[300]!),
+ ),
+ focusedBorder: OutlineInputBorder(
+ borderRadius: BorderRadius.circular(12),
+ borderSide: const BorderSide(color: AppColors.accent),
+ ),
+ contentPadding:
+ const EdgeInsets.symmetric(horizontal: 12),
+ isDense: true,
+ ),
+ style: const TextStyle(fontSize: 14),
+ textInputAction: TextInputAction.done,
+ onSubmitted: (_) => _submitTag(),
+ ),
+ ),
+ // 推荐标签
+ Padding(
+ padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 4),
+ child: Wrap(
+ spacing: 8,
+ runSpacing: 6,
+ children: _suggestedTags
+ .where((t) => !widget.selectedTags.contains(t))
+ .map((tag) => ActionChip(
+ label:
+ Text('#$tag', style: const TextStyle(fontSize: 12)),
+ backgroundColor: Colors.grey[100],
+ onPressed: () => widget.onTagAdded(tag),
+ materialTapTargetSize:
+ MaterialTapTargetSize.shrinkWrap,
+ visualDensity: VisualDensity.compact,
+ ))
+ .toList(),
+ ),
+ ),
+ const SizedBox(height: 16),
+ ],
+ ),
+ );
+ }
+}
diff --git a/app/lib/features/editor/widgets/text_format_bar.dart b/app/lib/features/editor/widgets/text_format_bar.dart
new file mode 100644
index 0000000..88ebd58
--- /dev/null
+++ b/app/lib/features/editor/widgets/text_format_bar.dart
@@ -0,0 +1,143 @@
+// 文字格式栏 -- 浮动在选中文字元素上方
+// 提供加粗/斜体/下划线/颜色/对齐 切换
+
+import 'package:flutter/material.dart';
+
+import '../../../core/theme/app_colors.dart';
+
+/// 文字格式栏 -- 浮动在选中文字元素上方
+class TextFormatBar extends StatelessWidget {
+ final bool bold;
+ final bool italic;
+ final bool underline;
+ final String? color;
+ final int alignment; // 0=left, 1=center, 2=right
+ final void Function({
+ bool? bold,
+ bool? italic,
+ bool? underline,
+ String? color,
+ int? alignment,
+ }) onFormatChanged;
+
+ const TextFormatBar({
+ super.key,
+ this.bold = false,
+ this.italic = false,
+ this.underline = false,
+ this.color,
+ this.alignment = 0,
+ required this.onFormatChanged,
+ });
+
+ static const _colors = ['#2D2420', '#E07A5F', '#81B29A', '#42A5F5'];
+
+ @override
+ Widget build(BuildContext context) {
+ return Container(
+ height: 40,
+ decoration: BoxDecoration(
+ color: Theme.of(context).colorScheme.surface,
+ borderRadius: BorderRadius.circular(12),
+ boxShadow: [
+ BoxShadow(
+ color: Colors.black.withValues(alpha: 0.1),
+ blurRadius: 8,
+ offset: const Offset(0, 2),
+ ),
+ ],
+ border: Border.all(color: Colors.grey[200]!),
+ ),
+ child: Row(
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ // B/I/U toggles
+ _toggleBtn('B', bold, () => onFormatChanged(bold: !bold)),
+ _toggleBtn('I', italic, () => onFormatChanged(italic: !italic)),
+ _toggleBtn(
+ 'U', underline, () => onFormatChanged(underline: !underline)),
+ const SizedBox(width: 4),
+ Container(width: 1, height: 20, color: Colors.grey[300]),
+ const SizedBox(width: 4),
+ // Color dots
+ ..._colors.map((c) => _colorDot(c, color == c)),
+ const SizedBox(width: 4),
+ Container(width: 1, height: 20, color: Colors.grey[300]),
+ const SizedBox(width: 4),
+ // Alignment
+ _alignBtn(Icons.format_align_left, 0),
+ _alignBtn(Icons.format_align_center, 1),
+ _alignBtn(Icons.format_align_right, 2),
+ const SizedBox(width: 4),
+ ],
+ ),
+ );
+ }
+
+ Widget _toggleBtn(String label, bool active, VoidCallback onTap) {
+ return GestureDetector(
+ onTap: onTap,
+ child: Container(
+ width: 36,
+ height: 36,
+ decoration: BoxDecoration(
+ color: active ? AppColors.accent : Colors.transparent,
+ borderRadius: BorderRadius.circular(8),
+ ),
+ alignment: Alignment.center,
+ child: Text(
+ label,
+ style: TextStyle(
+ fontSize: 16,
+ fontWeight: FontWeight.w700,
+ color: active ? Colors.white : Colors.grey[700],
+ fontStyle: label == 'I' ? FontStyle.italic : FontStyle.normal,
+ decoration:
+ label == 'U' ? TextDecoration.underline : TextDecoration.none,
+ ),
+ ),
+ ),
+ );
+ }
+
+ Widget _colorDot(String hex, bool active) {
+ final code = hex.replaceFirst('#', '');
+ final color = Color(int.parse('FF$code', radix: 16));
+ return GestureDetector(
+ onTap: () => onFormatChanged(color: hex),
+ child: Container(
+ width: 20,
+ height: 20,
+ margin: const EdgeInsets.symmetric(horizontal: 2),
+ decoration: BoxDecoration(
+ shape: BoxShape.circle,
+ color: color,
+ border:
+ active ? Border.all(color: AppColors.accent, width: 2) : null,
+ ),
+ ),
+ );
+ }
+
+ Widget _alignBtn(IconData icon, int align) {
+ final active = alignment == align;
+ return GestureDetector(
+ onTap: () => onFormatChanged(alignment: align),
+ child: Container(
+ width: 36,
+ height: 36,
+ decoration: BoxDecoration(
+ color:
+ active ? AppColors.accent.withValues(alpha: 0.1) : Colors.transparent,
+ borderRadius: BorderRadius.circular(8),
+ ),
+ alignment: Alignment.center,
+ child: Icon(
+ icon,
+ size: 18,
+ color: active ? AppColors.accent : Colors.grey[600],
+ ),
+ ),
+ );
+ }
+}
diff --git a/app/lib/features/home/bloc/home_bloc.dart b/app/lib/features/home/bloc/home_bloc.dart
index 3713f02..e6ae4ea 100644
--- a/app/lib/features/home/bloc/home_bloc.dart
+++ b/app/lib/features/home/bloc/home_bloc.dart
@@ -54,6 +54,9 @@ final class HomeLoaded extends HomeState {
/// 总日记数(spec §3.4 quick-stats)
final int totalCount;
+ /// 今日天气(从今日日记中提取,null 则默认晴)
+ final Weather? todayWeather;
+
const HomeLoaded({
this.recentJournals = const [],
this.hasTodayEntry = false,
@@ -61,6 +64,7 @@ final class HomeLoaded extends HomeState {
this.streakDays = 0,
this.monthCount = 0,
this.totalCount = 0,
+ this.todayWeather,
});
}
@@ -111,10 +115,21 @@ class HomeBloc extends Bloc {
// 推算连续天数
final streakDays = _calculateStreak(journals);
- // 本月日记数 & 总数(spec §3.4 quick-stats)
+ // 本月日记数(spec §3.4 quick-stats)
final monthCount = journals.where((j) =>
j.date.year == today.year && j.date.month == today.month).length;
- final totalCount = journals.length;
+
+ // 总日记数 — 使用仓库计数方法(不受分页限制)
+ final totalCount = await _journalRepo.getJournalCount();
+
+ // 今日天气 — 从今日日记中提取
+ final todayJournal = journals.firstWhere(
+ (j) => j.date.year == today.year &&
+ j.date.month == today.month &&
+ j.date.day == today.day,
+ orElse: () => journals.first, // fallback for type safety
+ );
+ final todayWeather = hasTodayEntry ? todayJournal.weather : null;
emit(HomeLoaded(
recentJournals: journals,
@@ -123,6 +138,7 @@ class HomeBloc extends Bloc {
streakDays: streakDays,
monthCount: monthCount,
totalCount: totalCount,
+ todayWeather: todayWeather,
));
} catch (e) {
emit(const HomeLoaded()); // 空状态而非错误,离线友好
diff --git a/app/lib/features/home/views/home_page.dart b/app/lib/features/home/views/home_page.dart
index 0aca342..ddfa62d 100644
--- a/app/lib/features/home/views/home_page.dart
+++ b/app/lib/features/home/views/home_page.dart
@@ -100,7 +100,7 @@ class _HomeView extends StatelessWidget {
_MoodSelectorCard(
topMood: state.topMood,
- weather: const _Weather(icon: '☀', label: '晴 26°'),
+ todayWeather: state.todayWeather,
onMoodTap: (_) => context.push('/editor'),
),
const SizedBox(height: DesignTokens.spacing20),
@@ -261,12 +261,12 @@ class _StreakBadge extends StatelessWidget {
class _MoodSelectorCard extends StatelessWidget {
const _MoodSelectorCard({
required this.topMood,
- required this.weather,
+ required this.todayWeather,
required this.onMoodTap,
});
final Mood? topMood;
- final _Weather weather;
+ final Weather? todayWeather;
final ValueChanged onMoodTap;
static const _moods = [
@@ -277,6 +277,14 @@ class _MoodSelectorCard extends StatelessWidget {
('🤔', '思考', Mood.thinking),
];
+ static const _weatherMap = {
+ Weather.sunny: ('☀', '晴'),
+ Weather.cloudy: ('☁', '多云'),
+ Weather.rainy: ('🌧', '雨'),
+ Weather.snowy: ('❄', '雪'),
+ Weather.windy: ('💨', '风'),
+ };
+
@override
Widget build(BuildContext context) {
final theme = Theme.of(context);
@@ -306,10 +314,13 @@ class _MoodSelectorCard extends StatelessWidget {
),
),
const Spacer(),
- Text(
- '${weather.icon} ${weather.label}',
- style: TextStyle(fontSize: 13, color: theme.colorScheme.onSurfaceVariant),
- ),
+ Builder(builder: (context) {
+ final w = _weatherMap[todayWeather] ?? _weatherMap[Weather.sunny]!;
+ return Text(
+ '${w.$1} ${w.$2}',
+ style: TextStyle(fontSize: 13, color: theme.colorScheme.onSurfaceVariant),
+ );
+ }),
],
),
const SizedBox(height: DesignTokens.spacing12),
@@ -376,12 +387,6 @@ class _MoodOption extends StatelessWidget {
}
}
-class _Weather {
- const _Weather({required this.icon, required this.label});
- final String icon;
- final String label;
-}
-
/// 4. "今天的日记" 渐变卡片 + 浮动写按钮
class _TodayCard extends StatelessWidget {
const _TodayCard({required this.hasTodayEntry, required this.onTap});
@@ -621,7 +626,9 @@ class _JournalCard extends StatelessWidget {
Widget build(BuildContext context) {
final theme = Theme.of(context);
final moodColor = AppColors.moodColors[journal.mood.value] ?? AppColors.accent;
- final excerpt = journal.tags.isEmpty ? '点击查看详情' : journal.tags.take(3).map((t) => '#$t').join(' ');
+ final excerpt = journal.contentExcerpt?.isNotEmpty == true
+ ? journal.contentExcerpt!
+ : (journal.tags.isEmpty ? '点击查看详情' : journal.tags.take(3).map((t) => '#$t').join(' '));
return Material(
color: theme.colorScheme.surface,
diff --git a/app/lib/features/parent/views/parent_page.dart b/app/lib/features/parent/views/parent_page.dart
index 285939c..ce09df5 100644
--- a/app/lib/features/parent/views/parent_page.dart
+++ b/app/lib/features/parent/views/parent_page.dart
@@ -922,7 +922,8 @@ class _JournalCard extends StatelessWidget {
try {
final dt = DateTime.parse(isoStr);
return DateFormat('MM-dd').format(dt);
- } catch (_) {
+ } catch (e) {
+ debugPrint('ParentPage._formatDate 失败: $e');
return '';
}
}
diff --git a/app/lib/features/profile/views/profile_page.dart b/app/lib/features/profile/views/profile_page.dart
index e68aa76..8aaf62d 100644
--- a/app/lib/features/profile/views/profile_page.dart
+++ b/app/lib/features/profile/views/profile_page.dart
@@ -408,7 +408,8 @@ class _LiveStatsBarState extends State<_LiveStatsBar> {
_streakDays = streak;
_monthCount = monthCount;
});
- } catch (_) {
+ } catch (e) {
+ debugPrint('ProfilePage._loadStats 失败: $e');
// 保持默认 0 值
}
}
diff --git a/app/lib/features/search/bloc/search_bloc.dart b/app/lib/features/search/bloc/search_bloc.dart
index b678380..d9e806e 100644
--- a/app/lib/features/search/bloc/search_bloc.dart
+++ b/app/lib/features/search/bloc/search_bloc.dart
@@ -1,7 +1,7 @@
-// 搜索 BLoC — 标签+心情筛选日记
+// 搜索 BLoC — 关键词+标签+心情筛选日记
//
// 状态机: SearchInitial → SearchLoading → SearchLoaded/SearchError
-// Phase 1 使用简单的标签+心情筛选,后续可扩展全文搜索。
+// 支持关键词搜索、标签筛选、心情筛选、结果分类 tab。
import 'package:flutter_bloc/flutter_bloc.dart';
@@ -11,16 +11,21 @@ import '../../../data/repositories/journal_repository.dart';
part 'search_event.dart';
part 'search_state.dart';
-/// 搜索 BLoC — 处理标签和心情筛选日记的状态转换
+/// 搜索 BLoC
class SearchBloc extends Bloc {
final JournalRepository _journalRepo;
+ /// 内存搜索历史(最多 10 条)
+ final List _searchHistory = [];
+
SearchBloc({required JournalRepository journalRepository})
: _journalRepo = journalRepository,
super(const SearchInitial()) {
on(_onSearchByMood);
on(_onSearchByTag);
+ on(_onSearchByKeyword);
on(_onSearchClear);
+ on(_onSearchTabChanged);
}
/// 按心情筛选日记
@@ -31,7 +36,7 @@ class SearchBloc extends Bloc {
emit(const SearchLoading());
try {
if (event.mood == null) {
- emit(const SearchLoaded());
+ emit(SearchLoaded(searchHistory: List.unmodifiable(_searchHistory)));
return;
}
final results = await _journalRepo.getJournals(
@@ -42,6 +47,7 @@ class SearchBloc extends Bloc {
emit(SearchLoaded(
results: results,
activeMood: event.mood!.value,
+ searchHistory: List.unmodifiable(_searchHistory),
));
} catch (e) {
emit(const SearchError('搜索失败,请重试'));
@@ -55,6 +61,7 @@ class SearchBloc extends Bloc {
) async {
emit(const SearchLoading());
try {
+ _addToHistory(event.tag);
final results = await _journalRepo.getJournals(
tag: event.tag,
page: 1,
@@ -63,6 +70,47 @@ class SearchBloc extends Bloc {
emit(SearchLoaded(
results: results,
activeTag: event.tag,
+ searchHistory: List.unmodifiable(_searchHistory),
+ ));
+ } catch (e) {
+ emit(const SearchError('搜索失败,请重试'));
+ }
+ }
+
+ /// 关键词搜索 — 在标题中匹配关键词
+ Future _onSearchByKeyword(
+ SearchByKeyword event,
+ Emitter emit,
+ ) async {
+ final keyword = event.keyword.trim();
+ if (keyword.isEmpty) {
+ emit(SearchLoaded(searchHistory: List.unmodifiable(_searchHistory)));
+ return;
+ }
+
+ emit(const SearchLoading());
+ try {
+ _addToHistory(keyword);
+ // 获取所有日记并在客户端按关键词过滤
+ final allJournals = await _journalRepo.getJournals(
+ page: 1,
+ pageSize: 200,
+ );
+ final lowerKeyword = keyword.toLowerCase();
+ final results = allJournals.where((j) {
+ final titleMatch = j.title.toLowerCase().contains(lowerKeyword);
+ final excerptMatch = (j.contentExcerpt ?? '')
+ .toLowerCase()
+ .contains(lowerKeyword);
+ final tagMatch =
+ j.tags.any((t) => t.toLowerCase().contains(lowerKeyword));
+ return titleMatch || excerptMatch || tagMatch;
+ }).toList();
+
+ emit(SearchLoaded(
+ results: results,
+ activeKeyword: keyword,
+ searchHistory: List.unmodifiable(_searchHistory),
));
} catch (e) {
emit(const SearchError('搜索失败,请重试'));
@@ -74,6 +122,26 @@ class SearchBloc extends Bloc {
SearchClear event,
Emitter emit,
) {
- emit(const SearchLoaded());
+ emit(SearchLoaded(searchHistory: List.unmodifiable(_searchHistory)));
+ }
+
+ /// 切换结果分类 tab
+ void _onSearchTabChanged(
+ SearchTabChanged event,
+ Emitter emit,
+ ) {
+ final current = state;
+ if (current is SearchLoaded) {
+ emit(current.copyWith(activeTab: event.tab));
+ }
+ }
+
+ /// 添加到搜索历史(去重,最多 10 条)
+ void _addToHistory(String keyword) {
+ _searchHistory.remove(keyword);
+ _searchHistory.insert(0, keyword);
+ if (_searchHistory.length > 10) {
+ _searchHistory.removeLast();
+ }
}
}
diff --git a/app/lib/features/search/bloc/search_event.dart b/app/lib/features/search/bloc/search_event.dart
index 2e5a7ba..b48a516 100644
--- a/app/lib/features/search/bloc/search_event.dart
+++ b/app/lib/features/search/bloc/search_event.dart
@@ -19,7 +19,19 @@ final class SearchByTag extends SearchEvent {
const SearchByTag(this.tag);
}
+/// 关键词搜索
+final class SearchByKeyword extends SearchEvent {
+ final String keyword;
+ const SearchByKeyword(this.keyword);
+}
+
/// 清除搜索结果
final class SearchClear extends SearchEvent {
const SearchClear();
}
+
+/// 切换搜索结果分类 tab
+final class SearchTabChanged extends SearchEvent {
+ final SearchResultTab tab;
+ const SearchTabChanged(this.tab);
+}
diff --git a/app/lib/features/search/bloc/search_state.dart b/app/lib/features/search/bloc/search_state.dart
index 014d833..952328e 100644
--- a/app/lib/features/search/bloc/search_state.dart
+++ b/app/lib/features/search/bloc/search_state.dart
@@ -2,6 +2,17 @@
part of 'search_bloc.dart';
+/// 搜索结果分类 tab
+enum SearchResultTab {
+ all('全部'),
+ journal('日记'),
+ template('模板'),
+ tag('标签');
+
+ const SearchResultTab(this.label);
+ final String label;
+}
+
/// 搜索状态基类
sealed class SearchState {
const SearchState();
@@ -19,7 +30,7 @@ final class SearchLoading extends SearchState {
/// 搜索结果已加载
final class SearchLoaded extends SearchState {
- /// 搜索结果列表(空列表表示无匹配)
+ /// 日记搜索结果列表
final List results;
/// 当前活跃的心情筛选条件
@@ -28,24 +39,47 @@ final class SearchLoaded extends SearchState {
/// 当前活跃的标签筛选条件
final String? activeTag;
+ /// 当前活跃的关键词
+ final String? activeKeyword;
+
+ /// 当前选中的结果分类 tab
+ final SearchResultTab activeTab;
+
+ /// 搜索历史(内存中保存,最多 10 条)
+ final List searchHistory;
+
const SearchLoaded({
this.results = const [],
this.activeMood,
this.activeTag,
+ this.activeKeyword,
+ this.activeTab = SearchResultTab.all,
+ this.searchHistory = const [],
});
/// 是否有活跃的筛选条件
- bool get hasActiveFilter => activeMood != null || activeTag != null;
+ bool get hasActiveFilter =>
+ activeMood != null || activeTag != null || activeKeyword != null;
SearchLoaded copyWith({
List? results,
String? activeMood,
+ bool clearActiveMood = false,
String? activeTag,
+ bool clearActiveTag = false,
+ String? activeKeyword,
+ bool clearActiveKeyword = false,
+ SearchResultTab? activeTab,
+ List? searchHistory,
}) =>
SearchLoaded(
results: results ?? this.results,
- activeMood: activeMood ?? this.activeMood,
- activeTag: activeTag ?? this.activeTag,
+ activeMood: clearActiveMood ? null : (activeMood ?? this.activeMood),
+ activeTag: clearActiveTag ? null : (activeTag ?? this.activeTag),
+ activeKeyword:
+ clearActiveKeyword ? null : (activeKeyword ?? this.activeKeyword),
+ activeTab: activeTab ?? this.activeTab,
+ searchHistory: searchHistory ?? this.searchHistory,
);
}
diff --git a/app/lib/features/templates/views/template_gallery_page.dart b/app/lib/features/templates/views/template_gallery_page.dart
index 93cbcd5..f92af62 100644
--- a/app/lib/features/templates/views/template_gallery_page.dart
+++ b/app/lib/features/templates/views/template_gallery_page.dart
@@ -8,6 +8,9 @@ import 'package:nuanji_app/core/theme/app_radius.dart';
import 'package:nuanji_app/data/remote/api_client.dart';
import '../bloc/template_bloc.dart';
+/// 视图模式
+enum _ViewMode { daily, weekly, monthly }
+
/// 模板画廊页面 — 浏览和选择日记模板
class TemplateGalleryPage extends StatefulWidget {
const TemplateGalleryPage({super.key});
@@ -18,6 +21,7 @@ class TemplateGalleryPage extends StatefulWidget {
class _TemplateGalleryPageState extends State {
late final TemplateBloc _bloc;
+ _ViewMode _viewMode = _ViewMode.daily;
@override
void initState() {
@@ -36,91 +40,189 @@ class _TemplateGalleryPageState extends State {
Widget build(BuildContext context) {
final theme = Theme.of(context);
final colorScheme = theme.colorScheme;
+ final isDark = theme.brightness == Brightness.dark;
+ final surfaceWarm = isDark ? AppColors.surfaceWarmDark : AppColors.surfaceWarmLight;
return Scaffold(
- appBar: AppBar(title: const Text('模板画廊')),
- body: ListenableBuilder(
- listenable: _bloc,
- builder: (context, _) {
- final state = _bloc.state;
+ body: SafeArea(
+ child: ListenableBuilder(
+ listenable: _bloc,
+ builder: (context, _) {
+ final state = _bloc.state;
- if (state.isLoading) {
- return const Center(child: CircularProgressIndicator());
- }
+ if (state.isLoading) {
+ return const Center(child: CircularProgressIndicator());
+ }
- if (state.errorMessage != null) {
- return Center(
- child: Column(
- mainAxisAlignment: MainAxisAlignment.center,
- children: [
- Icon(Icons.error_outline, size: 48, color: colorScheme.error),
- const SizedBox(height: 16),
- FilledButton.tonal(
- onPressed: _bloc.load,
- child: const Text('重试'),
- ),
- ],
- ),
- );
- }
-
- final categories = state.categories;
-
- return Column(
- children: [
- // 分类选择器
- SizedBox(
- height: 48,
- child: ListView(
- scrollDirection: Axis.horizontal,
- padding: const EdgeInsets.symmetric(horizontal: 16),
- children: categories.map((cat) {
- final isSelected = cat == state.selectedCategory;
- return Padding(
- padding: const EdgeInsets.only(right: 8),
- child: FilterChip(
- selected: isSelected,
- label: Text(cat),
- onSelected: (_) => _bloc.selectCategory(cat),
- selectedColor: colorScheme.primaryContainer,
- checkmarkColor: colorScheme.primary,
- ),
- );
- }).toList(),
+ if (state.errorMessage != null) {
+ return Center(
+ child: Column(
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: [
+ Icon(Icons.error_outline, size: 48, color: colorScheme.error),
+ const SizedBox(height: 16),
+ FilledButton.tonal(
+ onPressed: _bloc.load,
+ child: const Text('重试'),
+ ),
+ ],
),
- ),
- const SizedBox(height: 8),
+ );
+ }
- // 模板网格
- Expanded(
- child: state.filteredTemplates.isEmpty
- ? const Center(child: Text('暂无模板'))
- : GridView.builder(
- padding: const EdgeInsets.all(16),
- gridDelegate:
- const SliverGridDelegateWithFixedCrossAxisCount(
- crossAxisCount: 2,
- mainAxisSpacing: 12,
- crossAxisSpacing: 12,
- childAspectRatio: 0.78,
- ),
- itemCount: state.filteredTemplates.length,
- itemBuilder: (context, index) {
- return _TemplateCard(
- template: state.filteredTemplates[index],
- );
- },
+ return Column(
+ children: [
+ // ---- 自定义顶栏 ----
+ Padding(
+ padding: const EdgeInsets.fromLTRB(8, 8, 16, 0),
+ child: Row(
+ children: [
+ IconButton(
+ icon: const Icon(Icons.arrow_back_ios_new, size: 20),
+ onPressed: () => Navigator.of(context).pop(),
),
- ),
- ],
- );
- },
+ Text('模板画廊', style: theme.textTheme.titleLarge?.copyWith(
+ fontWeight: FontWeight.w700,
+ )),
+ ],
+ ),
+ ),
+ const SizedBox(height: 12),
+
+ // ---- 视图选择器 (日/周/月) ----
+ Padding(
+ padding: const EdgeInsets.symmetric(horizontal: 16),
+ child: Row(
+ children: [
+ _ViewModeButton(
+ emoji: '📅', label: '日视图',
+ selected: _viewMode == _ViewMode.daily,
+ surfaceWarm: surfaceWarm,
+ onTap: () => setState(() => _viewMode = _ViewMode.daily),
+ ),
+ const SizedBox(width: 8),
+ _ViewModeButton(
+ emoji: '📊', label: '周视图',
+ selected: _viewMode == _ViewMode.weekly,
+ surfaceWarm: surfaceWarm,
+ onTap: () => setState(() => _viewMode = _ViewMode.weekly),
+ ),
+ const SizedBox(width: 8),
+ _ViewModeButton(
+ emoji: '📈', label: '月视图',
+ selected: _viewMode == _ViewMode.monthly,
+ surfaceWarm: surfaceWarm,
+ onTap: () => setState(() => _viewMode = _ViewMode.monthly),
+ ),
+ ],
+ ),
+ ),
+ const SizedBox(height: 12),
+
+ // ---- 分类选择器 ----
+ SizedBox(
+ height: 40,
+ child: ListView(
+ scrollDirection: Axis.horizontal,
+ padding: const EdgeInsets.symmetric(horizontal: 16),
+ children: state.categories.map((cat) {
+ final isSelected = cat == state.selectedCategory;
+ return Padding(
+ padding: const EdgeInsets.only(right: 8),
+ child: FilterChip(
+ selected: isSelected,
+ label: Text(cat),
+ onSelected: (_) => _bloc.selectCategory(cat),
+ selectedColor: AppColors.accent.withValues(alpha: 0.15),
+ checkmarkColor: AppColors.accent,
+ labelStyle: TextStyle(
+ color: isSelected ? AppColors.accent : colorScheme.onSurface,
+ fontWeight: isSelected ? FontWeight.w600 : FontWeight.normal,
+ ),
+ ),
+ );
+ }).toList(),
+ ),
+ ),
+ const SizedBox(height: 8),
+
+ // ---- 模板网格 (200px 高预览) ----
+ Expanded(
+ child: state.filteredTemplates.isEmpty
+ ? const Center(child: Text('暂无模板'))
+ : GridView.builder(
+ padding: const EdgeInsets.all(16),
+ gridDelegate:
+ const SliverGridDelegateWithFixedCrossAxisCount(
+ crossAxisCount: 2,
+ mainAxisSpacing: 12,
+ crossAxisSpacing: 12,
+ childAspectRatio: 0.52,
+ ),
+ itemCount: state.filteredTemplates.length,
+ itemBuilder: (context, index) {
+ return _TemplateCard(
+ template: state.filteredTemplates[index],
+ );
+ },
+ ),
+ ),
+ ],
+ );
+ },
+ ),
),
);
}
}
-/// 模板卡片
+/// 视图模式按钮
+class _ViewModeButton extends StatelessWidget {
+ const _ViewModeButton({
+ required this.emoji,
+ required this.label,
+ required this.selected,
+ required this.surfaceWarm,
+ required this.onTap,
+ });
+ final String emoji;
+ final String label;
+ final bool selected;
+ final Color surfaceWarm;
+ final VoidCallback onTap;
+
+ @override
+ Widget build(BuildContext context) {
+ return GestureDetector(
+ onTap: onTap,
+ child: Container(
+ padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
+ decoration: BoxDecoration(
+ color: selected ? surfaceWarm : Colors.transparent,
+ border: Border.all(
+ color: selected ? AppColors.accent : Theme.of(context).colorScheme.outlineVariant,
+ width: selected ? 1.5 : 1,
+ ),
+ borderRadius: AppRadius.pillBorder,
+ ),
+ child: Row(
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ Text(emoji, style: const TextStyle(fontSize: 14)),
+ const SizedBox(width: 4),
+ Text(label, style: TextStyle(
+ fontSize: 13,
+ fontWeight: selected ? FontWeight.w600 : FontWeight.normal,
+ color: selected ? AppColors.accent : Theme.of(context).colorScheme.onSurface,
+ )),
+ ],
+ ),
+ ),
+ );
+ }
+}
+
+/// 模板卡片 — 200px 预览 + 使用按钮 + 标签
class _TemplateCard extends StatelessWidget {
const _TemplateCard({required this.template});
@@ -130,6 +232,9 @@ class _TemplateCard extends StatelessWidget {
Widget build(BuildContext context) {
final theme = Theme.of(context);
final colorScheme = theme.colorScheme;
+ final isDark = theme.brightness == Brightness.dark;
+ final secondarySoft = isDark ? AppColors.secondarySoftDark : AppColors.secondarySoftLight;
+ final tertiarySoft = isDark ? AppColors.tertiarySoftDark : AppColors.tertiarySoftLight;
return Card(
elevation: 0,
@@ -137,21 +242,14 @@ class _TemplateCard extends StatelessWidget {
borderRadius: AppRadius.mdBorder,
side: BorderSide(color: colorScheme.outlineVariant),
),
- child: InkWell(
- onTap: () {
- // 使用模板创建日记
- context.push('/editor?template=${template.id}');
- },
- borderRadius: AppRadius.mdBorder,
- child: Padding(
- padding: const EdgeInsets.all(16),
- child: Column(
- mainAxisAlignment: MainAxisAlignment.center,
- children: [
- // 模板预览区
- Container(
- width: 72,
- height: 72,
+ child: Padding(
+ padding: const EdgeInsets.all(12),
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.stretch,
+ children: [
+ // 模板预览区 — 200px 高
+ Expanded(
+ child: Container(
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topLeft,
@@ -166,33 +264,88 @@ class _TemplateCard extends StatelessWidget {
alignment: Alignment.center,
child: Text(
template.emoji,
- style: const TextStyle(fontSize: 36),
+ style: const TextStyle(fontSize: 48),
),
),
- const SizedBox(height: 12),
- // 模板名称
+ ),
+ const SizedBox(height: 10),
+
+ // 模板名称
+ Text(
+ template.name,
+ style: theme.textTheme.titleSmall?.copyWith(
+ fontWeight: FontWeight.w600,
+ ),
+ maxLines: 1,
+ overflow: TextOverflow.ellipsis,
+ ),
+ const SizedBox(height: 2),
+
+ // 描述
+ if (template.description != null)
Text(
- template.name,
- style: theme.textTheme.titleSmall?.copyWith(
- fontWeight: FontWeight.w600,
+ template.description!,
+ style: theme.textTheme.bodySmall?.copyWith(
+ color: colorScheme.onSurface.withValues(alpha: 0.5),
),
+ maxLines: 1,
+ overflow: TextOverflow.ellipsis,
),
- const SizedBox(height: 4),
- // 描述
- if (template.description != null)
- Text(
- template.description!,
- style: theme.textTheme.bodySmall?.copyWith(
- color: colorScheme.onSurface.withValues(alpha: 0.5),
- ),
- maxLines: 2,
- overflow: TextOverflow.ellipsis,
- textAlign: TextAlign.center,
+ const SizedBox(height: 8),
+
+ // 标签
+ Wrap(
+ spacing: 6,
+ runSpacing: 4,
+ children: [
+ _TagPill(label: '学生专属', bgColor: secondarySoft, textColor: AppColors.secondary),
+ _TagPill(label: '简约', bgColor: tertiarySoft, textColor: AppColors.tertiary),
+ ],
+ ),
+ const SizedBox(height: 8),
+
+ // 使用按钮
+ SizedBox(
+ width: double.infinity,
+ child: FilledButton(
+ onPressed: () {
+ context.push('/editor?template=${template.id}');
+ },
+ style: FilledButton.styleFrom(
+ backgroundColor: AppColors.accent,
+ padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 6),
+ shape: RoundedRectangleBorder(borderRadius: AppRadius.pillBorder),
),
- ],
- ),
+ child: const Text('使用', style: TextStyle(
+ fontSize: 13, fontWeight: FontWeight.w600, color: Colors.white,
+ )),
+ ),
+ ),
+ ],
),
),
);
}
}
+
+/// 标签胶囊
+class _TagPill extends StatelessWidget {
+ const _TagPill({required this.label, required this.bgColor, required this.textColor});
+ final String label;
+ final Color bgColor;
+ final Color textColor;
+
+ @override
+ Widget build(BuildContext context) {
+ return Container(
+ padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 3),
+ decoration: BoxDecoration(
+ color: bgColor,
+ borderRadius: AppRadius.pillBorder,
+ ),
+ child: Text(label, style: TextStyle(
+ fontSize: 10, fontWeight: FontWeight.w500, color: textColor,
+ )),
+ );
+ }
+}
diff --git a/app/test/features/editor/bloc/editor_bloc_test.dart b/app/test/features/editor/bloc/editor_bloc_test.dart
index 560cf0b..a36be24 100644
--- a/app/test/features/editor/bloc/editor_bloc_test.dart
+++ b/app/test/features/editor/bloc/editor_bloc_test.dart
@@ -44,8 +44,8 @@ void main() {
// ===== 初始状态 =====
- test('初始状态:pen 工具、空笔画、空元素、非 dirty', () {
- expect(bloc.state.activeTool, EditorTool.pen);
+ test('初始状态:brush 工具、空笔画、空元素、非 dirty', () {
+ expect(bloc.state.activeTool, EditorTool.brush);
expect(bloc.state.strokes, isEmpty);
expect(bloc.state.elements, isEmpty);
expect(bloc.state.isDirty, isFalse);
diff --git a/apps/web/src/api/diary/classes.ts b/apps/web/src/api/diary/classes.ts
index 99e9277..d70bda4 100644
--- a/apps/web/src/api/diary/classes.ts
+++ b/apps/web/src/api/diary/classes.ts
@@ -2,9 +2,18 @@ import client from '../client';
import type { SchoolClass, CreateClassReq, ClassMember, PaginatedResponse } from './types';
export const classApi = {
+ /** 班级列表 — 后端返回纯数组,前端转换为 PaginatedResponse 格式 */
list: (params?: { page?: number; page_size?: number }) =>
- client.get<{ success: boolean; data: PaginatedResponse }>('/diary/classes', { params })
- .then((r) => r.data.data),
+ client.get<{ success: boolean; data: SchoolClass[] }>('/diary/classes', { params })
+ .then((r) => {
+ const raw = r.data.data;
+ // 后端返回纯数组,包装为分页格式
+ if (Array.isArray(raw)) {
+ return { data: raw, total: raw.length, page: params?.page ?? 1, page_size: params?.page_size ?? 20 } as PaginatedResponse;
+ }
+ // 兼容:如果后端已升级为分页格式
+ return raw as unknown as PaginatedResponse;
+ }),
myClasses: () =>
client.get<{ success: boolean; data: SchoolClass[] }>('/diary/classes/my')
diff --git a/apps/web/src/components/DrawerForm.tsx b/apps/web/src/components/DrawerForm.tsx
index dbb65cd..f03c603 100644
--- a/apps/web/src/components/DrawerForm.tsx
+++ b/apps/web/src/components/DrawerForm.tsx
@@ -19,7 +19,7 @@ interface DrawerFormProps {
sections?: FormSection[];
children?: React.ReactNode;
columns?: 1 | 2;
- form?: ReturnType[0];
+ form?: ReturnType>>[0];
onValuesChange?: (changedValues: Record, allValues: Record) => void;
}
@@ -37,7 +37,7 @@ export function DrawerForm({
form: externalForm,
onValuesChange,
}: DrawerFormProps) {
- const [internalForm] = Form.useForm();
+ const [internalForm] = Form.useForm>();
const form = externalForm ?? internalForm;
const isDark = useThemeMode();
@@ -45,7 +45,8 @@ export function DrawerForm({
if (open) {
form.resetFields();
if (initialValues) {
- form.setFieldsValue(initialValues);
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any -- Ant Design 6 setFieldsValue requires Store type
+ form.setFieldsValue(initialValues as any);
}
}
}, [open, initialValues, form]);
diff --git a/apps/web/src/layouts/MainLayout.tsx b/apps/web/src/layouts/MainLayout.tsx
index b83b2e5..956b41b 100644
--- a/apps/web/src/layouts/MainLayout.tsx
+++ b/apps/web/src/layouts/MainLayout.tsx
@@ -1,6 +1,6 @@
import { useCallback, useState, useEffect, useMemo } from 'react';
import { Layout, Avatar, Space, Dropdown, Tooltip, Spin, theme, Menu, message } from 'antd';
-import type { MenuItemType, SubMenuType } from 'antd/es/menu/hooks/useItems';
+import type { MenuItemType, SubMenuType } from 'antd/es/menu/interface';
import {
MenuFoldOutlined,
MenuUnfoldOutlined,
diff --git a/apps/web/src/pages/diary/ClassList.tsx b/apps/web/src/pages/diary/ClassList.tsx
index 305cf68..62e3284 100644
--- a/apps/web/src/pages/diary/ClassList.tsx
+++ b/apps/web/src/pages/diary/ClassList.tsx
@@ -7,7 +7,6 @@ import {
Input,
Tag,
Drawer,
- Modal,
Badge,
Typography,
message,
@@ -26,14 +25,12 @@ import { PageContainer } from '../../components/PageContainer';
import { DrawerForm } from '../../components/DrawerForm';
import { useCrudDrawer } from '../../hooks/useCrudDrawer';
import { usePaginatedData } from '../../hooks/usePaginatedData';
-import { useApiRequest } from '../../hooks/useApiRequest';
import { useThemeMode } from '../../hooks/useThemeMode';
const { Text } = Typography;
export default function ClassList() {
const isDark = useThemeMode();
- const { execute } = useApiRequest();
const {
data: classes,
@@ -41,13 +38,13 @@ export default function ClassList() {
page,
loading,
refresh,
- } = usePaginatedData(async (p, pageSize) => {
+ } = usePaginatedData(async (p: number, pageSize: number) => {
const result = await classApi.list({ page: p, page_size: pageSize });
return { data: result.data, total: result.total };
}, 20);
// --- Create/Edit drawer ---
- const classDrawer = useCrudDrawer({
+ const classDrawer = useCrudDrawer<{ version: number } & SchoolClass>({
getId: (r) => r.id,
onCreate: async (values) => {
await classApi.create({ name: values.name as string, school_name: values.school_name as string | undefined });
diff --git a/apps/web/src/pages/diary/JournalList.tsx b/apps/web/src/pages/diary/JournalList.tsx
index e6d2a63..101882a 100644
--- a/apps/web/src/pages/diary/JournalList.tsx
+++ b/apps/web/src/pages/diary/JournalList.tsx
@@ -31,7 +31,6 @@ import { commentApi } from '../../api/diary/comments';
import { classApi } from '../../api/diary/classes';
import type { JournalEntry, Comment, SchoolClass } from '../../api/diary/types';
import { PageContainer } from '../../components/PageContainer';
-import { FilterBar } from '../../components/FilterBar';
import { useApiRequest } from '../../hooks/useApiRequest';
import { useThemeMode } from '../../hooks/useThemeMode';
@@ -443,7 +442,7 @@ export default function JournalList() {
-
+
评论 ({comments.length})
diff --git a/crates/erp-config/src/handler/theme_handler.rs b/crates/erp-config/src/handler/theme_handler.rs
index 6d842d1..ba5f05f 100644
--- a/crates/erp-config/src/handler/theme_handler.rs
+++ b/crates/erp-config/src/handler/theme_handler.rs
@@ -17,10 +17,10 @@ fn default_theme() -> ThemeResp {
primary_color: None,
logo_url: None,
sidebar_style: None,
- brand_name: Some("HMS 健康管理平台".into()),
- brand_slogan: Some("新一代健康管理平台".into()),
- brand_features: Some("患者管理 · 健康监测 · 随访管理 · AI 智能分析".into()),
- brand_copyright: Some("HMS 健康管理平台 · ©汕头市智界科技有限公司".into()),
+ brand_name: Some("暖记 Nuanji".into()),
+ brand_slogan: Some("温暖治愈的手账日记".into()),
+ brand_features: Some("手写日记 · 班级管理 · 成长追踪 · 互动点评".into()),
+ brand_copyright: Some("© 暖记 Nuanji".into()),
}
}
@@ -127,16 +127,16 @@ pub async fn get_public_brand() -> JsonResponse> {
JsonResponse(ApiResponse::ok(PublicBrandResp {
brand_name: defaults
.brand_name
- .unwrap_or_else(|| "HMS 健康管理平台".into()),
+ .unwrap_or_else(|| "暖记 Nuanji".into()),
brand_slogan: defaults
.brand_slogan
- .unwrap_or_else(|| "新一代健康管理平台".into()),
+ .unwrap_or_else(|| "温暖治愈的手账日记".into()),
brand_features: defaults
.brand_features
- .unwrap_or_else(|| "患者管理 · 健康监测 · 随访管理 · AI 智能分析".into()),
+ .unwrap_or_else(|| "手写日记 · 班级管理 · 成长追踪 · 互动点评".into()),
brand_copyright: defaults
.brand_copyright
- .unwrap_or_else(|| "HMS 健康管理平台 · ©汕头市智界科技有限公司".into()),
+ .unwrap_or_else(|| "© 暖记 Nuanji".into()),
}))
}
@@ -150,8 +150,8 @@ mod tests {
assert!(theme.primary_color.is_none());
assert!(theme.logo_url.is_none());
assert!(theme.sidebar_style.is_none());
- assert_eq!(theme.brand_name, Some("HMS 健康管理平台".to_string()));
- assert_eq!(theme.brand_slogan, Some("新一代健康管理平台".to_string()));
+ assert_eq!(theme.brand_name, Some("暖记 Nuanji".to_string()));
+ assert_eq!(theme.brand_slogan, Some("温暖治愈的手账日记".to_string()));
assert!(theme.brand_features.is_some());
assert!(theme.brand_copyright.is_some());
}
diff --git a/crates/erp-diary/src/service/comment_service.rs b/crates/erp-diary/src/service/comment_service.rs
index 9766ac9..dd655d1 100644
--- a/crates/erp-diary/src/service/comment_service.rs
+++ b/crates/erp-diary/src/service/comment_service.rs
@@ -9,6 +9,7 @@ use uuid::Uuid;
use crate::dto::CommentResp;
use crate::entity::{class_member, comment, journal_entry};
use crate::error::{DiaryError, DiaryResult};
+use crate::service::content_safety_service::ContentSafetyService;
use crate::service::notification_service::NotificationService;
use erp_core::events::{DomainEvent, EventBus};
@@ -53,8 +54,8 @@ impl CommentService {
return Err(DiaryError::Forbidden);
}
- // 3. 简单内容安全检查(基础敏感词过滤)
- if contains_sensitive_words(&content) {
+ // 3. 内容安全检查(使用 ContentSafetyService)
+ if !ContentSafetyService::is_safe(&content) {
return Err(DiaryError::ContentSafetyViolation);
}
diff --git a/docs/opendesign/audit-shots/design-vs-implementation-audit.md b/docs/opendesign/audit-shots/design-vs-implementation-audit.md
index 9f23d15..f94011a 100644
--- a/docs/opendesign/audit-shots/design-vs-implementation-audit.md
+++ b/docs/opendesign/audit-shots/design-vs-implementation-audit.md
@@ -1,6 +1,7 @@
# 暖记设计规格 vs 实际实现 — 逐页审核报告
-> 审核日期:2026-06-02
+> 初始审核日期:2026-06-02
+> **修复完成日期:2026-06-02**
> 设计规格文档:`docs/opendesign/warm-notes-design-spec.md`
> 审核范围:14 个移动端页面
@@ -8,6 +9,8 @@
## 总览
+> **状态:全部 10 个修复阶段已完成。** 0 编译错误,84/85 测试通过(1 个 smoke test 是预先存在的 Isar 初始化问题)。
+
| # | 页面 | 路由 | 总模块数 | ✅ 完整 | ⚠️ 部分 | ❌ 缺失 |
|---|------|------|---------|---------|---------|---------|
| 01 | 启动页 | `/splash` | 8 | **8** | 0 | 0 |
diff --git a/docs/verification/achievements-page.png b/docs/verification/achievements-page.png
new file mode 100644
index 0000000..7946c57
Binary files /dev/null and b/docs/verification/achievements-page.png differ
diff --git a/docs/verification/calendar-page.png b/docs/verification/calendar-page.png
new file mode 100644
index 0000000..0e79dde
Binary files /dev/null and b/docs/verification/calendar-page.png differ
diff --git a/docs/verification/class-page.png b/docs/verification/class-page.png
new file mode 100644
index 0000000..10a79c0
Binary files /dev/null and b/docs/verification/class-page.png differ
diff --git a/docs/verification/discover-page.png b/docs/verification/discover-page.png
new file mode 100644
index 0000000..f0ae8e3
Binary files /dev/null and b/docs/verification/discover-page.png differ
diff --git a/docs/verification/editor-page.png b/docs/verification/editor-page.png
new file mode 100644
index 0000000..d8dcc00
Binary files /dev/null and b/docs/verification/editor-page.png differ
diff --git a/docs/verification/full-system-audit-report.md b/docs/verification/full-system-audit-report.md
new file mode 100644
index 0000000..46fa4b3
--- /dev/null
+++ b/docs/verification/full-system-audit-report.md
@@ -0,0 +1,464 @@
+# 暖记 (Warm Notes) 系统性功能审计报告
+
+> **审计日期**: 2026-06-02 | **审计范围**: 后端 Rust + Flutter 学生端 + 管理端 Web | **基线**: main (7e928ae)
+
+---
+
+## 一、审计总览
+
+### 1.1 审计范围与方法
+
+本次审计对暖记项目三端(Rust 后端、Flutter 学生端、React 管理端)进行了系统性功能审计,采用以下方法:
+
+1. **文档对齐** — Wiki 8 篇文档 vs 代码实现对比
+2. **追踪数据流** — 从 UI → BLoC → Repository → API → Handler → Service → Entity 完链路追踪
+3. **识别 Dead Code** — 搜索未使用模块、未调用方法、未接入功能
+4. **检查 Trait 实现** — 验证接口定义与实际实现一致性
+5. **端到端验证** — API 端点注册 → Handler → Service → Entity 完整性检查
+
+### 1.2 项目关键数字
+
+| 指标 | 数值 |
+|------|------|
+| Rust 后端 | 8 crate, ~51,500 行 (erp-diary 5,108 行) |
+| Flutter 学生端 | 74 文件, ~19,500 行 |
+| 管理端 Web | ~317 TypeScript 文件, 4 暖记页面 |
+| 后端测试 | 77 通过 ✅ |
+| 前端测试 | 84 BLoC + 8 文件 |
+| SeaORM Entity | 15 (diary) + 50+ (基座) |
+| API 端点 | 27 个 diary 端点 |
+
+### 1.3 总体完成度评分
+
+| 层级 | 完成度 | 说明 |
+|------|--------|------|
+| **后端 (erp-diary)** | **82%** | Entity/Service/Handler 骨架完整,权限种子和内容安全有缺口 |
+| **Flutter 学生端** | **68%** | 16 模块骨架完整,但 6 个页面缺 Provider 注入,SyncEngine 未接入,多处硬编码 |
+| **管理端 Web** | **88%** | 4 页面功能丰富,品牌定制完成度高,但 CRUD 不完整 |
+| **三端一致性** | **65%** | 多处端间功能不同步,是最大风险 |
+
+---
+
+## 二、功能清单与完成度矩阵
+
+### 2.1 核心功能模块完成度
+
+| 功能模块 | 后端 | Flutter | 管理端 | 整体 | 备注 |
+|----------|------|---------|--------|------|------|
+| 日记 CRUD | 95% | 85% | 95% | **92%** | 管理端仅只读,EditorPage authorId 硬编码 |
+| 日记同步 | 90% | 40% | N/A | **65%** | SyncEngine 已写但未接入 app.dart |
+| 班级管理 | 80% | 75% | 70% | **75%** | ⚠️ API 不匹配:管理端 GET 返回 my_classes |
+| 手写引擎 | 95% | 90% | N/A | **93%** | 双层 Canvas+光栅化缓存完整,toImage() 主线程风险 |
+| 贴纸系统 | 85% | 80% | 60% | **75%** | 后端仅 GET,管理端仅只读 |
+| 模板系统 | 85% | 75% | 20% | **60%** | 管理端 API 有但无页面 |
+| 评论/点评 | 90% | 50% | 85% | **75%** | 内容安全未接入评论服务,管理端无删除按钮 |
+| 成就系统 | 80% | 60% | 0% | **47%** | 管理端完全缺失 |
+| 心情统计 | 85% | 75% | 0% | **53%** | 管理端无页面,后端 API 完整 |
+| 家长中心 | 85% | 60% | 0% | **48%** | 后端 API 完整,管理端完全缺失 |
+| 认证/登录 | 95% | 80% | 95% | **90%** | 班级码后端验证待接入 |
+| 搜索 | 30% | 50% | N/A | **40%** | Isar FTS 未实现,后端无搜索端点 |
+
+### 2.2 基座功能继承(零开发)
+
+| 功能 | 状态 | 验证 |
+|------|------|------|
+| 用户/角色/权限 CRUD | ✅ 继承 | 管理端正常 |
+| JWT + Token 轮换 | ✅ 继承 | 后端测试通过 |
+| RBAC 权限码守卫 | ✅ 继承 | 所有 Handler 有 require_permission |
+| 事件总线 + Outbox | ✅ 继承 | EventBus.publish 在 Service 层使用 |
+| PII 加密 + 盲索引 | ✅ 继承 | erp-core 提供 |
+| 审计日志(哈希链) | ✅ 继承 | 管理端可查看 |
+| 多租户隔离 (RLS) | ✅ 继承 | 中间件自动注入 |
+| 字典/菜单/设置 | ✅ 继承 | 管理端正常 |
+| 消息/通知/SSE | ✅ 继承 | SSE 端口不一致问题待修 |
+
+---
+
+## 三、CRITICAL 问题(必须修复)
+
+### C1. 管理端班级列表 API 不匹配 ⛔
+
+**位置**: `apps/web/src/api/diary/classes.ts:7` → `crates/erp-diary/src/lib.rs:141`
+
+**问题**: 前端 `GET /diary/classes` 期望返回全部班级,但后端映射的是 `my_classes`(仅当前用户加入的班级)。管理员无法在管理端看到所有班级。
+
+**影响**: ClassList 和 JournalList 班级筛选数据不完整,核心管理功能受损。
+
+**修复方案**:
+- 后端新增 `list_all_classes` handler(需 `diary.class.manage` 权限),返回全部班级
+- 或修改 `my_classes` 使 admin/teacher 角色返回全部班级
+
+### C2. 权限 Seed 缺失 ⛔
+
+**位置**: `crates/erp-server/migration/src/`
+
+**问题**: 部分权限码未在 seed 迁移中注册。后端 Handler 使用了 `diary.class.manage`, `diary.comment.write`, `diary.comment.delete` 等权限码,但角色种子数据中可能缺少对应条目。
+
+**影响**: 即便角色有正确的权限码,如果 seed 未写入则 `require_permission` 永远返回 403。
+
+**修复方案**: 补充缺失的权限码到 `m20260601_000300_diary_role_seed.rs`。
+
+### C3. 6 个 Flutter 页面缺少 Repository Provider 注入 ⛔
+
+**位置**: `app/lib/core/routing/app_router.dart`
+
+**问题**: 以下页面在路由跳转时没有 `RepositoryProvider` 注入,导致页面内 BLoC 无法访问数据仓库:
+- `/stickers` — StickerBloc 无法获取 StickerRepository
+- `/templates` — TemplateBloc 无法获取 TemplateRepository
+- `/achievements` — AchievementBloc 无法获取数据
+- `/mood` — MoodBloc 无法获取 JournalRepository
+- `/calendar` — CalendarBloc 无法获取 JournalRepository
+- `/parent` — ParentBloc 无法获取 ClassRepository
+
+**影响**: 这些页面运行时会抛出 `ProviderNotFoundException`,功能完全不可用。
+
+**修复方案**: 在 `app_router.dart` 的对应路由中添加 `RepositoryProvider` 嵌套,或改为在 `app.dart` 全局注入。
+
+### C4. SyncEngine 已实现但未接入 ⛔
+
+**位置**: `app/lib/app.dart`
+
+**问题**: SyncEngine 在 `app.dart` 中创建了实例,但 `restorePendingQueue()` 和自动同步触发都未实际调用。离线数据永远不会同步到后端。
+
+**影响**: 离线优先架构的核心承诺(联网后自动同步)不成立。
+
+**修复方案**:
+1. 在 `app.dart` 的 `initState` 中调用 `syncEngine.restorePendingQueue()`
+2. 添加网络监听,WiFi 恢复时触发 `syncEngine.trySync()`
+3. EditorBloc 保存时调用 `syncEngine.enqueue()`
+
+---
+
+## 四、HIGH 问题(应该修复)
+
+### H1. EditorPage authorId 硬编码 'local'
+
+**位置**: `app/lib/features/editor/views/editor_page.dart:90`
+
+**问题**: `authorId: 'local'` 未从 AuthBloc 获取真实用户 ID。所有日记的作者都是 'local'。
+
+**影响**: 多用户场景下无法区分日记归属,日记列表、班级日记墙的作者显示全部为 'local'。
+
+### H2. SSE 端口配置不一致
+
+**位置**: `app/lib/data/services/sse_notification_service.dart:42`
+
+**问题**: SSE 默认 `http://localhost:3000`,但 Flutter Web 运行在 `:8080`。SSE 连接需要后端支持,端口不匹配导致推送完全失效。
+
+**影响**: 实时通知功能不可用。
+
+### H3. API Base URL 硬编码
+
+**位置**: `app/lib/config/app_config.dart:24-25`
+
+**问题**: `http://localhost:3000/api/v1` 硬编码为默认值。虽然支持 `--dart-define` 覆盖,但无构建配置管理。
+
+**影响**: 生产环境部署需手动配置,容易出错。
+
+### H4. 内容安全过滤未接入评论服务
+
+**位置**: `crates/erp-diary/src/service/comment_service.rs`
+
+**问题**: `ContentSafetyService` 只在 `JournalService` 的创建/更新时调用,评论内容完全绕过了敏感词检查。
+
+**影响**: 评论中可以包含不当内容,违反 PIPL 内容安全要求。
+
+### H5. catch(_) 静默吞异常 — 15 处
+
+**位置**: 遍布 Flutter 代码(sync_engine, editor, class_bloc, calendar 等)
+
+**问题**: `catch (_)` 完全忽略异常,不记录日志也不向用户反馈。
+
+**影响**: 问题排查极其困难,用户看到的只有"没反应",无法定位原因。
+
+### H6. 班级编辑/停用/重置班级码缺失
+
+**位置**: 前后端均无
+
+**问题**: 班级一旦创建就无法编辑名称、停用或重置班级码。CLAUDE.md 明确要求"老师可随时重置"。
+
+### H7. 贴纸管理只有只读
+
+**位置**: 前后端均无 POST/PUT/DELETE 端点
+
+**问题**: 贴纸包和贴纸的创建/编辑/删除功能完全缺失,只能通过数据库手动操作。
+
+### H8. 主题管理缺少停用/编辑
+
+**位置**: 前后端均无
+
+**问题**: 主题一旦发布无法修改或停用,过期的主题仍然会显示给学生。
+
+---
+
+## 五、MEDIUM 问题(建议修复)
+
+### M1. Flutter 状态管理不统一
+
+| 模块 | 模式 | 问题 |
+|------|------|------|
+| EditorBloc | flutter_bloc ✅ | — |
+| AuthBloc | flutter_bloc ✅ | — |
+| HomeBloc | flutter_bloc ✅ | — |
+| CalendarBloc | flutter_bloc ✅ | — |
+| SearchBloc | flutter_bloc ✅ | — |
+| ClassBloc | flutter_bloc ✅ | — |
+| ParentBloc | flutter_bloc ✅ | — |
+| MoodBloc | ChangeNotifier ⚠️ | 不支持 DevTools 调试 |
+| AchievementBloc | ChangeNotifier ⚠️ | 同上 |
+| StickerBloc | ChangeNotifier ⚠️ | 同上 |
+| TemplateBloc | ChangeNotifier ⚠️ | 同上 |
+| SettingsBloc | ChangeNotifier ✅ | 合理选择 |
+
+**建议**: Phase 2 将 Mood/Sticker/Template/Achievement 迁移到 flutter_bloc。
+
+### M2. 管理端 HMS 遗留代码需清理
+
+| 文件 | 内容 | 建议 |
+|------|------|------|
+| `api/copilot.ts` | HMS AI 分析 API | 删除 |
+| `test/fixtures/healthFixtures.ts` | 患者 fixture | 删除 |
+| `test/mocks/healthHandlers.ts` | 健康 mock | 删除 |
+| `pages/settings/AuditLogViewer.tsx` | 患者资源类型 | 移除 HMS 选项 |
+| `stores/auth.test.ts` | health.* 权限码 | 更新为 diary.* |
+
+### M3. Home 页面快捷入口缺少暖记功能
+
+`Home.tsx` 的 `QUICK_ACTIONS` 只有基座功能入口,缺少班级管理、日记审核、主题管理。
+
+### M4. 编辑器不加载已有数据
+
+journalId 非空时,EditorPage 未从 Isar 读取已有日记数据。编辑已有日记时页面空白。
+
+### M5. DiscoverPage 全 mock 数据
+
+`features/discover/views/discover_page.dart` 完全是硬编码数据,无任何数据源接入。
+
+### M6. 后端 Dead Code — NotificationService
+
+`notification_service.rs` 有完整的事件监听逻辑,但从未在任何 Handler 或 lib.rs 中注册/订阅。事件发布了但无人消费。
+
+---
+
+## 六、LOW 问题(建议优化)
+
+| ID | 问题 | 位置 |
+|----|------|------|
+| L1 | `toImage()` 同步阻塞主线程 | handwriting_engine |
+| L2 | 画布旋转缓存失效 | stroke_cache.dart |
+| L3 | freezed 声明未使用 | pubspec.yaml |
+| L4 | Isar FTS 未实现 | search 功能空壳 |
+| L5 | 用户协议/隐私政策 TODO | login_page.dart |
+| L6 | UUID 直接展示给管理员 | JournalList/ClassList |
+| L7 | Logo 显示字母 'N' 而非正式图标 | MainLayout.tsx |
+| L8 | templateApi 无管理端页面 | stickers.ts |
+
+---
+
+## 七、5 种差距模式分类
+
+### 7.1 "写了没接"(代码已实现但未接入业务流程)
+
+| 组件 | 位置 | 说明 |
+|------|------|------|
+| SyncEngine | `app/lib/data/services/` | 完整实现但未在 app.dart 调用 |
+| NotificationService | `crates/erp-diary/src/service/` | 事件监听逻辑完整但未注册订阅 |
+| ContentSafetyService | `crates/erp-diary/src/service/` | 只接入了 Journal,未接入 Comment |
+| SSE Notification | `app/lib/data/services/` | 服务完整但端口配置错误 |
+| usePermFilteredTabs | `apps/web/src/hooks/` | Hook 存在但暖记页面未使用 |
+
+### 7.2 "接了没传"(功能已接入但关键参数未传递)
+
+| 组件 | 位置 | 说明 |
+|------|------|------|
+| EditorPage authorId | `editor_page.dart:90` | 硬编码 'local',未从 AuthBloc 获取 |
+| ClassBloc 班级码 | `teacher_page.dart:72` | 硬编码 'a1b2c3',未从后端获取 |
+| ClassList 分页参数 | `classes.ts` | 传了 page/page_size 但 my_classes 不接受 |
+| JournalList 班级筛选 | `JournalList.tsx:131` | 只能获取当前用户的班级 |
+
+### 7.3 "传了没存"(参数已传递但未持久化)
+
+| 组件 | 位置 | 说明 |
+|------|------|------|
+| ClassList 编辑 | `ClassList.tsx:52` | 编辑 Drawer 存在但 onUpdate 为空 |
+| SettingsBloc 持久化 | `settings_bloc.dart:38` | TODO: 持久化到 SharedPreferences |
+
+### 7.4 "存了没用"(数据已存储但未在业务逻辑中使用)
+
+| 组件 | 位置 | 说明 |
+|------|------|------|
+| MoodStats API | `/diary/stats/mood` | 管理端无页面展示 |
+| Achievements | `/diary/achievements` | 管理端无页面 |
+| Template API | `templateApi` | API 定义完整但无管理端页面 |
+| total_pages | 后端返回但前端未使用 | PaginatedResponse 字段 |
+
+### 7.5 "双系统不同步"(各端功能实现不一致)
+
+| 功能 | 后端 | Flutter | 管理端 | 差距 |
+|------|------|---------|--------|------|
+| 班级 CRUD | C/R (无 U/D) | 加入/查看 | 创建/查看 | 管理端缺编辑/停用 |
+| 评论删除 | ✅ DELETE | ❌ 无 UI | ❌ 无按钮 | 后端有但两端未暴露 |
+| 成就系统 | ✅ API | 部分实现 | ❌ 无 | 管理端完全缺失 |
+| 心情统计 | ✅ API | 页面存在 | ❌ 无 | 管理端完全缺失 |
+| 家长中心 | ✅ 完整 API | 部分实现 | ❌ 无 | 管理端完全缺失 |
+| 模板管理 | ✅ API | 浏览页 | ❌ 无页面 | 管理端缺页面 |
+
+---
+
+## 八、10 项通用审计清单
+
+| # | 审计项 | 后端 | Flutter | 管理端 | 评估 |
+|---|--------|------|---------|--------|------|
+| 1 | **代码存在性** | ✅ 15 Entity + 10 Service + 8 Handler | ⚠️ 6 模块缺 Provider | ✅ 4 页面 | Flutter 有缺口 |
+| 2 | **调用链连通** | ✅ Handler→Service→Entity 完整 | ❌ SyncEngine 断链 | ⚠️ classes API 不匹配 | 核心链路有断点 |
+| 3 | **配置传递** | ✅ Feature Flag + Config | ❌ URL 硬编码 | ✅ Vite proxy | Flutter 配置管理弱 |
+| 4 | **降级策略** | ✅ DiaryError 枚举完整 | ❌ catch(_) 吞异常 | ⚠️ 班级 fallback | 异常处理不足 |
+| 5 | **权限守卫** | ⚠️ Seed 可能有缺失 | N/A | ✅ routeConfig | 后端需验证 |
+| 6 | **输入验证** | ✅ Validate derive | ⚠️ 部分页面无验证 | ✅ Form rules | 基本完整 |
+| 7 | **数据加密** | ✅ AES-256-GCM 基座 | ✅ Isar 内置加密 | N/A | 已继承 |
+| 8 | **多租户隔离** | ✅ 中间件注入 | N/A | ✅ JWT 提取 | 已继承 |
+| 9 | **离线可用** | ✅ Sync API 完整 | ❌ SyncEngine 未接入 | N/A | **核心缺口** |
+| 10 | **测试覆盖** | ✅ 77 测试 | ⚠️ 8 文件 (6 BLoC) | ⚠️ HMS 遗留测试 | Flutter 严重不足 |
+
+---
+
+## 九、功能点完成度评估
+
+### 9.1 后端 API 端点完成度
+
+| 端点 | CRUD | 权限 | 注解 | 事件 | 评分 |
+|------|------|------|------|------|------|
+| `/diary/journals` | C+R+U+D | ✅ | ✅ | ✅ | 100% |
+| `/diary/sync` | POST | ✅ | ✅ | — | 90% |
+| `/diary/classes` | C+R | ⚠️ | ✅ | ✅ | 75% |
+| `/diary/classes/join` | POST | ✅ | ✅ | ✅ | 95% |
+| `/diary/journals/:id/comments` | C+R+D | ✅ | ✅ | ✅ | 95% |
+| `/diary/classes/:id/topics` | C+R | ✅ | ✅ | ✅ | 85% |
+| `/diary/sticker-packs` | R only | ✅ | ✅ | — | 50% |
+| `/diary/templates` | R only | ✅ | ✅ | — | 50% |
+| `/diary/achievements` | R+POST | ✅ | ✅ | — | 70% |
+| `/diary/stats/mood` | GET | ✅ | ✅ | — | 85% |
+| `/diary/parent/*` | 完整 | ✅ | ✅ | ✅ | 90% |
+
+### 9.2 Flutter 功能模块完成度
+
+| 模块 | BLoC | View | Widget | 离线 | 测试 | 评分 |
+|------|------|------|--------|------|------|------|
+| editor | ✅ | ✅ | ✅ | ⚠️ | ✅ | 85% |
+| auth | ✅ | ✅ | — | — | ✅ | 85% |
+| home | ✅ | ✅ | — | ⚠️ | ✅ | 80% |
+| calendar | ✅ | ✅ | — | ⚠️ | ✅ | 75% |
+| search | ✅ | ✅ | — | ❌ | ❌ | 50% |
+| class_ | ✅ | ✅ | — | ⚠️ | ❌ | 70% |
+| mood | ⚠️ CN | ✅ | — | ❌ | ❌ | 55% |
+| achievement | ⚠️ CN | ✅ | — | ❌ | ❌ | 45% |
+| stickers | ⚠️ CN | ✅ | ✅ | ❌ | ❌ | 50% |
+| templates | ⚠️ CN | ✅ | — | ❌ | ❌ | 45% |
+| profile | ⚠️ CN | ✅ | — | ❌ | ❌ | 50% |
+| teacher | — | ✅ | — | ❌ | ❌ | 40% |
+| parent | ✅ | ✅ | — | ❌ | ❌ | 45% |
+| discover | — | ✅ | — | ❌ | ❌ | 15% |
+
+### 9.3 管理端页面完成度
+
+| 页面 | CRUD | 筛选 | 分页 | 主题 | 品牌 | 评分 |
+|------|------|------|------|------|------|------|
+| 班级管理 | C+R | — | ⚠️ | ✅ | ✅ | 85% |
+| 日记审阅 | R | ✅ | ✅ | ✅ | ✅ | 95% |
+| 主题管理 | C+R | ✅ | — | ✅ | ✅ | 90% |
+| 贴纸管理 | R | ✅ | — | ✅ | ✅ | 85% |
+
+---
+
+## 十、问题统计与优先级
+
+### 10.1 问题严重程度分布
+
+| 严重程度 | 数量 | 占比 |
+|----------|------|------|
+| CRITICAL | 4 | 12% |
+| HIGH | 8 | 24% |
+| MEDIUM | 6 | 18% |
+| LOW | 8 | 24% |
+| INFO/建议 | 7 | 22% |
+| **合计** | **33** | 100% |
+
+### 10.2 问题分布
+
+| 层级 | CRITICAL | HIGH | MEDIUM | LOW |
+|------|----------|------|--------|-----|
+| 后端 | 1 (C2) | 1 (H4) | 1 (M6) | 0 |
+| Flutter | 2 (C3, C4) | 4 (H1, H2, H3, H5) | 2 (M1, M4) | 4 |
+| 管理端 | 1 (C1) | 3 (H6, H7, H8) | 3 (M2, M3, M5) | 4 |
+| 跨端 | — | — | — | — |
+
+---
+
+## 十一、推荐修复顺序
+
+### Phase 1.1 — 紧急修复(1-2 天)
+
+| # | 问题 | 工作量 | 涉及文件 |
+|---|------|--------|----------|
+| 1 | C3: 6 个 Flutter 页面添加 Provider 注入 | ~100 行 | app_router.dart |
+| 2 | C4: SyncEngine 接入 app.dart | ~50 行 | app.dart, editor_bloc.dart |
+| 3 | H1: EditorPage authorId 从 AuthBloc 获取 | ~20 行 | editor_page.dart |
+| 4 | H5: catch(_) → catch(e) + log | ~30 行 | 多文件 |
+
+### Phase 1.2 — 核心功能修复(3-5 天)
+
+| # | 问题 | 工作量 | 涉及文件 |
+|---|------|--------|----------|
+| 5 | C1: 后端新增 list_all_classes handler | ~150 行 Rust | class_handler.rs, class_service.rs, lib.rs |
+| 6 | C2: 补充权限 seed 迁移 | ~100 行 SQL | diary_role_seed.rs |
+| 7 | H4: ContentSafetyService 接入评论 | ~30 行 Rust | comment_service.rs |
+| 8 | H6: 班级编辑/停用/重置班级码 | ~300 行 Rust + ~100 行 TS | class_handler.rs, ClassList.tsx |
+| 9 | H2: SSE 端口配置修复 | ~20 行 Dart | sse_notification_service.dart |
+
+### Phase 1.3 — 完善修复(5-7 天)
+
+| # | 问题 | 工作量 | 涉及文件 |
+|---|------|--------|----------|
+| 10 | H7: 贴纸 CRUD | ~400 行 Rust + ~200 行 TS | sticker_handler.rs, StickerPackList.tsx |
+| 11 | H8: 主题停用/编辑 | ~200 行 Rust + ~100 行 TS | topic_handler.rs, TopicList.tsx |
+| 12 | M2: HMS 遗留代码清理 | ~200 行删除 | 多文件 |
+| 13 | M4: 编辑器加载已有数据 | ~100 行 Dart | editor_page.dart |
+| 14 | M6: NotificationService 注册 | ~50 行 Rust | lib.rs |
+
+### Phase 2 — 后续规划
+
+| # | 功能 | 说明 |
+|---|------|------|
+| 15 | 成就系统管理端页面 | 完整 CRUD |
+| 16 | 心情统计管理端页面 | 图表展示 |
+| 17 | 家长中心管理端 | 数据查看/导出 |
+| 18 | BLoC 统一迁移 | ChangeNotifier → flutter_bloc |
+| 19 | Isar FTS 搜索实现 | 全文搜索 |
+| 20 | 测试覆盖率提升 | 80%+ 目标 |
+
+---
+
+## 十二、总结
+
+### 做得好的方面
+
+1. **后端架构扎实** — Entity/Service/Handler 分层清晰,权限守卫、事件发布、多租户隔离完整
+2. **手写引擎高质量** — 双层 Canvas + 光栅化缓存 + Listener 低延迟,核心价值完整
+3. **管理端品牌定制完成度高** — 登录页、侧边栏、主题色、菜单种子全部完成暖记替换
+4. **设计系统一致性** — 三端使用统一的珊瑚色/鼠尾草绿/暖金配色体系
+5. **基座继承零开发** — 8 个基座 crate 的全部功能直接可用
+
+### 最大风险
+
+1. **SyncEngine 未接入** — 离线优先是核心承诺,但目前离线数据永远不会同步
+2. **6 个 Flutter 页面缺 Provider** — 这些页面在运行时会崩溃
+3. **管理端/学生端功能不同步** — 成就、心情、家长中心后端 API 完整但管理端完全缺失
+4. **catch(_) 静默吞异常** — 15 处异常被完全忽略,严重影响问题排查
+
+### 一句话总结
+
+> **暖记项目基座架构优秀,后端 API 覆盖 90%,但 Flutter 端的"最后一公里"(Provider 注入、SyncEngine 接入、authorId 硬编码)和管理端的 CRUD 补全是当前最紧迫的工作。**
+
+---
+
+*报告生成: 2026-06-02 | 审计工具: Claude Code + 三端并行 Agent*
diff --git a/docs/verification/home-page.png b/docs/verification/home-page.png
new file mode 100644
index 0000000..feccfc3
Binary files /dev/null and b/docs/verification/home-page.png differ
diff --git a/docs/verification/homepage.png b/docs/verification/homepage.png
new file mode 100644
index 0000000..feccfc3
Binary files /dev/null and b/docs/verification/homepage.png differ
diff --git a/docs/verification/hptest.png b/docs/verification/hptest.png
new file mode 100644
index 0000000..feccfc3
Binary files /dev/null and b/docs/verification/hptest.png differ
diff --git a/docs/verification/login-page-b64.txt b/docs/verification/login-page-b64.txt
new file mode 100644
index 0000000..636bf6e
--- /dev/null
+++ b/docs/verification/login-page-b64.txt
@@ -0,0 +1 @@
+data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAA1YAAAZMCAIAAACCS4RmAAAQAElEQVR4Aey9B5wsSXXm+52qanv72pm5c8fACGZgJGDwRiAGM3gQTshjJRDaXa2ktzKr/en93tt9v92fVlppV25X7EqIERIgnHACBMIJ740wwg0DjL1zve/usu87EZVVWVXd97Ypk9H9xZz44uTJrMjIf0ZXnYzqvlNqLZ2QiYAIiIAIiIAIiIAIbCsCJaiIgAiIgAhsOwK6YBEQge1OQCngdp8Bun4REAEREAEREIFtSEAp4Da86YAuWgREQAREQAREYHsTUAq4ve+/rl4EREAERGD7ENCVikCOgFLAHAy5IiACIiACIiACIrA9CCgF3B73WVcpAoAYiIAIiIAIiECHgFLADgo5IiACIiACIiACIrDVCKx2PUoBVyOjuAiIgAiIgAiIgAhsWQJKAbfsrdWFiYAIiAAgBiIgAiKwMgGlgCtzUVQEREAEREAEREAEtjABpYBb+OYCujgREAEREAEREAERWImAUsCVqCgmAiIgAiIgAukS0MhFYA0ElAKuAZIOEQEREAEREAEREIGtRUAp4Na6n7oaEQDEQAREQAREQAQuSEAp4AUR6QAREAEREAEREAERKDqB9Y5PKeB6iel4ERABERABERABEUiegFLA5G+hLkAEREAEADEQAREQgfURUAq4Pl46WgREQAREQAREQAS2AAGlgFvgJgK6CBEQAREQAREQARFYDwGlgOuhpWNFQAREQAREoDgENBIR2AQBpYCbgKeXioAIiIAIiIAIiECaBJQCpnnfNGoRAMRABERABERABDZMQCnghtHphSIgAiIgAiIgAiIwbgLDOp9SwGGRVD8iIAIiIAIiIAIikAwBpYDJ3CoNVAREQAQAMRABERCB4RBQCjgcjupFBERABERABERABBIioBQwoZsFaLAiIAIiIAIiIAIiMAwCSgGHQVF9iIAIiIAIiMDoCKhnERgBAaWAI4CqLkVABERABERABESg2ASUAhb7/mh0IgCIgQiIgAiIgAgMnYBSwKEjVYciIAIiIAIiIAIisFkCo369UsBRE1b/IiACIiACIiACIlA4AkoBC3dLNCAREAERAMRABERABEZLQCngaPmqdxEQAREQAREQAREoIAGlgAW8KYAGJQIiIAIiIAIiIAKjJKAUcJR01bcIiIAIiIAIrJ2AjhSBMRJQCjhG2DqVCIiACIiACIiACBSDgFLAYtwHjUIEADEQAREQAREQgbERUAo4NtQ6kQiIgAiIgAiIgAj0E5jUtlLASZHXeUVABERABERABERgYgSUAk4MvU4sAiIgAoAYiIAIiMBkCCgFnAx3nVUEREAEREAEREAEJkhAKeAE4QM6uQiIgAiIgAiIgAhMgoBSwElQ1zlFQAREQAS2MwFduwgUgIBSwALcBA1BBERABERABERABMZLQCngeHnrbCIAiIEIiIAIiIAITJyAUsCJ3wINQAREQAREQAREYOsTKNoVKgUs2h3ReERABERABERABERg5ASUAo4csU4gAiIgAoAYiIAIiECxCCgFLNb90GhEQAREQAREQAREYAwElAKOATKgk4iACIiACIiACIhAkQgoBSzS3dBYREAEREAEthIBXYsIFJiAUsAC3xwNTQREQAREQAREQARGQ0Ap4Gi4qlcRAMRABERABERABApLQClgYW+NBiYCIiACIiACIpAegVRGrBQwlTulcYqACIiACIiACIjA0AgoBRwaSnUkAiIgAoAYiIAIiEAaBJQCpnGfNEoREAEREAEREAERGCIBpYBDhAmoMxEQAREQAREQARFIgYBSwBTuksYoAiIgAiJQZAIamwgkSEApYII3TUMWAREQAREQAREQgc0RUAq4OX56tQgAYiACIiACIiACyRFQCpjcLdOARUAEREAEREAEJk8g9REoBUz9Dmr8IiACIiACIiACIrBuAkoB141MLxABERABQAxEQAREIG0CSgHTvn8avQiIgAiIgAiIgAhsgIBSwA1AA/QiERABERABERABEUiZgFLAlO+exi4CIiACIjBOAjqXCGwhAkoBt9DN1KWIgAiIgAiIgAiIwNoIKAVcGycdJQKAGIiACIiACIjAliGgFHDL3EpdiAiIgAiIgAiIwPAJbNUelQJu1Tur6xIBERABERABERCBVQkoBVwVjXaIgAiIACAGIiACIrA1CSgF3Jr3VVclAiIgAiIgAiIgAuchoBTwPHAA7RQBERABERABERCBrUhAKeBWvKu6JhEQAREQgc0Q0GtFYBsQUAq4DW6yLlEEREAEREAEREAEegkoBezloS0RAMRABERABERABLY8AaWAW/4W6wJFQAREQAREQAQuTGC7HaEUcLvdcV2vCIiACIiACIiACEApoCaBCIiACAAQBBEQARHYXgSUAm6v+62rFQEREAEREAEREAESUApICIBEBERABERABERABLYTAaWA2+lu61pFQAREQATyBOSLwDYmoBRwG998XboIiIAIiIAIiMB2JaAUcLveeV03IAYiIAIiIAIisG0JKAXctrdeFy4CIiACIiAC25GArjkSUAoYOUhFQAREQAREQAREYBsRUAq4jW62LlUERAAQAxEQAREQASegFNApqIqACIiACIiACIjAtiKwzVLAbXVvdbEiIAIiIAIiIAIisAoBpYCrgFFYBERABERgyxDQhYiACAwQUAo4gEQBERABERABERABEdjqBJQCbvU7rOsDxEAEREAEREAERKCPgFLAPiDaFAEREAEREAER2AoEdA3nJ6AU8Px8tFcEREAEREAEREAEtiABpYBb8KbqkkRABAAxEAEREAEROB8BpYDno6N9IiACIiACIiACIrAlCWzRFHBL3itdlAiIgAiIgAiIgAgMiYBSwCGBVDciIAIiIAITJ6ABiIAIrJmAUsA1o9KBIiACIiACIiACIrBVCCgF3Cp3UtcBiIEIiIAIiIAIiMAaCSgFXCMoHSYCIiACIiACIlBEAhrTxggoBdwYN71KBERABERABERABBImoBQw4ZunoYuACABiIAIiIAIisBECSgE3Qk2vEQEREAEREAEREIGkCSSeAibNXoMXAREQAREQAREQgQkRUAo4IfA6rQiIgAiIwIYJ6IUiIAKbJqAUcNMI1YEIiIAIiIAIiIAIpEZAKWBqd0zjBcRABERABERABERgkwSUAm4SoF4uAiIgAiIgAiIwDgI6x3AJKAUcLk/1JgIiIAIiIAIiIAIJEFAKmMBN0hBFQAQAMRABERABERgmAaWAw6SpvkRABERABERABEQgCQKJpIBJsNQgRUAEREAEREAERCARAkoBE7lRGqYIiIAIbEMCumQREIGREVAKODK06lgEREAEREAEREAEikpAKWBR74zGBYiBCIiACIiACIjAiAgoBRwRWHUrAiIgAiIgAiKwEQJ6zXgIKAUcD2edRQREQAREQAREQAQKREApYIFuhoYiAiIAiIEIiIAIiMA4CCgFHAdlnUMEREAEREAEREAECkWgYClgodhoMCIgAiIgAiIgAiKwRQkoBdyiN1aXJQIiIAIJEdBQRUAExk5AKeDYkeuEIiACIiACIiACIjBpAkoBJ30HdH5ADERABERABERABMZMQCngmIHrdCIgAiIgAiIgAk5AdbIElAJOlr/OLgIiIAIiIAIiIAITIKAUcALQdUoREAFADERABERABCZJQCngJOnr3CIgAiIgAiIgAiIwEQITSgEncq06qQiIgAiIgAiIgAiIQCCgFDBgkIiACIiACIyBgE4hAiJQGAJKAQtzKzQQERABERABERABERgXAaWA4yKt8wBiIAIiIAIiIAIiUBACSgELciM0DBEQAREQARHYmgR0VcUkoBSwmPdFoxIBERABERABERCBERJQCjhCuOpaBEQAEAMREAEREIEiElAKWMS7ojGJgAiIgAiIgAiIwEgJjDgFHOnY1bkIiIAIiIAIiIAIiMCGCCgF3BA2vUgEREAEROA8BLRLBESg8ASUAhb+FmmAIiACIiACIiACIjBsAkoBh01U/QFiIAIiIAIiIAIiUHACSgELfoM0PBEQAREQARFIg4BGmRYBpYBp3S+NVgREQAREQAREQASGQEAp4BAgqgsREAFADERABERABFIioBQwpbulsYqACIiACIiACIjAUAgMKQUcyljUiQiIgAiIgAiIgAiIwFgIKAUcC2adRAREQAS2JAFdlAiIQLIElAIme+s0cBEQAREQAREQARHYKAGlgBslp9cBYiACIiACIiACIpAoAaWAid44DVsEREAEREAEJkNAZ90aBJQCbo37qKsQAREQAREQAREQgXUQUAq4Dlg6VAREABADERABERCBrUBAKeBWuIu6BhEQAREQAREQARFYF4F1poDr6lsHi4AIiIAIiIAIiIAIFJKAUsBC3hYNSgREQAQKRUCDEQER2HIElAJuuVuqCxIBERABERABERCBCxFQCnghQtoPiIEIiIAIiIAIiMAWI6AUcIvdUF2OCIiACIiACAyHgHrZ2gSUAm7t+6urEwEREAEREAEREIEVCCgFXAGKQiIgAoAYiIAIiIAIbGUCSgG38t3VtYmACIiACIiACIjAigRWSQFXPFZBERABERABERABERCBLUFAKeCWuI26CBEQAREYCgF1IgIisG0IKAXcNrdaFyoCIiACIiACIiACGQGlgBkJtYAYiIAIiIAIiIAIbBMCSgG3yY3WZYqACIiACIjAygQU3Z4ElAJuz/uuqxYBERABERABEdjWBJQCbuvbr4sXAUAMREAE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jgI9C15XPea1GzEWhKNAz4LXVY957UaMBeEo0LPgddVjXjuRgY+aAgdKBR5b/9C4YNVZB4rZvbSPgK/r9WDrfyrq2cmjW82+yHA3W61miyV7Qj369287/NY3HX7Lmy6o/vfI2avYwVDu+8ClecdD6dk7GvZo1acIiIAIiECCBAY+agocSCkFNCAYc2060hUIYKD0Eevbz719keFusn9Dd5zr6twAQ/e1m/cxUDbfp3oQAREQAREYMoGhvvOPf2wDHzXFDaSUApJieyGQy1dcdOF2UF/IySLR51bfkdsk7khytXH27MHXvPrga/7qYNATH/1Qbqe75V27L37uj3fskuDvfGj3/xfnBwELD3hQ55i8E4/PR6LfiU9fdY9IPmrsbU3KF/hxXMUMv/LJO5q719zawP31/nqq9+E11zNPy8jG+o+vzav6iTTEQRwigaiaD+IQCUTdevOh53Om2BuJpYAGPh10V4Z8g5FoZr6XIYASfLiaucKVEny4mrnClRJ8uJq5wpUSfLiaucKVEny4mrnClRJ8uJq5wpUSfLiaucKVEny4mrnClRJ8uJq5wpUSfLiaucKVEnwMltrBOztWP36874BSpTJ3zb38/7pxtets8Etzc32Hzd79qnDMNa7hmLnc8XNXrxqv7NhhLIDBDOspZn68GbVtZsFxZWfBh6uZK1wpwYermStcKfQHTm8xboCbmStcKcGHq5krXCnBh6uZK1wpwYermStcKcGHq5krXCnBh6uZK1wpwYermStcKcGHq5krXCnBh6uZK1wpwYermStcKcGHq5krXCnBh6uZK1wpwYermStcKcGHq5krXCnBh6uZK1wpwYermStcKcGHq5krjAozatvMguOquBEBQDFKNLPguypuRABQjBLNLPiuihsRABSjRDMLvqviRgQAxSjRzILvuvY40ikppYBcnnFr5VaG3I+bXMmJTtDtGl/vxCMsonKq5OfPYh5onDrV109p5874uOZH8gU8Mne8BxlZQ7yv2/NverfeJ4fEhUCer3Xinz50MK5o/k1c1+QC56sPtv0QafsrxE9/7jODp2P3Q7ku9dPGSBC8UZwMNPd548Ltcz84iotPew5oPnAqEAKNPybRpxM29fNCHgnPE352DX7aFDRSqBTwAoxCMo4+BTw97wtyc3vGsc5y+E1/G/4ZP/93ATPn98788xf7ujn0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AtUzTz68TuLXgD4j4jGmz2GaIZ84E6URjwEHphnyiTNRGvEYcGCaIZ84E6URjwEHphnyiTOJRsHCm43LgNdl6BGcpSPmlARMIq6TpDzyzHsY9H2JDbp58rFAyIEcLAHreT2QgyVgPa8HcrAErB/o9WD3SmnvlARMIq6TpDzezHsY8GbULrt78rFEyGEYOOAQ5AwIMHIABBg5AAKMHAABlq4ccGqpbk5JQCOB/DFqeZ5nTA68BngN8BrgNcBrgNdAylwD4tRjiCXgoLIIZJfELCceIMMYEGDkAAgwcgAEGDkAAowcAAFGDoAAIwdAgJEDIMCGhsOgCp+hbcwlCTi0JNg6CZAACZDAYBFgOyRAAilPgBIw5YeIHSQBEiABEiABEiCBwSZACTjYRNmeCBmQAAmQAAmQAAmkOAFKwBQfIHaPBEiABEiABNwgwF66RYAS0K3xYm9JgARIgARIgARIYBAIUAIOAkQ2QQIkIEIGJEACJEACLhGgBHRptNhXEiABEiABEiABEhgUAoMkAQelL2yEBEiABEiABEiABEhgWAhQAg4LZh6EBEiABNKSAE+KBEjAWQKUgM4OHTtOAiRAAiRAAiRAAmtKgBJwTclxPxEyIAESIAESIAEScJQAJaCjA8dukwAJkAAJkMDIEOBR04MAJWB6jCPPggRIgARIgARIgAQGQIAScACwWJUESECEDEiABEiABNKBACVgOowiz4EESIAESIAESIAEBkRggBJwQG2zMgmQAAmQAAmQAAmQQEoSoARMyWFhp0iABEggpQiwMyRAAmlHgBIw7YaUJ0QCJEACJEACJEACqyNACbg6QtwuQgYkQAIkQAIkQAJpRoASMM0GlKdDAiRAAiRAAoNDgK2kNwFKwPQeX54dCZAACZAACZAACSQhQAmYBApTJEACImRAAiRAAiSQzgQoAdN5dHluJEACJEACJEACJJCUQC8SMGldJkmABEiABEiABEiABNKCACVgWgwjT4IESIAEBoUAGyEBEsgYApSAGTPUPFESIAESIAESIAESiBOgBIyT4FKEDEiABEiABEiABDKEACVghgw0T5MESIAESIAEkhNgNjMJUAJm5rjzrEmABEiABEiABDKaACVgRg8/T54ERMiABEiABEggEwlQAmbiqPOcSYAESIAESIAEMpuAUAJm+AXA0ycBEiABEiABEshEApSA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t954bbU1UeGtN16Hr6+v++3//ew3Pz+/D/vV+T/BVvBBfRoJZAoBnicJkAAJpCmBDJWA1UuW3HX7rRf+7a8PP3D/p5983N6P30yBqJr71ZdPPf7oJRf96/qrr0I8PJfE6KqqbbbdLjc/b97cr3DEiRMnw2+y6WY777obgqS27Q47hEKh115+uampMWmFRLKxsaGubpVdxdxhH5abqz80DQj+b5bYHelJgARIgARIgAScI5BxEhATaS8+9yzu9n743nuI+x6w3rZ++flnmBF88N5729vae6szWPl111v/iGNmFBUVffTBB7gLvHDB/FtvvH7LrbbeZ/9v93YI3NXdbsedWltann78id7q2HxBwaif/N8v/3LBhbDEd0eSBieceip2KS4uzslZzYcRUY1GAiRAAiRAAiSQ4gQyTgI+eO//nnr8Mcxmrf3AvPXGazddd004HF77plbbAu4+f/XlF1O32661tfWT2bOffOzRvnfZc5998vLz0cPPPp3Td81+bl20cAFqjh0/Hp5GAiRAAulNgGdHAplAILMk4KwP3n/7zTcGcVxxO/iF554dxAaTNoXZyofuuzcrOws3f3fbc6+NNt7klRdf+HTOJz0rd3R0fPzRrNtuujEUzDr4sO+gwl233bp44SIEa2lfz52HFiZMmAhPIwESIAESIAEScJ1AZknA2R/NGvQB++jD9we9zW4NPnTffV/Pm7vP/gcUl5QYY6YddVRuXu69d96Z+KifvR/9wP/u+fuffg/9BxVYX1+39TbbbrPd9i3NzTdcs7afXGxvb//8M51NXHeDDbr1LR1XeU4kQAIkQAIkkP4EMksCVi9eMuhDunRJ9aDcVk7aseam5jtvuwX3c6Hndt19D1unqKh4v28f2NjY8PorryDz2ssvr1y5AgFuEIc7wtvtsOM5P/rJ6MpKZKYdeeTGm26Kmjdfd+2qVbGvfSA/UHvt5ZdamluKioomTtIvowx0d9YnARIgARIggZQnkHEdzCwJiDuqbo3wp3M+nvX++zvtstvhRx2N+b9E57fbcccDDj5kr333RebRhx6Ahx16+BE///Xvph151Njx47AKCwSCx5986s677XbE0ccUFxcj0x977qkn//7HP/zngn9ecfF/rrzk4osvvOCpxx/DjrvvvXcgkFkXDM6aRgIkQAIkQAJpSSCzXtFLy8oGfRRxc3bohNFWU7c59yfnHzJtWjAY9Pc8GAzttudegYAmjz3x5KOPPf4vF1y448674AaxvxriQCBw8GHT7H8Bh9X+2OZbbtXU1LRsafWC+fPnf/N1dXU15CMU544779qf3VmHBJwkwE6TAAmQQIYRyCwJeMh3pm248SajK6sGy9aZMuWY408Y0mumasyYvtvffMstvzV1at91BrS1ckzVH//+jz//81+//8vff/fnv/3xb//42a9/C8Xpn4YcUIOsTAIkQAIkQAIkkGoEMksClldUnHz6GT86/2fdbI1XzzzrnMnrTEm1QR2U/kDwZWVnZedkB7tOQA5K42yEBEiABEiABEhgZAlklgQcWdY8OgmQAAmQQEoRYGdIIJMJUAJm8ujz3EmABEiABEiABDKUACVghg48T1uEDEiABEiABEggcwlQAmbu2PPMSYAESIAESCDzCPCMYwQoAWMguCABEiABEiABEiCBzCFACZg5Y80zJQESECEDEiABEiABjwAloIeBjgRIgARIgARIgAQyiUBmScBMGlmeKwmQAAmQAAmQAAn0SoASsFc03EACJEACJJAeBHgWJEACPQlQAvZkwgwJkAAJkAAJkAAJpDkBSsA0H2CenggZkAAJkAAJkAAJdCfglAQ03XvPdRIgARIgARIgARJIRmAkck4JFack4EiMJo9JAiRAAiRAAiRAAulHwDUJGE2/IeAZkQAJDAEBNkkCJEACw0zANYnimgQU1wAP8/XHw5EACZAACZAACYwMAcckinMSsF+32Udm6HlUEiABEiABEiCBzCXgmERxTQI6hjdznwc8cxIgARIYfgI8IgmMJAHXJIprEnAkx5bHJgESIAESIAESIIE0IUAJmCYDydMQIQMSIAESIAESIIH+EqAE7C8p1iMBEiABEiABEkg9AuzRGhJwVwI69r2bNRwf7kYCJEACJEACJJDSBFwVJO5KQMPfh0npZwQ7RwLDQ4BHIQESIIERJKDyz7WvgcRxuSsBRcBc0QsfJEACJEACJEACJDDcBCBCIEWG+6iDdjyXJaCIqkBOBg7axcCGSIAESIAESIAE+kkg6omQflZOxWqOS0BF6rIC1/6zkAAJkAAJDIwAa5NAChBwXn6kgQRMgcuAXSABEiABEiABEiABpwiknQSMikSjvDns1EU40M6yPgmQAAmQAAkMI4E0lRZpJwExL2tM5+15HTaIQhoJkAAJkAAJkIDTBEai81ZnGhG/tJA0eaSdBOw2LjpsIvQkQAIkQAIkQAIkMFACks6PdJeAPkyxXQAAEABJREFU6Tx2PDcSyCQCPFcSIAESIIFBJUAJOKg42RgJkAAJkAAJkAAJuEDADQnoAkn2kQRIgARIgARIgAScIUAJ6MxQsaMkQAIkkGkEeL4kQAJDR4AScOjYsmUSIAESIAESIAESSFEClIApOjDslggZkAAJkAAJkAAJDBUBSsChIst2SYAESIAESIAEBk6AewwTAUrAYQLNw5AACZAACZAACZBA6hCgBEydsWBPSIAERMiABEiABEhgWAhQAg4LZh6EBEiABEiABEiABFKJQGpJwFQiw76QAAmQAAmQAAmQQNoSoARM26HliZEACZCAKwTYTxIggeEnQAk4/Mx5RBIgARIgARIgARIYYQKUgCM8ADy8CBmQAAmQAAmQAAkMNwFKwOEmzuORAAmQAAmQAAmIkMEIE6AEHOEB4OFJgARIgARIgARIYPgJUAIOP3MekQRIQIQMSIAESIAERpQAJeCI4ufBSYAESIAESIAESGAkCIyMBByJM+UxSYAESIAESIAESIAEYgQoAWMguCABEiABEhhqAmyfBEggdQhQAqbOWLAnJEACJEACJEACJDBMBCgBhwk0DyNCBiRAAiRAAiRAAqlCgBIwVUaC/SABEiABEiCBdCTAc0pRApSAKTow7BYJkAAJkAAJkAAJDB0BSsChY8uWSYAERMiABEiABEggJQlQAqbksLBTJEACJEACJEACJDCUBIZWAg5lz9k2CZAACZAACZAACZDAGhJISwloYjCi0VjABQmQAAmQwDAS4KFIIE0IdAqJuLRIkxPT00g/CQjZB9NzE5OGA+adGB0JkAAJkAAJkMDQE+gUEpAWsKE/4jAeIY0kYEyqU/YN4+WT/FDMkgAJkAAJkED6EfAERkxspMPZpYEENGJ1eadUT4eB4TmQAAmQAAmQgFMEMqOzVmyo8PAUocsn7boExABEBc7lMWDfSYAESIAESIAEXCKgwiMqjusPxyVgNCJ8kAAJpAIB9oEESIAEMo2A4yLEXQkYFdyPt/OxmXbN8XxJgARIgARIgARGnABECKRI7ONoI96bAXdgcCTggA87CDsYAfpBaIdNkAAJkAAJkAAJkMAaEVApYtZoz5HfyU0JqKJ75NmxByRAAiSQ4QR4+iRAAkrATVnioASE2lbRrcxZSIAESIAESIAESGCECUCWQJyMcCcGfHgHJWB0wCfJHYaGAFslARIgARIgARLwCDgoTlyTgA4i9i4NOhIgARIgARJIDwI8i14IuCZRXJOADk609nKlME0CJEACJEACJJBGBFyTKK5JwDS6VHgqJOAkAXaaBEiABEggLQhQAqbFMPIkSIAESIAESIAESGAgBAYmAQfS8hDUdW2KdQgQsEkSIAESIAESIIFUJeCUUHFKArr5uzupep2yXyRAAiTQXwKsRwIk0C8CTgkVpySgOKWu+3WxsBIJkAAJkAAJkEDaEHBJqDglAV37unW6XNE8DxIgARIgARIggX4QcEqoOCUB+wGfVUiABEiABEiABAaDANtIcwKUgGk+wDw9EiABEiABEiABEuhJgBKwJxNmSIAERMiABEiABEggrQlQAqb18PLkSIAESIAESIAESCAZgeQSMFnNTMnV1Kz87NM5M999Z87HHy+tXpIpp83zJAESIAESIAESyCQClICx0Y5Go5B9l/z7wn/99S83XXvNvXfeccsN1/33Xxdg9aXnn2tvb4/V44IESIAE0pcAz4wESCBzCFAC6ljX19dddeklkH1LFi3SdV+pqVn55GOP/vdf/1yyeLEvzZAESIAESIAESIAEHCZACSh1dXVXXPzf+d983ccw1qxcedWlFy+cP7+POu5v4hmQAAmQAAmQQKoTwF27VO+iI/3LdAkYiYRvu+mGVbW1ifHaeNNNDz5s2mnf+/60I4/aepttA4EYora2tltvvL6pqTFRkwEJkAAJkAAJuE/ApTOYPWvWn3/3mwv++uev5811qd8p2deYvknJvg1Hp959++0F33xjj5SXn3/8yaeceOrpO++223rrb7DdDjseOePY7559Tll5ua2A+cLnn3naxvQkQAIkQAIkQALDTOCJRx9uaW6uram58ZqrqQLXEn6mS8BXXnwhQXD60TM23XyLxKoNJk6afOIppweDIbv61uuvt7W22ZieBNKBAM+BBEiABNwhMGbsONtZ3JrrqQJxj3hZdfW7b7913913XX3ZpRf94+9/+u2vf/2zn/7197/7zwX/vPbKy5949JFPZs/mDT3LMKMl4LKlS5cvW2ZBbLbFFptstpmNu/nKMVW777WXTXZ0dHzx+ac2picBEiABEiABEhhOAtOPPmb8hAn2iKoCr+0yFxju6HjskYeh/6ACMUe4YvkyTBlCFzY2NixbWj33yy9ffuH5W2+8/i+//91N110LLRiJRGxTmehFMloCLq2uToz6+htulIh7Bv6t/r161mSGBEiABEiABEhgiAjk5uWdeub3xoyLzwW2tt147dXffB37XGAoK+v4k07ecONNVnP0aPSzOZ9AC/7rb3/5YObM1VRO380ZLQEbGuoTIzs2fj0lMv5g7NixidX6urpEPLIB3tm8+Nxz9955B+YmR7YnPDoJkIBbBNhbEnCXQF5+/mnf/V5l1Rh7Cm2tbTdcM3AV6O28qrb27jtuu+bySzPzd98yWgJGImHvGlCXlZWti15KVnbn1nC4c69eqg9T2hgz5+PZM99959OPP+7/IXHFL1qwIKnVrFyJdtrb2vGMSmrYlx+hACIaCZAACZDACBIoKBh18ulnhEKxj+njBctTgfNsl0LeXODGm246urJysy222GmX3bbYaquEZLR1/H7e3LlXXPLfD997z5/MhDijJaATAwzJVVtT05tVjdG3Qa+89GJvFWw+HO5InOyLzz172X//ndSeeuIxVLvw73/9w69/kdT++Zc//eV3v128sPsPaGMvGgmQAAmQAAkMD4GW5pZ777rTfwcMKvDGa69J/MQvVOCJp57+o/N/ftxJpxwybdqM408876fn/+T/frnDTjsnfuvN39WO9va7br/1yccexe01fz69Y0rAVB/fB++794K//rk3e/vNN3AC33w9r7cKNl+9uPM/Ox4/cdKWW28NKy0tw74wxNYmT14Hq1Vjx4wbPz6pYSusoLAAnkYCJEACJOAUgTTpbHNT09VXXPLVl190O5/WlhbMBSZUYLetWC0rLz/siOk/+OF5xSUlWO1pLz3/3OOPPNwzn66ZjJOAUPqvvvTS7TffeN1VV7z+yquJcb3/f3cj05vdcPVViZqffvIxqt18/XXPPvUkLsREfkiDCRMnYk57DSzbdwvb9nCb7bY75rgTYPZrznvusy9iazvusivqnHrm987+0f9Lavn5BWJMQcEoVKORAAmQAAmQwDATwMzfrTde75/X8HdgtSoQlcdNmPD9H55XVFSEuKe9+tKLLz73bM98WmYySwJiovjyS/7z2MMPzp4166svvlixfFliUBd88w0yvZrv3UZdXR2qQQg+9/RT/7ngnzU1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SCsClIBpNZw8GRIgARIgARIgARLoDwFKwP5QYh0SECEDEiABEiABEkgjApSAaTSYPBUSIAESIAESIIHBJZC+rVECpu/Y8sxIgARIgARIgARIoBcClIC9gGGaBEiABETIgARIgATSlQAlYLqOLM+LBEiABEiABEiABHolQAnYKxoRbiIBEiABEiABEiCB9CRACZie48qzIgESIAESWFMC3I8EMoIAJWBGDDNPkgRIgARIgARIgAT8BCgB/TQYk4AIGZAACZAACZBABhCgBMyAQeYpkgAJkAAJkAAJ9E0g87ZSAmbemPOMSYAESIAESIAEMp4AJWDGXwIEQAIkIEIGJEACJJBpBCgBM23Eeb4kQAIkQAIkQAIkIJSAIsLrgARIgARIgARIgAQyiwAlYGaNN8+WBEiABEggToBLEshoApSAGT38PHkSIAESIAESIIHMJEAJmJnjzrMWIQMSIAESIAESyGAClIAZPPg8dRIgARIgARLINAI83zgBSsA4CS5JgARIgARIgARIIGMIUAJmzFDzREmABETIgARIgARIwBKgBLQc6EmABEiABEiABEgggwhklATMoHHlqZIACZAACZAACZBAHwQoAfuAw00kQAIkQAJpQICnQAIkkIQAJWASKEyRAAmQAAmQAAmQQHoToARM7/Hl2YmQAQmQAAmQAAmQQA8ClIA9kDBBAiRAAiRAAiTgOgH2f3UEKAFXR4jbSYAESIAESIAESCDtCFACpt2Q8oRIgAREyIAESIAESKBvApSAffPpsjXa3h6uq21fvqRt8YK2RfNpJEACJEACJEACI09g8QK8NOMFGi/TXV62udIngbSUgH2ecb83tq9Y2jjr3drnHll297WLrvz7N//8+Td/++mC//xu0eV/W3zNBYuv/ReNBEiABEiABEhg5AlccwFemvECjZdpvFjjJRsv3Hj5xos4Xsr7/bKfcRUpAbsMebh+VcN7ry+/76YFF/120WV/WX7/zateebppzqz2pYujLS1dqnKFBEiABEggtQiwNyQgeLHGSzZeuPHyjRdxvJTjBR0v63hxx0s8AfkJUAIqjUhzU/3bL1fffMmCf/92xcN3Nn40M9ywSjewkAAJkAAJkAAJuEwAL+h4WceLO17i8UKPl3u86Lt8QoPW90yXgC3ffLX8gVvnX/CLlY//r2XeF4PGlQ0NPwEekQRIgARI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
\ No newline at end of file
diff --git a/docs/verification/login-page.png b/docs/verification/login-page.png
new file mode 100644
index 0000000..1072809
Binary files /dev/null and b/docs/verification/login-page.png differ
diff --git a/docs/verification/mood-page.png b/docs/verification/mood-page.png
new file mode 100644
index 0000000..e1bd8fc
Binary files /dev/null and b/docs/verification/mood-page.png differ
diff --git a/docs/verification/parent-page.png b/docs/verification/parent-page.png
new file mode 100644
index 0000000..eb5d6d4
Binary files /dev/null and b/docs/verification/parent-page.png differ
diff --git a/docs/verification/profile-page.png b/docs/verification/profile-page.png
new file mode 100644
index 0000000..ffd38e4
Binary files /dev/null and b/docs/verification/profile-page.png differ
diff --git a/docs/verification/search-page.png b/docs/verification/search-page.png
new file mode 100644
index 0000000..879f476
Binary files /dev/null and b/docs/verification/search-page.png differ
diff --git a/docs/verification/settings-page.png b/docs/verification/settings-page.png
new file mode 100644
index 0000000..40232d9
Binary files /dev/null and b/docs/verification/settings-page.png differ
diff --git a/docs/verification/stickers-page.png b/docs/verification/stickers-page.png
new file mode 100644
index 0000000..6247790
Binary files /dev/null and b/docs/verification/stickers-page.png differ
diff --git a/docs/verification/teacher-page.png b/docs/verification/teacher-page.png
new file mode 100644
index 0000000..7c562e5
Binary files /dev/null and b/docs/verification/teacher-page.png differ
diff --git a/docs/verification/templates-page.png b/docs/verification/templates-page.png
new file mode 100644
index 0000000..61e100c
Binary files /dev/null and b/docs/verification/templates-page.png differ