| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538 |
- import 'package:flutter/material.dart';
- import 'package:url_launcher/url_launcher.dart';
-
- class HelpCenterScreen extends StatefulWidget {
- const HelpCenterScreen({super.key});
-
- @override
- State<HelpCenterScreen> createState() => _HelpCenterScreenState();
- }
-
- class _HelpCenterScreenState extends State<HelpCenterScreen> {
- final TextEditingController _searchController = TextEditingController();
- final List<FAQItem> _allFAQs = [];
- List<FAQItem> _filteredFAQs = [];
- List<FAQCategory> _categories = [];
- bool _isSearching = false;
- String _selectedCategoryId = 'all';
-
- @override
- void initState() {
- super.initState();
- _initializeData();
- _searchController.addListener(_onSearchChanged);
- }
-
- @override
- void dispose() {
- _searchController.dispose();
- super.dispose();
- }
-
- void _initializeData() {
- // 初始化分类数据
- _categories = [
- FAQCategory(id: 'all', name: '全部', icon: Icons.all_inclusive, color: Colors.blue),
- FAQCategory(id: 'account', name: '账户问题', icon: Icons.person, color: Colors.purple),
- FAQCategory(id: 'payment', name: '支付相关', icon: Icons.payment, color: Colors.green),
- FAQCategory(id: 'order', name: '订单问题', icon: Icons.shopping_cart, color: Colors.orange),
- FAQCategory(id: 'app', name: '应用使用', icon: Icons.phone_iphone, color: Colors.red),
- FAQCategory(id: 'privacy', name: '隐私安全', icon: Icons.security, color: Colors.teal),
- FAQCategory(id: 'other', name: '其他问题', icon: Icons.help_outline, color: Colors.grey),
- ];
-
- // 初始化FAQ数据
- _allFAQs.addAll([
- FAQItem(
- id: '1',
- question: '如何修改个人资料?',
- answer: '您可以在"我的"页面点击头像或个人信息进入编辑页面进行修改。修改完成后记得点击保存按钮。',
- categoryId: 'account',
- isExpanded: false,
- ),
- FAQItem(
- id: '2',
- question: '忘记密码怎么办?',
- answer: '在登录页面点击"忘记密码",按照提示输入注册邮箱或手机号,系统将发送重置密码链接到您的邮箱或手机。',
- categoryId: 'account',
- isExpanded: false,
- ),
- FAQItem(
- id: '3',
- question: '如何绑定/解绑第三方登录?',
- answer: '进入"设置" -> "账户与安全" -> "第三方账号绑定",在这里可以绑定或解绑微信、Apple ID等第三方账号。',
- categoryId: 'account',
- isExpanded: false,
- ),
- FAQItem(
- id: '4',
- question: '支付方式有哪些?',
- answer: '我们支持微信支付、支付宝、银联卡等多种支付方式。在支付时可以选择您方便的支付方式进行付款。',
- categoryId: 'payment',
- isExpanded: false,
- ),
- FAQItem(
- id: '5',
- question: '支付遇到问题怎么办?',
- answer: '1. 检查网络连接\n2. 确认支付账户余额充足\n3. 检查银行卡是否过期\n4. 如仍无法解决,请联系客服提供订单号',
- categoryId: 'payment',
- isExpanded: false,
- ),
- FAQItem(
- id: '6',
- question: '如何查看订单状态?',
- answer: '进入"我的订单"页面,可以查看所有订单的详细状态,包括待支付、进行中、已完成、已取消等状态。',
- categoryId: 'order',
- isExpanded: false,
- ),
- FAQItem(
- id: '7',
- question: '如何取消订单?',
- answer: '在订单详情页面,如果订单状态允许取消,会出现"取消订单"按钮。请注意,部分订单在特定状态下不可取消。',
- categoryId: 'order',
- isExpanded: false,
- ),
- FAQItem(
- id: '8',
- question: '应用出现闪退怎么办?',
- answer: '1. 尝试重启应用\n2. 检查应用是否为最新版本\n3. 清理手机缓存\n4. 重启手机设备\n5. 如问题持续,请反馈给我们',
- categoryId: 'app',
- isExpanded: false,
- ),
- FAQItem(
- id: '9',
- question: '如何更新应用到最新版本?',
- answer: 'iOS用户:前往App Store搜索应用并更新\nAndroid用户:前往应用商店或应用内检查更新',
- categoryId: 'app',
- isExpanded: false,
- ),
- FAQItem(
- id: '10',
- question: '如何保护我的隐私信息?',
- answer: '我们采用加密技术保护您的数据,不会向第三方泄露您的个人信息。您可以在隐私设置中管理数据权限。',
- categoryId: 'privacy',
- isExpanded: false,
- ),
- FAQItem(
- id: '11',
- question: '如何联系客服?',
- answer: '1. 拨打电话:400-123-4567(工作日 9:00-18:00)\n2. 发送邮件:support@example.com\n3. 在线客服:应用内"我的客服"',
- categoryId: 'other',
- isExpanded: false,
- ),
- FAQItem(
- id: '12',
- question: '服务时间是什么时候?',
- answer: '在线客服:每天 8:00-22:00\n电话客服:工作日 9:00-18:00\n节假日服务时间可能调整',
- categoryId: 'other',
- isExpanded: false,
- ),
- ]);
-
- _filteredFAQs = List.from(_allFAQs);
- }
-
- void _onSearchChanged() {
- final query = _searchController.text.trim();
- setState(() {
- _isSearching = query.isNotEmpty;
- _filteredFAQs = _allFAQs.where((faq) {
- final matchesSearch = faq.question.toLowerCase().contains(query.toLowerCase()) ||
- (faq.answer?.toLowerCase().contains(query.toLowerCase()) ?? false);
-
- final matchesCategory = _selectedCategoryId == 'all' ||
- faq.categoryId == _selectedCategoryId;
-
- return matchesSearch && matchesCategory;
- }).toList();
- });
- }
-
- void _selectCategory(String categoryId) {
- setState(() {
- _selectedCategoryId = categoryId;
- _filteredFAQs = _allFAQs.where((faq) {
- final matchesSearch = _isSearching
- ? (faq.question.toLowerCase().contains(_searchController.text.toLowerCase()) ||
- (faq.answer?.toLowerCase().contains(_searchController.text.toLowerCase()) ?? false))
- : true;
-
- final matchesCategory = categoryId == 'all' || faq.categoryId == categoryId;
-
- return matchesSearch && matchesCategory;
- }).toList();
- });
- }
-
- void _toggleFAQ(int index) {
- setState(() {
- _filteredFAQs[index].isExpanded = !_filteredFAQs[index].isExpanded;
- });
- }
-
- Future<void> _contactSupport(String method) async {
- switch (method) {
- case 'phone':
- final Uri telUri = Uri.parse('tel:4001234567');
- if (await canLaunchUrl(telUri)) {
- await launchUrl(telUri);
- }
- break;
- case 'email':
- final Uri emailUri = Uri(
- scheme: 'mailto',
- path: 'support@example.com',
- queryParameters: {'subject': '用户咨询'},
- );
- if (await canLaunchUrl(emailUri)) {
- await launchUrl(emailUri);
- }
- break;
- }
- }
-
- void _showFeedbackDialog(BuildContext context) {
- showDialog(
- context: context,
- builder: (context) => AlertDialog(
- title: const Text('问题反馈'),
- content: const Text('您可以将遇到的问题详细描述并发送给我们,我们会尽快处理。'),
- actions: [
- TextButton(
- onPressed: () => Navigator.of(context).pop(),
- child: const Text('取消'),
- ),
- TextButton(
- onPressed: () {
- Navigator.of(context).pop();
- _contactSupport('email');
- },
- child: const Text('去反馈'),
- ),
- ],
- ),
- );
- }
-
- @override
- Widget build(BuildContext context) {
- return Scaffold(
- appBar: AppBar(
- title: const Text('帮助中心'),
- actions: [
- IconButton(
- icon: const Icon(Icons.feedback_outlined),
- tooltip: '问题反馈',
- onPressed: () => _showFeedbackDialog(context),
- ),
- ],
- ),
- body: Column(
- children: [
- // 搜索栏
- Padding(
- padding: const EdgeInsets.all(16),
- child: Container(
- decoration: BoxDecoration(
- color: Colors.grey[100],
- borderRadius: BorderRadius.circular(12),
- border: Border.all(color: Colors.grey[300]!),
- ),
- child: TextField(
- controller: _searchController,
- decoration: InputDecoration(
- hintText: '搜索问题或关键词...',
- prefixIcon: const Icon(Icons.search, color: Colors.grey),
- border: InputBorder.none,
- suffixIcon: _searchController.text.isNotEmpty
- ? IconButton(
- icon: const Icon(Icons.clear, color: Colors.grey),
- onPressed: () {
- _searchController.clear();
- _onSearchChanged();
- },
- )
- : null,
- contentPadding: const EdgeInsets.symmetric(vertical: 14),
- ),
- ),
- ),
- ),
-
- // 分类导航
- SizedBox(
- height: 100,
- child: ListView.builder(
- scrollDirection: Axis.horizontal,
- padding: const EdgeInsets.symmetric(horizontal: 16),
- itemCount: _categories.length,
- itemBuilder: (context, index) {
- final category = _categories[index];
- final isSelected = _selectedCategoryId == category.id;
-
- return Padding(
- padding: const EdgeInsets.only(right: 12),
- child: Column(
- children: [
- GestureDetector(
- onTap: () => _selectCategory(category.id),
- child: Container(
- width: 70,
- height: 70,
- decoration: BoxDecoration(
- color: isSelected
- ? category.color.withOpacity(0.2)
- : Colors.grey[50],
- borderRadius: BorderRadius.circular(16),
- border: Border.all(
- color: isSelected
- ? category.color
- : Colors.transparent,
- width: 2,
- ),
- ),
- child: Column(
- mainAxisAlignment: MainAxisAlignment.center,
- children: [
- Icon(category.icon, color: category.color, size: 28),
- const SizedBox(height: 4),
- ],
- ),
- ),
- ),
- const SizedBox(height: 4),
- Text(
- category.name,
- style: TextStyle(
- fontSize: 12,
- fontWeight: isSelected ? FontWeight.bold : FontWeight.normal,
- color: isSelected ? category.color : Colors.grey[700],
- ),
- ),
- ],
- ),
- );
- },
- ),
- ),
-
- // 问题列表
- Expanded(
- child: _filteredFAQs.isEmpty
- ? Center(
- child: Column(
- mainAxisAlignment: MainAxisAlignment.center,
- children: [
- Icon(
- Icons.search_off,
- size: 60,
- color: Colors.grey[400],
- ),
- const SizedBox(height: 16),
- Text(
- _isSearching
- ? '没有找到相关问题的解答'
- : '暂无问题',
- style: TextStyle(
- color: Colors.grey[600],
- fontSize: 16,
- ),
- ),
- if (_isSearching) ...[
- const SizedBox(height: 8),
- TextButton(
- onPressed: () => _showFeedbackDialog(context),
- child: const Text('反馈问题给我们'),
- ),
- ],
- ],
- ),
- )
- : ListView.builder(
- padding: const EdgeInsets.all(16),
- itemCount: _filteredFAQs.length,
- itemBuilder: (context, index) {
- final faq = _filteredFAQs[index];
- final category = _categories.firstWhere(
- (cat) => cat.id == faq.categoryId,
- orElse: () => _categories.last,
- );
-
- return Card(
- margin: const EdgeInsets.only(bottom: 12),
- elevation: 1,
- shape: RoundedRectangleBorder(
- borderRadius: BorderRadius.circular(12),
- side: BorderSide(color: Colors.grey[200]!),
- ),
- child: ExpansionTile(
- key: Key(faq.id),
- initiallyExpanded: faq.isExpanded,
- onExpansionChanged: (_) => _toggleFAQ(index),
- leading: Container(
- width: 36,
- height: 36,
- decoration: BoxDecoration(
- color: category.color.withOpacity(0.1),
- borderRadius: BorderRadius.circular(8),
- ),
- child: Icon(
- category.icon,
- color: category.color,
- size: 20,
- ),
- ),
- title: Text(
- faq.question,
- style: const TextStyle(
- fontWeight: FontWeight.w500,
- fontSize: 15,
- ),
- ),
- children: [
- Padding(
- padding: const EdgeInsets.fromLTRB(68, 8, 16, 16),
- child: Column(
- crossAxisAlignment: CrossAxisAlignment.start,
- children: [
- Text(
- faq.answer ?? '',
- style: TextStyle(
- color: Colors.grey[700],
- fontSize: 14,
- height: 1.5,
- ),
- ),
- if (faq.id == '11') ...[
- const SizedBox(height: 16),
- const Text(
- '快速联系:',
- style: TextStyle(
- fontWeight: FontWeight.bold,
- fontSize: 14,
- ),
- ),
- const SizedBox(height: 8),
- Row(
- children: [
- ElevatedButton.icon(
- onPressed: () => _contactSupport('phone'),
- icon: const Icon(Icons.phone, size: 16),
- label: const Text('电话联系'),
- style: ElevatedButton.styleFrom(
- backgroundColor: Colors.green[50],
- foregroundColor: Colors.green,
- elevation: 0,
- ),
- ),
- const SizedBox(width: 12),
- ElevatedButton.icon(
- onPressed: () => _contactSupport('email'),
- icon: const Icon(Icons.email, size: 16),
- label: const Text('发送邮件'),
- style: ElevatedButton.styleFrom(
- backgroundColor: Colors.blue[50],
- foregroundColor: Colors.blue,
- elevation: 0,
- ),
- ),
- ],
- ),
- ],
- ],
- ),
- ),
- ],
- ),
- );
- },
- ),
- ),
-
- // 底部联系栏
- Container(
- padding: const EdgeInsets.all(16),
- decoration: BoxDecoration(
- color: Colors.grey[50],
- border: Border(top: BorderSide(color: Colors.grey[300]!)),
- ),
- child: Column(
- children: [
- const Text(
- '没有找到您需要的答案?',
- style: TextStyle(
- fontWeight: FontWeight.w600,
- fontSize: 15,
- ),
- ),
- const SizedBox(height: 8),
- const Text(
- '我们的客服团队随时为您提供帮助',
- style: TextStyle(color: Colors.grey, fontSize: 13),
- ),
- const SizedBox(height: 16),
- Row(
- mainAxisAlignment: MainAxisAlignment.spaceEvenly,
- children: [
- Expanded(
- child: OutlinedButton.icon(
- onPressed: () => _contactSupport('phone'),
- icon: const Icon(Icons.phone, size: 18),
- label: const Text('电话客服'),
- style: OutlinedButton.styleFrom(
- padding: const EdgeInsets.symmetric(vertical: 12),
- ),
- ),
- ),
- const SizedBox(width: 12),
- Expanded(
- child: ElevatedButton.icon(
- onPressed: () => _showFeedbackDialog(context),
- icon: const Icon(Icons.chat, size: 18),
- label: const Text('在线反馈'),
- style: ElevatedButton.styleFrom(
- padding: const EdgeInsets.symmetric(vertical: 12),
- ),
- ),
- ),
- ],
- ),
- ],
- ),
- ),
- ],
- ),
- );
- }
- }
-
- // 数据模型
- class FAQItem {
- final String id;
- final String question;
- final String? answer;
- final String categoryId;
- bool isExpanded;
-
- FAQItem({
- required this.id,
- required this.question,
- this.answer,
- required this.categoryId,
- required this.isExpanded,
- });
- }
-
- class FAQCategory {
- final String id;
- final String name;
- final IconData icon;
- final Color color;
-
- FAQCategory({
- required this.id,
- required this.name,
- required this.icon,
- required this.color,
- });
- }
|