Files
oneapp_docs/setting/README.md
2025-09-24 14:08:54 +08:00

804 lines
23 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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 提供了完整的应用设置管理功能涵盖用户偏好通知管理隐私安全等各个方面模块采用清晰的分层架构和模块化设计支持多语言主题切换和云端同步为用户提供个性化和安全的设置体验通过完善的状态管理和错误处理机制确保了设置功能的稳定性和用户体验