You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

340 lines
10 KiB

import 'dart:io';
import 'package:dating_touchme_app/oss/oss_manager.dart';
import 'package:flustars/flustars.dart';
import 'package:get/get.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:get_storage/get_storage.dart';
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
import 'package:image_picker/image_picker.dart';
import '../../network/user_api.dart';
import '../../pages/main/main_page.dart';
class UserInfoController extends GetxController {
// 用户信息表单字段
final gender = 'male'.obs; // 默认选择男性
final nickname = ''.obs;
final birthday = ''.obs;
final education = ''.obs;
final invitationCode = ''.obs;
final avatarUrl = ''.obs;
// 本地选择的头像文件路径(提交时先上传)
final avatarLocalPath = ''.obs;
// 加载状态
final isSubmitting = false.obs;
// GetStorage实例,用于存储用户信息
final storage = GetStorage();
// UserApi实例
late UserApi _userApi;
// 选择性别
void selectGender(String selectedGender) {
gender.value = selectedGender;
// 打印选择的性别
print('选择的性别: $selectedGender');
// 显示选择结果
SmartDialog.showToast('已选择${selectedGender == 'male' ? '' : ''}');
}
// 选择日期
void selectBirthday(String selectedDate) {
birthday.value = selectedDate;
// 打印选择的日期
print('选择的出生日期: $selectedDate');
// 显示选择结果
SmartDialog.showToast('出生日期已选择');
}
// 选择学历
void selectEducation(String selectedEducation) {
education.value = selectedEducation;
// 打印选择的学历
print('选择的学历: $selectedEducation');
// 显示选择结果
SmartDialog.showToast('学历已选择');
}
// 选择头像 - 业务逻辑处理
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) {
avatarLocalPath.value = photo.path;
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/mediaLibrary,permission_handler 会映射
denyToast: '相册权限被拒绝,请在设置中允许访问相册',
);
if (!ok) return;
// 从相册选择图片
final ImagePicker picker = ImagePicker();
final XFile? image = await picker.pickImage(source: ImageSource.gallery);
if (image != null) {
avatarLocalPath.value = image.path;
await processSelectedImage(File(image.path));
}
} 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;
}
@override
void onInit() {
super.onInit();
// 从全局依赖中获取UserApi
_userApi = Get.find<UserApi>();
}
// 处理选中的图片
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');
avatarUrl.value = imageUrl;
SmartDialog.dismiss();
SmartDialog.showToast('头像设置成功');
} catch (e) {
SmartDialog.dismiss();
print('处理图片失败: $e');
SmartDialog.showToast('设置头像失败,请重试');
}
}
// 选择头像入口方法(保持兼容性)
void selectAvatar() {
// 这个方法现在只是一个入口,实际的UI交互在页面中实现
// 页面会调用上面的具体处理方法
}
// 验证表单
bool _validateForm() {
if (avatarUrl.value.isEmpty && avatarLocalPath.value.isEmpty) {
SmartDialog.showToast('请先选择头像');
return false;
}
// 验证昵称
if (nickname.value.isEmpty) {
SmartDialog.showToast('请输入昵称');
return false;
}
// 验证生日
if (birthday.value.isEmpty) {
SmartDialog.showToast('请选择出生日期');
return false;
}
// 验证学历
if (education.value.isEmpty) {
SmartDialog.showToast('请选择学历');
return false;
}
// 验证头像(必须选择)
if (avatarUrl.value.isEmpty) {
SmartDialog.showToast('请先选择头像');
return false;
}
return true;
}
// 构建提交参数
Map<String, dynamic> _buildSubmitParams() {
// 从birthday字符串中提取年份
int birthYear = 0;
if (birthday.value.isNotEmpty) {
// 假设birthday格式为YYYY-MM-DD
final parts = birthday.value.split('-');
if (parts.isNotEmpty) {
birthYear = int.tryParse(parts[0]) ?? 0;
}
}
// 学历代码映射
Map<String, String> educationCodeMap = {
'大专以下': '0',
'大专': '1',
'本科': '2',
'硕士及以上': '3',
};
return {
'birthYear': birthYear,
'educationCode': educationCodeMap[education.value] ?? '0',
'genderCode': gender.value == 'male' ? '0' : '1', // 1:男, 2:女
'matchmakerInvitationCode': invitationCode.value,
'nickName': nickname.value,
};
}
// 提交用户信息
Future<void> submitUserInfo() async {
// 验证表单
if (!_validateForm()) {
return;
}
isSubmitting.value = true;
try {
// 构建请求参数
final params = _buildSubmitParams();
if (avatarUrl.value.isNotEmpty) {
params['avatarUrl'] = avatarUrl.value;
}
// 打印提交的信息
print('提交用户信息参数: $params');
// 调用注册婚姻信息接口
final response = await _userApi.registerMarriageInformation(params);
// 处理响应
if (response.data.isSuccess) {
// 获取 miId(资料id)
String miId = '';
final regData = response.data.data;
if (regData != null) {
miId = regData;
await storage.write('miId', miId);
} else {
// 尝试从本地存储获取
final stored = storage.read('miId');
if (stored is String && stored.isNotEmpty) {
miId = stored;
} else {
SmartDialog.showToast('获取资料ID失败,请重试');
return;
}
}
// 先调用认证审核保存接口(保存头像,authenticationCode=8)
try {
final payload = {
'miId': miId,
'authenticationCode': '8',
'value': '0',
'imgUrl': avatarUrl.value.isNotEmpty ? [avatarUrl.value] : ['0'],
};
final auditResp = await _userApi.saveCertificationAudit(payload);
if (auditResp.data.isSuccess) {
}
else{
SmartDialog.showToast(auditResp.data.message);
return;
}
} catch (e) {
print('保存认证审核失败: $e');
SmartDialog.showToast('提交失败,请重试');
return;
}
// 更新本地存储的用户信息
final currentUserInfo = storage.read('userInfo') ?? {};
if (currentUserInfo is Map<String, dynamic>) {
currentUserInfo.addAll({
'gender': gender.value,
'nickname': nickname.value,
'birthday': birthday.value,
'education': education.value,
'avatarUrl': avatarUrl.value,
});
await storage.write('userInfo', currentUserInfo);
}
// 显示成功提示
SmartDialog.showToast('信息提交成功!');
// 延迟后跳转
Future.delayed(const Duration(milliseconds: 1500), () {
// 跳转到主页面(根据登录流程,应该跳转到MainPage)
Get.offAll(() => MainPage());
});
} else {
SmartDialog.showToast(response.data.message);
}
} catch (e) {
print('提交用户信息失败: $e');
// 显示错误提示
SmartDialog.showToast('提交失败,请重试');
} finally {
isSubmitting.value = false;
}
}
}