Browse Source

完善功能

dev-2.0
YakumoChen 1 day ago
parent
commit
c5c303282a
19 changed files with 1362 additions and 337 deletions
  1. 16
      lib/controller/home/report_controller.dart
  2. 23
      lib/controller/home/user_information_controller.dart
  3. 2
      lib/controller/message/chat_settings_controller.dart
  4. 247
      lib/controller/mine/real_feedback_controller.dart
  5. 85
      lib/controller/setting/blacklist_controller.dart
  6. 72
      lib/model/mine/blacklist_data.dart
  7. 17
      lib/network/api_urls.dart
  8. 5
      lib/network/home_api.dart
  9. 34
      lib/network/home_api.g.dart
  10. 22
      lib/network/user_api.dart
  11. 139
      lib/network/user_api.g.dart
  12. 6
      lib/pages/home/report_page.dart
  13. 2
      lib/pages/home/timeline_info.dart
  14. 2
      lib/pages/home/timeline_item.dart
  15. 3
      lib/pages/home/user_information_page.dart
  16. 339
      lib/pages/mine/feedback_page.dart
  17. 4
      lib/pages/mine/mine_page.dart
  18. 460
      lib/pages/mine/real_feedback_page.dart
  19. 221
      lib/pages/setting/blacklist_page.dart

16
lib/controller/home/report_controller.dart

@ -12,7 +12,9 @@ import 'package:permission_handler/permission_handler.dart';
class ReportController extends GetxController {
final String id;
ReportController({required this.id});
final String userId;
final int type;
ReportController({required this.id, required this.userId, required this.type});
final checked = 1.obs;
@ -198,11 +200,15 @@ class ReportController extends GetxController {
try {
if(isClick.value) return;
isClick.value = true;
final response = await _homeApi.userReportPost({
final response = await _homeApi.userCommitUserReport({
"id": id,
"reportPicUrls": imgList.isNotEmpty ? imgList.join(",") : "",
"reportContent": message.value,
"reportReason": checked.value
"images": imgList.isNotEmpty ? imgList.join(",") : "",
"content": message.value,
"addUserBlacklist": blockUser.value,
"reportType": checked.value,
"targetId": id,
"targetType": type,
"targetUserId": userId,
});
if (response.data.isSuccess) {

23
lib/controller/home/user_information_controller.dart

@ -68,6 +68,29 @@ class UserInformationController extends GetxController {
}
}
createUserBlack() async {
try {
final response = await _userApi.userCreateUserBlacklist({
"blackUserId": userData.value.miUserId,
});
if (response.data.isSuccess) {
SmartDialog.showToast('已拉黑成功');
} else {
//
throw Exception(response.data.message ?? '获取数据失败');
}
} catch(e){
print('拉黑失败: $e');
SmartDialog.showToast('拉黑失败');
rethrow;
} finally {
}
}
int calculateAge(String birthdayStr) {
final birthday = DateTime.parse(birthdayStr); // 1996-1-20
final today = DateTime.now();

2
lib/controller/message/chat_settings_controller.dart

@ -494,7 +494,7 @@ class ChatSettingsController extends GetxController {
///
void reportUser() {
//
Get.to(() => ReportPage(id: "",));
Get.to(() => ReportPage(id: userId, userId: userId, type: 1,));
}
///

247
lib/controller/mine/real_feedback_controller.dart

@ -0,0 +1,247 @@
import 'dart:io';
import 'package:dating_touchme_app/network/user_api.dart';
import 'package:dating_touchme_app/oss/oss_manager.dart';
import 'package:flustars/flustars.dart';
import 'package:flutter/material.dart';
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
import 'package:get/get.dart';
import 'package:image_picker/image_picker.dart';
import 'package:permission_handler/permission_handler.dart';
class RealFeedbackController extends GetxController {
final int type;
RealFeedbackController({required this.type});
late UserApi _userApi;
final message = ''.obs;
final messageController = TextEditingController().obs;
final tagList = <Map>[].obs;
final active = 0.obs;
final imgList = <String>[].obs;
changeActive(int i){
active.value = i;
}
@override
void onInit() {
super.onInit();
_userApi = Get.find<UserApi>();
if(type == 1){
tagList.value = [
{"label": "账号异常", "value": 101},
{"label": "违规与封禁", "value": 102},
{"label": "头像/签名/实名认证", "value": 103},
];
} else if(type == 2){
tagList.value = [
{"label": "私信相关", "value": 201},
{"label": "资料相关", "value": 202},
{"label": "动态相关", "value": 203},
{"label": "直播间相关", "value": 204},
];
} else if(type == 3){
tagList.value = [
{"label": "举报有人诈骗", "value": 301},
{"label": "举报有人涉嫌诱导", "value": 302},
{"label": "其他不良行为举报", "value": 303},
{"label": "虚假宣传广告投诉", "value": 304},
{"label": "未成年问题", "value": 305},
{"label": "智能推荐相关", "value": 306},
];
}
}
// -
Future<void> handleCameraCapture() async {
try {
//
final ok = await _ensurePermission(
Permission.camera,
denyToast: '相机权限被拒绝,请在设置中允许访问相机',
);
if (!ok) return;
// /
await _ensurePermission(Permission.microphone, denyToast: '麦克风权限被拒绝');
//
final ImagePicker picker = ImagePicker();
final XFile? photo = await picker.pickImage(source: ImageSource.camera);
if (photo != null) {
await processSelectedImage(File(photo.path));
}
} catch (e) {
print('拍照失败: $e');
//
if (e.toString().contains('permission') || e.toString().contains('权限')) {
SmartDialog.showToast('相机权限被拒绝,请在设置中允许访问相机');
} else if (e.toString().contains('camera') ||
e.toString().contains('相机')) {
SmartDialog.showToast('设备没有可用的相机');
} else {
SmartDialog.showToast('拍照失败,请重试');
}
}
}
Future<void> handleGallerySelection() async {
try {
// /
// final ok = await _ensurePermission(
// Permission.photos,
// // Android photos storage/mediaLibrarypermission_handler
// denyToast: '相册权限被拒绝,请在设置中允许访问相册',
// );
// if (!ok) return;
//
final ImagePicker picker = ImagePicker();
final XFile? image = await picker.pickImage(source: ImageSource.gallery);
if (image != null) {
await processSelectedImage(File(image.path));
}
} catch (e) {
print('选择图片失败: $e');
//
if (e.toString().contains('permission') || e.toString().contains('权限')) {
SmartDialog.showToast('相册权限被拒绝,请在设置中允许访问相册');
} else {
SmartDialog.showToast('选择图片失败,请重试');
}
}
}
Future<void> handleMultiGallerySelection() async {
try {
// /
// final ok = await _ensurePermission(
// Permission.photos,
// // Android photos storage/mediaLibrarypermission_handler
// denyToast: '相册权限被拒绝,请在设置中允许访问相册',
// );
// if (!ok) return;
//
final ImagePicker picker = ImagePicker();
final List<XFile>? image = await picker.pickMultiImage(limit: 9 - imgList.length);
if (image != null) {
final futures = image.map((e){
return processSelectedMoreImage(File(e.path));
});
final list = await Future.wait(futures);
imgList.addAll(list);
print(imgList);
SmartDialog.dismiss();
SmartDialog.showToast('上传相册成功');
}
} catch (e) {
print('选择图片失败: $e');
//
if (e.toString().contains('permission') || e.toString().contains('权限')) {
SmartDialog.showToast('相册权限被拒绝,请在设置中允许访问相册');
} else {
SmartDialog.showToast('选择图片失败,请重试');
}
}
}
//
Future<bool> _ensurePermission(Permission permission, {String? denyToast}) async {
var status = await permission.status;
if (status.isGranted) return true;
if (status.isDenied || status.isRestricted || status.isLimited) {
status = await permission.request();
if (status.isGranted) return true;
if (denyToast != null) SmartDialog.showToast(denyToast);
return false;
}
if (status.isPermanentlyDenied) {
if (denyToast != null) SmartDialog.showToast('$denyToast,前往系统设置开启');
//
Future.delayed(const Duration(milliseconds: 300), openAppSettings);
return false;
}
return false;
}
//
Future<void> processSelectedImage(File imageFile) async {
try {
//
SmartDialog.showLoading(msg: '上传相册中...');
String objectName = '${DateUtil.getNowDateMs()}.${imageFile.path.split('.').last}';
String imageUrl = await OSSManager.instance.uploadFile(imageFile.readAsBytesSync(), objectName);
print('上传成功,图片URL: $imageUrl');
imgList.add(imageUrl);
SmartDialog.dismiss();
SmartDialog.showToast('相册上传成功');
} catch (e) {
SmartDialog.dismiss();
print('处理图片失败: $e');
SmartDialog.showToast('上传相册失败,请重试');
}
}
//
Future<String> processSelectedMoreImage(File imageFile) async {
try {
//
SmartDialog.showLoading(msg: '上传相册中...');
String objectName = '${DateUtil.getNowDateMs()}.${imageFile.path.split('.').last}';
String imageUrl = await OSSManager.instance.uploadFile(imageFile.readAsBytesSync(), objectName);
print('上传成功,图片URL: $imageUrl');
return imageUrl;
} catch (e) {
SmartDialog.dismiss();
print('处理图片失败: $e');
SmartDialog.showToast('上传相册失败,请重试');
return "";
}
}
sendFeedback() async {
try {
final response = await _userApi.userCreateUserFeedback({
"images": imgList.isNotEmpty ? imgList.join(",") : "",
"content": message.value,
"feedbackType": active.value,
});
if (response.data.isSuccess) {
SmartDialog.showToast('反馈已提交成功');
Get.until((route) => route.isFirst);
} else {
//
throw Exception(response.data.message ?? '获取数据失败');
}
} catch(e){
print('反馈提交失败: $e');
SmartDialog.showToast('反馈提交失败');
rethrow;
} finally {
}
}
}

85
lib/controller/setting/blacklist_controller.dart

@ -0,0 +1,85 @@
import 'package:dating_touchme_app/network/user_api.dart';
import 'package:easy_refresh/easy_refresh.dart';
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
import 'package:get/get.dart';
import 'package:dating_touchme_app/model/mine/blacklist_data.dart';
class BlacklistController extends GetxController {
late UserApi _userApi;
final page = 1.obs;
final size = 10.obs;
late final EasyRefreshController listRefreshController;
final blackList = <Records>[].obs;
@override
void onInit() {
super.onInit();
listRefreshController = EasyRefreshController(
controlFinishRefresh: true,
controlFinishLoad: true,
);
_userApi = Get.find<UserApi>();
getBlackList();
}
getBlackList() async {
try{
final response = await _userApi.userPageUserBlacklist(
pageNum: page.value,
pageSize: size.value,
);
if (response.data.isSuccess && response.data.data != null) {
final data = response.data.data?.records ?? [];
blackList.addAll(data.toList());
if((data.length ?? 0) == size.value){
listRefreshController.finishLoad(IndicatorResult.success);
} else {
listRefreshController.finishLoad(IndicatorResult.noMore);
}
} else {
//
throw Exception(response.data.message ?? '获取数据失败');
}
} catch(e) {
print('玫瑰记录获取失败: $e');
SmartDialog.showToast('玫瑰记录获取失败');
rethrow;
}
}
unBlack(String blackUserId) async {
try {
final response = await _userApi.userDeleteUserBlacklist({
"blackUserId": blackUserId,
});
if (response.data.isSuccess) {
SmartDialog.showToast('已解除拉黑');
blackList.value = blackList.where((e) => e.blackUserId != blackUserId).toList();
} else {
//
throw Exception(response.data.message ?? '获取数据失败');
}
} catch(e){
print('解除拉黑失败: $e');
SmartDialog.showToast('解除拉黑失败');
rethrow;
} finally {
}
}
}

72
lib/model/mine/blacklist_data.dart

@ -0,0 +1,72 @@
class BlacklistData {
List<Records>? records;
int? total;
int? size;
int? current;
int? pages;
BlacklistData(
{this.records, this.total, this.size, this.current, this.pages});
BlacklistData.fromJson(Map<String, dynamic> json) {
if (json['records'] != null) {
records = <Records>[];
json['records'].forEach((v) {
records!.add(new Records.fromJson(v));
});
}
total = json['total'];
size = json['size'];
current = json['current'];
pages = json['pages'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
if (this.records != null) {
data['records'] = this.records!.map((v) => v.toJson()).toList();
}
data['total'] = this.total;
data['size'] = this.size;
data['current'] = this.current;
data['pages'] = this.pages;
return data;
}
}
class Records {
String? id;
String? blackUserId;
String? miId;
String? nickName;
String? profilePhoto;
String? createTime;
Records(
{this.id,
this.blackUserId,
this.miId,
this.nickName,
this.profilePhoto,
this.createTime});
Records.fromJson(Map<String, dynamic> json) {
id = json['id'];
blackUserId = json['blackUserId'];
miId = json['miId'];
nickName = json['nickName'];
profilePhoto = json['profilePhoto'];
createTime = json['createTime'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
data['blackUserId'] = this.blackUserId;
data['miId'] = this.miId;
data['nickName'] = this.nickName;
data['profilePhoto'] = this.profilePhoto;
data['createTime'] = this.createTime;
return data;
}
}

17
lib/network/api_urls.dart

@ -236,4 +236,21 @@ class ApiUrls {
static const String userPageLiveMatchmaker =
'dating-agency-chat-audio/user/page/live-matchmaker';
static const String userCommitUserReport =
'dating-agency-chat-audio/user/commit/user-report';
static const String userCreateUserBlacklist =
'dating-agency-chat-audio/user/create/user-blacklist';
static const String userDeleteUserBlacklist =
'dating-agency-chat-audio/user/delete/user-blacklist';
static const String userPageUserBlacklist =
'dating-agency-chat-audio/user/page/user-blacklist';
static const String userCreateUserFeedback =
'dating-agency-service/user/create/user-feedback';
}

5
lib/network/home_api.dart

@ -99,4 +99,9 @@ abstract class HomeApi {
@Query('pageSize') required int pageSize,
});
@POST(ApiUrls.userCommitUserReport)
Future<HttpResponse<BaseResponse<dynamic>>> userCommitUserReport(
@Body() Map<String, dynamic> data,
);
}

34
lib/network/home_api.g.dart

@ -531,6 +531,40 @@ class _HomeApi implements HomeApi {
return httpResponse;
}
@override
Future<HttpResponse<BaseResponse<dynamic>>> userCommitUserReport(
Map<String, dynamic> data,
) async {
final _extra = <String, dynamic>{};
final queryParameters = <String, dynamic>{};
final _headers = <String, dynamic>{};
final _data = <String, dynamic>{};
_data.addAll(data);
final _options = _setStreamType<HttpResponse<BaseResponse<dynamic>>>(
Options(method: 'POST', headers: _headers, extra: _extra)
.compose(
_dio.options,
'dating-agency-chat-audio/user/commit/user-report',
queryParameters: queryParameters,
data: _data,
)
.copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)),
);
final _result = await _dio.fetch<Map<String, dynamic>>(_options);
late BaseResponse<dynamic> _value;
try {
_value = BaseResponse<dynamic>.fromJson(
_result.data!,
(json) => json as dynamic,
);
} on Object catch (e, s) {
errorLogger?.logError(e, s, _options);
rethrow;
}
final httpResponse = HttpResponse(_value, _result);
return httpResponse;
}
RequestOptions _setStreamType<T>(RequestOptions requestOptions) {
if (T != dynamic &&
!(requestOptions.responseType == ResponseType.bytes ||

22
lib/network/user_api.dart

@ -4,6 +4,7 @@ import 'package:dating_touchme_app/model/home/post_data.dart';
import 'package:dating_touchme_app/model/home/user_info_data.dart';
import 'package:dating_touchme_app/model/mine/bank_card_data.dart';
import 'package:dating_touchme_app/model/mine/bank_card_ocr_data.dart';
import 'package:dating_touchme_app/model/mine/blacklist_data.dart';
import 'package:dating_touchme_app/model/mine/connect_history_data.dart';
import 'package:dating_touchme_app/model/mine/education_data.dart';
import 'package:dating_touchme_app/model/mine/friend_apply_data.dart';
@ -313,4 +314,25 @@ abstract class UserApi {
@Query('pageSize') required int pageSize,
@Query('authorUserId') required String authorUserId,
});
@POST(ApiUrls.userCreateUserBlacklist)
Future<HttpResponse<BaseResponse<dynamic>>> userCreateUserBlacklist(
@Body() Map<String, dynamic> data,
);
@GET(ApiUrls.userPageUserBlacklist)
Future<HttpResponse<BaseResponse<BlacklistData>>> userPageUserBlacklist({
@Query('pageNum') required int pageNum,
@Query('pageSize') required int pageSize,
});
@POST(ApiUrls.userDeleteUserBlacklist)
Future<HttpResponse<BaseResponse<dynamic>>> userDeleteUserBlacklist(
@Body() Map<String, dynamic> data,
);
@POST(ApiUrls.userCreateUserFeedback)
Future<HttpResponse<BaseResponse<dynamic>>> userCreateUserFeedback(
@Body() Map<String, dynamic> data,
);
}

139
lib/network/user_api.g.dart

@ -1896,6 +1896,145 @@ class _UserApi implements UserApi {
return httpResponse;
}
@override
Future<HttpResponse<BaseResponse<dynamic>>> userCreateUserBlacklist(
Map<String, dynamic> data,
) async {
final _extra = <String, dynamic>{};
final queryParameters = <String, dynamic>{};
final _headers = <String, dynamic>{};
final _data = <String, dynamic>{};
_data.addAll(data);
final _options = _setStreamType<HttpResponse<BaseResponse<dynamic>>>(
Options(method: 'POST', headers: _headers, extra: _extra)
.compose(
_dio.options,
'dating-agency-chat-audio/user/create/user-blacklist',
queryParameters: queryParameters,
data: _data,
)
.copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)),
);
final _result = await _dio.fetch<Map<String, dynamic>>(_options);
late BaseResponse<dynamic> _value;
try {
_value = BaseResponse<dynamic>.fromJson(
_result.data!,
(json) => json as dynamic,
);
} on Object catch (e, s) {
errorLogger?.logError(e, s, _options);
rethrow;
}
final httpResponse = HttpResponse(_value, _result);
return httpResponse;
}
@override
Future<HttpResponse<BaseResponse<BlacklistData>>> userPageUserBlacklist({
required int pageNum,
required int pageSize,
}) async {
final _extra = <String, dynamic>{};
final queryParameters = <String, dynamic>{
r'pageNum': pageNum,
r'pageSize': pageSize,
};
final _headers = <String, dynamic>{};
const Map<String, dynamic>? _data = null;
final _options = _setStreamType<HttpResponse<BaseResponse<BlacklistData>>>(
Options(method: 'GET', headers: _headers, extra: _extra)
.compose(
_dio.options,
'dating-agency-chat-audio/user/page/user-blacklist',
queryParameters: queryParameters,
data: _data,
)
.copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)),
);
final _result = await _dio.fetch<Map<String, dynamic>>(_options);
late BaseResponse<BlacklistData> _value;
try {
_value = BaseResponse<BlacklistData>.fromJson(
_result.data!,
(json) => BlacklistData.fromJson(json as Map<String, dynamic>),
);
} on Object catch (e, s) {
errorLogger?.logError(e, s, _options);
rethrow;
}
final httpResponse = HttpResponse(_value, _result);
return httpResponse;
}
@override
Future<HttpResponse<BaseResponse<dynamic>>> userDeleteUserBlacklist(
Map<String, dynamic> data,
) async {
final _extra = <String, dynamic>{};
final queryParameters = <String, dynamic>{};
final _headers = <String, dynamic>{};
final _data = <String, dynamic>{};
_data.addAll(data);
final _options = _setStreamType<HttpResponse<BaseResponse<dynamic>>>(
Options(method: 'POST', headers: _headers, extra: _extra)
.compose(
_dio.options,
'dating-agency-chat-audio/user/delete/user-blacklist',
queryParameters: queryParameters,
data: _data,
)
.copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)),
);
final _result = await _dio.fetch<Map<String, dynamic>>(_options);
late BaseResponse<dynamic> _value;
try {
_value = BaseResponse<dynamic>.fromJson(
_result.data!,
(json) => json as dynamic,
);
} on Object catch (e, s) {
errorLogger?.logError(e, s, _options);
rethrow;
}
final httpResponse = HttpResponse(_value, _result);
return httpResponse;
}
@override
Future<HttpResponse<BaseResponse<dynamic>>> userCreateUserFeedback(
Map<String, dynamic> data,
) async {
final _extra = <String, dynamic>{};
final queryParameters = <String, dynamic>{};
final _headers = <String, dynamic>{};
final _data = <String, dynamic>{};
_data.addAll(data);
final _options = _setStreamType<HttpResponse<BaseResponse<dynamic>>>(
Options(method: 'POST', headers: _headers, extra: _extra)
.compose(
_dio.options,
'dating-agency-service/user/create/user-feedback',
queryParameters: queryParameters,
data: _data,
)
.copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)),
);
final _result = await _dio.fetch<Map<String, dynamic>>(_options);
late BaseResponse<dynamic> _value;
try {
_value = BaseResponse<dynamic>.fromJson(
_result.data!,
(json) => json as dynamic,
);
} on Object catch (e, s) {
errorLogger?.logError(e, s, _options);
rethrow;
}
final httpResponse = HttpResponse(_value, _result);
return httpResponse;
}
RequestOptions _setStreamType<T>(RequestOptions requestOptions) {
if (T != dynamic &&
!(requestOptions.responseType == ResponseType.bytes ||

6
lib/pages/home/report_page.dart

@ -10,7 +10,9 @@ import 'package:tdesign_flutter/tdesign_flutter.dart';
class ReportPage extends StatelessWidget {
final String id;
const ReportPage({super.key, required this.id});
final String userId;
final int type;
const ReportPage({super.key, required this.id, required this.userId, required this.type});
@ -109,7 +111,7 @@ class ReportPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return GetX<ReportController>(
init: ReportController(id: id),
init: ReportController(id: id, userId: userId, type: type),
builder: (controller){
return Scaffold(
appBar: PageAppbar(title: "举报中心"),

2
lib/pages/home/timeline_info.dart

@ -62,7 +62,7 @@ class TimelineInfo extends StatelessWidget {
onSelected: (v) {
if (v == 'report') {
print("举报");
Get.to(() => ReportPage(id: id,));
Get.to(() => ReportPage(id: id, userId: controller.item.value.userId ?? "", type: 2,));
}
},
child: Icon(

2
lib/pages/home/timeline_item.dart

@ -216,7 +216,7 @@ class _TimelineItemState extends State<TimelineItem> {
onSelected: (v) {
if (v == 'report') {
print("举报");
Get.to(() => ReportPage(id: widget.item.id ?? "",));
Get.to(() => ReportPage(id: widget.item.id ?? "", userId: widget.item.userId ?? "", type: 2,));
}
},
child: Icon(

3
lib/pages/home/user_information_page.dart

@ -479,9 +479,10 @@ class UserInformationPage extends StatelessWidget {
onSelected: (v) {
if (v == 'report') {
print("举报");
Get.to(() => ReportPage(id: "",));
Get.to(() => ReportPage(id: controller.userData.value.miUserId ?? "", userId: controller.userData.value.miUserId ?? "", type: 1,));
} else if (v == 'block') {
print("拉黑");
controller.createUserBlack();
}
},
child: Container(

339
lib/pages/mine/feedback_page.dart

@ -1,9 +1,17 @@
import 'package:dating_touchme_app/components/page_appbar.dart';
import 'package:dating_touchme_app/extension/ex_widget.dart';
import 'package:dating_touchme_app/generated/assets.dart';
import 'package:dating_touchme_app/pages/mine/real_feedback_page.dart';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:dating_touchme_app/components/page_appbar.dart';
import 'package:dating_touchme_app/extension/ex_widget.dart';
import 'package:dating_touchme_app/generated/assets.dart';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';
class FeedbackPage extends StatefulWidget {
const FeedbackPage({super.key});
@ -93,234 +101,75 @@ class _FeedbackPageState extends State<FeedbackPage> {
child: Container(
width: 375.w,
padding: EdgeInsets.symmetric(
vertical: 11.w,
horizontal: 14.w
vertical: 15.w,
horizontal: 10.w
),
decoration: BoxDecoration(
borderRadius: BorderRadius.vertical(top: Radius.circular(9.w)),
color: Colors.white
),
child: SingleChildScrollView(
child: Container(
width: 355.w,
height: 150.w,
padding: EdgeInsets.only(
left: 17.w,
right: 10.w
),
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(9.w)),
color: const Color.fromRGBO(250, 250, 250, 1)
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
RichText(
text: TextSpan(
style: TextStyle(
fontSize: 16.w,
fontWeight: FontWeight.w500
),
children: [
TextSpan(
text: "选择问题的类型",
style: TextStyle(
color: const Color.fromRGBO(51, 51, 51, 1)
)
),
TextSpan(
text: "*",
style: TextStyle(
color: const Color.fromRGBO(248, 85, 66, 1)
)
)
]
),
),
SizedBox(height: 11.w,),
Wrap(
alignment: WrapAlignment.spaceBetween,
spacing: 10.w,
runSpacing: 10.w,
children: [
...tagList.asMap().entries.map((entry){
return TagItem(title: entry.value, index: entry.key, active: active, changeActive: changeActive,);
}),
],
),
SizedBox(height: 20.w,),
RichText(
text: TextSpan(
style: TextStyle(
fontSize: 16.w,
fontWeight: FontWeight.w500
),
children: [
TextSpan(
text: "问题描述",
style: TextStyle(
color: const Color.fromRGBO(51, 51, 51, 1)
)
),
TextSpan(
text: "*",
style: TextStyle(
color: const Color.fromRGBO(248, 85, 66, 1)
)
)
]
),
),
SizedBox(height: 11.w,),
Container(
padding: EdgeInsets.all(14.w),
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(8.w)),
color: const Color.fromRGBO(245, 245, 245, 1)
),
child: TextField(
controller: _messageController,
maxLength: 500, //
minLines: 5, //
maxLines: 5, //
style: TextStyle(
fontSize: ScreenUtil().setWidth(13),
height: 1
),
decoration: InputDecoration(
contentPadding: EdgeInsets.symmetric(
vertical: 0,
horizontal: 0
),
hintText: "请输入交友心声",
border: const OutlineInputBorder(
borderSide: BorderSide.none, // //
),
// focusedBorder enabledBorder
focusedBorder: const OutlineInputBorder(
borderSide: BorderSide.none,
borderRadius: BorderRadius.all(Radius.circular(8.0)),
),
enabledBorder: const OutlineInputBorder(
borderSide: BorderSide.none,
borderRadius: BorderRadius.all(Radius.circular(8.0)),
),
),
onChanged: (value){
message = value;
},
),
),
SizedBox(height: 10.w,),
Wrap(
alignment: WrapAlignment.spaceBetween,
spacing: 10.w,
runSpacing: 10.w,
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Container(
width: 70.w,
height: 70.w,
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(9.w)),
border: Border.all(width: 1, color: const Color.fromRGBO(224, 224, 224, 1))
),
child: Center(
child: Icon(
Icons.add,
size: 18.w,
color: const Color.fromRGBO(224, 224, 224, 1)
),
),
Text(
"账号与个人信息",
),
Icon(
Icons.arrow_right,
size: 20.w,
color: const Color.fromRGBO(204, 204, 2074, 1),
)
],
),
SizedBox(height: 10.w,),
Text(
"上传问题截图可以让问题快速解决!",
style: TextStyle(
fontSize: 11.w,
color: const Color.fromRGBO(189, 189, 189, 1)
),
),
SizedBox(height: 20.w,),
RichText(
text: TextSpan(
style: TextStyle(
fontSize: 16.w,
fontWeight: FontWeight.w500
),
children: [
TextSpan(
text: "联系方式",
style: TextStyle(
color: const Color.fromRGBO(51, 51, 51, 1)
)
),
]
),
),
Container(
padding: EdgeInsets.symmetric(horizontal: 13.w),
margin: EdgeInsets.only(top: 7.w),
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(8.w)),
color: const Color.fromRGBO(245, 245, 245, 1)
),
child: TextField(
controller: _phoneController,
keyboardType: TextInputType.number,
style: TextStyle(
fontSize: ScreenUtil().setWidth(14),
height: 1
),
decoration: InputDecoration(
hintText: "留下手机号、QQ、邮箱,以便我们回复您",
contentPadding: EdgeInsets.symmetric(
vertical: 0,
horizontal: 0
),
border: const OutlineInputBorder(
borderSide: BorderSide.none, // //
),
// focusedBorder enabledBorder
focusedBorder: const OutlineInputBorder(
borderSide: BorderSide.none,
borderRadius: BorderRadius.all(Radius.circular(8.0)),
),
enabledBorder: const OutlineInputBorder(
borderSide: BorderSide.none,
borderRadius: BorderRadius.all(Radius.circular(8.0)),
),
),
onChanged: (value){
phone = value;
setState(() {
});
},
),
),
Container(
margin: EdgeInsets.symmetric(vertical: 30.w),
child: Container(
width: 350.w,
height: 45.w,
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(45.w)),
gradient: LinearGradient(
begin: Alignment.centerLeft, // 90deg:
end: Alignment.centerRight,
colors: [
Color.fromRGBO(131, 89, 255, 1), //
Color.fromRGBO(77, 127, 231, 1), //
Color.fromRGBO(61, 138, 224, 1), //
],
stops: [0.0, 0.7753, 1.0], // 0%77.53%100%
),
).onTap((){
Get.to(() => RealFeedbackPage(type: 1,));
}),
SizedBox(height: 25.w,),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
"现有功能建议",
),
child: Center(
child: Text(
"确认",
style: TextStyle(
fontSize: 18.w,
color: Colors.white,
fontWeight: FontWeight.w500
),
),
Icon(
Icons.arrow_right,
size: 20.w,
color: const Color.fromRGBO(204, 204, 2074, 1),
)
],
).onTap((){
Get.to(() => RealFeedbackPage(type: 2,));
}),
SizedBox(height: 25.w,),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
"举报投诉",
),
),
)
Icon(
Icons.arrow_right,
size: 20.w,
color: const Color.fromRGBO(204, 204, 2074, 1),
)
],
).onTap((){
Get.to(() => RealFeedbackPage(type: 3,));
}),
SizedBox(height: 25.w,),
],
),
),
@ -336,64 +185,4 @@ class _FeedbackPageState extends State<FeedbackPage> {
class TagItem extends StatefulWidget {
final String title;
final int index;
final int active;
final void Function(int) changeActive;
const TagItem({super.key, required this.title, required this.index, required this.active, required this.changeActive});
@override
State<TagItem> createState() => _TagItemState();
}
class _TagItemState extends State<TagItem> {
@override
Widget build(BuildContext context) {
return Stack(
children: [
Container(
padding: EdgeInsets.symmetric(
vertical: 9.w,
horizontal: 14.w
),
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(8.w)),
border: Border.all(width: 1, color: widget.index == widget.active ? const Color.fromRGBO(117, 98, 249, 1) : const Color.fromRGBO(207, 207, 207, 1)),
color: widget.index == widget.active ? const Color.fromRGBO(194, 195, 255, 0.2) : Colors.transparent
),
child: Text(
widget.title,
style: TextStyle(
fontSize: 13.w
),
),
).onTap((){
widget.changeActive(widget.index);
}),
if(widget.active == widget.index)Positioned(
bottom: 0,
right: 0,
child: Container(
width: 17.w,
height: 13.w,
decoration: BoxDecoration(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(8.w),
bottomRight: Radius.circular(8.w)
),
color: const Color.fromRGBO(117, 98, 249, 1)
),
child: Center(
child: Image.asset(
Assets.imagesCheck,
width: 6.w,
),
),
),
)
],
);
}
}

4
lib/pages/mine/mine_page.dart

@ -7,8 +7,10 @@ import 'package:dating_touchme_app/model/mine/user_count_data.dart';
import 'package:dating_touchme_app/network/user_api.dart';
import 'package:dating_touchme_app/pages/mine/auth_center_page.dart';
import 'package:dating_touchme_app/pages/mine/edit_info_page.dart';
import 'package:dating_touchme_app/pages/mine/feedback_page.dart';
import 'package:dating_touchme_app/pages/mine/my_friend_page.dart';
import 'package:dating_touchme_app/pages/mine/my_wallet_page.dart';
import 'package:dating_touchme_app/pages/mine/real_feedback_page.dart';
import 'package:dating_touchme_app/pages/mine/rose_page.dart';
import 'package:dating_touchme_app/pages/mine/user_help_center_page.dart';
import 'package:dating_touchme_app/pages/mine/vip_page.dart';
@ -401,7 +403,7 @@ class MinePageState extends State<MinePage> with AutomaticKeepAliveClientMixin{
fontSize: 14.w
),
), onClick: (cell) {
SmartDialog.showToast('功能暂未开放');
Get.to(() => FeedbackPage());
}
),
TDCell(arrow: true,

460
lib/pages/mine/real_feedback_page.dart

@ -0,0 +1,460 @@
import 'package:cached_network_image/cached_network_image.dart';
import 'package:dating_touchme_app/components/page_appbar.dart';
import 'package:dating_touchme_app/controller/mine/real_feedback_controller.dart';
import 'package:dating_touchme_app/extension/ex_widget.dart';
import 'package:dating_touchme_app/generated/assets.dart';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
import 'package:get/get.dart';
import 'package:tdesign_flutter/tdesign_flutter.dart';
class RealFeedbackPage extends StatelessWidget {
final int type;
const RealFeedbackPage({super.key, required this.type});
void _showAvatarPopup(RealFeedbackController controller){
Navigator.of(Get.context!).push(
TDSlidePopupRoute(
slideTransitionFrom: SlideTransitionFrom.bottom,
builder: (context) {
return Container(
height: 176,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(12.0),
topRight: Radius.circular(12.0),
),
),
child: Column(
children: [
ClipRRect(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(12.0),
topRight: Radius.circular(12.0),
),
child: TDCell(
arrow: false,
titleWidget: Center(
child: Text('拍照', style: TextStyle(fontSize: 16.w, color: const Color.fromRGBO(51, 51, 51, 1))),
),
style: TDCellStyle(
padding: EdgeInsets.all(TDTheme.of(context).spacer16),
clickBackgroundColor: TDTheme.of(context).bgColorContainerHover,
cardBorderRadius: BorderRadius.only(
topLeft: Radius.circular(12.0),
topRight: Radius.circular(12.0),
)
),
onClick: (cell) async{
Navigator.pop(context);
if(9 - controller.imgList.length == 1){
await controller.handleCameraCapture();
} else {
if(controller.imgList.length >= 9){
SmartDialog.showToast('超出数量限制,请先删除再尝试上传');
return;
}
await controller.handleCameraCapture();
}
},
),
),
const TDDivider(),
TDCell(
arrow: false,
titleWidget: Center(
child: Text('从相册选择'),
),
onClick: (cell) async{
Navigator.pop(context);
if(9 - controller.imgList.length == 1){
await controller.handleGallerySelection();
} else {
if(controller.imgList.length >= 9){
SmartDialog.showToast('超出数量限制,请先删除再尝试上传');
return;
}
await controller.handleMultiGallerySelection();
}
},
),
Expanded(
child: Container(
color: Color(0xFFF3F3F3),
),
),
TDCell(
arrow: false,
titleWidget: Center(
child: Text('取消'),
),
onClick: (cell){
Navigator.pop(context);
},
),
],
),
);
}),
);
}
@override
Widget build(BuildContext context) {
return GetX<RealFeedbackController>(
init: RealFeedbackController(type: type),
builder: (controller){
return Stack(
children: [
Container(
width: 375.w,
height: 812.h,
color: Colors.white,
),
Positioned(
top: -320.w,
left: -270.w,
child: Image.asset(
Assets.imagesFeedbackBg,
width: 971.75.w,
height: 781.25.w,
fit: BoxFit.cover,
),
),
Positioned(
top: 53.w,
left: 207.w,
child: Image.asset(
Assets.imagesFeedbackIcon,
width: 140.w,
height: 140.w,
),
),
Scaffold(
appBar: PageAppbar(title: "", backgroundColor: Colors.transparent,),
backgroundColor: Colors.transparent,
body: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
padding: EdgeInsets.symmetric(
vertical: 22.w,
horizontal: 14.w
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"意见反馈",
style: TextStyle(
fontSize: 21.w,
fontWeight: FontWeight.w500
),
),
SizedBox(height: 5.w,),
Text(
"Hi,给出你的小建议吧~",
style: TextStyle(
fontSize: 13.w,
fontWeight: FontWeight.w500
),
),
],
),
),
Expanded(
child: Container(
width: 375.w,
padding: EdgeInsets.symmetric(
vertical: 11.w,
horizontal: 14.w
),
decoration: BoxDecoration(
borderRadius: BorderRadius.vertical(top: Radius.circular(9.w)),
color: Colors.white
),
child: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
RichText(
text: TextSpan(
style: TextStyle(
fontSize: 16.w,
fontWeight: FontWeight.w500
),
children: [
TextSpan(
text: "选择问题的类型",
style: TextStyle(
color: const Color.fromRGBO(51, 51, 51, 1)
)
),
TextSpan(
text: "*",
style: TextStyle(
color: const Color.fromRGBO(248, 85, 66, 1)
)
)
]
),
),
SizedBox(height: 11.w,),
Wrap(
alignment: WrapAlignment.spaceBetween,
spacing: 10.w,
runSpacing: 10.w,
children: [
...controller.tagList.asMap().entries.map((entry){
return TagItem(item: entry.value, index: entry.key, active: controller.active.value, changeActive: controller.changeActive,);
}),
],
),
SizedBox(height: 20.w,),
RichText(
text: TextSpan(
style: TextStyle(
fontSize: 16.w,
fontWeight: FontWeight.w500
),
children: [
TextSpan(
text: "问题描述",
style: TextStyle(
color: const Color.fromRGBO(51, 51, 51, 1)
)
),
TextSpan(
text: "*",
style: TextStyle(
color: const Color.fromRGBO(248, 85, 66, 1)
)
)
]
),
),
SizedBox(height: 11.w,),
Container(
padding: EdgeInsets.all(14.w),
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(8.w)),
color: const Color.fromRGBO(245, 245, 245, 1)
),
child: TextField(
controller: controller.messageController.value,
maxLength: 500, //
minLines: 5, //
maxLines: 5, //
style: TextStyle(
fontSize: ScreenUtil().setWidth(13),
height: 1
),
decoration: InputDecoration(
contentPadding: EdgeInsets.symmetric(
vertical: 0,
horizontal: 0
),
hintText: "请输入交友心声",
border: const OutlineInputBorder(
borderSide: BorderSide.none, // //
),
// focusedBorder enabledBorder
focusedBorder: const OutlineInputBorder(
borderSide: BorderSide.none,
borderRadius: BorderRadius.all(Radius.circular(8.0)),
),
enabledBorder: const OutlineInputBorder(
borderSide: BorderSide.none,
borderRadius: BorderRadius.all(Radius.circular(8.0)),
),
),
onChanged: (value){
controller.message.value = value;
},
),
),
SizedBox(height: 10.w,),
Wrap(
spacing: 10.w,
runSpacing: 10.w,
children: [
...controller.imgList.map((e){
return Stack(
children: [
CachedNetworkImage(
imageUrl: e,
width: 70.w,
height: 70.w,
fit: BoxFit.cover,
),
Positioned(
left: 5.w,
top: 5.w,
child: Container(
width: 20.w,
height: 20.w,
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(20.w)),
color: const Color.fromRGBO(0, 0, 0, .3)
),
child: Icon(
Icons.close,
size: 20.w,
),
).onTap((){
controller.imgList.remove(e);
}),
)
],
);
}),
Container(
width: 70.w,
height: 70.w,
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(8.w)),
border: Border.all(width: 1, color: const Color.fromRGBO(224, 224, 224, 1))
),
child: Center(
child: Icon(
Icons.add,
size: 18.w,
color: const Color.fromRGBO(144, 144, 144, 1),
),
),
).onTap((){
_showAvatarPopup(controller);
})
],
),
SizedBox(height: 10.w,),
Text(
"上传问题截图可以让问题快速解决!",
style: TextStyle(
fontSize: 11.w,
color: const Color.fromRGBO(189, 189, 189, 1)
),
),
Container(
margin: EdgeInsets.symmetric(vertical: 30.w),
child: Container(
width: 350.w,
height: 45.w,
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(45.w)),
gradient: LinearGradient(
begin: Alignment.centerLeft, // 90deg:
end: Alignment.centerRight,
colors: [
Color.fromRGBO(131, 89, 255, 1), //
Color.fromRGBO(77, 127, 231, 1), //
Color.fromRGBO(61, 138, 224, 1), //
],
stops: [0.0, 0.7753, 1.0], // 0%77.53%100%
),
),
child: Center(
child: Text(
"确认",
style: TextStyle(
fontSize: 18.w,
color: Colors.white,
fontWeight: FontWeight.w500
),
),
),
),
).onTap((){
controller.sendFeedback();
})
],
),
),
),
)
],
),
)
],
);
},
);
}
}
class TagItem extends StatefulWidget {
final Map item;
final int index;
final int active;
final void Function(int) changeActive;
const TagItem({super.key, required this.item, required this.index, required this.active, required this.changeActive});
@override
State<TagItem> createState() => _TagItemState();
}
class _TagItemState extends State<TagItem> {
@override
Widget build(BuildContext context) {
return Stack(
children: [
Container(
padding: EdgeInsets.symmetric(
vertical: 9.w,
horizontal: 14.w
),
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(8.w)),
border: Border.all(width: 1, color: widget.item["value"] == widget.active ? const Color.fromRGBO(117, 98, 249, 1) : const Color.fromRGBO(207, 207, 207, 1)),
color: widget.item["value"] == widget.active ? const Color.fromRGBO(194, 195, 255, 0.2) : Colors.transparent
),
child: Text(
widget.item["label"],
style: TextStyle(
fontSize: 13.w
),
),
).onTap((){
widget.changeActive(widget.item["value"]);
}),
if(widget.active == widget.item["value"])Positioned(
bottom: 0,
right: 0,
child: Container(
width: 17.w,
height: 13.w,
decoration: BoxDecoration(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(8.w),
bottomRight: Radius.circular(8.w)
),
color: const Color.fromRGBO(117, 98, 249, 1)
),
child: Center(
child: Image.asset(
Assets.imagesCheck,
width: 6.w,
),
),
),
)
],
);
}
}

221
lib/pages/setting/blacklist_page.dart

@ -1,44 +1,92 @@
import 'package:cached_network_image/cached_network_image.dart';
import 'package:dating_touchme_app/components/page_appbar.dart';
import 'package:dating_touchme_app/controller/setting/blacklist_controller.dart';
import 'package:dating_touchme_app/extension/ex_widget.dart';
import 'package:dating_touchme_app/generated/assets.dart';
import 'package:dating_touchme_app/model/mine/blacklist_data.dart';
import 'package:dating_touchme_app/pages/home/report_page.dart';
import 'package:dating_touchme_app/pages/home/user_information_page.dart';
import 'package:easy_refresh/easy_refresh.dart';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';
import 'package:tdesign_flutter/tdesign_flutter.dart';
class BlacklistPage extends StatefulWidget {
class BlacklistPage extends StatelessWidget {
const BlacklistPage({super.key});
@override
State<BlacklistPage> createState() => _BlacklistPageState();
}
class _BlacklistPageState extends State<BlacklistPage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: PageAppbar(title: "黑名单"),
body: SingleChildScrollView(
child: Container(
padding: EdgeInsets.symmetric(
vertical: 20.w,
horizontal: 15.w
),
child: Column(
children: [
BlackItem(),
BlackItem(),
BlackItem(),
BlackItem(),
BlackItem(),
BlackItem(),
],
return GetX<BlacklistController>(
init: BlacklistController(),
builder: (controller) {
return Scaffold(
appBar: PageAppbar(title: "黑名单"),
body: EasyRefresh(
controller: controller.listRefreshController,
header: const ClassicHeader(
dragText: '下拉刷新',
armedText: '释放刷新',
readyText: '刷新中...',
processingText: '刷新中...',
processedText: '刷新完成',
failedText: '刷新失败',
noMoreText: '没有更多数据',
showMessage: false
),
footer: ClassicFooter(
dragText: '上拉加载',
armedText: '释放加载',
readyText: '加载中...',
processingText: '加载中...',
processedText: '加载完成',
failedText: '加载失败',
noMoreText: '没有更多数据',
showMessage: false
),
//
onRefresh: () async {
print('推荐列表下拉刷新被触发');
controller.page.value = 1;
controller.blackList.clear();
await controller.getBlackList();
controller.listRefreshController.finishRefresh(IndicatorResult.success);
controller.listRefreshController.finishLoad(IndicatorResult.none);
},
//
onLoad: () async {
print('推荐列表上拉加载被触发, hasMore: ');
controller.page.value += 1;
controller.getBlackList();
},
child: SingleChildScrollView(
child: Container(
padding: EdgeInsets.symmetric(
vertical: 20.w,
horizontal: 15.w
),
child: Column(
children: [
...controller.blackList.map((e){
return BlackItem(item: e, controller: controller,);
})
],
),
),
),
),
),
),
);
},
);
}
}
class BlackItem extends StatefulWidget {
const BlackItem({super.key});
final Records item;
final BlacklistController controller;
const BlackItem({super.key, required this.item, required this.controller});
@override
State<BlackItem> createState() => _BlackItemState();
@ -57,26 +105,39 @@ class _BlackItemState extends State<BlackItem> {
Row(
children: [
ClipRRect(
borderRadius: BorderRadius.all(Radius.circular(40.w)),
child: Image.asset(
Assets.imagesUserAvatar,
width: 40.w,
height: 40.w,
),
borderRadius: BorderRadius.all(Radius.circular(40.w)),
child: (widget.item.profilePhoto != null && widget.item.profilePhoto != "") ? CachedNetworkImage(
imageUrl: "${widget.item.profilePhoto ?? ""}?x-oss-process=image/format,webp/resize,w_120",
width: 40.w,
height: 40.w,
imageBuilder: (context, imageProvider) => Container(
decoration: BoxDecoration(
image: DecorationImage(
image: imageProvider,
fit: BoxFit.cover,
),
),
),
) : Image.asset(
gaplessPlayback: true,
Assets.imagesUserAvatar,
width: 40.w,
height: 40.w,
)
),
SizedBox(width: 12.w,),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"法大师傅",
"${widget.item.nickName ?? ""}",
style: TextStyle(
fontSize: 13.w,
fontWeight: FontWeight.w500
),
),
Text(
"拉黑时间:11月7日",
"30岁·广州",
style: TextStyle(
fontSize: 11.w,
color: const Color.fromRGBO(144, 144, 144, 1)
@ -86,26 +147,86 @@ class _BlackItemState extends State<BlackItem> {
)
],
),
Container(
width: 70.w,
height: 25.w,
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(25.w)),
border: Border.all(width: 1, color: const Color.fromRGBO(51, 51, 51, 1))
),
child: Center(
child: Text(
"拆除",
style: TextStyle(
fontSize: 13.w,
fontWeight: FontWeight.w500
),
),
),
Icon(
Icons.more_horiz,
size: 20.w,
)
],
),
);
).onTap(() {
Navigator.of(context).push(
TDSlidePopupRoute(
slideTransitionFrom: SlideTransitionFrom.bottom,
builder: (context) {
return Material(
borderRadius: BorderRadius.vertical(top: Radius.circular(9.w)),
child: ClipRRect(
borderRadius: BorderRadius.vertical(top: Radius.circular(9.w)),
child: Container(
color: TDTheme.of(context).bgColorContainer,
height: 212.w,
padding: EdgeInsets.symmetric(horizontal: 28.w),
child: Column(
children: [
Container(
height: 65.w,
decoration: BoxDecoration(
border: Border(bottom: BorderSide(width: 1, color: const Color.from(alpha: 245, red: 245, green: 245, blue: 1)))
),
child: Center(
child: Text(
"查看详情",
style: TextStyle(
fontSize: 18.w
),
),
),
).onTap((){
Get.to(() => UserInformationPage(miId: widget.item.miId ?? ""));
}),
Container(
height: 65.w,
decoration: BoxDecoration(
border: Border(bottom: BorderSide(width: 1, color: const Color.from(alpha: 245, red: 245, green: 245, blue: 1)))
),
child: Center(
child: Text(
"解除拉黑",
style: TextStyle(
fontSize: 18.w
),
),
),
).onTap((){
widget.controller.unBlack(widget.item.blackUserId ?? "");
}),
Container(
height: 65.w,
decoration: BoxDecoration(
border: Border(bottom: BorderSide(width: 1, color: const Color.fromRGBO(245, 245, 245, 1)))
),
child: Center(
child: Text(
"举报",
style: TextStyle(
fontSize: 18.w,
color: const Color.fromRGBO(245, 83, 83, 1)
),
),
),
).onTap((){
Get.to(() => ReportPage(id: widget.item.blackUserId ?? "", userId: widget.item.blackUserId ?? "", type: 1,));
}),
],
),
),
),
);
}),
);
});
}
}
Loading…
Cancel
Save