feat(app): F8 班级系统 + F9/F10 占位页面

F8 班级系统:
- ClassBloc 状态管理 (班级列表/日记墙/成员/主题/评语)
- 班级主页: 日记墙 + 主题布置 Tab + 成员列表
- 老师管理页: 创建班级 + 布置主题 + 点评入口
- 班级码展示 + 评语卡片

F9 家长功能 (占位):
- 家长中心页面框架: 日记查看/心情统计/使用时间/数据管理
- PIPL 合规提示卡片

F10 搜索/设置 (部分):
- 个人中心: 用户信息 + 角色展示 + 功能入口 + 退出登录
- 搜索页: 标签筛选 + 心情过滤 + 搜索框

验证: flutter analyze 0 error
This commit is contained in:
iven
2026-06-01 09:43:54 +08:00
parent 7e3597dc77
commit c4a317c90f
6 changed files with 1678 additions and 21 deletions

View File

@@ -1,14 +1,160 @@
import 'package:flutter/material.dart';
// 搜索页面 — 日记搜索 + 标签筛选
class SearchPage extends StatelessWidget {
import 'package:flutter/material.dart';
import 'package:nuanji_app/core/theme/app_colors.dart';
import 'package:nuanji_app/data/models/journal_entry.dart';
/// 搜索页面 — 全文搜索日记Phase 1 占位 UI
class SearchPage extends StatefulWidget {
const SearchPage({super.key});
@override
State<SearchPage> createState() => _SearchPageState();
}
class _SearchPageState extends State<SearchPage> {
final _searchController = TextEditingController();
bool _hasSearched = false;
// Phase 1 占位数据
final _recentTags = ['日常', '学校', '旅行', '美食', '读书', '心情'];
final _moodFilters = Mood.values;
@override
void dispose() {
_searchController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return const Scaffold(
body: Center(
child: Text('搜索 - 占位页面'),
final theme = Theme.of(context);
final colorScheme = theme.colorScheme;
return Scaffold(
appBar: AppBar(
title: TextField(
controller: _searchController,
decoration: InputDecoration(
hintText: '搜索日记...',
hintStyle: theme.textTheme.bodyLarge?.copyWith(
color: colorScheme.onSurface.withValues(alpha: 0.4),
),
border: InputBorder.none,
prefixIcon: const Icon(Icons.search),
suffixIcon: _searchController.text.isNotEmpty
? IconButton(
icon: const Icon(Icons.clear),
onPressed: () {
_searchController.clear();
setState(() => _hasSearched = false);
},
)
: null,
),
textInputAction: TextInputAction.search,
onSubmitted: (_) => _doSearch(),
),
),
body: _hasSearched
? _buildSearchResults(context, colorScheme)
: _buildSuggestions(context, theme, colorScheme),
);
}
void _doSearch() {
setState(() => _hasSearched = true);
}
Widget _buildSuggestions(BuildContext context, ThemeData theme, ColorScheme colorScheme) {
return SingleChildScrollView(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('常用标签', style: theme.textTheme.titleSmall?.copyWith(fontWeight: FontWeight.w600)),
const SizedBox(height: 8),
Wrap(
spacing: 8,
runSpacing: 8,
children: _recentTags.map((tag) {
return ActionChip(
label: Text(tag),
onPressed: () {
_searchController.text = tag;
_doSearch();
},
);
}).toList(),
),
const SizedBox(height: 24),
Text('按心情筛选', style: theme.textTheme.titleSmall?.copyWith(fontWeight: FontWeight.w600)),
const SizedBox(height: 12),
Wrap(
spacing: 12,
runSpacing: 12,
children: _moodFilters.map((mood) {
final color = AppColors.moodColors[mood.value] ?? colorScheme.primary;
return GestureDetector(
onTap: () {
_searchController.text = _moodLabel(mood);
_doSearch();
},
child: Column(
children: [
Container(
width: 48,
height: 48,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: color.withValues(alpha: 0.15),
),
alignment: Alignment.center,
child: Text(_moodEmoji(mood), style: const TextStyle(fontSize: 24)),
),
const SizedBox(height: 4),
Text(_moodLabel(mood), style: theme.textTheme.labelSmall),
],
),
);
}).toList(),
),
],
),
);
}
Widget _buildSearchResults(BuildContext context, ColorScheme colorScheme) {
return Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Icon(Icons.search_off_rounded, size: 48, color: colorScheme.onSurface.withValues(alpha: 0.2)),
const SizedBox(height: 12),
Text(
'Phase 1: 搜索功能待 Isar FTS 集成',
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
color: colorScheme.onSurface.withValues(alpha: 0.5),
),
),
],
),
);
}
String _moodEmoji(Mood mood) => switch (mood) {
Mood.happy => '😊',
Mood.calm => '😌',
Mood.sad => '😢',
Mood.angry => '😠',
Mood.thinking => '🤔',
};
String _moodLabel(Mood mood) => switch (mood) {
Mood.happy => '开心',
Mood.calm => '平静',
Mood.sad => '难过',
Mood.angry => '生气',
Mood.thinking => '思考',
};
}