937 lines
35 KiB
Dart
Executable File
937 lines
35 KiB
Dart
Executable File
import 'package:flutter/cupertino.dart';
|
||
import 'package:flutter/material.dart';
|
||
import 'package:flutter/services.dart';
|
||
import 'package:flutter_native_contact_picker/flutter_native_contact_picker.dart';
|
||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||
import 'package:get/get.dart';
|
||
import 'package:star_lock/appRouters.dart';
|
||
import 'package:star_lock/app_settings/app_colors.dart';
|
||
import 'package:star_lock/login/login/entity/LoginEntity.dart';
|
||
import 'package:star_lock/main/lockDetail/electronicKey/sendElectronicKey/sendElectronicKey/view/sendElectronicKeyView_logic.dart';
|
||
import 'package:star_lock/network/api_repository.dart';
|
||
import 'package:star_lock/tools/NativeInteractionTool.dart';
|
||
import 'package:star_lock/tools/baseGetXController.dart';
|
||
import 'package:star_lock/tools/commonDataManage.dart';
|
||
import 'package:star_lock/tools/commonItem.dart';
|
||
import 'package:star_lock/tools/dateTool.dart';
|
||
import 'package:star_lock/tools/pickers/pickers.dart';
|
||
import 'package:star_lock/tools/pickers/time_picker/model/date_mode.dart';
|
||
import 'package:star_lock/tools/pickers/time_picker/model/pduration.dart';
|
||
import 'package:star_lock/tools/regularExpression.dart';
|
||
import 'package:star_lock/tools/showTipView.dart';
|
||
import 'package:star_lock/tools/submitBtn.dart';
|
||
import 'package:permission_handler/permission_handler.dart';
|
||
|
||
class SendElectronicKeyView extends StatefulWidget {
|
||
SendElectronicKeyView({required this.type, Key? key}) : super(key: key);
|
||
String type;
|
||
|
||
@override
|
||
State<SendElectronicKeyView> createState() => _SendElectronicKeyViewState();
|
||
}
|
||
|
||
class _SendElectronicKeyViewState extends State<SendElectronicKeyView>
|
||
with AutomaticKeepAliveClientMixin {
|
||
late FlutterContactPicker _contactPicker;
|
||
|
||
@override
|
||
void initState() {
|
||
super.initState();
|
||
_contactPicker = FlutterContactPicker();
|
||
}
|
||
|
||
@override
|
||
Widget build(BuildContext context) {
|
||
super.build(context);
|
||
return GetBuilder<SendElectronicKeyViewLogic>(
|
||
tag: widget.type,
|
||
init: SendElectronicKeyViewLogic(widget.type),
|
||
builder: (SendElectronicKeyViewLogic logic) {
|
||
if (logic.state.isSendSuccess == true) {
|
||
return sendElectronicKeySucceed(logic);
|
||
} else {
|
||
switch (widget.type) {
|
||
case '0':
|
||
// 限时
|
||
return SingleChildScrollView(
|
||
child: Column(
|
||
children: <Widget>[
|
||
keyInfoWidget(logic),
|
||
keyTimeWidget(logic),
|
||
remoteUnlockingWidget(logic),
|
||
keyRealNameWidget(logic),
|
||
keyBottomWidget(logic.state.timeLimitTips, logic)
|
||
],
|
||
),
|
||
);
|
||
case '1':
|
||
// 永久
|
||
return SingleChildScrollView(
|
||
child: Column(
|
||
children: <Widget>[
|
||
keyInfoWidget(logic),
|
||
remoteUnlockingWidget(logic),
|
||
keyRealNameWidget(logic),
|
||
keyBottomWidget(logic.state.permanentTips, logic)
|
||
],
|
||
),
|
||
);
|
||
case '2':
|
||
// 单次
|
||
return SingleChildScrollView(
|
||
child: Column(
|
||
children: <Widget>[
|
||
keyInfoWidget(logic),
|
||
remoteUnlockingWidget(logic),
|
||
keyRealNameWidget(logic),
|
||
keyBottomWidget(logic.state.onceLimitTips, logic)
|
||
],
|
||
),
|
||
);
|
||
case '3':
|
||
// 循环
|
||
return SingleChildScrollView(
|
||
child: Column(
|
||
children: <Widget>[
|
||
keyInfoWidget(logic),
|
||
keyPeriodValidityWidget(logic),
|
||
remoteUnlockingWidget(logic),
|
||
keyRealNameWidget(logic),
|
||
keyBottomWidget(logic.state.cycleLimitTips, logic)
|
||
],
|
||
),
|
||
);
|
||
default:
|
||
return Container();
|
||
}
|
||
}
|
||
});
|
||
}
|
||
|
||
// 顶部钥匙信息widget
|
||
Widget keyInfoWidget(SendElectronicKeyViewLogic logic) {
|
||
return Column(
|
||
children: <Widget>[
|
||
// Container(height: 10.h),
|
||
// CommonItem(
|
||
// leftTitel: '接收者'.tr,
|
||
// rightTitle: '',
|
||
// isHaveLine: true,
|
||
// isHaveRightWidget: true,
|
||
// rightWidget: getTFWidget(
|
||
// true,
|
||
// '请输入手机号或者邮箱'.tr,
|
||
// 1,
|
||
// logic)),
|
||
perpetualKeyWidget(logic, '接收者'.tr, '请输入手机号或者邮箱'.tr),
|
||
Obx(() => Visibility(
|
||
visible: RegularExpression()
|
||
.isPhoneNumber(logic.state.emailOrPhone.value),
|
||
child: CommonItem(
|
||
leftTitel: '国家/地区'.tr,
|
||
rightTitle: '',
|
||
isHaveLine: true,
|
||
isHaveRightWidget: true,
|
||
isHaveDirection: true,
|
||
rightWidget: Text(
|
||
'${logic.state.countryName} +${logic.state.countryCode}',
|
||
textAlign: TextAlign.end,
|
||
style: TextStyle(
|
||
fontSize: 22.sp, color: AppColors.darkGrayTextColor),
|
||
),
|
||
action: () async {
|
||
final Object? result = await Navigator.pushNamed(
|
||
context, Routers.selectCountryRegionPage);
|
||
if (result != null) {
|
||
result as Map<String, dynamic>;
|
||
logic.state.countryCode = result['code'];
|
||
logic.state.countryName = result['countryName'];
|
||
logic.update();
|
||
}
|
||
},
|
||
),
|
||
)),
|
||
CommonItem(
|
||
leftTitel: '姓名'.tr,
|
||
rightTitle: '',
|
||
isHaveRightWidget: true,
|
||
rightWidget: getTFWidget(false, '请输入'.tr, 2, logic, maxSize: 50)),
|
||
Container(height: 10.h),
|
||
],
|
||
);
|
||
}
|
||
|
||
Widget perpetualKeyWidget(
|
||
SendElectronicKeyViewLogic logic, String titleStr, String rightTitle) {
|
||
return Column(
|
||
children: <Widget>[
|
||
Container(
|
||
height: 65.h,
|
||
padding: EdgeInsets.only(left: 20.w, right: 20.w),
|
||
decoration: BoxDecoration(
|
||
color: Colors.white,
|
||
border: Border(
|
||
bottom: BorderSide(
|
||
color: AppColors.greyLineColor,
|
||
width: 2.0.h,
|
||
),
|
||
)),
|
||
child: Row(
|
||
children: <Widget>[
|
||
Text(titleStr, style: TextStyle(fontSize: 22.sp)),
|
||
SizedBox(width: 6.w),
|
||
Expanded(
|
||
child: TextField(
|
||
controller: logic.getCurrentController(1),
|
||
maxLines: 1,
|
||
inputFormatters: <TextInputFormatter>[
|
||
FilteringTextInputFormatter.deny('\n'),
|
||
LengthLimitingTextInputFormatter(30),
|
||
],
|
||
autofocus: false,
|
||
textAlign: TextAlign.end,
|
||
decoration: InputDecoration(
|
||
hintText: rightTitle,
|
||
hintStyle: TextStyle(fontSize: 22.sp),
|
||
focusedBorder: const OutlineInputBorder(
|
||
borderSide:
|
||
BorderSide(width: 0, color: Colors.transparent)),
|
||
disabledBorder: const OutlineInputBorder(
|
||
borderSide:
|
||
BorderSide(width: 0, color: Colors.transparent)),
|
||
enabledBorder: const OutlineInputBorder(
|
||
borderSide:
|
||
BorderSide(width: 0, color: Colors.transparent)),
|
||
border: const OutlineInputBorder(
|
||
borderSide:
|
||
BorderSide(width: 0, color: Colors.transparent)),
|
||
contentPadding: const EdgeInsets.symmetric(vertical: 0),
|
||
),
|
||
style: TextStyle(
|
||
fontSize: 22.sp, textBaseline: TextBaseline.alphabetic),
|
||
),
|
||
),
|
||
SizedBox(width: 10.w),
|
||
Container(
|
||
width: 32.w,
|
||
height: 32.w,
|
||
decoration: const BoxDecoration(
|
||
color: Colors.white,
|
||
image: DecorationImage(
|
||
image: AssetImage('images/icon_addressBook.png'),
|
||
fit: BoxFit.fill),
|
||
),
|
||
alignment: Alignment.center,
|
||
child: InkWell(
|
||
onTap: () async {
|
||
try {
|
||
final PermissionStatus status =
|
||
await Permission.contacts.request();
|
||
if (status.isGranted) {
|
||
// 保存当前路由
|
||
final currentRoute = ModalRoute.of(context);
|
||
|
||
final Contact? currentContact =
|
||
await _contactPicker.selectContact();
|
||
|
||
// 检查路由是否仍然存在且组件是否挂载
|
||
if (currentRoute?.isCurrent == true && mounted) {
|
||
// 检查 GetX 控制器是否仍然存在
|
||
if (Get.isRegistered<SendElectronicKeyViewLogic>(
|
||
tag: widget.type)) {
|
||
final logic = Get.find<SendElectronicKeyViewLogic>(
|
||
tag: widget.type);
|
||
|
||
if (currentContact != null) {
|
||
// 处理手机号
|
||
if (currentContact.phoneNumbers != null &&
|
||
currentContact.phoneNumbers!.isNotEmpty) {
|
||
String phoneNumber =
|
||
currentContact.phoneNumbers![0];
|
||
// 移除所有空格、括号、连字符等特殊字符
|
||
phoneNumber = phoneNumber.replaceAll(
|
||
RegExp(r'[\s\(\)\-]'), '');
|
||
// 如果号码以+开头,保留+号
|
||
if (phoneNumber.startsWith('+')) {
|
||
phoneNumber = '+' +
|
||
phoneNumber
|
||
.substring(1)
|
||
.replaceAll(RegExp(r'[^\d]'), '');
|
||
} else {
|
||
phoneNumber = phoneNumber.replaceAll(
|
||
RegExp(r'[^\d]'), '');
|
||
}
|
||
logic.state.emailOrPhoneController.text =
|
||
phoneNumber;
|
||
logic.state.emailOrPhone.value = phoneNumber;
|
||
}
|
||
|
||
// 处理姓名
|
||
if (currentContact.fullName != null &&
|
||
currentContact.fullName!.isNotEmpty) {
|
||
logic.state.keyNameController.text =
|
||
currentContact.fullName!;
|
||
}
|
||
|
||
// 更新UI
|
||
logic.update();
|
||
}
|
||
}
|
||
}
|
||
} else {
|
||
// 权限被拒绝,显示提示
|
||
if (mounted) {
|
||
ScaffoldMessenger.of(context).showSnackBar(
|
||
SnackBar(
|
||
content: Text('需要通讯录权限才能选择联系人'.tr),
|
||
duration: const Duration(seconds: 2),
|
||
),
|
||
);
|
||
}
|
||
}
|
||
} catch (e) {
|
||
print('Error selecting contact: $e');
|
||
if (mounted) {
|
||
ScaffoldMessenger.of(context).showSnackBar(
|
||
SnackBar(
|
||
content: Text('获取通讯录失败,请检查权限设置'.tr),
|
||
duration: const Duration(seconds: 2),
|
||
),
|
||
);
|
||
}
|
||
}
|
||
},
|
||
),
|
||
),
|
||
Container(
|
||
color: AppColors.greyLineColor,
|
||
height: 2.0.h,
|
||
)
|
||
],
|
||
),
|
||
)
|
||
],
|
||
);
|
||
}
|
||
|
||
// 生效失效时间
|
||
Widget keyTimeWidget(SendElectronicKeyViewLogic logic) {
|
||
return Column(
|
||
children: <Widget>[
|
||
CommonItem(
|
||
leftTitel: '生效时间'.tr,
|
||
rightTitle: logic.state.timeLimitBeginTime,
|
||
isHaveLine: true,
|
||
isHaveDirection: true,
|
||
action: () {
|
||
final PDuration selectDate = PDuration.parse(
|
||
DateTime.parse(logic.state.timeLimitBeginTime));
|
||
Pickers.showDatePicker(context,
|
||
selectDate: selectDate,
|
||
mode: DateMode.YMDHM, onConfirm: (PDuration p) {
|
||
logic.state.timeLimitBeginTime =
|
||
DateTool().getYMDHNDateString(p, 1);
|
||
logic.update();
|
||
});
|
||
}),
|
||
CommonItem(
|
||
leftTitel: '失效时间'.tr,
|
||
rightTitle: logic.state.timeLimitEndTime,
|
||
isHaveDirection: true,
|
||
action: () {
|
||
final PDuration selectDate = PDuration.parse(
|
||
DateTime.tryParse(logic.state.timeLimitEndTime));
|
||
Pickers.showDatePicker(context,
|
||
selectDate: selectDate,
|
||
mode: DateMode.YMDHM, onConfirm: (PDuration p) {
|
||
logic.state.timeLimitEndTime =
|
||
DateTool().getYMDHNDateString(p, 1);
|
||
logic.update();
|
||
});
|
||
}),
|
||
Container(height: 10.h),
|
||
],
|
||
);
|
||
}
|
||
|
||
// 实名认证
|
||
Widget keyRealNameWidget(SendElectronicKeyViewLogic logic) {
|
||
return Column(
|
||
children: <Widget>[
|
||
Obx(() => CommonItem(
|
||
leftTitel: '实名认证'.tr,
|
||
rightTitle: '',
|
||
isTipsImg: true,
|
||
isHaveLine: logic.state.isRequireAuth.value,
|
||
tipsImgAction: () {
|
||
ShowTipView().showSureAlertDialog(
|
||
'人脸实名认证指的是用户在使用手机APP开锁时,需要先进行本人人脸验证,验证通过才能开锁。'.tr);
|
||
},
|
||
isHaveRightWidget: true,
|
||
rightWidget: SizedBox(
|
||
width: 60.w,
|
||
height: 50.h,
|
||
child: _remoteSwitch(false, logic)),
|
||
)),
|
||
Obx(() => Visibility(
|
||
visible: logic.state.isRequireAuth.value,
|
||
child: CommonItem(
|
||
leftTitel: '真实姓名'.tr,
|
||
rightTitle: '',
|
||
isHaveRightWidget: true,
|
||
isHaveLine: true,
|
||
rightWidget: getTFWidget(false, '请输入真实姓名'.tr, 3, logic)))),
|
||
Obx(() => Visibility(
|
||
visible: logic.state.isRequireAuth.value,
|
||
child: CommonItem(
|
||
leftTitel: '身份证号'.tr,
|
||
rightTitle: '',
|
||
isHaveRightWidget: true,
|
||
rightWidget: getTFWidget(false, '请输入身份证号'.tr, 4, logic)))),
|
||
],
|
||
);
|
||
}
|
||
|
||
// 循环有效期
|
||
Widget keyPeriodValidityWidget(SendElectronicKeyViewLogic logic) {
|
||
return Column(
|
||
children: <Widget>[
|
||
CommonItem(
|
||
leftTitel: '有效期'.tr,
|
||
rightTitle:
|
||
'${logic.state.cycleBeginTime}\n${logic.state.cycleEndTime}',
|
||
isHaveDirection: true,
|
||
isHaveLine: true,
|
||
action: () async {
|
||
final result = await Get.toNamed(Routers.seletKeyCyclicDatePage,
|
||
arguments: <String, Object>{
|
||
'validityValue': logic.state.weekdaysList,
|
||
'starDate': logic.state.cycleBeginTime,
|
||
'endDate': logic.state.cycleEndTime,
|
||
'starTime': logic.state.effectiveDateTime,
|
||
'endTime': logic.state.failureDateTime
|
||
});
|
||
if (result != null && result.isNotEmpty) {
|
||
logic.state.weekdaysList = result['validityValue'];
|
||
logic.state.cycleBeginTime = result['starDate'];
|
||
logic.state.cycleEndTime = result['endDate'];
|
||
logic.state.effectiveDateTime = result['starTime'];
|
||
logic.state.failureDateTime = result['endTime'];
|
||
logic.update();
|
||
}
|
||
}),
|
||
Visibility(
|
||
visible: logic.state.weekdaysList.isNotEmpty,
|
||
child: CommonItem(
|
||
leftTitel: '有效日'.tr,
|
||
rightTitle: logic.weekDayStr.join(',').toString(),
|
||
isHaveDirection: true,
|
||
isHaveLine: true,
|
||
action: () async {
|
||
final result = await Get.toNamed(
|
||
Routers.seletKeyCyclicDatePage,
|
||
arguments: <String, Object>{
|
||
'validityValue': logic.state.weekdaysList,
|
||
'starDate': logic.state.cycleBeginTime,
|
||
'endDate': logic.state.cycleEndTime,
|
||
'starTime': logic.state.effectiveDateTime,
|
||
'endTime': logic.state.failureDateTime
|
||
});
|
||
if (result != null && result.isNotEmpty) {
|
||
logic.state.weekdaysList = result['validityValue'];
|
||
logic.state.cycleBeginTime = result['starDate'];
|
||
logic.state.cycleEndTime = result['endDate'];
|
||
logic.state.effectiveDateTime = result['starTime'];
|
||
logic.state.failureDateTime = result['endTime'];
|
||
logic.update();
|
||
}
|
||
})),
|
||
Visibility(
|
||
visible: logic.state.effectiveDateTime.isNotEmpty,
|
||
child: CommonItem(
|
||
leftTitel: '有效时间'.tr,
|
||
rightTitle:
|
||
'${logic.state.effectiveDateTime}-${logic.state.failureDateTime}',
|
||
isHaveDirection: true,
|
||
isHaveLine: true,
|
||
action: () async {
|
||
final result = await Get.toNamed(
|
||
Routers.seletKeyCyclicDatePage,
|
||
arguments: <String, Object>{
|
||
'validityValue': logic.state.weekdaysList,
|
||
'starDate': logic.state.cycleBeginTime,
|
||
'endDate': logic.state.cycleEndTime,
|
||
'starTime': logic.state.effectiveDateTime,
|
||
'endTime': logic.state.failureDateTime
|
||
});
|
||
if (result != null && result.isNotEmpty) {
|
||
logic.state.weekdaysList = result['validityValue'];
|
||
logic.state.cycleBeginTime = result['starDate'];
|
||
logic.state.cycleEndTime = result['endDate'];
|
||
logic.state.effectiveDateTime = result['starTime'];
|
||
logic.state.failureDateTime = result['endTime'];
|
||
logic.update();
|
||
}
|
||
})),
|
||
],
|
||
);
|
||
}
|
||
|
||
Widget keyBottomWidget(
|
||
String sendElectronicKeyTips, SendElectronicKeyViewLogic logic) {
|
||
return Column(
|
||
children: <Widget>[
|
||
Container(
|
||
padding: EdgeInsets.all(20.w),
|
||
child: Row(
|
||
children: <Widget>[
|
||
Expanded(
|
||
child: Text(
|
||
sendElectronicKeyTips,
|
||
textAlign: TextAlign.start,
|
||
style: TextStyle(
|
||
fontSize: 18.sp, color: AppColors.darkGrayTextColor),
|
||
)),
|
||
],
|
||
),
|
||
),
|
||
SubmitBtn(
|
||
btnName: '发送'.tr,
|
||
onClick: () {
|
||
if (logic.state.isDemoMode == false) {
|
||
logic.sendElectronicKeyRequest();
|
||
setState(() {});
|
||
} else {
|
||
//演示模式不获取接口
|
||
logic.showToast('演示模式'.tr);
|
||
}
|
||
}),
|
||
Container(
|
||
padding: EdgeInsets.only(right: 30.w),
|
||
child: Row(
|
||
mainAxisAlignment: MainAxisAlignment.end,
|
||
children: <Widget>[
|
||
TextButton(
|
||
onPressed: () {
|
||
// 获取是否是演示模式 演示模式不获取接口
|
||
if (logic.state.isDemoMode == false) {
|
||
Navigator.pushNamed(
|
||
context, Routers.massSendElectronicKeyManagePage);
|
||
} else {
|
||
logic.showToast('演示模式'.tr);
|
||
}
|
||
},
|
||
child: Text(
|
||
'群发钥匙'.tr,
|
||
style:
|
||
TextStyle(color: AppColors.mainColor, fontSize: 22.sp),
|
||
)),
|
||
],
|
||
),
|
||
),
|
||
],
|
||
);
|
||
}
|
||
|
||
// 发送电子钥匙成功
|
||
Widget sendElectronicKeySucceed(SendElectronicKeyViewLogic logic) {
|
||
return Column(
|
||
children: <Widget>[
|
||
Container(
|
||
height: 250.h,
|
||
width: 1.sw,
|
||
color: Colors.white,
|
||
child: Column(
|
||
children: <Widget>[
|
||
SizedBox(
|
||
height: 30.h,
|
||
),
|
||
Image.asset(
|
||
'images/icon_send_success.png',
|
||
width: 100.w,
|
||
height: 100.w,
|
||
),
|
||
SizedBox(
|
||
height: 20.h,
|
||
),
|
||
Row(
|
||
mainAxisAlignment: MainAxisAlignment.center,
|
||
children: <Widget>[
|
||
Text(
|
||
'发送成功'.tr,
|
||
style: TextStyle(
|
||
fontSize: 26.sp,
|
||
color: Colors.black,
|
||
fontWeight: FontWeight.w500),
|
||
),
|
||
],
|
||
),
|
||
],
|
||
),
|
||
),
|
||
SizedBox(
|
||
height: 20.h,
|
||
),
|
||
SubmitBtn(
|
||
btnName: '完成'.tr,
|
||
onClick: () {
|
||
logic.state.isSendSuccess = false;
|
||
logic.resetData();
|
||
logic.update();
|
||
}),
|
||
SizedBox(
|
||
height: 10.h,
|
||
),
|
||
if (logic.emailOrPhone != null)
|
||
OutLineBtn(
|
||
btnName:
|
||
logic.state.userNameType.value == 1 ? '短信通知'.tr : '邮件通知'.tr,
|
||
onClick: () {
|
||
Get.toNamed(Routers.sendEmailNotificationPage,
|
||
arguments: <String, Object?>{
|
||
'receiver': logic.emailOrPhone,
|
||
'channelType': logic.state.userNameType.value,
|
||
'keyId': logic.keyId,
|
||
'unlockType': 1
|
||
});
|
||
},
|
||
),
|
||
SizedBox(
|
||
height: 10.h,
|
||
),
|
||
if (logic.emailOrPhone != null &&
|
||
logic.state.currentLanguage.value == 'zh_CN')
|
||
OutLineBtn(
|
||
btnName: '微信通知'.tr,
|
||
onClick: () {
|
||
logic.sendMsg(isPhone: logic.emailOrPhone!.contains('@'));
|
||
},
|
||
),
|
||
],
|
||
);
|
||
}
|
||
|
||
//标记房间为已入住 isOn:已入住: 1 空闲:2
|
||
Future<void> updateRoomCheckIn(SendElectronicKeyViewLogic logic) async {
|
||
final LoginEntity entity = await ApiRepository.to.setRoomStatusData(
|
||
lockId: CommonDataManage().currentKeyInfo.lockId!,
|
||
roomStatus: 1,
|
||
);
|
||
if (entity.errorCode!.codeIsSuccessful) {
|
||
logic.showToast('标记成功'.tr);
|
||
}
|
||
}
|
||
|
||
// 接受者信息输入框
|
||
Widget getTFWidget(bool isHaveBtn, String tfStr, int lineIndex,
|
||
SendElectronicKeyViewLogic logic,
|
||
{int maxSize = 30}) {
|
||
return SizedBox(
|
||
height: 65.h,
|
||
width: 320.w,
|
||
child: Row(
|
||
children: <Widget>[
|
||
Expanded(
|
||
child: TextField(
|
||
controller: logic.getCurrentController(lineIndex),
|
||
//输入框一行
|
||
maxLines: 1,
|
||
inputFormatters: <TextInputFormatter>[
|
||
FilteringTextInputFormatter.deny('\n'),
|
||
LengthLimitingTextInputFormatter(maxSize),
|
||
],
|
||
// controller: _controller,
|
||
autofocus: false,
|
||
textAlign: TextAlign.end,
|
||
decoration: InputDecoration(
|
||
//输入里面输入文字内边距设置
|
||
hintText: tfStr,
|
||
hintStyle: TextStyle(fontSize: 22.sp),
|
||
focusedBorder: const OutlineInputBorder(
|
||
borderSide:
|
||
BorderSide(width: 0, color: Colors.transparent)),
|
||
disabledBorder: const OutlineInputBorder(
|
||
borderSide:
|
||
BorderSide(width: 0, color: Colors.transparent)),
|
||
enabledBorder: const OutlineInputBorder(
|
||
borderSide:
|
||
BorderSide(width: 0, color: Colors.transparent)),
|
||
border: const OutlineInputBorder(
|
||
borderSide:
|
||
BorderSide(width: 0, color: Colors.transparent)),
|
||
contentPadding: const EdgeInsets.symmetric(vertical: 0),
|
||
),
|
||
style: TextStyle(
|
||
fontSize: 22.sp, textBaseline: TextBaseline.alphabetic),
|
||
onChanged: (String value) {
|
||
logic.update();
|
||
},
|
||
),
|
||
),
|
||
SizedBox(
|
||
width: 10.w,
|
||
),
|
||
if (isHaveBtn)
|
||
Container(
|
||
width: 32.w,
|
||
height: 32.w,
|
||
decoration: const BoxDecoration(
|
||
color: Colors.white,
|
||
image: DecorationImage(
|
||
image: AssetImage('images/icon_addressBook.png'),
|
||
fit: BoxFit.fill),
|
||
),
|
||
alignment: Alignment.center,
|
||
child: InkWell(
|
||
onTap: () async {
|
||
try {
|
||
final PermissionStatus status =
|
||
await Permission.contacts.request();
|
||
if (status.isGranted) {
|
||
final Contact? currentContact =
|
||
await _contactPicker.selectContact();
|
||
if (currentContact != null && mounted) {
|
||
// 处理手机号
|
||
if (currentContact.phoneNumbers != null &&
|
||
currentContact.phoneNumbers!.isNotEmpty) {
|
||
String phoneNumber = currentContact.phoneNumbers![0];
|
||
// 移除所有空格、括号、连字符等特殊字符
|
||
phoneNumber =
|
||
phoneNumber.replaceAll(RegExp(r'[\s\(\)\-]'), '');
|
||
// 如果号码以+开头,保留+号
|
||
if (phoneNumber.startsWith('+')) {
|
||
phoneNumber = '+' +
|
||
phoneNumber
|
||
.substring(1)
|
||
.replaceAll(RegExp(r'[^\d]'), '');
|
||
} else {
|
||
phoneNumber =
|
||
phoneNumber.replaceAll(RegExp(r'[^\d]'), '');
|
||
}
|
||
logic.state.emailOrPhoneController.text = phoneNumber;
|
||
logic.state.emailOrPhone.value = phoneNumber;
|
||
}
|
||
|
||
// 处理姓名
|
||
if (currentContact.fullName != null &&
|
||
currentContact.fullName!.isNotEmpty) {
|
||
logic.state.keyNameController.text =
|
||
currentContact.fullName!;
|
||
}
|
||
|
||
// 更新UI
|
||
logic.update();
|
||
}
|
||
} else {
|
||
// 权限被拒绝,显示提示
|
||
if (mounted) {
|
||
ScaffoldMessenger.of(context).showSnackBar(
|
||
SnackBar(
|
||
content: Text('需要通讯录权限才能选择联系人'.tr),
|
||
duration: const Duration(seconds: 2),
|
||
),
|
||
);
|
||
}
|
||
}
|
||
} catch (e) {
|
||
print('Error selecting contact: $e');
|
||
if (mounted) {
|
||
ScaffoldMessenger.of(context).showSnackBar(
|
||
SnackBar(
|
||
content: Text('获取通讯录失败,请检查权限设置'.tr),
|
||
duration: const Duration(seconds: 2),
|
||
),
|
||
);
|
||
}
|
||
}
|
||
},
|
||
),
|
||
)
|
||
else
|
||
Container()
|
||
],
|
||
),
|
||
);
|
||
}
|
||
|
||
// 远程开锁
|
||
Widget remoteUnlockingWidget(SendElectronicKeyViewLogic logic) {
|
||
return Visibility(
|
||
visible: logic.state.isDemoMode
|
||
? false
|
||
: (CommonDataManage().currentKeyInfo.lockSetting!.remoteUnlock == 1
|
||
? true
|
||
: false),
|
||
child: Column(
|
||
children: <Widget>[
|
||
Obx(() => CommonItem(
|
||
leftTitel: '允许远程开锁'.tr,
|
||
rightTitle: '',
|
||
isHaveRightWidget: true,
|
||
rightWidget: SizedBox(
|
||
width: 60.w, height: 50.h, child: _remoteSwitch(true, logic)),
|
||
action: () {})),
|
||
Container(height: 10.h),
|
||
],
|
||
),
|
||
);
|
||
}
|
||
|
||
//isRemote true:远程开锁 false:实名认证
|
||
CupertinoSwitch _remoteSwitch(
|
||
bool isRemote, SendElectronicKeyViewLogic logic) {
|
||
return CupertinoSwitch(
|
||
activeColor: CupertinoColors.activeBlue,
|
||
trackColor: CupertinoColors.systemGrey5,
|
||
thumbColor: CupertinoColors.white,
|
||
value: isRemote
|
||
? logic.state.isRemoteUnlock.value
|
||
: logic.state.isAuthentication.value,
|
||
onChanged: (bool value) {
|
||
if (isRemote) {
|
||
logic.state.isRemoteUnlock.value = !logic.state.isRemoteUnlock.value;
|
||
} else {
|
||
if (logic.state.isAuthentication.value == false) {
|
||
logic.keyCheckFace();
|
||
} else {
|
||
logic.state.isAuthentication.value = false;
|
||
logic.state.isRequireAuth.value = false;
|
||
}
|
||
}
|
||
},
|
||
);
|
||
}
|
||
|
||
Future _openModalBottomSheet() async {
|
||
showModalBottomSheet(
|
||
context: context,
|
||
shape: RoundedRectangleBorder(
|
||
borderRadius: BorderRadiusDirectional.circular(10)),
|
||
constraints: BoxConstraints(maxHeight: 323.h),
|
||
builder: (BuildContext context) {
|
||
return Column(
|
||
children: <Widget>[
|
||
Container(
|
||
color: Colors.white,
|
||
padding: EdgeInsets.only(top: 16.h, bottom: 16.h),
|
||
width: ScreenUtil().screenWidth,
|
||
child: Center(
|
||
child: Text(
|
||
'分享',
|
||
style: TextStyle(
|
||
fontSize: 24.sp,
|
||
color: AppColors.blackColor,
|
||
fontWeight: FontWeight.w500),
|
||
),
|
||
),
|
||
),
|
||
const Divider(
|
||
height: 1,
|
||
color: AppColors.greyLineColor,
|
||
),
|
||
Container(
|
||
width: ScreenUtil().screenWidth,
|
||
height: 160.h,
|
||
color: Colors.white,
|
||
child: ListView(
|
||
scrollDirection: Axis.horizontal, //横向滚动
|
||
children: initBottomSheetList()),
|
||
),
|
||
Container(
|
||
height: 8.h,
|
||
color: AppColors.greyBackgroundColor,
|
||
),
|
||
Container(
|
||
color: Colors.white,
|
||
margin: const EdgeInsets.only(bottom: 0, left: 0, right: 0),
|
||
width: ScreenUtil().screenWidth,
|
||
child: TextButton(
|
||
style: ButtonStyle(
|
||
overlayColor:
|
||
MaterialStateProperty.all<Color>(Colors.white)),
|
||
child: Text(
|
||
'取消'.tr,
|
||
style: TextStyle(
|
||
color: Colors.black, fontSize: 24.sp),
|
||
),
|
||
onPressed: () {
|
||
Navigator.pop(context);
|
||
},
|
||
),
|
||
)
|
||
],
|
||
);
|
||
});
|
||
}
|
||
|
||
List<Widget> initBottomSheetList() {
|
||
final List<Widget> widgetList = <Widget>[];
|
||
widgetList.add(buildCenter3('images/icon_wechat.png', '微信好友'.tr, 0));
|
||
widgetList.add(buildCenter3('images/icon_message.png', '短信'.tr, 1));
|
||
widgetList.add(buildCenter3('images/icon_email.png', '邮件'.tr, 2));
|
||
widgetList.add(buildCenter3('images/icon_more.png', '更多'.tr, 3));
|
||
return widgetList;
|
||
}
|
||
|
||
GestureDetector buildCenter3(
|
||
String imageName, String titleStr, int itemIndex) {
|
||
return GestureDetector(
|
||
child: Container(
|
||
width: 120.w,
|
||
// height: 64.h,
|
||
margin:
|
||
EdgeInsets.only(top: 20.w, bottom: 20.w, left: 10.w, right: 10.w),
|
||
child: Column(
|
||
mainAxisAlignment: MainAxisAlignment.center,
|
||
children: <Widget>[
|
||
Image.asset(
|
||
imageName,
|
||
width: 50.w,
|
||
height: 50.h,
|
||
),
|
||
SizedBox(
|
||
height: 16.w,
|
||
),
|
||
Text(
|
||
titleStr,
|
||
style: TextStyle(
|
||
fontSize: 20.sp, color: Colors.black),
|
||
),
|
||
],
|
||
),
|
||
),
|
||
onTap: () => _jumpSmartDeviceRoute(itemIndex),
|
||
);
|
||
}
|
||
|
||
void _jumpSmartDeviceRoute(int itemIndex) {
|
||
Get.back();
|
||
switch (itemIndex) {
|
||
case 0:
|
||
//微信好友
|
||
final String pwdShareStr = '您好,您的电子钥匙生成成功'.tr;
|
||
NativeInteractionTool().loadNativeShare(shareText: pwdShareStr);
|
||
break;
|
||
case 1:
|
||
//短信
|
||
final String pwdShareStr = '您好,您的电子钥匙生成成功'.tr;
|
||
NativeInteractionTool().loadNativeShare(shareText: pwdShareStr);
|
||
break;
|
||
case 2:
|
||
//邮件
|
||
Get.toNamed(Routers.sendEmailNotificationPage,
|
||
arguments: <String, Object?>{'unlockType': 1});
|
||
break;
|
||
case 3:
|
||
//更多
|
||
final String pwdShareStr = '您好,您的电子钥匙生成成功'.tr;
|
||
NativeInteractionTool().loadNativeShare(shareText: pwdShareStr);
|
||
break;
|
||
default:
|
||
}
|
||
}
|
||
|
||
@override
|
||
bool get wantKeepAlive => true;
|
||
}
|