123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584 |
- import 'dart:convert';
- import 'dart:html';
- import 'dart:typed_data';
- import 'package:web_socket_channel/web_socket_channel.dart';
- import 'package:fluttertoast/fluttertoast.dart';
- import 'package:colorize_logger/colorize_logger.dart';
- import 'package:flutter/material.dart';
- import 'package:flutter/services.dart';
- import 'package:get_it/get_it.dart';
- import 'package:http/http.dart' as http;
- import 'package:sprintf/sprintf.dart';
- import 'package:ustest/Services/DeviceService.dart';
- class DeviceInfoView extends StatefulWidget {
- DeviceInfoView();
- @override
- _DeviceInfoViewState createState() => _DeviceInfoViewState();
- }
- class _DeviceInfoViewState extends State<DeviceInfoView> {
- late List<File> _files;
- String _uniqueCode = "xxxxxx";
- String _token = "xxxxxx";
- String _examCode = "";
- final _filesController = TextEditingController();
- final _connectTextController = TextEditingController(
- text: '{"jsonrpc": "2.0",'
- '"method": "ConnectAsync",'
- '"params": [{'
- '"DeviceUniqueCode": "4914352a75f645279f6b4ad6764cc288",'
- '"Password": "4914352a75f645279f6b4ad6764cc288",'
- '"DeviceModel": "E30",'
- '"DeviceType": "US",'
- '"SoftwareVersion": "1.11.0",'
- '"SystemVersion": "2.2.27.5",'
- '"CPUModel": "I5-10400",'
- '"Description": "自测设备",'
- '"Name": "ZCSB",'
- '"Organ": "Organization_20220608060137EVEo3p",'
- '"SystemLanguage": "Chinese"'
- '}],'
- '"id": 1 }');
- final _channel = WebSocketChannel.connect(
- Uri.parse('ws://192.168.6.20:9301?token=8557855B64474684B45294B75B1EDBA1'),
- );
- @override
- void initState() {
- getDeviceInfo();
- super.initState();
- }
- void getDeviceInfo() async {
- try {
- var request = _connectTextController.text;
- var service = GetIt.instance.get<DeviceService>();
- var device = await service.getDeviceDetail(request);
- setState(() {
- _uniqueCode = device.uniqueCode;
- _token = device.token;
- });
- } catch (ex) {
- print("initState ex" + ex.toString());
- }
- }
- @override
- Widget build(BuildContext context) {
- return Scaffold(
- body: Center(
- child: Container(
- padding: const EdgeInsets.fromLTRB(20, 30, 20, 20),
- child: Column(children: [
- Padding(
- padding: EdgeInsets.all(8.0),
- child: Row(
- children: [
- Expanded(
- child: TextField(
- controller: _connectTextController,
- keyboardType: TextInputType.multiline,
- textInputAction: TextInputAction.newline,
- decoration: InputDecoration(
- border: const OutlineInputBorder(),
- labelText: "请求数据"),
- minLines: 1,
- maxLines: 5,
- )),
- TextButton(
- onPressed: onConnect, child: const Text("Connect"))
- ],
- ),
- ),
- Padding(
- padding: EdgeInsets.all(8.0),
- child: Row(
- children: [Text("超声机设备Id"), Text("Device12345678")],
- mainAxisAlignment: MainAxisAlignment.spaceBetween,
- )),
- Padding(
- padding: EdgeInsets.all(8.0),
- child: Row(
- children: [Text("超声机唯一码"), Text(_uniqueCode)],
- mainAxisAlignment: MainAxisAlignment.spaceBetween,
- )),
- Padding(
- padding: EdgeInsets.all(8.0),
- child: Row(
- children: [
- Text("Token"),
- Expanded(
- child: Text(
- _token,
- ))
- ],
- mainAxisAlignment: MainAxisAlignment.spaceBetween,
- )),
- Padding(
- padding: EdgeInsets.all(8.0),
- child: Row(
- children: [
- Text("创建检查"),
- Text(_examCode),
- ],
- mainAxisAlignment: MainAxisAlignment.spaceBetween,
- )),
- Padding(
- padding: EdgeInsets.all(8.0),
- child: Row(
- children: [
- Expanded(
- child: TextField(
- restorationId: "file",
- keyboardType: TextInputType.text,
- decoration: InputDecoration(
- border: const OutlineInputBorder(),
- labelText: "请选择一个vid和一个对应缩略图jpg文件"),
- maxLength: 1,
- controller: _filesController,
- ),
- ),
- TextButton(
- onPressed: _onBrowse,
- child: Text("Browse"),
- )
- ],
- )),
- Row(
- mainAxisAlignment: MainAxisAlignment.spaceEvenly,
- children: [
- TextButton.icon(
- onPressed: onCreateExamPressed,
- icon: Icon(Icons.add),
- label: Text("开始检查")),
- TextButton.icon(
- onPressed: onUploadPressed,
- icon: Icon(Icons.upload_file),
- label: Text("上传图像")),
- TextButton.icon(
- onPressed: onFinshExanPressed,
- icon: Icon(Icons.done_all),
- label: Text("结束检查"))
- ],
- ),
- StreamBuilder(
- stream: _channel.stream,
- builder: (context, snapshot) {
- var message = "";
- // var message =
- // snapshot.hasData ? '${snapshot.data}' : 'no message';
- if (snapshot.hasData) {
- var uint8Array =
- Uint8List.fromList(snapshot.data as List<int>);
- var byteData = uint8Array.buffer.asByteData();
- var byteDataLength = byteData.lengthInBytes;
- var messageConentList =
- Uint8List.view(uint8Array.buffer, 0, byteDataLength);
- var messageConentLength = messageConentList.length;
- var messageConent = Uint8List.fromList(messageConentList);
- var messageText = Utf8Decoder().convert(messageConent);
- Map<String, dynamic> messageObject =
- jsonDecode(messageText);
- //通知类型区分
- if (messageObject["NotificationType"] as int ==
- NotificationTypeEnum.ConnectionNotification.index) {
- var connectionNotification =
- ConnectionNotification.fromJson(messageObject);
- print(
- "connectionNotification.NotificationType:${connectionNotification.notificationType}");
- } else if (messageObject["NotificationType"] as int ==
- NotificationTypeEnum.DisconnectNotification.index) {
- var disconnectNotification =
- DisconnectNotification.fromJson(messageObject);
- print(
- "disconnectNotification.NotificationType:${disconnectNotification.notificationType}");
- }
- message = messageText;
- }
- return new Padding(
- padding: const EdgeInsets.symmetric(vertical: 24.0),
- child: new Text(message),
- );
- },
- )
- ]))),
- );
- }
- @override
- void dispose() {
- //_channel.sink.close();
- super.dispose();
- }
- void onConnect() async {
- try {
- var request = _connectTextController.text;
- var service = GetIt.instance.get<DeviceService>();
- var device = await service.connectAsync(request);
- setState(() {
- _uniqueCode = device.uniqueCode;
- _token = device.token;
- });
- } catch (ex) {
- print("_token ex" + ex.toString());
- }
- }
- void _onBrowse() {
- var uploadInput = new FileUploadInputElement();
- uploadInput.multiple = true;
- //uploadInput.accept = '*.vid';
- uploadInput.click();
- uploadInput.onChange.listen(
- (changeEvent) {
- _files = uploadInput.files!;
- for (var i = 0; i < _files.length; i++) {
- _filesController.text += _files[i].name + ';';
- }
- },
- );
- }
- void _onProgress(ProgressEvent e) {
- print("upload progress is" + e.total.toString());
- }
- Future<String> uploadFileToSever(File file) async {
- var url = '';
- try {
- print('File Name:' + file.name);
- var client = http.Client();
- var body = sprintf(
- '{"jsonrpc": "2.0", "method": "GetAuthorizationAsync", "params": [{"Token": "%s", "FileName": "%s", "ApplicantTypeEnum": 1 }], "id": 1 }',
- [_token, file.name]);
- final response = await client.post(
- Uri.parse('http://192.168.6.20:8303/IStorageService'),
- body: body);
- print('GetAuthorizationAsync response.body' + response.body);
- final parsed = jsonDecode(response.body);
- var authorization = parsed['result']['Authorization'].toString();
- url = parsed['result']['StorageUrl'].toString();
- print('GetAuthorizationAsync result' + authorization);
- final headers = {"Authorization": authorization};
- var formData = new FormData();
- formData.appendBlob('file', file);
- await HttpRequest.request(url,
- method: 'PUT',
- sendData: formData,
- requestHeaders: headers,
- onProgress: _onProgress)
- .then((value) {
- var data = value;
- var responseText = data.responseText!;
- final parsed = jsonDecode(responseText);
- var reuslt = parsed['IsSuccess'];
- Logger.info(
- "status:" + data.status.toString() + ",isSuccess:" + reuslt);
- }).catchError((onError) {
- Logger.error(onError);
- });
- } catch (ex) {
- print(ex);
- }
- return url;
- }
- void onUploadPressed() async {
- if (_examCode == "") {
- showToast("请先开始一个检查");
- return;
- }
- var privewUrl = '';
- var vidUrl = '';
- for (var i = 0; i < _files.length; i++) {
- var name = _files[i].name;
- if (name.endsWith(".VID")) {
- vidUrl = await uploadFileToSever(_files[i]);
- Logger.info("Vid File upload to " + vidUrl);
- } else {
- privewUrl = await uploadFileToSever(_files[i]);
- Logger.info("Preview File upload to " + privewUrl);
- }
- }
- var client = http.Client();
- //update data
- var body = sprintf(
- '{"jsonrpc": "2.0", "method": "UploadExamDataAsync", "params": [{"Token": "%s", "ExamCode": "%s", "PreviewFileToken": "%s", "FileToken": "%s","Application": "腹部", "PatientScanType": "Routine" }], "id": 1 }',
- [_token, _examCode, privewUrl, vidUrl]);
- print('UploadExamData http.Client()' + body);
- final response2 = await client.post(
- Uri.parse('http://192.168.6.20:8303/IRemedicalService'),
- body: body);
- print('UploadExamData response.body' + response2.body);
- final parsed2 = jsonDecode(response2.body);
- var resutlt = parsed2['result'].toString();
- print('UploadExamData result ' + resutlt);
- }
- void onCreateExamPressed() async {
- var client = http.Client();
- var body = sprintf(
- '{"jsonrpc": "2.0", "method": "CreateExamInfoAsync", "params": [{"Token": "%s", "PatientType": "Person", "PatientInfo": [{"Name":"張三","IdentityCard":"320525198806110078","Sex":"2","Age":"34"}] }], "id": 1 }',
- [_token]);
- print('CreateExamInfo http.Client()' + body);
- final response = await client.post(
- Uri.parse('http://192.168.6.20:8303/IRemedicalService'),
- body: body);
- print('CreateExamInfo response.body' + response.body);
- final parsed = jsonDecode(response.body);
- var examCode = parsed['result']['ExamCode'].toString();
- print('CreateExamInfo result examCode' + examCode);
- setState(() {
- _examCode = examCode;
- });
- //client.close();
- }
- void onFinshExanPressed() async {
- if (_examCode == "") {
- showToast("No exam to finish");
- return;
- }
- var client = http.Client();
- try {
- var body = sprintf(
- '{"jsonrpc": "2.0", "method": "DeviceFinishExamAsync", "params": [{"Token": "%s", "Records":["%s"]}], "id": 1 }',
- [_token, _examCode]);
- print('FinishExam http.Client()' + body);
- final response = await client.post(
- Uri.parse('http://192.168.6.20:8303/IRemedicalService'),
- body: body);
- print('FinishExam response.body' + response.body);
- final parsed = jsonDecode(response.body);
- var result = parsed['result'] as bool;
- print('FinishExam result examCode' + result.toString());
- setState(() {
- _examCode = "";
- });
- //client.close();
- } catch (ex) {
- print('FinishExam.to ex' + ex.toString());
- }
- }
- void showToast(String msg) {
- Fluttertoast.showToast(
- msg: msg,
- toastLength: Toast.LENGTH_SHORT,
- gravity: ToastGravity.CENTER,
- timeInSecForIosWeb: 1,
- backgroundColor: Colors.red[500],
- textColor: Colors.white,
- fontSize: 16.0);
- }
- }
- enum NotificationTypeEnum {
- /// <summary>
- /// Unknown|0| 未知
- /// </summary>
- Unknown,
- /// <summary>
- /// ChatMsgNotification|1| 聊天通知
- /// </summary>
- ChatMsgNotification,
- /// <summary>
- /// TokenReplacedNotification|2| 账号被替换登出通知
- /// </summary>
- TokenReplacedNotification,
- /// <summary>
- /// DisconnectNotification| 3|与服务器断开连接通知
- /// </summary>
- DisconnectNotification,
- /// <summary>
- /// ConnectionNotification| 4| 与服务器已连接通知
- /// </summary>
- ConnectionNotification,
- /// <summary>
- /// ExamRecordsFinishedNotification| 5 | 完成检查通知
- /// </summary>
- ExamRecordsFinishedNotification,
- /// <summary>
- /// RejectApplyConsultationNotification| 6 | 拒绝预约申请的通知
- /// </summary>
- RejectApplyConsultationNotification,
- /// <summary>
- /// CancelInvitingInLiveConsultationNotification| 7 | 取消会诊过程中邀请其他成员的通知
- /// </summary>
- CancelInvitingInLiveConsultationNotification,
- /// <summary>
- /// InviteInLiveConsultationNotification| 8 | 会诊过程中邀请其他成员的通知
- /// </summary>
- InviteInLiveConsultationNotification,
- /// <summary>
- /// InviteInLiveConsultationNotification| 9 | 会诊开始前提醒的通知
- /// </summary>
- ConsultationRemindNotification,
- /// <summary>
- /// PasswordExpiredWarningNotification| 10 | 用户密码过期预警通知
- /// </summary>
- PasswordExpiredWarningNotification,
- /// <summary>
- /// InviteLiveConsultationNotification| 11 | 开始会诊的通知
- /// </summary>
- InviteLiveConsultationNotification,
- /// <summary>
- /// AcceptLiveConsultationNotification| 12 | 接受会诊的通知
- /// </summary>
- AcceptLiveConsultationNotification,
- /// <summary>
- /// RejectLiveConsultationNotification| 13 | 拒绝会诊的通知
- /// </summary>
- RejectLiveConsultationNotification,
- /// <summary>
- /// InviteLiveConsultationToDeviceNotification| 14 | 开始会诊通知 to 设备端
- /// </summary>
- InviteLiveConsultationToDeviceNotification,
- /// <summary>
- /// CancelLiveConsultationNotification| 15 | 取消会诊通知
- /// </summary>
- CancelLiveConsultationNotification,
- /// <summary>
- /// CloseLiveConsultationNotification| 16 | 关闭会诊通知
- /// </summary>
- CloseLiveConsultationNotification,
- /// <summary>
- /// JoinLiveConsultationNotification| 17 | 进入会诊通知
- /// </summary>
- JoinLiveConsultationNotification,
- /// <summary>
- /// NetworkErrConsultationNotification| 18 | 网络质量不佳会诊通知
- /// </summary>
- NetworkErrConsultationNotification,
- /// <summary>
- /// LeaveConsultationNotification| 19 | 离开会诊通知
- /// </summary>
- LeaveConsultationNotification,
- /// <summary>
- /// JoinInLiveConsultationNotification| 20 | 会诊中加入房间
- /// </summary>
- JoinInLiveConsultationNotification,
- /// <summary>
- /// RejectLiveConsultationNotification| 21 | 拒绝会诊的通知
- /// </summary>
- RejectInviteLiveConsultationNotification,
- /// <summary>
- /// ApplyConsultationNotification| 22 | 会诊申请通知
- /// </summary>
- ApplyConsultationNotification,
- /// <summary>
- /// ApprovalApplyConsultationNotification| 23 | 批准申请会诊通知
- /// </summary>
- ApprovalApplyConsultationNotification,
- /// <summary>
- /// InviteeConsultationNotification| 24 | 会诊受邀请人通知
- /// </summary>
- InviteeConsultationNotification,
- /// <summary>
- /// InviteeApproveApplyConsultationNotification| 25 | 会诊受邀请参与人同意通知
- /// </summary>
- InviteeApproveApplyConsultationNotification,
- /// <summary>
- /// InviteeRejectApplyConsultationNotification| 26 | 会诊受邀请参与人拒绝通知
- /// </summary>
- InviteeRejectApplyConsultationNotification,
- /// <summary>
- /// MuteLiveConsultationNotification| 27 | 开启关闭静音
- /// </summary>
- MuteLiveConsultationNotification,
- /// <summary>
- /// SwitchLiveConsultationVideoNotification| 28 | 开启关闭视频
- /// </summary>
- SwitchLiveConsultationVideoNotification,
- /// <summary>
- /// HeartRateJoinConsultationNotification| 29 | 会诊心跳,进入房间
- /// </summary>
- HeartRateJoinConsultationNotification,
- /// <summary>
- /// HeartRateLeaveConsultationNotification| 30 | 会诊心跳,离开房间
- /// </summary>
- HeartRateLeaveConsultationNotification,
- /// <summary>
- /// CloseLiveConsultationToDeviceNotification| 31 | 关闭会诊通知 to 设备端
- /// </summary>
- CloseLiveConsultationToDeviceNotification,
- /// <summary>
- /// CancelLiveConsultationToDeviceNotification| 32 | 取消会诊通知 to 设备端
- /// </summary>
- CancelLiveConsultationToDeviceNotification
- }
- class ConnectionNotification {
- NotificationTypeEnum notificationType;
- ConnectionNotification({
- this.notificationType = NotificationTypeEnum.Unknown,
- });
- factory ConnectionNotification.fromJson(Map<String, dynamic> map) {
- return ConnectionNotification(
- notificationType: NotificationTypeEnum.values
- .firstWhere((e) => e.index == map['NotificationType']),
- );
- }
- }
- class DisconnectNotification {
- NotificationTypeEnum notificationType;
- DisconnectNotification({
- this.notificationType = NotificationTypeEnum.Unknown,
- });
- factory DisconnectNotification.fromJson(Map<String, dynamic> map) {
- return DisconnectNotification(
- notificationType: NotificationTypeEnum.values
- .firstWhere((e) => e.index == map['NotificationType']),
- );
- }
- }
|