1,新增邮件类型选择公用组件

2,新增获取电子钥匙通知模版API对接
3,完善电子钥匙发送成功后邮件通知相关页面及逻辑
4,根据后台返回电子钥匙类型显示短信、邮件通知
This commit is contained in:
Daisy 2024-06-11 17:55:00 +08:00
parent 99b7a443ed
commit e6592bf06b
13 changed files with 482 additions and 33 deletions

View File

@ -29,15 +29,17 @@ class AuthorizedAdminSendEntity {
class Data {
int? receiverUid;
ReceiverUser? receiverUser;
int? usernameType;
int? keyId;
Data({this.receiverUid, this.receiverUser, this.keyId});
Data({this.receiverUid, this.receiverUser, this.usernameType, this.keyId});
Data.fromJson(Map<String, dynamic> json) {
receiverUid = json['receiverUid'];
receiverUser = json['receiverUser'] != null
? ReceiverUser.fromJson(json['receiverUser'])
: null;
usernameType = json['usernameType'];
keyId = json['keyId'];
}
@ -47,6 +49,7 @@ class Data {
if (receiverUser != null) {
data['receiverUser'] = receiverUser!.toJson();
}
data['usernameType'] = usernameType;
data['keyId'] = keyId;
return data;
}

View File

@ -185,6 +185,7 @@ class SendElectronicKeyViewLogic extends BaseGetXController {
state.createUser.value = 0;
state.isSendSuccess = true;
keyId = entity.data!.keyId;
state.userNameType.value = entity.data?.usernameType ?? 0;
resetData();
update();
eventBus.fire(ElectronicKeyListRefreshUI());

View File

@ -424,10 +424,11 @@ class _SendElectronicKeyViewState extends State<SendElectronicKeyView>
// ),
if (logic.emailOrPhone != null)
OutLineBtn(
btnName: logic.emailOrPhone!.contains('@') ? '邮件通知' : '短信通知',
btnName: logic.state.userNameType.value == 1 ? '短信通知' : '邮件通知',
onClick: () {
if (logic.emailOrPhone!.contains('@')) {
Get.toNamed(Routers.sendEmailNotificationPage);
if (logic.state.userNameType.value == 2) {
Get.toNamed(Routers.sendEmailNotificationPage,
arguments: <String, String?>{'email': logic.emailOrPhone});
} else {
logic.sendMsg(isPhone: true);
}

View File

@ -32,6 +32,7 @@ class SendElectronicKeyViewState {
RxInt createUser = 0.obs; //1 0
bool isDemoMode = false;
RxBool isRequireAuth = false.obs; //
RxInt userNameType = 0.obs; //1: 2:
final String timeLimitTips = '接收者在有效期内可以不限次数使用'; //
final String permanentTips = '接收者可以使用此App开关锁'; //

View File

@ -0,0 +1,79 @@
class SendEmailNotificationEntity {
SendEmailNotificationEntity(
{this.errorCode, this.description, this.errorMsg, this.data});
SendEmailNotificationEntity.fromJson(Map<String, dynamic> json) {
errorCode = json['errorCode'];
description = json['description'];
errorMsg = json['errorMsg'];
data = json['data'] != null
? EmailNotificationData.fromJson(json['data'])
: null;
}
int? errorCode;
String? description;
String? errorMsg;
EmailNotificationData? data;
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['errorCode'] = errorCode;
data['description'] = description;
data['errorMsg'] = errorMsg;
if (this.data != null) {
data['data'] = this.data!.toJson();
}
return data;
}
}
class EmailNotificationData {
EmailNotificationData({this.list});
EmailNotificationData.fromJson(Map<String, dynamic> json) {
if (json['list'] != null) {
list = <EmailNotificationItem>[];
json['list'].forEach((v) {
list!.add(EmailNotificationItem.fromJson(v));
});
}
}
List<EmailNotificationItem>? list;
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
if (list != null) {
data['list'] =
list!.map((EmailNotificationItem v) => v.toJson()).toList();
}
return data;
}
}
class EmailNotificationItem {
EmailNotificationItem(
{this.type, this.name, this.template, this.isUse, this.fee});
EmailNotificationItem.fromJson(Map<String, dynamic> json) {
type = json['type'];
name = json['name'];
template = json['template'];
isUse = json['isUse'];
fee = json['fee'];
}
String? type;
String? name;
String? template;
int? isUse;
int? fee;
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['type'] = type;
data['name'] = name;
data['template'] = template;
data['isUse'] = isUse;
data['fee'] = fee;
return data;
}
}

View File

@ -0,0 +1,25 @@
import 'package:get_storage/get_storage.dart';
import 'package:star_lock/main/lockDetail/electronicKey/sendEmailNotification/sendEmailNotification_entity.dart';
import 'package:star_lock/main/lockDetail/electronicKey/sendEmailNotification/sendEmailNotification_state.dart';
import 'package:star_lock/network/api_repository.dart';
import 'package:star_lock/tools/baseGetXController.dart';
import 'package:star_lock/tools/commonDataManage.dart';
class SendEmailNotificationLogic extends BaseGetXController {
final SendEmailNotificationState state = SendEmailNotificationState();
// 1 2
Future<void> getKeyNoticeTemplate() async {
final SendEmailNotificationEntity entity =
await ApiRepository.to.getKeyNoticeTemplate(
lockId: CommonDataManage().currentKeyInfo.lockId ?? 0,
keyId: CommonDataManage().currentKeyInfo.keyId ?? 0,
channelType: 2,
);
if (entity.errorCode!.codeIsSuccessful) {
state.emailTemplateList.value =
entity.data?.list ?? <EmailNotificationItem>[];
state.emailTemplateList.refresh();
}
}
}

View File

@ -1,6 +1,11 @@
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get_utils/get_utils.dart';
import 'package:get/get.dart';
import 'package:star_lock/main/lockDetail/electronicKey/sendEmailNotification/SendEmailNotification_logic.dart';
import 'package:star_lock/main/lockDetail/electronicKey/sendEmailNotification/sendEmailNotification_state.dart';
import 'package:star_lock/tools/emailNotifyTypeSelectAlert.dart';
import 'package:star_lock/tools/pickers/pickers.dart';
import 'package:star_lock/tools/pickers/style/default_style.dart';
import 'package:star_lock/translations/trans_lib.dart';
import '../../../../app_settings/app_colors.dart';
@ -12,42 +17,71 @@ class SendEmailNotificationPage extends StatefulWidget {
const SendEmailNotificationPage({Key? key}) : super(key: key);
@override
State<SendEmailNotificationPage> createState() => _SendEmailNotificationPageState();
State<SendEmailNotificationPage> createState() =>
_SendEmailNotificationPageState();
}
class _SendEmailNotificationPageState extends State<SendEmailNotificationPage> {
final TextEditingController _emailController = TextEditingController();
final SendEmailNotificationLogic logic =
Get.put(SendEmailNotificationLogic());
final SendEmailNotificationState state =
Get.find<SendEmailNotificationLogic>().state;
@override
void initState() {
super.initState();
logic.getKeyNoticeTemplate();
}
@override
Widget build(BuildContext context) {
_emailController.text = "亲爱的用户 \n\n你收到电子钥匙请试用APP(www.baidu.com)或小程序开锁 \n\n星锁";
return Scaffold(
backgroundColor: AppColors.mainBackgroundColor,
appBar: TitleAppBar(barTitle: "邮件通知", haveBack: true, backgroundColor: AppColors.mainColor),
appBar: TitleAppBar(
barTitle: '邮件通知',
haveBack: true,
backgroundColor: AppColors.mainColor),
body: SingleChildScrollView(
child: Column(
children: [
CommonItem(
leftTitel: TranslationLoader.lanKeys!.receiver!.tr,
rightTitle: "786612630@qq.com",
isHaveLine: true,
),
CommonItem(
leftTitel: "类型",
rightTitle: "个人邮件",
isHaveDirection: true,
),
children: <Widget>[
Obx(() => CommonItem(
leftTitel: TranslationLoader.lanKeys!.receiver!.tr,
rightTitle: state.getEmail.value,
isHaveLine: true,
)),
Obx(() => CommonItem(
leftTitel: '类型',
rightTitle:
state.emailNotifyType.value == 1 ? '系统邮件' : '个人邮件',
isHaveDirection: true,
action: () {
EmailNotifyTypeSelectAlert.showEmailNotifyTypeSelectAlert(
context, (int value) {
state.emailNotifyType.value = value;
});
},
)),
Container(height: 10.h),
CommonItem(leftTitel: "模板", rightTitle: "默认模板", isHaveDirection: true, isHaveLine: true),
Obx(() => CommonItem(
leftTitel: '模板',
rightTitle: state.selectEmailTemplate.value,
isHaveDirection: true,
isHaveLine: true,
action: () {
openBottomItemSheet(context);
},
)),
Container(
height: 360.h,
color: Colors.white,
padding: EdgeInsets.only(left: 20.w, right: 20.w, top: 20.h, bottom: 20.h),
padding: EdgeInsets.only(
left: 20.w, right: 20.w, top: 20.h, bottom: 20.h),
child: TextField(
maxLines: 8,
maxLength: 1000,
textAlign: TextAlign.start,
controller: _emailController,
controller: state.emailController,
style: TextStyle(
color: Colors.black,
fontSize: 22.sp,
@ -86,7 +120,7 @@ class _SendEmailNotificationPageState extends State<SendEmailNotificationPage> {
),
Container(height: 40.h),
SubmitBtn(
btnName: '发送',
btnName: '发送'.tr,
fontSize: 28.sp,
borderRadius: 20.w,
margin: EdgeInsets.only(left: 30.w, right: 30.w, top: 30.w),
@ -97,4 +131,16 @@ class _SendEmailNotificationPageState extends State<SendEmailNotificationPage> {
),
);
}
// pickerView
void openBottomItemSheet(BuildContext context) {
final List nameList =
state.emailTemplateList.map((item) => item.name!).toList();
Pickers.showSinglePicker(context,
data: nameList,
pickerStyle: DefaultPickerStyle(), onConfirm: (p, int position) {
state.selectEmailTemplate.value = nameList[position];
});
}
}

View File

@ -0,0 +1,17 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:star_lock/main/lockDetail/electronicKey/sendEmailNotification/sendEmailNotification_entity.dart';
class SendEmailNotificationState {
SendEmailNotificationState() {
if (Get.arguments['email'] != null) {
getEmail.value = Get.arguments['email'];
}
}
RxString getEmail = ''.obs;
final TextEditingController emailController = TextEditingController();
RxInt emailNotifyType = 1.obs; //1 2
RxList emailTemplateList = <EmailNotificationItem>[].obs;
RxString selectEmailTemplate = '默认模版'.obs;
}

View File

@ -254,4 +254,5 @@ abstract class Api {
final String deleteTemplateURL = '/v2/service/delete'; //
final String checkIpURL = '/checkIp/ip';
final String keyNoticeTemplateURL = '/key/getNoticeTemplate'; //
}

View File

@ -595,8 +595,9 @@ class ApiProvider extends BaseProvider {
'lockIds': lockIds,
}));
Future<Response> selectLockList(String searchStr) =>
post(selectLockListURL.toUrl, jsonEncode({
Future<Response> selectLockList(String searchStr) => post(
selectLockListURL.toUrl,
jsonEncode({
'searchStr': searchStr,
}));
@ -841,7 +842,8 @@ class ApiProvider extends BaseProvider {
//
Future<Response> getServerDatetimeLoadData(bool isUnShowLoading) =>
post(getServerDatetimeUrl.toUrl, jsonEncode({}), isUnShowLoading: isUnShowLoading);
post(getServerDatetimeUrl.toUrl, jsonEncode({}),
isUnShowLoading: isUnShowLoading);
//
Future<Response> setLockDiagnoseData(
@ -2227,10 +2229,22 @@ class ApiProvider extends BaseProvider {
);
Future<Response<dynamic>> checkIpAction(String ip) => post(
checkIpURL.toUrl,
jsonEncode(<String, dynamic>{'ip': ip}),
isUnShowLoading: true,
);
checkIpURL.toUrl,
jsonEncode(<String, dynamic>{'ip': ip}),
isUnShowLoading: true,
);
Future<Response<dynamic>> getKeyNoticeTemplate(
int lockId, int keyId, int channelType) =>
post(
keyNoticeTemplateURL.toUrl,
jsonEncode(<String, dynamic>{
'lockId': lockId,
'keyId': keyId,
'channelType': channelType
}),
isUnShowLoading: true,
);
}
extension ExtensionString on String {

View File

@ -8,6 +8,7 @@ import 'package:star_lock/main/lockDetail/electronicKey/electronicKeyList/entity
import 'package:star_lock/main/lockDetail/electronicKey/electronicKeyList/entity/ElectronicKeyListEntity.dart';
import 'package:star_lock/main/lockDetail/electronicKey/massSendElectronicKey/massSendLockGroupList/lockUserList/lockUserList_entity.dart';
import 'package:star_lock/main/lockDetail/electronicKey/massSendElectronicKey/massSendLockGroupList/massSendLockGroupListEntity.dart';
import 'package:star_lock/main/lockDetail/electronicKey/sendEmailNotification/sendEmailNotification_entity.dart';
import 'package:star_lock/main/lockDetail/face/addFace/addFace_entity.dart';
import 'package:star_lock/main/lockDetail/fingerprint/fingerprintList/fingerprint_entity.dart';
import 'package:star_lock/main/lockDetail/lockSet/basicInformation/basicInformation/KeyDetailEntity.dart';
@ -891,8 +892,10 @@ class ApiRepository {
}
//
Future<GetServerDatetimeEntity> getServerDatetimeData({bool? isUnShowLoading}) async {
final res = await apiProvider.getServerDatetimeLoadData(isUnShowLoading ?? true);
Future<GetServerDatetimeEntity> getServerDatetimeData(
{bool? isUnShowLoading}) async {
final res =
await apiProvider.getServerDatetimeLoadData(isUnShowLoading ?? true);
return GetServerDatetimeEntity.fromJson(res.body);
}
@ -2244,4 +2247,15 @@ class ApiRepository {
final Response<dynamic> res = await apiProvider.checkIpAction(ip);
return CheckIPEntity.fromJson(res.body);
}
//
Future<SendEmailNotificationEntity> getKeyNoticeTemplate({
required int lockId,
required int keyId,
required int channelType,
}) async {
final Response<dynamic> res =
await apiProvider.getKeyNoticeTemplate(lockId, keyId, channelType);
return SendEmailNotificationEntity.fromJson(res.body);
}
}

View File

@ -0,0 +1,135 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';
import 'package:star_lock/app_settings/app_colors.dart';
class EmailNotifyTypeSelectAlert extends StatelessWidget {
const EmailNotifyTypeSelectAlert({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
//
throw UnimplementedError();
}
static void showEmailNotifyTypeSelectAlert(
BuildContext context, Function(int) onSelected) {
bool isSystemEmailSelected = true; //
showCupertinoDialog(
context: context,
builder: (BuildContext context) {
return StatefulBuilder(
builder: (BuildContext context, StateSetter setState) {
return CupertinoAlertDialog(
title: const Text('类型选择'),
content: Column(
children: <Widget>[
Padding(
padding: EdgeInsets.only(
left: 10.w, top: 8.h, bottom: 16.h, right: 10.w),
child: Align(
alignment: Alignment.centerLeft,
child:
Text('请选择要使用哪种类型', style: TextStyle(fontSize: 20.sp)),
),
),
GestureDetector(
onTap: () {
setState(() {
isSystemEmailSelected = true;
});
},
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Image.asset(
isSystemEmailSelected
? 'images/icon_round_select.png'
: 'images/icon_round_unSelect.png',
width: 30.w,
height: 30.w,
),
Padding(
padding: EdgeInsets.only(left: 10.w),
child: Text(
'系统邮件(推荐)',
style: TextStyle(
fontSize: 22.sp, fontWeight: FontWeight.bold),
),
),
],
),
),
Padding(
padding: EdgeInsets.only(top: 6.h, left: 10.w, bottom: 10.h),
child: Align(
alignment: Alignment.centerLeft,
child: Text(
'邮件将从软件平台直接发给用户,请根据需要在软件那里购买邮件数量',
style: TextStyle(fontSize: 18.sp),
textAlign: TextAlign.left,
),
),
),
GestureDetector(
onTap: () {
setState(() {
isSystemEmailSelected = false;
});
},
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Image.asset(
!isSystemEmailSelected
? 'images/icon_round_select.png'
: 'images/icon_round_unSelect.png',
width: 30.w,
height: 30.w,
),
Padding(
padding: EdgeInsets.only(left: 10.w),
child: Text(
'个人邮件',
style: TextStyle(
fontSize: 22.sp, fontWeight: FontWeight.bold),
),
),
],
),
),
Padding(
padding: EdgeInsets.only(top: 6.h, left: 10.w),
child: Align(
alignment: Alignment.centerLeft,
child: Text(
'邮件将从你的个人邮箱发给用户',
style: TextStyle(fontSize: 18.sp),
),
),
),
],
),
actions: <Widget>[
CupertinoDialogAction(
onPressed: () {
final int selectedType =
isSystemEmailSelected ? 1 : 2; // 1 2
onSelected(selectedType);
Get.back();
},
child: Text(
'确定'.tr,
style: TextStyle(color: AppColors.mainColor),
),
),
],
);
});
},
);
}
}

View File

@ -10,6 +10,8 @@ import 'package:star_lock/common/XSConstantMacro/XSConstantMacro.dart';
typedef AuthInfoCallback = void Function(String? idCard, String? name);
class ShowCupertinoAlertView {
bool isSystemEmailSelected = true; //
//
void showQRImageAlert(BuildContext widgetContext, String qrCodeUrl) {
showCupertinoModalPopup(
@ -398,4 +400,114 @@ class ShowCupertinoAlertView {
},
);
}
// //
// void emailNotifyTypeSlectAlert() {
// showCupertinoDialog(
// context: Get.context!,
// builder: (BuildContext context) {
// return CupertinoAlertDialog(
// title: const Text('类型选择'),
// content: Column(
// children: <Widget>[
// Padding(
// padding: EdgeInsets.only(
// left: 10.w, top: 8.h, bottom: 16.h, right: 10.w),
// child: Align(
// alignment: Alignment.centerLeft,
// child: Text('请选择要使用哪种类型', style: TextStyle(fontSize: 20.sp)),
// ),
// ),
// GestureDetector(
// onTap: () {
// setState(() {
// isSystemEmailSelected = true;
// });
// },
// child: Row(
// mainAxisAlignment: MainAxisAlignment.start,
// crossAxisAlignment: CrossAxisAlignment.center,
// children: <Widget>[
// Image.asset(
// isSystemEmailSelected
// ? 'images/icon_round_select.png'
// : 'images/icon_round_unSelect.png',
// width: 30.w,
// height: 30.w,
// ),
// Padding(
// padding: EdgeInsets.only(left: 10.w),
// child: Text(
// '系统邮件(推荐)',
// style: TextStyle(
// fontSize: 22.sp, fontWeight: FontWeight.bold),
// ),
// ),
// ],
// ),
// ),
// Padding(
// padding: EdgeInsets.only(top: 6.h, left: 10.w, bottom: 10.h),
// child: Align(
// alignment: Alignment.centerLeft,
// child: Text(
// '邮件将从软件平台直接发给用户,请根据需要在软件那里购买邮件数量',
// style: TextStyle(fontSize: 18.sp),
// textAlign: TextAlign.left,
// ),
// ),
// ),
// GestureDetector(
// onTap: () {
// setState(() {
// isSystemEmailSelected = false;
// });
// },
// child: Row(
// mainAxisAlignment: MainAxisAlignment.start,
// crossAxisAlignment: CrossAxisAlignment.center,
// children: <Widget>[
// Image.asset(
// !isSystemEmailSelected
// ? 'images/icon_round_select.png'
// : 'images/icon_round_unSelect.png',
// width: 30.w,
// height: 30.w,
// ),
// Padding(
// padding: EdgeInsets.only(left: 10.w),
// child: Text(
// '个人邮件',
// style: TextStyle(
// fontSize: 22.sp, fontWeight: FontWeight.bold),
// ),
// ),
// ],
// ),
// ),
// Padding(
// padding: EdgeInsets.only(top: 6.h, left: 10.w),
// child: Align(
// alignment: Alignment.centerLeft,
// child: Text(
// '邮件将从你的个人邮箱发给用户',
// style: TextStyle(fontSize: 18.sp),
// ),
// ),
// ),
// ],
// ),
// actions: <Widget>[
// CupertinoDialogAction(
// onPressed: Get.back,
// child: Text(
// '确定'.tr,
// style: TextStyle(color: AppColors.mainColor),
// ),
// ),
// ],
// );
// },
// );
// }
}