314 lines
10 KiB
Dart
314 lines
10 KiB
Dart
|
import 'package:flutter/material.dart';
|
||
|
import 'package:flutter/services.dart';
|
||
|
import 'package:image_picker/image_picker.dart';
|
||
|
import 'dart:io';
|
||
|
import '../../../../../customWidget/photo_picker_row.dart';
|
||
|
import 'package:qhd_prevention/pages/my_appbar.dart';
|
||
|
|
||
|
// feedback_type.dart
|
||
|
enum FeedbackType {
|
||
|
systemError,
|
||
|
uiOptimization,
|
||
|
designIssue,
|
||
|
performanceIssue,
|
||
|
other,
|
||
|
}
|
||
|
|
||
|
class FeedbackApp extends StatelessWidget {
|
||
|
const FeedbackApp({super.key});
|
||
|
|
||
|
@override
|
||
|
Widget build(BuildContext context) {
|
||
|
return Scaffold(
|
||
|
appBar: MyAppbar(title:'问题反馈' ),
|
||
|
body: const FeedbackPage(),
|
||
|
);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
class FeedbackPage extends StatefulWidget {
|
||
|
const FeedbackPage({super.key});
|
||
|
|
||
|
@override
|
||
|
State<FeedbackPage> createState() => _FeedbackPageState();
|
||
|
}
|
||
|
|
||
|
class _FeedbackPageState extends State<FeedbackPage> {
|
||
|
final _formKey = GlobalKey<FormState>();
|
||
|
final TextEditingController _titleController = TextEditingController();
|
||
|
final TextEditingController _descriptionController = TextEditingController();
|
||
|
|
||
|
// 反馈类型
|
||
|
FeedbackType? _selectedType = FeedbackType.other;
|
||
|
|
||
|
// 上传的图片
|
||
|
List<File> _images = [];
|
||
|
|
||
|
// 获取反馈类型名称
|
||
|
String _getTypeName(FeedbackType type) {
|
||
|
switch (type) {
|
||
|
case FeedbackType.systemError:
|
||
|
return '系统错误';
|
||
|
case FeedbackType.uiOptimization:
|
||
|
return '界面优化';
|
||
|
case FeedbackType.designIssue:
|
||
|
return '设计缺陷';
|
||
|
case FeedbackType.performanceIssue:
|
||
|
return '性能问题';
|
||
|
case FeedbackType.other:
|
||
|
return '其他';
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// 选择图片
|
||
|
Future<void> _pickImage() async {
|
||
|
if (_images.length >= 4) return;
|
||
|
|
||
|
final picker = ImagePicker();
|
||
|
try {
|
||
|
final pickedFile = await picker.pickImage(source: ImageSource.gallery);
|
||
|
if (pickedFile != null) {
|
||
|
setState(() {
|
||
|
_images.add(File(pickedFile.path));
|
||
|
});
|
||
|
}
|
||
|
} catch (e) {
|
||
|
ScaffoldMessenger.of(
|
||
|
context,
|
||
|
).showSnackBar(const SnackBar(content: Text('无法访问相册,请检查权限设置')));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// 删除图片
|
||
|
void _removeImage(int index) {
|
||
|
setState(() {
|
||
|
_images.removeAt(index);
|
||
|
});
|
||
|
}
|
||
|
|
||
|
@override
|
||
|
Widget build(BuildContext context) {
|
||
|
return Scaffold(
|
||
|
appBar: MyAppbar(title: "问题反馈"),
|
||
|
body: Container(
|
||
|
color: Colors.white,
|
||
|
child: Form(
|
||
|
key: _formKey,
|
||
|
child: SingleChildScrollView(
|
||
|
padding: const EdgeInsets.all(16),
|
||
|
child: Column(
|
||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||
|
children: [
|
||
|
// 标题输入
|
||
|
const Text('标题', style: TextStyle(fontWeight: FontWeight.bold)),
|
||
|
const SizedBox(height: 8),
|
||
|
TextFormField(
|
||
|
controller: _titleController,
|
||
|
decoration: const InputDecoration(
|
||
|
hintText: '请输入标题...',
|
||
|
border: OutlineInputBorder(),
|
||
|
),
|
||
|
validator: (value) {
|
||
|
if (value == null || value.isEmpty) {
|
||
|
return '请输入标题';
|
||
|
}
|
||
|
return null;
|
||
|
},
|
||
|
),
|
||
|
const SizedBox(height: 24),
|
||
|
|
||
|
// 问题描述
|
||
|
const Text(
|
||
|
'详细问题和意见',
|
||
|
style: TextStyle(fontWeight: FontWeight.bold),
|
||
|
),
|
||
|
const SizedBox(height: 8),
|
||
|
TextFormField(
|
||
|
controller: _descriptionController,
|
||
|
maxLines: 5,
|
||
|
decoration:
|
||
|
const InputDecoration(
|
||
|
hintText: '请补充详细问题和意见...',
|
||
|
border: OutlineInputBorder(),
|
||
|
contentPadding: EdgeInsets.all(10),
|
||
|
),
|
||
|
validator: (value) {
|
||
|
if (value == null || value.isEmpty) {
|
||
|
return '请补充详细问题和意见';
|
||
|
}
|
||
|
return null;
|
||
|
},
|
||
|
),
|
||
|
const SizedBox(height: 24),
|
||
|
|
||
|
// 反馈类型
|
||
|
const Text(
|
||
|
'反馈类型',
|
||
|
style: TextStyle(fontWeight: FontWeight.bold),
|
||
|
),
|
||
|
const SizedBox(height: 8),
|
||
|
Wrap(
|
||
|
spacing: 16,
|
||
|
children:
|
||
|
FeedbackType.values.map((type) {
|
||
|
return ChoiceChip(
|
||
|
label: Text(_getTypeName(type)),
|
||
|
selected: _selectedType == type,
|
||
|
onSelected: (selected) {
|
||
|
setState(() {
|
||
|
if (selected) {
|
||
|
_selectedType = type;
|
||
|
}
|
||
|
});
|
||
|
},
|
||
|
);
|
||
|
}).toList(),
|
||
|
),
|
||
|
|
||
|
// const SizedBox(height: 14),
|
||
|
// Row(
|
||
|
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||
|
// children: [
|
||
|
// const Text(
|
||
|
// '请提供相关问题的截图或照片',
|
||
|
// style: TextStyle(fontWeight: FontWeight.bold),
|
||
|
// ),
|
||
|
// Text(
|
||
|
// '${_images.length}/4',
|
||
|
// style: const TextStyle(color: Colors.grey),
|
||
|
// ),
|
||
|
// ],),
|
||
|
|
||
|
// 图片上传
|
||
|
const SizedBox(height: 16),
|
||
|
|
||
|
RepairedPhotoSection(
|
||
|
horizontalPadding: 0,
|
||
|
title: "请提供相关问题的截图或照片",
|
||
|
maxCount: 4,
|
||
|
mediaType: MediaType.image,
|
||
|
onChanged: (files) {
|
||
|
// 上传 files 到服务器
|
||
|
},
|
||
|
onAiIdentify: () {},
|
||
|
),
|
||
|
|
||
|
// GridView.builder(
|
||
|
// shrinkWrap: true,
|
||
|
// physics: const NeverScrollableScrollPhysics(),
|
||
|
// gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
|
||
|
// crossAxisCount: 4,
|
||
|
// crossAxisSpacing: 8,
|
||
|
// mainAxisSpacing: 8,
|
||
|
// childAspectRatio: 1,
|
||
|
// ),
|
||
|
// itemCount: _images.length + 1,
|
||
|
// itemBuilder: (context, index) {
|
||
|
// if (index < _images.length) {
|
||
|
// return Stack(
|
||
|
// children: [
|
||
|
// Container(
|
||
|
// decoration: BoxDecoration(
|
||
|
// borderRadius: BorderRadius.circular(8),
|
||
|
// image: DecorationImage(
|
||
|
// image: FileImage(_images[index]),
|
||
|
// fit: BoxFit.cover,
|
||
|
// ),
|
||
|
// ),
|
||
|
// ),
|
||
|
// Positioned(
|
||
|
// top: 4,
|
||
|
// right: 4,
|
||
|
// child: GestureDetector(
|
||
|
// onTap: () => _removeImage(index),
|
||
|
// child: Container(
|
||
|
// padding: const EdgeInsets.all(2),
|
||
|
// decoration: const BoxDecoration(
|
||
|
// shape: BoxShape.circle,
|
||
|
// color: Colors.black54,
|
||
|
// ),
|
||
|
// child: const Icon(
|
||
|
// Icons.close,
|
||
|
// size: 16,
|
||
|
// color: Colors.white,
|
||
|
// ),
|
||
|
// ),
|
||
|
// ),
|
||
|
// ),
|
||
|
// ],
|
||
|
// );
|
||
|
// } else {
|
||
|
// return _images.length < 4
|
||
|
// ? GestureDetector(
|
||
|
// onTap: _pickImage,
|
||
|
// child: Container(
|
||
|
// decoration: BoxDecoration(
|
||
|
// border: Border.all(color: Colors.grey),
|
||
|
// borderRadius: BorderRadius.circular(8),
|
||
|
// ),
|
||
|
// child: const Icon(
|
||
|
// Icons.add,
|
||
|
// size: 40,
|
||
|
// color: Colors.grey,
|
||
|
// ),
|
||
|
// ),
|
||
|
// )
|
||
|
// : const SizedBox();
|
||
|
// }
|
||
|
// },
|
||
|
// ),
|
||
|
const SizedBox(height: 40),
|
||
|
|
||
|
// 提交按钮
|
||
|
SizedBox(
|
||
|
width: double.infinity,
|
||
|
child: ElevatedButton(
|
||
|
onPressed: _submitFeedback,
|
||
|
style: ElevatedButton.styleFrom(
|
||
|
backgroundColor: Colors.blue,
|
||
|
padding: const EdgeInsets.symmetric(vertical: 16),
|
||
|
shape: RoundedRectangleBorder(
|
||
|
borderRadius: BorderRadius.circular(8),
|
||
|
),
|
||
|
),
|
||
|
child: const Text(
|
||
|
'提交',
|
||
|
style: TextStyle(fontSize: 18, color: Colors.white),
|
||
|
),
|
||
|
),
|
||
|
),
|
||
|
],
|
||
|
),
|
||
|
),
|
||
|
),
|
||
|
),
|
||
|
);
|
||
|
}
|
||
|
|
||
|
// 提交反馈
|
||
|
void _submitFeedback() {
|
||
|
if (_formKey.currentState!.validate()) {
|
||
|
// 模拟提交过程
|
||
|
showDialog(
|
||
|
context: context,
|
||
|
barrierDismissible: false,
|
||
|
builder: (context) => const Center(child: CircularProgressIndicator()),
|
||
|
);
|
||
|
|
||
|
Future.delayed(const Duration(seconds: 2), () {
|
||
|
Navigator.pop(context); // 关闭加载对话框
|
||
|
ScaffoldMessenger.of(
|
||
|
context,
|
||
|
).showSnackBar(const SnackBar(content: Text('反馈提交成功!')));
|
||
|
|
||
|
// 重置表单
|
||
|
_formKey.currentState!.reset();
|
||
|
setState(() {
|
||
|
_images.clear();
|
||
|
_selectedType = FeedbackType.other;
|
||
|
});
|
||
|
});
|
||
|
}
|
||
|
}
|
||
|
}
|