1、全局枚举字典工具类
2、视频投诉页面联调
This commit is contained in:
parent
53f368938a
commit
c7ded11e89
@ -11,5 +11,8 @@ class CommonApi {
|
|||||||
///[source]=wechat_open [clientId]=428a8310cd442757ae699df5d894f051 [grantType]=social [socialState]=1
|
///[source]=wechat_open [clientId]=428a8310cd442757ae699df5d894f051 [grantType]=social [socialState]=1
|
||||||
static const String wxLogin = '/app/member/bind/wechat';
|
static const String wxLogin = '/app/member/bind/wechat';
|
||||||
|
|
||||||
|
// 获取字典枚举
|
||||||
|
static const String dictionaryApi = '/system/dict/data/type/';
|
||||||
|
|
||||||
///resource/oss/upload
|
///resource/oss/upload
|
||||||
}
|
}
|
||||||
|
@ -8,8 +8,10 @@ class VideoApi {
|
|||||||
// post
|
// post
|
||||||
static const String myPublicList = '/app/vlog/myPublicList'; // 我发布的视频
|
static const String myPublicList = '/app/vlog/myPublicList'; // 我发布的视频
|
||||||
static const String myLikedList = '/app/vlog/myLikedList'; // 我点赞的视频
|
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 doVideoComment = '/app/comment/publish'; // 发布评论
|
||||||
|
static const String reportVideoApi = '/app/feedback/add'; // 投诉视频
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static const String unlike = '/app/vlog/unlike'; //取消点赞
|
static const String unlike = '/app/vlog/unlike'; //取消点赞
|
||||||
|
@ -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();
|
||||||
|
};
|
||||||
|
},
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
249
lib/pages/video/report.dart
Normal file
249
lib/pages/video/report.dart
Normal file
@ -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<ReportPage> createState() => _ReportPageState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _ReportPageState extends State<ReportPage> with SingleTickerProviderStateMixin {
|
||||||
|
int? _selectedIndex;
|
||||||
|
late dynamic args;
|
||||||
|
final TextEditingController _reportController = TextEditingController();
|
||||||
|
final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey();
|
||||||
|
List<dynamic> reasonTypeData = [];
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
args = Get.arguments ?? {};
|
||||||
|
getReportReasons('ums_feedback_reasontype'); // 获取投诉枚举
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
_reportController.dispose();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 加载数据的方法
|
||||||
|
Future<void> getReportReasons(String key) async {
|
||||||
|
try {
|
||||||
|
final data = await Commondictionary.getCommonDictionary(key);
|
||||||
|
setState(() {
|
||||||
|
reasonTypeData = data;
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
print('加载失败: $e');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 投诉视频
|
||||||
|
Future<void> 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);
|
||||||
|
}
|
||||||
|
}
|
@ -12,6 +12,7 @@ import 'package:loopin/pages/my/nick_name.dart';
|
|||||||
import 'package:loopin/pages/my/setting.dart';
|
import 'package:loopin/pages/my/setting.dart';
|
||||||
import 'package:loopin/pages/my/user_info.dart';
|
import 'package:loopin/pages/my/user_info.dart';
|
||||||
import 'package:loopin/pages/my/vloger.dart';
|
import 'package:loopin/pages/my/vloger.dart';
|
||||||
|
import 'package:loopin/pages/video/report.dart';
|
||||||
|
|
||||||
import '../layouts/index.dart';
|
import '../layouts/index.dart';
|
||||||
/* 引入路由页面 */
|
/* 引入路由页面 */
|
||||||
@ -34,6 +35,7 @@ final Map<String, Widget> routes = {
|
|||||||
'/order': const Order(),
|
'/order': const Order(),
|
||||||
'/order/detail': const OrderDetail(),
|
'/order/detail': const OrderDetail(),
|
||||||
'/vloger': const Vloger(),
|
'/vloger': const Vloger(),
|
||||||
|
'/report': const ReportPage(),
|
||||||
//settins
|
//settins
|
||||||
'/setting': const Setting(),
|
'/setting': const Setting(),
|
||||||
'/userInfo': const UserInfo(),
|
'/userInfo': const UserInfo(),
|
||||||
|
26
lib/utils/getCommonDictionary.dart
Normal file
26
lib/utils/getCommonDictionary.dart
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
library;
|
||||||
|
|
||||||
|
import 'package:loopin/api/common_api.dart';
|
||||||
|
import 'package:loopin/service/http.dart';
|
||||||
|
|
||||||
|
class Commondictionary {
|
||||||
|
// 获取字段配置
|
||||||
|
static Future<List<dynamic>> 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 [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user