Merge branch 'release' of https://gitee.com/starlock-cn/app-starlock into release
# Conflicts: # images/lan/lan_en.json # images/lan/lan_keys.json # images/lan/lan_zh.json
This commit is contained in:
commit
8f63629e4a
@ -52,14 +52,14 @@ android {
|
|||||||
// 这里“debug”不是一个自定义变量,而是一个特定的关键词,凡是使用--debug模式,都会引用到这里
|
// 这里“debug”不是一个自定义变量,而是一个特定的关键词,凡是使用--debug模式,都会引用到这里
|
||||||
// 目前看来,debug模式没办法在buildTypes里面按flavors指定编译签名,所有口味的debug模式只能用同一个签名
|
// 目前看来,debug模式没办法在buildTypes里面按flavors指定编译签名,所有口味的debug模式只能用同一个签名
|
||||||
debug {
|
debug {
|
||||||
// storeFile file("starlock.keystore")
|
storeFile file("starlock.keystore")
|
||||||
// storePassword '123456'
|
storePassword '123456'
|
||||||
// keyAlias = 'starlock'
|
keyAlias = 'starlock'
|
||||||
// keyPassword '123456'
|
keyPassword '123456'
|
||||||
storeFile file("xhj.jks")
|
// storeFile file("xhj.jks")
|
||||||
storePassword 'xhj8872'
|
// storePassword 'xhj8872'
|
||||||
keyAlias = 'upload'
|
// keyAlias = 'upload'
|
||||||
keyPassword 'xhj8872'
|
// keyPassword 'xhj8872'
|
||||||
}
|
}
|
||||||
sky {
|
sky {
|
||||||
// CN=Unknown, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown
|
// CN=Unknown, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown
|
||||||
|
|||||||
@ -862,6 +862,7 @@
|
|||||||
"五": "Fri",
|
"五": "Fri",
|
||||||
"六": "Sat",
|
"六": "Sat",
|
||||||
"日": "Sun",
|
"日": "Sun",
|
||||||
|
|
||||||
"新建短信模版":"New SMS template",
|
"新建短信模版":"New SMS template",
|
||||||
"新建邮件模版":"New email template",
|
"新建邮件模版":"New email template",
|
||||||
"自定义短信模版":"Custom SMS template",
|
"自定义短信模版":"Custom SMS template",
|
||||||
@ -874,4 +875,12 @@
|
|||||||
"国家地区的选择将影响数据安全,你当前选择的是阿尔巴尼亚,请确认后再继续": "The selection of the country or region will affect data security. You have currently selected Albania. Please confirm before continuing",
|
"国家地区的选择将影响数据安全,你当前选择的是阿尔巴尼亚,请确认后再继续": "The selection of the country or region will affect data security. You have currently selected Albania. Please confirm before continuing",
|
||||||
"确认国家或地区": "Confirm country or region",
|
"确认国家或地区": "Confirm country or region",
|
||||||
"我知道了": "I know",
|
"我知道了": "I know",
|
||||||
|
|
||||||
|
"为了让您及时收到重要通知和更新,我们需要获取通知权限。请点击“确定”按钮,然后在设置页面中启用通知权限。": "To receive important updates, please click 'OK' and enable notifications in the settings.",
|
||||||
|
"开启后,可通过长按锁上的设置键重新上电,用APP重新添加": "After turning on, you can re-power on by long pressing the setting key on the lock, and re-add it with the APP",
|
||||||
|
"已有": "Already has",
|
||||||
|
"新增": "New",
|
||||||
|
"账号格式错误": "The account format is incorrect",
|
||||||
|
"接收者信息为空": "The recipient information is empty"
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -900,10 +900,19 @@
|
|||||||
"自定义邮件模版":"自定义邮件模版",
|
"自定义邮件模版":"自定义邮件模版",
|
||||||
"名称":"名称",
|
"名称":"名称",
|
||||||
"星星锁": "星星锁",
|
"星星锁": "星星锁",
|
||||||
|
|
||||||
"无考勤记录": "无考勤记录",
|
"无考勤记录": "无考勤记录",
|
||||||
"大家干劲十足": "大家干劲十足",
|
"大家干劲十足": "大家干劲十足",
|
||||||
"工作时长未出炉": "工作时长未出炉",
|
"工作时长未出炉": "工作时长未出炉",
|
||||||
"国家地区的选择将影响数据安全,你当前选择的是阿尔巴尼亚,请确认后再继续": "国家地区的选择将影响数据安全,你当前选择的是阿尔巴尼亚,请确认后再继续",
|
"国家地区的选择将影响数据安全,你当前选择的是阿尔巴尼亚,请确认后再继续": "国家地区的选择将影响数据安全,你当前选择的是阿尔巴尼亚,请确认后再继续",
|
||||||
"确认国家或地区": "确认国家或地区",
|
"确认国家或地区": "确认国家或地区",
|
||||||
"我知道了": "我知道了"
|
"我知道了": "我知道了",
|
||||||
|
|
||||||
|
"为了让您及时收到重要通知和更新,我们需要获取通知权限。请点击“确定”按钮,然后在设置页面中启用通知权限。": "为了让您及时收到重要通知和更新,我们需要获取通知权限。请点击“确定”按钮,然后在设置页面中启用通知权限。",
|
||||||
|
"开启后,可通过长按锁上的设置键重新上电,用APP重新添加":"开启后,可通过长按锁上的设置键重新上电,用APP重新添加",
|
||||||
|
"已有": "已有",
|
||||||
|
"新增": "新增",
|
||||||
|
"账号格式错误": "账号格式错误",
|
||||||
|
"接收者信息为空": "接收者信息为空"
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -862,17 +862,25 @@
|
|||||||
"五": "五",
|
"五": "五",
|
||||||
"六": "六",
|
"六": "六",
|
||||||
"日": "日",
|
"日": "日",
|
||||||
"新建短信模版":"新建短信模版",
|
|
||||||
"新建邮件模版":"新建邮件模版",
|
|
||||||
"自定义短信模版":"自定义短信模版",
|
|
||||||
"自定义邮件模版":"自定义邮件模版",
|
|
||||||
"名称":"名称",
|
|
||||||
"星星锁": "星星锁",
|
|
||||||
|
|
||||||
"无考勤记录": "无考勤记录",
|
"无考勤记录": "无考勤记录",
|
||||||
"大家干劲十足": "大家干劲十足",
|
"大家干劲十足": "大家干劲十足",
|
||||||
"工作时长未出炉": "工作时长未出炉",
|
"工作时长未出炉": "工作时长未出炉",
|
||||||
"国家地区的选择将影响数据安全,你当前选择的是阿尔巴尼亚,请确认后再继续": "国家地区的选择将影响数据安全,你当前选择的是阿尔巴尼亚,请确认后再继续",
|
"国家地区的选择将影响数据安全,你当前选择的是阿尔巴尼亚,请确认后再继续": "国家地区的选择将影响数据安全,你当前选择的是阿尔巴尼亚,请确认后再继续",
|
||||||
"确认国家或地区": "确认国家或地区",
|
"确认国家或地区": "确认国家或地区",
|
||||||
"我知道了": "我知道了"
|
"我知道了": "我知道了",
|
||||||
|
|
||||||
|
"新建短信模版": "新建短信模版",
|
||||||
|
"新建邮件模版": "新建邮件模版",
|
||||||
|
"自定义短信模版": "自定义短信模版",
|
||||||
|
"自定义邮件模版": "自定义邮件模版",
|
||||||
|
"名称": "名称",
|
||||||
|
"星星锁": "星星锁",
|
||||||
|
"为了让您及时收到重要通知和更新,我们需要获取通知权限。请点击“确定”按钮,然后在设置页面中启用通知权限。": "为了让您及时收到重要通知和更新,我们需要获取通知权限。请点击“确定”按钮,然后在设置页面中启用通知权限。",
|
||||||
|
"开启后,可通过长按锁上的设置键重新上电,用APP重新添加":"开启后,可通过长按锁上的设置键重新上电,用APP重新添加",
|
||||||
|
"已有": "已有",
|
||||||
|
"新增": "新增",
|
||||||
|
"账号格式错误": "账号格式错误",
|
||||||
|
"接收者信息为空": "接收者信息为空"
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -71,14 +71,14 @@
|
|||||||
// iOS 8 Notifications
|
// iOS 8 Notifications
|
||||||
[application registerUserNotificationSettings:
|
[application registerUserNotificationSettings:
|
||||||
[UIUserNotificationSettings settingsForTypes:
|
[UIUserNotificationSettings settingsForTypes:
|
||||||
(UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge)
|
(UIUserNotificationTypeSound | UIUserNotificationTypeAlert)
|
||||||
categories:nil]];
|
categories:nil]];
|
||||||
[application registerForRemoteNotifications];
|
[application registerForRemoteNotifications];
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// iOS < 8 Notifications
|
// iOS < 8 Notifications
|
||||||
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:
|
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:
|
||||||
(UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound)];
|
(UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound)];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
|
|||||||
@ -325,7 +325,8 @@ class BlueManage {
|
|||||||
mac != null) {
|
mac != null) {
|
||||||
scanSingleTimer?.cancel();
|
scanSingleTimer?.cancel();
|
||||||
//兼容android 的低配手机
|
//兼容android 的低配手机
|
||||||
await doNotSearchBLE(mac, connectStateCallBack);
|
await doNotSearchBLE(mac, connectStateCallBack,
|
||||||
|
isAddEquipment: isAddEquipment);
|
||||||
scanSingleTimer = Timer(3.seconds, () {
|
scanSingleTimer = Timer(3.seconds, () {
|
||||||
scanSingleTimer?.cancel();
|
scanSingleTimer?.cancel();
|
||||||
startScanSingle(deviceName, 15, (List<ScanResult> scanDevices) => null);
|
startScanSingle(deviceName, 15, (List<ScanResult> scanDevices) => null);
|
||||||
@ -384,6 +385,7 @@ class BlueManage {
|
|||||||
isAddEquipment == false) {
|
isAddEquipment == false) {
|
||||||
connectStateCallBack(BluetoothConnectionState.disconnected);
|
connectStateCallBack(BluetoothConnectionState.disconnected);
|
||||||
EasyLoading.showToast('该锁已被重置'.tr, duration: 2000.milliseconds);
|
EasyLoading.showToast('该锁已被重置'.tr, duration: 2000.milliseconds);
|
||||||
|
scanDevices.clear();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
//尝试连接设备
|
//尝试连接设备
|
||||||
@ -392,7 +394,8 @@ class BlueManage {
|
|||||||
|
|
||||||
//直接给蓝牙设备写入
|
//直接给蓝牙设备写入
|
||||||
Future<void> doNotSearchBLE(
|
Future<void> doNotSearchBLE(
|
||||||
String masAdds, ConnectStateCallBack connectStateCallBack) async {
|
String masAdds, ConnectStateCallBack connectStateCallBack,
|
||||||
|
{bool isAddEquipment = false}) async {
|
||||||
await FlutterBluePlus.stopScan();
|
await FlutterBluePlus.stopScan();
|
||||||
if (bluetoothConnectDevice == null ||
|
if (bluetoothConnectDevice == null ||
|
||||||
bluetoothConnectDevice?.remoteId.str != masAdds) {
|
bluetoothConnectDevice?.remoteId.str != masAdds) {
|
||||||
@ -401,12 +404,14 @@ class BlueManage {
|
|||||||
_initListenConnectionState();
|
_initListenConnectionState();
|
||||||
}
|
}
|
||||||
//尝试连接设备
|
//尝试连接设备
|
||||||
await bluetoothDeviceConnect(bluetoothConnectDevice!, connectStateCallBack);
|
await bluetoothDeviceConnect(bluetoothConnectDevice!, connectStateCallBack,
|
||||||
|
isAddEquipment: isAddEquipment);
|
||||||
}
|
}
|
||||||
|
|
||||||
//设备连接
|
//设备连接
|
||||||
Future<void> bluetoothDeviceConnect(BluetoothDevice bluetoothConnectDevice,
|
Future<void> bluetoothDeviceConnect(BluetoothDevice bluetoothConnectDevice,
|
||||||
ConnectStateCallBack connectStateCallBack) async {
|
ConnectStateCallBack connectStateCallBack,
|
||||||
|
{bool isAddEquipment = false}) async {
|
||||||
// 重连三次
|
// 重连三次
|
||||||
const int maxAttempts = 3;
|
const int maxAttempts = 3;
|
||||||
int attempt = 0;
|
int attempt = 0;
|
||||||
@ -430,23 +435,22 @@ class BlueManage {
|
|||||||
|
|
||||||
if (bluetoothConnectionState == BluetoothConnectionState.connected) {
|
if (bluetoothConnectionState == BluetoothConnectionState.connected) {
|
||||||
try {
|
try {
|
||||||
bluetoothConnectDevice!
|
final List<BluetoothService> services =
|
||||||
.discoverServices()
|
await bluetoothConnectDevice.discoverServices();
|
||||||
.then((List<BluetoothService> services) {
|
//循环判断服务
|
||||||
for (final BluetoothService service in services) {
|
for (final BluetoothService service in services) {
|
||||||
if (service.uuid == _serviceIdConnect) {
|
if (service.uuid == _serviceIdConnect) {
|
||||||
for (final BluetoothCharacteristic characteristic
|
for (final BluetoothCharacteristic characteristic
|
||||||
in service.characteristics) {
|
in service.characteristics) {
|
||||||
if (characteristic.characteristicUuid ==
|
if (characteristic.characteristicUuid ==
|
||||||
_characteristicIdSubscription) {
|
_characteristicIdSubscription) {
|
||||||
_subScribeToCharacteristic(characteristic);
|
_subScribeToCharacteristic(characteristic);
|
||||||
bluetoothConnectionState = BluetoothConnectionState.connected;
|
bluetoothConnectionState = BluetoothConnectionState.connected;
|
||||||
connectStateCallBack(bluetoothConnectionState!);
|
connectStateCallBack(bluetoothConnectionState!);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
} on Exception catch (e) {
|
} on Exception catch (e) {
|
||||||
bluetoothConnectionState = BluetoothConnectionState.disconnected;
|
bluetoothConnectionState = BluetoothConnectionState.disconnected;
|
||||||
connectStateCallBack(bluetoothConnectionState!);
|
connectStateCallBack(bluetoothConnectionState!);
|
||||||
|
|||||||
@ -170,7 +170,6 @@ class _MassSendElectronicKeyPageState extends State<MassSendElectronicKeyPage> {
|
|||||||
if (value != null) {
|
if (value != null) {
|
||||||
value as Map<String, dynamic>;
|
value as Map<String, dynamic>;
|
||||||
state.receiverList = value['lockUserList'];
|
state.receiverList = value['lockUserList'];
|
||||||
|
|
||||||
setState(() {});
|
setState(() {});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@ -3,6 +3,7 @@ import 'package:flutter_native_contact_picker/flutter_native_contact_picker.dart
|
|||||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:star_lock/main/lockDetail/electronicKey/massSendElectronicKey/massSendLockGroupList/lockUserList/lockUserList_entity.dart';
|
import 'package:star_lock/main/lockDetail/electronicKey/massSendElectronicKey/massSendLockGroupList/lockUserList/lockUserList_entity.dart';
|
||||||
|
import 'package:star_lock/tools/regexp_tool.dart';
|
||||||
import 'package:star_lock/translations/trans_lib.dart';
|
import 'package:star_lock/translations/trans_lib.dart';
|
||||||
import '../../../../../../app_settings/app_colors.dart';
|
import '../../../../../../app_settings/app_colors.dart';
|
||||||
|
|
||||||
@ -13,6 +14,7 @@ class MassSendReceiverCell extends StatefulWidget {
|
|||||||
required this.onDeleteUser,
|
required this.onDeleteUser,
|
||||||
Key? key,
|
Key? key,
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
final int currentIndex;
|
final int currentIndex;
|
||||||
final LockUserItemData userData;
|
final LockUserItemData userData;
|
||||||
final VoidCallback onDeleteUser;
|
final VoidCallback onDeleteUser;
|
||||||
@ -25,6 +27,7 @@ class _MassSendReceiverCellState extends State<MassSendReceiverCell> {
|
|||||||
final FlutterContactPicker contactPicker = FlutterContactPicker();
|
final FlutterContactPicker contactPicker = FlutterContactPicker();
|
||||||
late TextEditingController _receiverController;
|
late TextEditingController _receiverController;
|
||||||
late TextEditingController _nickNameController;
|
late TextEditingController _nickNameController;
|
||||||
|
RxString errorTxt = ''.obs;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
@ -50,50 +53,95 @@ class _MassSendReceiverCellState extends State<MassSendReceiverCell> {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Container(
|
return Column(
|
||||||
color: Colors.white,
|
mainAxisSize: MainAxisSize.min,
|
||||||
child: Row(
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: <Widget>[
|
||||||
GestureDetector(
|
Container(
|
||||||
onTap: widget.onDeleteUser,
|
color: Colors.white,
|
||||||
child: Padding(
|
child: Row(
|
||||||
padding: EdgeInsets.symmetric(horizontal: 20.w),
|
children: <Widget>[
|
||||||
child: Image.asset(
|
GestureDetector(
|
||||||
'images/icon_massSend_delete.png',
|
onTap: widget.onDeleteUser,
|
||||||
width: 26.w,
|
child: Container(
|
||||||
height: 26.w,
|
color: Colors.transparent,
|
||||||
|
padding: EdgeInsets.all(20.r),
|
||||||
|
child: Image.asset(
|
||||||
|
'images/icon_massSend_delete.png',
|
||||||
|
width: 26.w,
|
||||||
|
height: 26.w,
|
||||||
|
),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
Expanded(
|
||||||
|
child: Column(
|
||||||
|
children: <Widget>[
|
||||||
|
_buildCellWidget(
|
||||||
|
leftTitle: TranslationLoader.lanKeys!.receiver!.tr,
|
||||||
|
isInputField: true,
|
||||||
|
inputHint: TranslationLoader
|
||||||
|
.lanKeys!.pleaseEnterNumberOrEmail!.tr,
|
||||||
|
controller: _receiverController,
|
||||||
|
isContactPickerEnabled: true,
|
||||||
|
onSubmitted: (String text) {
|
||||||
|
final bool isEmail = RegexpTool.isEmail(text);
|
||||||
|
final bool isPhoneNumber =
|
||||||
|
RegexpTool.isPhoneNumber(text);
|
||||||
|
if (text.trim() == '' || isEmail || isPhoneNumber) {
|
||||||
|
errorTxt.value = '';
|
||||||
|
} else {
|
||||||
|
errorTxt.value = '账号格式错误'.tr;
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
Divider(
|
||||||
|
color: AppColors.greyLineColor,
|
||||||
|
indent: 20.w,
|
||||||
|
endIndent: 20.w,
|
||||||
|
height: 1,
|
||||||
|
),
|
||||||
|
_buildCellWidget(
|
||||||
|
leftTitle: TranslationLoader.lanKeys!.name!.tr,
|
||||||
|
isInputField: true,
|
||||||
|
inputHint: TranslationLoader.lanKeys!.enterYourName!.tr,
|
||||||
|
controller: _nickNameController,
|
||||||
|
isContactPickerEnabled: false,
|
||||||
|
onSubmitted: (String text) {
|
||||||
|
final bool isEmail = RegexpTool.isEmail(text);
|
||||||
|
final bool isPhoneNumber =
|
||||||
|
RegexpTool.isPhoneNumber(text);
|
||||||
|
if (text.trim() == '' || isEmail || isPhoneNumber) {
|
||||||
|
errorTxt.value = '';
|
||||||
|
} else {
|
||||||
|
errorTxt.value = '账号格式错误'.tr;
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
Expanded(
|
),
|
||||||
child: Column(
|
Obx(() {
|
||||||
children: [
|
return errorTxt.value.trim() != ''
|
||||||
_buildCellWidget(
|
? Padding(
|
||||||
leftTitle: TranslationLoader.lanKeys!.receiver!.tr,
|
padding: EdgeInsets.only(
|
||||||
isInputField: true,
|
left: 80.w,
|
||||||
inputHint:
|
top: 10.h,
|
||||||
TranslationLoader.lanKeys!.pleaseEnterNumberOrEmail!.tr,
|
bottom: 10.h,
|
||||||
controller: _receiverController,
|
),
|
||||||
isContactPickerEnabled: true,
|
child: Text(
|
||||||
),
|
errorTxt.value,
|
||||||
Divider(
|
style: TextStyle(
|
||||||
color: AppColors.greyLineColor,
|
color: Colors.red,
|
||||||
indent: 20.w,
|
fontSize: 18.sp,
|
||||||
endIndent: 20.w,
|
),
|
||||||
height: 1,
|
),
|
||||||
),
|
)
|
||||||
_buildCellWidget(
|
: SizedBox(
|
||||||
leftTitle: TranslationLoader.lanKeys!.name!.tr,
|
height: 10.w,
|
||||||
isInputField: true,
|
);
|
||||||
inputHint: TranslationLoader.lanKeys!.enterYourName!.tr,
|
}),
|
||||||
controller: _nickNameController,
|
],
|
||||||
isContactPickerEnabled: false,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -103,20 +151,22 @@ class _MassSendReceiverCellState extends State<MassSendReceiverCell> {
|
|||||||
required String inputHint,
|
required String inputHint,
|
||||||
required TextEditingController controller,
|
required TextEditingController controller,
|
||||||
required bool isContactPickerEnabled,
|
required bool isContactPickerEnabled,
|
||||||
|
ValueChanged<String>? onSubmitted,
|
||||||
}) {
|
}) {
|
||||||
return Container(
|
return Container(
|
||||||
height: 60.h,
|
height: 60.h,
|
||||||
padding: EdgeInsets.only(right: 20.w),
|
padding: EdgeInsets.only(right: 20.w),
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: <Widget>[
|
||||||
SizedBox(width: 20.w),
|
SizedBox(width: 20.w),
|
||||||
Text(leftTitle, style: TextStyle(fontSize: 22.sp)),
|
Text(leftTitle, style: TextStyle(fontSize: 22.sp)),
|
||||||
Expanded(child: SizedBox(width: 10.w)),
|
Expanded(child: SizedBox(width: 10.w)),
|
||||||
Row(
|
Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.end,
|
mainAxisAlignment: MainAxisAlignment.end,
|
||||||
children: [
|
children: <Widget>[
|
||||||
if (isInputField)
|
if (isInputField)
|
||||||
_buildTextField(controller, inputHint, isContactPickerEnabled)
|
_buildTextField(controller, inputHint, isContactPickerEnabled,
|
||||||
|
onSubmitted: onSubmitted)
|
||||||
else
|
else
|
||||||
Text(
|
Text(
|
||||||
controller.text,
|
controller.text,
|
||||||
@ -132,11 +182,12 @@ class _MassSendReceiverCellState extends State<MassSendReceiverCell> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildTextField(TextEditingController controller, String hintText,
|
Widget _buildTextField(TextEditingController controller, String hintText,
|
||||||
bool isContactPickerEnabled) {
|
bool isContactPickerEnabled,
|
||||||
|
{ValueChanged<String>? onSubmitted}) {
|
||||||
return SizedBox(
|
return SizedBox(
|
||||||
width: 380.w,
|
width: 380.w,
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: <Widget>[
|
||||||
Expanded(
|
Expanded(
|
||||||
child: TextField(
|
child: TextField(
|
||||||
controller: controller,
|
controller: controller,
|
||||||
@ -148,6 +199,7 @@ class _MassSendReceiverCellState extends State<MassSendReceiverCell> {
|
|||||||
hintStyle: TextStyle(fontSize: 22.sp),
|
hintStyle: TextStyle(fontSize: 22.sp),
|
||||||
border: InputBorder.none,
|
border: InputBorder.none,
|
||||||
),
|
),
|
||||||
|
onSubmitted: onSubmitted,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
if (isContactPickerEnabled)
|
if (isContactPickerEnabled)
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
import 'package:get/get.dart';
|
||||||
import 'package:star_lock/main/lockDetail/electronicKey/massSendElectronicKey/massSendLockGroupList/lockUserList/lockUserList_entity.dart';
|
import 'package:star_lock/main/lockDetail/electronicKey/massSendElectronicKey/massSendLockGroupList/lockUserList/lockUserList_entity.dart';
|
||||||
import 'package:star_lock/main/lockDetail/electronicKey/massSendElectronicKey/massSendLockGroupList/massSendReceiver/massSendReceiver_state.dart';
|
import 'package:star_lock/main/lockDetail/electronicKey/massSendElectronicKey/massSendLockGroupList/massSendReceiver/massSendReceiver_state.dart';
|
||||||
import 'package:star_lock/tools/baseGetXController.dart';
|
import 'package:star_lock/tools/baseGetXController.dart';
|
||||||
@ -6,14 +7,25 @@ import 'package:star_lock/tools/storage.dart';
|
|||||||
class MassSendReceiverLogic extends BaseGetXController {
|
class MassSendReceiverLogic extends BaseGetXController {
|
||||||
MassSendReceiverState state = MassSendReceiverState();
|
MassSendReceiverState state = MassSendReceiverState();
|
||||||
|
|
||||||
|
@override
|
||||||
|
void onInit() {
|
||||||
|
super.onInit();
|
||||||
|
final dynamic data = Get.arguments;
|
||||||
|
if (data is Map && data['lockUserList'] is List) {
|
||||||
|
data['lockUserList'].forEach((dynamic lockUser) {
|
||||||
|
state.lockUserList.add(lockUser);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> onReady() async {
|
Future<void> onReady() async {
|
||||||
super.onReady();
|
super.onReady();
|
||||||
|
|
||||||
LockUserItemData data = LockUserItemData();
|
final LockUserItemData data = LockUserItemData();
|
||||||
state.lockUserList.add(data);
|
state.lockUserList.add(data);
|
||||||
|
|
||||||
var isVip = await Storage.getBool(saveIsVip);
|
final bool? isVip = await Storage.getBool(saveIsVip);
|
||||||
state.isVip.value = isVip ?? false;
|
state.isVip.value = isVip ?? false;
|
||||||
state.isVip.refresh();
|
state.isVip.refresh();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,13 +1,17 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_easyloading/flutter_easyloading.dart';
|
||||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:star_lock/appRouters.dart';
|
import 'package:star_lock/appRouters.dart';
|
||||||
import 'package:star_lock/app_settings/app_colors.dart';
|
import 'package:star_lock/app_settings/app_colors.dart';
|
||||||
|
import 'package:star_lock/app_settings/app_settings.dart';
|
||||||
import 'package:star_lock/main/lockDetail/electronicKey/massSendElectronicKey/massSendLockGroupList/lockUserList/lockUserList_entity.dart';
|
import 'package:star_lock/main/lockDetail/electronicKey/massSendElectronicKey/massSendLockGroupList/lockUserList/lockUserList_entity.dart';
|
||||||
import 'package:star_lock/main/lockDetail/electronicKey/massSendElectronicKey/massSendLockGroupList/massSendReceiver/massSendReceiverCell.dart';
|
import 'package:star_lock/main/lockDetail/electronicKey/massSendElectronicKey/massSendLockGroupList/massSendReceiver/massSendReceiverCell.dart';
|
||||||
import 'package:star_lock/main/lockDetail/electronicKey/massSendElectronicKey/massSendLockGroupList/massSendReceiver/massSendReceiver_logic.dart';
|
import 'package:star_lock/main/lockDetail/electronicKey/massSendElectronicKey/massSendLockGroupList/massSendReceiver/massSendReceiver_logic.dart';
|
||||||
import 'package:star_lock/tools/showCupertinoAlertView.dart';
|
import 'package:star_lock/main/lockDetail/electronicKey/massSendElectronicKey/massSendLockGroupList/massSendReceiver/massSendReceiver_state.dart';
|
||||||
import 'package:star_lock/tools/commonItem.dart';
|
import 'package:star_lock/tools/commonItem.dart';
|
||||||
|
import 'package:star_lock/tools/regexp_tool.dart';
|
||||||
|
import 'package:star_lock/tools/showCupertinoAlertView.dart';
|
||||||
import 'package:star_lock/translations/trans_lib.dart';
|
import 'package:star_lock/translations/trans_lib.dart';
|
||||||
|
|
||||||
class MassSendReceiverPage extends StatefulWidget {
|
class MassSendReceiverPage extends StatefulWidget {
|
||||||
@ -20,8 +24,8 @@ class MassSendReceiverPage extends StatefulWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _MassSendReceiverPageState extends State<MassSendReceiverPage> {
|
class _MassSendReceiverPageState extends State<MassSendReceiverPage> {
|
||||||
final logic = Get.put(MassSendReceiverLogic());
|
final MassSendReceiverLogic logic = Get.put(MassSendReceiverLogic());
|
||||||
final state = Get.find<MassSendReceiverLogic>().state;
|
final MassSendReceiverState state = Get.find<MassSendReceiverLogic>().state;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
@ -40,7 +44,7 @@ class _MassSendReceiverPageState extends State<MassSendReceiverPage> {
|
|||||||
icon: const Icon(Icons.arrow_back_ios, color: Colors.white),
|
icon: const Icon(Icons.arrow_back_ios, color: Colors.white),
|
||||||
onPressed: () => Navigator.of(context).pop(),
|
onPressed: () => Navigator.of(context).pop(),
|
||||||
),
|
),
|
||||||
actions: [
|
actions: <Widget>[
|
||||||
TextButton(
|
TextButton(
|
||||||
child: Text(
|
child: Text(
|
||||||
TranslationLoader.lanKeys!.save!.tr,
|
TranslationLoader.lanKeys!.save!.tr,
|
||||||
@ -50,24 +54,37 @@ class _MassSendReceiverPageState extends State<MassSendReceiverPage> {
|
|||||||
if (!state.isVip.value) {
|
if (!state.isVip.value) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Map<String, dynamic> resultMap = {};
|
if (state.lockUserList.isEmpty) {
|
||||||
resultMap['lockUserList'] = state.lockUserList.value;
|
EasyLoading.showToast('接收者信息为空'.tr);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (final LockUserItemData userItem in state.lockUserList) {
|
||||||
|
final bool isEmail = RegexpTool.isEmail(userItem.userid ?? '');
|
||||||
|
final bool isPhoneNumber =
|
||||||
|
RegexpTool.isPhoneNumber(userItem.userid ?? '');
|
||||||
|
if (!isEmail && !isPhoneNumber) {
|
||||||
|
EasyLoading.showToast('账号格式错误'.tr);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
final Map<String, dynamic> resultMap = <String, dynamic>{};
|
||||||
|
resultMap['lockUserList'] = state.lockUserList;
|
||||||
Navigator.pop(context, resultMap);
|
Navigator.pop(context, resultMap);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
body: Column(
|
body: Column(
|
||||||
children: [
|
children: <Widget>[
|
||||||
Obx(() => Visibility(
|
Obx(() => Visibility(
|
||||||
visible: state.isVip.value ? false : true,
|
visible: !state.isVip.value,
|
||||||
child: ShowCupertinoAlertView()
|
child: ShowCupertinoAlertView()
|
||||||
.topTipsAdvancedFeatures('开通高级功能后才可以选择和添加接收者'.tr))),
|
.topTipsAdvancedFeatures('开通高级功能后才可以选择和添加接收者'.tr))),
|
||||||
Obx(() => Visibility(
|
Obx(() => Visibility(
|
||||||
visible: state.isVip.value ? true : false,
|
visible: state.isVip.value,
|
||||||
child: CommonItem(
|
child: CommonItem(
|
||||||
leftTitel: TranslationLoader.lanKeys!.countryAndRegion!.tr,
|
leftTitel: TranslationLoader.lanKeys!.countryAndRegion!.tr,
|
||||||
rightTitle: "",
|
rightTitle: '',
|
||||||
isHaveLine: true,
|
isHaveLine: true,
|
||||||
isHaveRightWidget: true,
|
isHaveRightWidget: true,
|
||||||
isHaveDirection: true,
|
isHaveDirection: true,
|
||||||
@ -78,7 +95,7 @@ class _MassSendReceiverPageState extends State<MassSendReceiverPage> {
|
|||||||
fontSize: 22.sp, color: AppColors.darkGrayTextColor),
|
fontSize: 22.sp, color: AppColors.darkGrayTextColor),
|
||||||
),
|
),
|
||||||
action: () async {
|
action: () async {
|
||||||
var result = await Navigator.pushNamed(
|
final Object? result = await Navigator.pushNamed(
|
||||||
context, Routers.selectCountryRegionPage);
|
context, Routers.selectCountryRegionPage);
|
||||||
if (result != null) {
|
if (result != null) {
|
||||||
result as Map<String, dynamic>;
|
result as Map<String, dynamic>;
|
||||||
@ -88,24 +105,26 @@ class _MassSendReceiverPageState extends State<MassSendReceiverPage> {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
))),
|
))),
|
||||||
Obx(() => Row(
|
Obx(() => Padding(
|
||||||
children: [controlViewTitle(0), controlViewTitle(1)],
|
padding: EdgeInsets.symmetric(vertical: 20.h),
|
||||||
|
child: Row(
|
||||||
|
children: <Widget>[controlViewTitle(0), controlViewTitle(1)],
|
||||||
|
),
|
||||||
)),
|
)),
|
||||||
SizedBox(
|
SizedBox(
|
||||||
height: 2.h,
|
height: 2.h,
|
||||||
),
|
),
|
||||||
Obx(() => Visibility(
|
Obx(() => Visibility(
|
||||||
visible: state.isVip.value ? true : false,
|
visible: state.isVip.value,
|
||||||
child: Expanded(
|
child: Expanded(
|
||||||
child: ListView.separated(
|
child: ListView.separated(
|
||||||
itemBuilder: (BuildContext context, int index) {
|
itemBuilder: (BuildContext context, int index) {
|
||||||
LockUserItemData data = state.lockUserList.value[index];
|
final LockUserItemData data = state.lockUserList[index];
|
||||||
state.emailOrPhoneController.text = data.userid ?? '';
|
state.emailOrPhoneController.text = data.userid ?? '';
|
||||||
state.keyNameController.text = data.nickname ?? '';
|
state.keyNameController.text = data.nickname ?? '';
|
||||||
|
|
||||||
return _itemBuilder(index, data);
|
return _itemBuilder(index, data);
|
||||||
},
|
},
|
||||||
itemCount: state.lockUserList.value.length,
|
itemCount: state.lockUserList.length,
|
||||||
separatorBuilder: (BuildContext context, int index) {
|
separatorBuilder: (BuildContext context, int index) {
|
||||||
return Divider(
|
return Divider(
|
||||||
height: 20.h,
|
height: 20.h,
|
||||||
@ -129,7 +148,7 @@ class _MassSendReceiverPageState extends State<MassSendReceiverPage> {
|
|||||||
child: Row(
|
child: Row(
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: [
|
children: <Widget>[
|
||||||
Image.asset(
|
Image.asset(
|
||||||
state.isVip.value
|
state.isVip.value
|
||||||
? 'images/icon_btn_add.png'
|
? 'images/icon_btn_add.png'
|
||||||
@ -141,7 +160,7 @@ class _MassSendReceiverPageState extends State<MassSendReceiverPage> {
|
|||||||
width: 6.w,
|
width: 6.w,
|
||||||
),
|
),
|
||||||
Text(
|
Text(
|
||||||
btnIndex == 0 ? '已有' : '新增',
|
btnIndex == 0 ? '已有'.tr : '新增'.tr,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: state.isVip.value
|
color: state.isVip.value
|
||||||
? AppColors.mainColor
|
? AppColors.mainColor
|
||||||
@ -158,17 +177,27 @@ class _MassSendReceiverPageState extends State<MassSendReceiverPage> {
|
|||||||
}
|
}
|
||||||
if (btnIndex == 0) {
|
if (btnIndex == 0) {
|
||||||
//已有
|
//已有
|
||||||
Navigator.pushNamed(context, Routers.lockUserListPage).then((val) {
|
Navigator.pushNamed(context, Routers.lockUserListPage)
|
||||||
|
.then((Object? val) {
|
||||||
if (val != null) {
|
if (val != null) {
|
||||||
val as Map<String, dynamic>;
|
val as Map<String, dynamic>;
|
||||||
state.lockUserList.value = val['lockUserList'];
|
if (val['lockUserList'] is List) {
|
||||||
|
final List<int?> uid = state.lockUserList
|
||||||
|
.where((LockUserItemData e) => e.isCheck ?? false)
|
||||||
|
.map((LockUserItemData e) => e.uid)
|
||||||
|
.toList();
|
||||||
|
val['lockUserList'].forEach((LockUserItemData itemData) {
|
||||||
|
if (!uid.contains(itemData.uid)) {
|
||||||
|
state.lockUserList.add(itemData);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
setState(() {});
|
setState(() {});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else if (btnIndex == 1) {
|
} else if (btnIndex == 1) {
|
||||||
//新增
|
//新增
|
||||||
state.lockUserList.value.add(LockUserItemData());
|
state.lockUserList.add(LockUserItemData());
|
||||||
setState(() {});
|
setState(() {});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -177,12 +206,11 @@ class _MassSendReceiverPageState extends State<MassSendReceiverPage> {
|
|||||||
|
|
||||||
Widget _itemBuilder(int index, LockUserItemData userData) {
|
Widget _itemBuilder(int index, LockUserItemData userData) {
|
||||||
return MassSendReceiverCell(
|
return MassSendReceiverCell(
|
||||||
currentIndex: index,
|
currentIndex: index,
|
||||||
userData: userData,
|
userData: userData,
|
||||||
onDeleteUser: () {
|
onDeleteUser: () {
|
||||||
state.lockUserList.removeAt(index - 1);
|
state.lockUserList.removeAt(index);
|
||||||
setState(() {});
|
setState(() {});
|
||||||
},
|
});
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -10,11 +10,11 @@ class MassSendReceiverState {
|
|||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
|
||||||
var isVip = false.obs;
|
RxBool isVip = false.obs;
|
||||||
var lockUserList = <LockUserItemData>[].obs;
|
RxList<LockUserItemData> lockUserList = <LockUserItemData>[].obs;
|
||||||
TextEditingController emailOrPhoneController = TextEditingController();
|
TextEditingController emailOrPhoneController = TextEditingController();
|
||||||
TextEditingController keyNameController = TextEditingController();
|
TextEditingController keyNameController = TextEditingController();
|
||||||
|
|
||||||
var countryCode = '86'.obs;
|
RxString countryCode = '86'.obs;
|
||||||
var countryName = '中国'.obs;
|
RxString countryName = '中国'.obs;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,11 +1,10 @@
|
|||||||
import 'package:flutter/cupertino.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_easyloading/flutter_easyloading.dart';
|
import 'package:flutter_easyloading/flutter_easyloading.dart';
|
||||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
|
import '../../../../flavors.dart';
|
||||||
|
|
||||||
import '../../../../app_settings/app_colors.dart';
|
import '../../../../app_settings/app_colors.dart';
|
||||||
import '../../../../blue/blue_manage.dart';
|
|
||||||
import '../../../../tools/appRouteObserver.dart';
|
import '../../../../tools/appRouteObserver.dart';
|
||||||
import '../../../../tools/showTipView.dart';
|
import '../../../../tools/showTipView.dart';
|
||||||
import '../../../../tools/submitBtn.dart';
|
import '../../../../tools/submitBtn.dart';
|
||||||
@ -23,7 +22,7 @@ class ResetButtonPage extends StatefulWidget {
|
|||||||
class _ResetButtonPageState extends State<ResetButtonPage> with RouteAware {
|
class _ResetButtonPageState extends State<ResetButtonPage> with RouteAware {
|
||||||
final logic = Get.put(ResetButtonLogic());
|
final logic = Get.put(ResetButtonLogic());
|
||||||
final state = Get.find<ResetButtonLogic>().state;
|
final state = Get.find<ResetButtonLogic>().state;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
@ -44,10 +43,16 @@ class _ResetButtonPageState extends State<ResetButtonPage> with RouteAware {
|
|||||||
mainAxisAlignment: MainAxisAlignment.start,
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
if (F.isSKY)
|
||||||
TranslationLoader.lanKeys!.resetButtonTip1!.tr,
|
Text(
|
||||||
style: TextStyle(fontSize: 20.sp),
|
TranslationLoader.lanKeys!.resetButtonTip1!.tr,
|
||||||
),
|
style: TextStyle(fontSize: 20.sp),
|
||||||
|
)
|
||||||
|
else
|
||||||
|
Text(
|
||||||
|
'开启后,可通过长按锁上的设置键重新上电,用APP重新添加'.tr,
|
||||||
|
style: TextStyle(fontSize: 20.sp),
|
||||||
|
),
|
||||||
SizedBox(
|
SizedBox(
|
||||||
height: 10.h,
|
height: 10.h,
|
||||||
),
|
),
|
||||||
@ -63,35 +68,38 @@ class _ResetButtonPageState extends State<ResetButtonPage> with RouteAware {
|
|||||||
height: 30.h,
|
height: 30.h,
|
||||||
),
|
),
|
||||||
Obx(() => Row(
|
Obx(() => Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.start,
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Text(
|
child: Text(
|
||||||
"${TranslationLoader.lanKeys!.currentMode!.tr} : ${state.resetButtonEnable.value == 1 ? TranslationLoader.lanKeys!.opened!.tr : TranslationLoader.lanKeys!.closed!.tr}",
|
"${TranslationLoader.lanKeys!.currentMode!.tr} : ${state.resetButtonEnable.value == 1 ? TranslationLoader.lanKeys!.opened!.tr : TranslationLoader.lanKeys!.closed!.tr}",
|
||||||
style:
|
style: TextStyle(
|
||||||
TextStyle(fontWeight: FontWeight.w600, fontSize: 20.sp),
|
fontWeight: FontWeight.w600, fontSize: 20.sp),
|
||||||
)),
|
)),
|
||||||
],
|
],
|
||||||
)),
|
)),
|
||||||
SizedBox(
|
SizedBox(
|
||||||
height: 30.h,
|
height: 30.h,
|
||||||
),
|
),
|
||||||
Obx(() => SubmitBtn(
|
Obx(() => SubmitBtn(
|
||||||
btnName: state.resetButtonEnable.value == 1 ? TranslationLoader.lanKeys!.close!.tr : TranslationLoader.lanKeys!.open!.tr,
|
btnName: state.resetButtonEnable.value == 1
|
||||||
|
? TranslationLoader.lanKeys!.close!.tr
|
||||||
|
: TranslationLoader.lanKeys!.open!.tr,
|
||||||
borderRadius: 20.w,
|
borderRadius: 20.w,
|
||||||
fontSize: 32.sp,
|
fontSize: 32.sp,
|
||||||
// margin: EdgeInsets.only(left: 03.w, right: 30.w, top: 20.w),
|
// margin: EdgeInsets.only(left: 03.w, right: 30.w, top: 20.w),
|
||||||
padding: EdgeInsets.only(top: 20.w, bottom: 20.w),
|
padding: EdgeInsets.only(top: 20.w, bottom: 20.w),
|
||||||
onClick: () {
|
onClick: () {
|
||||||
// showDeletAlertTipDialog(context);
|
// showDeletAlertTipDialog(context);
|
||||||
ShowTipView().showIosTipWithContentDialog('确定要${state.resetButtonEnable.value == 1 ? TranslationLoader.lanKeys!.close!.tr : TranslationLoader.lanKeys!.open!.tr}重置键?', () {
|
ShowTipView().showIosTipWithContentDialog(
|
||||||
|
'确定要${state.resetButtonEnable.value == 1 ? TranslationLoader.lanKeys!.close!.tr : TranslationLoader.lanKeys!.open!.tr}重置键?',
|
||||||
|
() {
|
||||||
logic.sendBurglarAlarm();
|
logic.sendBurglarAlarm();
|
||||||
});
|
});
|
||||||
})),
|
})),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
)
|
));
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -144,5 +152,4 @@ class _ResetButtonPageState extends State<ResetButtonPage> with RouteAware {
|
|||||||
state.ifCurrentScreen.value = false;
|
state.ifCurrentScreen.value = false;
|
||||||
state.sureBtnState.value = 0;
|
state.sureBtnState.value = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,7 +1,11 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
import 'dart:io';
|
||||||
import 'package:connectivity_plus/connectivity_plus.dart';
|
import 'package:connectivity_plus/connectivity_plus.dart';
|
||||||
|
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
|
import 'package:permission_handler/permission_handler.dart';
|
||||||
import 'package:star_lock/main/lockMian/lockList/lockList_logic.dart';
|
import 'package:star_lock/main/lockMian/lockList/lockList_logic.dart';
|
||||||
|
import 'package:star_lock/tools/showTipView.dart';
|
||||||
|
|
||||||
import '../../../app_settings/app_settings.dart';
|
import '../../../app_settings/app_settings.dart';
|
||||||
import '../../../blue/blue_manage.dart';
|
import '../../../blue/blue_manage.dart';
|
||||||
@ -17,7 +21,8 @@ class LockMainLogic extends BaseGetXController {
|
|||||||
|
|
||||||
Future<LockListInfoEntity> getStarLockInfo(
|
Future<LockListInfoEntity> getStarLockInfo(
|
||||||
{bool isUnShowLoading = false}) async {
|
{bool isUnShowLoading = false}) async {
|
||||||
LockListInfoEntity entity = await ApiRepository.to.getStarLockListInfo(
|
final LockListInfoEntity entity =
|
||||||
|
await ApiRepository.to.getStarLockListInfo(
|
||||||
pageNo: pageNo,
|
pageNo: pageNo,
|
||||||
pageSize: 50,
|
pageSize: 50,
|
||||||
isUnShowLoading: isUnShowLoading,
|
isUnShowLoading: isUnShowLoading,
|
||||||
@ -59,33 +64,35 @@ class LockMainLogic extends BaseGetXController {
|
|||||||
|
|
||||||
/// 获取联网类型
|
/// 获取联网类型
|
||||||
void getConnectType() async {
|
void getConnectType() async {
|
||||||
var connectResult = await (Connectivity().checkConnectivity());
|
final ConnectivityResult connectResult =
|
||||||
|
await (Connectivity().checkConnectivity());
|
||||||
if (connectResult == ConnectivityResult.mobile) {
|
if (connectResult == ConnectivityResult.mobile) {
|
||||||
// _netType = "4G";
|
// _netType = "4G";
|
||||||
state.networkConnectionStatus.value = 1;
|
state.networkConnectionStatus.value = 1;
|
||||||
AppLog.log("网络连接: 4G 4G 4G 4G 4G");
|
AppLog.log('网络连接: 4G 4G 4G 4G 4G');
|
||||||
} else if (connectResult == ConnectivityResult.wifi) {
|
} else if (connectResult == ConnectivityResult.wifi) {
|
||||||
// _netType = "wifi";
|
// _netType = "wifi";
|
||||||
state.networkConnectionStatus.value = 1;
|
state.networkConnectionStatus.value = 1;
|
||||||
AppLog.log("网络连接: wifi wifi wifi wifi wifi");
|
AppLog.log('网络连接: wifi wifi wifi wifi wifi');
|
||||||
} else {
|
} else {
|
||||||
// _netType = "未连接";
|
// _netType = "未连接";
|
||||||
state.networkConnectionStatus.value = 0;
|
state.networkConnectionStatus.value = 0;
|
||||||
AppLog.log("网络连接: 未连接 未连接 未连接 未连接 未连接");
|
AppLog.log('网络连接: 未连接 未连接 未连接 未连接 未连接');
|
||||||
// showToast("网络访问失败,请检查网络是否正常");
|
// showToast("网络访问失败,请检查网络是否正常");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 判断网络是否连接
|
/// 判断网络是否连接
|
||||||
Future<bool> isConnected() async {
|
Future<bool> isConnected() async {
|
||||||
var connectResult = await (Connectivity().checkConnectivity());
|
final ConnectivityResult connectResult =
|
||||||
|
await Connectivity().checkConnectivity();
|
||||||
return connectResult != ConnectivityResult.none;
|
return connectResult != ConnectivityResult.none;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 设置网络切换监听
|
/// 设置网络切换监听
|
||||||
connectListener() async {
|
Future<void> connectListener() async {
|
||||||
Connectivity().onConnectivityChanged.listen((ConnectivityResult result) {
|
Connectivity().onConnectivityChanged.listen((ConnectivityResult result) {
|
||||||
AppLog.log("设置网络切换监听:$result");
|
AppLog.log('设置网络切换监听:$result');
|
||||||
if (state.networkConnectionStatus.value == 0 &&
|
if (state.networkConnectionStatus.value == 0 &&
|
||||||
result != ConnectivityResult.none) {
|
result != ConnectivityResult.none) {
|
||||||
// 从无网络到有网络
|
// 从无网络到有网络
|
||||||
@ -95,36 +102,52 @@ class LockMainLogic extends BaseGetXController {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 检测推送是否开启
|
||||||
|
Future<void> checkWhetherPushIsEnabled() async {
|
||||||
|
bool notificationEnabled = false;
|
||||||
|
|
||||||
|
if (Platform.isAndroid) {
|
||||||
|
notificationEnabled = await FlutterLocalNotificationsPlugin()
|
||||||
|
.resolvePlatformSpecificImplementation<
|
||||||
|
AndroidFlutterLocalNotificationsPlugin>()
|
||||||
|
?.areNotificationsEnabled() ??
|
||||||
|
false;
|
||||||
|
} else if (Platform.isIOS) {
|
||||||
|
notificationEnabled = await FlutterLocalNotificationsPlugin()
|
||||||
|
.resolvePlatformSpecificImplementation<
|
||||||
|
IOSFlutterLocalNotificationsPlugin>()
|
||||||
|
?.requestPermissions(
|
||||||
|
alert: true,
|
||||||
|
badge: false,
|
||||||
|
sound: true,
|
||||||
|
) ??
|
||||||
|
false;
|
||||||
|
}
|
||||||
|
if (!notificationEnabled) {
|
||||||
|
//推送未开启
|
||||||
|
ShowTipView().showIosTipWithContentDialog(
|
||||||
|
'为了让您及时收到重要通知和更新,我们需要获取通知权限。请点击“确定”按钮,然后在设置页面中启用通知权限。'.tr, () async {
|
||||||
|
openAppSettings();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void onReady() {
|
void onReady() {
|
||||||
// TODO: implement onReady
|
|
||||||
super.onReady();
|
super.onReady();
|
||||||
|
|
||||||
// 开启UDP
|
// 开启UDP
|
||||||
UdpHelp().openUDP();
|
UdpHelp().openUDP();
|
||||||
|
|
||||||
BlueManage();
|
BlueManage();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void onInit() {
|
void onInit() {
|
||||||
// TODO: implement onInit
|
|
||||||
super.onInit();
|
super.onInit();
|
||||||
|
checkWhetherPushIsEnabled();
|
||||||
// getLockInfo();
|
|
||||||
// 设置网络变化监听
|
|
||||||
// connectListener();
|
|
||||||
// 获取网络连接状态
|
|
||||||
// getConnectType();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void onClose() {
|
void onClose() {
|
||||||
// TODO: implement onClose
|
|
||||||
super.onClose();
|
super.onClose();
|
||||||
|
|
||||||
// refreshController.dispose();
|
|
||||||
// _teamEvent.cancel();
|
|
||||||
// state.timer.cancel();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -54,9 +54,6 @@ class _StarLockMainPageState extends State<StarLockMainPage> with BaseWidget {
|
|||||||
WidgetsBinding.instance.addPostFrameCallback((_) async {
|
WidgetsBinding.instance.addPostFrameCallback((_) async {
|
||||||
setState(() {});
|
setState(() {});
|
||||||
});
|
});
|
||||||
// if (mounted) {
|
|
||||||
// setSŒe(() {});
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|||||||
@ -5,7 +5,10 @@ import 'package:flutter_screenutil/flutter_screenutil.dart';
|
|||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:star_lock/main/lockMian/lockMain/lockMain_page.dart';
|
import 'package:star_lock/main/lockMian/lockMain/lockMain_page.dart';
|
||||||
import 'package:star_lock/main/lockMian/lockMain/xhj/lockMain_xhj_state.dart';
|
import 'package:star_lock/main/lockMian/lockMain/xhj/lockMain_xhj_state.dart';
|
||||||
|
import 'package:star_lock/mine/minePersonInfo/minePersonInfoPage/minePersonInfo_entity.dart';
|
||||||
|
import 'package:star_lock/network/api_repository.dart';
|
||||||
import 'package:star_lock/tools/baseGetXController.dart';
|
import 'package:star_lock/tools/baseGetXController.dart';
|
||||||
|
import 'package:star_lock/tools/storage.dart';
|
||||||
|
|
||||||
class LockMainXHJLogic extends BaseGetXController {
|
class LockMainXHJLogic extends BaseGetXController {
|
||||||
final LockMainXHJState state = LockMainXHJState();
|
final LockMainXHJState state = LockMainXHJState();
|
||||||
@ -17,6 +20,14 @@ class LockMainXHJLogic extends BaseGetXController {
|
|||||||
|
|
||||||
bool get isMall => state.index ==1;
|
bool get isMall => state.index ==1;
|
||||||
|
|
||||||
|
//用户信息
|
||||||
|
Future<void> getUserInfoRequest() async {
|
||||||
|
final MinePersonInfoEntity entity = await ApiRepository.to.getUserInfo();
|
||||||
|
if (entity.errorCode!.codeIsSuccessful) {
|
||||||
|
Storage.setBool(saveIsVip, entity.data!.isVip==1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//打开设备弹窗
|
//打开设备弹窗
|
||||||
void openEquipment() {
|
void openEquipment() {
|
||||||
showModalBottomSheet(
|
showModalBottomSheet(
|
||||||
@ -48,6 +59,7 @@ class LockMainXHJLogic extends BaseGetXController {
|
|||||||
@override
|
@override
|
||||||
void onInit() {
|
void onInit() {
|
||||||
super.onInit();
|
super.onInit();
|
||||||
|
getUserInfoRequest();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|||||||
@ -39,7 +39,7 @@ class StarLockMineLogic extends BaseGetXController {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
getMineInfoData() async {
|
Future<void> getMineInfoData() async {
|
||||||
final String? data = await Storage.getString(saveUserLoginData);
|
final String? data = await Storage.getString(saveUserLoginData);
|
||||||
if (data != null && data.isNotEmpty) {
|
if (data != null && data.isNotEmpty) {
|
||||||
state.userNickName.value = (await Storage.getNickname())!;
|
state.userNickName.value = (await Storage.getNickname())!;
|
||||||
@ -59,7 +59,6 @@ class StarLockMineLogic extends BaseGetXController {
|
|||||||
@override
|
@override
|
||||||
Future<void> onInit() async {
|
Future<void> onInit() async {
|
||||||
super.onInit();
|
super.onInit();
|
||||||
|
|
||||||
getMineInfoData();
|
getMineInfoData();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -28,7 +28,7 @@ class StarLockMinePageState extends State<StarLockMinePage> with BaseWidget {
|
|||||||
final StarLockMineState state = Get.find<StarLockMineLogic>().state;
|
final StarLockMineState state = Get.find<StarLockMineLogic>().state;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
logic.getUserInfoRequest();
|
logic.getUserInfoRequest();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -12,10 +12,11 @@ import 'lockUserManageList_state.dart';
|
|||||||
|
|
||||||
class LockUserManageListLogic extends BaseGetXController {
|
class LockUserManageListLogic extends BaseGetXController {
|
||||||
final LockUserManageListState state = LockUserManageListState();
|
final LockUserManageListState state = LockUserManageListState();
|
||||||
|
StreamSubscription? _getElectronicKeyListRefreshUIEvent;
|
||||||
|
|
||||||
//请求锁用户列表
|
//请求锁用户列表
|
||||||
Future<LockUserListEntity> lockUserListRequest() async {
|
Future<LockUserListEntity> lockUserListRequest() async {
|
||||||
LockUserListEntity entity =
|
final LockUserListEntity entity =
|
||||||
await ApiRepository.to.lockUserList(pageNo.toString(), pageSize, state.searchController.text);
|
await ApiRepository.to.lockUserList(pageNo.toString(), pageSize, state.searchController.text);
|
||||||
if(entity.errorCode!.codeIsSuccessful){
|
if(entity.errorCode!.codeIsSuccessful){
|
||||||
if (pageNo == 1) {
|
if (pageNo == 1) {
|
||||||
@ -23,7 +24,7 @@ class LockUserManageListLogic extends BaseGetXController {
|
|||||||
pageNo++;
|
pageNo++;
|
||||||
} else {
|
} else {
|
||||||
if (entity.data!.isNotEmpty) {
|
if (entity.data!.isNotEmpty) {
|
||||||
state.dataList.value.addAll(entity.data!);
|
state.dataList.addAll(entity.data!);
|
||||||
pageNo++;
|
pageNo++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -33,7 +34,7 @@ class LockUserManageListLogic extends BaseGetXController {
|
|||||||
|
|
||||||
//删除锁用户管理
|
//删除锁用户管理
|
||||||
Future<void> deletelockUserRequest(int uid) async {
|
Future<void> deletelockUserRequest(int uid) async {
|
||||||
var entity = await ApiRepository.to.deletLockUser(uid);
|
final entity = await ApiRepository.to.deletLockUser(uid);
|
||||||
if (entity.errorCode!.codeIsSuccessful) {
|
if (entity.errorCode!.codeIsSuccessful) {
|
||||||
EasyLoading.showToast('删除成功',duration: 2000.milliseconds);
|
EasyLoading.showToast('删除成功',duration: 2000.milliseconds);
|
||||||
showToast('删除成功', something: (){
|
showToast('删除成功', something: (){
|
||||||
@ -44,7 +45,6 @@ class LockUserManageListLogic extends BaseGetXController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// 刷新电子钥匙列表
|
/// 刷新电子钥匙列表
|
||||||
StreamSubscription? _getElectronicKeyListRefreshUIEvent;
|
|
||||||
void _getElectronicKeyListRefreshUIAction() {
|
void _getElectronicKeyListRefreshUIAction() {
|
||||||
// 蓝牙协议通知传输跟蓝牙之外的数据传输类不一样 eventBus
|
// 蓝牙协议通知传输跟蓝牙之外的数据传输类不一样 eventBus
|
||||||
_getElectronicKeyListRefreshUIEvent = eventBus.on<LockUserManageListRefreshUI>().listen((event) {
|
_getElectronicKeyListRefreshUIEvent = eventBus.on<LockUserManageListRefreshUI>().listen((event) {
|
||||||
@ -55,23 +55,18 @@ class LockUserManageListLogic extends BaseGetXController {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
void onReady() {
|
void onReady() {
|
||||||
// TODO: implement onReady
|
|
||||||
super.onReady();
|
super.onReady();
|
||||||
|
|
||||||
_getElectronicKeyListRefreshUIAction();
|
_getElectronicKeyListRefreshUIAction();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void onInit() {
|
void onInit() {
|
||||||
// TODO: implement onInit
|
|
||||||
super.onInit();
|
super.onInit();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void onClose() {
|
void onClose() {
|
||||||
// TODO: implement onClose
|
|
||||||
super.onClose();
|
super.onClose();
|
||||||
|
|
||||||
_getElectronicKeyListRefreshUIEvent?.cancel();
|
_getElectronicKeyListRefreshUIEvent?.cancel();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -38,7 +38,6 @@ class _LockUserManageListPageState extends State<LockUserManageListPage> {
|
|||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
|
|
||||||
getHttpData();
|
getHttpData();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -15,7 +15,7 @@ class NewSMSTemplateLogic extends BaseGetXController {
|
|||||||
//获取默认模板-- 1:电子钥匙 2:密码
|
//获取默认模板-- 1:电子钥匙 2:密码
|
||||||
Future<void> getDefaultTemplate() async {
|
Future<void> getDefaultTemplate() async {
|
||||||
final NewSMSTemplateEntity entity = await ApiRepository.to
|
final NewSMSTemplateEntity entity = await ApiRepository.to
|
||||||
.getDefaultTemplate(type: state.currentTemplate.value.type ?? 0);
|
.getDefaultTemplate(type: state.templateType.value);
|
||||||
if (entity.errorCode!.codeIsSuccessful) {
|
if (entity.errorCode!.codeIsSuccessful) {
|
||||||
state.templateList.value = entity.dataList ?? <SMSTemplateData>[];
|
state.templateList.value = entity.dataList ?? <SMSTemplateData>[];
|
||||||
if (state.templateList.isNotEmpty) {
|
if (state.templateList.isNotEmpty) {
|
||||||
@ -59,9 +59,32 @@ class NewSMSTemplateLogic extends BaseGetXController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
List<TextSpan> buildElectronicKeySpan({required bool isPreview}) {
|
// 更新短信条数的函数
|
||||||
final List<TextSpan> textSpans = <TextSpan>[];
|
void updateSmsCost(String template) {
|
||||||
|
state.smsCost.value = calculateSmsCost(template);
|
||||||
|
}
|
||||||
|
|
||||||
|
int calculateSmsCost(String template) {
|
||||||
|
final int smsCount = template.length;
|
||||||
|
if (smsCount <= 70) {
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
return (smsCount / 67).ceil();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//构建电子钥匙模板
|
||||||
|
List<TextSpan> buildElectronicKeySpan({required bool isPreview}) {
|
||||||
|
//短信模版
|
||||||
|
if (state.templateType.value == 1) {
|
||||||
|
return _buildSMSElectronicKey(isPreview);
|
||||||
|
} else {
|
||||||
|
return _buildEmailElectronicKey(isPreview);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
List<TextSpan> _buildSMSElectronicKey(bool isPreview) {
|
||||||
|
final List<TextSpan> textSpans = <TextSpan>[];
|
||||||
// 如果是预览模式,添加预览模板的文本
|
// 如果是预览模式,添加预览模板的文本
|
||||||
if (isPreview) {
|
if (isPreview) {
|
||||||
textSpans.add(
|
textSpans.add(
|
||||||
@ -74,7 +97,7 @@ class NewSMSTemplateLogic extends BaseGetXController {
|
|||||||
// 将模板分割为文本片段
|
// 将模板分割为文本片段
|
||||||
final List<String> textFragments = state.currentTemplate.value.template
|
final List<String> textFragments = state.currentTemplate.value.template
|
||||||
?.split(RegularExpression.urlRegExp) ??
|
?.split(RegularExpression.urlRegExp) ??
|
||||||
[];
|
<String>[];
|
||||||
|
|
||||||
// 添加链接文本和普通文本到文本片段列表
|
// 添加链接文本和普通文本到文本片段列表
|
||||||
for (int i = 0; i < textFragments.length; i++) {
|
for (int i = 0; i < textFragments.length; i++) {
|
||||||
@ -115,7 +138,62 @@ class NewSMSTemplateLogic extends BaseGetXController {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
return textSpans;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<TextSpan> _buildEmailElectronicKey(bool isPreview) {
|
||||||
|
final List<TextSpan> textSpans = <TextSpan>[];
|
||||||
|
|
||||||
|
//邮件模版
|
||||||
|
// 如果是预览模式,添加预览模板的文本
|
||||||
|
if (isPreview) {
|
||||||
|
textSpans.add(
|
||||||
|
TextSpan(
|
||||||
|
text: '${state.templateOneTf.text}\n',
|
||||||
|
style: state.defaultStyle,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
String template = state.currentTemplate.value.template ?? '';
|
||||||
|
template = template.replaceAll(',', ',\n');
|
||||||
|
|
||||||
|
// 定义匹配 ${} 包围的变量的正则表达式
|
||||||
|
final RegExp variableRegExp = RegExp(r'\{([^}]+)\}');
|
||||||
|
final Iterable<Match> matches = variableRegExp.allMatches(template);
|
||||||
|
|
||||||
|
int start = 0;
|
||||||
|
for (final Match match in matches) {
|
||||||
|
// 添加非变量文本
|
||||||
|
if (match.start > start) {
|
||||||
|
textSpans.add(
|
||||||
|
TextSpan(
|
||||||
|
text: template.substring(start, match.start),
|
||||||
|
style: state.defaultStyle,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加变量文本
|
||||||
|
textSpans.add(
|
||||||
|
TextSpan(
|
||||||
|
text: match.group(0),
|
||||||
|
style: state.highStyle,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
start = match.end;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加剩余的非变量文本
|
||||||
|
if (start < template.length) {
|
||||||
|
textSpans.add(
|
||||||
|
TextSpan(
|
||||||
|
text: template.substring(start),
|
||||||
|
style: state.defaultStyle,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
return textSpans;
|
return textSpans;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -132,64 +210,68 @@ class NewSMSTemplateLogic extends BaseGetXController {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 定义匹配 ${} 包围的变量的正则表达式
|
//短信模版才需要加默认模版
|
||||||
final RegExp variableRegExp = RegExp(r'\$\{([^}]+)\}');
|
if (state.templateType == 1 ||
|
||||||
|
(state.templateType == 2 && isPreview == false)) {
|
||||||
|
// 定义匹配 ${} 包围的变量的正则表达式
|
||||||
|
final RegExp variableRegExp = RegExp(r'\$\{([^}]+)\}');
|
||||||
|
|
||||||
final String template = state.currentTemplate.value.template ?? '';
|
final String template = state.currentTemplate.value.template ?? '';
|
||||||
|
|
||||||
// 对模板进行处理
|
// 对模板进行处理
|
||||||
int startIndex = 0;
|
int startIndex = 0;
|
||||||
for (final Match match in variableRegExp.allMatches(template)) {
|
for (final Match match in variableRegExp.allMatches(template)) {
|
||||||
// 处理变量之前的文本
|
// 处理变量之前的文本
|
||||||
final String nonVariableText =
|
final String nonVariableText =
|
||||||
template.substring(startIndex, match.start);
|
template.substring(startIndex, match.start);
|
||||||
|
// 替换非变量文本中的字符
|
||||||
|
final String replacedNonVariableText =
|
||||||
|
nonVariableText.replaceAllMapped(RegExp(r',|。'), (Match match) {
|
||||||
|
return '${match.group(0)}\n';
|
||||||
|
});
|
||||||
|
textSpans.add(
|
||||||
|
TextSpan(
|
||||||
|
text: replacedNonVariableText,
|
||||||
|
style: state.defaultStyle,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
// 处理变量
|
||||||
|
final String variableText = match.group(0) ?? '';
|
||||||
|
textSpans.add(
|
||||||
|
TextSpan(
|
||||||
|
text: variableText,
|
||||||
|
style: state.highStyle,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
// 更新起始索引
|
||||||
|
startIndex = match.end;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加最后一个变量之后的文本
|
||||||
|
final String remainingText = template.substring(startIndex);
|
||||||
// 替换非变量文本中的字符
|
// 替换非变量文本中的字符
|
||||||
final String replacedNonVariableText =
|
final String replacedRemainingText =
|
||||||
nonVariableText.replaceAllMapped(RegExp(r',|。'), (Match match) {
|
remainingText.replaceAllMapped(RegExp(r',|。'), (Match match) {
|
||||||
return '${match.group(0)}\n';
|
return '${match.group(0)}\n';
|
||||||
});
|
});
|
||||||
textSpans.add(
|
textSpans.add(
|
||||||
TextSpan(
|
TextSpan(
|
||||||
text: replacedNonVariableText,
|
text: replacedRemainingText,
|
||||||
style: state.defaultStyle,
|
style: state.defaultStyle,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
// 处理变量
|
// 在预览模式下,添加预览模板的文本
|
||||||
final String variableText = match.group(0) ?? '';
|
if (isPreview) {
|
||||||
textSpans.add(
|
textSpans.add(
|
||||||
TextSpan(
|
TextSpan(
|
||||||
text: variableText,
|
text: '\n${state.templateTwoTf.text}',
|
||||||
style: state.highStyle,
|
style: state.defaultStyle,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
}
|
||||||
// 更新起始索引
|
|
||||||
startIndex = match.end;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 添加最后一个变量之后的文本
|
|
||||||
final String remainingText = template.substring(startIndex);
|
|
||||||
// 替换非变量文本中的字符
|
|
||||||
final String replacedRemainingText =
|
|
||||||
remainingText.replaceAllMapped(RegExp(r',|。'), (Match match) {
|
|
||||||
return '${match.group(0)}\n';
|
|
||||||
});
|
|
||||||
textSpans.add(
|
|
||||||
TextSpan(
|
|
||||||
text: replacedRemainingText,
|
|
||||||
style: state.defaultStyle,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
// 在预览模式下,添加预览模板的文本
|
|
||||||
if (isPreview) {
|
|
||||||
textSpans.add(
|
|
||||||
TextSpan(
|
|
||||||
text: '\n${state.templateTwoTf.text}',
|
|
||||||
style: state.defaultStyle,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return textSpans;
|
return textSpans;
|
||||||
|
|||||||
@ -28,7 +28,7 @@ class _NewSMSTemplatePageState extends State<NewSMSTemplatePage> {
|
|||||||
return Scaffold(
|
return Scaffold(
|
||||||
backgroundColor: AppColors.mainBackgroundColor,
|
backgroundColor: AppColors.mainBackgroundColor,
|
||||||
appBar: TitleAppBar(
|
appBar: TitleAppBar(
|
||||||
barTitle: state.templateType.value == 1 ? '新建短信模版'.tr : '新建邮件模版'.tr,
|
barTitle: state.templateType == 1 ? '新建短信模版'.tr : '新建邮件模版'.tr,
|
||||||
haveBack: true,
|
haveBack: true,
|
||||||
backgroundColor: AppColors.mainColor,
|
backgroundColor: AppColors.mainColor,
|
||||||
),
|
),
|
||||||
@ -109,18 +109,24 @@ class _NewSMSTemplatePageState extends State<NewSMSTemplatePage> {
|
|||||||
height: 100,
|
height: 100,
|
||||||
child: _buildTextField(state.templateOneTf),
|
child: _buildTextField(state.templateOneTf),
|
||||||
),
|
),
|
||||||
Obx(() => _buildTemplateWithType(isPreview: false)),
|
Obx(() => Container(
|
||||||
|
width: 1.sw - 50.w,
|
||||||
|
margin: EdgeInsets.only(left: 25.w, right: 25.w),
|
||||||
|
child: _buildTemplateWithType(isPreview: false),
|
||||||
|
)),
|
||||||
SizedBox(height: 10.h),
|
SizedBox(height: 10.h),
|
||||||
Container(
|
Obx(() => Visibility(
|
||||||
margin: EdgeInsets.symmetric(horizontal: 25.w, vertical: 25.h),
|
visible: state.templateType.value == 1,
|
||||||
height: 100,
|
child: Container(
|
||||||
child: Stack(
|
margin: EdgeInsets.symmetric(horizontal: 25.w, vertical: 25.h),
|
||||||
alignment: Alignment.bottomRight,
|
height: 100,
|
||||||
children: <Widget>[
|
child: Stack(
|
||||||
_buildTextField(state.templateTwoTf),
|
alignment: Alignment.bottomRight,
|
||||||
],
|
children: <Widget>[
|
||||||
),
|
_buildTextField(state.templateTwoTf),
|
||||||
),
|
],
|
||||||
|
),
|
||||||
|
))),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@ -144,7 +150,9 @@ class _NewSMSTemplatePageState extends State<NewSMSTemplatePage> {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
Obx(() => Container(
|
Obx(() => Container(
|
||||||
|
width: 1.sw - 50.w,
|
||||||
margin: EdgeInsets.only(left: 25.w, right: 25.w),
|
margin: EdgeInsets.only(left: 25.w, right: 25.w),
|
||||||
|
padding: EdgeInsets.only(left: 20.w, right: 20.w, top: 10.h),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: const Color(0xFFF5F5F5),
|
color: const Color(0xFFF5F5F5),
|
||||||
borderRadius: BorderRadius.circular(10.h),
|
borderRadius: BorderRadius.circular(10.h),
|
||||||
@ -158,7 +166,7 @@ class _NewSMSTemplatePageState extends State<NewSMSTemplatePage> {
|
|||||||
bottom: 25.h,
|
bottom: 25.h,
|
||||||
),
|
),
|
||||||
child: Text(
|
child: Text(
|
||||||
'预计产生短信条数:2',
|
'预计产生短信条数:${state.smsCost.value}',
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: Colors.grey,
|
color: Colors.grey,
|
||||||
fontSize: 20.sp,
|
fontSize: 20.sp,
|
||||||
@ -176,19 +184,12 @@ class _NewSMSTemplatePageState extends State<NewSMSTemplatePage> {
|
|||||||
state.currentTemplate.value.template!.isEmpty) {
|
state.currentTemplate.value.template!.isEmpty) {
|
||||||
return const SizedBox.shrink(); // 如果为空,返回一个空的 SizedBox
|
return const SizedBox.shrink(); // 如果为空,返回一个空的 SizedBox
|
||||||
} else {
|
} else {
|
||||||
return Row(
|
return RichText(
|
||||||
children: <Widget>[
|
text: TextSpan(
|
||||||
Padding(
|
children: state.currentTemplate.value.typeName == '电子钥匙'
|
||||||
padding: EdgeInsets.symmetric(horizontal: 25.w, vertical: 10.h),
|
? logic.buildElectronicKeySpan(isPreview: isPreview)
|
||||||
child: Obx(() => RichText(
|
: logic.buildPasswordSpan(isPreview: isPreview),
|
||||||
text: TextSpan(
|
),
|
||||||
children: state.currentTemplate.value.typeName == '电子钥匙'
|
|
||||||
? logic.buildElectronicKeySpan(isPreview: isPreview)
|
|
||||||
: logic.buildPasswordSpan(isPreview: isPreview),
|
|
||||||
),
|
|
||||||
)),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -213,6 +214,7 @@ class _NewSMSTemplatePageState extends State<NewSMSTemplatePage> {
|
|||||||
onChanged: (String value) {
|
onChanged: (String value) {
|
||||||
setState(() {
|
setState(() {
|
||||||
controller.text = value;
|
controller.text = value;
|
||||||
|
logic.updateSmsCost(value); // 更新短信条数
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|||||||
@ -30,7 +30,8 @@ class NewSMSTemplateState {
|
|||||||
|
|
||||||
RxBool isVip = false.obs;
|
RxBool isVip = false.obs;
|
||||||
RxList<SMSTemplateData> templateList = <SMSTemplateData>[].obs;
|
RxList<SMSTemplateData> templateList = <SMSTemplateData>[].obs;
|
||||||
Rx<SMSTemplateData> currentTemplate = SMSTemplateData().obs;
|
Rx<SMSTemplateData> currentTemplate = SMSTemplateData().obs; //当前模板信息
|
||||||
RxBool isShowDate = false.obs;
|
RxBool isShowDate = false.obs; //是否显示日期
|
||||||
RxInt templateType = 0.obs;
|
RxInt templateType = 0.obs; //1:短信 2:邮件
|
||||||
|
RxInt smsCost = 0.obs; //短信条数
|
||||||
}
|
}
|
||||||
|
|||||||
@ -12,9 +12,8 @@ import '../../../../tools/baseGetXController.dart';
|
|||||||
class CustomSMSTemplateListLogic extends BaseGetXController {
|
class CustomSMSTemplateListLogic extends BaseGetXController {
|
||||||
CustomSMSTemplateListState state = CustomSMSTemplateListState();
|
CustomSMSTemplateListState state = CustomSMSTemplateListState();
|
||||||
|
|
||||||
//获取短信模板列表
|
// 获取短信模板列表
|
||||||
Future<void> getSMSTemplateListRequest({required bool isRefresh}) async {
|
Future<void> getSMSTemplateListRequest({required bool isRefresh}) async {
|
||||||
// 如果是下拉刷新,清空已有数据
|
|
||||||
if (isRefresh) {
|
if (isRefresh) {
|
||||||
state.smsTemplateList.clear();
|
state.smsTemplateList.clear();
|
||||||
pageNo = 1;
|
pageNo = 1;
|
||||||
@ -31,7 +30,7 @@ class CustomSMSTemplateListLogic extends BaseGetXController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//删除短信模版
|
// 删除短信模板
|
||||||
Future<void> deleteSMSTemplateRequest({required int id}) async {
|
Future<void> deleteSMSTemplateRequest({required int id}) async {
|
||||||
final LoginEntity entity =
|
final LoginEntity entity =
|
||||||
await ApiRepository.to.deleteTemplateInfo(id: id);
|
await ApiRepository.to.deleteTemplateInfo(id: id);
|
||||||
@ -42,131 +41,75 @@ class CustomSMSTemplateListLogic extends BaseGetXController {
|
|||||||
|
|
||||||
List<TextSpan> buildElectronicKeySpan(
|
List<TextSpan> buildElectronicKeySpan(
|
||||||
{required CustomSMSTemplateItem templateData}) {
|
{required CustomSMSTemplateItem templateData}) {
|
||||||
final List<TextSpan> textSpans = <TextSpan>[];
|
final List<TextSpan> textSpans = [];
|
||||||
|
_addTextSpan(textSpans, '${templateData.regards}\n', state.defaultStyle);
|
||||||
textSpans.add(
|
_buildTextSpansFromTemplate(
|
||||||
TextSpan(
|
textSpans, templateData.template, state.defaultStyle, state.highStyle);
|
||||||
text: '${templateData.regards}\n',
|
_addTextSpan(textSpans, '\n${templateData.tips}', state.defaultStyle);
|
||||||
style: state.defaultStyle,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
// 将模板分割为文本片段
|
|
||||||
final List<String> textFragments =
|
|
||||||
templateData.template?.split(RegularExpression.urlRegExp) ?? [];
|
|
||||||
|
|
||||||
// 添加链接文本和普通文本到文本片段列表
|
|
||||||
for (int i = 0; i < textFragments.length; i++) {
|
|
||||||
final String textFragment = textFragments[i];
|
|
||||||
// 添加普通文本
|
|
||||||
textSpans.add(
|
|
||||||
TextSpan(
|
|
||||||
text: textFragment,
|
|
||||||
style: state.defaultStyle,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
// 如果不是最后一个文本片段,则添加换行符
|
|
||||||
if (i < textFragments.length - 1) {
|
|
||||||
textSpans.add(
|
|
||||||
TextSpan(
|
|
||||||
text: '\n',
|
|
||||||
style: state.defaultStyle,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
// 添加链接文本
|
|
||||||
textSpans.add(
|
|
||||||
TextSpan(
|
|
||||||
text: RegularExpression.urlRegExp
|
|
||||||
.stringMatch(templateData.template!) ??
|
|
||||||
'',
|
|
||||||
style: state.highStyle,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
textSpans.add(
|
|
||||||
TextSpan(
|
|
||||||
text: '\n${templateData.tips}',
|
|
||||||
style: state.defaultStyle,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
return textSpans;
|
return textSpans;
|
||||||
}
|
}
|
||||||
|
|
||||||
List<TextSpan> buildPasswordSpan(
|
List<TextSpan> buildPasswordSpan(
|
||||||
{required CustomSMSTemplateItem templateData}) {
|
{required CustomSMSTemplateItem templateData}) {
|
||||||
final List<TextSpan> textSpans = <TextSpan>[];
|
final List<TextSpan> textSpans = [];
|
||||||
|
_addTextSpan(textSpans, '${templateData.regards}\n', state.defaultStyle);
|
||||||
textSpans.add(
|
_buildPasswordTextSpans(
|
||||||
TextSpan(
|
textSpans, templateData.template, state.defaultStyle, state.highStyle);
|
||||||
text: '${templateData.regards}\n',
|
_addTextSpan(textSpans, '\n${templateData.tips}', state.defaultStyle);
|
||||||
style: state.defaultStyle,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
// 定义匹配 ${} 包围的变量的正则表达式
|
|
||||||
final RegExp variableRegExp = RegExp(r'\$\{([^}]+)\}');
|
|
||||||
|
|
||||||
final String template = templateData.template ?? '';
|
|
||||||
|
|
||||||
// 对模板进行处理
|
|
||||||
int startIndex = 0;
|
|
||||||
for (final Match match in variableRegExp.allMatches(template)) {
|
|
||||||
// 处理变量之前的文本
|
|
||||||
final String nonVariableText =
|
|
||||||
template.substring(startIndex, match.start);
|
|
||||||
// 替换非变量文本中的字符
|
|
||||||
final String replacedNonVariableText =
|
|
||||||
nonVariableText.replaceAllMapped(RegExp(r',|。'), (Match match) {
|
|
||||||
return '${match.group(0)}\n';
|
|
||||||
});
|
|
||||||
textSpans.add(
|
|
||||||
TextSpan(
|
|
||||||
text: replacedNonVariableText,
|
|
||||||
style: state.defaultStyle,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
// 处理变量
|
|
||||||
final String variableText = match.group(0) ?? '';
|
|
||||||
textSpans.add(
|
|
||||||
TextSpan(
|
|
||||||
text: variableText,
|
|
||||||
style: state.highStyle,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
// 更新起始索引
|
|
||||||
startIndex = match.end;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 添加最后一个变量之后的文本
|
|
||||||
final String remainingText = template.substring(startIndex);
|
|
||||||
// 替换非变量文本中的字符
|
|
||||||
final String replacedRemainingText =
|
|
||||||
remainingText.replaceAllMapped(RegExp(r',|。'), (Match match) {
|
|
||||||
return '${match.group(0)}\n';
|
|
||||||
});
|
|
||||||
textSpans.add(
|
|
||||||
TextSpan(
|
|
||||||
text: replacedRemainingText,
|
|
||||||
style: state.defaultStyle,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
textSpans.add(
|
|
||||||
TextSpan(
|
|
||||||
text: '\n${templateData.tips}',
|
|
||||||
style: state.defaultStyle,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
return textSpans;
|
return textSpans;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _buildTextSpansFromTemplate(List<TextSpan> textSpans, String? template,
|
||||||
|
TextStyle defaultStyle, TextStyle highStyle) {
|
||||||
|
final List<String> textFragments =
|
||||||
|
template?.split(RegularExpression.urlRegExp) ?? [];
|
||||||
|
for (int i = 0; i < textFragments.length; i++) {
|
||||||
|
_addTextSpan(textSpans, textFragments[i], defaultStyle);
|
||||||
|
if (i < textFragments.length - 1) {
|
||||||
|
_addTextSpan(textSpans, '\n', defaultStyle);
|
||||||
|
_addTextSpan(
|
||||||
|
textSpans,
|
||||||
|
RegularExpression.urlRegExp.stringMatch(template!) ?? '',
|
||||||
|
highStyle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _buildPasswordTextSpans(List<TextSpan> textSpans, String? template,
|
||||||
|
TextStyle defaultStyle, TextStyle highStyle) {
|
||||||
|
final RegExp variableRegExp = RegExp(r'\$\{([^}]+)\}');
|
||||||
|
final String text = template ?? '';
|
||||||
|
int startIndex = 0;
|
||||||
|
|
||||||
|
for (final Match match in variableRegExp.allMatches(text)) {
|
||||||
|
_addTextSpan(
|
||||||
|
textSpans,
|
||||||
|
text
|
||||||
|
.substring(startIndex, match.start)
|
||||||
|
.replaceAllMapped(RegExp(r',|。'), (Match match) {
|
||||||
|
return '${match.group(0)}\n';
|
||||||
|
}),
|
||||||
|
defaultStyle);
|
||||||
|
_addTextSpan(textSpans, match.group(0) ?? '', highStyle);
|
||||||
|
startIndex = match.end;
|
||||||
|
}
|
||||||
|
|
||||||
|
_addTextSpan(
|
||||||
|
textSpans,
|
||||||
|
text.substring(startIndex).replaceAllMapped(RegExp(r',|。'),
|
||||||
|
(Match match) {
|
||||||
|
return '${match.group(0)}\n';
|
||||||
|
}),
|
||||||
|
defaultStyle);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _addTextSpan(List<TextSpan> textSpans, String text, TextStyle style) {
|
||||||
|
textSpans.add(TextSpan(text: text, style: style));
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
onReady() async {
|
Future<void> onReady() async {
|
||||||
|
super.onReady();
|
||||||
var isVip = await Storage.getBool(saveIsVip);
|
var isVip = await Storage.getBool(saveIsVip);
|
||||||
state.isVip.value = isVip ?? false;
|
state.isVip.value = isVip ?? false;
|
||||||
}
|
}
|
||||||
|
|||||||
18
lib/tools/regexp_tool.dart
Normal file
18
lib/tools/regexp_tool.dart
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
///
|
||||||
|
/// 正则判断工具
|
||||||
|
///
|
||||||
|
class RegexpTool {
|
||||||
|
//判断手机号
|
||||||
|
static bool isPhoneNumber(String input) {
|
||||||
|
// 手机号正则表达式
|
||||||
|
final RegExp phoneNumberRegExp = RegExp(r'^1[0-9]{10}$');
|
||||||
|
return phoneNumberRegExp.hasMatch(input);
|
||||||
|
}
|
||||||
|
|
||||||
|
//判断邮箱
|
||||||
|
static bool isEmail(String input) {
|
||||||
|
// 邮箱正则表达式
|
||||||
|
final RegExp emailRegExp = RegExp(r'^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$');
|
||||||
|
return emailRegExp.hasMatch(input);
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user