816 lines
24 KiB
Dart
816 lines
24 KiB
Dart
import 'dart:io' as io;
|
||
import 'package:flutter/material.dart';
|
||
import '../../../constants/app_constants.dart';
|
||
import '../../../utils/http/http_client.dart';
|
||
|
||
/// 时间: 2026-03-30
|
||
/// 功能: 诗词投稿页面
|
||
/// 介绍: 用户提交诗词收录申请,支持相似度检测和人机验证
|
||
/// 最新变化: 新增投稿功能
|
||
|
||
class ManuscriptPage extends StatefulWidget {
|
||
const ManuscriptPage({super.key});
|
||
|
||
@override
|
||
State<ManuscriptPage> createState() => _ManuscriptPageState();
|
||
}
|
||
|
||
class _ManuscriptPageState extends State<ManuscriptPage> {
|
||
final _formKey = GlobalKey<FormState>();
|
||
final _nameController = TextEditingController();
|
||
final _urlController = TextEditingController();
|
||
final _keywordsController = TextEditingController();
|
||
final _introduceController = TextEditingController();
|
||
|
||
List<Map<String, dynamic>> _categories = [];
|
||
String? _selectedCategory;
|
||
bool _isLoadingCategories = true;
|
||
bool _isCheckingName = false;
|
||
bool _isSubmitting = false;
|
||
|
||
bool _nameExists = false;
|
||
int _maxSimilarity = 0;
|
||
int _similarCount = 0;
|
||
bool _nameChecked = false;
|
||
|
||
@override
|
||
void initState() {
|
||
super.initState();
|
||
_loadCategories();
|
||
}
|
||
|
||
@override
|
||
void dispose() {
|
||
_nameController.dispose();
|
||
_urlController.dispose();
|
||
_keywordsController.dispose();
|
||
_introduceController.dispose();
|
||
super.dispose();
|
||
}
|
||
|
||
String _getPlatform() {
|
||
try {
|
||
final String osName = io.Platform.operatingSystem;
|
||
if (osName == 'ohos' ||
|
||
osName == 'harmonyos' ||
|
||
osName == 'openharmony') {
|
||
return 'HarmonyOS Flutter';
|
||
} else if (io.Platform.isAndroid) {
|
||
return 'Android Flutter';
|
||
} else if (io.Platform.isIOS) {
|
||
return 'iOS Flutter';
|
||
} else if (io.Platform.isWindows) {
|
||
return 'Windows Flutter';
|
||
} else if (io.Platform.isMacOS) {
|
||
return 'macOS Flutter';
|
||
} else if (io.Platform.isLinux) {
|
||
return 'Linux Flutter';
|
||
} else {
|
||
return 'Flutter';
|
||
}
|
||
} catch (e) {
|
||
return 'Flutter';
|
||
}
|
||
}
|
||
|
||
Future<void> _loadCategories() async {
|
||
try {
|
||
final response = await HttpClient.get(
|
||
'app/apply.php',
|
||
queryParameters: {'api': 'categories'},
|
||
);
|
||
|
||
if (response.isSuccess) {
|
||
final data = response.jsonData;
|
||
if (data['ok'] == true && data['categories'] != null) {
|
||
setState(() {
|
||
_categories = List<Map<String, dynamic>>.from(data['categories']);
|
||
_isLoadingCategories = false;
|
||
});
|
||
} else {
|
||
setState(() => _isLoadingCategories = false);
|
||
_showSnackBar('加载分类失败', isError: true);
|
||
}
|
||
} else {
|
||
setState(() => _isLoadingCategories = false);
|
||
_showSnackBar('加载分类失败', isError: true);
|
||
}
|
||
} catch (e) {
|
||
setState(() => _isLoadingCategories = false);
|
||
_showSnackBar('网络请求失败: $e', isError: true);
|
||
}
|
||
}
|
||
|
||
Future<void> _checkName() async {
|
||
final name = _nameController.text.trim();
|
||
if (name.isEmpty) {
|
||
setState(() {
|
||
_nameChecked = false;
|
||
_nameExists = false;
|
||
});
|
||
return;
|
||
}
|
||
|
||
setState(() => _isCheckingName = true);
|
||
|
||
try {
|
||
final response = await HttpClient.postForm(
|
||
'app/apply.php?api=check-name',
|
||
data: {'name': name, 'threshold': '80'},
|
||
);
|
||
|
||
if (response.isSuccess) {
|
||
final data = response.jsonData;
|
||
if (data['ok'] == true) {
|
||
setState(() {
|
||
_nameChecked = true;
|
||
_nameExists = data['exists'] ?? false;
|
||
_maxSimilarity = (data['max_similarity'] ?? 0).toInt();
|
||
_similarCount = (data['similar_count'] ?? 0).toInt();
|
||
});
|
||
}
|
||
}
|
||
} catch (e) {
|
||
_showSnackBar('检测失败,请重试', isError: true);
|
||
} finally {
|
||
setState(() => _isCheckingName = false);
|
||
}
|
||
}
|
||
|
||
Future<void> _submitForm() async {
|
||
if (!_formKey.currentState!.validate()) return;
|
||
|
||
if (!_nameChecked) {
|
||
await _checkName();
|
||
if (!_nameChecked) return;
|
||
}
|
||
|
||
if (_nameExists) {
|
||
_showSnackBar('该诗词已存在,请更换', isError: true);
|
||
return;
|
||
}
|
||
|
||
final confirm = await _showConfirmDialog();
|
||
if (!confirm) return;
|
||
|
||
setState(() => _isSubmitting = true);
|
||
|
||
try {
|
||
final response = await HttpClient.postForm(
|
||
'app/apply.php?api=submit',
|
||
data: {
|
||
'name': _nameController.text.trim(),
|
||
'catename': _selectedCategory,
|
||
'url': _urlController.text.trim(),
|
||
'keywords': _keywordsController.text.trim(),
|
||
'introduce': _introduceController.text.trim(),
|
||
'img': _getPlatform(),
|
||
'threshold': '80',
|
||
},
|
||
);
|
||
|
||
if (response.isSuccess) {
|
||
final data = response.jsonData;
|
||
if (data['ok'] == true) {
|
||
_showResultDialog(true, data['message'] ?? '✅ 提交成功!等待审核');
|
||
_resetForm();
|
||
} else {
|
||
_showResultDialog(false, data['error'] ?? '提交失败');
|
||
}
|
||
} else {
|
||
_showResultDialog(false, response.message);
|
||
}
|
||
} catch (e) {
|
||
_showResultDialog(false, '网络请求失败: $e');
|
||
} finally {
|
||
setState(() => _isSubmitting = false);
|
||
}
|
||
}
|
||
|
||
void _resetForm() {
|
||
_formKey.currentState?.reset();
|
||
_nameController.clear();
|
||
_urlController.clear();
|
||
_keywordsController.clear();
|
||
_introduceController.clear();
|
||
setState(() {
|
||
_selectedCategory = null;
|
||
_nameChecked = false;
|
||
_nameExists = false;
|
||
_maxSimilarity = 0;
|
||
_similarCount = 0;
|
||
});
|
||
}
|
||
|
||
Future<bool> _showConfirmDialog() async {
|
||
return await showDialog<bool>(
|
||
context: context,
|
||
builder: (context) => AlertDialog(
|
||
shape: RoundedRectangleBorder(
|
||
borderRadius: BorderRadius.circular(16),
|
||
),
|
||
title: const Row(
|
||
children: [
|
||
Icon(Icons.help_outline, color: AppConstants.primaryColor),
|
||
SizedBox(width: 8),
|
||
Text('确认提交'),
|
||
],
|
||
),
|
||
content: Column(
|
||
mainAxisSize: MainAxisSize.min,
|
||
crossAxisAlignment: CrossAxisAlignment.start,
|
||
children: [
|
||
_buildConfirmItem('参考语句', _nameController.text),
|
||
_buildConfirmItem('分类', _selectedCategory ?? ''),
|
||
_buildConfirmItem('诗人和标题', _urlController.text),
|
||
_buildConfirmItem('关键词', _keywordsController.text),
|
||
_buildConfirmItem('平台', _getPlatform()),
|
||
_buildConfirmItem('介绍', _introduceController.text, maxLines: 2),
|
||
],
|
||
),
|
||
actions: [
|
||
TextButton(
|
||
onPressed: () => Navigator.pop(context, false),
|
||
child: const Text('取消'),
|
||
),
|
||
ElevatedButton(
|
||
onPressed: () => Navigator.pop(context, true),
|
||
style: ElevatedButton.styleFrom(
|
||
backgroundColor: AppConstants.primaryColor,
|
||
foregroundColor: Colors.white,
|
||
shape: RoundedRectangleBorder(
|
||
borderRadius: BorderRadius.circular(8),
|
||
),
|
||
),
|
||
child: const Text('确认提交'),
|
||
),
|
||
],
|
||
),
|
||
) ??
|
||
false;
|
||
}
|
||
|
||
Widget _buildConfirmItem(String label, String value, {int maxLines = 1}) {
|
||
return Padding(
|
||
padding: const EdgeInsets.symmetric(vertical: 4),
|
||
child: Row(
|
||
crossAxisAlignment: CrossAxisAlignment.start,
|
||
children: [
|
||
SizedBox(
|
||
width: 80,
|
||
child: Text(
|
||
'$label:',
|
||
style: TextStyle(color: Colors.grey[600], fontSize: 14),
|
||
),
|
||
),
|
||
Expanded(
|
||
child: Text(
|
||
value,
|
||
style: const TextStyle(fontSize: 14, fontWeight: FontWeight.w500),
|
||
maxLines: maxLines,
|
||
overflow: TextOverflow.ellipsis,
|
||
),
|
||
),
|
||
],
|
||
),
|
||
);
|
||
}
|
||
|
||
void _showResultDialog(bool success, String message) {
|
||
showDialog(
|
||
context: context,
|
||
builder: (context) => AlertDialog(
|
||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)),
|
||
title: Row(
|
||
children: [
|
||
Icon(
|
||
success ? Icons.check_circle : Icons.error,
|
||
color: success
|
||
? AppConstants.successColor
|
||
: AppConstants.errorColor,
|
||
),
|
||
const SizedBox(width: 8),
|
||
Text(success ? '提交成功' : '提交失败'),
|
||
],
|
||
),
|
||
content: Text(message),
|
||
actions: [
|
||
TextButton(
|
||
onPressed: () => Navigator.pop(context),
|
||
child: const Text('确定'),
|
||
),
|
||
],
|
||
),
|
||
);
|
||
}
|
||
|
||
void _showSnackBar(String message, {bool isError = false}) {
|
||
ScaffoldMessenger.of(context).showSnackBar(
|
||
SnackBar(
|
||
content: Row(
|
||
children: [
|
||
Icon(
|
||
isError ? Icons.error_outline : Icons.check_circle_outline,
|
||
color: Colors.white,
|
||
),
|
||
const SizedBox(width: 8),
|
||
Expanded(child: Text(message)),
|
||
],
|
||
),
|
||
backgroundColor: isError
|
||
? AppConstants.errorColor
|
||
: AppConstants.successColor,
|
||
behavior: SnackBarBehavior.floating,
|
||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)),
|
||
margin: const EdgeInsets.all(16),
|
||
),
|
||
);
|
||
}
|
||
|
||
@override
|
||
Widget build(BuildContext context) {
|
||
return Scaffold(
|
||
backgroundColor: const Color(0xFFF5F5F5),
|
||
appBar: AppBar(
|
||
title: const Text(
|
||
'📝 诗词投稿',
|
||
style: TextStyle(
|
||
color: AppConstants.primaryColor,
|
||
fontWeight: FontWeight.bold,
|
||
),
|
||
),
|
||
backgroundColor: Colors.white,
|
||
elevation: 0,
|
||
centerTitle: true,
|
||
leading: IconButton(
|
||
icon: const Icon(Icons.arrow_back, color: AppConstants.primaryColor),
|
||
onPressed: () => Navigator.of(context).pop(),
|
||
),
|
||
),
|
||
body: Form(
|
||
key: _formKey,
|
||
child: ListView(
|
||
padding: const EdgeInsets.all(16),
|
||
children: [
|
||
_buildHeaderCard(),
|
||
const SizedBox(height: 16),
|
||
_buildFormCard(),
|
||
const SizedBox(height: 24),
|
||
_buildSubmitButton(),
|
||
const SizedBox(height: 16),
|
||
_buildTipsCard(),
|
||
],
|
||
),
|
||
),
|
||
);
|
||
}
|
||
|
||
Widget _buildHeaderCard() {
|
||
return Container(
|
||
padding: const EdgeInsets.all(20),
|
||
decoration: BoxDecoration(
|
||
gradient: LinearGradient(
|
||
colors: [
|
||
AppConstants.primaryColor.withAlpha(30),
|
||
AppConstants.primaryColor.withAlpha(10),
|
||
],
|
||
begin: Alignment.topLeft,
|
||
end: Alignment.bottomRight,
|
||
),
|
||
borderRadius: BorderRadius.circular(16),
|
||
),
|
||
child: Row(
|
||
children: [
|
||
Container(
|
||
padding: const EdgeInsets.all(12),
|
||
decoration: BoxDecoration(
|
||
color: Colors.white,
|
||
borderRadius: BorderRadius.circular(12),
|
||
),
|
||
child: const Icon(
|
||
Icons.edit_note,
|
||
color: AppConstants.primaryColor,
|
||
size: 32,
|
||
),
|
||
),
|
||
const SizedBox(width: 16),
|
||
const Expanded(
|
||
child: Column(
|
||
crossAxisAlignment: CrossAxisAlignment.start,
|
||
children: [
|
||
Text(
|
||
'收录经典诗词',
|
||
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
|
||
),
|
||
SizedBox(height: 4),
|
||
Text(
|
||
'支持原创和古诗,传承中华文化',
|
||
style: TextStyle(fontSize: 14, color: Colors.grey),
|
||
),
|
||
],
|
||
),
|
||
),
|
||
],
|
||
),
|
||
);
|
||
}
|
||
|
||
Widget _buildFormCard() {
|
||
return Container(
|
||
decoration: BoxDecoration(
|
||
color: Colors.white,
|
||
borderRadius: BorderRadius.circular(16),
|
||
boxShadow: [
|
||
BoxShadow(
|
||
color: Colors.black.withAlpha(10),
|
||
blurRadius: 10,
|
||
offset: const Offset(0, 2),
|
||
),
|
||
],
|
||
),
|
||
child: Column(
|
||
children: [
|
||
_buildSectionHeader('📝 投稿信息'),
|
||
const Divider(height: 1),
|
||
Padding(
|
||
padding: const EdgeInsets.all(16),
|
||
child: Column(
|
||
children: [
|
||
_buildNameField(),
|
||
const SizedBox(height: 16),
|
||
_buildCategoryField(),
|
||
const SizedBox(height: 16),
|
||
_buildUrlField(),
|
||
const SizedBox(height: 16),
|
||
_buildKeywordsField(),
|
||
const SizedBox(height: 16),
|
||
_buildIntroduceField(),
|
||
],
|
||
),
|
||
),
|
||
],
|
||
),
|
||
);
|
||
}
|
||
|
||
Widget _buildSectionHeader(String title) {
|
||
return Padding(
|
||
padding: const EdgeInsets.all(16),
|
||
child: Row(
|
||
children: [
|
||
Text(
|
||
title,
|
||
style: const TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
|
||
),
|
||
],
|
||
),
|
||
);
|
||
}
|
||
|
||
Widget _buildNameField() {
|
||
return Column(
|
||
crossAxisAlignment: CrossAxisAlignment.start,
|
||
children: [
|
||
Row(
|
||
children: [
|
||
const Text(
|
||
'参考语句',
|
||
style: TextStyle(fontSize: 14, fontWeight: FontWeight.w500),
|
||
),
|
||
const Text(' *', style: TextStyle(color: AppConstants.errorColor)),
|
||
const Spacer(),
|
||
if (_isCheckingName)
|
||
const SizedBox(
|
||
width: 16,
|
||
height: 16,
|
||
child: CircularProgressIndicator(strokeWidth: 2),
|
||
),
|
||
],
|
||
),
|
||
const SizedBox(height: 8),
|
||
TextFormField(
|
||
controller: _nameController,
|
||
decoration: InputDecoration(
|
||
hintText: '如:纤云弄巧,飞星传恨',
|
||
border: OutlineInputBorder(borderRadius: BorderRadius.circular(12)),
|
||
contentPadding: const EdgeInsets.symmetric(
|
||
horizontal: 16,
|
||
vertical: 12,
|
||
),
|
||
suffixIcon: _nameChecked
|
||
? Icon(
|
||
_nameExists ? Icons.error : Icons.check_circle,
|
||
color: _nameExists
|
||
? AppConstants.errorColor
|
||
: AppConstants.successColor,
|
||
)
|
||
: null,
|
||
),
|
||
validator: (value) {
|
||
if (value == null || value.trim().isEmpty) {
|
||
return '请输入参考语句';
|
||
}
|
||
return null;
|
||
},
|
||
onChanged: (value) {
|
||
setState(() {
|
||
_nameChecked = false;
|
||
_nameExists = false;
|
||
});
|
||
},
|
||
onFieldSubmitted: (_) => _checkName(),
|
||
),
|
||
if (_nameChecked) _buildSimilarityInfo(),
|
||
const SizedBox(height: 8),
|
||
Align(
|
||
alignment: Alignment.centerRight,
|
||
child: TextButton.icon(
|
||
onPressed: _isCheckingName ? null : _checkName,
|
||
icon: const Icon(Icons.search, size: 18),
|
||
label: const Text('检测是否存在'),
|
||
),
|
||
),
|
||
],
|
||
);
|
||
}
|
||
|
||
Widget _buildSimilarityInfo() {
|
||
return Container(
|
||
margin: const EdgeInsets.only(top: 8),
|
||
padding: const EdgeInsets.all(12),
|
||
decoration: BoxDecoration(
|
||
color: _nameExists
|
||
? AppConstants.errorColor.withAlpha(20)
|
||
: AppConstants.successColor.withAlpha(20),
|
||
borderRadius: BorderRadius.circular(8),
|
||
),
|
||
child: Row(
|
||
children: [
|
||
Icon(
|
||
_nameExists ? Icons.warning : Icons.check_circle,
|
||
color: _nameExists
|
||
? AppConstants.errorColor
|
||
: AppConstants.successColor,
|
||
size: 20,
|
||
),
|
||
const SizedBox(width: 8),
|
||
Expanded(
|
||
child: Text(
|
||
_nameExists
|
||
? '⚠️ 发现相似内容,相似 $_similarCount 条,最高相似度 $_maxSimilarity%'
|
||
: '✅ 未发现相似内容',
|
||
style: TextStyle(
|
||
color: _nameExists
|
||
? AppConstants.errorColor
|
||
: AppConstants.successColor,
|
||
fontSize: 13,
|
||
),
|
||
),
|
||
),
|
||
],
|
||
),
|
||
);
|
||
}
|
||
|
||
Widget _buildCategoryField() {
|
||
return Column(
|
||
crossAxisAlignment: CrossAxisAlignment.start,
|
||
children: [
|
||
const Row(
|
||
children: [
|
||
Text(
|
||
'分类',
|
||
style: TextStyle(fontSize: 14, fontWeight: FontWeight.w500),
|
||
),
|
||
Text(' *', style: TextStyle(color: AppConstants.errorColor)),
|
||
],
|
||
),
|
||
const SizedBox(height: 8),
|
||
DropdownButtonFormField<String>(
|
||
value: _selectedCategory,
|
||
decoration: InputDecoration(
|
||
hintText: '请选择分类',
|
||
border: OutlineInputBorder(borderRadius: BorderRadius.circular(12)),
|
||
contentPadding: const EdgeInsets.symmetric(
|
||
horizontal: 16,
|
||
vertical: 12,
|
||
),
|
||
),
|
||
items: _categories.map((cat) {
|
||
return DropdownMenuItem(
|
||
value: cat['catename'] as String,
|
||
child: Text(cat['catename'] as String),
|
||
);
|
||
}).toList(),
|
||
onChanged: (value) {
|
||
setState(() => _selectedCategory = value);
|
||
},
|
||
validator: (value) {
|
||
if (value == null || value.isEmpty) {
|
||
return '请选择分类';
|
||
}
|
||
return null;
|
||
},
|
||
),
|
||
],
|
||
);
|
||
}
|
||
|
||
Widget _buildUrlField() {
|
||
return Column(
|
||
crossAxisAlignment: CrossAxisAlignment.start,
|
||
children: [
|
||
const Row(
|
||
children: [
|
||
Text(
|
||
'诗人和标题',
|
||
style: TextStyle(fontSize: 14, fontWeight: FontWeight.w500),
|
||
),
|
||
Text(' *', style: TextStyle(color: AppConstants.errorColor)),
|
||
],
|
||
),
|
||
const SizedBox(height: 8),
|
||
TextFormField(
|
||
controller: _urlController,
|
||
decoration: InputDecoration(
|
||
hintText: '如:李白 静夜思',
|
||
border: OutlineInputBorder(borderRadius: BorderRadius.circular(12)),
|
||
contentPadding: const EdgeInsets.symmetric(
|
||
horizontal: 16,
|
||
vertical: 12,
|
||
),
|
||
),
|
||
validator: (value) {
|
||
if (value == null || value.trim().isEmpty) {
|
||
return '请输入诗人和标题';
|
||
}
|
||
return null;
|
||
},
|
||
),
|
||
],
|
||
);
|
||
}
|
||
|
||
Widget _buildKeywordsField() {
|
||
return Column(
|
||
crossAxisAlignment: CrossAxisAlignment.start,
|
||
children: [
|
||
const Row(
|
||
children: [
|
||
Text(
|
||
'关键词',
|
||
style: TextStyle(fontSize: 14, fontWeight: FontWeight.w500),
|
||
),
|
||
Text(' *', style: TextStyle(color: AppConstants.errorColor)),
|
||
],
|
||
),
|
||
const SizedBox(height: 8),
|
||
TextFormField(
|
||
controller: _keywordsController,
|
||
decoration: InputDecoration(
|
||
hintText: '用逗号分隔,如:思乡,月亮,唐诗',
|
||
border: OutlineInputBorder(borderRadius: BorderRadius.circular(12)),
|
||
contentPadding: const EdgeInsets.symmetric(
|
||
horizontal: 16,
|
||
vertical: 12,
|
||
),
|
||
),
|
||
validator: (value) {
|
||
if (value == null || value.trim().isEmpty) {
|
||
return '请输入关键词';
|
||
}
|
||
return null;
|
||
},
|
||
),
|
||
],
|
||
);
|
||
}
|
||
|
||
Widget _buildIntroduceField() {
|
||
return Column(
|
||
crossAxisAlignment: CrossAxisAlignment.start,
|
||
children: [
|
||
const Row(
|
||
children: [
|
||
Text(
|
||
'诗词介绍',
|
||
style: TextStyle(fontSize: 14, fontWeight: FontWeight.w500),
|
||
),
|
||
Text(' *', style: TextStyle(color: AppConstants.errorColor)),
|
||
],
|
||
),
|
||
const SizedBox(height: 8),
|
||
TextFormField(
|
||
controller: _introduceController,
|
||
maxLines: 5,
|
||
decoration: InputDecoration(
|
||
hintText: '请输入诗词详细介绍...',
|
||
border: OutlineInputBorder(borderRadius: BorderRadius.circular(12)),
|
||
contentPadding: const EdgeInsets.all(16),
|
||
),
|
||
validator: (value) {
|
||
if (value == null || value.trim().isEmpty) {
|
||
return '请输入诗词介绍';
|
||
}
|
||
return null;
|
||
},
|
||
),
|
||
],
|
||
);
|
||
}
|
||
|
||
Widget _buildSubmitButton() {
|
||
return Container(
|
||
height: 56,
|
||
decoration: BoxDecoration(
|
||
gradient: LinearGradient(
|
||
colors: [
|
||
AppConstants.primaryColor,
|
||
AppConstants.primaryColor.withAlpha(200),
|
||
],
|
||
),
|
||
borderRadius: BorderRadius.circular(16),
|
||
boxShadow: [
|
||
BoxShadow(
|
||
color: AppConstants.primaryColor.withAlpha(50),
|
||
blurRadius: 10,
|
||
offset: const Offset(0, 4),
|
||
),
|
||
],
|
||
),
|
||
child: ElevatedButton(
|
||
onPressed: _isSubmitting ? null : _submitForm,
|
||
style: ElevatedButton.styleFrom(
|
||
backgroundColor: Colors.transparent,
|
||
shadowColor: Colors.transparent,
|
||
shape: RoundedRectangleBorder(
|
||
borderRadius: BorderRadius.circular(16),
|
||
),
|
||
),
|
||
child: _isSubmitting
|
||
? const SizedBox(
|
||
width: 24,
|
||
height: 24,
|
||
child: CircularProgressIndicator(
|
||
color: Colors.white,
|
||
strokeWidth: 2,
|
||
),
|
||
)
|
||
: const Row(
|
||
mainAxisAlignment: MainAxisAlignment.center,
|
||
children: [
|
||
Icon(Icons.send, color: Colors.white),
|
||
SizedBox(width: 8),
|
||
Text(
|
||
'提交收录',
|
||
style: TextStyle(
|
||
fontSize: 16,
|
||
fontWeight: FontWeight.bold,
|
||
color: Colors.white,
|
||
),
|
||
),
|
||
],
|
||
),
|
||
),
|
||
);
|
||
}
|
||
|
||
Widget _buildTipsCard() {
|
||
return Container(
|
||
padding: const EdgeInsets.all(16),
|
||
decoration: BoxDecoration(
|
||
color: Colors.blue[50],
|
||
borderRadius: BorderRadius.circular(12),
|
||
),
|
||
child: Column(
|
||
crossAxisAlignment: CrossAxisAlignment.start,
|
||
children: [
|
||
Row(
|
||
children: [
|
||
Icon(Icons.lightbulb_outline, color: Colors.blue[700], size: 20),
|
||
const SizedBox(width: 8),
|
||
Text(
|
||
'投稿提示',
|
||
style: TextStyle(
|
||
fontSize: 14,
|
||
fontWeight: FontWeight.bold,
|
||
color: Colors.blue[700],
|
||
),
|
||
),
|
||
],
|
||
),
|
||
const SizedBox(height: 8),
|
||
Text(
|
||
'• 支持原创诗词和经典古诗\n• 相似度超过80%将无法提交\n• 提交后等待审核通过\n• 平台信息自动识别:${_getPlatform()}',
|
||
style: TextStyle(
|
||
fontSize: 13,
|
||
color: Colors.blue[700],
|
||
height: 1.5,
|
||
),
|
||
),
|
||
],
|
||
),
|
||
);
|
||
}
|
||
}
|