Browse Source

同步Server最新接口

loki.wu 2 years ago
parent
commit
c0defc3909

+ 5 - 3
lib/services/authentication.m.dart

@@ -2205,8 +2205,8 @@ enum CustomerRpcCode {
 	VideoDeviceIdRepeatError,
 	PreviewFileTokenIsEmpty,
 	CoverImageTokenIsEmpty,
-	placeHolder_2026,
-	placeHolder_2027,
+	OrganizationCodeInconformity,
+	OnlyCommonUserUsed,
 	placeHolder_2028,
 	placeHolder_2029,
 	placeHolder_2030,
@@ -6254,7 +6254,7 @@ enum CustomerRpcCode {
 	ServerIsDisabled,
 	UserOrgCanNotChoseChild,
 	AnnouncementCodeIsEmpty,
-	placeHolder_6075,
+	UserScanInfoError,
 	placeHolder_6076,
 	placeHolder_6077,
 	placeHolder_6078,
@@ -7222,6 +7222,8 @@ enum CustomerRpcCode {
 	StudentNotPay,
 	LiveCodeIsEmpty,
 	LiveRoomIsEmpty,
+	DeviceRejected,
+	ReportSubmitted,
 }
 
 class ValidateTokenResult {

+ 5 - 0
lib/services/device.dart

@@ -242,5 +242,10 @@ class DeviceService extends JsonRpcClientBase {
 		return rpcRst;
 	}
 
+	Future<bool> scanBindDeviceAsync(ScanBindDeviceRequest request) async {
+		var rpcRst = await call("ScanBindDeviceAsync", request);
+		return rpcRst;
+	}
+
 }
 

+ 25 - 0
lib/services/device.m.dart

@@ -1876,4 +1876,29 @@ class RemoteLogResponseRequest extends TokenRequest{
 	}
 }
 
+class ScanBindDeviceRequest extends TokenRequest{
+	String? shortCode;
+
+	ScanBindDeviceRequest({
+		this.shortCode,
+		String? token,
+	}) : super(
+			token: token,
+		);
+
+	factory ScanBindDeviceRequest.fromJson(Map<String, dynamic> map) {
+		return ScanBindDeviceRequest( 
+			shortCode: map['ShortCode'],
+			token: map['Token'],
+		);
+	}
+
+	Map<String, dynamic> toJson() {
+		final map = super.toJson();
+		if(shortCode != null)
+			map['ShortCode'] = shortCode;
+		return map;
+	}
+}
+
 

+ 7 - 0
lib/services/education.dart

@@ -42,6 +42,7 @@ class EducationService extends JsonRpcClientBase {
 		FJsonConvert.setDecoder((map) => JoinLiveCourseResult.fromJson(map));
 		FJsonConvert.setDecoder((map) => LiveHeartRateResult.fromJson(map));
 		FJsonConvert.setDecoder((map) => LiveCourseBaseResult.fromJson(map));
+		FJsonConvert.setDecoder((map) => LiveCourseMember.fromJson(map));
 		FJsonConvert.setDecoder((map) => RemoteExaminationPageDTO.fromJson(map));
 	}
 
@@ -235,6 +236,12 @@ class EducationService extends JsonRpcClientBase {
 		return rpcRst;
 	}
 
+	Future<LiveCourseMember> deviceJoinInLiveCourseAsync(JoinLiveCourseRequest request) async {
+		var rpcRst = await call("DeviceJoinInLiveCourseAsync", request);
+		var result = LiveCourseMember.fromJson(rpcRst as Map<String, dynamic>);
+		return result;
+	}
+
 	Future<bool> uploadRemoteExaminationDataAsync(UploadRemoteExamRequest request) async {
 		var rpcRst = await call("UploadRemoteExaminationDataAsync", request);
 		return rpcRst;

+ 17 - 0
lib/services/education.m.dart

@@ -2371,6 +2371,9 @@ class LiveCourseMember {
 	LiveDataDTO? liveData;
 	List<VideoDeviceOutputInfo >? videoDeviceInfos;
 	bool isControllingParameter;
+	bool mergedChannel;
+	int mergedVideoOutputWidth;
+	int mergedVideoOutputHeight;
 
 	LiveCourseMember({
 		this.id,
@@ -2389,6 +2392,9 @@ class LiveCourseMember {
 		this.liveData,
 		this.videoDeviceInfos,
 		this.isControllingParameter = false,
+		this.mergedChannel = false,
+		this.mergedVideoOutputWidth = 0,
+		this.mergedVideoOutputHeight = 0,
 	});
 
 	factory LiveCourseMember.fromJson(Map<String, dynamic> map) {
@@ -2409,6 +2415,9 @@ class LiveCourseMember {
 			liveData: map['LiveData'] != null ? LiveDataDTO.fromJson(map['LiveData']) : null,
 			videoDeviceInfos: map['VideoDeviceInfos'] != null ? (map['VideoDeviceInfos'] as List).map((e)=>VideoDeviceOutputInfo.fromJson(e as Map<String,dynamic>)).toList() : null,
 			isControllingParameter: map['IsControllingParameter'],
+			mergedChannel: map['MergedChannel'],
+			mergedVideoOutputWidth: map['MergedVideoOutputWidth'],
+			mergedVideoOutputHeight: map['MergedVideoOutputHeight'],
 		);
 	}
 
@@ -2436,6 +2445,9 @@ class LiveCourseMember {
 		if(videoDeviceInfos != null)
 			map['VideoDeviceInfos'] = videoDeviceInfos;
 		map['IsControllingParameter'] = isControllingParameter;
+		map['MergedChannel'] = mergedChannel;
+		map['MergedVideoOutputWidth'] = mergedVideoOutputWidth;
+		map['MergedVideoOutputHeight'] = mergedVideoOutputHeight;
 		return map;
 	}
 }
@@ -2552,8 +2564,10 @@ class JoinLiveCourseResult extends LiveCourseBaseResult{
 }
 
 class JoinLiveCourseRequest extends InitiateLiveCourseRequest{
+	String? deviceCode;
 
 	JoinLiveCourseRequest({
+		this.deviceCode,
 		String? courseCode,
 		String? token,
 	}) : super(
@@ -2563,6 +2577,7 @@ class JoinLiveCourseRequest extends InitiateLiveCourseRequest{
 
 	factory JoinLiveCourseRequest.fromJson(Map<String, dynamic> map) {
 		return JoinLiveCourseRequest( 
+			deviceCode: map['DeviceCode'],
 			courseCode: map['CourseCode'],
 			token: map['Token'],
 		);
@@ -2570,6 +2585,8 @@ class JoinLiveCourseRequest extends InitiateLiveCourseRequest{
 
 	Map<String, dynamic> toJson() {
 		final map = super.toJson();
+		if(deviceCode != null)
+			map['DeviceCode'] = deviceCode;
 		return map;
 	}
 }

+ 73 - 0
lib/services/liveConsultation.m.dart

@@ -946,16 +946,19 @@ class ConsultationExportData {
 class ConsultationReportItem {
 	String? consultationCode;
 	String? fileToken;
+	DateTime? submissionTime;
 
 	ConsultationReportItem({
 		this.consultationCode,
 		this.fileToken,
+		this.submissionTime,
 	});
 
 	factory ConsultationReportItem.fromJson(Map<String, dynamic> map) {
 		return ConsultationReportItem( 
 			consultationCode: map['ConsultationCode'],
 			fileToken: map['FileToken'],
+			submissionTime: map['SubmissionTime'] != null ? DateTime.parse(map['SubmissionTime']) : null,
 		);
 	}
 
@@ -965,6 +968,8 @@ class ConsultationReportItem {
 			map['ConsultationCode'] = consultationCode;
 		if(fileToken != null)
 			map['FileToken'] = fileToken;
+		if(submissionTime != null)
+			map['SubmissionTime'] = JsonRpcUtils.dateFormat(submissionTime!);
 		return map;
 	}
 }
@@ -1019,12 +1024,14 @@ class ConsultationFileItem {
 	String? fileToken;
 	RemedicalFileDataTypeEnum fileDataType;
 	ConsultationFileTypeEnum consultationFileType;
+	DateTime? submissionTime;
 
 	ConsultationFileItem({
 		this.consultationCode,
 		this.fileToken,
 		this.fileDataType = RemedicalFileDataTypeEnum.VinnoVidSingle,
 		this.consultationFileType = ConsultationFileTypeEnum.Screenshot,
+		this.submissionTime,
 	});
 
 	factory ConsultationFileItem.fromJson(Map<String, dynamic> map) {
@@ -1033,6 +1040,7 @@ class ConsultationFileItem {
 			fileToken: map['FileToken'],
 			fileDataType: RemedicalFileDataTypeEnum.values.firstWhere((e) => e.index == map['FileDataType']),
 			consultationFileType: ConsultationFileTypeEnum.values.firstWhere((e) => e.index == map['ConsultationFileType']),
+			submissionTime: map['SubmissionTime'] != null ? DateTime.parse(map['SubmissionTime']) : null,
 		);
 	}
 
@@ -1044,6 +1052,8 @@ class ConsultationFileItem {
 			map['FileToken'] = fileToken;
 		map['FileDataType'] = fileDataType.index;
 		map['ConsultationFileType'] = consultationFileType.index;
+		if(submissionTime != null)
+			map['SubmissionTime'] = JsonRpcUtils.dateFormat(submissionTime!);
 		return map;
 	}
 }
@@ -4153,6 +4163,61 @@ class LoginLockInfoDTO {
 	}
 }
 
+class AssociatedInfoDTO {
+	String? id;
+	String? title;
+	String? cTitle;
+	String? eTitle;
+	String? icon;
+	String? description;
+	String? url;
+	int index;
+
+	AssociatedInfoDTO({
+		this.id,
+		this.title,
+		this.cTitle,
+		this.eTitle,
+		this.icon,
+		this.description,
+		this.url,
+		this.index = 0,
+	});
+
+	factory AssociatedInfoDTO.fromJson(Map<String, dynamic> map) {
+		return AssociatedInfoDTO( 
+			id: map['Id'],
+			title: map['Title'],
+			cTitle: map['CTitle'],
+			eTitle: map['ETitle'],
+			icon: map['Icon'],
+			description: map['Description'],
+			url: map['Url'],
+			index: map['Index'],
+		);
+	}
+
+	Map<String, dynamic> toJson() {
+		final map = Map<String, dynamic>();
+		if(id != null)
+			map['Id'] = id;
+		if(title != null)
+			map['Title'] = title;
+		if(cTitle != null)
+			map['CTitle'] = cTitle;
+		if(eTitle != null)
+			map['ETitle'] = eTitle;
+		if(icon != null)
+			map['Icon'] = icon;
+		if(description != null)
+			map['Description'] = description;
+		if(url != null)
+			map['Url'] = url;
+		map['Index'] = index;
+		return map;
+	}
+}
+
 class UserDTO extends UserBaseDTO{
 	String? phone;
 	String? email;
@@ -4183,6 +4248,7 @@ class UserDTO extends UserBaseDTO{
 	String? signature;
 	String? language;
 	bool enableReportLabel;
+	List<AssociatedInfoDTO >? associatedInfos;
 
 	UserDTO({
 		this.phone,
@@ -4214,6 +4280,7 @@ class UserDTO extends UserBaseDTO{
 		this.signature,
 		this.language,
 		this.enableReportLabel = false,
+		this.associatedInfos,
 		String? userCode,
 		String? userName,
 		String? headImageUrl,
@@ -4258,6 +4325,7 @@ class UserDTO extends UserBaseDTO{
 			signature: map['Signature'],
 			language: map['Language'],
 			enableReportLabel: map['EnableReportLabel'],
+			associatedInfos: map['AssociatedInfos'] != null ? (map['AssociatedInfos'] as List).map((e)=>AssociatedInfoDTO.fromJson(e as Map<String,dynamic>)).toList() : null,
 			userCode: map['UserCode'],
 			userName: map['UserName'],
 			headImageUrl: map['HeadImageUrl'],
@@ -4320,6 +4388,8 @@ class UserDTO extends UserBaseDTO{
 		if(language != null)
 			map['Language'] = language;
 		map['EnableReportLabel'] = enableReportLabel;
+		if(associatedInfos != null)
+			map['AssociatedInfos'] = associatedInfos;
 		return map;
 	}
 }
@@ -4360,6 +4430,7 @@ class UserExtendDTO extends UserDTO{
 		String? signature,
 		String? language,
 		bool enableReportLabel = false,
+		List<AssociatedInfoDTO >? associatedInfos,
 		String? userCode,
 		String? userName,
 		String? headImageUrl,
@@ -4395,6 +4466,7 @@ class UserExtendDTO extends UserDTO{
 			signature: signature,
 			language: language,
 			enableReportLabel: enableReportLabel,
+			associatedInfos: associatedInfos,
 			userCode: userCode,
 			userName: userName,
 			headImageUrl: headImageUrl,
@@ -4435,6 +4507,7 @@ class UserExtendDTO extends UserDTO{
 			signature: map['Signature'],
 			language: map['Language'],
 			enableReportLabel: map['EnableReportLabel'],
+			associatedInfos: map['AssociatedInfos'] != null ? (map['AssociatedInfos'] as List).map((e)=>AssociatedInfoDTO.fromJson(e as Map<String,dynamic>)).toList() : null,
 			userCode: map['UserCode'],
 			userName: map['UserName'],
 			headImageUrl: map['HeadImageUrl'],

+ 31 - 0
lib/services/login.dart

@@ -22,6 +22,9 @@ class LoginService extends JsonRpcClientBase {
 				) {
 		/// 注册响应实体反序列化处理器
 		FJsonConvert.setDecoder((map) => LoginResult.fromJson(map));
+		FJsonConvert.setDecoder((map) => StartAssociatedWithAccountResult.fromJson(map));
+		FJsonConvert.setDecoder((map) => GetAssociatedAccountInfoResult.fromJson(map));
+		FJsonConvert.setDecoder((map) => CheckConfirmScanStateResult.fromJson(map));
 	}
 
 	Future<LoginResult> commonLoginAsync(CommonLoginRequest request) async {
@@ -90,5 +93,33 @@ class LoginService extends JsonRpcClientBase {
 		return rpcRst;
 	}
 
+	Future<StartAssociatedWithAccountResult> startAssociatedWithAccountAsync(StartAssociatedWithAccountRequest request) async {
+		var rpcRst = await call("StartAssociatedWithAccountAsync", request);
+		var result = StartAssociatedWithAccountResult.fromJson(rpcRst as Map<String, dynamic>);
+		return result;
+	}
+
+	Future<GetAssociatedAccountInfoResult> getAssociatedAccountInfoAsync(GetAssociatedAccountInfoRequest request) async {
+		var rpcRst = await call("GetAssociatedAccountInfoAsync", request);
+		var result = GetAssociatedAccountInfoResult.fromJson(rpcRst as Map<String, dynamic>);
+		return result;
+	}
+
+	Future<String> getScanCodeAsync(GetScanCodeRequest request) async {
+		var rpcRst = await call("GetScanCodeAsync", request);
+		return rpcRst;
+	}
+
+	Future<bool> confirmScanAsync(ConfirmScanRequest request) async {
+		var rpcRst = await call("ConfirmScanAsync", request);
+		return rpcRst;
+	}
+
+	Future<CheckConfirmScanStateResult> checkConfirmScanStateAsync(CheckConfirmScanStateRequest request) async {
+		var rpcRst = await call("CheckConfirmScanStateAsync", request);
+		var result = CheckConfirmScanStateResult.fromJson(rpcRst as Map<String, dynamic>);
+		return result;
+	}
+
 }
 

+ 265 - 0
lib/services/login.m.dart

@@ -393,4 +393,269 @@ class GenerateNewPasswordRequest extends TokenRequest{
 	}
 }
 
+enum AssociatedAccountResultEnum {
+	Success,
+	UserNotFind,
+	UserNameIsEmpty,
+	Error,
+}
+
+class StartAssociatedWithAccountResult {
+	bool isSuccess;
+	AssociatedAccountResultEnum state;
+
+	StartAssociatedWithAccountResult({
+		this.isSuccess = false,
+		this.state = AssociatedAccountResultEnum.Success,
+	});
+
+	factory StartAssociatedWithAccountResult.fromJson(Map<String, dynamic> map) {
+		return StartAssociatedWithAccountResult( 
+			isSuccess: map['IsSuccess'],
+			state: AssociatedAccountResultEnum.values.firstWhere((e) => e.index == map['State']),
+		);
+	}
+
+	Map<String, dynamic> toJson() {
+		final map = Map<String, dynamic>();
+		map['IsSuccess'] = isSuccess;
+		map['State'] = state.index;
+		return map;
+	}
+}
+
+class StartAssociatedWithAccountRequest extends TokenRequest{
+	String? wingUserName;
+	String? thirdPartyUserId;
+	String? languageCode;
+
+	StartAssociatedWithAccountRequest({
+		this.wingUserName,
+		this.thirdPartyUserId,
+		this.languageCode,
+		String? token,
+	}) : super(
+			token: token,
+		);
+
+	factory StartAssociatedWithAccountRequest.fromJson(Map<String, dynamic> map) {
+		return StartAssociatedWithAccountRequest( 
+			wingUserName: map['WingUserName'],
+			thirdPartyUserId: map['ThirdPartyUserId'],
+			languageCode: map['LanguageCode'],
+			token: map['Token'],
+		);
+	}
+
+	Map<String, dynamic> toJson() {
+		final map = super.toJson();
+		if(wingUserName != null)
+			map['WingUserName'] = wingUserName;
+		if(thirdPartyUserId != null)
+			map['ThirdPartyUserId'] = thirdPartyUserId;
+		if(languageCode != null)
+			map['LanguageCode'] = languageCode;
+		return map;
+	}
+}
+
+class AssociatedFeatureInfoDTO extends AssociatedInfoDTO{
+	String? featureCode;
+
+	AssociatedFeatureInfoDTO({
+		this.featureCode,
+		String? id,
+		String? title,
+		String? cTitle,
+		String? eTitle,
+		String? icon,
+		String? description,
+		String? url,
+		int index = 0,
+	}) : super(
+			id: id,
+			title: title,
+			cTitle: cTitle,
+			eTitle: eTitle,
+			icon: icon,
+			description: description,
+			url: url,
+			index: index,
+		);
+
+	factory AssociatedFeatureInfoDTO.fromJson(Map<String, dynamic> map) {
+		return AssociatedFeatureInfoDTO( 
+			featureCode: map['FeatureCode'],
+			id: map['Id'],
+			title: map['Title'],
+			cTitle: map['CTitle'],
+			eTitle: map['ETitle'],
+			icon: map['Icon'],
+			description: map['Description'],
+			url: map['Url'],
+			index: map['Index'],
+		);
+	}
+
+	Map<String, dynamic> toJson() {
+		final map = super.toJson();
+		if(featureCode != null)
+			map['FeatureCode'] = featureCode;
+		return map;
+	}
+}
+
+class GetAssociatedAccountInfoResult {
+	bool isSuccess;
+	List<AssociatedFeatureInfoDTO >? accountInfoList;
+
+	GetAssociatedAccountInfoResult({
+		this.isSuccess = false,
+		this.accountInfoList,
+	});
+
+	factory GetAssociatedAccountInfoResult.fromJson(Map<String, dynamic> map) {
+		return GetAssociatedAccountInfoResult( 
+			isSuccess: map['IsSuccess'],
+			accountInfoList: map['AccountInfoList'] != null ? (map['AccountInfoList'] as List).map((e)=>AssociatedFeatureInfoDTO.fromJson(e as Map<String,dynamic>)).toList() : null,
+		);
+	}
+
+	Map<String, dynamic> toJson() {
+		final map = Map<String, dynamic>();
+		map['IsSuccess'] = isSuccess;
+		if(accountInfoList != null)
+			map['AccountInfoList'] = accountInfoList;
+		return map;
+	}
+}
+
+class GetAssociatedAccountInfoRequest extends TokenRequest{
+
+	GetAssociatedAccountInfoRequest({
+		String? token,
+	}) : super(
+			token: token,
+		);
+
+	factory GetAssociatedAccountInfoRequest.fromJson(Map<String, dynamic> map) {
+		return GetAssociatedAccountInfoRequest( 
+			token: map['Token'],
+		);
+	}
+
+	Map<String, dynamic> toJson() {
+		final map = super.toJson();
+		return map;
+	}
+}
+
+enum ScanLoginSource {
+	PC,
+	Web,
+	US,
+}
+
+class GetScanCodeRequest {
+	ScanLoginSource scanLoginSource;
+	String? installVersion;
+
+	GetScanCodeRequest({
+		this.scanLoginSource = ScanLoginSource.PC,
+		this.installVersion,
+	});
+
+	factory GetScanCodeRequest.fromJson(Map<String, dynamic> map) {
+		return GetScanCodeRequest( 
+			scanLoginSource: ScanLoginSource.values.firstWhere((e) => e.index == map['ScanLoginSource']),
+			installVersion: map['InstallVersion'],
+		);
+	}
+
+	Map<String, dynamic> toJson() {
+		final map = Map<String, dynamic>();
+		map['ScanLoginSource'] = scanLoginSource.index;
+		if(installVersion != null)
+			map['InstallVersion'] = installVersion;
+		return map;
+	}
+}
+
+class ConfirmScanRequest extends TokenRequest{
+	String? scanCode;
+
+	ConfirmScanRequest({
+		this.scanCode,
+		String? token,
+	}) : super(
+			token: token,
+		);
+
+	factory ConfirmScanRequest.fromJson(Map<String, dynamic> map) {
+		return ConfirmScanRequest( 
+			scanCode: map['ScanCode'],
+			token: map['Token'],
+		);
+	}
+
+	Map<String, dynamic> toJson() {
+		final map = super.toJson();
+		if(scanCode != null)
+			map['ScanCode'] = scanCode;
+		return map;
+	}
+}
+
+enum CheckConfirmScanState {
+	Wait,
+	Success,
+	Expire,
+}
+
+class CheckConfirmScanStateResult {
+	CheckConfirmScanState checkConfirmScanState;
+	LoginResult? loginResult;
+
+	CheckConfirmScanStateResult({
+		this.checkConfirmScanState = CheckConfirmScanState.Wait,
+		this.loginResult,
+	});
+
+	factory CheckConfirmScanStateResult.fromJson(Map<String, dynamic> map) {
+		return CheckConfirmScanStateResult( 
+			checkConfirmScanState: CheckConfirmScanState.values.firstWhere((e) => e.index == map['CheckConfirmScanState']),
+			loginResult: map['LoginResult'] != null ? LoginResult.fromJson(map['LoginResult']) : null,
+		);
+	}
+
+	Map<String, dynamic> toJson() {
+		final map = Map<String, dynamic>();
+		map['CheckConfirmScanState'] = checkConfirmScanState.index;
+		if(loginResult != null)
+			map['LoginResult'] = loginResult;
+		return map;
+	}
+}
+
+class CheckConfirmScanStateRequest {
+	String? scanCode;
+
+	CheckConfirmScanStateRequest({
+		this.scanCode,
+	});
+
+	factory CheckConfirmScanStateRequest.fromJson(Map<String, dynamic> map) {
+		return CheckConfirmScanStateRequest( 
+			scanCode: map['ScanCode'],
+		);
+	}
+
+	Map<String, dynamic> toJson() {
+		final map = Map<String, dynamic>();
+		if(scanCode != null)
+			map['ScanCode'] = scanCode;
+		return map;
+	}
+}
+
 

+ 36 - 0
lib/services/notification.m.dart

@@ -76,6 +76,7 @@ enum NotificationTypeEnum {
 	ConnectStatusToClientNotification,
 	GetRemoteLogToDeviceNotification,
 	GetRemoteLogToClientNotification,
+	StartCourseHeartRateToDeviceNotification,
 }
 
 class NotificationDTO {
@@ -2237,6 +2238,41 @@ class StartConsolutionHeartRateToDeviceNotification extends NotificationDTO{
 	}
 }
 
+class StartCourseHeartRateToDeviceNotification extends NotificationDTO{
+	String? liveRoomCode;
+	int intervalSeconds;
+
+	StartCourseHeartRateToDeviceNotification({
+		NotificationTypeEnum notificationType = NotificationTypeEnum.Unknown,
+		this.liveRoomCode,
+		this.intervalSeconds = 0,
+		String? code,
+		bool isResponse = false,
+	}) : super(
+			notificationType: notificationType,
+			code: code,
+			isResponse: isResponse,
+		);
+
+	factory StartCourseHeartRateToDeviceNotification.fromJson(Map<String, dynamic> map) {
+		return StartCourseHeartRateToDeviceNotification( 
+			notificationType: NotificationTypeEnum.values.firstWhere((e) => e.index == map['NotificationType']),
+			liveRoomCode: map['LiveRoomCode'],
+			intervalSeconds: map['IntervalSeconds'],
+			code: map['Code'],
+			isResponse: map['IsResponse'],
+		);
+	}
+
+	Map<String, dynamic> toJson() {
+		final map = super.toJson();
+		if(liveRoomCode != null)
+			map['LiveRoomCode'] = liveRoomCode;
+		map['IntervalSeconds'] = intervalSeconds;
+		return map;
+	}
+}
+
 class LiveConsultationMemberInfo {
 	String? id;
 	String? name;

+ 3 - 0
lib/services/notificationdecoder.dart

@@ -148,6 +148,9 @@ class NotificationDecoder {
 		_builders.add(NotificationTypeEnum.StartConsolutionHeartRateToDeviceNotification,
 				(map) => StartConsolutionHeartRateToDeviceNotification.fromJson(map));
 
+		_builders.add(NotificationTypeEnum.StartCourseHeartRateToDeviceNotification,
+				(map) => StartCourseHeartRateToDeviceNotification.fromJson(map));
+
 		_builders.add(NotificationTypeEnum.AcceptLiveConsultationNotification,
 				(map) => AcceptLiveConsultationNotification.fromJson(map));
 

+ 87 - 1
lib/services/other.m.dart

@@ -1,5 +1,6 @@
 import 'authentication.m.dart';
 import 'notification.m.dart';
+import 'login.m.dart';
 import 'upgrade.m.dart';
 import 'user.m.dart';
 import 'liveConsultation.m.dart';
@@ -18,7 +19,6 @@ import 'vinnoServer.m.dart';
 import 'position.m.dart';
 import 'rank.m.dart';
 import 'identityApply.m.dart';
-import 'login.m.dart';
 import 'role.m.dart';
 import 'region.m.dart';
 import 'aSR.m.dart';
@@ -1751,6 +1751,36 @@ class ReportLiveStateResult {
 	}
 }
 
+class ConfirmAssociatedWithAccountRequest extends TokenRequest{
+	String? emailAddress;
+	String? verifyCode;
+
+	ConfirmAssociatedWithAccountRequest({
+		this.emailAddress,
+		this.verifyCode,
+		String? token,
+	}) : super(
+			token: token,
+		);
+
+	factory ConfirmAssociatedWithAccountRequest.fromJson(Map<String, dynamic> map) {
+		return ConfirmAssociatedWithAccountRequest( 
+			emailAddress: map['EmailAddress'],
+			verifyCode: map['VerifyCode'],
+			token: map['Token'],
+		);
+	}
+
+	Map<String, dynamic> toJson() {
+		final map = super.toJson();
+		if(emailAddress != null)
+			map['EmailAddress'] = emailAddress;
+		if(verifyCode != null)
+			map['VerifyCode'] = verifyCode;
+		return map;
+	}
+}
+
 class DeleteThesaurusCodeRequest extends TokenRequest{
 	String? thesaurusCode;
 
@@ -1808,6 +1838,7 @@ class SignUpRequest extends UserDTO{
 		String? signature,
 		String? language,
 		bool enableReportLabel = false,
+		List<AssociatedInfoDTO >? associatedInfos,
 		String? userCode,
 		String? userName,
 		String? headImageUrl,
@@ -1843,6 +1874,7 @@ class SignUpRequest extends UserDTO{
 			signature: signature,
 			language: language,
 			enableReportLabel: enableReportLabel,
+			associatedInfos: associatedInfos,
 			userCode: userCode,
 			userName: userName,
 			headImageUrl: headImageUrl,
@@ -1881,6 +1913,7 @@ class SignUpRequest extends UserDTO{
 			signature: map['Signature'],
 			language: map['Language'],
 			enableReportLabel: map['EnableReportLabel'],
+			associatedInfos: map['AssociatedInfos'] != null ? (map['AssociatedInfos'] as List).map((e)=>AssociatedInfoDTO.fromJson(e as Map<String,dynamic>)).toList() : null,
 			userCode: map['UserCode'],
 			userName: map['UserName'],
 			headImageUrl: map['HeadImageUrl'],
@@ -6174,6 +6207,7 @@ class ManageUserInfoDTO extends UserDTO{
 		String? signature,
 		String? language,
 		bool enableReportLabel = false,
+		List<AssociatedInfoDTO >? associatedInfos,
 		String? userCode,
 		String? userName,
 		String? headImageUrl,
@@ -6209,6 +6243,7 @@ class ManageUserInfoDTO extends UserDTO{
 			signature: signature,
 			language: language,
 			enableReportLabel: enableReportLabel,
+			associatedInfos: associatedInfos,
 			userCode: userCode,
 			userName: userName,
 			headImageUrl: headImageUrl,
@@ -6256,6 +6291,7 @@ class ManageUserInfoDTO extends UserDTO{
 			signature: map['Signature'],
 			language: map['Language'],
 			enableReportLabel: map['EnableReportLabel'],
+			associatedInfos: map['AssociatedInfos'] != null ? (map['AssociatedInfos'] as List).map((e)=>AssociatedInfoDTO.fromJson(e as Map<String,dynamic>)).toList() : null,
 			userCode: map['UserCode'],
 			userName: map['UserName'],
 			headImageUrl: map['HeadImageUrl'],
@@ -6330,6 +6366,7 @@ class ModifyUserRequest extends ManageUserInfoDTO{
 		String? signature,
 		String? language,
 		bool enableReportLabel = false,
+		List<AssociatedInfoDTO >? associatedInfos,
 		String? userCode,
 		String? userName,
 		String? headImageUrl,
@@ -6374,6 +6411,7 @@ class ModifyUserRequest extends ManageUserInfoDTO{
 			signature: signature,
 			language: language,
 			enableReportLabel: enableReportLabel,
+			associatedInfos: associatedInfos,
 			userCode: userCode,
 			userName: userName,
 			headImageUrl: headImageUrl,
@@ -6422,6 +6460,7 @@ class ModifyUserRequest extends ManageUserInfoDTO{
 			signature: map['Signature'],
 			language: map['Language'],
 			enableReportLabel: map['EnableReportLabel'],
+			associatedInfos: map['AssociatedInfos'] != null ? (map['AssociatedInfos'] as List).map((e)=>AssociatedInfoDTO.fromJson(e as Map<String,dynamic>)).toList() : null,
 			userCode: map['UserCode'],
 			userName: map['UserName'],
 			headImageUrl: map['HeadImageUrl'],
@@ -8907,12 +8946,14 @@ enum SyncTypeEnum {
 	ChangeRoom,
 	SaveViewer,
 	DeleteViewer,
+	DeviceAcceptIn,
 }
 
 enum SyncServiceEnum {
 	Live,
 	LiveConsultation,
 	Notification,
+	ScanLogin,
 }
 
 enum WSConnectTypeEnum {
@@ -9390,6 +9431,51 @@ enum ArrowOrientation {
 	Right,
 }
 
+class UserScanInfo {
+	String? scanCode;
+	ScanLoginSource scanLoginSource;
+	DateTime? createTime;
+	DateTime? expireTime;
+	String? installVersion;
+	LoginResult? loginResult;
+
+	UserScanInfo({
+		this.scanCode,
+		this.scanLoginSource = ScanLoginSource.PC,
+		this.createTime,
+		this.expireTime,
+		this.installVersion,
+		this.loginResult,
+	});
+
+	factory UserScanInfo.fromJson(Map<String, dynamic> map) {
+		return UserScanInfo( 
+			scanCode: map['ScanCode'],
+			scanLoginSource: ScanLoginSource.values.firstWhere((e) => e.index == map['ScanLoginSource']),
+			createTime: map['CreateTime'] != null ? DateTime.parse(map['CreateTime']) : null,
+			expireTime: map['ExpireTime'] != null ? DateTime.parse(map['ExpireTime']) : null,
+			installVersion: map['InstallVersion'],
+			loginResult: map['LoginResult'] != null ? LoginResult.fromJson(map['LoginResult']) : null,
+		);
+	}
+
+	Map<String, dynamic> toJson() {
+		final map = Map<String, dynamic>();
+		if(scanCode != null)
+			map['ScanCode'] = scanCode;
+		map['ScanLoginSource'] = scanLoginSource.index;
+		if(createTime != null)
+			map['CreateTime'] = JsonRpcUtils.dateFormat(createTime!);
+		if(expireTime != null)
+			map['ExpireTime'] = JsonRpcUtils.dateFormat(expireTime!);
+		if(installVersion != null)
+			map['InstallVersion'] = installVersion;
+		if(loginResult != null)
+			map['LoginResult'] = loginResult;
+		return map;
+	}
+}
+
 class UserCMSDTO {
 	String? cMSData;
 

+ 3 - 0
lib/services/user.m.dart

@@ -405,6 +405,7 @@ class UserInfoByCodeDTO extends UserDTO{
 		String? signature,
 		String? language,
 		bool enableReportLabel = false,
+		List<AssociatedInfoDTO >? associatedInfos,
 		String? userCode,
 		String? userName,
 		String? headImageUrl,
@@ -440,6 +441,7 @@ class UserInfoByCodeDTO extends UserDTO{
 			signature: signature,
 			language: language,
 			enableReportLabel: enableReportLabel,
+			associatedInfos: associatedInfos,
 			userCode: userCode,
 			userName: userName,
 			headImageUrl: headImageUrl,
@@ -480,6 +482,7 @@ class UserInfoByCodeDTO extends UserDTO{
 			signature: map['Signature'],
 			language: map['Language'],
 			enableReportLabel: map['EnableReportLabel'],
+			associatedInfos: map['AssociatedInfos'] != null ? (map['AssociatedInfos'] as List).map((e)=>AssociatedInfoDTO.fromJson(e as Map<String,dynamic>)).toList() : null,
 			userCode: map['UserCode'],
 			userName: map['UserName'],
 			headImageUrl: map['HeadImageUrl'],