diff --git a/lib/api/common_api.dart b/lib/api/common_api.dart index 37dce77..9331eb3 100644 --- a/lib/api/common_api.dart +++ b/lib/api/common_api.dart @@ -11,5 +11,8 @@ class CommonApi { ///[source]=wechat_open [clientId]=428a8310cd442757ae699df5d894f051 [grantType]=social [socialState]=1 static const String wxLogin = '/app/member/bind/wechat'; + // 获取字典枚举 + static const String dictionaryApi = '/system/dict/data/type/'; + ///resource/oss/upload } diff --git a/lib/api/video_api.dart b/lib/api/video_api.dart index d611143..50ea08c 100644 --- a/lib/api/video_api.dart +++ b/lib/api/video_api.dart @@ -8,8 +8,10 @@ class VideoApi { // post static const String myPublicList = '/app/vlog/myPublicList'; // 我发布的视频 static const String myLikedList = '/app/vlog/myLikedList'; // 我点赞的视频 - static const String videoCommentList = '/comment/list'; // 视频点赞列表 + static const String videoCommentList = '/comment/list'; // 视频评论列表 static const String doVideoComment = '/app/comment/publish'; // 发布评论 + static const String reportVideoApi = '/app/feedback/add'; // 投诉视频 + static const String unlike = '/app/vlog/unlike'; //取消点赞 diff --git a/lib/pages/video/module/recommend.dart b/lib/pages/video/module/recommend.dart index 59c85a9..5dae672 100644 --- a/lib/pages/video/module/recommend.dart +++ b/lib/pages/video/module/recommend.dart @@ -1260,9 +1260,17 @@ void handleComment(index) { ), ], ), - onTap: () { - // 举报 - }, + onTap: ()async { + player.pause(); + // 跳转到举报页面并等待返回结果 + final result = await Get.toNamed( + '/report', + arguments: videoList[videoModuleController + .videoPlayIndex.value]); + if (result != null) { + player.play(); + }; + }, ), ], ), diff --git a/lib/pages/video/report.dart b/lib/pages/video/report.dart new file mode 100644 index 0000000..9b4811e --- /dev/null +++ b/lib/pages/video/report.dart @@ -0,0 +1,249 @@ +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:loopin/service/http.dart'; +import 'package:loopin/api/video_api.dart'; +import 'package:flutter/services.dart'; +import 'package:loopin/components/my_toast.dart'; +import 'package:loopin/utils/getCommonDictionary.dart'; +import '../../behavior/custom_scroll_behavior.dart'; + +class ReportPage extends StatefulWidget { + const ReportPage({super.key}); + + @override + State createState() => _ReportPageState(); +} + +class _ReportPageState extends State with SingleTickerProviderStateMixin { + int? _selectedIndex; + late dynamic args; + final TextEditingController _reportController = TextEditingController(); + final GlobalKey scaffoldKey = GlobalKey(); + List reasonTypeData = []; + + @override + void initState() { + super.initState(); + args = Get.arguments ?? {}; + getReportReasons('ums_feedback_reasontype'); // 获取投诉枚举 + } + + @override + void dispose() { + _reportController.dispose(); + super.dispose(); + } + + // 加载数据的方法 + Future getReportReasons(String key) async { + try { + final data = await Commondictionary.getCommonDictionary(key); + setState(() { + reasonTypeData = data; + }); + } catch (e) { + print('加载失败: $e'); + } + } + + // 投诉视频 + Future doReportVideo(String dictValue, String reasonText) async { + try { + final res = await Http.post(VideoApi.reportVideoApi, data: { + 'type': '1', // 类型 1 举报 2 投诉 3 建议 + 'content': reasonText, + 'aimId': args['id'], + 'aimType': '4', // 1 会员 2 群组 3 评论 4 视频 5 聊天 + 'reasonType':dictValue + + }); + if (res['code'] == 200) { // 投诉成功,返回视频页面 + MyToast().tip( + title: '投诉成功', + position: 'center', + type: 'success', + ); + Get.back(result: {'returnTo': '/'}); + }else{ + MyToast().tip( + title: '投诉失败', + position: 'center', + type: 'error', + ); + } + } catch (e) { + print('投诉失败: $e'); + } + } + + @override + Widget build(BuildContext context) { + return Scaffold( + key: scaffoldKey, + backgroundColor: Colors.white, + appBar: AppBar( + centerTitle: true, + backgroundColor: Colors.white, + foregroundColor: Colors.black, + elevation: 0, + title: const Text( + '举报', + style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold), + ), + ), + body: ScrollConfiguration( + behavior: CustomScrollBehavior().copyWith(scrollbars: false), + child: SingleChildScrollView( + padding: const EdgeInsets.all(16), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const Text( + '您的举报我们将尽快受理,核实后我们将第一时间告知受理结果,请尽量提交完整的举报描述', + style: TextStyle(fontSize: 13, color: Colors.grey, height: 1.4), + ), + const SizedBox(height: 20), + // 两列布局的投诉选项 + reasonTypeData.isEmpty + ? const Center(child: CircularProgressIndicator()) + : GridView.builder( + shrinkWrap: true, + physics: const NeverScrollableScrollPhysics(), + gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: 2, + crossAxisSpacing: 8, + mainAxisSpacing: 2, + childAspectRatio: 4, + ), + itemCount: reasonTypeData.length, + itemBuilder: (context, index) { + return _buildRadioItem(index); + }, + ), + const SizedBox(height: 24), + const Text( + '举报描述(选填)', + style: TextStyle(fontSize: 14, color: Colors.black54, fontWeight: FontWeight.w500), + ), + const SizedBox(height: 8), + Container( + decoration: BoxDecoration( + border: Border.all(color: Colors.grey.shade300), + borderRadius: BorderRadius.circular(4), + ), + child: TextField( + controller: _reportController, + maxLines: 5, + maxLength: 32, + cursorColor: Colors.black54, + style: const TextStyle( + color: Colors.black54, + fontSize: 14, + ), + decoration: const InputDecoration( + contentPadding: EdgeInsets.all(12), + border: InputBorder.none, + hintText: '请输入内容', + hintStyle: TextStyle(color: Colors.grey, fontSize: 13), + ), + ), + ), + Align( + alignment: Alignment.centerRight, + child: Text( + '${_reportController.text.length}/32', + style: const TextStyle(fontSize: 12, color: Colors.grey), + ), + ), + const SizedBox(height: 30), + SizedBox( + width: double.infinity, + child: ElevatedButton( + onPressed: _selectedIndex != null ? _submitReport : null, + style: ElevatedButton.styleFrom( + backgroundColor: Colors.red, + foregroundColor: Colors.white, + padding: const EdgeInsets.symmetric(vertical: 14), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(6), + ), + ), + child: const Text('提交', style: TextStyle(fontSize: 15)), + ), + ), + ], + ), + ), + ), + ); + } + + Widget _buildRadioItem(int index) { + final item = reasonTypeData[index]; + final isSelected = _selectedIndex == index; + + return GestureDetector( + onTap: () { + setState(() { + _selectedIndex = index; + }); + }, + child: Container( + padding: const EdgeInsets.symmetric(vertical: 8), + child: Row( + children: [ + Container( + width: 20, + height: 20, + decoration: BoxDecoration( + shape: BoxShape.circle, + border: Border.all( + color: isSelected ? Colors.green : Colors.grey, + width: 1.5, + ), + ), + child: isSelected + ? Center( + child: Container( + width: 12, + height: 12, + decoration: const BoxDecoration( + shape: BoxShape.circle, + color: Colors.green, + ), + ), + ) + : null, + ), + const SizedBox(width: 8), + Expanded( + child: Text( + item['dictLabel'] ?? '未知原因', + style: TextStyle( + fontSize: 13, + color: isSelected ? Colors.green : Colors.black54, + ), + overflow: TextOverflow.ellipsis, + ), + ), + ], + ), + ), + ); + } + + void _submitReport() { + if (_selectedIndex == null) { + MyToast().tip( + title: '请选择举报原因!', + position: 'center', + type: 'error', + ); + return; + } + // 获取选中的原因 + final selectedReason = reasonTypeData[_selectedIndex!]; + final reasonText = _reportController.text; + doReportVideo(selectedReason['dictValue'],reasonText); + } +} \ No newline at end of file diff --git a/lib/router/index.dart b/lib/router/index.dart index f1b894b..0d694a0 100644 --- a/lib/router/index.dart +++ b/lib/router/index.dart @@ -12,6 +12,7 @@ import 'package:loopin/pages/my/nick_name.dart'; import 'package:loopin/pages/my/setting.dart'; import 'package:loopin/pages/my/user_info.dart'; import 'package:loopin/pages/my/vloger.dart'; +import 'package:loopin/pages/video/report.dart'; import '../layouts/index.dart'; /* 引入路由页面 */ @@ -34,6 +35,7 @@ final Map routes = { '/order': const Order(), '/order/detail': const OrderDetail(), '/vloger': const Vloger(), + '/report': const ReportPage(), //settins '/setting': const Setting(), '/userInfo': const UserInfo(), diff --git a/lib/utils/getCommonDictionary.dart b/lib/utils/getCommonDictionary.dart new file mode 100644 index 0000000..4b8ce91 --- /dev/null +++ b/lib/utils/getCommonDictionary.dart @@ -0,0 +1,26 @@ +library; + +import 'package:loopin/api/common_api.dart'; +import 'package:loopin/service/http.dart'; + +class Commondictionary { + // 获取字段配置 + static Future> getCommonDictionary(String key) async { + try { + final res = await Http.get('${CommonApi.dictionaryApi}$key'); + + if (res['code'] == 200 && res['data'] != null) { + final data = res['data']; + if (data is List) { + return data; + } else { + return []; + } + } + return []; + } catch (e) { + print('获取字典数据失败: $e'); + return []; + } + } +} \ No newline at end of file