Files
oneapp_docs/setting/README.md

804 lines
23 KiB
Markdown
Raw Permalink Normal View History

2025-09-24 14:08:54 +08:00
# OneApp Setting - 应用设置模块文档
## 模块概述
`app_setting` 是 OneApp 的应用设置管理模块,提供用户偏好设置、系统配置、通知管理、隐私设置等功能。该模块采用模块化设计,支持动态配置更新和多语言切换,为用户提供个性化的应用体验。
### 基本信息
- **模块名称**: app_setting
- **版本**: 0.2.26
- **仓库**: https://gitlab-rd0.maezia.com/dssomobile/oneapp/dssomobile-oneapp-app-setting
- **Flutter 版本**: >=2.10.5
- **Dart 版本**: >=2.16.2 <4.0.0
## 目录结构
```
app_setting/
├── lib/
│ ├── app_setting.dart # 主导出文件
│ ├── route_dp.dart # 路由配置
│ ├── route_export.dart # 路由导出
│ ├── generated/ # 代码生成文件
│ ├── l10n/ # 国际化文件
│ └── src/ # 源代码目录
│ ├── pages/ # 设置页面
│ ├── widgets/ # 设置组件
│ ├── models/ # 数据模型
│ ├── services/ # 服务层
│ └── constants/ # 常量定义
├── assets/ # 静态资源
├── set_notification_uml.puml # 通知设置 UML 图
├── set_notification_uml.svg # 通知设置 UML 图
├── pubspec.yaml # 依赖配置
└── README.md # 项目说明
```
## 核心功能模块
### 1. 用户偏好设置
#### 个人信息设置
```dart
// 个人信息设置服务
class ProfileSettingsService {
final SettingRepository _settingRepository;
final StorageService _storageService;
ProfileSettingsService(this._settingRepository, this._storageService);
// 获取用户个人信息设置
Future<Result<UserProfileSettings>> getUserProfileSettings() async {
try {
final settings = await _settingRepository.getUserProfileSettings();
return Right(settings);
} catch (e) {
return Left(SettingFailure.loadFailed(e.toString()));
}
}
// 更新用户头像
Future<Result<void>> updateUserAvatar(String avatarUrl) async {
try {
await _settingRepository.updateUserAvatar(avatarUrl);
await _storageService.setString('user_avatar', avatarUrl);
return Right(unit);
} catch (e) {
return Left(SettingFailure.updateFailed(e.toString()));
}
}
// 更新用户昵称
Future<Result<void>> updateUserNickname(String nickname) async {
try {
await _settingRepository.updateUserNickname(nickname);
await _storageService.setString('user_nickname', nickname);
return Right(unit);
} catch (e) {
return Left(SettingFailure.updateFailed(e.toString()));
}
}
}
```
#### 应用偏好设置
```dart
// 应用偏好设置模型
class AppPreferenceSettings {
final String language;
final String theme;
final bool enableDarkMode;
final bool enableAutoStart;
final bool enableBackgroundRefresh;
final double fontSize;
final bool enableHapticFeedback;
final bool enableSoundEffects;
const AppPreferenceSettings({
required this.language,
required this.theme,
required this.enableDarkMode,
required this.enableAutoStart,
required this.enableBackgroundRefresh,
required this.fontSize,
required this.enableHapticFeedback,
required this.enableSoundEffects,
});
factory AppPreferenceSettings.fromJson(Map<String, dynamic> json) {
return AppPreferenceSettings(
language: json['language'] ?? 'zh-CN',
theme: json['theme'] ?? 'system',
enableDarkMode: json['enable_dark_mode'] ?? false,
enableAutoStart: json['enable_auto_start'] ?? true,
enableBackgroundRefresh: json['enable_background_refresh'] ?? true,
fontSize: (json['font_size'] ?? 16.0).toDouble(),
enableHapticFeedback: json['enable_haptic_feedback'] ?? true,
enableSoundEffects: json['enable_sound_effects'] ?? true,
);
}
}
// 应用偏好设置服务
class AppPreferenceService {
final StorageService _storageService;
AppPreferenceService(this._storageService);
// 获取应用偏好设置
Future<AppPreferenceSettings> getAppPreferences() async {
final json = await _storageService.getObject('app_preferences') ?? {};
return AppPreferenceSettings.fromJson(json);
}
// 保存应用偏好设置
Future<void> saveAppPreferences(AppPreferenceSettings settings) async {
await _storageService.setObject('app_preferences', settings.toJson());
// 通知其他模块设置变更
_notifySettingsChanged(settings);
}
// 更新语言设置
Future<void> updateLanguage(String language) async {
final settings = await getAppPreferences();
final updatedSettings = settings.copyWith(language: language);
await saveAppPreferences(updatedSettings);
}
// 更新主题设置
Future<void> updateTheme(String theme, bool enableDarkMode) async {
final settings = await getAppPreferences();
final updatedSettings = settings.copyWith(
theme: theme,
enableDarkMode: enableDarkMode,
);
await saveAppPreferences(updatedSettings);
}
}
```
### 2. 通知设置管理
#### 通知偏好配置
```dart
// 通知设置模型
class NotificationSettings {
final bool enablePushNotification;
final bool enableSoundNotification;
final bool enableVibrationNotification;
final bool enableLEDNotification;
final NotificationTime quietHours;
final Map<NotificationType, bool> typeSettings;
const NotificationSettings({
required this.enablePushNotification,
required this.enableSoundNotification,
required this.enableVibrationNotification,
required this.enableLEDNotification,
required this.quietHours,
required this.typeSettings,
});
factory NotificationSettings.defaultSettings() {
return NotificationSettings(
enablePushNotification: true,
enableSoundNotification: true,
enableVibrationNotification: true,
enableLEDNotification: false,
quietHours: NotificationTime.defaultQuietHours(),
typeSettings: {
NotificationType.system: true,
NotificationType.charging: true,
NotificationType.maintenance: true,
NotificationType.security: true,
NotificationType.social: false,
NotificationType.marketing: false,
},
);
}
}
// 通知设置服务
class NotificationSettingsService {
final SettingRepository _settingRepository;
final PushNotificationService _pushService;
NotificationSettingsService(this._settingRepository, this._pushService);
// 获取通知设置
Future<Result<NotificationSettings>> getNotificationSettings() async {
try {
final settings = await _settingRepository.getNotificationSettings();
return Right(settings);
} catch (e) {
return Left(SettingFailure.loadFailed(e.toString()));
}
}
// 更新通知设置
Future<Result<void>> updateNotificationSettings(
NotificationSettings settings,
) async {
try {
await _settingRepository.updateNotificationSettings(settings);
// 同步到推送服务
await _syncNotificationSettingsToPushService(settings);
return Right(unit);
} catch (e) {
return Left(SettingFailure.updateFailed(e.toString()));
}
}
// 切换通知类型开关
Future<Result<void>> toggleNotificationType(
NotificationType type,
bool enabled,
) async {
try {
final currentSettings = await getNotificationSettings();
return currentSettings.fold(
(failure) => Left(failure),
(settings) async {
final updatedTypeSettings = Map<NotificationType, bool>.from(
settings.typeSettings,
);
updatedTypeSettings[type] = enabled;
final updatedSettings = settings.copyWith(
typeSettings: updatedTypeSettings,
);
return await updateNotificationSettings(updatedSettings);
},
);
} catch (e) {
return Left(SettingFailure.updateFailed(e.toString()));
}
}
}
```
### 3. 隐私安全设置
#### 隐私设置管理
```dart
// 隐私设置模型
class PrivacySettings {
final bool enableLocationSharing;
final bool enableDataAnalytics;
final bool enablePersonalizedAds;
final bool enableContactSync;
final bool enableBiometricAuth;
final bool enableAutoLock;
final Duration autoLockDuration;
final List<String> blockedContacts;
const PrivacySettings({
required this.enableLocationSharing,
required this.enableDataAnalytics,
required this.enablePersonalizedAds,
required this.enableContactSync,
required this.enableBiometricAuth,
required this.enableAutoLock,
required this.autoLockDuration,
required this.blockedContacts,
});
factory PrivacySettings.defaultSettings() {
return PrivacySettings(
enableLocationSharing: true,
enableDataAnalytics: false,
enablePersonalizedAds: false,
enableContactSync: false,
enableBiometricAuth: false,
enableAutoLock: true,
autoLockDuration: Duration(minutes: 5),
blockedContacts: [],
);
}
}
// 隐私设置服务
class PrivacySettingsService {
final SettingRepository _settingRepository;
final ConsentService _consentService;
final BiometricService _biometricService;
PrivacySettingsService(
this._settingRepository,
this._consentService,
this._biometricService,
);
// 获取隐私设置
Future<Result<PrivacySettings>> getPrivacySettings() async {
try {
final settings = await _settingRepository.getPrivacySettings();
return Right(settings);
} catch (e) {
return Left(SettingFailure.loadFailed(e.toString()));
}
}
// 更新隐私设置
Future<Result<void>> updatePrivacySettings(
PrivacySettings settings,
) async {
try {
// 检查权限变更
await _handlePrivacyPermissionChanges(settings);
await _settingRepository.updatePrivacySettings(settings);
return Right(unit);
} catch (e) {
return Left(SettingFailure.updateFailed(e.toString()));
}
}
// 启用生物识别认证
Future<Result<void>> enableBiometricAuth() async {
try {
// 检查生物识别可用性
final isAvailable = await _biometricService.isAvailable();
if (!isAvailable) {
return Left(SettingFailure.biometricNotAvailable());
}
// 验证生物识别
final isAuthenticated = await _biometricService.authenticate(
localizedReason: '请验证生物识别以启用此功能',
);
if (!isAuthenticated) {
return Left(SettingFailure.biometricAuthFailed());
}
// 更新设置
final currentSettings = await getPrivacySettings();
return currentSettings.fold(
(failure) => Left(failure),
(settings) async {
final updatedSettings = settings.copyWith(
enableBiometricAuth: true,
);
return await updatePrivacySettings(updatedSettings);
},
);
} catch (e) {
return Left(SettingFailure.updateFailed(e.toString()));
}
}
}
```
### 4. 系统设置
#### 系统信息与设置
```dart
// 系统设置服务
class SystemSettingsService {
final PackageInfo _packageInfo;
final StorageService _storageService;
final NetworkService _networkService;
SystemSettingsService(
this._packageInfo,
this._storageService,
this._networkService,
);
// 获取应用信息
AppInfo getAppInfo() {
return AppInfo(
appName: _packageInfo.appName,
packageName: _packageInfo.packageName,
version: _packageInfo.version,
buildNumber: _packageInfo.buildNumber,
);
}
// 获取存储信息
Future<StorageInfo> getStorageInfo() async {
final cacheSize = await _getCacheSize();
final userData = await _getUserDataSize();
final tempFiles = await _getTempFilesSize();
return StorageInfo(
cacheSize: cacheSize,
userDataSize: userData,
tempFilesSize: tempFiles,
totalUsage: cacheSize + userData + tempFiles,
);
}
// 清理缓存
Future<Result<void>> clearCache() async {
try {
// 清理网络缓存
await _networkService.clearCache();
// 清理图片缓存
await _clearImageCache();
// 清理临时文件
await _clearTempFiles();
return Right(unit);
} catch (e) {
return Left(SettingFailure.clearCacheFailed(e.toString()));
}
}
// 检查更新
Future<Result<UpdateInfo?>> checkForUpdates() async {
try {
final updateInfo = await _networkService.checkAppUpdate(
currentVersion: _packageInfo.version,
);
return Right(updateInfo);
} catch (e) {
return Left(SettingFailure.updateCheckFailed(e.toString()));
}
}
// 导出用户数据
Future<Result<String>> exportUserData() async {
try {
final userData = await _collectUserData();
final exportPath = await _saveDataToFile(userData);
return Right(exportPath);
} catch (e) {
return Left(SettingFailure.exportFailed(e.toString()));
}
}
}
```
## 页面组件设计
### 主设置页面
```dart
// 主设置页面
class SettingsMainPage extends StatefulWidget {
@override
_SettingsMainPageState createState() => _SettingsMainPageState();
}
class _SettingsMainPageState extends State<SettingsMainPage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('设置'),
),
body: ListView(
children: [
_buildUserSection(),
_buildAppSection(),
_buildPrivacySection(),
_buildNotificationSection(),
_buildSystemSection(),
_buildAboutSection(),
],
),
);
}
Widget _buildUserSection() {
return SettingsSection(
title: '账户',
children: [
SettingsTile.navigation(
leading: Icon(Icons.person),
title: Text('个人信息'),
subtitle: Text('头像、昵称等'),
onPressed: (context) => _navigateToProfile(),
),
SettingsTile.navigation(
leading: Icon(Icons.security),
title: Text('安全设置'),
subtitle: Text('密码、生物识别'),
onPressed: (context) => _navigateToSecurity(),
),
],
);
}
Widget _buildAppSection() {
return SettingsSection(
title: '应用',
children: [
SettingsTile.navigation(
leading: Icon(Icons.language),
title: Text('语言'),
subtitle: Text('中文(简体)'),
onPressed: (context) => _navigateToLanguage(),
),
SettingsTile.navigation(
leading: Icon(Icons.palette),
title: Text('主题'),
subtitle: Text('跟随系统'),
onPressed: (context) => _navigateToTheme(),
),
SettingsTile.switchTile(
leading: Icon(Icons.dark_mode),
title: Text('深色模式'),
initialValue: false,
onToggle: (value) => _toggleDarkMode(value),
),
],
);
}
}
```
### 通知设置页面
```dart
// 通知设置页面
class NotificationSettingsPage extends StatefulWidget {
@override
_NotificationSettingsPageState createState() => _NotificationSettingsPageState();
}
class _NotificationSettingsPageState extends State<NotificationSettingsPage> {
late NotificationSettingsBloc _bloc;
@override
void initState() {
super.initState();
_bloc = context.read<NotificationSettingsBloc>();
_bloc.add(LoadNotificationSettings());
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('通知设置')),
body: BlocBuilder<NotificationSettingsBloc, NotificationSettingsState>(
builder: (context, state) {
if (state is NotificationSettingsLoaded) {
return _buildSettingsList(state.settings);
} else if (state is NotificationSettingsError) {
return _buildErrorState(state.message);
} else {
return _buildLoadingState();
}
},
),
);
}
Widget _buildSettingsList(NotificationSettings settings) {
return ListView(
children: [
SettingsSection(
title: '通知开关',
children: [
SettingsTile.switchTile(
leading: Icon(Icons.notifications),
title: Text('推送通知'),
subtitle: Text('接收应用推送消息'),
initialValue: settings.enablePushNotification,
onToggle: (value) => _togglePushNotification(value),
),
SettingsTile.switchTile(
leading: Icon(Icons.volume_up),
title: Text('声音'),
initialValue: settings.enableSoundNotification,
onToggle: (value) => _toggleSoundNotification(value),
),
SettingsTile.switchTile(
leading: Icon(Icons.vibration),
title: Text('振动'),
initialValue: settings.enableVibrationNotification,
onToggle: (value) => _toggleVibrationNotification(value),
),
],
),
SettingsSection(
title: '通知类型',
children: [
...settings.typeSettings.entries.map(
(entry) => SettingsTile.switchTile(
leading: _getNotificationTypeIcon(entry.key),
title: Text(_getNotificationTypeName(entry.key)),
initialValue: entry.value,
onToggle: (value) => _toggleNotificationType(entry.key, value),
),
),
],
),
SettingsSection(
title: '免打扰',
children: [
SettingsTile.navigation(
leading: Icon(Icons.schedule),
title: Text('免打扰时间'),
subtitle: Text('${settings.quietHours.startTime} - ${settings.quietHours.endTime}'),
onPressed: (context) => _navigateToQuietHours(),
),
],
),
],
);
}
}
```
## 状态管理
### 设置状态管理
```dart
// 设置状态 BLoC
class SettingsBloc extends Bloc<SettingsEvent, SettingsState> {
final AppPreferenceService _preferenceService;
final NotificationSettingsService _notificationService;
final PrivacySettingsService _privacyService;
SettingsBloc(
this._preferenceService,
this._notificationService,
this._privacyService,
) : super(SettingsInitial()) {
on<LoadAllSettings>(_onLoadAllSettings);
on<UpdateAppPreference>(_onUpdateAppPreference);
on<UpdateNotificationSettings>(_onUpdateNotificationSettings);
on<UpdatePrivacySettings>(_onUpdatePrivacySettings);
}
Future<void> _onLoadAllSettings(
LoadAllSettings event,
Emitter<SettingsState> emit,
) async {
emit(SettingsLoading());
try {
final appPreferences = await _preferenceService.getAppPreferences();
final notificationSettings = await _notificationService.getNotificationSettings();
final privacySettings = await _privacyService.getPrivacySettings();
final allSettings = AllSettings(
appPreferences: appPreferences,
notificationSettings: notificationSettings.getOrElse(() => NotificationSettings.defaultSettings()),
privacySettings: privacySettings.getOrElse(() => PrivacySettings.defaultSettings()),
);
emit(SettingsLoaded(allSettings));
} catch (e) {
emit(SettingsError('加载设置失败: $e'));
}
}
}
```
## 路由配置
### 设置模块路由
```dart
// 设置模块路由配置
class SettingRoutes {
static const String main = '/settings';
static const String profile = '/settings/profile';
static const String notification = '/settings/notification';
static const String privacy = '/settings/privacy';
static const String security = '/settings/security';
static const String language = '/settings/language';
static const String theme = '/settings/theme';
static const String about = '/settings/about';
static List<ModularRoute> get routes => [
ChildRoute(
main,
child: (context, args) => SettingsMainPage(),
),
ChildRoute(
profile,
child: (context, args) => ProfileSettingsPage(),
),
ChildRoute(
notification,
child: (context, args) => NotificationSettingsPage(),
),
ChildRoute(
privacy,
child: (context, args) => PrivacySettingsPage(),
),
ChildRoute(
security,
child: (context, args) => SecuritySettingsPage(),
),
ChildRoute(
language,
child: (context, args) => LanguageSettingsPage(),
),
ChildRoute(
theme,
child: (context, args) => ThemeSettingsPage(),
),
ChildRoute(
about,
child: (context, args) => AboutPage(),
),
];
}
```
## 依赖管理
### 核心依赖
- **basic_network**: 网络请求服务
- **basic_storage**: 本地存储
- **basic_modular**: 模块化框架
- **basic_intl**: 国际化支持
### 服务依赖
- **clr_setting**: 设置服务 SDK
- **clr_media**: 媒体服务
- **app_consent**: 用户同意管理
### 系统依赖
- **package_info**: 应用信息获取
- **cupertino_icons**: iOS 风格图标
## 数据持久化
### 设置存储策略
```dart
// 设置存储管理器
class SettingsStorageManager {
final StorageService _storageService;
SettingsStorageManager(this._storageService);
// 保存设置到本地
Future<void> saveSettings<T>(String key, T settings) async {
await _storageService.setObject(key, settings.toJson());
}
// 从本地加载设置
Future<T?> loadSettings<T>(
String key,
T Function(Map<String, dynamic>) fromJson,
) async {
final json = await _storageService.getObject(key);
if (json != null) {
return fromJson(json);
}
return null;
}
// 同步设置到云端
Future<void> syncSettingsToCloud() async {
// 实现云端同步逻辑
}
}
```
## 错误处理
### 设置特定异常
```dart
// 设置功能异常
abstract class SettingFailure {
const SettingFailure();
factory SettingFailure.loadFailed(String message) = LoadFailure;
factory SettingFailure.updateFailed(String message) = UpdateFailure;
factory SettingFailure.clearCacheFailed(String message) = ClearCacheFailure;
factory SettingFailure.biometricNotAvailable() = BiometricNotAvailableFailure;
factory SettingFailure.biometricAuthFailed() = BiometricAuthFailure;
}
class LoadFailure extends SettingFailure {
final String message;
const LoadFailure(this.message);
}
```
## 总结
`app_setting` 模块为 OneApp 提供了完整的应用设置管理功能,涵盖用户偏好、通知管理、隐私安全等各个方面。模块采用清晰的分层架构和模块化设计,支持多语言、主题切换和云端同步,为用户提供个性化和安全的设置体验。通过完善的状态管理和错误处理机制,确保了设置功能的稳定性和用户体验。