马良AI写作初始化仓库

This commit is contained in:
邓滨杰
2025-09-10 00:07:52 +08:00
parent 3c06bb1a03
commit 39c0f8840f
1309 changed files with 318528 additions and 0 deletions

View File

@@ -0,0 +1,547 @@
import 'package:flutter/material.dart';
import 'package:ainoval/models/app_registration_config.dart';
import 'package:ainoval/utils/web_theme.dart';
/// 注册设置管理页面
/// 用于管理应用的注册功能配置
class RegistrationSettingsScreen extends StatefulWidget {
const RegistrationSettingsScreen({Key? key}) : super(key: key);
@override
State<RegistrationSettingsScreen> createState() => _RegistrationSettingsScreenState();
}
class _RegistrationSettingsScreenState extends State<RegistrationSettingsScreen> {
RegistrationConfig? _config;
bool _isLoading = true;
@override
void initState() {
super.initState();
_loadConfiguration();
}
/// 加载当前配置
Future<void> _loadConfiguration() async {
setState(() {
_isLoading = true;
});
try {
final config = RegistrationConfig(
phoneRegistrationEnabled: await AppRegistrationConfig.isPhoneRegistrationEnabled(),
emailRegistrationEnabled: await AppRegistrationConfig.isEmailRegistrationEnabled(),
verificationRequired: await AppRegistrationConfig.isVerificationRequired(),
quickRegistrationEnabled: await AppRegistrationConfig.isQuickRegistrationEnabled(),
);
setState(() {
_config = config;
_isLoading = false;
});
} catch (e) {
setState(() {
_isLoading = false;
});
_showError('加载配置失败: $e');
}
}
/// 更新配置
Future<void> _updateConfiguration(RegistrationConfig newConfig) async {
try {
await AppRegistrationConfig.setPhoneRegistrationEnabled(newConfig.phoneRegistrationEnabled);
await AppRegistrationConfig.setEmailRegistrationEnabled(newConfig.emailRegistrationEnabled);
await AppRegistrationConfig.setVerificationRequired(newConfig.verificationRequired);
await AppRegistrationConfig.setQuickRegistrationEnabled(newConfig.quickRegistrationEnabled);
setState(() {
_config = newConfig;
});
_showSuccess('配置已保存');
} catch (e) {
_showError('保存配置失败: $e');
}
}
/// 重置到默认配置
Future<void> _resetToDefaults() async {
try {
await AppRegistrationConfig.resetToDefaults();
await _loadConfiguration();
_showSuccess('已重置为默认配置');
} catch (e) {
_showError('重置配置失败: $e');
}
}
/// 显示成功消息
void _showSuccess(String message) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Row(
children: [
Icon(Icons.check_circle, color: Theme.of(context).colorScheme.onPrimary, size: 20),
SizedBox(width: 8),
Text(message),
],
),
backgroundColor: Theme.of(context).colorScheme.primary,
duration: Duration(seconds: 2),
),
);
}
/// 显示错误消息
void _showError(String message) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Row(
children: [
Icon(Icons.error, color: Theme.of(context).colorScheme.onError, size: 20),
SizedBox(width: 8),
Expanded(child: Text(message)),
],
),
backgroundColor: Theme.of(context).colorScheme.error,
duration: Duration(seconds: 3),
),
);
}
/// 显示确认对话框
Future<bool> _showConfirmDialog(String title, String content) async {
return await showDialog<bool>(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text(title),
content: Text(content),
actions: [
TextButton(
onPressed: () => Navigator.of(context).pop(false),
child: Text('取消'),
),
TextButton(
onPressed: () => Navigator.of(context).pop(true),
child: Text('确定'),
),
],
);
},
) ?? false;
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('注册设置'),
actions: [
IconButton(
icon: Icon(Icons.refresh),
onPressed: _loadConfiguration,
tooltip: '刷新配置',
),
PopupMenuButton<String>(
onSelected: (value) async {
if (value == 'reset') {
final confirmed = await _showConfirmDialog(
'重置配置',
'确定要将所有注册设置重置为默认值吗?',
);
if (confirmed) {
_resetToDefaults();
}
}
},
itemBuilder: (context) => [
PopupMenuItem(
value: 'reset',
child: Row(
children: [
Icon(Icons.restore, size: 20),
SizedBox(width: 8),
Text('重置为默认'),
],
),
),
],
),
],
),
body: _isLoading
? Center(child: CircularProgressIndicator())
: _config == null
? _buildErrorState()
: _buildConfigurationForm(),
);
}
/// 构建错误状态
Widget _buildErrorState() {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(
Icons.error_outline,
size: 64,
color: Theme.of(context).colorScheme.error,
),
SizedBox(height: 16),
Text(
'加载配置失败',
style: Theme.of(context).textTheme.headlineSmall,
),
SizedBox(height: 8),
Text(
'请检查应用权限或重新启动应用',
style: Theme.of(context).textTheme.bodyMedium,
textAlign: TextAlign.center,
),
SizedBox(height: 24),
ElevatedButton(
onPressed: _loadConfiguration,
child: Text('重新加载'),
),
],
),
);
}
/// 构建配置表单
Widget _buildConfigurationForm() {
return SingleChildScrollView(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// 配置概览卡片
_buildOverviewCard(),
const SizedBox(height: 24),
// 注册方式设置
_buildRegistrationMethodsSection(),
const SizedBox(height: 24),
// 验证设置
_buildVerificationSection(),
const SizedBox(height: 24),
// 预览和测试
_buildPreviewSection(),
],
),
);
}
/// 构建概览卡片
Widget _buildOverviewCard() {
final availableMethods = _config!.availableMethods;
return Card(
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Icon(
Icons.info_outline,
color: Theme.of(context).colorScheme.primary,
),
SizedBox(width: 8),
Text(
'当前配置状态',
style: Theme.of(context).textTheme.titleMedium?.copyWith(
fontWeight: FontWeight.bold,
),
),
],
),
SizedBox(height: 12),
Row(
children: [
Icon(
_config!.quickRegistrationEnabled ? Icons.flash_on : Icons.flash_off,
color: _config!.quickRegistrationEnabled ? Theme.of(context).colorScheme.primary : WebTheme.getSecondaryTextColor(context),
),
SizedBox(width: 8),
Text('快捷注册: ${_config!.quickRegistrationEnabled ? "开启" : "关闭"}'),
],
),
SizedBox(height: 8),
if (availableMethods.isEmpty)
Container(
padding: const EdgeInsets.all(12),
decoration: BoxDecoration(
color: Theme.of(context).colorScheme.errorContainer,
borderRadius: BorderRadius.circular(8),
),
child: Row(
children: [
Icon(
Icons.warning,
color: Theme.of(context).colorScheme.onErrorContainer,
),
SizedBox(width: 8),
Expanded(
child: Text(
'警告:当前没有启用邮箱或手机注册方式!',
style: TextStyle(
color: Theme.of(context).colorScheme.onErrorContainer,
fontWeight: FontWeight.w500,
),
),
),
],
),
)
else ...[
Text(
'可用的注册方式: ${availableMethods.map((m) => m.displayName).join('')}',
style: Theme.of(context).textTheme.bodyMedium,
),
SizedBox(height: 4),
Text(
'验证码验证: ${_config!.verificationRequired ? "必需" : "可选"}',
style: Theme.of(context).textTheme.bodyMedium,
),
],
],
),
),
);
}
/// 构建注册方式设置区域
Widget _buildRegistrationMethodsSection() {
return Card(
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'注册方式',
style: Theme.of(context).textTheme.titleMedium?.copyWith(
fontWeight: FontWeight.bold,
),
),
SizedBox(height: 16),
// 快捷注册开关
_buildSettingTile(
title: '快捷注册',
subtitle: '仅用户名+密码,无需邮箱/手机与验证码',
value: _config!.quickRegistrationEnabled,
icon: Icons.flash_on,
onChanged: (value) {
_updateConfiguration(_config!.copyWith(
quickRegistrationEnabled: value,
));
},
),
Divider(),
// 邮箱注册开关
_buildSettingTile(
title: '邮箱注册',
subtitle: '允许用户通过邮箱地址注册账户',
value: _config!.emailRegistrationEnabled,
icon: Icons.email,
onChanged: (value) {
_updateConfiguration(_config!.copyWith(
emailRegistrationEnabled: value,
));
},
),
Divider(),
// 手机注册开关
_buildSettingTile(
title: '手机注册',
subtitle: '允许用户通过手机号注册账户',
value: _config!.phoneRegistrationEnabled,
icon: Icons.phone,
onChanged: (value) {
_updateConfiguration(_config!.copyWith(
phoneRegistrationEnabled: value,
));
},
),
],
),
),
);
}
/// 构建验证设置区域
Widget _buildVerificationSection() {
return Card(
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'验证设置',
style: Theme.of(context).textTheme.titleMedium?.copyWith(
fontWeight: FontWeight.bold,
),
),
SizedBox(height: 16),
_buildSettingTile(
title: '验证码验证',
subtitle: '注册时是否必须进行邮箱或手机验证码验证',
value: _config!.verificationRequired,
icon: Icons.verified_user,
onChanged: (value) {
_updateConfiguration(_config!.copyWith(
verificationRequired: value,
));
},
),
],
),
),
);
}
/// 构建预览区域
Widget _buildPreviewSection() {
return Card(
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'配置预览',
style: Theme.of(context).textTheme.titleMedium?.copyWith(
fontWeight: FontWeight.bold,
),
),
SizedBox(height: 16),
Container(
padding: const EdgeInsets.all(12),
decoration: BoxDecoration(
color: WebTheme.isDarkMode(context)
? WebTheme.darkGrey800
: WebTheme.grey100,
borderRadius: BorderRadius.circular(8),
border: Border.all(
color: Theme.of(context).dividerColor,
),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'注册页面将显示的选项:',
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
fontWeight: FontWeight.w500,
),
),
SizedBox(height: 8),
if (_config!.availableMethods.isEmpty) ...[
Text(
'• 无邮箱/手机注册(建议开启快捷注册以允许用户注册)',
style: TextStyle(
color: Theme.of(context).colorScheme.error,
),
),
] else ...[
for (final method in _config!.availableMethods)
Padding(
padding: const EdgeInsets.symmetric(vertical: 2),
child: Row(
children: [
Icon(
method == RegistrationMethod.email
? Icons.email
: Icons.phone,
size: 16,
color: WebTheme.getSecondaryTextColor(context),
),
SizedBox(width: 8),
Text('${method.displayName}'),
],
),
),
if (_config!.verificationRequired) ...[
SizedBox(height: 4),
Row(
children: [
Icon(
Icons.security,
size: 16,
color: WebTheme.getSecondaryTextColor(context),
),
SizedBox(width: 8),
Text('需要验证码验证'),
],
),
],
],
],
),
),
if (_config!.availableMethods.isNotEmpty) ...[
SizedBox(height: 16),
Text(
'提示:用户可以使用 EnhancedLoginScreen 进行注册',
style: Theme.of(context).textTheme.bodySmall?.copyWith(
color: WebTheme.getSecondaryTextColor(context),
),
),
],
],
),
),
);
}
/// 构建设置项
Widget _buildSettingTile({
required String title,
required String subtitle,
required bool value,
required IconData icon,
required ValueChanged<bool> onChanged,
}) {
return ListTile(
contentPadding: EdgeInsets.zero,
leading: Icon(
icon,
color: WebTheme.getSecondaryTextColor(context),
),
title: Text(
title,
style: Theme.of(context).textTheme.bodyLarge?.copyWith(
fontWeight: FontWeight.w500,
color: WebTheme.getTextColor(context),
),
),
subtitle: Text(
subtitle,
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
color: WebTheme.getSecondaryTextColor(context),
),
),
trailing: Switch(
value: value,
onChanged: onChanged,
activeColor: Theme.of(context).colorScheme.primary,
),
);
}
}