21 changed files with 979 additions and 277 deletions
@ -0,0 +1,9 @@ |
|||||
|
import 'package:get/get.dart'; |
||||
|
import '../controllers/feedback_controller.dart'; |
||||
|
|
||||
|
class FeedbackBinding extends Bindings { |
||||
|
@override |
||||
|
void dependencies() { |
||||
|
Get.lazyPut<FeedbackController>(() => FeedbackController()); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,59 @@ |
|||||
|
import 'package:flutter/material.dart'; |
||||
|
import 'package:get/get.dart'; |
||||
|
import '../../../data/services/network/api.dart'; |
||||
|
|
||||
|
class FeedbackController extends GetxController { |
||||
|
final TextEditingController feedbackController = TextEditingController(); |
||||
|
//final TextEditingController contactController = TextEditingController(); |
||||
|
|
||||
|
final RxBool isSubmitting = false.obs; |
||||
|
final GlobalKey<FormState> formKey = GlobalKey<FormState>(); |
||||
|
|
||||
|
@override |
||||
|
void onClose() { |
||||
|
feedbackController.dispose(); |
||||
|
//contactController.dispose(); |
||||
|
super.onClose(); |
||||
|
} |
||||
|
|
||||
|
// 提交反馈 |
||||
|
Future<void> submitFeedback() async { |
||||
|
if (!formKey.currentState!.validate()) { |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
isSubmitting.value = true; |
||||
|
|
||||
|
try { |
||||
|
final feedbackText = feedbackController.text; |
||||
|
Map<String, dynamic> data = { |
||||
|
"message": feedbackText, // 反馈内容 |
||||
|
}; |
||||
|
|
||||
|
final response = await Api.feedback(data); |
||||
|
|
||||
|
if (response != null) { |
||||
|
Get.back(); // 返回上一页 |
||||
|
Get.snackbar( |
||||
|
'success'.tr, // 成功 |
||||
|
'feedbackSubmitSuccess'.tr, // 反馈提交成功 |
||||
|
snackPosition: SnackPosition.BOTTOM, |
||||
|
backgroundColor: Colors.green.withOpacity(0.7), |
||||
|
colorText: Colors.white, |
||||
|
margin: const EdgeInsets.all(10), |
||||
|
); |
||||
|
} |
||||
|
} catch (e) { |
||||
|
Get.snackbar( |
||||
|
'error'.tr, // 错误 |
||||
|
'feedbackSubmitFailed'.tr, // 反馈提交失败 |
||||
|
snackPosition: SnackPosition.BOTTOM, |
||||
|
backgroundColor: Colors.red.withOpacity(0.7), |
||||
|
colorText: Colors.white, |
||||
|
margin: const EdgeInsets.all(10), |
||||
|
); |
||||
|
} finally { |
||||
|
isSubmitting.value = false; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,203 @@ |
|||||
|
import 'package:flutter/material.dart'; |
||||
|
import 'package:get/get.dart'; |
||||
|
import 'package:flutter_screenutil/flutter_screenutil.dart'; |
||||
|
import 'dart:ui'; |
||||
|
import '../controllers/feedback_controller.dart'; |
||||
|
|
||||
|
class FeedbackView extends GetView<FeedbackController> { |
||||
|
const FeedbackView({Key? key}) : super(key: key); |
||||
|
|
||||
|
@override |
||||
|
Widget build(BuildContext context) { |
||||
|
final isDarkMode = Theme.of(context).brightness == Brightness.dark; |
||||
|
|
||||
|
return Scaffold( |
||||
|
backgroundColor: isDarkMode ? Colors.black : Colors.grey[100], |
||||
|
appBar: AppBar( |
||||
|
elevation: 0, |
||||
|
backgroundColor: isDarkMode ? Colors.black : Colors.white, |
||||
|
leading: IconButton( |
||||
|
icon: Icon( |
||||
|
Icons.arrow_back_ios, |
||||
|
size: 20.sp, |
||||
|
color: isDarkMode ? Colors.white : Colors.black, |
||||
|
), |
||||
|
onPressed: () => Get.back(), |
||||
|
), |
||||
|
title: Text( |
||||
|
'feedback'.tr, // 帮助与反馈 |
||||
|
style: TextStyle( |
||||
|
fontSize: 17.sp, |
||||
|
fontWeight: FontWeight.w600, |
||||
|
color: isDarkMode ? Colors.white : Colors.black, |
||||
|
), |
||||
|
), |
||||
|
centerTitle: true, |
||||
|
), |
||||
|
body: GestureDetector( |
||||
|
onTap: () => FocusScope.of(context).unfocus(), |
||||
|
child: Form( |
||||
|
key: controller.formKey, |
||||
|
child: ListView( |
||||
|
padding: EdgeInsets.all(16.w), |
||||
|
children: [ |
||||
|
// 顶部提示文字 |
||||
|
Text( |
||||
|
'feedbackDescription'.tr, // 请描述您遇到的问题或建议 |
||||
|
style: TextStyle( |
||||
|
fontSize: 14.sp, |
||||
|
color: isDarkMode ? Colors.white70 : Colors.black54, |
||||
|
), |
||||
|
), |
||||
|
SizedBox(height: 16.h), |
||||
|
|
||||
|
// 反馈内容输入框 |
||||
|
Container( |
||||
|
decoration: BoxDecoration( |
||||
|
color: isDarkMode |
||||
|
? Colors.white.withOpacity(0.05) |
||||
|
: Colors.white, |
||||
|
borderRadius: BorderRadius.circular(16.r), |
||||
|
boxShadow: [ |
||||
|
BoxShadow( |
||||
|
color: isDarkMode |
||||
|
? Colors.black.withOpacity(0.2) |
||||
|
: Colors.black.withOpacity(0.05), |
||||
|
blurRadius: 10, |
||||
|
offset: const Offset(0, 2), |
||||
|
), |
||||
|
], |
||||
|
), |
||||
|
child: ClipRRect( |
||||
|
borderRadius: BorderRadius.circular(16.r), |
||||
|
child: BackdropFilter( |
||||
|
filter: isDarkMode |
||||
|
? ImageFilter.blur(sigmaX: 5, sigmaY: 5) |
||||
|
: ImageFilter.blur(sigmaX: 0, sigmaY: 0), |
||||
|
child: Padding( |
||||
|
padding: |
||||
|
EdgeInsets.symmetric(horizontal: 16.w, vertical: 8.h), |
||||
|
child: TextFormField( |
||||
|
controller: controller.feedbackController, |
||||
|
maxLines: 8, |
||||
|
maxLength: 500, |
||||
|
style: TextStyle( |
||||
|
color: isDarkMode ? Colors.white : Colors.black87, |
||||
|
), |
||||
|
decoration: InputDecoration( |
||||
|
hintText: 'feedbackHint'.tr, // 请输入您的反馈内容... |
||||
|
hintStyle: TextStyle( |
||||
|
color: isDarkMode ? Colors.white38 : Colors.black38, |
||||
|
), |
||||
|
border: InputBorder.none, |
||||
|
counterStyle: TextStyle( |
||||
|
color: isDarkMode ? Colors.white54 : Colors.black54, |
||||
|
), |
||||
|
), |
||||
|
validator: (value) { |
||||
|
if (value == null || value.trim().isEmpty) { |
||||
|
return 'feedbackRequired'.tr; // 请输入反馈内容 |
||||
|
} |
||||
|
return null; |
||||
|
}, |
||||
|
), |
||||
|
), |
||||
|
), |
||||
|
), |
||||
|
), |
||||
|
SizedBox(height: 24.h), |
||||
|
|
||||
|
// 联系方式标题 |
||||
|
// Text( |
||||
|
// 'contactInfo'.tr, // 联系方式 |
||||
|
// style: TextStyle( |
||||
|
// fontSize: 14.sp, |
||||
|
// color: isDarkMode ? Colors.white70 : Colors.black54, |
||||
|
// ), |
||||
|
// ), |
||||
|
// SizedBox(height: 16.h), |
||||
|
|
||||
|
// // 联系方式输入框 |
||||
|
// Container( |
||||
|
// decoration: BoxDecoration( |
||||
|
// color: isDarkMode |
||||
|
// ? Colors.white.withOpacity(0.05) |
||||
|
// : Colors.white, |
||||
|
// borderRadius: BorderRadius.circular(16.r), |
||||
|
// boxShadow: [ |
||||
|
// BoxShadow( |
||||
|
// color: isDarkMode |
||||
|
// ? Colors.black.withOpacity(0.2) |
||||
|
// : Colors.black.withOpacity(0.05), |
||||
|
// blurRadius: 10, |
||||
|
// offset: const Offset(0, 2), |
||||
|
// ), |
||||
|
// ], |
||||
|
// ), |
||||
|
// child: ClipRRect( |
||||
|
// borderRadius: BorderRadius.circular(16.r), |
||||
|
// child: BackdropFilter( |
||||
|
// filter: isDarkMode |
||||
|
// ? ImageFilter.blur(sigmaX: 5, sigmaY: 5) |
||||
|
// : ImageFilter.blur(sigmaX: 0, sigmaY: 0), |
||||
|
// child: Padding( |
||||
|
// padding: |
||||
|
// EdgeInsets.symmetric(horizontal: 16.w, vertical: 8.h), |
||||
|
// child: TextFormField( |
||||
|
// controller: controller.contactController, |
||||
|
// style: TextStyle( |
||||
|
// color: isDarkMode ? Colors.white : Colors.black87, |
||||
|
// ), |
||||
|
// decoration: InputDecoration( |
||||
|
// hintText: 'contactHint'.tr, // 邮箱/手机号,方便我们联系您 |
||||
|
// hintStyle: TextStyle( |
||||
|
// color: isDarkMode ? Colors.white38 : Colors.black38, |
||||
|
// ), |
||||
|
// border: InputBorder.none, |
||||
|
// ), |
||||
|
// ), |
||||
|
// ), |
||||
|
// ), |
||||
|
// ), |
||||
|
// ), |
||||
|
// SizedBox(height: 40.h), |
||||
|
|
||||
|
// 提交按钮 |
||||
|
Obx(() => ElevatedButton( |
||||
|
onPressed: controller.isSubmitting.value |
||||
|
? null |
||||
|
: controller.submitFeedback, |
||||
|
style: ElevatedButton.styleFrom( |
||||
|
backgroundColor: Colors.blue[600], |
||||
|
padding: EdgeInsets.symmetric(vertical: 12.h), |
||||
|
shape: RoundedRectangleBorder( |
||||
|
borderRadius: BorderRadius.circular(16.r), |
||||
|
), |
||||
|
elevation: 0, |
||||
|
), |
||||
|
child: controller.isSubmitting.value |
||||
|
? SizedBox( |
||||
|
height: 20.h, |
||||
|
width: 20.h, |
||||
|
child: CircularProgressIndicator( |
||||
|
strokeWidth: 2.w, |
||||
|
valueColor: const AlwaysStoppedAnimation<Color>( |
||||
|
Colors.white), |
||||
|
), |
||||
|
) |
||||
|
: Text( |
||||
|
'submit'.tr, // 提交 |
||||
|
style: TextStyle( |
||||
|
fontSize: 16.sp, |
||||
|
fontWeight: FontWeight.w500, |
||||
|
color: Colors.white, |
||||
|
), |
||||
|
), |
||||
|
)), |
||||
|
], |
||||
|
), |
||||
|
), |
||||
|
), |
||||
|
); |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue