From dd4447a0290f54cfba8a9391805b2e1113e7243a Mon Sep 17 00:00:00 2001 From: wyf <494641114@qq.com> Date: Tue, 20 Jan 2026 09:26:55 +0800 Subject: [PATCH] =?UTF-8?q?=E5=88=9D=E5=A7=8B=E6=8F=90=E4=BA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .dockerignore | 9 + .flutter-plugins | 8 + .flutter-plugins-dependencies | 1 + .gitignore | 3 + .idea/.gitignore | 8 + CHANGELOG.md | 3 + Dockerfile | 17 + README.md | 49 + analysis_options.yaml | 30 + bin/assets/algConfig.json | 118 ++ bin/const/CommonVariables.dart | 63 + bin/const/Constants.dart | 9 + bin/const/HttpStatusCode.dart | 4 + bin/const/MessageConstants.dart | 10 + bin/const/MessageType.dart | 13 + bin/const/ResponseJsonCode.dart | 4 + bin/const/RuzhuMessageType.dart | 12 + bin/const/ServiceConstant.dart | 37 + bin/controller/AreaController.dart | 241 +++ bin/controller/AreaController.route.dart | 24 + bin/controller/BedController.dart | 181 ++ bin/controller/BedController.route.dart | 30 + bin/controller/BedTypeController.dart | 121 ++ bin/controller/BedTypeController.route.dart | 47 + bin/controller/DictionaryTypeController.dart | 111 ++ .../DictionaryTypeController.route.dart | 47 + bin/controller/DiseaseTypeController.dart | 117 ++ .../DiseaseTypeController.route.dart | 47 + bin/controller/FileUploadController.dart | 98 + .../FileUploadController.route.dart | 14 + bin/controller/PersonController.dart | 114 ++ bin/controller/PersonController.route.dart | 47 + bin/controller/PersonTypeController.dart | 111 ++ .../PersonTypeController.route.dart | 47 + bin/controller/RoomController.dart | 235 +++ bin/controller/RoomController.route.dart | 57 + bin/controller/RoomTypeController.dart | 122 ++ bin/controller/RoomTypeController.route.dart | 47 + bin/enum/BedStatus.dart | 11 + bin/enum/DeviceStatus.dart | 11 + bin/enum/MessageStatus.dart | 13 + bin/enum/ReportStatus.dart | 80 + bin/enum/StatisticsResultType.dart | 11 + bin/enum/StatisticsType.dart | 12 + bin/handler/MqttHandler.dart | 17 + bin/main.dart | 211 ++ bin/model/ApiResponse.dart | 66 + bin/model/ApiResponse.g.dart | 40 + bin/model/Area.dart | 37 + bin/model/Area.g.dart | 40 + bin/model/Bed.dart | 61 + bin/model/Bed.g.dart | 69 + bin/model/BedType.dart | 44 + bin/model/BedType.g.dart | 38 + bin/model/DictionaryType.dart | 36 + bin/model/DictionaryType.g.dart | 32 + bin/model/DiseaseType.dart | 47 + bin/model/DiseaseType.g.dart | 43 + bin/model/Person.dart | 78 + bin/model/Person.g.dart | 90 + bin/model/PersonType.dart | 40 + bin/model/PersonType.g.dart | 39 + bin/model/Reservation.dart | 47 + bin/model/Reservation.g.dart | 49 + bin/model/Room.dart | 52 + bin/model/Room.g.dart | 56 + bin/model/RoomTest.dart | 26 + bin/model/RoomTest.g.dart | 42 + bin/model/RoomType.dart | 47 + bin/model/RoomType.g.dart | 38 + bin/model/StatisticsResult.dart | 33 + bin/model/StatisticsResult.g.dart | 24 + bin/model/Test.dart | 1 + bin/model/WebSocketMessage.dart | 18 + bin/model/WebSocketMessage.g.dart | 25 + bin/model/api_response.dart | 29 + bin/model/app_uri_status.dart | 19 + bin/model/dto/DiseaseStatistics.dart | 27 + bin/model/dto/DiseaseStatistics.g.dart | 20 + bin/repository/AreaRepository.dart | 165 ++ bin/repository/BedRepository.dart | 481 +++++ bin/repository/BedTypeRepository.dart | 191 ++ bin/repository/DictionaryTypeRepository.dart | 149 ++ bin/repository/DiseaseTypeRepository.dart | 209 ++ bin/repository/PersonRepository.dart | 391 ++++ bin/repository/PersonTypeRepository.dart | 136 ++ bin/repository/RoomRepository.dart | 302 +++ bin/repository/RoomTypeRepository.dart | 214 +++ bin/repository/StatisticsRepository.dart | 75 + bin/repository/TestRepository.dart | 9 + bin/service/AreaService copy.dart | 1606 ++++++++++++++++ bin/service/AreaService.dart | 1692 +++++++++++++++++ bin/service/BedService.dart | 124 ++ bin/service/BedTypeService.dart | 38 + bin/service/DictionaryService.dart | 22 + bin/service/DiseaseTypeService.dart | 43 + bin/service/InstantAlarmService.dart | 12 + bin/service/PersonService.dart | 64 + bin/service/PersonTypeService.dart | 33 + bin/service/RoomService.dart | 336 ++++ bin/service/RoomTypeService.dart | 38 + bin/service/TokenService.dart | 14 + bin/util/MyUtils.dart | 95 + bin/util/requestWithLog.dart | 102 + pubspec.lock | 1132 +++++++++++ pubspec.yaml | 42 + 106 files changed, 11690 insertions(+) create mode 100644 .dockerignore create mode 100644 .flutter-plugins create mode 100644 .flutter-plugins-dependencies create mode 100644 .gitignore create mode 100644 .idea/.gitignore create mode 100644 CHANGELOG.md create mode 100644 Dockerfile create mode 100644 README.md create mode 100644 analysis_options.yaml create mode 100644 bin/assets/algConfig.json create mode 100644 bin/const/CommonVariables.dart create mode 100644 bin/const/Constants.dart create mode 100644 bin/const/HttpStatusCode.dart create mode 100644 bin/const/MessageConstants.dart create mode 100644 bin/const/MessageType.dart create mode 100644 bin/const/ResponseJsonCode.dart create mode 100644 bin/const/RuzhuMessageType.dart create mode 100644 bin/const/ServiceConstant.dart create mode 100644 bin/controller/AreaController.dart create mode 100644 bin/controller/AreaController.route.dart create mode 100644 bin/controller/BedController.dart create mode 100644 bin/controller/BedController.route.dart create mode 100644 bin/controller/BedTypeController.dart create mode 100644 bin/controller/BedTypeController.route.dart create mode 100644 bin/controller/DictionaryTypeController.dart create mode 100644 bin/controller/DictionaryTypeController.route.dart create mode 100644 bin/controller/DiseaseTypeController.dart create mode 100644 bin/controller/DiseaseTypeController.route.dart create mode 100644 bin/controller/FileUploadController.dart create mode 100644 bin/controller/FileUploadController.route.dart create mode 100644 bin/controller/PersonController.dart create mode 100644 bin/controller/PersonController.route.dart create mode 100644 bin/controller/PersonTypeController.dart create mode 100644 bin/controller/PersonTypeController.route.dart create mode 100644 bin/controller/RoomController.dart create mode 100644 bin/controller/RoomController.route.dart create mode 100644 bin/controller/RoomTypeController.dart create mode 100644 bin/controller/RoomTypeController.route.dart create mode 100644 bin/enum/BedStatus.dart create mode 100644 bin/enum/DeviceStatus.dart create mode 100644 bin/enum/MessageStatus.dart create mode 100644 bin/enum/ReportStatus.dart create mode 100644 bin/enum/StatisticsResultType.dart create mode 100644 bin/enum/StatisticsType.dart create mode 100644 bin/handler/MqttHandler.dart create mode 100644 bin/main.dart create mode 100644 bin/model/ApiResponse.dart create mode 100644 bin/model/ApiResponse.g.dart create mode 100644 bin/model/Area.dart create mode 100644 bin/model/Area.g.dart create mode 100644 bin/model/Bed.dart create mode 100644 bin/model/Bed.g.dart create mode 100644 bin/model/BedType.dart create mode 100644 bin/model/BedType.g.dart create mode 100644 bin/model/DictionaryType.dart create mode 100644 bin/model/DictionaryType.g.dart create mode 100644 bin/model/DiseaseType.dart create mode 100644 bin/model/DiseaseType.g.dart create mode 100644 bin/model/Person.dart create mode 100644 bin/model/Person.g.dart create mode 100644 bin/model/PersonType.dart create mode 100644 bin/model/PersonType.g.dart create mode 100644 bin/model/Reservation.dart create mode 100644 bin/model/Reservation.g.dart create mode 100644 bin/model/Room.dart create mode 100644 bin/model/Room.g.dart create mode 100644 bin/model/RoomTest.dart create mode 100644 bin/model/RoomTest.g.dart create mode 100644 bin/model/RoomType.dart create mode 100644 bin/model/RoomType.g.dart create mode 100644 bin/model/StatisticsResult.dart create mode 100644 bin/model/StatisticsResult.g.dart create mode 100644 bin/model/Test.dart create mode 100644 bin/model/WebSocketMessage.dart create mode 100644 bin/model/WebSocketMessage.g.dart create mode 100644 bin/model/api_response.dart create mode 100644 bin/model/app_uri_status.dart create mode 100644 bin/model/dto/DiseaseStatistics.dart create mode 100644 bin/model/dto/DiseaseStatistics.g.dart create mode 100644 bin/repository/AreaRepository.dart create mode 100644 bin/repository/BedRepository.dart create mode 100644 bin/repository/BedTypeRepository.dart create mode 100644 bin/repository/DictionaryTypeRepository.dart create mode 100644 bin/repository/DiseaseTypeRepository.dart create mode 100644 bin/repository/PersonRepository.dart create mode 100644 bin/repository/PersonTypeRepository.dart create mode 100644 bin/repository/RoomRepository.dart create mode 100644 bin/repository/RoomTypeRepository.dart create mode 100644 bin/repository/StatisticsRepository.dart create mode 100644 bin/repository/TestRepository.dart create mode 100644 bin/service/AreaService copy.dart create mode 100644 bin/service/AreaService.dart create mode 100644 bin/service/BedService.dart create mode 100644 bin/service/BedTypeService.dart create mode 100644 bin/service/DictionaryService.dart create mode 100644 bin/service/DiseaseTypeService.dart create mode 100644 bin/service/InstantAlarmService.dart create mode 100644 bin/service/PersonService.dart create mode 100644 bin/service/PersonTypeService.dart create mode 100644 bin/service/RoomService.dart create mode 100644 bin/service/RoomTypeService.dart create mode 100644 bin/service/TokenService.dart create mode 100644 bin/util/MyUtils.dart create mode 100644 bin/util/requestWithLog.dart create mode 100644 pubspec.lock create mode 100644 pubspec.yaml diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..21504f8 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,9 @@ +.dockerignore +Dockerfile +build/ +.dart_tool/ +.git/ +.github/ +.gitignore +.idea/ +.packages diff --git a/.flutter-plugins b/.flutter-plugins new file mode 100644 index 0000000..53c1de5 --- /dev/null +++ b/.flutter-plugins @@ -0,0 +1,8 @@ +# This is a generated file; do not edit or check into version control. +file_picker=D:\\flutters\\hosted\\pub.flutter-io.cn\\file_picker-8.3.7\\ +flutter_plugin_android_lifecycle=D:\\flutters\\hosted\\pub.flutter-io.cn\\flutter_plugin_android_lifecycle-2.0.26\\ +path_provider=D:\\flutters\\hosted\\pub.flutter-io.cn\\path_provider-2.1.5\\ +path_provider_android=D:\\flutters\\hosted\\pub.flutter-io.cn\\path_provider_android-2.2.15\\ +path_provider_foundation=D:\\flutters\\hosted\\pub.flutter-io.cn\\path_provider_foundation-2.4.1\\ +path_provider_linux=D:\\flutters\\hosted\\pub.flutter-io.cn\\path_provider_linux-2.2.1\\ +path_provider_windows=D:\\flutters\\hosted\\pub.flutter-io.cn\\path_provider_windows-2.3.0\\ diff --git a/.flutter-plugins-dependencies b/.flutter-plugins-dependencies new file mode 100644 index 0000000..f569d31 --- /dev/null +++ b/.flutter-plugins-dependencies @@ -0,0 +1 @@ +{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"file_picker","path":"D:\\\\flutters\\\\hosted\\\\pub.flutter-io.cn\\\\file_picker-8.3.7\\\\","native_build":true,"dependencies":[]},{"name":"path_provider_foundation","path":"D:\\\\flutters\\\\hosted\\\\pub.flutter-io.cn\\\\path_provider_foundation-2.4.1\\\\","shared_darwin_source":true,"native_build":true,"dependencies":[]}],"android":[{"name":"file_picker","path":"D:\\\\flutters\\\\hosted\\\\pub.flutter-io.cn\\\\file_picker-8.3.7\\\\","native_build":true,"dependencies":["flutter_plugin_android_lifecycle"]},{"name":"flutter_plugin_android_lifecycle","path":"D:\\\\flutters\\\\hosted\\\\pub.flutter-io.cn\\\\flutter_plugin_android_lifecycle-2.0.26\\\\","native_build":true,"dependencies":[]},{"name":"path_provider_android","path":"D:\\\\flutters\\\\hosted\\\\pub.flutter-io.cn\\\\path_provider_android-2.2.15\\\\","native_build":true,"dependencies":[]}],"macos":[{"name":"file_picker","path":"D:\\\\flutters\\\\hosted\\\\pub.flutter-io.cn\\\\file_picker-8.3.7\\\\","native_build":true,"dependencies":[]},{"name":"path_provider_foundation","path":"D:\\\\flutters\\\\hosted\\\\pub.flutter-io.cn\\\\path_provider_foundation-2.4.1\\\\","shared_darwin_source":true,"native_build":true,"dependencies":[]}],"linux":[{"name":"file_picker","path":"D:\\\\flutters\\\\hosted\\\\pub.flutter-io.cn\\\\file_picker-8.3.7\\\\","native_build":false,"dependencies":[]},{"name":"path_provider_linux","path":"D:\\\\flutters\\\\hosted\\\\pub.flutter-io.cn\\\\path_provider_linux-2.2.1\\\\","native_build":false,"dependencies":[]}],"windows":[{"name":"file_picker","path":"D:\\\\flutters\\\\hosted\\\\pub.flutter-io.cn\\\\file_picker-8.3.7\\\\","native_build":false,"dependencies":[]},{"name":"path_provider_windows","path":"D:\\\\flutters\\\\hosted\\\\pub.flutter-io.cn\\\\path_provider_windows-2.3.0\\\\","native_build":false,"dependencies":[]}],"web":[{"name":"file_picker","path":"D:\\\\flutters\\\\hosted\\\\pub.flutter-io.cn\\\\file_picker-8.3.7\\\\","dependencies":[]}]},"dependencyGraph":[{"name":"file_picker","dependencies":["flutter_plugin_android_lifecycle"]},{"name":"flutter_plugin_android_lifecycle","dependencies":[]},{"name":"path_provider","dependencies":["path_provider_android","path_provider_foundation","path_provider_linux","path_provider_windows"]},{"name":"path_provider_android","dependencies":[]},{"name":"path_provider_foundation","dependencies":[]},{"name":"path_provider_linux","dependencies":[]},{"name":"path_provider_windows","dependencies":[]}],"date_created":"2026-01-17 10:13:16.955655","version":"3.24.4","swift_package_manager_enabled":false} \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3a85790 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +# https://dart.dev/guides/libraries/private-files +# Created by `dart pub` +.dart_tool/ diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..35410ca --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# 默认忽略的文件 +/shelf/ +/workspace.xml +# 基于编辑器的 HTTP 客户端请求 +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..effe43c --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,3 @@ +## 1.0.0 + +- Initial version. diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..6657431 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,17 @@ +# Use latest stable channel SDK. +FROM dart:3.5.4 AS build +LABEL qmqz=admin@ipayl.com + +# Resolve app dependencies. +WORKDIR /app +COPY pubspec.* ./ +RUN dart pub get + +ADD bin /app/bin +RUN dart compile exe bin/main.dart -o bin/server + +FROM scratch +COPY --from=build /runtime/ / +COPY --from=build /app/bin/server /app/bin/ + +CMD ["/app/bin/server"] \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..e695d9d --- /dev/null +++ b/README.md @@ -0,0 +1,49 @@ +A server app built using [Shelf](https://pub.dev/packages/shelf), +configured to enable running with [Docker](https://www.docker.com/). + +This sample code handles HTTP GET requests to `/` and `/echo/` + +# Running the sample + +## Running with the Dart SDK + +You can run the example with the [Dart SDK](https://dart.dev/get-dart) +like this: + +``` +$ dart run bin/server.dart +Server listening on port 8080 +``` + +And then from a second terminal: +``` +$ curl http://0.0.0.0:8080 +Hello, World! +$ curl http://0.0.0.0:8080/echo/I_love_Dart +I_love_Dart +``` + +## Running with Docker + +If you have [Docker Desktop](https://www.docker.com/get-started) installed, you +can build and run with the `docker` command: + +``` +$ docker build . -t myserver +$ docker run -it -p 8080:8080 myserver +Server listening on port 8080 +``` + +And then from a second terminal: +``` +$ curl http://0.0.0.0:8080 +Hello, World! +$ curl http://0.0.0.0:8080/echo/I_love_Dart +I_love_Dart +``` + +You should see the logging printed in the first terminal: +``` +2021-05-06T15:47:04.620417 0:00:00.000158 GET [200] / +2021-05-06T15:47:08.392928 0:00:00.001216 GET [200] /echo/I_love_Dart +``` diff --git a/analysis_options.yaml b/analysis_options.yaml new file mode 100644 index 0000000..dee8927 --- /dev/null +++ b/analysis_options.yaml @@ -0,0 +1,30 @@ +# This file configures the static analysis results for your project (errors, +# warnings, and lints). +# +# This enables the 'recommended' set of lints from `package:lints`. +# This set helps identify many issues that may lead to problems when running +# or consuming Dart code, and enforces writing Dart using a single, idiomatic +# style and format. +# +# If you want a smaller set of lints you can change this to specify +# 'package:lints/core.yaml'. These are just the most critical lints +# (the recommended set includes the core lints). +# The core lints are also what is used by pub.dev for scoring packages. + +include: package:lints/recommended.yaml + +# Uncomment the following section to specify additional rules. + +# linter: +# rules: +# - camel_case_types + +# analyzer: +# exclude: +# - path/to/excluded/files/** + +# For more information about the core and recommended set of lints, see +# https://dart.dev/go/core-lints + +# For additional information about configuring this file, see +# https://dart.dev/guides/language/analysis-options diff --git a/bin/assets/algConfig.json b/bin/assets/algConfig.json new file mode 100644 index 0000000..12f88ad --- /dev/null +++ b/bin/assets/algConfig.json @@ -0,0 +1,118 @@ +[ + { + "id": 1, + "name": "心率预警", + "level": 1, + "cond": [ + { + "field": "heartRate", + "min": 50, + "max": 110 + } + ], + "startTime": "9:00", + "endTime": "9:00", + "triggerCount": 5, + "interval": 30, + "enable": true, + "type": 1, + "dataType": 1 + }, + { + "id": 2, + "name": "呼吸预警", + "level": 1, + "cond": [ + { + "field": "breathRate", + "min": 7, + "max": 30 + } + ], + "startTime": "9:00", + "endTime": "9:00", + "triggerCount": 5, + "interval": 30, + "enable": true, + "type": 2, + "dataType": 1 + } +, + { + "id": 3, + "name": "睡眠异常", + "level": 2, + "cond": [ + { + "field": "sleepScore.score", + "min": 51 + } + ], + "startTime": "9:00", + "endTime": "9:00", + "triggerCount": 0, + "interval": 30, + "enable": true, + "type": 3, + "dataType": 2 + } +, + { + "id": 4, + "name": "呼吸暂停", + "level": 1, + "cond": [ + { + "field": "breathStat.typeList id=306=value", + "max": 3 + } + ], + "startTime": "18:00", + "endTime": "9:00", + "triggerCount": 0, + "interval": 30, + "enable": true, + "type": 2, + "dataType": 2 + } +, + { + "id": 5, + "name": "离床过长", + "level": 2, + "cond": [ + { + "field": "inBed", + "value": "离床" + } + ], + "startTime": "9:00", + "endTime": "9:00", + "triggerCount": 600, + "interval": 30, + "enable": false, + "type": 5, + "dataType": 1 + } +, + { + "id": 6, + "name": "心率骤停", + "level": 1, + "cond": [ + { + "field": "heartRate", + "min": 1 + } + ], + "startTime": "9:00", + "endTime": "9:00", + "triggerCount": 60, + "interval": 30, + "enable": false, + "process": true, + "pd": [5,7,15], + "type": 5, + "dataType": 1 + } +] \ No newline at end of file diff --git a/bin/const/CommonVariables.dart b/bin/const/CommonVariables.dart new file mode 100644 index 0000000..b329da2 --- /dev/null +++ b/bin/const/CommonVariables.dart @@ -0,0 +1,63 @@ +class CommonVariables { + static bool isNetWorkOn = false; + static String supabaseUrl = "https://zhmht.swes.com.cn:3443"; + // 企业微信客服拉起的url地址 + // static String wxKfUrl = "https://work.weixin.qq.com/kfid/kfcab6a07e8aac68945"; + static String wxKfUrl = "https://work.weixin.qq.com/kfid/kfc7d2337b9c07b1269"; + // 企业微信ID + // static String wxCorpId = "wwc17348c75dbde1dc"; + static String wxCorpId = "ww51feda6026280cd0"; + //ICP备案号 + static String ICPRightCode = "皖ICP备2024068219号-1A"; + //公司名称 + static String enterpriseName = "合肥眠花糖家具有限责任公司"; + //备案时间 + static String ICPTime = "2019-2029"; + static String shoph5Url = "https://zhmht.swes.com.cn:1443"; + + static Map callMap = {}; + + static const String weather_apiKey = + '40e23445cf0a29561af2b5b7d506a38b'; // 替换为你的 API 密钥 + static String shareText = "您的朋友邀请您使用《智慧眠花糖》APP,请复制后面链接在浏览器中打开! " + + shoph5Url + + "/#/pages/download/download"; + + //容器圆角 + static double filter_selector_border_radius = 50; + static double slider_container_border_radius = 10; + static double dialog_selector_border_radius = 6; + + //列表数据(X秒内为刚刚数据) + static int recent_data_time = 60 * 5; + + //表格间距 + static int form_padding_small = 1; + static int form_padding_medium = 5; + static int form_padding_large = 8; + + //内容容器最小高度百分比 + static double text_height_small_percent = 0.036; //注释 + static double text_height_medium_percent = 0.037; //正文 + static double text_height_large_percent = 0.046; //标题/搜索栏 + static double text_height_more_large_percent = 0.074; //菜单 + static double icon_height_medium_percent = 0.014; //icon + + static int default_page = 1; + static int default_limit_max = 999999; + static int default_limit = 10; + + //下拉最大高度 + static double dropdown_max_height = 200; + + //详情弹窗左边字段显示宽度百分比 + static double dialog_attribute_width_percent = 0.15; + + static String default_gender = "1"; + static bool default_vibrate = true; + static int default_weight = 65; + static int default_age = 30; + static String default_phone = "18612345678"; + static int default_height = 170; + static String default_username = "眠眠"; +} diff --git a/bin/const/Constants.dart b/bin/const/Constants.dart new file mode 100644 index 0000000..7fd03ad --- /dev/null +++ b/bin/const/Constants.dart @@ -0,0 +1,9 @@ +class Constants { + static const int port = 9200; + static const String serviceName = "vsbs_room"; + + static int default_page = 1; + static int default_limit_max = 999999; + static int default_limit = 10; + +} diff --git a/bin/const/HttpStatusCode.dart b/bin/const/HttpStatusCode.dart new file mode 100644 index 0000000..e426c5b --- /dev/null +++ b/bin/const/HttpStatusCode.dart @@ -0,0 +1,4 @@ +class HttpStatusCode { + static const int ok = 200; // 请求成功,服务器已返回请求的数据。 + static const int internalServerError = 500; // 服务器内部错误。 +} diff --git a/bin/const/MessageConstants.dart b/bin/const/MessageConstants.dart new file mode 100644 index 0000000..bda1d81 --- /dev/null +++ b/bin/const/MessageConstants.dart @@ -0,0 +1,10 @@ +class MessageConstants { + // 成功提示 + static const String DELETE_ERROR = "删除失败,请联系管理员"; + static const String UPDATE_ERROR = "更新失败,请联系管理员"; + static const String ADD_ERROR = "添加失败,请联系管理员"; + + static const String ADD_SUCCESS = "添加成功"; + static const String UPDATE_SUCCESS = "更新成功"; + static const String DELETE_SUCCESS = "删除成功"; +} diff --git a/bin/const/MessageType.dart b/bin/const/MessageType.dart new file mode 100644 index 0000000..735e843 --- /dev/null +++ b/bin/const/MessageType.dart @@ -0,0 +1,13 @@ +enum MessageType { + instant_alarm("1", "实时体征消息"), // 实时体征消息 + check_in("2", "入住消息"), // 入住消息 + service("3", "服务消息"), // 服务消息 + system("4", "系统消息"); // 系统消息 + + // 枚举的值 + final String code; // 整数值 + final String description; // 字符串描述 + + // 构造函数 + const MessageType(this.code, this.description); +} \ No newline at end of file diff --git a/bin/const/ResponseJsonCode.dart b/bin/const/ResponseJsonCode.dart new file mode 100644 index 0000000..acb36be --- /dev/null +++ b/bin/const/ResponseJsonCode.dart @@ -0,0 +1,4 @@ +class ResponseJsonCode { + static const int success = 200; // 操作成功 + static const int fail = 400; // 操作失败 +} diff --git a/bin/const/RuzhuMessageType.dart b/bin/const/RuzhuMessageType.dart new file mode 100644 index 0000000..a022932 --- /dev/null +++ b/bin/const/RuzhuMessageType.dart @@ -0,0 +1,12 @@ +enum RuzhuMessageType { + reservation("1", "预约消息"), // 预约消息 + check_in("2", "入住消息"), // 入住消息 + check_out("3", "退住消息"); // 退住消息 + + // 枚举的值 + final String code; // 整数值 + final String description; // 字符串描述 + + // 构造函数 + const RuzhuMessageType(this.code, this.description); +} diff --git a/bin/const/ServiceConstant.dart b/bin/const/ServiceConstant.dart new file mode 100644 index 0000000..40114d7 --- /dev/null +++ b/bin/const/ServiceConstant.dart @@ -0,0 +1,37 @@ +class ServiceConstant { + //基础地址 + // static const String baseHost = "vsbs.he-info.cn"; + static const String baseHost = "vsbst-api.he-info.cn"; + static const String apibaseHost = "songxia.he-info.com"; + //服务地址 + static String service_address = "https://$apibaseHost"; + static String web_service_address = "https://$baseHost"; + static String app_server_service = "/wx/app/bizreport/app"; //服务名称 + //服务名称及api + //房间类型 + //房间 + static const String room_service = "/vsbs_room"; + static const String room_list = "/room/roomList"; //房间列表 + static const String disease_range_data = "/statistics/disease"; + //日志 + static String logService = "$web_service_address/vsbs_log"; + //websocket网关 + static const String webSocketService = "wss://$baseHost/vsbs_ws_gateway/ws"; + //数据中心 + static String dataCenterService = "$service_address/vsbs_data_center"; + static const String sleepReportData = "/api/sleep/data/list"; //睡眠报告数据 + //机构数据 + static String agency_service = "$service_address/vsbs_agency"; //机构服务 + static const String agency_list = "/agency/allAgencyList"; //获取机构列表 + + //用户中心 + static String userCenterService = "$service_address/vsbs_user_center"; + //添加报警 + static const String addMessage = "/api/message/info"; + static const String message_service = "/vsbs_message_center"; + static const String message_list = "/api/message/info"; //查询消息 + + set serviceAddress(String host) { + service_address = host; + } +} diff --git a/bin/controller/AreaController.dart b/bin/controller/AreaController.dart new file mode 100644 index 0000000..06245e9 --- /dev/null +++ b/bin/controller/AreaController.dart @@ -0,0 +1,241 @@ +import 'dart:convert'; + +import 'package:EasyDartModule/EasyDartModule.dart'; +import 'package:EasyDartModule/base/webserver/WebServer.dart'; + +import '../const/HttpStatusCode.dart'; +import '../const/MessageConstants.dart'; +import '../const/ResponseJsonCode.dart'; +import '../model/ApiResponse.dart'; +import '../service/AreaService.dart'; + +part 'AreaController.route.dart'; + +@RequestMapping(path: "/report") +class AreaController { + final AreaService areaService = AreaService(); + set callHandler(handler) => _callHandler = handler; + Map> get routeMap => routes; + + AreaController(); + + // 获取实时数据 + @RequestMapping(path: "/getInstantData", method: HttpMethod.GET,auth: false) + Future getInstantData( + Request request, Map jwt) async { + ApiResponse apiResponse = ApiResponse(); + + try { + var queryParameters = request.requestedUri.queryParameters; + String? mac = queryParameters['mac']; + String? openId = queryParameters['openId']; + + if (mac == null || mac.isEmpty) { + apiResponse.code = ResponseJsonCode.fail; + apiResponse.message = "查询失败,设备mac不能为空"; + return Response( + HttpStatusCode.ok, + body: apiResponse.serialize(), + ); + } + if (openId == null || openId.isEmpty) { + apiResponse.code = ResponseJsonCode.fail; + apiResponse.message = "查询失败,设备openId不能为空"; + return Response( + HttpStatusCode.ok, + body: apiResponse.serialize(), + ); + } + Map result = await areaService.getInstantData(mac,openId); + if (result['flag'] == 1) { + // 成功 + // apiResponse.code = ResponseJsonCode.success; + // apiResponse.message = result['msg'] ?? "查询成功"; + // apiResponse.data = result['data']; + apiResponse.code = ResponseJsonCode.success; + apiResponse.message = result['msg'] ?? "查询成功"; + + // 2. 将 result['data'] 包装成 List> + if (result['data'] != null) { + // result['data'] 是一个 Map,包装成 List + Map dataMap = + Map.from(result['data']); + + // 可以在这里添加一些额外字段(可选) + dataMap['responseTime'] = DateTime.now().millisecondsSinceEpoch; + + // 将单个 Map 放入 List 中 + apiResponse.data = [dataMap]; + } else { + apiResponse.data = []; + } + } else { + // 失败 + apiResponse.code = ResponseJsonCode.fail; + apiResponse.message = result['msg'] ?? "查询失败"; + apiResponse.data = null; + } + + return Response( + HttpStatusCode.ok, + body: apiResponse.serialize(), + ); + } catch (e) { + apiResponse.code = ResponseJsonCode.fail; + apiResponse.message = "查询失败: $e"; + return Response( + HttpStatusCode.internalServerError, + body: apiResponse.serialize(), + ); + } + } + + // 开始体验设备 + @RequestMapping(path: "/start", method: HttpMethod.POST,auth: false) + Future start(Request request) async { + ApiResponse apiResponse = ApiResponse(); + + try { + var data = jsonDecode(await request.readAsString()); + + if (data == null || data.isEmpty || data['mac'] == null) { + apiResponse.code = ResponseJsonCode.fail; + apiResponse.message = "请求失败,设备mac不能为空"; + return Response( + HttpStatusCode.ok, + body: apiResponse.serialize(), + ); + } + if (data == null || data.isEmpty || data['openId'] == null) { + apiResponse.code = ResponseJsonCode.fail; + apiResponse.message = "请求失败,设备openId不能为空"; + return Response( + HttpStatusCode.ok, + body: apiResponse.serialize(), + ); + } + + Map result = await areaService.startKuaijian(data); + if (result['flag'] == 1) { + apiResponse.code = ResponseJsonCode.success; + apiResponse.message = result['msg'] ?? MessageConstants.ADD_SUCCESS; + } else { + apiResponse.code = ResponseJsonCode.fail; + apiResponse.message = result['msg'] ?? "操作失败"; + } + + return Response( + HttpStatusCode.ok, + body: apiResponse.serialize(), + ); + } catch (e) { + apiResponse.code = ResponseJsonCode.fail; + apiResponse.message = "添加失败: $e"; + return Response( + HttpStatusCode.internalServerError, + body: apiResponse.serialize(), + ); + } + } + + // 结束体验设备 + @RequestMapping(path: "/end", method: HttpMethod.POST,auth: false) + Future end(Request request) async { + ApiResponse apiResponse = ApiResponse(); + + try { + var data = jsonDecode(await request.readAsString()); + if (data == null || data.isEmpty || data['mac'] == null) { + apiResponse.code = ResponseJsonCode.fail; + apiResponse.message = "请求失败,设备mac不能为空"; + return Response( + HttpStatusCode.ok, + body: apiResponse.serialize(), + ); + } + if (data == null || data.isEmpty || data['openId'] == null) { + apiResponse.code = ResponseJsonCode.fail; + apiResponse.message = "请求失败,设备openId不能为空"; + return Response( + HttpStatusCode.ok, + body: apiResponse.serialize(), + ); + } + + Map result = await areaService.endKuaijian(data); + if (result['flag'] == 1) { + apiResponse.code = ResponseJsonCode.success; + apiResponse.message = result['msg'] ?? MessageConstants.ADD_SUCCESS; + } else { + apiResponse.code = ResponseJsonCode.fail; + apiResponse.message = result['msg'] ?? "操作失败"; + } + + return Response( + HttpStatusCode.ok, + body: apiResponse.serialize(), + ); + } catch (e) { + apiResponse.code = ResponseJsonCode.fail; + apiResponse.message = "添加失败: $e"; + return Response( + HttpStatusCode.internalServerError, + body: apiResponse.serialize(), + ); + } + } + + // // 更新区域 + // @RequestMapping(path: "/updateArea", method: HttpMethod.PUT) + // Future updateArea(Request request) async { + // ApiResponse apiResponse = ApiResponse(); + // try { + // var data = jsonDecode(await request.readAsString()); + // var areaId = data['_id']; + // var updatedArea = Area.fromJson(data); + // if (updatedArea.id == null || updatedArea.id!.isEmpty) { + // apiResponse.code = ResponseJsonCode.fail; + // apiResponse.message = "区域ID不能为空"; + // String serializedJson = apiResponse.serialize(); + // return Response(HttpStatusCode.ok, body: serializedJson); + // } + // var result = await areaService.updateArea(areaId, updatedArea); + // apiResponse.code = 1; + // apiResponse.message = result; + // String serializedJson = apiResponse.serialize(); + // return Response(200, body: serializedJson); // 发送成功响应 + // } catch (e) { + // apiResponse.code = -1; + // apiResponse.message = "更新失败: $e"; // 包含异常信息 + // String serializedJson = apiResponse.serialize(); + // return Response(500, body: serializedJson); // 发送失败响应 + // } + // } + + // 删除区域 + // @RequestMapping(path: "/deleteArea", method: HttpMethod.DELETE) + // Future deleteArea(Request request) async { + // ApiResponse apiResponse = ApiResponse(); + // try { + // var data = jsonDecode(await request.readAsString()); + // var areaId = data['areaId']; + // var result = await areaService.deleteArea(areaId); + // apiResponse.code = 1; + // if (result.isEmpty) { + // apiResponse.code = ResponseJsonCode.success; + // apiResponse.message = MessageConstants.DELETE_SUCCESS; + // String serializedJson = apiResponse.serialize(); + // return Response(HttpStatusCode.ok, body: serializedJson); // 发送成功响应 + // } + // apiResponse.code = ResponseJsonCode.fail; + // apiResponse.message = result; + // String serializedJson = apiResponse.serialize(); + // return Response(HttpStatusCode.ok, body: serializedJson); + // } catch (e) { + // apiResponse.code = -1; + // apiResponse.message = "删除失败: $e"; // 包含异常信息 + // String serializedJson = apiResponse.serialize(); + // return Response(500, body: serializedJson); // 发送失败响应 + // } + // } +} diff --git a/bin/controller/AreaController.route.dart b/bin/controller/AreaController.route.dart new file mode 100644 index 0000000..e0a97c1 --- /dev/null +++ b/bin/controller/AreaController.route.dart @@ -0,0 +1,24 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +// ************************************************************************** +// RouteGenerator +// ************************************************************************** + +part of 'AreaController.dart'; + +late var _callHandler; +final Map> routes = { + HttpMethod.GET: [ + [ + "/report/getInstantData", + HttpResponseType.JSON, + _callHandler.getInstantData, + 2, + false + ] + ], + HttpMethod.POST: [ + ["/report/start", HttpResponseType.JSON, _callHandler.start, 1, false], + ["/report/end", HttpResponseType.JSON, _callHandler.end, 1, false] + ], +}; diff --git a/bin/controller/BedController.dart b/bin/controller/BedController.dart new file mode 100644 index 0000000..d18be46 --- /dev/null +++ b/bin/controller/BedController.dart @@ -0,0 +1,181 @@ +import 'dart:convert'; + +import 'package:EasyDartModule/EasyDartModule.dart'; +import 'package:EasyDartModule/base/webserver/WebServer.dart'; + +import '../const/HttpStatusCode.dart'; +import '../const/MessageConstants.dart'; +import '../const/ResponseJsonCode.dart'; +import '../model/ApiResponse.dart'; +import '../model/Bed.dart'; +import '../service/BedService.dart'; +import '../model/Reservation.dart'; + +part 'BedController.route.dart'; +@RequestMapping(path: "/bed") +class BedController { + final BedService bedService = BedService(); + set callHandler(handler) => _callHandler = handler; + Map> get routeMap => routes; + + BedController(); + + // 获取床位列表 + @RequestMapping(path: "/bedList", method: HttpMethod.GET) + Future getBedList(Request request, Map jwt) async { + ApiResponse>> apiResponse = ApiResponse(); + try { + var queryParameters = request.requestedUri.queryParameters; + Bed query = Bed.fromQueryParameters(queryParameters,jwt); + List bedList = await bedService.getBedList(query); + int bedCount = await bedService.getBedCount(query); + List> bedListMap = + bedList.map((e) => e as Map).toList(); // 强制转换 + apiResponse.code = ResponseJsonCode.success; + apiResponse.data = bedListMap; + apiResponse.total = bedCount; + String serializedJson = apiResponse.serialize(); + return Response(HttpStatusCode.ok, body: serializedJson); // 发送响应 + } catch (e) { + apiResponse.code = ResponseJsonCode.fail; + apiResponse.message = "查询失败: $e"; // 包含异常信息 + String serializedJson = apiResponse.serialize(); + return Response(HttpStatusCode.internalServerError, body: serializedJson); + } + } + + // 获取单个床位信息 + /* @RequestMapping(path: "/getBed", method: HttpMethod.GET) + Future getBedById(Request request) async { + ApiResponse> apiResponse = ApiResponse(); + try { + var data = jsonDecode(await request.readAsString()); + var bedId = data['bed_id']; + if (bedId == null) { + apiResponse.code = ResponseJsonCode.fail; + apiResponse.message = '床位ID不能为空'; + String serializedJson = apiResponse.serialize(); + return Response(HttpStatusCode.ok, body: serializedJson); // 发送错误响应 + } + var bed = await bedService.getBedById(bedId); + if (bed != null) { + apiResponse.code = ResponseJsonCode.success; + apiResponse.data = bed.toJson(); + String serializedJson = apiResponse.serialize(); + return Response(HttpStatusCode.ok, body: serializedJson); // 发送成功响应 + } else { + apiResponse.code = ResponseJsonCode.fail; + apiResponse.message = '未找到床位'; + String serializedJson = apiResponse.serialize(); + return Response(HttpStatusCode.ok, body: serializedJson); // 发送未找到响应 + } + } catch (e) { + apiResponse.code = ResponseJsonCode.fail; + apiResponse.message = '查询失败: $e'; + String serializedJson = apiResponse.serialize(); + return Response(HttpStatusCode.internalServerError, + body: serializedJson); // 发送失败响应 + } + } */ + + // 添加床位信息 + @RequestMapping(path: "/addBed", method: HttpMethod.POST) + Future addBed(Request request) async { + ApiResponse apiResponse = ApiResponse(); + try { + var data = jsonDecode(await request.readAsString()); + var bed = Bed.fromJson(data); + var result = await bedService.createBed(bed); + apiResponse.code = ResponseJsonCode.success; + apiResponse.message = MessageConstants.ADD_SUCCESS; + String serializedJson = apiResponse.serialize(); + return Response(HttpStatusCode.ok, body: serializedJson); // 发送成功响应 + } catch (e) { + apiResponse.code = ResponseJsonCode.fail; + apiResponse.message = MessageConstants.ADD_ERROR; // 包含异常信息 + String serializedJson = apiResponse.serialize(); + return Response(HttpStatusCode.internalServerError, + body: serializedJson); // 发送失败响应 + } + } + + // 更新床位信息 + @RequestMapping(path: "/updateBed", method: HttpMethod.PUT) + Future updateBed(Request request) async { + ApiResponse apiResponse = ApiResponse(); + try { + var data = jsonDecode(await request.readAsString()); + var bedId = data['bed_id']; + var updatedBed = Bed.fromJson(data); + if (updatedBed.id == null || updatedBed.id!.isEmpty) { + apiResponse.code = ResponseJsonCode.fail; + apiResponse.message = "床位ID不能为空"; + String serializedJson = apiResponse.serialize(); + return Response(HttpStatusCode.ok, body: serializedJson); + } + var result = await bedService.updateBed(bedId, updatedBed); + apiResponse.code = ResponseJsonCode.success; + apiResponse.message = result; + String serializedJson = apiResponse.serialize(); + return Response(HttpStatusCode.ok, body: serializedJson); // 发送成功响应 + } catch (e) { + apiResponse.code = ResponseJsonCode.fail; + apiResponse.message = "更新失败: $e"; // 包含异常信息 + String serializedJson = apiResponse.serialize(); + return Response(HttpStatusCode.internalServerError, + body: serializedJson); // 发送失败响应 + } + } + + // 删除床位信息 + @RequestMapping(path: "/deleteBed", method: HttpMethod.DELETE) + Future deleteBed(Request request) async { + ApiResponse apiResponse = ApiResponse(); + try { + var data = jsonDecode(await request.readAsString()); + var bedId = data['bed_id']; + var result = await bedService.deleteBed(bedId); + if (result.isEmpty) { + apiResponse.code = ResponseJsonCode.success; + apiResponse.message = MessageConstants.DELETE_SUCCESS; + String serializedJson = apiResponse.serialize(); + return Response(HttpStatusCode.ok, body: serializedJson); // 发送成功响应 + } + apiResponse.code = ResponseJsonCode.fail; + apiResponse.message = result; + String serializedJson = apiResponse.serialize(); + return Response(HttpStatusCode.ok, body: serializedJson); + } catch (e) { + apiResponse.code = ResponseJsonCode.fail; + apiResponse.message = MessageConstants.DELETE_ERROR; // 包含异常信息 + String serializedJson = apiResponse.serialize(); + return Response(HttpStatusCode.internalServerError, + body: serializedJson); // 发送失败响应 + } + } + + + // 查询预约信息 + @RequestMapping(path: "/orderCheckIn", method: HttpMethod.GET) + Future orderCheckIn(Request request,Map jwt) async { + ApiResponse>> apiResponse = ApiResponse(); + try { + var queryParameters = request.requestedUri.queryParameters; + Reservation query = Reservation.fromQueryParameters(queryParameters,jwt); + List bedList = await bedService.getOrderCheckIn(query); + // int bedCount = await bedService.getBedCount(query); + List> bedListMap = + bedList.map((e) => e as Map).toList(); // 强制转换 + apiResponse.code = ResponseJsonCode.success; + apiResponse.data = bedListMap; + // apiResponse.total = bedCount; + String serializedJson = apiResponse.serialize(); + return Response(HttpStatusCode.ok, body: serializedJson); // 发送响应 + } catch (e) { + apiResponse.code = ResponseJsonCode.fail; + apiResponse.message = "查询失败: $e"; // 包含异常信息 + String serializedJson = apiResponse.serialize(); + return Response(HttpStatusCode.internalServerError, body: serializedJson); + } + } +} diff --git a/bin/controller/BedController.route.dart b/bin/controller/BedController.route.dart new file mode 100644 index 0000000..59d71a1 --- /dev/null +++ b/bin/controller/BedController.route.dart @@ -0,0 +1,30 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +// ************************************************************************** +// RouteGenerator +// ************************************************************************** + +part of 'BedController.dart'; + +late var _callHandler; +final Map> routes = { + HttpMethod.GET: [ + ["/bed/bedList", HttpResponseType.JSON, _callHandler.getBedList, 2, true], + [ + "/bed/orderCheckIn", + HttpResponseType.JSON, + _callHandler.orderCheckIn, + 2, + true + ] + ], + HttpMethod.POST: [ + ["/bed/addBed", HttpResponseType.JSON, _callHandler.addBed, 1, true] + ], + HttpMethod.PUT: [ + ["/bed/updateBed", HttpResponseType.JSON, _callHandler.updateBed, 1, true] + ], + HttpMethod.DELETE: [ + ["/bed/deleteBed", HttpResponseType.JSON, _callHandler.deleteBed, 1, true] + ], +}; diff --git a/bin/controller/BedTypeController.dart b/bin/controller/BedTypeController.dart new file mode 100644 index 0000000..21895f1 --- /dev/null +++ b/bin/controller/BedTypeController.dart @@ -0,0 +1,121 @@ +import 'dart:convert'; +import 'package:EasyDartModule/EasyDartModule.dart'; +import 'package:EasyDartModule/base/webserver/WebServer.dart'; + +import '../model/BedType.dart'; +import '../service/BedTypeService.dart'; +import '../model/ApiResponse.dart'; +import '../const/HttpStatusCode.dart'; +import '../const/MessageConstants.dart'; +import '../const/ResponseJsonCode.dart'; + +part 'BedTypeController.route.dart'; +@RequestMapping(path: "/bedType") +class BedTypeController { + final BedTypeService bedTypeService = BedTypeService(); + set callHandler(handler) => _callHandler = handler; + Map> get routeMap => routes; + + BedTypeController(); + + // 获取床位类型列表 + @RequestMapping(path: "/bedTypeList", method: HttpMethod.GET) + Future getBedTypeList(Request request, Map jwt) async { + ApiResponse>> apiResponse = ApiResponse(); + try { + var queryParameters = request.requestedUri.queryParameters; + BedType query = BedType.fromQueryParameters(queryParameters,jwt); + List bedTypeList = await bedTypeService.getBedTypeList(query); + int bedTypeCount = await bedTypeService.getBedTypeCount(query); + List> bedTypeListMap = + bedTypeList.map((e) => e as Map).toList(); // 强制转换 + apiResponse.code = ResponseJsonCode.success; + apiResponse.data = bedTypeListMap; + apiResponse.total = bedTypeCount; + String serializedJson = apiResponse.serialize(); + return Response(HttpStatusCode.ok, body: serializedJson); // 发送响应 + } catch (e) { + apiResponse.code = ResponseJsonCode.fail; + apiResponse.message = "查询失败: $e"; // 包含异常信息 + String serializedJson = apiResponse.serialize(); + return Response(HttpStatusCode.internalServerError, body: serializedJson); + } + } + + // 添加床位类型 + @RequestMapping(path: "/addBedType", method: HttpMethod.POST) + Future addBedType(Request request) async { + ApiResponse apiResponse = ApiResponse(); + try { + var data = jsonDecode(await request.readAsString()); + var bedType = BedType.fromJson(data); + var result = await bedTypeService.addBedType(bedType); + apiResponse.code = ResponseJsonCode.success; + apiResponse.message = MessageConstants.ADD_SUCCESS; + String serializedJson = apiResponse.serialize(); + return Response(HttpStatusCode.ok, body: serializedJson); // 发送成功响应 + } catch (e) { + apiResponse.code = ResponseJsonCode.fail; + apiResponse.message = MessageConstants.ADD_ERROR; // 包含异常信息 + String serializedJson = apiResponse.serialize(); + return Response(HttpStatusCode.internalServerError, + body: serializedJson); // 发送失败响应 + } + } + + // 更新床位类型 + @RequestMapping(path: "/updateBedType", method: HttpMethod.PUT) + Future updateBedType(Request request) async { + ApiResponse apiResponse = ApiResponse(); + try { + var data = jsonDecode(await request.readAsString()); + var bedTypeId = data['bed_type_id']; + var updatedBedType = BedType.fromJson(data); + if (updatedBedType.id == null || updatedBedType.id!.isEmpty) { + apiResponse.code = ResponseJsonCode.fail; + apiResponse.message = "床位类型ID不能为空"; + String serializedJson = apiResponse.serialize(); + return Response(HttpStatusCode.ok, body: serializedJson); + } + var result = + await bedTypeService.updateBedType(bedTypeId, updatedBedType); + apiResponse.code = ResponseJsonCode.success; + apiResponse.message = result; + String serializedJson = apiResponse.serialize(); + return Response(HttpStatusCode.ok, body: serializedJson); // 发送成功响应 + } catch (e) { + apiResponse.code = ResponseJsonCode.fail; + apiResponse.message = "更新失败: $e"; // 包含异常信息 + String serializedJson = apiResponse.serialize(); + return Response(HttpStatusCode.internalServerError, + body: serializedJson); // 发送失败响应 + } + } + + // 删除床位类型 + @RequestMapping(path: "/deleteBedType", method: HttpMethod.DELETE) + Future deleteBedType(Request request) async { + ApiResponse apiResponse = ApiResponse(); + try { + var data = jsonDecode(await request.readAsString()); + var bedTypeId = data['bed_type_id']; + var result = await bedTypeService.deleteBedType(bedTypeId); + if (result.isEmpty) { + apiResponse.code = ResponseJsonCode.success; + apiResponse.message = MessageConstants.DELETE_SUCCESS; + String serializedJson = apiResponse.serialize(); + return Response(HttpStatusCode.ok, body: serializedJson); // 发送成功响应 + } + apiResponse.code = ResponseJsonCode.fail; + apiResponse.message = result; + String serializedJson = apiResponse.serialize(); + return Response(HttpStatusCode.ok, body: serializedJson); + } catch (e) { + apiResponse.code = ResponseJsonCode.fail; + apiResponse.message = MessageConstants.DELETE_ERROR; // 包含异常信息 + String serializedJson = apiResponse.serialize(); + return Response(HttpStatusCode.internalServerError, + body: serializedJson); // 发送失败响应 + } + } +} \ No newline at end of file diff --git a/bin/controller/BedTypeController.route.dart b/bin/controller/BedTypeController.route.dart new file mode 100644 index 0000000..dd317bb --- /dev/null +++ b/bin/controller/BedTypeController.route.dart @@ -0,0 +1,47 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +// ************************************************************************** +// RouteGenerator +// ************************************************************************** + +part of 'BedTypeController.dart'; + +late var _callHandler; +final Map> routes = { + HttpMethod.GET: [ + [ + "/bedType/bedTypeList", + HttpResponseType.JSON, + _callHandler.getBedTypeList, + 2, + true + ] + ], + HttpMethod.POST: [ + [ + "/bedType/addBedType", + HttpResponseType.JSON, + _callHandler.addBedType, + 1, + true + ] + ], + HttpMethod.PUT: [ + [ + "/bedType/updateBedType", + HttpResponseType.JSON, + _callHandler.updateBedType, + 1, + true + ] + ], + HttpMethod.DELETE: [ + [ + "/bedType/deleteBedType", + HttpResponseType.JSON, + _callHandler.deleteBedType, + 1, + true + ] + ], +}; diff --git a/bin/controller/DictionaryTypeController.dart b/bin/controller/DictionaryTypeController.dart new file mode 100644 index 0000000..ef23a91 --- /dev/null +++ b/bin/controller/DictionaryTypeController.dart @@ -0,0 +1,111 @@ +import 'dart:convert'; + +import 'package:EasyDartModule/EasyDartModule.dart'; +import 'package:EasyDartModule/base/webserver/WebServer.dart'; + +import '../const/HttpStatusCode.dart'; +import '../const/ResponseJsonCode.dart'; +import '../model/ApiResponse.dart'; +import '../model/DictionaryType.dart'; +import '../service/DictionaryService.dart'; +import '../const/MessageConstants.dart'; + +part 'DictionaryTypeController.route.dart'; +@RequestMapping(path: "/dictionary") +class DictionaryTypeController { + final DictionaryService dictionaryService = DictionaryService(); + set callHandler(handler) => _callHandler = handler; + Map> get routeMap => routes; + + DictionaryTypeController(); + + // 获取字典列表 + @RequestMapping(path: "/list", method: HttpMethod.GET) + Future getDictionaryList( + Request request, Map jwt) async { + ApiResponse>> apiResponse = ApiResponse(); + try { + var queryParameters = request.requestedUri.queryParameters; + DictionaryType query = + DictionaryType.fromQueryParameters(queryParameters, jwt); + List dictionaryList = + await dictionaryService.getDictionaryList(query); + List> dictionaryListMap = + dictionaryList.map((e) => e.toJson()).toList(); // 转换为 Map + apiResponse.code = ResponseJsonCode.success; + apiResponse.data = dictionaryListMap; + String serializedJson = apiResponse.serialize(); + return Response(HttpStatusCode.ok, body: serializedJson); // 发送响应 + } catch (e) { + apiResponse.code = ResponseJsonCode.fail; + apiResponse.message = "查询失败: $e"; // 包含异常信息 + String serializedJson = apiResponse.serialize(); + return Response(HttpStatusCode.internalServerError, body: serializedJson); + } + } + + // 添加字典 + @RequestMapping(path: "/add", method: HttpMethod.POST) + Future addDictionary(Request request) async { + ApiResponse apiResponse = ApiResponse(); + try { + var data = jsonDecode(await request.readAsString()); + var dictionary = DictionaryType.fromJson(data); + var result = await dictionaryService.addDictionary(dictionary); + apiResponse.code = ResponseJsonCode.success; + apiResponse.message = MessageConstants.ADD_SUCCESS; + String serializedJson = apiResponse.serialize(); + return Response(HttpStatusCode.ok, body: serializedJson); // 发送成功响应 + } catch (e) { + apiResponse.code = ResponseJsonCode.fail; + apiResponse.message = "添加失败: $e"; // 包含异常信息 + String serializedJson = apiResponse.serialize(); + return Response(HttpStatusCode.internalServerError, + body: serializedJson); // 发送失败响应 + } + } + + // 更新字典 + @RequestMapping(path: "/update", method: HttpMethod.PUT) + Future updateDictionary(Request request) async { + ApiResponse apiResponse = ApiResponse(); + try { + var data = jsonDecode(await request.readAsString()); + var dictionaryId = data['_id']; + var updatedDictionary = DictionaryType.fromJson(data); + var result = await dictionaryService.updateDictionary( + dictionaryId, updatedDictionary); + apiResponse.code = ResponseJsonCode.success; + apiResponse.message = result; + String serializedJson = apiResponse.serialize(); + return Response(HttpStatusCode.ok, body: serializedJson); // 发送成功响应 + } catch (e) { + apiResponse.code = ResponseJsonCode.fail; + apiResponse.message = "更新失败: $e"; // 包含异常信息 + String serializedJson = apiResponse.serialize(); + return Response(HttpStatusCode.internalServerError, + body: serializedJson); // 发送失败响应 + } + } + + // 删除字典 + @RequestMapping(path: "/delete", method: HttpMethod.DELETE) + Future deleteDictionary(Request request) async { + ApiResponse apiResponse = ApiResponse(); + try { + var data = jsonDecode(await request.readAsString()); + var dictionaryId = data['_id']; + var result = await dictionaryService.deleteDictionary(dictionaryId); + apiResponse.code = ResponseJsonCode.success; + apiResponse.message = result; + String serializedJson = apiResponse.serialize(); + return Response(HttpStatusCode.ok, body: serializedJson); // 发送成功响应 + } catch (e) { + apiResponse.code = ResponseJsonCode.fail; + apiResponse.message = "删除失败: $e"; // 包含异常信息 + String serializedJson = apiResponse.serialize(); + return Response(HttpStatusCode.internalServerError, + body: serializedJson); // 发送失败响应 + } + } +} diff --git a/bin/controller/DictionaryTypeController.route.dart b/bin/controller/DictionaryTypeController.route.dart new file mode 100644 index 0000000..3a191cb --- /dev/null +++ b/bin/controller/DictionaryTypeController.route.dart @@ -0,0 +1,47 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +// ************************************************************************** +// RouteGenerator +// ************************************************************************** + +part of 'DictionaryTypeController.dart'; + +late var _callHandler; +final Map> routes = { + HttpMethod.GET: [ + [ + "/dictionary/list", + HttpResponseType.JSON, + _callHandler.getDictionaryList, + 2, + true + ] + ], + HttpMethod.POST: [ + [ + "/dictionary/add", + HttpResponseType.JSON, + _callHandler.addDictionary, + 1, + true + ] + ], + HttpMethod.PUT: [ + [ + "/dictionary/update", + HttpResponseType.JSON, + _callHandler.updateDictionary, + 1, + true + ] + ], + HttpMethod.DELETE: [ + [ + "/dictionary/delete", + HttpResponseType.JSON, + _callHandler.deleteDictionary, + 1, + true + ] + ], +}; diff --git a/bin/controller/DiseaseTypeController.dart b/bin/controller/DiseaseTypeController.dart new file mode 100644 index 0000000..b3324f2 --- /dev/null +++ b/bin/controller/DiseaseTypeController.dart @@ -0,0 +1,117 @@ +import 'dart:convert'; +import 'package:EasyDartModule/EasyDartModule.dart'; +import 'package:EasyDartModule/base/webserver/WebServer.dart'; + +import '../model/DiseaseType.dart'; +import '../service/DiseaseTypeService.dart'; +import '../model/ApiResponse.dart'; +import '../const/HttpStatusCode.dart'; +import '../const/MessageConstants.dart'; +import '../const/ResponseJsonCode.dart'; + +part 'DiseaseTypeController.route.dart'; +@RequestMapping(path: "/diseaseType") +class DiseaseTypeController { + final DiseaseTypeService diseaseTypeService = DiseaseTypeService(); + set callHandler(handler) => _callHandler = handler; + Map> get routeMap => routes; + + DiseaseTypeController(); + + // 获取疾病类型列表 + @RequestMapping(path: "/diseaseTypeList", method: HttpMethod.GET) + Future getDiseaseTypeList(Request request, Map jwt) async { + ApiResponse>> apiResponse = ApiResponse(); + try { + var queryParameters = request.requestedUri.queryParameters; + DiseaseType query = DiseaseType.fromQueryParameters(queryParameters,jwt); + List diseaseTypeList = await diseaseTypeService.getDiseaseTypeList(query); + int diseaseTypeCount = await diseaseTypeService.getDiseaseTypeCount(query); + List> diseaseTypeListMap = + diseaseTypeList.map((e) => e as Map).toList(); // 强制转换 + apiResponse.code = ResponseJsonCode.success; + apiResponse.data = diseaseTypeListMap; + apiResponse.total = diseaseTypeCount; + String serializedJson = apiResponse.serialize(); + return Response(HttpStatusCode.ok, body: serializedJson); // 发送响应 + } catch (e) { + apiResponse.code = ResponseJsonCode.fail; + apiResponse.message = "查询失败: $e"; // 包含异常信息 + String serializedJson = apiResponse.serialize(); + return Response(HttpStatusCode.internalServerError, body: serializedJson); + } + } + + // 添加疾病类型 + @RequestMapping(path: "/addDiseaseType", method: HttpMethod.POST) + Future addDiseaseType(Request request) async { + ApiResponse apiResponse = ApiResponse(); + try { + var data = jsonDecode(await request.readAsString()); + var diseaseType = DiseaseType.fromJson(data); + var result = await diseaseTypeService.addDiseaseType(diseaseType); + apiResponse.code = ResponseJsonCode.success; + apiResponse.message = MessageConstants.ADD_SUCCESS; + String serializedJson = apiResponse.serialize(); + return Response(HttpStatusCode.ok, body: serializedJson); // 发送成功响应 + } catch (e) { + apiResponse.code = ResponseJsonCode.fail; + apiResponse.message = MessageConstants.ADD_ERROR; // 包含异常信息 + String serializedJson = apiResponse.serialize(); + return Response(HttpStatusCode.internalServerError, body: serializedJson); // 发送失败响应 + } + } + + // 更新疾病类型 + @RequestMapping(path: "/updateDiseaseType", method: HttpMethod.PUT) + Future updateDiseaseType(Request request) async { + ApiResponse apiResponse = ApiResponse(); + try { + var data = jsonDecode(await request.readAsString()); + var diseaseTypeId = data['_id']; + var updatedDiseaseType = DiseaseType.fromJson(data); + if (updatedDiseaseType.id == null || updatedDiseaseType.id!.isEmpty) { + apiResponse.code = ResponseJsonCode.fail; + apiResponse.message = "疾病类型ID不能为空"; + String serializedJson = apiResponse.serialize(); + return Response(HttpStatusCode.ok, body: serializedJson); + } + var result = await diseaseTypeService.updateDiseaseType(diseaseTypeId, updatedDiseaseType); + apiResponse.code = ResponseJsonCode.success; + apiResponse.message = result; + String serializedJson = apiResponse.serialize(); + return Response(HttpStatusCode.ok, body: serializedJson); // 发送成功响应 + } catch (e) { + apiResponse.code = ResponseJsonCode.fail; + apiResponse.message = "更新失败: $e"; // 包含异常信息 + String serializedJson = apiResponse.serialize(); + return Response(HttpStatusCode.internalServerError, body: serializedJson); // 发送失败响应 + } + } + + // 删除疾病类型 + @RequestMapping(path: "/deleteDiseaseType", method: HttpMethod.DELETE) + Future deleteDiseaseType(Request request) async { + ApiResponse apiResponse = ApiResponse(); + try { + var data = jsonDecode(await request.readAsString()); + var diseaseTypeId = data['id']; + var result = await diseaseTypeService.deleteDiseaseType(diseaseTypeId); + if (result.isEmpty) { + apiResponse.code = ResponseJsonCode.success; + apiResponse.message = MessageConstants.DELETE_SUCCESS; + String serializedJson = apiResponse.serialize(); + return Response(HttpStatusCode.ok, body: serializedJson); // 发送成功响应 + } + apiResponse.code = ResponseJsonCode.fail; + apiResponse.message = result; + String serializedJson = apiResponse.serialize(); + return Response(HttpStatusCode.ok, body: serializedJson); + } catch (e) { + apiResponse.code = ResponseJsonCode.fail; + apiResponse.message = MessageConstants.DELETE_ERROR; // 包含异常信息 + String serializedJson = apiResponse.serialize(); + return Response(HttpStatusCode.internalServerError, body: serializedJson); // 发送失败响应 + } + } +} \ No newline at end of file diff --git a/bin/controller/DiseaseTypeController.route.dart b/bin/controller/DiseaseTypeController.route.dart new file mode 100644 index 0000000..cbd7e57 --- /dev/null +++ b/bin/controller/DiseaseTypeController.route.dart @@ -0,0 +1,47 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +// ************************************************************************** +// RouteGenerator +// ************************************************************************** + +part of 'DiseaseTypeController.dart'; + +late var _callHandler; +final Map> routes = { + HttpMethod.GET: [ + [ + "/diseaseType/diseaseTypeList", + HttpResponseType.JSON, + _callHandler.getDiseaseTypeList, + 2, + true + ] + ], + HttpMethod.POST: [ + [ + "/diseaseType/addDiseaseType", + HttpResponseType.JSON, + _callHandler.addDiseaseType, + 1, + true + ] + ], + HttpMethod.PUT: [ + [ + "/diseaseType/updateDiseaseType", + HttpResponseType.JSON, + _callHandler.updateDiseaseType, + 1, + true + ] + ], + HttpMethod.DELETE: [ + [ + "/diseaseType/deleteDiseaseType", + HttpResponseType.JSON, + _callHandler.deleteDiseaseType, + 1, + true + ] + ], +}; diff --git a/bin/controller/FileUploadController.dart b/bin/controller/FileUploadController.dart new file mode 100644 index 0000000..c84817c --- /dev/null +++ b/bin/controller/FileUploadController.dart @@ -0,0 +1,98 @@ +import 'package:EasyDartModule/EasyDartModule.dart'; +import 'package:EasyDartModule/base/webserver/WebServer.dart'; +import 'package:intl/intl.dart'; +import 'package:shelf_multipart/shelf_multipart.dart'; // 导入 shelf_multipart 插件 + +import '../const/HttpStatusCode.dart'; +import '../const/ResponseJsonCode.dart'; +import '../model/ApiResponse.dart'; + +part 'FileUploadController.route.dart'; +@RequestMapping(path: "/file") +class FileUploadController { + FileUploadController(); + set callHandler(handler) => _callHandler = handler; + Map> get routeMap => routes; + + // 上传文件 + @RequestMapping(path: "/upload", method: HttpMethod.POST) + Future uploadFile(Request request) async { + ApiResponse apiResponse = ApiResponse(); + request.formData(); + + try { + // 检查请求的 Content-Type 是否为 multipart/form-data + var contentType = request.headers['content-type']; + if (contentType == null || + !contentType.startsWith('multipart/form-data')) { + apiResponse.code = ResponseJsonCode.fail; + apiResponse.message = "请求格式必须是 multipart/form-data"; + return Response(HttpStatusCode.internalServerError, + body: apiResponse.serialize()); + } + if (request.formData() case var form?) { + String description = "上传成功"; + String bucket = ""; + String? fileExtension; // 文件后缀 + + var file; + await for (final formData in form.formData) { + if (formData.name == 'bucket') { + bucket = await formData.part.readString(); + } + if (formData.name == 'file') { + final filename = formData.filename; + if (filename != null && filename.isNotEmpty) { + fileExtension = filename.split('.').last; // 提取文件后缀 + } + file = await formData.part.readBytes(); + } + } + if (bucket.isEmpty) { + description = "桶名不能为空"; + } + if (file == null) { + description = "文件不能为空"; + } + final String folderName = + DateFormat('yyyy-MM-dd').format(DateTime.now()); + String objectName = + "$folderName/${DateTime.now().millisecondsSinceEpoch}.$fileExtension"; + // 创建存储桶(如果不存在) + await EasyDartModule.storage.createBucket(bucket); + + // 上传文件 + var path = + await EasyDartModule.storage.uploadObject(bucket, objectName, file); + + // EasyDartModule.storage.getObject(bucket, objectName).then((data) { + // print("下载文件"); + // File("b.gif").writeAsBytesSync(data); + // print("下载完毕"); + // }); + return Response.ok(path); + } else if (request.multipart() case var multipart?) { + final description = StringBuffer('Regular multipart request\n'); + + await for (final part in multipart.parts) { + description.writeln('new part'); + + part.headers.forEach( + (key, value) => description.writeln('Header $key=$value')); + final content = await part.readString(); + description.writeln('content: $content'); + + description.writeln('end of part'); + } + return Response.ok(description.toString()); + } else { + return Response.ok('Not a multipart request'); + } + } catch (e) { + apiResponse.code = ResponseJsonCode.fail; + apiResponse.message = "文件上传失败: $e"; + return Response(HttpStatusCode.internalServerError, + body: apiResponse.serialize()); + } + } +} diff --git a/bin/controller/FileUploadController.route.dart b/bin/controller/FileUploadController.route.dart new file mode 100644 index 0000000..6848cc4 --- /dev/null +++ b/bin/controller/FileUploadController.route.dart @@ -0,0 +1,14 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +// ************************************************************************** +// RouteGenerator +// ************************************************************************** + +part of 'FileUploadController.dart'; + +late var _callHandler; +final Map> routes = { + HttpMethod.POST: [ + ["/file/upload", HttpResponseType.JSON, _callHandler.uploadFile, 1, true] + ], +}; diff --git a/bin/controller/PersonController.dart b/bin/controller/PersonController.dart new file mode 100644 index 0000000..8b42f05 --- /dev/null +++ b/bin/controller/PersonController.dart @@ -0,0 +1,114 @@ +import 'dart:convert'; + +import 'package:EasyDartModule/EasyDartModule.dart'; +import 'package:EasyDartModule/base/webserver/WebServer.dart'; + +import '../const/HttpStatusCode.dart'; +import '../const/MessageConstants.dart'; +import '../const/ResponseJsonCode.dart'; +import '../model/ApiResponse.dart'; +import '../model/Person.dart'; +import '../service/PersonService.dart'; + +part 'PersonController.route.dart'; +@RequestMapping(path: "/person") +class PersonController { + final PersonService personService = PersonService(); + set callHandler(handler) => _callHandler = handler; + Map> get routeMap => routes; + + PersonController(); + + // 获取人员列表 + @RequestMapping(path: "/personList", method: HttpMethod.GET) + Future getPersonList( + Request request, Map jwt) async { + ApiResponse>> apiResponse = ApiResponse(); + try { + var queryParameters = request.requestedUri.queryParameters; + Person query = Person.fromQueryParameters(queryParameters, jwt); + var personList = await personService.getPersonList(query); + int personCount = await personService.getPersonCount(query); + print(personList); + List> personListMap = + personList.map((e) => e as Map).toList(); + apiResponse.code = ResponseJsonCode.success; + apiResponse.data = personListMap; + apiResponse.total = personCount; + String serializedJson = apiResponse.serialize(); + return Response(HttpStatusCode.ok, body: serializedJson); + } catch (e) { + apiResponse.code = ResponseJsonCode.fail; + apiResponse.message = "查询失败: $e"; + String serializedJson = apiResponse.serialize(); + return Response(HttpStatusCode.internalServerError, body: serializedJson); + } + } + + // 添加人员 + @RequestMapping(path: "/addPerson", method: HttpMethod.POST) + Future addPerson(Request request) async { + ApiResponse apiResponse = ApiResponse(); + try { + var data = jsonDecode(await request.readAsString()); + var person = Person.fromJson(data); + var result = await personService.addPerson(person); + apiResponse.code = ResponseJsonCode.success; + apiResponse.message = MessageConstants.ADD_SUCCESS; + String serializedJson = apiResponse.serialize(); + return Response(HttpStatusCode.ok, body: serializedJson); + } catch (e) { + apiResponse.code = ResponseJsonCode.fail; + apiResponse.message = MessageConstants.ADD_ERROR; + String serializedJson = apiResponse.serialize(); + return Response(HttpStatusCode.internalServerError, body: serializedJson); + } + } + + // 更新人员信息 + @RequestMapping(path: "/updatePerson", method: HttpMethod.PUT) + Future updatePerson(Request request) async { + ApiResponse apiResponse = ApiResponse(); + try { + var data = jsonDecode(await request.readAsString()); + var personId = data['_id']; + var updatedPerson = Person.fromJson(data); + var result = await personService.updatePerson(personId, updatedPerson); + apiResponse.code = ResponseJsonCode.success; + apiResponse.message = result; + String serializedJson = apiResponse.serialize(); + return Response(HttpStatusCode.ok, body: serializedJson); // 发送成功响应 + } catch (e) { + apiResponse.code = ResponseJsonCode.fail; + apiResponse.message = "更新失败: $e"; + String serializedJson = apiResponse.serialize(); + return Response(HttpStatusCode.internalServerError, body: serializedJson); + } + } + + // 删除人员 + @RequestMapping(path: "/deletePerson", method: HttpMethod.DELETE) + Future deletePerson(Request request) async { + ApiResponse apiResponse = ApiResponse(); + try { + var data = jsonDecode(await request.readAsString()); + var personId = data['_id']; + var result = await personService.deletePerson(personId); + if (result.isEmpty) { + apiResponse.code = ResponseJsonCode.success; + apiResponse.message = MessageConstants.DELETE_SUCCESS; + String serializedJson = apiResponse.serialize(); + return Response(HttpStatusCode.ok, body: serializedJson); // 发送成功响应 + } + apiResponse.code = ResponseJsonCode.fail; + apiResponse.message = result; + String serializedJson = apiResponse.serialize(); + return Response(HttpStatusCode.ok, body: serializedJson); + } catch (e) { + apiResponse.code = ResponseJsonCode.fail; + apiResponse.message = "删除失败: $e"; + String serializedJson = apiResponse.serialize(); + return Response(HttpStatusCode.internalServerError, body: serializedJson); + } + } +} diff --git a/bin/controller/PersonController.route.dart b/bin/controller/PersonController.route.dart new file mode 100644 index 0000000..2ea997e --- /dev/null +++ b/bin/controller/PersonController.route.dart @@ -0,0 +1,47 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +// ************************************************************************** +// RouteGenerator +// ************************************************************************** + +part of 'PersonController.dart'; + +late var _callHandler; +final Map> routes = { + HttpMethod.GET: [ + [ + "/person/personList", + HttpResponseType.JSON, + _callHandler.getPersonList, + 2, + true + ] + ], + HttpMethod.POST: [ + [ + "/person/addPerson", + HttpResponseType.JSON, + _callHandler.addPerson, + 1, + true + ] + ], + HttpMethod.PUT: [ + [ + "/person/updatePerson", + HttpResponseType.JSON, + _callHandler.updatePerson, + 1, + true + ] + ], + HttpMethod.DELETE: [ + [ + "/person/deletePerson", + HttpResponseType.JSON, + _callHandler.deletePerson, + 1, + true + ] + ], +}; diff --git a/bin/controller/PersonTypeController.dart b/bin/controller/PersonTypeController.dart new file mode 100644 index 0000000..60ae33e --- /dev/null +++ b/bin/controller/PersonTypeController.dart @@ -0,0 +1,111 @@ +import 'dart:convert'; + +import 'package:EasyDartModule/EasyDartModule.dart'; +import 'package:EasyDartModule/base/webserver/WebServer.dart'; + +import '../model/PersonType.dart'; +import '../service/PersonTypeService.dart'; +import '../model/ApiResponse.dart'; +import '../const/HttpStatusCode.dart'; +import '../const/MessageConstants.dart'; +import '../const/ResponseJsonCode.dart'; + +part 'PersonTypeController.route.dart'; +@RequestMapping(path: "/personType") +class PersonTypeController { + final PersonTypeService personTypeService = PersonTypeService(); + set callHandler(handler) => _callHandler = handler; + Map> get routeMap => routes; + + PersonTypeController(); + + // 获取人员类型列表 + @RequestMapping(path: "/personTypeList", method: HttpMethod.GET) + Future getPersonTypeList(Request request, Map jwt) async { + ApiResponse>> apiResponse = ApiResponse(); + try { + var queryParameters = request.requestedUri.queryParameters; + PersonType query = PersonType.fromQueryParameters(queryParameters,jwt); + var personTypeList = await personTypeService.getPersonTypeList(query); + List> personTypeListMap = + personTypeList.map((e) => e as Map).toList(); + apiResponse.code = ResponseJsonCode.success; + apiResponse.data = personTypeListMap; + String serializedJson = apiResponse.serialize(); + return Response(HttpStatusCode.ok, body: serializedJson); + } catch (e) { + apiResponse.code = ResponseJsonCode.fail; + apiResponse.message = "查询失败: $e"; + String serializedJson = apiResponse.serialize(); + return Response(HttpStatusCode.internalServerError, body: serializedJson); + } + } + + // 添加人员类型 + @RequestMapping(path: "/addPersonType", method: HttpMethod.POST) + Future addPersonType(Request request) async { + ApiResponse apiResponse = ApiResponse(); + try { + var data = jsonDecode(await request.readAsString()); + var personType = PersonType.fromJson(data); + var result = await personTypeService.addPersonType(personType); + apiResponse.code = ResponseJsonCode.success; + apiResponse.message = MessageConstants.ADD_SUCCESS; + String serializedJson = apiResponse.serialize(); + return Response(HttpStatusCode.ok, body: serializedJson); + } catch (e) { + apiResponse.code = ResponseJsonCode.fail; + apiResponse.message = MessageConstants.ADD_ERROR; + String serializedJson = apiResponse.serialize(); + return Response(HttpStatusCode.internalServerError, body: serializedJson); + } + } + + // 更新人员类型 + @RequestMapping(path: "/updatePersonType", method: HttpMethod.PUT) + Future updatePersonType(Request request) async { + ApiResponse apiResponse = ApiResponse(); + try { + var data = jsonDecode(await request.readAsString()); + var personTypeId = data['person_type_id']; + var updatedPersonType = PersonType.fromJson(data); + var result = await personTypeService.updatePersonType( + personTypeId, updatedPersonType); + apiResponse.code = ResponseJsonCode.success; + apiResponse.message = MessageConstants.UPDATE_SUCCESS; + String serializedJson = apiResponse.serialize(); + return Response(HttpStatusCode.ok, body: serializedJson); + } catch (e) { + apiResponse.code = ResponseJsonCode.fail; + apiResponse.message = "更新失败: $e"; + String serializedJson = apiResponse.serialize(); + return Response(HttpStatusCode.internalServerError, body: serializedJson); + } + } + + // 删除人员类型 + @RequestMapping(path: "/deletePersonType", method: HttpMethod.DELETE) + Future deletePersonType(Request request) async { + ApiResponse apiResponse = ApiResponse(); + try { + var data = jsonDecode(await request.readAsString()); + var personTypeId = data['person_type_id']; + var result = await personTypeService.deletePersonType(personTypeId); + if (result.isEmpty) { + apiResponse.code = ResponseJsonCode.success; + apiResponse.message = MessageConstants.DELETE_SUCCESS; + String serializedJson = apiResponse.serialize(); + return Response(HttpStatusCode.ok, body: serializedJson); // 发送成功响应 + } + apiResponse.code = ResponseJsonCode.fail; + apiResponse.message = result; + String serializedJson = apiResponse.serialize(); + return Response(HttpStatusCode.ok, body: serializedJson); + } catch (e) { + apiResponse.code = ResponseJsonCode.fail; + apiResponse.message = "删除失败: $e"; + String serializedJson = apiResponse.serialize(); + return Response(HttpStatusCode.internalServerError, body: serializedJson); + } + } +} diff --git a/bin/controller/PersonTypeController.route.dart b/bin/controller/PersonTypeController.route.dart new file mode 100644 index 0000000..c765090 --- /dev/null +++ b/bin/controller/PersonTypeController.route.dart @@ -0,0 +1,47 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +// ************************************************************************** +// RouteGenerator +// ************************************************************************** + +part of 'PersonTypeController.dart'; + +late var _callHandler; +final Map> routes = { + HttpMethod.GET: [ + [ + "/personType/personTypeList", + HttpResponseType.JSON, + _callHandler.getPersonTypeList, + 2, + true + ] + ], + HttpMethod.POST: [ + [ + "/personType/addPersonType", + HttpResponseType.JSON, + _callHandler.addPersonType, + 1, + true + ] + ], + HttpMethod.PUT: [ + [ + "/personType/updatePersonType", + HttpResponseType.JSON, + _callHandler.updatePersonType, + 1, + true + ] + ], + HttpMethod.DELETE: [ + [ + "/personType/deletePersonType", + HttpResponseType.JSON, + _callHandler.deletePersonType, + 1, + true + ] + ], +}; diff --git a/bin/controller/RoomController.dart b/bin/controller/RoomController.dart new file mode 100644 index 0000000..ae09b2a --- /dev/null +++ b/bin/controller/RoomController.dart @@ -0,0 +1,235 @@ +import 'dart:convert'; +import 'package:EasyDartModule/EasyDartModule.dart'; +import 'package:EasyDartModule/base/webserver/WebServer.dart'; +import '../model/Room.dart'; +import '../service/RoomService.dart'; +import '../model/ApiResponse.dart'; +import '../const/MessageConstants.dart'; +import '../const/ResponseJsonCode.dart'; +import '../const/HttpStatusCode.dart'; + +part 'RoomController.route.dart'; +@RequestMapping(path: "/room") +class RoomController { + final RoomService roomService = RoomService(); + set callHandler(handler) => _callHandler = handler; + Map> get routeMap => routes; + + RoomController(); + + // 获取房间列表 + @RequestMapping(path: "/roomList", method: HttpMethod.GET) + Future getRoomList( + Request request, Map jwt) async { + ApiResponse>> apiResponse = ApiResponse(); + try { + var queryParameters = request.requestedUri.queryParameters; + Room query = Room.fromQueryParameters(queryParameters, jwt); + List roomList = await roomService.getRoomList(query, + page: queryParameters['page'] == null + ? 1 + : int.parse(queryParameters['page']!), + pageSize: queryParameters['limit'] == null + ? 10 + : int.parse(queryParameters['limit']!)); + int roomTypeCount = await roomService.getRoomCount(query); + List> roomListMap = + roomList.map((e) => e as Map).toList(); // 强制转换 + apiResponse.code = ResponseJsonCode.success; + apiResponse.data = roomListMap; + apiResponse.total = roomTypeCount; + String serializedJson = apiResponse.serialize(); + return Response(HttpStatusCode.ok, body: serializedJson); // 发送响应 + } catch (e) { + apiResponse.code = ResponseJsonCode.fail; + apiResponse.message = "查询失败: $e"; // 包含异常信息 + String serializedJson = apiResponse.serialize(); + return Response(HttpStatusCode.internalServerError, body: serializedJson); + } + } + + // 添加房间 + @RequestMapping(path: "/addRoom", method: HttpMethod.POST) + Future addRoom(Request request) async { + ApiResponse apiResponse = ApiResponse(); + try { + var data = jsonDecode(await request.readAsString()); + var room = Room.fromJson(data); + var result = await roomService.addRoom(room); + if (result == null || result.isEmpty) { + apiResponse.code = ResponseJsonCode.success; + apiResponse.message = MessageConstants.ADD_SUCCESS; + String serializedJson = apiResponse.serialize(); + return Response(HttpStatusCode.ok, body: serializedJson); + } + apiResponse.code = ResponseJsonCode.fail; + apiResponse.message = result; + String serializedJson = apiResponse.serialize(); + return Response(HttpStatusCode.ok, body: serializedJson); // 发送成功响应 + } catch (e) { + apiResponse.code = ResponseJsonCode.fail; + apiResponse.message = "添加失败: $e"; // 包含异常信息 + String serializedJson = apiResponse.serialize(); + return Response(500, body: serializedJson); // 发送失败响应 + } + } + + // 更新房间 + @RequestMapping(path: "/updateRoom", method: HttpMethod.PUT) + Future updateRoom(Request request) async { + ApiResponse apiResponse = ApiResponse(); + try { + var data = jsonDecode(await request.readAsString()); + var roomId = data['_id']; + var updatedRoom = Room.fromJson(data); + if (updatedRoom.id == null || updatedRoom.id!.isEmpty) { + apiResponse.code = ResponseJsonCode.fail; + apiResponse.message = "房间类型ID不能为空"; + String serializedJson = apiResponse.serialize(); + return Response(HttpStatusCode.ok, body: serializedJson); + } + var result = await roomService.updateRoom(roomId, updatedRoom); + apiResponse.code = 1; + apiResponse.message = result; + String serializedJson = apiResponse.serialize(); + return Response(200, body: serializedJson); // 发送成功响应 + } catch (e) { + apiResponse.code = -1; + apiResponse.message = "更新失败: $e"; // 包含异常信息 + String serializedJson = apiResponse.serialize(); + return Response(500, body: serializedJson); // 发送失败响应 + } + } + + // 删除房间 + @RequestMapping(path: "/deleteRoom", method: HttpMethod.DELETE) + Future deleteRoom(Request request) async { + ApiResponse apiResponse = ApiResponse(); + try { + var data = jsonDecode(await request.readAsString()); + var roomId = data['roomId']; + var result = await roomService.deleteRoom(roomId); + apiResponse.code = 1; + if (result.isEmpty) { + apiResponse.code = ResponseJsonCode.success; + apiResponse.message = MessageConstants.DELETE_SUCCESS; + String serializedJson = apiResponse.serialize(); + return Response(HttpStatusCode.ok, body: serializedJson); // 发送成功响应 + } + apiResponse.code = ResponseJsonCode.fail; + apiResponse.message = result; + String serializedJson = apiResponse.serialize(); + return Response(HttpStatusCode.ok, body: serializedJson); + } catch (e) { + apiResponse.code = -1; + apiResponse.message = "删除失败: $e"; // 包含异常信息 + String serializedJson = apiResponse.serialize(); + return Response(500, body: serializedJson); // 发送失败响应 + } + } + + //办理预约信息 + @RequestMapping(path: "/addOrderCheckIn", method: HttpMethod.POST) + Future addOrderCheckIn( + Request request, Map jwt) async { + ApiResponse apiResponse = ApiResponse(); + try { + var data = jsonDecode(await request.readAsString()); + var result = await roomService.addOrderCheckIn(data,jwt); + if (result == null || result.isEmpty) { + apiResponse.code = ResponseJsonCode.success; + apiResponse.message = MessageConstants.ADD_SUCCESS; + String serializedJson = apiResponse.serialize(); + roomService.addReservationMessage(data, jwt); + return Response(HttpStatusCode.ok, body: serializedJson); + } + apiResponse.code = ResponseJsonCode.fail; + apiResponse.message = result; + String serializedJson = apiResponse.serialize(); + return Response(HttpStatusCode.ok, body: serializedJson); // 发送成功响应 + } catch (e) { + apiResponse.code = ResponseJsonCode.fail; + apiResponse.message = "添加失败: $e"; // 包含异常信息 + String serializedJson = apiResponse.serialize(); + return Response(500, body: serializedJson); // 发送失败响应 + } + } + + //删除预约入住信息 + @RequestMapping(path: "/delOrderCheckIn", method: HttpMethod.POST) + Future delOrderCheckIn(Request request) async { + ApiResponse apiResponse = ApiResponse(); + try { + var data = jsonDecode(await request.readAsString()); + var result = await roomService.delOrderCheckIn(data); + if (result == null || result.isEmpty) { + apiResponse.code = ResponseJsonCode.success; + apiResponse.message = MessageConstants.ADD_SUCCESS; + String serializedJson = apiResponse.serialize(); + return Response(HttpStatusCode.ok, body: serializedJson); + } + apiResponse.code = ResponseJsonCode.fail; + apiResponse.message = result; + String serializedJson = apiResponse.serialize(); + return Response(HttpStatusCode.ok, body: serializedJson); // 发送成功响应 + } catch (e) { + apiResponse.code = ResponseJsonCode.fail; + apiResponse.message = "添加失败: $e"; // 包含异常信息 + String serializedJson = apiResponse.serialize(); + return Response(500, body: serializedJson); // 发送失败响应 + } + } + + //办理入住信息 + @RequestMapping(path: "/addRuzhuCheckIn", method: HttpMethod.POST) + Future addRuzhuCheckIn( + Request request, Map jwt) async { + ApiResponse apiResponse = ApiResponse(); + try { + var data = jsonDecode(await request.readAsString()); + var result = await roomService.addRuzhuCheckIn(data, jwt); + if (result == null || result.isEmpty) { + apiResponse.code = ResponseJsonCode.success; + apiResponse.message = MessageConstants.ADD_SUCCESS; + String serializedJson = apiResponse.serialize(); + return Response(HttpStatusCode.ok, body: serializedJson); + } + apiResponse.code = ResponseJsonCode.fail; + apiResponse.message = result; + String serializedJson = apiResponse.serialize(); + return Response(HttpStatusCode.ok, body: serializedJson); // 发送成功响应 + } catch (e) { + apiResponse.code = ResponseJsonCode.fail; + apiResponse.message = "添加失败: $e"; // 包含异常信息 + String serializedJson = apiResponse.serialize(); + return Response(500, body: serializedJson); // 发送失败响应 + } + } + + + //办理退住信息 + @RequestMapping(path: "/checkout", method: HttpMethod.POST) + Future checkout( + Request request, Map jwt) async { + ApiResponse apiResponse = ApiResponse(); + try { + var data = jsonDecode(await request.readAsString()); + var result = await roomService.checkout(data, jwt); + if (result == null || result.isEmpty) { + apiResponse.code = ResponseJsonCode.success; + apiResponse.message = MessageConstants.ADD_SUCCESS; + String serializedJson = apiResponse.serialize(); + return Response(HttpStatusCode.ok, body: serializedJson); + } + apiResponse.code = ResponseJsonCode.fail; + apiResponse.message = result; + String serializedJson = apiResponse.serialize(); + return Response(HttpStatusCode.ok, body: serializedJson); // 发送成功响应 + } catch (e) { + apiResponse.code = ResponseJsonCode.fail; + apiResponse.message = "添加失败: $e"; // 包含异常信息 + String serializedJson = apiResponse.serialize(); + return Response(500, body: serializedJson); // 发送失败响应 + } + } +} diff --git a/bin/controller/RoomController.route.dart b/bin/controller/RoomController.route.dart new file mode 100644 index 0000000..a385bd7 --- /dev/null +++ b/bin/controller/RoomController.route.dart @@ -0,0 +1,57 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +// ************************************************************************** +// RouteGenerator +// ************************************************************************** + +part of 'RoomController.dart'; + +late var _callHandler; +final Map> routes = { + HttpMethod.GET: [ + ["/room/roomList", HttpResponseType.JSON, _callHandler.getRoomList, 2, true] + ], + HttpMethod.POST: [ + ["/room/addRoom", HttpResponseType.JSON, _callHandler.addRoom, 1, true], + [ + "/room/addOrderCheckIn", + HttpResponseType.JSON, + _callHandler.addOrderCheckIn, + 2, + true + ], + [ + "/room/delOrderCheckIn", + HttpResponseType.JSON, + _callHandler.delOrderCheckIn, + 1, + true + ], + [ + "/room/addRuzhuCheckIn", + HttpResponseType.JSON, + _callHandler.addRuzhuCheckIn, + 2, + true + ], + ["/room/checkout", HttpResponseType.JSON, _callHandler.checkout, 2, true] + ], + HttpMethod.PUT: [ + [ + "/room/updateRoom", + HttpResponseType.JSON, + _callHandler.updateRoom, + 1, + true + ] + ], + HttpMethod.DELETE: [ + [ + "/room/deleteRoom", + HttpResponseType.JSON, + _callHandler.deleteRoom, + 1, + true + ] + ], +}; diff --git a/bin/controller/RoomTypeController.dart b/bin/controller/RoomTypeController.dart new file mode 100644 index 0000000..1e05b4b --- /dev/null +++ b/bin/controller/RoomTypeController.dart @@ -0,0 +1,122 @@ +import 'dart:convert'; +import 'package:EasyDartModule/EasyDartModule.dart'; +import 'package:EasyDartModule/base/webserver/WebServer.dart'; + +import '../model/RoomType.dart'; +import '../service/RoomTypeService.dart'; +import '../model/ApiResponse.dart'; +import '../const/HttpStatusCode.dart'; +import '../const/MessageConstants.dart'; +import '../const/ResponseJsonCode.dart'; + +part 'RoomTypeController.route.dart'; +@RequestMapping(path: "/roomType") +class RoomTypeController { + final RoomTypeService roomTypeService = RoomTypeService(); + set callHandler(handler) => _callHandler = handler; + Map> get routeMap => routes; + + RoomTypeController(); + + // 获取房间类型列表 + @RequestMapping(path: "/roomTypeList", method: HttpMethod.GET) + Future getRoomTypeList(Request request, Map jwt) async { + ApiResponse>> apiResponse = ApiResponse(); + try { + var queryParameters = request.requestedUri.queryParameters; + RoomType query = RoomType.fromQueryParameters(queryParameters,jwt); + List roomTypeList = await roomTypeService.getRoomTypeList(query); + int roomTypeCount = await roomTypeService.getRoomTypeCount(query); + List> roomTypeListMap = + roomTypeList.map((e) => e as Map).toList(); // 强制转换 + apiResponse.code = ResponseJsonCode.success; + apiResponse.data = + roomTypeListMap; + apiResponse.total = roomTypeCount; + String serializedJson = apiResponse.serialize(); + return Response(HttpStatusCode.ok, body: serializedJson); // 发送响应 + } catch (e) { + apiResponse.code = ResponseJsonCode.fail; + apiResponse.message = "查询失败: $e"; // 包含异常信息 + String serializedJson = apiResponse.serialize(); + return Response(HttpStatusCode.internalServerError, body: serializedJson); + } + } + + // 添加房间类型 + @RequestMapping(path: "/addRoomType", method: HttpMethod.POST) + Future addRoomType(Request request) async { + ApiResponse apiResponse = ApiResponse(); + try { + var data = jsonDecode(await request.readAsString()); + var roomType = RoomType.fromJson(data); + var result = await roomTypeService.addRoomType(roomType); + apiResponse.code = ResponseJsonCode.success; + apiResponse.message = MessageConstants.ADD_SUCCESS; + String serializedJson = apiResponse.serialize(); + return Response(HttpStatusCode.ok, body: serializedJson); // 发送成功响应 + } catch (e) { + apiResponse.code = ResponseJsonCode.fail; + apiResponse.message = MessageConstants.ADD_ERROR; // 包含异常信息 + String serializedJson = apiResponse.serialize(); + return Response(HttpStatusCode.internalServerError, + body: serializedJson); // 发送失败响应 + } + } + + // 更新房间类型 + @RequestMapping(path: "/updateRoomType", method: HttpMethod.PUT) + Future updateRoomType(Request request) async { + ApiResponse apiResponse = ApiResponse(); + try { + var data = jsonDecode(await request.readAsString()); + var roomTypeId = data['_id']; + var updatedRoomType = RoomType.fromJson(data); + if (updatedRoomType.id == null || updatedRoomType.id!.isEmpty) { + apiResponse.code = ResponseJsonCode.fail; + apiResponse.message = "房间类型ID不能为空"; + String serializedJson = apiResponse.serialize(); + return Response(HttpStatusCode.ok, body: serializedJson); + } + var result = + await roomTypeService.updateRoomType(roomTypeId, updatedRoomType); + apiResponse.code = ResponseJsonCode.success; + apiResponse.message = result; + String serializedJson = apiResponse.serialize(); + return Response(HttpStatusCode.ok, body: serializedJson); // 发送成功响应 + } catch (e) { + apiResponse.code = ResponseJsonCode.fail; + apiResponse.message = "更新失败: $e"; // 包含异常信息 + String serializedJson = apiResponse.serialize(); + return Response(HttpStatusCode.internalServerError, + body: serializedJson); // 发送失败响应 + } + } + + // 删除房间类型 + @RequestMapping(path: "/deleteRoomType", method: HttpMethod.DELETE) + Future deleteRoomType(Request request) async { + ApiResponse apiResponse = ApiResponse(); + try { + var data = jsonDecode(await request.readAsString()); + var roomTypeId = data['id']; + var result = await roomTypeService.deleteRoomType(roomTypeId); + if (result.isEmpty) { + apiResponse.code = ResponseJsonCode.success; + apiResponse.message = MessageConstants.DELETE_SUCCESS; + String serializedJson = apiResponse.serialize(); + return Response(HttpStatusCode.ok, body: serializedJson); // 发送成功响应 + } + apiResponse.code = ResponseJsonCode.fail; + apiResponse.message = result; + String serializedJson = apiResponse.serialize(); + return Response(HttpStatusCode.ok, body: serializedJson); + } catch (e) { + apiResponse.code = ResponseJsonCode.fail; + apiResponse.message = MessageConstants.DELETE_ERROR; // 包含异常信息 + String serializedJson = apiResponse.serialize(); + return Response(HttpStatusCode.internalServerError, + body: serializedJson); // 发送失败响应 + } + } +} diff --git a/bin/controller/RoomTypeController.route.dart b/bin/controller/RoomTypeController.route.dart new file mode 100644 index 0000000..850c7df --- /dev/null +++ b/bin/controller/RoomTypeController.route.dart @@ -0,0 +1,47 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +// ************************************************************************** +// RouteGenerator +// ************************************************************************** + +part of 'RoomTypeController.dart'; + +late var _callHandler; +final Map> routes = { + HttpMethod.GET: [ + [ + "/roomType/roomTypeList", + HttpResponseType.JSON, + _callHandler.getRoomTypeList, + 2, + true + ] + ], + HttpMethod.POST: [ + [ + "/roomType/addRoomType", + HttpResponseType.JSON, + _callHandler.addRoomType, + 1, + true + ] + ], + HttpMethod.PUT: [ + [ + "/roomType/updateRoomType", + HttpResponseType.JSON, + _callHandler.updateRoomType, + 1, + true + ] + ], + HttpMethod.DELETE: [ + [ + "/roomType/deleteRoomType", + HttpResponseType.JSON, + _callHandler.deleteRoomType, + 1, + true + ] + ], +}; diff --git a/bin/enum/BedStatus.dart b/bin/enum/BedStatus.dart new file mode 100644 index 0000000..37ad812 --- /dev/null +++ b/bin/enum/BedStatus.dart @@ -0,0 +1,11 @@ +enum BedStatus { + using(0, "使用中"), //使用中 + no_using(1, "未使用"); //未使用 + + // 枚举的值 + final int code; // 整数值 + final String description; // 字符串描述 + + // 构造函数 + const BedStatus(this.code, this.description); +} diff --git a/bin/enum/DeviceStatus.dart b/bin/enum/DeviceStatus.dart new file mode 100644 index 0000000..7b5169f --- /dev/null +++ b/bin/enum/DeviceStatus.dart @@ -0,0 +1,11 @@ +enum DeviceStatus { + OFFLONE(0, "离线"), //离线 + ONLINE(1, "在线"); //在线 + + // 枚举的值 + final int code; // 整数值 + final String description; // 字符串描述 + + // 构造函数 + const DeviceStatus(this.code, this.description); +} diff --git a/bin/enum/MessageStatus.dart b/bin/enum/MessageStatus.dart new file mode 100644 index 0000000..95988b3 --- /dev/null +++ b/bin/enum/MessageStatus.dart @@ -0,0 +1,13 @@ +enum MessageStatus { + //消息状态 0:无需处理 1:待处理 2:已处理 + notify(0, "无需处理"), + waring(1, "待处理"), + dealed(2, "已处理"); + + // 枚举的值 + final int code; // 整数值 + final String description; // 字符串描述 + + // 构造函数 + const MessageStatus(this.code, this.description); +} diff --git a/bin/enum/ReportStatus.dart b/bin/enum/ReportStatus.dart new file mode 100644 index 0000000..afbf2d0 --- /dev/null +++ b/bin/enum/ReportStatus.dart @@ -0,0 +1,80 @@ +/// 报告状态枚举 +enum ReportStatus { + experienceing, // 0 - 体验中 ok + generating, // 1 - 生成报告中 ok + appNormalClose, // 2 - APP正常关闭 ok + appAbnormalClose, // 3 - APP异常关闭 ok 可以捕获到的异常 + appActiveClose, // 4 - APP主动关闭 ok + reportExceptionClose,// 5 - 报告生成异常关闭 ok + completed, // 9 - 完成 + //网络断掉了怎么办?todo websocket心跳 弹窗提示 微信视频结束之后要将微信标志重置 监听网络状态 + //网络 蓝牙 视频播放 设备连接 + //todo 监听网络状态 失败了停止播放视频 + //todo 监听蓝牙状态 断掉就停止播放视频并且发送异常关闭 + //todo 重新打开app +} + +/// 扩展方法,提供数字映射和文本描述 +extension ReportStatusExtension on ReportStatus { + /// 获取对应的数字状态值 + int get value { + switch (this) { + case ReportStatus.experienceing: + return 0; + case ReportStatus.generating: + return 1; + case ReportStatus.appNormalClose: + return 2; + case ReportStatus.appAbnormalClose: + return 3; + case ReportStatus.appActiveClose: + return 4; + case ReportStatus.reportExceptionClose: + return 5; + case ReportStatus.completed: + return 9; + } + } + + /// 获取文本描述 + String get label { + switch (this) { + case ReportStatus.experienceing: + return "体验中"; + case ReportStatus.generating: + return "生成报告中"; + case ReportStatus.appNormalClose: + return "APP正常关闭"; + case ReportStatus.appAbnormalClose: + return "APP异常关闭"; + case ReportStatus.appActiveClose: + return "APP主动关闭"; + case ReportStatus.reportExceptionClose: + return "报告生成异常关闭"; + case ReportStatus.completed: + return "完成"; + } + } + + /// 根据数字获取枚举 + static ReportStatus fromValue(int value) { + switch (value) { + case 0: + return ReportStatus.experienceing; + case 1: + return ReportStatus.generating; + case 2: + return ReportStatus.appNormalClose; + case 3: + return ReportStatus.appAbnormalClose; + case 4: + return ReportStatus.appActiveClose; + case 5: + return ReportStatus.reportExceptionClose; + case 9: + return ReportStatus.completed; + default: + throw Exception("未知报告状态: $value"); + } + } +} diff --git a/bin/enum/StatisticsResultType.dart b/bin/enum/StatisticsResultType.dart new file mode 100644 index 0000000..26131ef --- /dev/null +++ b/bin/enum/StatisticsResultType.dart @@ -0,0 +1,11 @@ +enum StatisticsResultType { + score(1, "睡眠评分统计"), + hrv(2, "hrv统计"); + + // 枚举的值 + final int code; // 整数值 + final String description; // 字符串描述 + + // 构造函数 + const StatisticsResultType(this.code, this.description); +} diff --git a/bin/enum/StatisticsType.dart b/bin/enum/StatisticsType.dart new file mode 100644 index 0000000..7f55af9 --- /dev/null +++ b/bin/enum/StatisticsType.dart @@ -0,0 +1,12 @@ +enum StatisticsType { + area("1", "区域统计"), + room("2", "房间统计"), + person("3", "个人统计"); //在线 + + // 枚举的值 + final String code; // 整数值 + final String description; // 字符串描述 + + // 构造函数 + const StatisticsType(this.code, this.description); +} diff --git a/bin/handler/MqttHandler.dart b/bin/handler/MqttHandler.dart new file mode 100644 index 0000000..f27b0ca --- /dev/null +++ b/bin/handler/MqttHandler.dart @@ -0,0 +1,17 @@ + +class MqttHandler { + + + // 报警处理 单独线程 todo + void message(String topic, String msg) { + // print("topic: $topic, msg:$msg"); + try { + // statisticsService.saveDeviceStatus(msg); + // alarmRuleService.judgeInstantAlarm(msg); + } catch (e) { + // print(e); + } + //遍历路径获取匹配的topic 进行websocket数据转发 + // _topicPathHandler.forwardMessageByTopic(topic, msg); + } +} diff --git a/bin/main.dart b/bin/main.dart new file mode 100644 index 0000000..fe6a864 --- /dev/null +++ b/bin/main.dart @@ -0,0 +1,211 @@ +import 'dart:convert'; +import 'dart:io'; + +import 'package:EasyDartModule/EasyDartModule.dart'; +import 'package:EasyDartModule/base/database/DataBase.dart'; +import 'package:EasyDartModule/base/discovery/Discovery.dart'; +import 'package:EasyDartModule/base/logger/Logger.dart'; +import 'package:EasyDartModule/base/mqtt/mqtt.dart'; +import 'package:EasyDartModule/base/redis/redis.dart'; +import 'package:EasyDartModule/base/storage/Storage.dart'; +import 'package:EasyDartModule/base/websocket/WebSocket.dart'; + +import './const/Constants.dart'; +import './controller/AreaController.dart'; +import './controller/BedController.dart'; +import './controller/BedTypeController.dart'; +import './controller/DiseaseTypeController.dart'; +import './controller/PersonController.dart'; +import './controller/PersonTypeController.dart'; +import './controller/RoomController.dart'; +import './controller/RoomTypeController.dart'; +// import './controller/StatisticsController.dart'; +// import './service/AlarmRuleService.dart'; +import './controller/FileUploadController.dart'; + +import 'handler/MqttHandler.dart'; +import 'const/ServiceConstant.dart'; +// import 'service/DailyTaskService.dart'; + +import './const/CommonVariables.dart'; + +void main(List args) async { + if (true) { + initEasyDartModule(); + await EasyDartModule.redis.connect(); + // return; + } + if (false) { + String? ep = Platform.environment["vsbs_server_port"]; + int port = ep == null ? 9200 : int.parse(ep); + String nacosServer = + Platform.environment["nacos_server"] ?? "http://10.20.1.2:8848"; + String nacosNameSpaceId = Platform.environment["nacos_namespaceId"] ?? + "d3b43bfe-f584-4b8f-a390-353abc69c856"; + String nacosBindIp = Platform.environment["nacos_bindIp"] ?? ""; + //初始化服务发现 + EasyDartModule.init( + discoveryConfig: + DiscoveryConfig(host: nacosServer, namespaceId: nacosNameSpaceId)); + //注册实例 + await EasyDartModule.discovery + .registerInstance(Constants.serviceName, nacosBindIp, Constants.port); + + //查询日志服务配置信息 + String logger = await EasyDartModule.discovery.getConfig("logger"); + var loggerConfig = jsonDecode(logger); + //查询数据库配置信息 + String mongodb = await EasyDartModule.discovery.getConfig("mongodb"); + var mongodbConfig = jsonDecode(mongodb); + //查询存储配置 + String storage = await EasyDartModule.discovery.getConfig("storage"); + var storageConfig = jsonDecode(storage); + //查询mqtt配置 + String mqtt = await EasyDartModule.discovery.getConfig("mqtt"); + var mqttConfig = jsonDecode(mqtt); + var redisConfig = + jsonDecode(await EasyDartModule.discovery.getConfig("redis")); + + var gatewayConfig = + jsonDecode(await EasyDartModule.discovery.getConfig("gateway")); + ServiceConstant.service_address = gatewayConfig["host"]; +// ServiceConstant.service_address = "https://vsbst-api.he-info.cn"; + + MqttHandler mqttHandler = MqttHandler(); + + EasyDartModule.init( + loggerConfig: LoggerConfig( + host: loggerConfig["host"], serviceName: Constants.serviceName), + dataBaseConfig: DataBaseConfig( + host: mongodbConfig["host"], + userName: mongodbConfig["userName"], + password: mongodbConfig["password"], + dataBase: mongodbConfig["dataBase"]), + storageConfig: StorageConfig( + host: storageConfig["host"], + port: storageConfig["port"], + accessKey: storageConfig["accessKey"], + secretKey: storageConfig["secretKey"]), + mqttConfig: MqttConfig( + host: mqttConfig["host"], + clientId: mqttConfig["clientId"], + topic: [mqttConfig["topic"]], + messgae: (topic, msg) { + mqttHandler.message(topic, msg); + // print("topic: $topic, msg:$msg"); + }), + redisConfig: + RedisConfig(host: redisConfig["host"], port: redisConfig["port"])); + + EasyDartModule.webServer.addHandler(RoomController()); + EasyDartModule.webServer.addHandler(RoomTypeController()); + EasyDartModule.webServer.addHandler(BedTypeController()); + EasyDartModule.webServer.addHandler(BedController()); + EasyDartModule.webServer.addHandler(DiseaseTypeController()); + EasyDartModule.webServer.addHandler(PersonController()); + EasyDartModule.webServer.addHandler(PersonTypeController()); + // EasyDartModule.webServer.addHandler(StatisticsController()); + EasyDartModule.webServer.addHandler(AreaController()); + EasyDartModule.webServer.addHandler(FileUploadController()); + EasyDartModule.webServer.start(port); + + //测试mqtt 订阅 + // EasyDartModule.mqtt + // .subscribe("/vsbs/sensor/mattress/676a227a1e121f98e5000000", 0); + // EasyDartModule.mqtt.connect(); + // EasyDartModule.mqtt. + //推送 + // EasyDartModule.mqtt.publish(topic, msg); + //测试db + // Future.delayed(Duration(seconds: 5), () async { + // var db = EasyDartModule.dataBase; + // var r = await db.query("uc_sys_user"); + // print(r); + // }); + + //测试storage + // String bucketName = "test-bu"; + // String objectName = "/aa/bb/objectName.gif"; + // EasyDartModule.storage.createBucket(bucketName).then((v) { + // EasyDartModule.storage + // .uploadObject(bucketName, objectName, File("a.gif").readAsBytesSync()) + // .then((path) { + // print("上传文件: $path"); + // EasyDartModule.storage.getObject(bucketName, objectName).then((data) { + // print("下载文件"); + // File("b.gif").writeAsBytesSync(data); + // print("下载完毕"); + // }); + // }); + // // EasyDartModule.storage.deleteObject(bucketName, "objectName"); + // }); + + await EasyDartModule.redis.connect(); + + // AlarmRuleService(); + // DailyTaskService(); + // EasyDartModule.logger + // .info("${Constants.serviceName}启动完毕", tag: Constants.serviceName); + } +} + +void initEasyDartModule() { + try { + EasyDartModule.init( + loggerConfig: LoggerConfig( + host: ServiceConstant.logService, serviceName: "快检报告服务"), + redisConfig: RedisConfig(host: "192.168.1.129", port: 6379), + webSocketConfig: + WebSocketConfig(ServiceConstant.webSocketService, (data) { + // 接收到服务消息 + var json = jsonDecode(data); + // ef.log("[websokcet]:${json}"); + EasyDartModule.logger.info("[websokcet数据]:${json}"); + if (json['wsId'] != null) { + // ef.kvRoot.websocketId = json['wsId']; + } + if (json['code'] != null && json['code'] != 200) { + EasyDartModule.logger + .error("[websokcet数据]:websocket连接失败--》" + json['msg']); + } + if (json["path"] != null) { + var call = CommonVariables.callMap[json["path"]]; + if (call != null) { + try { + if (json['path'] != "/smartbed/connect") { + call(json["data"]); + } else { + call(json); + } + } catch (e) { + print(e); + } + } else { + print("未找到当前路径: ${json["path"]} 回调函数"); + EasyDartModule.logger.error("未找到当前路径: ${json["path"]} 回调函数"); + } + } + // print(data); + }, onOpen: () { + // 连接建立完毕 + // EasyDartModule.websocket + // .sendData(jsonEncode({"path": "/aa/bb", "type": 1})); + print("object"); + })); + + EasyDartModule.webServer.addHandler(RoomController()); + EasyDartModule.webServer.addHandler(RoomTypeController()); + EasyDartModule.webServer.addHandler(BedTypeController()); + EasyDartModule.webServer.addHandler(BedController()); + EasyDartModule.webServer.addHandler(DiseaseTypeController()); + EasyDartModule.webServer.addHandler(PersonController()); + EasyDartModule.webServer.addHandler(PersonTypeController()); + // EasyDartModule.webServer.addHandler(StatisticsController()); + EasyDartModule.webServer.addHandler(AreaController()); + EasyDartModule.webServer.addHandler(FileUploadController()); + EasyDartModule.webServer.start(9200,); + } catch (e) { + print(e); + EasyDartModule.logger.error("websocket连接失败--》:$e"); + } +} diff --git a/bin/model/ApiResponse.dart b/bin/model/ApiResponse.dart new file mode 100644 index 0000000..f6da16b --- /dev/null +++ b/bin/model/ApiResponse.dart @@ -0,0 +1,66 @@ +import 'dart:convert'; +import 'package:json_annotation/json_annotation.dart'; +import 'package:fixnum/fixnum.dart'; // 用于处理 Int64 类型 + +part 'ApiResponse.g.dart'; + +@JsonSerializable(genericArgumentFactories: true) +class ApiResponse { + int? code; + int? total; + T? data; + String? message; + + ApiResponse(); + + // JSON 反序列化 + factory ApiResponse.fromJson( + Map json, + T Function(Object? json) fromJsonT, + ) => + _$ApiResponseFromJson(json, fromJsonT); + + // JSON 序列化 + Map toJson(Object? Function(T value) toJsonT) => + _$ApiResponseToJson(this, toJsonT); + + // 添加自定义的 toJson 序列化方法,确保能正确序列化泛型数据 + String serialize() { + // 手动处理 data 中的 Int64 转换为 int + var serializedData = _serializeData(data); + return jsonEncode({ + 'code': code, + 'total': total, + 'data': serializedData, + 'message': message, + }); + } + + // 递归处理 data 中的每个项,转换 Int64 为 int + dynamic _serializeData(dynamic data) { + if (data is List) { + // 处理 List 中的 Int64 类型 + return data.map((e) => _serializeData(e)).toList(); + } else if (data is Map) { + // 处理 Map 中的 Int64 类型 + var map = Map.from(data); + map.forEach((key, value) { + if (value is Int64) { + map[key] = value.toInt(); + } else { + map[key] = _serializeData(value); + } + }); + return map; + } else if (data is Int64) { + // 如果是 Int64 类型,转换为 int + return data.toInt(); + } + return data; + } + + @override + String toString() { + return serialize(); + } +} diff --git a/bin/model/ApiResponse.g.dart b/bin/model/ApiResponse.g.dart new file mode 100644 index 0000000..188e6ed --- /dev/null +++ b/bin/model/ApiResponse.g.dart @@ -0,0 +1,40 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'ApiResponse.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +ApiResponse _$ApiResponseFromJson( + Map json, + T Function(Object? json) fromJsonT, +) => + ApiResponse() + ..code = (json['code'] as num?)?.toInt() + ..total = (json['total'] as num?)?.toInt() + ..data = _$nullableGenericFromJson(json['data'], fromJsonT) + ..message = json['message'] as String?; + +Map _$ApiResponseToJson( + ApiResponse instance, + Object? Function(T value) toJsonT, +) => + { + 'code': instance.code, + 'total': instance.total, + 'data': _$nullableGenericToJson(instance.data, toJsonT), + 'message': instance.message, + }; + +T? _$nullableGenericFromJson( + Object? input, + T Function(Object? json) fromJson, +) => + input == null ? null : fromJson(input); + +Object? _$nullableGenericToJson( + T? input, + Object? Function(T value) toJson, +) => + input == null ? null : toJson(input); diff --git a/bin/model/Area.dart b/bin/model/Area.dart new file mode 100644 index 0000000..62975c5 --- /dev/null +++ b/bin/model/Area.dart @@ -0,0 +1,37 @@ +import 'package:json_annotation/json_annotation.dart'; + +part 'Area.g.dart'; + +@JsonSerializable() +class Area { + @JsonKey(name: '_id') + String? id; // 区域id + String? area_name; // 区域名称 + String? area_desc; // 区域描述 + int? created_at; // 创建时间(毫秒) + int? updated_at; // 更新时间(毫秒) + String? created_by_id; // 创建人ID + String? created_by_name; // 创建人名称 + String? updated_by_id; // 更新人ID + String? updated_by_name; // 更新人名称 + String? oid; // 机构ID + int? deleted; // 是否删除 + String? points; // 坐标点集合 + String? tid; // 所属机构 + int? level; // 权限等级 + + Area(); + static Area fromJson(Map json) => _$AreaFromJson(json); + Map toJson() => _$AreaToJson(this); + + // 使用查询参数填充 Area 对象 + static Area fromQueryParameters(Map queryParameters, Map jwt) { + var json = {}; + queryParameters.forEach((key, value) { + json[key] = value; + }); + json['tid'] = jwt['tid']; + json['level'] = jwt['level']; + return Area.fromJson(json); + } +} \ No newline at end of file diff --git a/bin/model/Area.g.dart b/bin/model/Area.g.dart new file mode 100644 index 0000000..10a1fc8 --- /dev/null +++ b/bin/model/Area.g.dart @@ -0,0 +1,40 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'Area.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +Area _$AreaFromJson(Map json) => Area() + ..id = json['_id'] as String? + ..area_name = json['area_name'] as String? + ..area_desc = json['area_desc'] as String? + ..created_at = (json['created_at'] as num?)?.toInt() + ..updated_at = (json['updated_at'] as num?)?.toInt() + ..created_by_id = json['created_by_id'] as String? + ..created_by_name = json['created_by_name'] as String? + ..updated_by_id = json['updated_by_id'] as String? + ..updated_by_name = json['updated_by_name'] as String? + ..oid = json['oid'] as String? + ..deleted = (json['deleted'] as num?)?.toInt() + ..points = json['points'] as String? + ..tid = json['tid'] as String? + ..level = (json['level'] as num?)?.toInt(); + +Map _$AreaToJson(Area instance) => { + '_id': instance.id, + 'area_name': instance.area_name, + 'area_desc': instance.area_desc, + 'created_at': instance.created_at, + 'updated_at': instance.updated_at, + 'created_by_id': instance.created_by_id, + 'created_by_name': instance.created_by_name, + 'updated_by_id': instance.updated_by_id, + 'updated_by_name': instance.updated_by_name, + 'oid': instance.oid, + 'deleted': instance.deleted, + 'points': instance.points, + 'tid': instance.tid, + 'level': instance.level, + }; diff --git a/bin/model/Bed.dart b/bin/model/Bed.dart new file mode 100644 index 0000000..755f9d9 --- /dev/null +++ b/bin/model/Bed.dart @@ -0,0 +1,61 @@ +import 'package:json_annotation/json_annotation.dart'; + +part 'Bed.g.dart'; + +@JsonSerializable() +class Bed { + @JsonKey(name: '_id') + String? id; // 床位id + String? bed_type_id; // 床位类型ID + @JsonKey(ignore: true) + String? bed_type_name; // 床位类型名称 + String? bed_name; // 床位名称 + bool? is_mapped; // 是否映射 + String? mapped_coordinates; // 映射坐标点 + String? device_model; // 设备型号 + String? device_name; // 设备名称 + String? device_id; // 设备ID + int? status; // 当前状态 (0: 离线, 1: 在线) + int? created_at; // 创建时间(毫秒数) + int? updated_at; // 更新时间(毫秒数) + String? created_by_id; // 创建人ID + String? created_by_name; // 创建人名称 + String? updated_by_id; // 更新人ID + String? updated_by_name; // 更新人名称 + String? oid; // 机构ID + @JsonKey(ignore: true) + int? start_time; + @JsonKey(ignore: true) + int? end_time; + String? room_id; //房间id + + int? deleted; // 是否删除(逻辑删除标识) + String? tid; // 所属机构 + int? level; // 权限等级 + String? areaIds; //区域id集合 + String? roomIds; //房间id集合 + String? mapping; //是否映射 + String? device_status; //设备状态 + String? page; + String? limit; + List? deviceIds; + String? roomTypes; //房间类型 + + Bed(); + + // 从JSON中反序列化 + static Bed fromJson(Map json) => _$BedFromJson(json); + + // 转换成JSON + Map toJson() => _$BedToJson(this); + + static Bed fromQueryParameters(Map queryParameters, jwt) { + var json = {}; + queryParameters.forEach((key, value) { + json[key] = value; + }); + json['tid'] = jwt['tid']; + json['level'] = jwt['level']; + return Bed.fromJson(json); + } +} diff --git a/bin/model/Bed.g.dart b/bin/model/Bed.g.dart new file mode 100644 index 0000000..358e1b6 --- /dev/null +++ b/bin/model/Bed.g.dart @@ -0,0 +1,69 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'Bed.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +Bed _$BedFromJson(Map json) => Bed() + ..id = json['_id'] as String? + ..bed_type_id = json['bed_type_id'] as String? + ..bed_name = json['bed_name'] as String? + ..is_mapped = json['is_mapped'] as bool? + ..mapped_coordinates = json['mapped_coordinates'] as String? + ..device_model = json['device_model'] as String? + ..device_name = json['device_name'] as String? + ..device_id = json['device_id'] as String? + ..status = (json['status'] as num?)?.toInt() + ..created_at = (json['created_at'] as num?)?.toInt() + ..updated_at = (json['updated_at'] as num?)?.toInt() + ..created_by_id = json['created_by_id'] as String? + ..created_by_name = json['created_by_name'] as String? + ..updated_by_id = json['updated_by_id'] as String? + ..updated_by_name = json['updated_by_name'] as String? + ..oid = json['oid'] as String? + ..room_id = json['room_id'] as String? + ..deleted = (json['deleted'] as num?)?.toInt() + ..tid = json['tid'] as String? + ..level = (json['level'] as num?)?.toInt() + ..areaIds = json['areaIds'] as String? + ..roomIds = json['roomIds'] as String? + ..mapping = json['mapping'] as String? + ..device_status = json['device_status'] as String? + ..page = json['page'] as String? + ..limit = json['limit'] as String? + ..deviceIds = + (json['deviceIds'] as List?)?.map((e) => e as String).toList() + ..roomTypes = json['roomTypes'] as String?; + +Map _$BedToJson(Bed instance) => { + '_id': instance.id, + 'bed_type_id': instance.bed_type_id, + 'bed_name': instance.bed_name, + 'is_mapped': instance.is_mapped, + 'mapped_coordinates': instance.mapped_coordinates, + 'device_model': instance.device_model, + 'device_name': instance.device_name, + 'device_id': instance.device_id, + 'status': instance.status, + 'created_at': instance.created_at, + 'updated_at': instance.updated_at, + 'created_by_id': instance.created_by_id, + 'created_by_name': instance.created_by_name, + 'updated_by_id': instance.updated_by_id, + 'updated_by_name': instance.updated_by_name, + 'oid': instance.oid, + 'room_id': instance.room_id, + 'deleted': instance.deleted, + 'tid': instance.tid, + 'level': instance.level, + 'areaIds': instance.areaIds, + 'roomIds': instance.roomIds, + 'mapping': instance.mapping, + 'device_status': instance.device_status, + 'page': instance.page, + 'limit': instance.limit, + 'deviceIds': instance.deviceIds, + 'roomTypes': instance.roomTypes, + }; diff --git a/bin/model/BedType.dart b/bin/model/BedType.dart new file mode 100644 index 0000000..4bde4bb --- /dev/null +++ b/bin/model/BedType.dart @@ -0,0 +1,44 @@ +import 'package:json_annotation/json_annotation.dart'; + +part 'BedType.g.dart'; + +@JsonSerializable() +class BedType { + @JsonKey(name: '_id') + String? id; // 房间id + String? bed_type_name; // 床位类型名称 + String? description; // 类型描述 + int? created_at; // 创建时间(毫秒数) + int? updated_at; // 更新时间(毫秒数) + String? created_by_id; // 创建人ID + String? created_by_name; // 创建人名称 + String? updated_by_id; // 更新人ID + String? updated_by_name; // 更新人名称 + int? deleted; // 是否删除(逻辑删除标识) + String? oid; // 机构ID + @JsonKey(ignore: true) + int? start_time; + @JsonKey(ignore: true) + int? end_time; + String? tid; // 所属机构 + int? level; // 权限等级 + + BedType(); + + // 从JSON中反序列化 + static BedType fromJson(Map json) => _$BedTypeFromJson(json); + + // 转换成JSON + Map toJson() => _$BedTypeToJson(this); + + static BedType fromQueryParameters( + Map queryParameters, Map jwt) { + var json = {}; + queryParameters.forEach((key, value) { + json[key] = value; + }); + json['tid'] = jwt['tid']; + json['level'] = jwt['level']; + return BedType.fromJson(json); + } +} diff --git a/bin/model/BedType.g.dart b/bin/model/BedType.g.dart new file mode 100644 index 0000000..0216fc6 --- /dev/null +++ b/bin/model/BedType.g.dart @@ -0,0 +1,38 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'BedType.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +BedType _$BedTypeFromJson(Map json) => BedType() + ..id = json['_id'] as String? + ..bed_type_name = json['bed_type_name'] as String? + ..description = json['description'] as String? + ..created_at = (json['created_at'] as num?)?.toInt() + ..updated_at = (json['updated_at'] as num?)?.toInt() + ..created_by_id = json['created_by_id'] as String? + ..created_by_name = json['created_by_name'] as String? + ..updated_by_id = json['updated_by_id'] as String? + ..updated_by_name = json['updated_by_name'] as String? + ..deleted = (json['deleted'] as num?)?.toInt() + ..oid = json['oid'] as String? + ..tid = json['tid'] as String? + ..level = (json['level'] as num?)?.toInt(); + +Map _$BedTypeToJson(BedType instance) => { + '_id': instance.id, + 'bed_type_name': instance.bed_type_name, + 'description': instance.description, + 'created_at': instance.created_at, + 'updated_at': instance.updated_at, + 'created_by_id': instance.created_by_id, + 'created_by_name': instance.created_by_name, + 'updated_by_id': instance.updated_by_id, + 'updated_by_name': instance.updated_by_name, + 'deleted': instance.deleted, + 'oid': instance.oid, + 'tid': instance.tid, + 'level': instance.level, + }; diff --git a/bin/model/DictionaryType.dart b/bin/model/DictionaryType.dart new file mode 100644 index 0000000..e6dbaad --- /dev/null +++ b/bin/model/DictionaryType.dart @@ -0,0 +1,36 @@ +import 'package:json_annotation/json_annotation.dart'; + +part 'DictionaryType.g.dart'; + +@JsonSerializable() +class DictionaryType { + @JsonKey(name: '_id') + String? id; // 字典ID + String? dict_name; // 字典名称 + String? dict_type; // 字典类型 + String? status; // 状态 + String? create_by; // 创建者 + int? create_time; // 创建时间(毫秒) + String? update_by; // 更新者 + int? update_time; // 更新时间(毫秒) + String? remark; // 备注 + + DictionaryType(); + + // 从 JSON 创建 Dictionary 实例 + static DictionaryType fromJson(Map json) => _$DictionaryTypeFromJson(json); + + // 将 Dictionary 实例转换为 JSON + Map toJson() => _$DictionaryTypeToJson(this); + + // 使用查询参数填充 Dictionary 对象 + static DictionaryType fromQueryParameters(Map queryParameters, Map jwt) { + var json = {}; + queryParameters.forEach((key, value) { + json[key] = value; + }); + json['tid'] = jwt['tid']; + json['level'] = jwt['level']; + return DictionaryType.fromJson(json); + } +} \ No newline at end of file diff --git a/bin/model/DictionaryType.g.dart b/bin/model/DictionaryType.g.dart new file mode 100644 index 0000000..4fa302d --- /dev/null +++ b/bin/model/DictionaryType.g.dart @@ -0,0 +1,32 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'DictionaryType.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +DictionaryType _$DictionaryTypeFromJson(Map json) => + DictionaryType() + ..id = json['_id'] as String? + ..dict_name = json['dict_name'] as String? + ..dict_type = json['dict_type'] as String? + ..status = json['status'] as String? + ..create_by = json['create_by'] as String? + ..create_time = (json['create_time'] as num?)?.toInt() + ..update_by = json['update_by'] as String? + ..update_time = (json['update_time'] as num?)?.toInt() + ..remark = json['remark'] as String?; + +Map _$DictionaryTypeToJson(DictionaryType instance) => + { + '_id': instance.id, + 'dict_name': instance.dict_name, + 'dict_type': instance.dict_type, + 'status': instance.status, + 'create_by': instance.create_by, + 'create_time': instance.create_time, + 'update_by': instance.update_by, + 'update_time': instance.update_time, + 'remark': instance.remark, + }; diff --git a/bin/model/DiseaseType.dart b/bin/model/DiseaseType.dart new file mode 100644 index 0000000..40b9753 --- /dev/null +++ b/bin/model/DiseaseType.dart @@ -0,0 +1,47 @@ +import 'package:json_annotation/json_annotation.dart'; + +part 'DiseaseType.g.dart'; + +@JsonSerializable() +class DiseaseType { + @JsonKey(name: '_id') + String? id; // 疾病类型ID + String? disease_type_name; // 疾病类型名称 + String? description; // 类型描述 + int? created_at; // 创建时间(毫秒数) + int? updated_at; // 更新时间(毫秒数) + String? created_by_id; // 创建人ID + String? created_by_name; // 创建人名称 + String? updated_by_id; // 更新人ID + String? updated_by_name; // 更新人名称 + int? deleted; // 是否删除(逻辑删除标识) + String? oid; // 机构ID + @JsonKey(ignore: true) + int? start_time; + @JsonKey(ignore: true) + int? end_time; + String? color; //疾病颜色 + + int? num; //统计人数 + String? tid; // 所属机构 + int? level; // 权限等级 + + DiseaseType(); + + // 从JSON中反序列化 + static DiseaseType fromJson(Map json) => + _$DiseaseTypeFromJson(json); + + // 转换成JSON + Map toJson() => _$DiseaseTypeToJson(this); + + static DiseaseType fromQueryParameters(Map queryParameters, Map jwt) { + var json = {}; + queryParameters.forEach((key, value) { + json[key] = value; + }); + json['tid'] = jwt['tid']; + json['level'] = jwt['level']; + return DiseaseType.fromJson(json); + } +} diff --git a/bin/model/DiseaseType.g.dart b/bin/model/DiseaseType.g.dart new file mode 100644 index 0000000..857b83d --- /dev/null +++ b/bin/model/DiseaseType.g.dart @@ -0,0 +1,43 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'DiseaseType.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +DiseaseType _$DiseaseTypeFromJson(Map json) => DiseaseType() + ..id = json['_id'] as String? + ..disease_type_name = json['disease_type_name'] as String? + ..description = json['description'] as String? + ..created_at = (json['created_at'] as num?)?.toInt() + ..updated_at = (json['updated_at'] as num?)?.toInt() + ..created_by_id = json['created_by_id'] as String? + ..created_by_name = json['created_by_name'] as String? + ..updated_by_id = json['updated_by_id'] as String? + ..updated_by_name = json['updated_by_name'] as String? + ..deleted = (json['deleted'] as num?)?.toInt() + ..oid = json['oid'] as String? + ..color = json['color'] as String? + ..num = (json['num'] as num?)?.toInt() + ..tid = json['tid'] as String? + ..level = (json['level'] as num?)?.toInt(); + +Map _$DiseaseTypeToJson(DiseaseType instance) => + { + '_id': instance.id, + 'disease_type_name': instance.disease_type_name, + 'description': instance.description, + 'created_at': instance.created_at, + 'updated_at': instance.updated_at, + 'created_by_id': instance.created_by_id, + 'created_by_name': instance.created_by_name, + 'updated_by_id': instance.updated_by_id, + 'updated_by_name': instance.updated_by_name, + 'deleted': instance.deleted, + 'oid': instance.oid, + 'color': instance.color, + 'num': instance.num, + 'tid': instance.tid, + 'level': instance.level, + }; diff --git a/bin/model/Person.dart b/bin/model/Person.dart new file mode 100644 index 0000000..6bad0d5 --- /dev/null +++ b/bin/model/Person.dart @@ -0,0 +1,78 @@ +import 'package:json_annotation/json_annotation.dart'; + +part 'Person.g.dart'; + +@JsonSerializable() +class Person { + @JsonKey(name: '_id') + String? id; // 人员id + String? room_id; // 选择的房间id + String? room_name; // 选择的房间名称 + String? bed_id; // 选择的床位id + String? bed_name; // 选择的床位名称 + int? check_in_start_time; // 入住的开始时间(毫秒数) + int? check_in_end_time; // 入住的结束时间(毫秒数) + String? contact_name; // 联系人名称 + String? contact_relationship; // 联系人关系类型 + String? contact_phone; // 联系人手机号码 + String? person_name; // 人员姓名 + String? gender; // 性别 + String? ethnicity; // 民族 + String? person_type_id; // 人员类型id + String? person_type_name; // 人员类型名称 + String? id_card_number; // 身份证号码 + String? phone_number; // 手机号码 + String? service_level; // 服务等级 + String? health_info; // 健康信息 + String? height; // 身高 + String? weight; // 体重 + String? tid; // 机构ID + String? oid; // 机构ID + int? deleted; + int? created_at; // 创建时间(毫秒) + int? updated_at; // 更新时间(毫秒) + int? data_level; //数据等级 + + String? age; + String? desc; //备注 + int? level; // 权限等级 + // @JsonKey(ignore: true) + String? bed_ids; //床位id列表 + + //查询条件 + // @JsonKey(ignore: true) + String? query_gender; //性别 + // @JsonKey(ignore: true) + String? deviceID; //设备id + // @JsonKey(ignore: true) + String? status; //入住状态 + // @JsonKey(ignore: true) + String? start_time; + // @JsonKey(ignore: true) + String? end_time; + // @JsonKey(ignore: true) + String? query_person_type; + // @JsonKey(ignore: true) + String? page; + // @JsonKey(ignore: true) + String? limit; + + Person(); + + // 从JSON中反序列化 + static Person fromJson(Map json) => _$PersonFromJson(json); + + // 转换成JSON + Map toJson() => _$PersonToJson(this); + + static Person fromQueryParameters( + Map queryParameters, Map jwt) { + var json = {}; + queryParameters.forEach((key, value) { + json[key] = value; + }); + json['tid'] = jwt['tid']; + json['level'] = jwt['level']; + return Person.fromJson(json); + } +} diff --git a/bin/model/Person.g.dart b/bin/model/Person.g.dart new file mode 100644 index 0000000..5e378c5 --- /dev/null +++ b/bin/model/Person.g.dart @@ -0,0 +1,90 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'Person.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +Person _$PersonFromJson(Map json) => Person() + ..id = json['_id'] as String? + ..room_id = json['room_id'] as String? + ..room_name = json['room_name'] as String? + ..bed_id = json['bed_id'] as String? + ..bed_name = json['bed_name'] as String? + ..check_in_start_time = (json['check_in_start_time'] as num?)?.toInt() + ..check_in_end_time = (json['check_in_end_time'] as num?)?.toInt() + ..contact_name = json['contact_name'] as String? + ..contact_relationship = json['contact_relationship'] as String? + ..contact_phone = json['contact_phone'] as String? + ..person_name = json['person_name'] as String? + ..gender = json['gender'] as String? + ..ethnicity = json['ethnicity'] as String? + ..person_type_id = json['person_type_id'] as String? + ..person_type_name = json['person_type_name'] as String? + ..id_card_number = json['id_card_number'] as String? + ..phone_number = json['phone_number'] as String? + ..service_level = json['service_level'] as String? + ..health_info = json['health_info'] as String? + ..height = json['height'] as String? + ..weight = json['weight'] as String? + ..tid = json['tid'] as String? + ..oid = json['oid'] as String? + ..deleted = (json['deleted'] as num?)?.toInt() + ..created_at = (json['created_at'] as num?)?.toInt() + ..updated_at = (json['updated_at'] as num?)?.toInt() + ..data_level = (json['data_level'] as num?)?.toInt() + ..age = json['age'] as String? + ..desc = json['desc'] as String? + ..level = (json['level'] as num?)?.toInt() + ..bed_ids = json['bed_ids'] as String? + ..query_gender = json['query_gender'] as String? + ..deviceID = json['deviceID'] as String? + ..status = json['status'] as String? + ..start_time = json['start_time'] as String? + ..end_time = json['end_time'] as String? + ..query_person_type = json['query_person_type'] as String? + ..page = json['page'] as String? + ..limit = json['limit'] as String?; + +Map _$PersonToJson(Person instance) => { + '_id': instance.id, + 'room_id': instance.room_id, + 'room_name': instance.room_name, + 'bed_id': instance.bed_id, + 'bed_name': instance.bed_name, + 'check_in_start_time': instance.check_in_start_time, + 'check_in_end_time': instance.check_in_end_time, + 'contact_name': instance.contact_name, + 'contact_relationship': instance.contact_relationship, + 'contact_phone': instance.contact_phone, + 'person_name': instance.person_name, + 'gender': instance.gender, + 'ethnicity': instance.ethnicity, + 'person_type_id': instance.person_type_id, + 'person_type_name': instance.person_type_name, + 'id_card_number': instance.id_card_number, + 'phone_number': instance.phone_number, + 'service_level': instance.service_level, + 'health_info': instance.health_info, + 'height': instance.height, + 'weight': instance.weight, + 'tid': instance.tid, + 'oid': instance.oid, + 'deleted': instance.deleted, + 'created_at': instance.created_at, + 'updated_at': instance.updated_at, + 'data_level': instance.data_level, + 'age': instance.age, + 'desc': instance.desc, + 'level': instance.level, + 'bed_ids': instance.bed_ids, + 'query_gender': instance.query_gender, + 'deviceID': instance.deviceID, + 'status': instance.status, + 'start_time': instance.start_time, + 'end_time': instance.end_time, + 'query_person_type': instance.query_person_type, + 'page': instance.page, + 'limit': instance.limit, + }; diff --git a/bin/model/PersonType.dart b/bin/model/PersonType.dart new file mode 100644 index 0000000..340c039 --- /dev/null +++ b/bin/model/PersonType.dart @@ -0,0 +1,40 @@ +import 'package:json_annotation/json_annotation.dart'; + +part 'PersonType.g.dart'; + +@JsonSerializable() +class PersonType { + @JsonKey(name: '_id') + String? id; // 人员类型id + String? person_type_name; // 人员类型名称 + String? description; // 类型描述 + int? created_at; // 创建时间(毫秒数) + int? updated_at; // 更新时间(毫秒数) + String? created_by_id; // 创建人ID + String? created_by_name; // 创建人名称 + String? updated_by_id; // 更新人ID + String? updated_by_name; // 更新人名称 + int? deleted; // 是否删除(逻辑删除标识) + String? oid; // 机构ID + + String? tid; // 所属机构 + int? level; // 权限等级 + PersonType(); + + // 从JSON中反序列化 + static PersonType fromJson(Map json) => + _$PersonTypeFromJson(json); + + // 转换成JSON + Map toJson() => _$PersonTypeToJson(this); + + static PersonType fromQueryParameters(Map queryParameters, Map jwt) { + var json = {}; + queryParameters.forEach((key, value) { + json[key] = value; + }); + json['tid'] = jwt['tid']; + json['level'] = jwt['level']; + return PersonType.fromJson(json); + } +} diff --git a/bin/model/PersonType.g.dart b/bin/model/PersonType.g.dart new file mode 100644 index 0000000..cf38fad --- /dev/null +++ b/bin/model/PersonType.g.dart @@ -0,0 +1,39 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'PersonType.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +PersonType _$PersonTypeFromJson(Map json) => PersonType() + ..id = json['_id'] as String? + ..person_type_name = json['person_type_name'] as String? + ..description = json['description'] as String? + ..created_at = (json['created_at'] as num?)?.toInt() + ..updated_at = (json['updated_at'] as num?)?.toInt() + ..created_by_id = json['created_by_id'] as String? + ..created_by_name = json['created_by_name'] as String? + ..updated_by_id = json['updated_by_id'] as String? + ..updated_by_name = json['updated_by_name'] as String? + ..deleted = (json['deleted'] as num?)?.toInt() + ..oid = json['oid'] as String? + ..tid = json['tid'] as String? + ..level = (json['level'] as num?)?.toInt(); + +Map _$PersonTypeToJson(PersonType instance) => + { + '_id': instance.id, + 'person_type_name': instance.person_type_name, + 'description': instance.description, + 'created_at': instance.created_at, + 'updated_at': instance.updated_at, + 'created_by_id': instance.created_by_id, + 'created_by_name': instance.created_by_name, + 'updated_by_id': instance.updated_by_id, + 'updated_by_name': instance.updated_by_name, + 'deleted': instance.deleted, + 'oid': instance.oid, + 'tid': instance.tid, + 'level': instance.level, + }; diff --git a/bin/model/Reservation.dart b/bin/model/Reservation.dart new file mode 100644 index 0000000..5eaf532 --- /dev/null +++ b/bin/model/Reservation.dart @@ -0,0 +1,47 @@ +import 'package:json_annotation/json_annotation.dart'; + +part 'Reservation.g.dart'; + +@JsonSerializable() +class Reservation { + int? created_at; // 创建时间(毫秒数) + String? created_by_name; // 创建人名称 + int? updated_at; // 更新时间(毫秒数) + String? updated_by_name; // 更新人名称 + int? deleted; // 是否删除(逻辑删除标识) + String? room_id; // 房间ID + String? bed_id; // 床位ID + int? start_time; // 开始时间(毫秒数) + int? end_time; // 结束时间(毫秒数) + int? total_days; // 总天数 + String? contact_name; // 联系人名称 + String? relationship_type; // 关系类型 + String? phone_number; // 手机号码 + int? oid; // 机构id + String? desc; // 备注 + @JsonKey(name: '_id') + String? id; // ID + + String? tid; // 所属机构 + int? level; // 权限等级 + + Reservation(); + + // 从JSON中反序列化 + static Reservation fromJson(Map json) => + _$ReservationFromJson(json); + + // 转换成JSON + Map toJson() => _$ReservationToJson(this); + + // 辅助方法:从查询参数生成对象 + static Reservation fromQueryParameters(Map queryParameters, Map jwt) { + var json = {}; + queryParameters.forEach((key, value) { + json[key] = value; + }); + json['tid'] = jwt['tid']; + json['level'] = jwt['level']; + return Reservation.fromJson(json); + } +} diff --git a/bin/model/Reservation.g.dart b/bin/model/Reservation.g.dart new file mode 100644 index 0000000..0c7281c --- /dev/null +++ b/bin/model/Reservation.g.dart @@ -0,0 +1,49 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'Reservation.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +Reservation _$ReservationFromJson(Map json) => Reservation() + ..created_at = (json['created_at'] as num?)?.toInt() + ..created_by_name = json['created_by_name'] as String? + ..updated_at = (json['updated_at'] as num?)?.toInt() + ..updated_by_name = json['updated_by_name'] as String? + ..deleted = (json['deleted'] as num?)?.toInt() + ..room_id = json['room_id'] as String? + ..bed_id = json['bed_id'] as String? + ..start_time = (json['start_time'] as num?)?.toInt() + ..end_time = (json['end_time'] as num?)?.toInt() + ..total_days = (json['total_days'] as num?)?.toInt() + ..contact_name = json['contact_name'] as String? + ..relationship_type = json['relationship_type'] as String? + ..phone_number = json['phone_number'] as String? + ..oid = (json['oid'] as num?)?.toInt() + ..desc = json['desc'] as String? + ..id = json['_id'] as String? + ..tid = json['tid'] as String? + ..level = (json['level'] as num?)?.toInt(); + +Map _$ReservationToJson(Reservation instance) => + { + 'created_at': instance.created_at, + 'created_by_name': instance.created_by_name, + 'updated_at': instance.updated_at, + 'updated_by_name': instance.updated_by_name, + 'deleted': instance.deleted, + 'room_id': instance.room_id, + 'bed_id': instance.bed_id, + 'start_time': instance.start_time, + 'end_time': instance.end_time, + 'total_days': instance.total_days, + 'contact_name': instance.contact_name, + 'relationship_type': instance.relationship_type, + 'phone_number': instance.phone_number, + 'oid': instance.oid, + 'desc': instance.desc, + '_id': instance.id, + 'tid': instance.tid, + 'level': instance.level, + }; diff --git a/bin/model/Room.dart b/bin/model/Room.dart new file mode 100644 index 0000000..a5b4f7b --- /dev/null +++ b/bin/model/Room.dart @@ -0,0 +1,52 @@ +import 'package:json_annotation/json_annotation.dart'; + +part 'Room.g.dart'; + +@JsonSerializable() +class Room { + @JsonKey(name: '_id') + String? id; // 房间id + String? room_name; // 房间名称 + String? room_desc; // 房间描述 + double? bed_num; // 总床位数 + double? bed_num_use; // 剩余可用床位数 + String? room_type; // 房间类型 + // @JsonKey(ignore: true) + String? room_type_name; // 房间类型名称 + List? imgs; // 图片地址列表 + int? deleted; //是否删除 + int? created_at; // 创建时间(毫秒) + int? updated_at; // 更新时间(毫秒) + String? created_by_id; // 创建人ID + String? created_by_name; // 创建人名称 + String? updated_by_id; // 更新人ID + String? updated_by_name; // 更新人名称 + String? oid; // 机构ID + @JsonKey(ignore: true) + int? start_time; + @JsonKey(ignore: true) + int? end_time; + String? area_id; // 区域ID + String? area_name; // 区域名称 + + String? tid; // 所属机构 + int? level; // 权限等级 + int? bed_count;//床位总数 + int? bed_use_count;//床位为使用 + + Room(); + static Room fromJson(Map json) => _$RoomFromJson(json); + Map toJson() => _$RoomToJson(this); + + // 使用查询参数填充 RoomType 对象 + static Room fromQueryParameters( + Map queryParameters, Map jwt) { + var json = {}; + queryParameters.forEach((key, value) { + json[key] = value; + }); + json['tid'] = jwt['tid']; + json['level'] = jwt['level']; + return Room.fromJson(json); + } +} diff --git a/bin/model/Room.g.dart b/bin/model/Room.g.dart new file mode 100644 index 0000000..f5a34b1 --- /dev/null +++ b/bin/model/Room.g.dart @@ -0,0 +1,56 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'Room.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +Room _$RoomFromJson(Map json) => Room() + ..id = json['_id'] as String? + ..room_name = json['room_name'] as String? + ..room_desc = json['room_desc'] as String? + ..bed_num = (json['bed_num'] as num?)?.toDouble() + ..bed_num_use = (json['bed_num_use'] as num?)?.toDouble() + ..room_type = json['room_type'] as String? + ..room_type_name = json['room_type_name'] as String? + ..imgs = (json['imgs'] as List?)?.map((e) => e as String).toList() + ..deleted = (json['deleted'] as num?)?.toInt() + ..created_at = (json['created_at'] as num?)?.toInt() + ..updated_at = (json['updated_at'] as num?)?.toInt() + ..created_by_id = json['created_by_id'] as String? + ..created_by_name = json['created_by_name'] as String? + ..updated_by_id = json['updated_by_id'] as String? + ..updated_by_name = json['updated_by_name'] as String? + ..oid = json['oid'] as String? + ..area_id = json['area_id'] as String? + ..area_name = json['area_name'] as String? + ..tid = json['tid'] as String? + ..level = (json['level'] as num?)?.toInt() + ..bed_count = (json['bed_count'] as num?)?.toInt() + ..bed_use_count = (json['bed_use_count'] as num?)?.toInt(); + +Map _$RoomToJson(Room instance) => { + '_id': instance.id, + 'room_name': instance.room_name, + 'room_desc': instance.room_desc, + 'bed_num': instance.bed_num, + 'bed_num_use': instance.bed_num_use, + 'room_type': instance.room_type, + 'room_type_name': instance.room_type_name, + 'imgs': instance.imgs, + 'deleted': instance.deleted, + 'created_at': instance.created_at, + 'updated_at': instance.updated_at, + 'created_by_id': instance.created_by_id, + 'created_by_name': instance.created_by_name, + 'updated_by_id': instance.updated_by_id, + 'updated_by_name': instance.updated_by_name, + 'oid': instance.oid, + 'area_id': instance.area_id, + 'area_name': instance.area_name, + 'tid': instance.tid, + 'level': instance.level, + 'bed_count': instance.bed_count, + 'bed_use_count': instance.bed_use_count, + }; diff --git a/bin/model/RoomTest.dart b/bin/model/RoomTest.dart new file mode 100644 index 0000000..1c5ee6b --- /dev/null +++ b/bin/model/RoomTest.dart @@ -0,0 +1,26 @@ +import 'package:json_annotation/json_annotation.dart'; + +part 'RoomTest.g.dart'; + +@JsonSerializable() +class RoomTest { + String? room_id; // 房间id + String? room_name; // 房间名称 + String? room_desc; // 房间描述 + double? bed_num; // 总床位数 + double? bed_num_use; // 剩余可用床位数 + String? room_type; // 房间类型 + List? imgs; // 图片地址列表 + String? oid; // 机构ID + int? deleted; //是否删除 + int? created_at; // 创建时间(毫秒) + int? updated_at; // 更新时间(毫秒) + String? created_by_id; // 创建人ID + String? created_by_name; // 创建人名称 + String? updated_by_id; // 更新人ID + String? updated_by_name; // 更新人名称 + + RoomTest(); + static RoomTest fromJson(Map json) => _$RoomTestFromJson(json); + Map toJson() => _$RoomTestToJson(this); +} diff --git a/bin/model/RoomTest.g.dart b/bin/model/RoomTest.g.dart new file mode 100644 index 0000000..2b5edbd --- /dev/null +++ b/bin/model/RoomTest.g.dart @@ -0,0 +1,42 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'RoomTest.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +RoomTest _$RoomTestFromJson(Map json) => RoomTest() + ..room_id = json['room_id'] as String? + ..room_name = json['room_name'] as String? + ..room_desc = json['room_desc'] as String? + ..bed_num = (json['bed_num'] as num?)?.toDouble() + ..bed_num_use = (json['bed_num_use'] as num?)?.toDouble() + ..room_type = json['room_type'] as String? + ..imgs = (json['imgs'] as List?)?.map((e) => e as String).toList() + ..oid = json['oid'] as String? + ..deleted = (json['deleted'] as num?)?.toInt() + ..created_at = (json['created_at'] as num?)?.toInt() + ..updated_at = (json['updated_at'] as num?)?.toInt() + ..created_by_id = json['created_by_id'] as String? + ..created_by_name = json['created_by_name'] as String? + ..updated_by_id = json['updated_by_id'] as String? + ..updated_by_name = json['updated_by_name'] as String?; + +Map _$RoomTestToJson(RoomTest instance) => { + 'room_id': instance.room_id, + 'room_name': instance.room_name, + 'room_desc': instance.room_desc, + 'bed_num': instance.bed_num, + 'bed_num_use': instance.bed_num_use, + 'room_type': instance.room_type, + 'imgs': instance.imgs, + 'oid': instance.oid, + 'deleted': instance.deleted, + 'created_at': instance.created_at, + 'updated_at': instance.updated_at, + 'created_by_id': instance.created_by_id, + 'created_by_name': instance.created_by_name, + 'updated_by_id': instance.updated_by_id, + 'updated_by_name': instance.updated_by_name, + }; diff --git a/bin/model/RoomType.dart b/bin/model/RoomType.dart new file mode 100644 index 0000000..5b2bcf9 --- /dev/null +++ b/bin/model/RoomType.dart @@ -0,0 +1,47 @@ +import 'package:json_annotation/json_annotation.dart'; + +part 'RoomType.g.dart'; + +@JsonSerializable() +class RoomType { + @JsonKey(name: '_id') + String? id; // 房间类型ID + String? room_type_name; // 房间类型名称 + String? description; // 房间类型描述 + int? created_at; // 创建时间(毫秒) + int? updated_at; // 更新时间(毫秒) + String? created_by_id; // 创建人ID + String? created_by_name; // 创建人名称 + String? updated_by_id; // 更新人ID + String? updated_by_name; // 更新人名称 + String? oid; //机构id + @JsonKey(ignore: true) + int? start_time; + @JsonKey(ignore: true) + int? end_time; + int? deleted; + + String? tid; // 所属机构 + int? level; // 权限等级 + + RoomType(); + + // 从 JSON 中生成 RoomType 对象 + static RoomType fromJson(Map json) => + _$RoomTypeFromJson(json); + + // 将 RoomType 对象转化为 JSON + Map toJson() => _$RoomTypeToJson(this); + + // 使用查询参数填充 RoomType 对象 + static RoomType fromQueryParameters( + Map queryParameters, Map jwt) { + var json = {}; + queryParameters.forEach((key, value) { + json[key] = value; + }); + json['tid'] = jwt['tid']; + json['level'] = jwt['level']; + return RoomType.fromJson(json); + } +} diff --git a/bin/model/RoomType.g.dart b/bin/model/RoomType.g.dart new file mode 100644 index 0000000..df3a007 --- /dev/null +++ b/bin/model/RoomType.g.dart @@ -0,0 +1,38 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'RoomType.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +RoomType _$RoomTypeFromJson(Map json) => RoomType() + ..id = json['_id'] as String? + ..room_type_name = json['room_type_name'] as String? + ..description = json['description'] as String? + ..created_at = (json['created_at'] as num?)?.toInt() + ..updated_at = (json['updated_at'] as num?)?.toInt() + ..created_by_id = json['created_by_id'] as String? + ..created_by_name = json['created_by_name'] as String? + ..updated_by_id = json['updated_by_id'] as String? + ..updated_by_name = json['updated_by_name'] as String? + ..oid = json['oid'] as String? + ..deleted = (json['deleted'] as num?)?.toInt() + ..tid = json['tid'] as String? + ..level = (json['level'] as num?)?.toInt(); + +Map _$RoomTypeToJson(RoomType instance) => { + '_id': instance.id, + 'room_type_name': instance.room_type_name, + 'description': instance.description, + 'created_at': instance.created_at, + 'updated_at': instance.updated_at, + 'created_by_id': instance.created_by_id, + 'created_by_name': instance.created_by_name, + 'updated_by_id': instance.updated_by_id, + 'updated_by_name': instance.updated_by_name, + 'oid': instance.oid, + 'deleted': instance.deleted, + 'tid': instance.tid, + 'level': instance.level, + }; diff --git a/bin/model/StatisticsResult.dart b/bin/model/StatisticsResult.dart new file mode 100644 index 0000000..0fbdb1c --- /dev/null +++ b/bin/model/StatisticsResult.dart @@ -0,0 +1,33 @@ +import 'package:json_annotation/json_annotation.dart'; + +part 'StatisticsResult.g.dart'; + +@JsonSerializable() +class StatisticsResult { + @JsonKey(name: '_id') + String? id; // ID + int? type; // type 1睡眠评分统计 2.hrv统计 + int? start_time; // 开始时间 + int? end_time; // 结束时间 + String? data; // 统计数据 + StatisticsResult(); + + // 从 JSON 中生成 RoomType 对象 + static StatisticsResult fromJson(Map json) => + _$StatisticsResultFromJson(json); + + // 将 RoomType 对象转化为 JSON + Map toJson() => _$StatisticsResultToJson(this); + + // 使用查询参数填充 RoomType 对象 + static StatisticsResult fromQueryParameters( + Map queryParameters, Map jwt) { + var json = {}; + queryParameters.forEach((key, value) { + json[key] = value; + }); + json['tid'] = jwt['tid']; + json['level'] = jwt['level']; + return StatisticsResult.fromJson(json); + } +} diff --git a/bin/model/StatisticsResult.g.dart b/bin/model/StatisticsResult.g.dart new file mode 100644 index 0000000..adc3448 --- /dev/null +++ b/bin/model/StatisticsResult.g.dart @@ -0,0 +1,24 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'StatisticsResult.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +StatisticsResult _$StatisticsResultFromJson(Map json) => + StatisticsResult() + ..id = json['_id'] as String? + ..type = (json['type'] as num?)?.toInt() + ..start_time = (json['start_time'] as num?)?.toInt() + ..end_time = (json['end_time'] as num?)?.toInt() + ..data = json['data'] as String?; + +Map _$StatisticsResultToJson(StatisticsResult instance) => + { + '_id': instance.id, + 'type': instance.type, + 'start_time': instance.start_time, + 'end_time': instance.end_time, + 'data': instance.data, + }; diff --git a/bin/model/Test.dart b/bin/model/Test.dart new file mode 100644 index 0000000..183c3f5 --- /dev/null +++ b/bin/model/Test.dart @@ -0,0 +1 @@ +class Test {} \ No newline at end of file diff --git a/bin/model/WebSocketMessage.dart b/bin/model/WebSocketMessage.dart new file mode 100644 index 0000000..fa6d15d --- /dev/null +++ b/bin/model/WebSocketMessage.dart @@ -0,0 +1,18 @@ +import 'package:json_annotation/json_annotation.dart'; + +part 'WebSocketMessage.g.dart'; + +@JsonSerializable() +class WebSocketMessage { + String path; + int? type; + dynamic data; + String? to; + String? mac; + + WebSocketMessage({required this.path, this.type, this.data, this.to,this.mac}); + + static WebSocketMessage fromJson(Map json) => + _$WebSocketMessageFromJson(json); + Map toJson() => _$WebSocketMessageToJson(this); +} diff --git a/bin/model/WebSocketMessage.g.dart b/bin/model/WebSocketMessage.g.dart new file mode 100644 index 0000000..ee52f3b --- /dev/null +++ b/bin/model/WebSocketMessage.g.dart @@ -0,0 +1,25 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'WebSocketMessage.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +WebSocketMessage _$WebSocketMessageFromJson(Map json) => + WebSocketMessage( + path: json['path'] as String, + type: (json['type'] as num?)?.toInt(), + data: json['data'], + to: json['to'] as String?, + mac: json['mac'] as String?, + ); + +Map _$WebSocketMessageToJson(WebSocketMessage instance) => + { + 'path': instance.path, + 'type': instance.type, + 'data': instance.data, + 'to': instance.to, + 'mac': instance.mac, + }; diff --git a/bin/model/api_response.dart b/bin/model/api_response.dart new file mode 100644 index 0000000..f46cb05 --- /dev/null +++ b/bin/model/api_response.dart @@ -0,0 +1,29 @@ +class ApiResponse { + int? code; + T? data; + String? msg; + int? total; + dynamic rawResponse; // 原始 Dio 响应对象 + + ApiResponse({ + required this.code, + this.data, + this.msg, + this.total, + this.rawResponse, + }); + + factory ApiResponse.fromJson( + Map json, + T Function(Object?) fromJsonT, { + dynamic rawResponse, + }) { + return ApiResponse( + code: json['code'] as int?, + data: json['data'] != null ? fromJsonT(json['data']) : null, + msg: json['msg'] as String?, + total: json['total'] as int?, + rawResponse: rawResponse, // 保留 Dio 原始响应对象 + ); + } +} diff --git a/bin/model/app_uri_status.dart b/bin/model/app_uri_status.dart new file mode 100644 index 0000000..233fd91 --- /dev/null +++ b/bin/model/app_uri_status.dart @@ -0,0 +1,19 @@ +// lib/http_status_codes.dart + +class HttpStatusCodes { + // Success codes + static const int ok = 200; + static const int created = 201; + static const int accepted = 202; + + // Client error codes + static const int badRequest = 400; + static const int unauthorized = 401;//401 参数错误 + static const int forbidden = 403;//403 禁止,多条数据,不允许修改 + static const int notFound = 404;//404 没有报告 + + // Server error codes + static const int internalServerError = 500;//500 内部异常 + static const int notImplemented = 501; + static const int serviceUnavailable = 503; +} diff --git a/bin/model/dto/DiseaseStatistics.dart b/bin/model/dto/DiseaseStatistics.dart new file mode 100644 index 0000000..3552f93 --- /dev/null +++ b/bin/model/dto/DiseaseStatistics.dart @@ -0,0 +1,27 @@ +import 'package:json_annotation/json_annotation.dart'; +import '../DiseaseType.dart'; + +part 'DiseaseStatistics.g.dart'; + +@JsonSerializable() +class DiseaseStatistics { + int? total; // 总数 + List? disease_type_list; // 疾病类型列表 + + DiseaseStatistics(); + + // 从JSON中反序列化 + static DiseaseStatistics fromJson(Map json) => + _$DiseaseStatisticsFromJson(json); + + // 转换成JSON + Map toJson() => _$DiseaseStatisticsToJson(this); + + static DiseaseStatistics fromQueryParameters(Map queryParameters) { + var json = {}; + queryParameters.forEach((key, value) { + json[key] = value; + }); + return DiseaseStatistics.fromJson(json); + } +} diff --git a/bin/model/dto/DiseaseStatistics.g.dart b/bin/model/dto/DiseaseStatistics.g.dart new file mode 100644 index 0000000..9e41b78 --- /dev/null +++ b/bin/model/dto/DiseaseStatistics.g.dart @@ -0,0 +1,20 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'DiseaseStatistics.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +DiseaseStatistics _$DiseaseStatisticsFromJson(Map json) => + DiseaseStatistics() + ..total = (json['total'] as num?)?.toInt() + ..disease_type_list = (json['disease_type_list'] as List?) + ?.map((e) => DiseaseType.fromJson(e as Map)) + .toList(); + +Map _$DiseaseStatisticsToJson(DiseaseStatistics instance) => + { + 'total': instance.total, + 'disease_type_list': instance.disease_type_list, + }; diff --git a/bin/repository/AreaRepository.dart b/bin/repository/AreaRepository.dart new file mode 100644 index 0000000..658fab0 --- /dev/null +++ b/bin/repository/AreaRepository.dart @@ -0,0 +1,165 @@ +import 'package:EasyDartModule/EasyDartModule.dart'; +import '../model/Area.dart'; +import '../const/MessageConstants.dart'; + +class AreaRepository { + // 获取所有区域列表 + Future fetchAreaList(Area query, + {int page = 1, int pageSize = 10}) async { + var db = EasyDartModule.dataBase; + + // 构建查询条件 + SelectorBuilder select = SelectorBuilder(); + + // 添加查询条件 + if (query.oid != null) { + select.eq('oid', query.oid); + } + if (query.id != null) { + select.eq('area_id', query.id); + } + if (query.tid != null) { + select.eq('oid', query.tid); + } + if (query.level != null) { + select.gte('level', query.level); + } + if (query.area_name != null) { + select.match('area_name', query.area_name!, caseInsensitive: true); + } + if (query.area_desc != null) { + select.eq('area_desc', query.area_desc); + } + if (query.created_by_id != null) { + select.eq('created_by_id', query.created_by_id); + } + if (query.updated_by_id != null) { + select.eq('updated_by_id', query.updated_by_id); + } + if (query.created_at != null) { + select.gte('created_at', query.created_at); + } + if (query.updated_at != null) { + select.lte('updated_at', query.updated_at); + } + select.eq('deleted', 0); + // 设置分页 + select.skip((page - 1) * pageSize).limit(pageSize); + // 设置排序 + select.sortBy("created_at"); // 按创建时间排序 + + // 执行查询 + var result = await db.query( + 'bus_area_info', + condition: select, // 查询条件 + 分页 + 排序 + ); + + if (result.isEmpty) { + return []; + } + + return result; + } + + // 获取单个区域信息 + Future fetchAreaById(int areaId) async { + var db = EasyDartModule.dataBase; + + // 构建查询条件 + var condition = {'area_id': areaId}; + + // 执行查询 + var result = await db.query( + 'bus_area_info', + condition: condition, + ); + + if (result.isNotEmpty) { + return Area.fromJson(result.first); + } + + return null; + } + + // 添加区域 + Future insertArea(Area area) async { + var db = EasyDartModule.dataBase; + // 执行插入操作 + var result = await db.insert('bus_area_info', area.toJson()); + // 返回是否插入成功 + return true; + } + + // 更新区域信息 + Future updateArea(String areaId, Area updatedArea) async { + String message = ""; + var db = EasyDartModule.dataBase; + var str = updatedArea.toJson(); + str.remove("_id"); + var updateCondition = { + '_id': ObjectId.fromHexString(areaId), + }; + try { + var result = await db.update('bus_area_info', str, updateCondition); + return message; // 返回受影响的行数 + } catch (e) { + message = MessageConstants.UPDATE_ERROR; + return message; + } + } + + // 删除区域 (逻辑删除) + Future deleteArea(String areaId) async { + var db = EasyDartModule.dataBase; + String message = ""; + try { + var areaIdList = areaId.split(','); + var objectIdList = + areaIdList.map((id) => ObjectId.fromHexString(id)).toList(); + var condition = { + '_id': {'\$in': objectIdList} + }; // 使用 \$in 操作符查询多个 ID + var update = { + '\$set': {'deleted': 1} + }; // 逻辑删除,只更新 deleted 字段 + var result = await db.update('bus_area_info', update, condition); + return message; // 返回受影响的行数 + } catch (e) { + print("Error during deleteArea: $e"); + message = MessageConstants.DELETE_ERROR; + return message; + } + } + + // 获取区域数量 + Future getAreaCount(Area query) async { + var db = EasyDartModule.dataBase; + + // 构建查询条件 + SelectorBuilder select = SelectorBuilder(); + + if (query.id != null) { + select.eq('_id', query.id); + } + if (query.tid != null) { + select.eq('oid', query.tid); + } + if (query.level != null) { + select.gte('level', query.level); + } + if (query.area_name != null) { + select.match('area_name', query.area_name!, caseInsensitive: true); + } + if (query.area_desc != null) { + select.eq('area_desc', query.area_desc); + } + select.eq('deleted', 0); + // 执行查询并返回计数 + var result = await db.query( + 'bus_area_info', + condition: select, + ); + + return result.length; + } +} diff --git a/bin/repository/BedRepository.dart b/bin/repository/BedRepository.dart new file mode 100644 index 0000000..5ed72e6 --- /dev/null +++ b/bin/repository/BedRepository.dart @@ -0,0 +1,481 @@ +import 'package:EasyDartModule/EasyDartModule.dart'; + +import '../const/MessageConstants.dart'; +import '../model/Bed.dart'; +import '../model/Person.dart'; +import '../model/Reservation.dart'; +import '../enum/DeviceStatus.dart'; +import '../const/Constants.dart'; + +class BedRepository { + // 获取床位列表,支持查询条件 + Future fetchBedList(Bed query) async { + var db = EasyDartModule.dataBase; + SelectorBuilder select = SelectorBuilder(); + // 添加查询条件 + if (query.id != null) { + select.eq('_id', query.id); + } + if (query.tid != null) { + select.eq('oid', query.tid); + } + if (query.level != null) { + select.gte('data_level', query.level); + } + if (query.room_id != null) { + // List roomTypes = query.roomIds!.split(','); + // select.oneFrom('room_id', roomTypes); + select.eq('room_id', query.room_id); + } + if (query.mapping != null) { + if (query.mapping!.length == 1) { + if (query.mapping == "1") { + select.nin('mapped_coordinates', [null, '']); + } else if (query.mapping == "0") { + select.oneFrom('mapped_coordinates', [null, '']); + } + } + } + if (query.device_status != null) { + List deviceIdList = []; + if (query.device_status!.length == 1) { + var allDevices = + await EasyDartModule.redis.get("oid_${query.tid}_devices"); + if (allDevices != null) { + if (query.device_status == DeviceStatus.ONLINE.code.toString()) { + if (allDevices != null && allDevices.isNotEmpty) { + List deviceIds = allDevices.split(','); + for (var deviceId in deviceIds) { + var deviceStatus = + await EasyDartModule.redis.get("mac_$deviceId"); + if (deviceStatus != null && deviceStatus.isNotEmpty) { + deviceIdList.add(deviceId); + } + } + } + if (deviceIdList.isNotEmpty) { + select.oneFrom('device_id', deviceIdList); + } else { + return []; + } + } else if (query.device_status == + DeviceStatus.OFFLONE.code.toString()) { + if (allDevices != null && allDevices.isNotEmpty) { + List deviceIds = allDevices.split(','); + for (var deviceId in deviceIds) { + var deviceStatus = + await EasyDartModule.redis.get("mac_$deviceId"); + if (deviceStatus == null || deviceStatus.isEmpty) { + deviceIdList.add(deviceId); + } + } + if (deviceIdList.isNotEmpty) { + select.oneFrom('device_id', deviceIdList); + } + } + } + } + } + } + if (query.areaIds != null) { + List areaIds = query.areaIds!.split(','); + SelectorBuilder newSelect = SelectorBuilder(); + var newquery = newSelect.oneFrom('area_id', areaIds); + var result = await db.query( + 'bus_room_info', + condition: newquery, + ); + if (result.isNotEmpty) { + List roomIds = []; + for (var item in result) { + roomIds.add(item['_id'].toHexString()); + } + select.oneFrom('room_id', roomIds); + } + } + if (query.room_id != null) { + select.eq('room_id', query.room_id); + } + if (query.bed_type_id != null) { + // select.eq('bed_type_id', query.bed_type_id); + List roomTypes = query.bed_type_id!.split(','); + select.oneFrom('bed_type_id', roomTypes); + } + if (query.bed_type_name != null) { + select.match('bed_type_name', query.bed_type_name!, + caseInsensitive: true); + } + if (query.bed_name != null) { + select.match('bed_name', query.bed_name!, caseInsensitive: true); + } + if (query.is_mapped != null) { + select.eq('is_mapped', query.is_mapped == true ? 1 : 0); + } + if (query.device_model != null) { + select.match('device_model', query.device_model!, caseInsensitive: true); + } + if (query.device_name != null) { + select.match('device_name', query.device_name!, caseInsensitive: true); + } + if (query.device_id != null) { + select.match('device_id', query.device_id!, caseInsensitive: false); + } + if (query.status != null) { + select.eq('status', query.status); + } + if (query.created_by_id != null) { + select.eq('created_by_id', query.created_by_id); + } + if (query.updated_by_id != null) { + select.eq('updated_by_id', query.updated_by_id); + } + if (query.oid != null) { + select.eq('oid', query.oid); + } + if (query.start_time != null) { + select.gte('created_at', query.start_time); + } + if (query.end_time != null) { + select.lte('created_at', query.end_time); + } + if (query.deviceIds != null && query.deviceIds!.isNotEmpty) { + select.oneFrom('device_id', query.deviceIds!); + } + select.eq('deleted', 0); + // 设置分页 + select + .skip(((int.tryParse(query.page ?? Constants.default_page.toString()) ?? + Constants.default_page) - + 1) * + (int.tryParse(query.limit ?? Constants.default_limit.toString()) ?? + Constants.default_limit)) + .limit( + int.tryParse(query.limit ?? Constants.default_limit.toString()) ?? + Constants.default_limit); + + // 设置排序 + select.sortBy("created_at"); // 按创建时间排序 + // 执行查询 + var result = await db.query('bus_bed_info', condition: select); + + // 如果查询结果为空,返回空列表 + return result.isEmpty ? [] : result; + } + + // 获取单个床位信息 + Future fetchBedById(String bedId) async { + var db = EasyDartModule.dataBase; + var condition = {'_id': ObjectId.fromHexString(bedId)}; // 使用 bed_id 作为条件 + var result = await db.query('bus_bed_info', condition: condition); + return result.isNotEmpty ? result.first : null; + } + + // 插入床位信息 + Future insertBed(Bed bed) async { + var db = EasyDartModule.dataBase; + int currentTime = DateTime.now().millisecondsSinceEpoch; + bed.created_at = currentTime; + bed.updated_at = currentTime; + bed.deleted = 0; // 初始化为未删除 + var result = await db.insert('bus_bed_info', bed.toJson()); + return true; + } + + // 更新床位信息 + Future updateBed(String bedId, Bed updatedBed) async { + var db = EasyDartModule.dataBase; + String message = ""; + updatedBed.updated_at = DateTime.now().millisecondsSinceEpoch; + var condition = {'bed_id': bedId}; // 使用 bed_id 作为条件 + try { + var result = + await db.update('bus_bed_info', updatedBed.toJson(), condition); + message = MessageConstants.UPDATE_SUCCESS; + } catch (e) { + message = MessageConstants.UPDATE_ERROR; + } + return message; + } + + // 删除床位(逻辑删除) + Future deleteBed(String bedId) async { + var db = EasyDartModule.dataBase; + String message = ""; + var condition = {'bed_id': bedId}; // 使用 bed_id 作为查询条件 + var result = await db.query('bus_bed_info', condition: condition); + + if (result.isNotEmpty) { + // 标记为已删除 + var update = {'deleted': 1}; + try { + var updateResult = await db.update('bus_bed_info', update, condition); + message = MessageConstants.DELETE_SUCCESS; + } catch (e) { + message = MessageConstants.DELETE_ERROR; + } + } else { + message = "未找到床位"; + } + return message; + } + + Future getBedCount(Bed query) async { + var db = EasyDartModule.dataBase; + SelectorBuilder select = SelectorBuilder(); + + // 添加查询条件 + if (query.id != null) { + select.eq('_id', query.id); + } + if (query.tid != null) { + select.eq('oid', query.tid); + } + if (query.level != null) { + select.gte('data_level', query.level); + } + if (query.room_id != null) { + // List roomTypes = query.roomIds!.split(','); + // select.oneFrom('room_id', roomTypes); + select.eq('room_id', query.room_id); + } + if (query.mapping != null) { + if (query.mapping!.length == 1) { + if (query.mapping == "1") { + select.nin('mapped_coordinates', [null, '']); + } else if (query.mapping == "0") { + select.oneFrom('mapped_coordinates', [null, '']); + } + } + } + if (query.device_status != null) { + List deviceIdList = []; + if (query.device_status!.length == 1) { + var allDevices = + await EasyDartModule.redis.get("oid_${query.tid}_devices"); + if (allDevices != null) { + if (query.device_status == DeviceStatus.ONLINE.code.toString()) { + if (allDevices != null && allDevices.isNotEmpty) { + List deviceIds = allDevices.split(','); + for (var deviceId in deviceIds) { + var deviceStatus = + await EasyDartModule.redis.get("mac_$deviceId"); + if (deviceStatus != null && deviceStatus.isNotEmpty) { + deviceIdList.add(deviceId); + } + } + } + if (deviceIdList.isNotEmpty) { + select.oneFrom('device_id', deviceIdList); + } else { + return 0; + } + } else if (query.device_status == + DeviceStatus.OFFLONE.code.toString()) { + if (allDevices != null && allDevices.isNotEmpty) { + List deviceIds = allDevices.split(','); + for (var deviceId in deviceIds) { + var deviceStatus = + await EasyDartModule.redis.get("mac_$deviceId"); + if (deviceStatus == null || deviceStatus.isEmpty) { + deviceIdList.add(deviceId); + } + } + if (deviceIdList.isNotEmpty) { + select.oneFrom('device_id', deviceIdList); + } + } + } + } + } + } + if (query.areaIds != null) { + List areaIds = query.areaIds!.split(','); + SelectorBuilder newSelect = SelectorBuilder(); + var newquery = newSelect.oneFrom('area_id', areaIds); + var result = await db.query( + 'bus_room_info', + condition: newquery, + ); + if (result.isNotEmpty) { + List roomIds = []; + for (var item in result) { + roomIds.add(item['_id'].toHexString()); + } + select.oneFrom('room_id', roomIds); + } + } + if (query.room_id != null) { + select.eq('room_id', query.room_id); + } + if (query.bed_type_id != null) { + // select.eq('bed_type_id', query.bed_type_id); + List roomTypes = query.bed_type_id!.split(','); + select.oneFrom('bed_type_id', roomTypes); + } + if (query.bed_type_name != null) { + select.match('bed_type_name', query.bed_type_name!, + caseInsensitive: true); + } + if (query.bed_name != null) { + select.match('bed_name', query.bed_name!, caseInsensitive: true); + } + if (query.is_mapped != null) { + select.eq('is_mapped', query.is_mapped == true ? 1 : 0); + } + if (query.device_model != null) { + select.match('device_model', query.device_model!, caseInsensitive: true); + } + if (query.device_name != null) { + select.match('device_name', query.device_name!, caseInsensitive: true); + } + if (query.device_id != null) { + select.match('device_id', query.device_id!, caseInsensitive: false); + } + if (query.status != null) { + select.eq('status', query.status); + } + if (query.created_by_id != null) { + select.eq('created_by_id', query.created_by_id); + } + if (query.updated_by_id != null) { + select.eq('updated_by_id', query.updated_by_id); + } + if (query.oid != null) { + select.eq('oid', query.oid); + } + if (query.start_time != null) { + select.gte('created_at', query.start_time); + } + if (query.end_time != null) { + select.lte('created_at', query.end_time); + } + if (query.deviceIds != null && query.deviceIds!.isNotEmpty) { + select.oneFrom('device_id', query.deviceIds!); + } + select.eq('deleted', 0); + + // 执行查询,获取符合条件的记录数量 + var result = await db.query( + 'bus_bed_info', + condition: select, // 查询条件 + ); + + // 如果查询结果为空,返回 0 + if (result.isEmpty) { + return 0; + } + + // 返回计数结果 + return result.length; + } + + Future getOrderCheckInList(Reservation query) async { + var db = EasyDartModule.dataBase; + SelectorBuilder select = SelectorBuilder(); + + // 添加查询条件 + if (query.id != null) { + select.eq('_id', query.id); + } + if (query.room_id != null) { + select.eq('room_id', query.room_id); + } + if (query.bed_id != null) { + select.eq('bed_id', query.bed_id!); + } + if (query.start_time != null) { + select.gte('start_time', query.start_time); + } + if (query.end_time != null) { + select.lte('end_time', query.end_time); + } + if (query.total_days != null) { + select.eq('total_days', query.total_days); + } + if (query.contact_name != null) { + select.match('contact_name', query.contact_name!, caseInsensitive: true); + } + if (query.relationship_type != null) { + select.match('relationship_type', query.relationship_type!, + caseInsensitive: true); + } + if (query.phone_number != null) { + select.match('phone_number', query.phone_number!, caseInsensitive: true); + } + if (query.oid != null) { + select.eq('oid', query.oid); + } + if (query.desc != null) { + select.match('desc', query.desc!, caseInsensitive: true); + } + + // 添加默认查询条件 + select.eq('deleted', 0); + + // 执行查询 + var result = await db.query('bus_room_check_info', condition: select); + + // 如果查询结果为空,返回空列表 + return result.isEmpty ? [] : result; + } + + Future updateBedStatus(String bed_id, int code, Person person) async { + var start_time = person.check_in_start_time; + var end_time = person.check_in_end_time; + var db = EasyDartModule.dataBase; + var condition = {'_id': ObjectId.fromHexString(bed_id)}; // 使用 bed_id 作为条件 + var update = { + '\$set': { + 'status': code, + 'updated_at': DateTime.now().millisecondsSinceEpoch, + 'start_time': start_time, + 'end_time': end_time, + }, + }; + try { + var result = await db.update('bus_bed_info', update, condition); + } catch (e) { + print(e); + } + } + + //存储统计信息 + Future addStatistics( + Map result, int code, int queryStartTime, int queryEndTime) async { + var db = EasyDartModule.dataBase; + try { + if (result != null && result.isNotEmpty) { + result.forEach((tid, statistics) async { + Map info = {}; + info['tid'] = tid; + info['type'] = code; + info['start_time'] = queryStartTime; + info['end_time'] = queryEndTime; + info['data'] = statistics; + var result = await db.insert('bus_statistics_info', info); + print("object"); + }); + } + } catch (e) { + print(e); + } + } + + findResultByQuery(Map query) async { + var db = EasyDartModule.dataBase; + SelectorBuilder select = SelectorBuilder(); + select.eq('type', query['type']); + select.gte('start_time', query['startTime']); + select.lte('end_time', query['endTime']); + select.eq('tid', query['tid']); + var result = await db.query( + 'bus_statistics_info', + condition: select, + ); + + if (result.isEmpty) { + return []; + } + return result; + } +} diff --git a/bin/repository/BedTypeRepository.dart b/bin/repository/BedTypeRepository.dart new file mode 100644 index 0000000..850a760 --- /dev/null +++ b/bin/repository/BedTypeRepository.dart @@ -0,0 +1,191 @@ +import 'package:EasyDartModule/EasyDartModule.dart'; +import '../model/BedType.dart'; +import '../const/MessageConstants.dart'; + +class BedTypeRepository { + // 获取所有床位类型列表,根据床位类型的查询条件 + Future fetchBedTypeList(BedType query, {int page = 1, int pageSize = 10}) async { + var db = EasyDartModule.dataBase; + SelectorBuilder select = SelectorBuilder(); + + // 添加查询条件 + if (query.id != null) { + select.eq('_id', query.id); + } + if (query.tid != null) { + select.eq('oid', query.tid); + } + if (query.level != null) { + select.gte('data_level', query.level); + } + if (query.bed_type_name != null) { + select.match('bed_type_name', query.bed_type_name!, caseInsensitive: true); + } + if (query.created_by_id != null) { + select.eq('created_by_id', query.created_by_id); + } + if (query.created_by_name != null) { + select.eq('created_by_name', query.created_by_name); + } + if (query.oid != null) { + select.eq('oid', query.oid); + } + if (query.start_time != null) { + select.gte('created_at', query.start_time); + } + if (query.end_time != null) { + select.lte('created_at', query.end_time); + } + + // 设置分页 + select.eq('deleted', 0); + select.skip((page - 1) * pageSize).limit(pageSize); + + // 设置排序 + select.sortBy("created_at"); // 按创建时间排序 + + // 执行查询 + var result = await db.query('bus_bed_type', condition: select); + + // 如果查询结果为空,返回空列表 + if (result.isEmpty) { + return []; + } + + // 返回查询结果 + return result; + } + + // 获取单个床位类型信息 + Future fetchBedTypeById(String bedTypeId) async { + var db = EasyDartModule.dataBase; + var condition = {'bed_type_id': bedTypeId}; // 使用 Map 格式作为条件 + var result = await db.query('bus_bed_type', condition: condition); + + // 如果查询到结果,返回床位类型数据 + if (result.isNotEmpty) { + return BedType.fromJson(result.first); + } + + // 如果没有找到,返回 null + return null; + } + + // 添加床位类型 + Future insertBedType(BedType bedType) async { + var db = EasyDartModule.dataBase; + + // 设置创建时间和更新时间 + int currentTime = DateTime.now().millisecondsSinceEpoch; + bedType.created_at = currentTime; + bedType.updated_at = currentTime; + bedType.deleted = 0; // 初始化为未删除 + + // 执行插入 SQL + var result = await db.insert('bus_bed_type', bedType.toJson()); + + // 如果影响行数大于 0,说明插入成功 + return true; + } + + // 更新床位类型信息 + Future updateBedType(String bedTypeId, BedType updatedBedType) async { + var db = EasyDartModule.dataBase; + String message = ""; + + // 设置更新时间 + updatedBedType.updated_at = DateTime.now().millisecondsSinceEpoch; + + // 使用 bed_type_id 作为条件 + var condition = {'bed_type_id': bedTypeId}; + + try { + // 执行更新 SQL + var result = await db.update('bus_bed_type', updatedBedType.toJson(), condition); + message = MessageConstants.UPDATE_SUCCESS; + } catch (e) { + message = MessageConstants.UPDATE_ERROR; + } + + return message; + } + + // 删除床位类型(逻辑删除) + Future deleteBedType(String bedTypeId) async { + var db = EasyDartModule.dataBase; + String message = ""; + + // 检查是否有床位绑定了该床位类型 + var condition = {'bed_type_id': bedTypeId}; // 使用 Map 格式作为条件 + var beds = await db.query( + 'bus_bed_info', + condition: condition, // 修正:条件应使用 Map 格式 + ); + + // 如果有床位绑定该类型,返回错误信息 + if (beds.isNotEmpty) { + message = "床位类型已经被绑定,请先解除床位类型绑定."; + return message; + } + + // 如果没有床位绑定,执行逻辑删除操作 + try { + var update = {'deleted': 1}; // 标记为已删除 + var result = await db.update('bus_bed_type', update, condition); + message = MessageConstants.DELETE_SUCCESS; + } catch (e) { + message = MessageConstants.DELETE_ERROR; + } + + return message; + } + + Future getBedTypeCount(BedType query) async { + var db = EasyDartModule.dataBase; + SelectorBuilder select = SelectorBuilder(); + + // 添加查询条件 + if (query.id != null) { + select.eq('bed_type_id', query.id); + } + if (query.tid != null) { + select.eq('oid', query.tid); + } + if (query.level != null) { + select.gte('data_level', query.level); + } + if (query.bed_type_name != null) { + select.match('bed_type_name', query.bed_type_name!, caseInsensitive: true); + } + if (query.created_by_id != null) { + select.eq('created_by_id', query.created_by_id); + } + if (query.created_by_name != null) { + select.eq('created_by_name', query.created_by_name); + } + if (query.oid != null) { + select.eq('oid', query.oid); + } + if (query.start_time != null) { + select.gte('created_at', query.start_time); + } + if (query.end_time != null) { + select.lte('created_at', query.end_time); + } + select.eq('deleted', 0); + + // 执行查询,获取符合条件的记录数量 + var result = await db.query( + 'bus_bed_type', + condition: select, // 查询条件 + ); + + // 如果查询结果为空,返回 0 + if (result.isEmpty) { + return 0; + } + + // 返回计数结果 + return result.length; + } +} \ No newline at end of file diff --git a/bin/repository/DictionaryTypeRepository.dart b/bin/repository/DictionaryTypeRepository.dart new file mode 100644 index 0000000..80847a6 --- /dev/null +++ b/bin/repository/DictionaryTypeRepository.dart @@ -0,0 +1,149 @@ +import 'package:EasyDartModule/EasyDartModule.dart'; +import '../model/DictionaryType.dart'; + +class DictionaryTypeRepository { + // 获取字典列表,支持查询条件 + Future> fetchDictionaryList(DictionaryType query) async { + var db = EasyDartModule.dataBase; + SelectorBuilder select = SelectorBuilder(); + + // 添加查询条件 + if (query.id != null) { + select.eq('_id', ObjectId.fromHexString(query.id!)); + } + if (query.dict_name != null) { + select.match('dict_name', query.dict_name!, caseInsensitive: true); + } + if (query.dict_type != null) { + select.match('dict_type', query.dict_type!, caseInsensitive: true); + } + if (query.status != null) { + select.eq('status', query.status); + } + if (query.create_by != null) { + select.eq('create_by', query.create_by); + } + if (query.update_by != null) { + select.eq('update_by', query.update_by); + } + if (query.remark != null) { + select.match('remark', query.remark!, caseInsensitive: true); + } + if (query.create_time != null) { + select.gte('create_time', query.create_time); + } + if (query.update_time != null) { + select.lte('update_time', query.update_time); + } + + // 设置排序 + select.sortBy("create_time"); // 按创建时间排序 + + // 执行查询 + var result = await db.query('bus_dict_types', condition: select); + + // 如果查询结果为空,返回空列表 + return result.isEmpty ? [] : result.map((e) => DictionaryType.fromJson(e)).toList(); + } + + // 获取单个字典信息 + Future fetchDictionaryById(String id) async { + var db = EasyDartModule.dataBase; + var condition = {'_id': ObjectId.fromHexString(id)}; // 使用 id 作为条件 + var result = await db.query('bus_dict_types', condition: condition); + return result.isNotEmpty ? DictionaryType.fromJson(result.first) : null; + } + + // 插入字典信息 + Future insertDictionary(DictionaryType DictionaryType) async { + var db = EasyDartModule.dataBase; + int currentTime = DateTime.now().millisecondsSinceEpoch; + DictionaryType.create_time = currentTime; + DictionaryType.update_time = currentTime; + var result = await db.insert('bus_dict_types', DictionaryType.toJson()); + return true; + } + + // 更新字典信息 + Future updateDictionary(String id, DictionaryType updatedDictionary) async { + var db = EasyDartModule.dataBase; + String message = ""; + updatedDictionary.update_time = DateTime.now().millisecondsSinceEpoch; + var condition = {'_id': ObjectId.fromHexString(id)}; // 使用 id 作为条件 + try { + var result = await db.update('bus_dict_types', updatedDictionary.toJson(), condition); + message = "更新成功"; + } catch (e) { + message = "更新失败: $e"; + } + return message; + } + + // 删除字典(逻辑删除) + Future deleteDictionary(String id) async { + var db = EasyDartModule.dataBase; + String message = ""; + var condition = {'_id': ObjectId.fromHexString(id)}; // 使用 id 作为查询条件 + var result = await db.query('bus_dict_types', condition: condition); + + if (result.isNotEmpty) { + // 标记为已删除 + var update = {'deleted': 1}; + try { + var updateResult = await db.update('bus_dict_types', update, condition); + message = "删除成功"; + } catch (e) { + message = "删除失败: $e"; + } + } else { + message = "未找到字典"; + } + return message; + } + + // 获取字典数量 + Future getDictionaryCount(DictionaryType query) async { + var db = EasyDartModule.dataBase; + SelectorBuilder select = SelectorBuilder(); + + // 添加查询条件 + if (query.id != null) { + select.eq('_id', ObjectId.fromHexString(query.id!)); + } + if (query.dict_name != null) { + select.match('dict_name', query.dict_name!, caseInsensitive: true); + } + if (query.dict_type != null) { + select.match('dict_type', query.dict_type!, caseInsensitive: true); + } + if (query.status != null) { + select.eq('status', query.status); + } + if (query.create_by != null) { + select.eq('create_by', query.create_by); + } + if (query.update_by != null) { + select.eq('update_by', query.update_by); + } + if (query.remark != null) { + select.match('remark', query.remark!, caseInsensitive: true); + } + if (query.create_time != null) { + select.gte('create_time', query.create_time); + } + if (query.update_time != null) { + select.lte('update_time', query.update_time); + } + + // 执行查询,获取符合条件的记录数量 + var result = await db.query('bus_dict_types', condition: select); + + // 如果查询结果为空,返回 0 + if (result.isEmpty) { + return 0; + } + + // 返回计数结果 + return result.length; + } +} \ No newline at end of file diff --git a/bin/repository/DiseaseTypeRepository.dart b/bin/repository/DiseaseTypeRepository.dart new file mode 100644 index 0000000..9a9093a --- /dev/null +++ b/bin/repository/DiseaseTypeRepository.dart @@ -0,0 +1,209 @@ +import 'package:EasyDartModule/EasyDartModule.dart'; +import '../model/DiseaseType.dart'; +import '../const/MessageConstants.dart'; + +class DiseaseTypeRepository { + // 获取所有疾病类型列表 + Future fetchDiseaseTypeList(DiseaseType query, {int page = 1, int pageSize = 10}) async { + var db = EasyDartModule.dataBase; + SelectorBuilder select = SelectorBuilder(); + + // 添加查询条件 + if (query.id != null) { + select.eq('_id', query.id); + } + if (query.tid != null) { + select.eq('oid', query.tid); + } + if (query.level != null) { + select.gte('data_level', query.level); + } + if (query.disease_type_name != null) { + select.match('disease_type_name', query.disease_type_name!, caseInsensitive: true); + } + if (query.description != null) { + select.eq('description', query.description); + } + if (query.created_by_id != null) { + select.eq('created_by_id', query.created_by_id); + } + if (query.created_by_name != null) { + select.eq('created_by_name', query.created_by_name); + } + if (query.updated_by_id != null) { + select.eq('updated_by_id', query.updated_by_id); + } + if (query.updated_by_name != null) { + select.eq('updated_by_name', query.updated_by_name); + } + if (query.oid != null) { + select.eq('oid', query.oid); + } + if (query.start_time != null) { + select.gte('created_time', query.start_time); + } + if (query.end_time != null) { + select.lte('created_time', query.end_time); + } + // 设置分页 + select.eq('deleted', 0); + select.skip((page - 1) * pageSize).limit(pageSize); + // 设置排序 + select.sortBy("created_at"); // 按创建时间排序 + // 执行查询 + var result = await db.query('bus_disease_type', condition: select); + // 如果查询结果为空,返回空列表 + if (result.isEmpty) { + return []; + } + // 返回查询结果 + return result; + } + + // 获取单个疾病类型信息 + Future fetchDiseaseTypeById(int diseaseTypeId) async { + var db = EasyDartModule.dataBase; + var condition = {'disease_type_id': diseaseTypeId}; // 使用 disease_type_id 为条件 + // 执行查询 SQL + var result = await db.query('bus_disease_type', condition: condition); + // 如果查询到结果,返回疾病类型数据 + if (result.isNotEmpty) { + return DiseaseType.fromJson(result.first); + } + // 如果没有找到,返回 null + return null; + } + + // 添加疾病类型 + Future insertDiseaseType(DiseaseType diseaseType) async { + var db = EasyDartModule.dataBase; + // 执行插入 SQL + var result = await db.insert('bus_disease_type', diseaseType.toJson()); + // 如果返回的影响行数大于0,说明插入成功 + return true; // 确保返回的是影响的行数 + } + + // 更新疾病类型 + Future updateDiseaseType(String diseaseTypeId, DiseaseType updatedDiseaseType) async { + String message = ""; + var db = EasyDartModule.dataBase; + var str = updatedDiseaseType.toJson(); + str.remove("_id"); + var updateCondition = { + '_id': ObjectId.fromHexString(diseaseTypeId), + }; + try { + var result = await db.update('bus_disease_type', str, updateCondition); + return message; // 返回受影响的行数 + } catch (e) { + message = MessageConstants.UPDATE_ERROR; + return message; + } + } + + // 删除疾病类型 (逻辑删除前检查是否有疾病绑定) + Future deleteDiseaseType(String diseaseTypeIds) async { + String message = ""; + var db = EasyDartModule.dataBase; + // 将逗号分隔的多个 diseaseTypeIds 字符串转换为 List + var diseaseTypeIdList = diseaseTypeIds.split(','); + // 检查是否有疾病绑定这些疾病类型 + var condition = { + 'disease_type': {'\$in': diseaseTypeIdList} + }; // 使用 \$in 操作符查询多个 ID + var diseases = await db.query('bus_disease_info', condition: condition); + if (diseases.isNotEmpty) { + // 如果有疾病绑定这些疾病类型,返回 false + message = "疾病类型已经被绑定,请先解除疾病类型绑定."; + return message; + } + // 如果没有疾病绑定,执行逻辑删除操作 + try { + var objectIdList = diseaseTypeIdList.map((id) => ObjectId.fromHexString(id)).toList(); + var deleteCondition = { + '_id': {'\$in': objectIdList} + }; // 使用 \$in 操作符查询多个 ID + var update = { + '\$set': {'deleted': 1} + }; // 逻辑删除,只更新 deleted 字段 + var result = await db.update('bus_disease_type', update, deleteCondition); + message = MessageConstants.DELETE_SUCCESS; + } catch (e) { + print("Error during deleteDiseaseType: $e"); + message = MessageConstants.DELETE_ERROR; + } + return message; + } + + Future getDiseaseTypeCount(DiseaseType query) async { + var db = EasyDartModule.dataBase; + SelectorBuilder select = SelectorBuilder(); + + // 添加查询条件 + if (query.id != null) { + select.eq('disease_type_id', query.id); + } + if (query.tid != null) { + select.eq('oid', query.tid); + } + if (query.level != null) { + select.gte('data_level', query.level); + } + if (query.disease_type_name != null) { + select.match('disease_type_name', query.disease_type_name!, caseInsensitive: true); + } + if (query.description != null) { + select.eq('description', query.description); + } + if (query.created_by_id != null) { + select.eq('created_by_id', query.created_by_id); + } + if (query.created_by_name != null) { + select.eq('created_by_name', query.created_by_name); + } + if (query.updated_by_id != null) { + select.eq('updated_by_id', query.updated_by_id); + } + if (query.updated_by_name != null) { + select.eq('updated_by_name', query.updated_by_name); + } + if (query.oid != null) { + select.eq('oid', query.oid); + } + if (query.start_time != null) { + select.gte('created_time', query.start_time); + } + if (query.end_time != null) { + select.lte('created_time', query.end_time); + } + select.eq('deleted', 0); + + // 执行查询,获取符合条件的记录数量 + var result = await db.query('bus_disease_type', condition: select); + // 如果查询结果为空,返回 0 + if (result.isEmpty) { + return 0; + } + // 返回计数结果 + return result.length; + } + + Future fetchDiseaseTypeListByOrganization(String oid) async { + var db = EasyDartModule.dataBase; + SelectorBuilder select = SelectorBuilder(); + // 添加查询条件 + select.eq('oid', oid); + select.eq('deleted', 0); + // 执行查询 + var result = await db.query('bus_disease_type', condition: select); + // 如果查询结果为空,返回空列表 + if (result.isEmpty) { + return []; + } + // 返回查询结果 + return result; +} + + + +} \ No newline at end of file diff --git a/bin/repository/PersonRepository.dart b/bin/repository/PersonRepository.dart new file mode 100644 index 0000000..874310b --- /dev/null +++ b/bin/repository/PersonRepository.dart @@ -0,0 +1,391 @@ +import 'package:EasyDartModule/EasyDartModule.dart'; + +import '../const/Constants.dart'; +import '../model/Person.dart'; + +class PersonRepository { + // 获取所有人员列表 + Future fetchPersonList( + Person query, + ) async { + var db = EasyDartModule.dataBase; + SelectorBuilder select = SelectorBuilder(); + // 添加查询条件 + if (query.id != null) { + select.eq('_id', ObjectId.fromHexString(query.id!)); + } + if (query.tid != null) { + select.eq('oid', query.tid); + } + if (query.level != null) { + select.gte('data_level', query.level); + } + if (query.room_id != null) { + select.eq('room_id', query.room_id); + } + if (query.room_name != null) { + select.match('room_name', query.room_name!, caseInsensitive: true); + } + if (query.bed_id != null) { + select.eq('bed_id', query.bed_id); + } + if (query.bed_ids != null) { + List bedIds = query.bed_ids!.split(','); + select.oneFrom('bed_id', bedIds); + } + if (query.bed_name != null) { + select.match('bed_name', query.bed_name!, caseInsensitive: true); + } + if (query.check_in_start_time != null) { + select.gte('check_in_start_time', query.check_in_start_time); + } + if (query.check_in_end_time != null) { + select.lte('check_in_end_time', query.check_in_end_time); + } + if (query.contact_name != null) { + select.match('contact_name', query.contact_name!, caseInsensitive: true); + } + if (query.contact_relationship != null) { + select.eq('contact_relationship', query.contact_relationship); + } + if (query.contact_phone != null) { + select.eq('contact_phone', query.contact_phone); + } + if (query.person_name != null) { + select.match('person_name', query.person_name!, caseInsensitive: false); + } + if (query.gender != null) { + List genders = query.gender!.split(","); + if (genders.length == 1) { + select.eq('gender', genders.first); + } + // select.eq('gender', query.gender); + } + if (query.ethnicity != null) { + select.eq('ethnicity', query.ethnicity); + } + if (query.person_type_id != null) { + List bedIds = query.person_type_id!.split(','); + select.oneFrom('person_type_id', bedIds); + // select.eq('person_type_id', query.person_type_id); + } + if (query.person_type_name != null) { + select.match('person_type_name', query.person_type_name!, + caseInsensitive: true); + } + if (query.id_card_number != null) { + select.eq('id_card_number', query.id_card_number); + } + if (query.phone_number != null) { + select.eq('phone_number', query.phone_number); + } + if (query.service_level != null) { + select.eq('service_level', query.service_level); + } + if (query.health_info != null) { + select.eq('health_info', query.health_info); + } + if (query.height != null) { + select.eq('height', query.height); + } + if (query.tid != null) { + select.eq('oid', query.tid); + } + if (query.query_gender != null) { + List genders = query.query_gender!.split(","); + if (genders.length == 1) { + select.eq('gender', genders.first); + } + } + + if (query.start_time != null && + query.start_time!.isNotEmpty && + query.end_time != null && + query.end_time!.isNotEmpty) { + SelectorBuilder select1 = SelectorBuilder(); + SelectorBuilder select2 = SelectorBuilder(); + select1.gte('check_in_start_time', int.parse(query.start_time!)); + select2.lte('check_in_start_time', int.parse(query.end_time!)); + select1.and(select2); + SelectorBuilder select3 = SelectorBuilder(); + SelectorBuilder select4 = SelectorBuilder(); + select3.gte('check_in_end_time', int.parse(query.start_time!)); + select4.lte('check_in_end_time', int.parse(query.end_time!)); + select3.and(select4); + select1.or(select3); + SelectorBuilder select5 = SelectorBuilder(); + SelectorBuilder select6 = SelectorBuilder(); + select5.lte('check_in_start_time', int.parse(query.start_time!)); + select6.gte('check_in_end_time', int.parse(query.end_time!)); + select5.and(select6); + SelectorBuilder select7 = SelectorBuilder(); + SelectorBuilder select8 = SelectorBuilder(); + select7.gte('check_in_end_time', int.parse(query.start_time!)); + select8.lte('check_in_end_time', int.parse(query.end_time!)); + select7.and(select8); + select5.and(select7); + select1.or(select5); + select.and(select1); + } + if (query.status != null) { + List status = query.status!.split(","); + if (status.length == 1) { + if (status.first == "1") { + select.nin('bed_id', [null, '']); + } else if (status.first == "2") { + select.oneFrom('bed_id', [null, '']); + } + } + } + if (query.query_person_type != null) { + List personTypes = query.query_person_type!.split(','); + select.oneFrom('person_type_id', personTypes); + } + + // 设置分页 + select.eq('deleted', 0); + select + .skip(((int.tryParse(query.page ?? Constants.default_page.toString()) ?? + Constants.default_page) - + 1) * + (int.tryParse(query.limit ?? Constants.default_limit.toString()) ?? + Constants.default_limit)) + .limit( + int.tryParse(query.limit ?? Constants.default_limit.toString()) ?? + Constants.default_limit); + + // 设置排序 + select.sortBy("created_at"); + + // 执行查询 + var result = await db.query( + 'bus_person', + condition: select, + ); + return result.isEmpty ? [] : result; + } + + // 获取单个人员信息 + Future fetchPersonById(String personId) async { + var db = EasyDartModule.dataBase; + var condition = {'_id': personId}; + var result = await db.query( + 'bus_person', + condition: condition, + ); + if (result.isNotEmpty) { + return Person.fromJson(result.first); + } + return null; + } + + // 插入人员 + Future insertPerson(Person person) async { + var db = EasyDartModule.dataBase; + var result = await db.insert('bus_person', person.toJson()); + return true; + } + + // 更新人员信息 + Future updatePerson(String personId, Person updatedPerson) async { + String message = ""; + var db = EasyDartModule.dataBase; + var condition = {'_id': ObjectId.fromHexString(personId)}; + var update = { + '\$set': { + 'room_id': updatedPerson.room_id, + 'room_name': updatedPerson.room_name, + 'bed_id': updatedPerson.bed_id, + 'bed_name': updatedPerson.bed_name, + }, + }; + try { + var result = await db.update('bus_person', update, condition); + return ""; + } catch (e) { + print("Error updating person: $e"); + return "更新失败: $e"; + } + } + + // 删除人员 (逻辑删除) + Future deletePerson(String personId) async { + String message = ""; + var db = EasyDartModule.dataBase; + var condition = {'person_id': personId}; + try { + var result = await db.update('bus_person', {'deleted': 1}, condition); + return ""; + } catch (e) { + print("Error deleting person: $e"); + return "删除失败: $e"; + } + } + + Future fetchPersonsByOrganizationId(String oid) async { + var db = EasyDartModule.dataBase; + SelectorBuilder select = SelectorBuilder(); + // 添加查询条件 + select.eq('oid', oid); + select.eq('deleted', 0); + // 设置排序 + select.sortBy("created_at"); + // 执行查询 + var result = await db.query('bus_person', condition: select); + // 如果查询结果为空,返回空列表 + if (result.isEmpty) { + return []; + } + // 返回查询结果 + return result; + } + + getPersonCount(Person query) async { + var db = EasyDartModule.dataBase; + SelectorBuilder select = SelectorBuilder(); + + // 添加查询条件 + if (query.id != null) { + select.eq('_id', ObjectId.fromHexString(query.id!)); + } + if (query.tid != null) { + select.eq('oid', query.tid); + } + if (query.level != null) { + select.gte('data_level', query.level); + } + if (query.room_id != null) { + select.eq('room_id', query.room_id); + } + if (query.room_name != null) { + select.match('room_name', query.room_name!, caseInsensitive: true); + } + if (query.bed_id != null) { + select.eq('bed_id', query.bed_id); + } + if (query.bed_name != null) { + select.match('bed_name', query.bed_name!, caseInsensitive: true); + } + if (query.check_in_start_time != null) { + select.gte('check_in_start_time', query.check_in_start_time); + } + if (query.check_in_end_time != null) { + select.lte('check_in_end_time', query.check_in_end_time); + } + if (query.contact_name != null) { + select.match('contact_name', query.contact_name!, caseInsensitive: true); + } + if (query.contact_relationship != null) { + select.eq('contact_relationship', query.contact_relationship); + } + if (query.contact_phone != null) { + select.eq('contact_phone', query.contact_phone); + } + if (query.person_name != null) { + select.match('person_name', query.person_name!, caseInsensitive: true); + } + if (query.gender != null) { + List genders = query.gender!.split(","); + if (genders.length == 1) { + select.eq('gender', genders.first); + } + // select.eq('gender', query.gender); + } + if (query.ethnicity != null) { + select.eq('ethnicity', query.ethnicity); + } + if (query.person_type_id != null) { + List bedIds = query.person_type_id!.split(','); + select.oneFrom('person_type_id', bedIds); + // select.eq('person_type_id', query.person_type_id); + } + if (query.person_type_name != null) { + select.match('person_type_name', query.person_type_name!, + caseInsensitive: true); + } + if (query.id_card_number != null) { + select.eq('id_card_number', query.id_card_number); + } + if (query.phone_number != null) { + select.eq('phone_number', query.phone_number); + } + if (query.service_level != null) { + select.eq('service_level', query.service_level); + } + if (query.health_info != null) { + select.eq('health_info', query.health_info); + } + if (query.height != null) { + select.eq('height', query.height); + } + if (query.tid != null) { + select.eq('oid', query.tid); + } + if (query.query_gender != null) { + List genders = query.query_gender!.split(","); + if (genders.length == 1) { + select.eq('gender', genders.first); + } + } + + if (query.start_time != null && + query.start_time!.isNotEmpty && + query.end_time != null && + query.end_time!.isNotEmpty) { + SelectorBuilder select1 = SelectorBuilder(); + SelectorBuilder select2 = SelectorBuilder(); + select1.gte('check_in_start_time', int.parse(query.start_time!)); + select2.lte('check_in_start_time', int.parse(query.end_time!)); + select1.and(select2); + SelectorBuilder select3 = SelectorBuilder(); + SelectorBuilder select4 = SelectorBuilder(); + select3.gte('check_in_end_time', int.parse(query.start_time!)); + select4.lte('check_in_end_time', int.parse(query.end_time!)); + select3.and(select4); + select1.or(select3); + SelectorBuilder select5 = SelectorBuilder(); + SelectorBuilder select6 = SelectorBuilder(); + select5.lte('check_in_start_time', int.parse(query.start_time!)); + select6.gte('check_in_end_time', int.parse(query.end_time!)); + select5.and(select6); + SelectorBuilder select7 = SelectorBuilder(); + SelectorBuilder select8 = SelectorBuilder(); + select7.gte('check_in_end_time', int.parse(query.start_time!)); + select8.lte('check_in_end_time', int.parse(query.end_time!)); + select7.and(select8); + select5.and(select7); + select1.or(select5); + select.and(select1); + } + if (query.status != null) { + List status = query.status!.split(","); + if (status.length == 1) { + if (status.first == "1") { + select.nin('bed_id', [null, '']); + } else if (status.first == "2") { + select.oneFrom('bed_id', [null, '']); + } + } + } + if (query.query_person_type != null) { + List personTypes = query.query_person_type!.split(','); + select.oneFrom('person_type_id', personTypes); + } + + // 设置分页 + select.eq('deleted', 0); + // 执行查询,获取符合条件的记录数量 + var result = await db.query( + 'bus_person', + condition: select, // 查询条件 + ); + + // 如果查询结果为空,返回 0 + if (result.isEmpty) { + return 0; + } + + // 返回计数结果 + return result.length; + } +} diff --git a/bin/repository/PersonTypeRepository.dart b/bin/repository/PersonTypeRepository.dart new file mode 100644 index 0000000..4f64dac --- /dev/null +++ b/bin/repository/PersonTypeRepository.dart @@ -0,0 +1,136 @@ +import 'package:EasyDartModule/EasyDartModule.dart'; +import '../model/PersonType.dart'; +import '../const/MessageConstants.dart'; + +class PersonTypeRepository { + // 获取所有人员类型列表 + Future fetchPersonTypeList(PersonType query, + {int page = 1, int pageSize = 10}) async { + var db = EasyDartModule.dataBase; + SelectorBuilder select = SelectorBuilder(); + + // 添加查询条件 + if (query.id != null) { + select.eq('_id', query.id); + } + if (query.tid != null) { + select.eq('oid', query.tid); + } + if (query.level != null) { + select.gte('data_level', query.level); + } + if (query.person_type_name != null) { + select.match('bus_person_type_name', query.person_type_name!, + caseInsensitive: true); + } + if (query.description != null) { + select.eq('description', query.description); + } + if (query.created_by_id != null) { + select.eq('created_by_id', query.created_by_id); + } + if (query.created_by_name != null) { + select.eq('created_by_name', query.created_by_name); + } + if (query.updated_by_id != null) { + select.eq('updated_by_id', query.updated_by_id); + } + if (query.updated_by_name != null) { + select.eq('updated_by_name', query.updated_by_name); + } + if (query.oid != null) { + select.eq('oid', query.oid); + } + if (query.created_at != null) { + select.gte('created_at', query.created_at); + } + if (query.updated_at != null) { + select.lte('updated_at', query.updated_at); + } + + // 设置分页 + select.eq('deleted', 0); + select.skip((page - 1) * pageSize).limit(pageSize); + // 设置排序 + select.sortBy("created_at"); + + // 执行查询 + var result = await db.query( + 'bus_person_type', + condition: select, + ); + return result.isEmpty ? [] : result; + } + + // 获取单个人员类型信息 + Future fetchPersonTypeById(String personTypeId) async { + var db = EasyDartModule.dataBase; + var condition = {'bus_person_type_id': personTypeId}; + var result = await db.query( + 'bus_person_type', + condition: condition, + ); + if (result.isNotEmpty) { + return PersonType.fromJson(result.first); + } + return null; + } + + // 插入人员类型 + Future insertPersonType(PersonType personType) async { + var db = EasyDartModule.dataBase; + var result = await db.insert('bus_person_type', personType.toJson()); + return true; + } + + // 更新人员类型 + Future updatePersonType( + String personTypeId, PersonType updatedPersonType) async { + String message = ""; + var db = EasyDartModule.dataBase; + var str = updatedPersonType.toJson(); + str.remove("bus_person_type_id"); + var updateCondition = {'bus_person_type_id': personTypeId}; + try { + var result = await db.update('bus_person_type', str, updateCondition); + return message; + } catch (e) { + message = MessageConstants.UPDATE_ERROR; + return message; + } + } + + // 删除人员类型 (逻辑删除前检查是否有人员绑定) + Future deletePersonType(String personTypeId) async { + String message = ""; + var db = EasyDartModule.dataBase; + var condition = {'bus_person_type_id': personTypeId}; + var persons = await db.query( + 'person', + condition: condition, + ); + if (persons.isNotEmpty) { + message = "人员类型已经被绑定,请先解除人员类型绑定."; + return message; + } + try { + var update = {'deleted': 1}; + var result = await db.update('bus_person_type', update, condition); + return message; + } catch (e) { + print("Error during deletePersonType: $e"); + message = MessageConstants.DELETE_ERROR; + return message; + } + } + + Future checkPersonTypeBinding(String personTypeId) async { + var db = EasyDartModule.dataBase; + var condition = {'person_type_id': personTypeId}; + var result = await db.query( + 'bus_person', + condition: condition, + ); + return result.isNotEmpty; // 如果有绑定,返回 true + } +} diff --git a/bin/repository/RoomRepository.dart b/bin/repository/RoomRepository.dart new file mode 100644 index 0000000..98dfe9b --- /dev/null +++ b/bin/repository/RoomRepository.dart @@ -0,0 +1,302 @@ +import 'package:EasyDartModule/EasyDartModule.dart'; +import '../model/Room.dart'; +import '../const/MessageConstants.dart'; + +class RoomRepository { + // 获取所有房间列表 + Future fetchRoomList(Room query, + {int page = 1, int pageSize = 10}) async { + var db = EasyDartModule.dataBase; + + // 构建查询条件 + SelectorBuilder select = SelectorBuilder(); + + // 添加查询条件 + if (query.id != null) { + select.eq('_id', ObjectId.fromHexString(query.id!)); + } + if (query.tid != null) { + select.eq('oid', query.tid); + } + if (query.level != null) { + select.gte('data_level', query.level); + } + if (query.room_name != null) { + select.match('room_name', query.room_name!, caseInsensitive: true); + } + if (query.room_type != null) { + List roomTypes = query.room_type!.split(','); + select.oneFrom('room_type', roomTypes); + } + if (query.room_desc != null) { + select.eq('room_desc', query.room_desc); + } + if (query.bed_num != null) { + select.eq('bed_num', query.bed_num); + } + if (query.bed_num_use != null) { + select.eq('bed_num_use', query.bed_num_use); + } + if (query.created_by_id != null) { + select.eq('created_by_id', query.created_by_id); + } + if (query.updated_by_id != null) { + select.eq('updated_by_id', query.updated_by_id); + } + if (query.created_at != null) { + select.gte('created_at', query.created_at); + } + if (query.updated_at != null) { + select.lte('updated_at', query.updated_at); + } + if (query.area_id != null) { + select.eq('area_id', query.area_id); + } + + select.eq('deleted', 0); + // 设置分页 + select.skip((page - 1) * pageSize).limit(pageSize); + // 设置排序 + select.sortBy("created_at"); // 按创建时间排序 + + // 执行查询 + var result = await db.query( + 'bus_room_info', + condition: select, // 查询条件 + 分页 + 排序 + ); + + if (result.isEmpty) { + return []; + } + + return result; + } + + // 获取单个房间信息 + Future fetchRoomById(int roomId) async { + var db = EasyDartModule.dataBase; + + // 构建查询条件 + var condition = {'room_id': roomId}; + + // 执行查询 + var result = await db.query( + 'bus_room_info', + condition: condition, + ); + + if (result.isNotEmpty) { + return Room.fromJson(result.first); + } + + return null; + } + + // 添加房间 + Future insertRoom(Room room) async { + var db = EasyDartModule.dataBase; + // 执行插入操作 + var result = await db.insert('bus_room_info', room.toJson()); + // 返回是否插入成功 + return true; + } + + // 更新房间信息 + Future updateRoom(String roomId, Room updatedRoom) async { + String message = ""; + var db = EasyDartModule.dataBase; + var str = updatedRoom.toJson(); + str.remove("_id"); + var updateCondition = { + '_id': ObjectId.fromHexString(roomId), + }; + try { + // var result = await db.update('bus_room_type', update, condition); + var result = await db.update('bus_room_info', str, updateCondition); + return message; // 返回受影响的行数 + } catch (e) { + message = MessageConstants.UPDATE_ERROR; + return message; + } + } + + // 删除房间 (逻辑删除) + Future deleteRoom(String roomId) async { + var db = EasyDartModule.dataBase; + // 构建查询条件 + var condition = {'room_id': roomId}; + String message = ""; + // try { + try { + var roomIdList = roomId.split(','); + var objectIdList = + roomIdList.map((id) => ObjectId.fromHexString(id)).toList(); + var condition = { + '_id': {'\$in': objectIdList} + }; // 使用 \$in 操作符查询多个 ID + var update = { + '\$set': {'deleted': 1} + }; // 逻辑删除,只更新 deleted 字段 + var result = await db.update('bus_room_info', update, condition); + return message; // 返回受影响的行数 + } catch (e) { + print("Error during deleteRoomType: $e"); + message = MessageConstants.DELETE_ERROR; + return message; + } + } + + // 获取房间数量 + Future getRoomCount(Room query) async { + var db = EasyDartModule.dataBase; + + // 构建查询条件 + SelectorBuilder select = SelectorBuilder(); + + if (query.id != null) { + select.eq('_id', query.id); + } + if (query.tid != null) { + select.eq('oid', query.tid); + } + if (query.level != null) { + select.gte('data_level', query.level); + } + if (query.room_type != null) { + select.eq('room_type', query.room_type); + } + if (query.room_desc != null) { + select.eq('room_desc', query.room_desc); + } + if (query.bed_num != null) { + select.eq('bed_num', query.bed_num); + } + if (query.bed_num_use != null) { + select.eq('bed_num_use', query.bed_num_use); + } + + // 执行查询并返回计数 + var result = await db.query( + 'bus_room_info', + condition: select, + ); + + return result.length; + } + + //办理预约入住 + addOrderCheckIn(data) async { + var db = EasyDartModule.dataBase; + // 执行插入操作 + var result = await db.insert('bus_room_check_info', data); + + // 返回是否插入成功 + final pipeline = AggregationPipelineBuilder() + // .addStage(Match(where.eq('type', 1).map['\$query'])) + // 关联房间表 + .addStage(AddFields({ + 'data.room_info.id': {'\$toObjectId': '\$data.room_info.id'}, + 'data.bed_info.id': {'\$toObjectId': '\$data.bed_info.id'} + })) + .addStage(Lookup( + from: 'bus_room_info', + localField: 'data.room_info.id', + foreignField: '_id', + as: 'room_info')) + // 关联床位表 + .addStage(Lookup( + from: 'bus_bed_info', + localField: 'data.bed_info.id', + foreignField: '_id', + as: 'bed_info')) + // 选择需要的字段 + .addStage(Project({ + '_id': 1, // 预约表的 _id + 'level': 1, // 预约人姓名 + 'appointment_date': 1, // 预约时间 + 'status': 1, // 预约状态 + 'data': 1, + 'room_id': { + '\$arrayElemAt': ['\$room_info._id', 0] + }, // 取房间ID + 'room_name': { + '\$arrayElemAt': ['\$room_info.room_name', 0] + }, // 取房间名称 + 'bed_id': { + '\$arrayElemAt': ['\$bed_info._id', 0] + }, // 取床位ID + 'bed_name': { + '\$arrayElemAt': ['\$bed_info.bed_name', 0] + } // 取床位名称 + })) + .build(); + + try { + // final db1 = Db('mongodb://192.168.1.80:27017/test'); + const host = "192.168.1.80:27017"; + const userName = "root"; + const password = "123456"; + const dataBase = "test"; + // 创建连接字符串 + final connectionString = + "mongodb://$userName:$password@$host/$dataBase?authSource=admin"; + + var db1 = await Db.create(connectionString); + await db1.open(); + final result1 = await DbCollection(db1, 'bus_message') + .aggregateToStream(pipeline) + .toList(); + print(result1); + } catch (e) { + print(e); + } + return result; + } + + //删除预约入住 + delOrderCheckIn(data) async { + var db = EasyDartModule.dataBase; + // 构建查询条件 + // var condition = {'room_id': roomId}; + String message = ""; + // try { + try { + var roomIdList = data['id'].split(','); + var objectIdList = + roomIdList.map((id) => ObjectId.fromHexString(id)).toList(); + var condition = { + '_id': {'\$in': objectIdList} + }; // 使用 \$in 操作符查询多个 ID + var update = { + '\$set': {'deleted': 1} + }; // 逻辑删除,只更新 deleted 字段 + var result = await db.update('bus_room_check_info', update, condition, + multiUpdate: true); + return message; // 返回受影响的行数 + } catch (e) { + print("Error during deleteRoomType: $e"); + message = MessageConstants.DELETE_ERROR; + return message; + } + } + + Future addOrderCheckInRuZhuRecord(data) async { + try { + var db = EasyDartModule.dataBase; + // 执行插入操作 + var result = await db.insert('bus_ruzhu_info', data); + } catch (e) { + print(e); + } + } + + Future addCheckOutRecord(data) async { + try { + var db = EasyDartModule.dataBase; + // 执行插入操作 + var result = await db.insert('bus_checkout_info', data); + } catch (e) { + print(e); + } + } +} diff --git a/bin/repository/RoomTypeRepository.dart b/bin/repository/RoomTypeRepository.dart new file mode 100644 index 0000000..16a16ea --- /dev/null +++ b/bin/repository/RoomTypeRepository.dart @@ -0,0 +1,214 @@ +import 'package:EasyDartModule/EasyDartModule.dart'; +import '../model/RoomType.dart'; +import '../const/MessageConstants.dart'; + +class RoomTypeRepository { + // 获取所有房间类型列表 + Future fetchRoomTypeList(RoomType query, + {int page = 1, int pageSize = 10}) async { + var db = EasyDartModule.dataBase; + SelectorBuilder select = SelectorBuilder(); + // 添加查询条件 + + if (query.id != null) { + select.eq('_id', query.id); + } + if (query.tid != null) { + select.eq('oid', query.tid); + } + if (query.level != null) { + select.gte('data_level', query.level); + } + if (query.room_type_name != null) { + select.match('room_type_name', query.room_type_name!, + caseInsensitive: true); + } + if (query.description != null) { + select.eq('description', query.description); + } + if (query.created_by_id != null) { + select.eq('created_by_id', query.created_by_id); + } + if (query.created_by_name != null) { + select.eq('created_by_name', query.created_by_name); + } + if (query.updated_by_id != null) { + select.eq('updated_by_id', query.updated_by_id); + } + if (query.updated_by_name != null) { + select.eq('updated_by_name', query.updated_by_name); + } + if (query.oid != null) { + select.eq('oid', query.oid); + } + if (query.start_time != null) { + select.gte('created_time', query.start_time); + } + if (query.end_time != null) { + select.lte('created_time', query.end_time); + } + // 设置分页 + select.eq('deleted', 0); + select.skip((page - 1) * pageSize).limit(pageSize); + // 设置排序 + select.sortBy("created_at"); // 按 room_type_id 降序排序 + // 执行查询,组合查询条件与分页、排序 + var result = await db.query( + 'bus_room_type', + condition: select, // 查询条件 + 分页 + 排序 + ); + // 如果查询结果为空,返回空列表 + if (result.isEmpty) { + return []; + } + // 返回查询结果 + return result; + } + + // 获取单个房间类型信息 + Future fetchRoomTypeById(int roomTypeId) async { + var db = EasyDartModule.dataBase; + var condition = {'room_type_id': roomTypeId}; // 使用 room_type_id 为条件 + // 执行查询 SQL + var result = await db.query( + 'bus_room_type', + condition: condition, // 修正:应该使用 Map 格式的条件 + ); + + // 如果查询到结果,返回房间类型数据 + if (result.isNotEmpty) { + return RoomType.fromJson(result.first); + } + // 如果没有找到,返回 null + return null; + } + + // 添加房间类型 + Future insertRoomType(RoomType roomType) async { + var db = EasyDartModule.dataBase; + // 执行插入 SQL + var result = await db.insert('bus_room_type', roomType.toJson()); + // 如果返回的影响行数大于0,说明插入成功 + return true; // 确保返回的是影响的行数 + } + + // 更新房间类型 + Future updateRoomType( + String roomTypeId, RoomType updatedRoomType) async { + String message = ""; + var db = EasyDartModule.dataBase; + var str = updatedRoomType.toJson(); + str.remove("_id"); + var updateCondition = { + '_id': ObjectId.fromHexString(roomTypeId), + }; + try { + // var result = await db.update('bus_room_type', update, condition); + var result = await db.update('bus_room_type', str, updateCondition); + return message; // 返回受影响的行数 + } catch (e) { + message = MessageConstants.UPDATE_ERROR; + return message; + } + } + + // 删除房间类型 (逻辑删除前检查是否有房间绑定) + Future deleteRoomType(String roomTypeIds) async { + String message = ""; + var db = EasyDartModule.dataBase; + // 将逗号分隔的多个 roomTypeIds 字符串转换为 List + var roomTypeIdList = roomTypeIds.split(','); + // 检查是否有房间绑定这些房间类型 + var condition = { + 'room_type': {'\$in': roomTypeIdList} + }; // 使用 \$in 操作符查询多个 ID + var rooms = await db.query( + 'bus_room_info', + condition: condition, + ); + if (rooms.isNotEmpty) { + // 如果有房间绑定这些房间类型,返回 false + message = "房间类型已经被绑定,请先解除房间类型绑定."; + return message; + } + // 如果没有房间绑定,执行逻辑删除操作 + try { + var objectIdList = + roomTypeIdList.map((id) => ObjectId.fromHexString(id)).toList(); + var condition = { + '_id': {'\$in': objectIdList} + }; // 使用 \$in 操作符查询多个 ID + var update = { + '\$set': {'deleted': 1} + }; // 逻辑删除,只更新 deleted 字段 + var result = await db.update('bus_room_type', update, condition); + + return message; // 返回受影响的行数 + } catch (e) { + print("Error during deleteRoomType: $e"); + message = MessageConstants.DELETE_ERROR; + return message; + } + } + + Future getRoomTypeCount(RoomType query) async { + var db = EasyDartModule.dataBase; + + // 创建查询构建器 + SelectorBuilder select = SelectorBuilder(); + + // 添加查询条件 + if (query.id != null) { + select.eq('room_type_id', query.id); + } + if (query.tid != null) { + select.eq('oid', query.tid); + } + if (query.level != null) { + select.gte('data_level', query.level); + } + if (query.room_type_name != null) { + select.match('room_type_name', query.room_type_name!, + caseInsensitive: true); + } + if (query.description != null) { + select.eq('description', query.description); + } + if (query.created_by_id != null) { + select.eq('created_by_id', query.created_by_id); + } + if (query.created_by_name != null) { + select.eq('created_by_name', query.created_by_name); + } + if (query.updated_by_id != null) { + select.eq('updated_by_id', query.updated_by_id); + } + if (query.updated_by_name != null) { + select.eq('updated_by_name', query.updated_by_name); + } + if (query.oid != null) { + select.eq('oid', query.oid); + } + if (query.start_time != null) { + select.gte('created_time', query.start_time); + } + if (query.end_time != null) { + select.lte('created_time', query.end_time); + } + select.eq('deleted', 0); + + // 执行查询,获取符合条件的记录数量 + var result = await db.query( + 'bus_room_type', + condition: select, // 查询条件 + ); + + // 如果查询结果为空,返回 0 + if (result.isEmpty) { + return 0; + } + + // 返回计数结果 + return result.length; + } +} diff --git a/bin/repository/StatisticsRepository.dart b/bin/repository/StatisticsRepository.dart new file mode 100644 index 0000000..2d25b5d --- /dev/null +++ b/bin/repository/StatisticsRepository.dart @@ -0,0 +1,75 @@ +import 'package:EasyDartModule/EasyDartModule.dart'; + +import '../model/Bed.dart'; + +class StatisticsRepository { + // 获取床位列表,支持查询条件 + Future fetchBedList(Bed query) async { + var db = EasyDartModule.dataBase; + SelectorBuilder select = SelectorBuilder(); + + // 添加查询条件 + if (query.id != null) { + select.eq('_id', query.id); + } + if (query.tid != null) { + select.eq('oid', query.tid); + } + if (query.level != null) { + select.gte('data_level', query.level); + } + if (query.bed_type_id != null) { + select.eq('bed_type_id', query.bed_type_id); + } + if (query.bed_type_name != null) { + select.match('bed_type_name', query.bed_type_name!, + caseInsensitive: true); + } + if (query.bed_name != null) { + select.match('bed_name', query.bed_name!, caseInsensitive: true); + } + if (query.is_mapped != null) { + select.eq('is_mapped', query.is_mapped == true ? 1 : 0); + } + if (query.device_model != null) { + select.match('device_model', query.device_model!, caseInsensitive: true); + } + if (query.device_name != null) { + select.match('device_name', query.device_name!, caseInsensitive: true); + } + if (query.device_id != null) { + select.eq('device_id', query.device_id); + } + if (query.status != null) { + select.eq('status', query.status); + } + if (query.created_by_id != null) { + select.eq('created_by_id', query.created_by_id); + } + if (query.updated_by_id != null) { + select.eq('updated_by_id', query.updated_by_id); + } + if (query.oid != null) { + select.eq('oid', query.oid); + } + if (query.start_time != null) { + select.gte('created_at', query.start_time); + } + if (query.end_time != null) { + select.lte('created_at', query.end_time); + } + if (query.deleted != null) { + select.eq('deleted', query.deleted); + } + + // 执行查询 + var result = await db.query('bus_bed_info', condition: select); + + // 如果查询结果为空,返回空列表 + return result.isEmpty ? [] : result; + } + + addStatisticsDayResult() { + + } +} diff --git a/bin/repository/TestRepository.dart b/bin/repository/TestRepository.dart new file mode 100644 index 0000000..67b488f --- /dev/null +++ b/bin/repository/TestRepository.dart @@ -0,0 +1,9 @@ +import 'package:EasyDartModule/EasyDartModule.dart'; + +class TestRepository { + static Future>> query() { + return EasyDartModule.dataBase.query( + "test", + ); + } +} diff --git a/bin/service/AreaService copy.dart b/bin/service/AreaService copy.dart new file mode 100644 index 0000000..391cfc4 --- /dev/null +++ b/bin/service/AreaService copy.dart @@ -0,0 +1,1606 @@ +// import 'dart:async'; +// import 'dart:convert'; +// // import 'dart:math'; + +// import 'package:EasyDartModule/EasyDartModule.dart' as edm; + +// import '../const/CommonVariables.dart'; +// import '../model/WebSocketMessage.dart'; +// import '../repository/AreaRepository.dart'; +// // import 'package:http/http.dart' as http; + +// import '../const/ServiceConstant.dart'; +// import '../util/requestWithLog.dart'; +// import '../enum/ReportStatus.dart'; + +// class AreaService { +// final AreaRepository areaRepository = AreaRepository(); + +// Map>> bodyDataCache = +// {}; // 存储原始实时数据 mac -> list实时数据列表 +// Map>> processedDataCache = +// {}; // 存储处理过的数据 mac -> list处理数据列表 +// Map> userInfoMap = {}; // 存储用户信息 mac -> 用户信息 +// Map deviceUserMap = {}; // 设备与用户的映射 mac -> openId +// Map macProcess = {}; // 存储检测进度 mac -> 进度百分比 +// Map deviceStartTimeMap = {}; // mac -> 开始体验的时间戳(毫秒) +// Map deviceTimers = {}; // 设备超时定时器 mac -> Timer +// Map lastValidDataTime = {}; // 最后有效数据时间 mac -> timestamp +// Map lastBedStatusTime = {}; // 最后离床状态开始时间 mac -> timestamp + +// // 新增:进度相关 +// Map _progressTimers = {}; // 进度更新定时器 +// Map _lastProgressTime = {}; // 最后更新进度的时间 + +// // 新增:记录初始数据处理状态 +// Map _initialDataProcessed = {}; // 是否已处理过初始数据 + +// // 新增:心率直线检测相关 +// Map>> _heartRateSequenceCache = +// {}; // 存储心率连续相同序列 +// Map _inStraightLineMode = {}; // 是否处于直线检测模式 +// Map> _lastStraightLineStart = {}; // 直线开始的第一个数据 + +// // 新增:报告生成状态管理 +// Map _reportGeneratingMap = {}; // mac -> 是否正在生成报告 +// Map _reportGeneratedMap = {}; // mac -> 是否已生成报告 + +// int dataLength = 300; // 目标有效数据长度 +// int initialDataLength = 180; // 初始需要的数据长度(3分钟) +// int noDataTimeout = 20 * 1000; // 20秒无数据超时 +// int bedOffTimeout = 20 * 1000; // 20秒离床超时 +// int totalTimeout = 20 * 60 * 1000; // 20分钟总超时 +// int totalHeartPercent = 80; // 心率有效占比 +// int standardThreshold = 5; // 允许跳动范围 +// int heartStillTime = 10; // 心率直线判断阈值 + +// Timer? _offlineCheckTimer; +// bool _isTimerRunning = false; + +// AreaService() { +// // 从Redis恢复体验中的设备 +// _recoverExperiences(); +// // 启动离线检测定时器 +// _startOfflineCheckTimer(); +// } + +// // 从Redis恢复体验中的设备 +// Future _recoverExperiences() async { +// try { +// // 使用keys方法获取所有体验中的设备 +// final keys = await edm.EasyDartModule.redis.keys("experience_*"); + +// for (var key in keys) { +// try { +// final experienceData = await edm.EasyDartModule.redis.get(key); +// if (experienceData != null) { +// final data = jsonDecode(experienceData); +// final mac = data['mac']; +// final openId = data['openId']; +// final startTime = data['startTime']; +// final now = DateTime.now().millisecondsSinceEpoch; + +// // 如果体验时间超过20分钟,结束体验 +// if (now - startTime > totalTimeout) { +// await updateDeviceConnectStatus( +// ReportStatus.reportExceptionClose.value, mac, +// remark: "超时自动结束"); +// await _callRemoteEndExperience(mac, openId, "超时自动结束", +// ReportStatus.reportExceptionClose.value); +// await edm.EasyDartModule.redis.delete(key); +// } else { +// // 恢复设备体验状态 +// deviceStartTimeMap[mac] = startTime; +// deviceUserMap[mac] = openId; + +// // 恢复用户信息 +// final userInfoKey = "user_info_$mac"; +// final userInfoData = +// await edm.EasyDartModule.redis.get(userInfoKey); +// if (userInfoData != null) { +// userInfoMap[mac] = jsonDecode(userInfoData); +// } + +// // 恢复初始数据处理状态 +// _initialDataProcessed[mac] = false; + +// // 初始化心率序列缓存 +// _heartRateSequenceCache[mac] = []; +// _inStraightLineMode[mac] = false; + +// // 初始化报告状态 +// _reportGeneratingMap[mac] = false; +// _reportGeneratedMap[mac] = false; + +// // 启动设备超时定时器 +// _startDeviceTimeoutTimer(mac); + +// // 恢复进度定时器 +// _startProgressTimer(mac); + +// print("从Redis恢复设备体验: $mac, openId: $openId"); +// } +// } +// } catch (e) { +// print("恢复设备体验数据失败: $e"); +// } +// } +// } catch (e) { +// print("从Redis恢复体验失败: $e"); +// } +// } + +// // 保存体验信息到Redis +// Future _saveExperienceToRedis(String mac, Map userInfo, +// String openId, int startTime) async { +// try { +// final key = "experience_$mac"; +// final data = { +// 'mac': mac, +// 'openId': openId, +// 'startTime': startTime, +// 'saveTime': DateTime.now().millisecondsSinceEpoch, +// }; + +// // 保存体验信息 +// await edm.EasyDartModule.redis.set(key, jsonEncode(data)); + +// // 保存用户信息 +// final userInfoKey = "user_info_$mac"; +// await edm.EasyDartModule.redis.set(userInfoKey, jsonEncode(userInfo)); + +// print("保存体验信息到Redis: $mac, openId: $openId"); +// } catch (e) { +// print("保存体验信息到Redis失败: $e"); +// } +// } + +// // 从Redis删除体验信息 +// Future _removeExperienceFromRedis(String mac) async { +// try { +// await edm.EasyDartModule.redis.delete("experience_$mac"); +// await edm.EasyDartModule.redis.delete("user_info_$mac"); +// print("从Redis删除体验信息: $mac"); +// } catch (e) { +// print("从Redis删除体验信息失败: $e"); +// } +// } + +// // 启动设备超时定时器 +// void _startDeviceTimeoutTimer(String mac) { +// // 先取消现有的定时器 +// _stopDeviceTimeoutTimer(mac); + +// // 启动新的定时器 +// deviceTimers[mac] = Timer(Duration(milliseconds: totalTimeout), () { +// _handleDeviceTimeout(mac); +// }); +// } + +// // 停止设备超时定时器 +// void _stopDeviceTimeoutTimer(String mac) { +// if (deviceTimers.containsKey(mac) && deviceTimers[mac] != null) { +// deviceTimers[mac]!.cancel(); +// deviceTimers[mac] = null; +// } +// } + +// // 处理设备超时 +// void _handleDeviceTimeout(String mac) async { +// final openId = deviceUserMap[mac]; +// if (openId != null) { +// print("设备超时: $mac, openId: $openId"); +// await updateDeviceConnectStatus( +// ReportStatus.reportExceptionClose.value, mac, +// remark: "体验超时"); +// await _endExperience( +// mac, openId, "体验超时", ReportStatus.reportExceptionClose.value); +// } +// } + +// // 启动进度更新定时器 +// void _startProgressTimer(String mac) { +// // 先取消现有的定时器 +// _stopProgressTimer(mac); + +// // 每秒更新一次进度 +// _progressTimers[mac] = Timer.periodic(Duration(seconds: 1), (timer) { +// _updateProgress(mac); +// }); + +// _lastProgressTime[mac] = DateTime.now().millisecondsSinceEpoch; +// } + +// // 停止进度更新定时器 +// void _stopProgressTimer(String mac) { +// if (_progressTimers.containsKey(mac) && _progressTimers[mac] != null) { +// _progressTimers[mac]!.cancel(); +// _progressTimers[mac] = null; +// } +// _lastProgressTime.remove(mac); +// } + +// // 更新进度 +// void _updateProgress(String mac) { +// try { +// // 如果设备不在体验中,停止定时器 +// if (!checkUsing(mac)) { +// _stopProgressTimer(mac); +// return; +// } + +// final startTime = deviceStartTimeMap[mac]; +// if (startTime == null) return; + +// final now = DateTime.now().millisecondsSinceEpoch; +// final duration = now - startTime; + +// // 计算基于时间的进度(20分钟 = 1200秒) +// int timeBasedProgress = (duration / (20 * 60 * 1000) * 100).toInt(); + +// // 计算基于数据的进度 +// final processedCount = processedDataCache[mac]?.length ?? 0; +// int dataBasedProgress = (processedCount / dataLength * 100).toInt(); + +// // 综合进度策略: +// // 1. 前期(前2分钟)以时间进度为主 +// // 2. 中期(2-5分钟)时间和数据进度结合 +// // 3. 后期(5分钟后)以数据进度为主 + +// int finalProgress; + +// if (duration < 2 * 60 * 1000) { +// // 前2分钟 +// // 80%时间进度 + 20%数据进度 +// finalProgress = +// (timeBasedProgress * 0.8 + dataBasedProgress * 0.2).toInt(); +// } else if (duration < 5 * 60 * 1000) { +// // 2-5分钟 +// // 50%时间进度 + 50%数据进度 +// finalProgress = +// (timeBasedProgress * 0.5 + dataBasedProgress * 0.5).toInt(); +// } else { +// // 5分钟后 +// // 20%时间进度 + 80%数据进度 +// finalProgress = +// (timeBasedProgress * 0.2 + dataBasedProgress * 0.8).toInt(); +// } + +// // 确保进度不会减少(用户体验角度) +// final int currentProgress = macProcess[mac] ?? 0; +// if (finalProgress > currentProgress) { +// macProcess[mac] = finalProgress.clamp(0, 100); +// } else if (duration > 30 * 1000) { +// // 30秒后允许轻微下降,避免卡住 +// // 如果有数据但进度不增长,缓慢增加时间进度 +// if (processedCount > 0 && currentProgress < 10) { +// macProcess[mac] = (currentProgress + 1).clamp(0, 100); +// } +// } + +// // 如果报告已生成或正在生成,进度设为100% +// if ((_reportGeneratingMap[mac] ?? false) || +// (_reportGeneratedMap[mac] ?? false)) { +// macProcess[mac] = 100; +// } + +// // 记录最后更新时间 +// _lastProgressTime[mac] = now; +// } catch (e) { +// print("更新进度异常: $e, MAC=$mac"); +// } +// } + +// // 析构函数,清理定时器 +// void dispose() { +// _stopOfflineCheckTimer(); + +// // 清理所有设备定时器 +// deviceTimers.forEach((mac, timer) { +// if (timer != null) { +// timer.cancel(); +// } +// }); +// deviceTimers.clear(); + +// // 清理所有进度定时器 +// _progressTimers.forEach((mac, timer) { +// if (timer != null) { +// timer.cancel(); +// } +// }); +// _progressTimers.clear(); + +// // 清理心率序列缓存 +// _heartRateSequenceCache.clear(); +// _inStraightLineMode.clear(); +// _lastStraightLineStart.clear(); + +// // 清理报告状态 +// _reportGeneratingMap.clear(); +// _reportGeneratedMap.clear(); +// } + +// // 开始离线检测定时器 +// void _startOfflineCheckTimer() { +// if (_isTimerRunning) return; + +// _isTimerRunning = true; +// _offlineCheckTimer = Timer.periodic(Duration(seconds: 1), (timer) { +// _checkDeviceOfflineStatus(); +// }); + +// edm.EasyDartModule.logger.info("离线检测定时器已启动"); +// } + +// // 停止离线检测定时器 +// void _stopOfflineCheckTimer() { +// if (_offlineCheckTimer != null) { +// _offlineCheckTimer!.cancel(); +// _offlineCheckTimer = null; +// } +// _isTimerRunning = false; +// edm.EasyDartModule.logger.info("离线检测定时器已停止"); +// } + +// // 检查设备离线状态 +// void _checkDeviceOfflineStatus() { +// try { +// final now = DateTime.now().millisecondsSinceEpoch; + +// // 检查无数据超时 +// lastValidDataTime.forEach((mac, lastTime) { +// if (now - lastTime > noDataTimeout) { +// print("设备无数据超时: $mac"); +// _handleNoDataTimeout(mac); +// } +// }); + +// // 检查离床状态超时 +// lastBedStatusTime.forEach((mac, offBedTime) { +// if (now - offBedTime > bedOffTimeout) { +// print("设备离床超时: $mac"); +// _handleBedOffTimeout(mac); +// } +// }); +// } catch (e) { +// print("检测离线异常: $e"); +// } +// } + +// // 处理无数据超时 +// void _handleNoDataTimeout(String mac) async { +// final openId = deviceUserMap[mac]; +// if (openId != null) { +// await updateDeviceConnectStatus( +// ReportStatus.reportExceptionClose.value, mac, +// remark: "无数据超时"); +// await _endExperience( +// mac, openId, "无数据超时", ReportStatus.reportExceptionClose.value); +// } +// } + +// // 处理离床超时 +// void _handleBedOffTimeout(String mac) async { +// final openId = deviceUserMap[mac]; +// if (openId != null) { +// await updateDeviceConnectStatus( +// ReportStatus.reportExceptionClose.value, mac, +// remark: "离床超时"); +// await _endExperience( +// mac, openId, "离床超时", ReportStatus.reportExceptionClose.value); +// } +// } + +// // 开始快检体验 +// Future> startKuaijian(Map data) async { +// String msg = ""; +// int flag = 1; + +// try { +// String mac = _normalizeMac(data['mac']); +// String openId = data['openId']?.toString() ?? ''; + +// if (openId.isEmpty) { +// return {"msg": "openId不能为空", "flag": 0}; +// } + +// bool haveRun = await checkHaveRun(data); +// if (haveRun) { +// print( +// "[调试][${DateTime.now().toIso8601String()}]: 已经在运行,跳过 ${data['mac']}"); +// msg = "该设备正在体验中"; +// flag = 0; +// return {"msg": msg, "flag": flag}; +// } + +// // 检查该mac是否正在体验中 +// bool using = checkUsing(mac); +// if (using) { +// msg = "该设备正在体验中"; +// flag = 0; +// return {"msg": msg, "flag": flag}; +// } + +// bool state = await checkDeviceState(mac); +// if (!state) { +// msg = "设备离线"; +// flag = 0; +// return {"msg": msg, "flag": flag}; +// } + +// // 提取并处理用户信息(设置默认值) +// final userInfo = _processUserInfo(data); + +// // 2. 记录开始体验时间 +// final startTime = DateTime.now().millisecondsSinceEpoch; +// deviceStartTimeMap[mac] = startTime; +// deviceUserMap[mac] = openId; +// userInfoMap[mac] = userInfo; +// lastValidDataTime[mac] = startTime; // 初始化最后有效数据时间 +// _initialDataProcessed[mac] = false; // 初始化初始数据处理标志 + +// // 3. 初始化心率序列相关缓存 +// _heartRateSequenceCache[mac] = []; +// _inStraightLineMode[mac] = false; + +// // 4. 初始化报告状态 +// _reportGeneratingMap[mac] = false; +// _reportGeneratedMap[mac] = false; + +// // 5. 保存到Redis +// await _saveExperienceToRedis(mac, userInfo, openId, startTime); + +// // 6. 启动设备超时定时器 +// _startDeviceTimeoutTimer(mac); + +// // 7. 启动进度定时器 +// _startProgressTimer(mac); + +// edm.EasyDartModule.logger +// .info("记录设备开始体验时间: $mac, openId: $openId, 时间: $startTime"); + +// // 8. 调用服务号后端通知开始体验 +// await rpcStartKuaijian(data); + +// // 9. 开始记录实时数据 +// startGetBodyData(data); + +// //10.更新远程api +// await rpcStart(data); +// } catch (e) { +// print("申请体验报告失败: $e"); +// return {"msg": "系统异常", "flag": 0}; +// } + +// return {"msg": "开始体验成功", "flag": flag}; +// } + +// // 处理用户信息,设置默认值 +// Map _processUserInfo(Map data) { +// // 设置默认值 +// final defaultValues = { +// 'username': '体验用户', +// 'age': 30, +// 'height': 170, +// 'weight': 60, +// 'gender': 1, // 1:男, 2:女 +// 'phoneNo': '未知', +// 'deviceNo': data['mac'] ?? '', +// }; + +// // 处理用户信息,空值或无效值使用默认值 +// final userInfo = { +// 'username': +// _getValueOrDefault(data['username'], defaultValues['username']), +// 'age': _getIntValueOrDefault(data['age'], defaultValues['age']), +// 'height': _getIntValueOrDefault(data['height'], defaultValues['height']), +// 'weight': _getIntValueOrDefault(data['weight'], defaultValues['weight']), +// 'gender': _getIntValueOrDefault(data['gender'], defaultValues['gender']), +// 'phoneNo': _getValueOrDefault(data['phoneNo'], defaultValues['phoneNo']), +// 'deviceNo': _getValueOrDefault( +// data['deviceNo'] ?? data['mac'], defaultValues['deviceNo']), +// }; + +// // 验证年龄、身高、体重范围 - 修复类型转换问题 +// userInfo['age'] = _validateRange( +// userInfo['age'] as int, 1, 120, defaultValues['age'] as int); + +// userInfo['height'] = _validateRange( +// userInfo['height'] as int, 50, 250, defaultValues['height'] as int); + +// userInfo['weight'] = _validateRange( +// userInfo['weight'] as int, 10, 300, defaultValues['weight'] as int); + +// userInfo['gender'] = _validateRange( +// userInfo['gender'] as int, 1, 2, defaultValues['gender'] as int); + +// print("处理后的用户信息: $userInfo"); +// return userInfo; +// } + +// // 获取字符串值或默认值 +// String _getValueOrDefault(dynamic value, String defaultValue) { +// if (value == null) return defaultValue; + +// final strValue = value.toString().trim(); +// if (strValue.isEmpty) return defaultValue; + +// return strValue; +// } + +// // 获取整数值或默认值 +// int _getIntValueOrDefault(dynamic value, int defaultValue) { +// if (value == null) return defaultValue; + +// try { +// if (value is String) { +// final trimmed = value.trim(); +// if (trimmed.isEmpty) return defaultValue; +// return int.tryParse(trimmed) ?? defaultValue; +// } else if (value is int) { +// return value; +// } else if (value is double) { +// return value.toInt(); +// } else if (value is num) { +// return value.toInt(); +// } +// } catch (e) { +// print("转换整数值失败: $value, $e"); +// } + +// return defaultValue; +// } + +// // 验证数值范围 +// int _validateRange(int value, int min, int max, int defaultValue) { +// if (value >= min && value <= max) { +// return value; +// } +// return defaultValue; +// } + +// // 结束快检体验 +// Future> endKuaijian(Map data) async { +// String msg = ""; +// int flag = 1; + +// try { +// String mac = _normalizeMac(data['mac']); +// String openId = data['openId']?.toString() ?? ''; + +// if (openId.isEmpty) { +// return {"msg": "openId不能为空", "flag": 0}; +// } + +// // 检查该设备是否在体验中 +// if (!checkUsing(mac)) { +// return {"msg": "该设备未在体验中", "flag": 0}; +// } + +// // 检查是否是同一个用户 +// if (deviceUserMap[mac] != openId) { +// return {"msg": "无权结束该设备的体验", "flag": 0}; +// } + +// // 检查是否已经在生成报告 +// if (_reportGeneratingMap[mac] ?? false) { +// return {"msg": "报告正在生成中,请稍候", "flag": 0}; +// } + +// // 检查是否已经生成报告 +// if (_reportGeneratedMap[mac] ?? false) { +// return {"msg": "报告已生成,请查看结果", "flag": 0}; +// } + +// // 获取当前有效数据量 +// final processedCount = processedDataCache[mac]?.length ?? 0; + +// if (processedCount >= dataLength) { +// // 正常完成体验,生成报告 +// final reportId = await _requestSleepAnalytics(mac, openId); +// if (reportId != null) { +// msg = "体验完成,报告ID: $reportId"; +// await _callRemoteCompleteExperience( +// mac, openId, "正常完成", reportId, ReportStatus.completed.value); +// } else { +// msg = "体验完成,但生成报告失败"; +// await updateDeviceConnectStatus( +// ReportStatus.reportExceptionClose.value, mac, +// remark: "报告生成失败"); +// await _endExperience( +// mac, openId, "报告生成失败", ReportStatus.reportExceptionClose.value); +// } +// } else { +// // 提前结束体验 +// await updateDeviceConnectStatus(ReportStatus.appNormalClose.value, mac, +// remark: "用户主动结束"); +// await _endExperience( +// mac, openId, "用户主动结束", ReportStatus.appNormalClose.value); +// msg = "体验已提前结束"; +// } +// } catch (e) { +// print("结束体验失败: $e"); +// return {"msg": "系统异常", "flag": 0}; +// } + +// return {"msg": msg, "flag": flag}; +// } + +// // 结束体验的通用方法 +// Future _endExperience( +// String mac, String openId, String reason, int reportStatus, +// {bool rpc = true}) async { +// try { +// print("结束体验: MAC=$mac, openId=$openId, 原因=$reason"); + +// // 1. 调用远程结束接口 +// if (rpc) { +// await _callRemoteEndExperience(mac, openId, reason, reportStatus); +// } + +// // 2. 清理本地数据 +// deviceStartTimeMap.remove(mac); +// deviceUserMap.remove(mac); +// userInfoMap.remove(mac); +// bodyDataCache.remove(mac); +// processedDataCache.remove(mac); +// macProcess.remove(mac); +// lastValidDataTime.remove(mac); +// lastBedStatusTime.remove(mac); +// _initialDataProcessed.remove(mac); + +// // 3. 清理心率序列相关缓存 +// _heartRateSequenceCache.remove(mac); +// _inStraightLineMode.remove(mac); +// _lastStraightLineStart.remove(mac); + +// // 4. 清理报告状态 +// _reportGeneratingMap.remove(mac); +// _reportGeneratedMap.remove(mac); + +// // 5. 停止定时器 +// _stopDeviceTimeoutTimer(mac); +// _stopProgressTimer(mac); + +// // 6. 从Redis删除 +// await _removeExperienceFromRedis(mac); + +// // 7. 停止监听设备数据 +// _stopListeningDeviceData(mac); + +// // 8. 通知前端 +// _notifyExperienceEnd(mac, openId, reason); + +// edm.EasyDartModule.logger.info("体验已结束: $mac, 原因: $reason"); +// } catch (e) { +// edm.EasyDartModule.logger.error("结束体验异常: $e, MAC=$mac"); +// } +// } + +// // 请求睡眠分析报告 +// Future _requestSleepAnalytics(String mac, String openId) async { +// try { +// // 检查是否已经在生成报告 +// if (_reportGeneratingMap[mac] ?? false) { +// print("报告已经在生成中,跳过重复请求: $mac"); +// return null; +// } + +// // 检查是否已经生成报告 +// if (_reportGeneratedMap[mac] ?? false) { +// print("报告已经生成,跳过重复请求: $mac"); +// return null; +// } + +// final userInfo = userInfoMap[mac]; +// final processedData = processedDataCache[mac]; + +// if (userInfo == null || +// processedData == null || +// processedData.length < dataLength) { +// print("请求报告失败: 数据不足或用户信息缺失"); +// await updateDeviceConnectStatus( +// ReportStatus.reportExceptionClose.value, mac, +// remark: "数据不足或用户信息缺失"); +// return null; +// } + +// // 设置报告正在生成中 +// _reportGeneratingMap[mac] = true; +// print("开始生成报告: $mac, openId: $openId, 数据量: ${processedData.length}"); + +// // 准备请求数据 +// final Map requestData = { +// "username": userInfo['username'], +// "age": userInfo['age'], +// "height": userInfo['height'], +// "weight": userInfo['weight'], +// "gender": userInfo['gender'], +// "deviceNo": userInfo['deviceNo'], +// "phoneNo": userInfo['phoneNo'], +// "dataList": processedData, +// }; + +// print( +// "用户信息: ${userInfo['username']}, 年龄: ${userInfo['age']}, 电话: ${userInfo['phoneNo']}"); + +// // 发送HTTP请求 +// final reportId = await _sendReportRequest(requestData, mac); + +// // 报告生成完成 +// _reportGeneratingMap[mac] = false; + +// if (reportId != null) { +// _reportGeneratedMap[mac] = true; +// print("报告生成成功: $reportId"); +// return reportId; +// } else { +// print("报告生成失败"); +// await updateDeviceConnectStatus( +// ReportStatus.reportExceptionClose.value, mac, +// remark: "报告生成失败"); +// return null; +// } +// } catch (e) { +// print("请求睡眠分析异常: $e"); +// _reportGeneratingMap[mac] = false; +// await updateDeviceConnectStatus( +// ReportStatus.reportExceptionClose.value, mac, +// remark: "请求睡眠分析异常: $e"); +// return null; +// } +// } + +// // 发送报告请求 +// Future _sendReportRequest( +// Map data, String mac) async { +// try { +// // 处理 dataList 的数据转换 +// if (data['dataList'] != null && data['dataList'] is List) { +// List> originalList = +// List>.from(data['dataList']); + +// // 将原始数据转换为新的格式 +// List> transformedList = originalList.map((item) { +// // 从原始数据中提取 heartRate 和 breathRate +// // 如果字段不存在或为null,则使用默认值0 +// int heartRate = item['heartRate'] is int +// ? item['heartRate'] +// : (item['heartRate'] is double +// ? (item['heartRate'] as double).toInt() +// : 0); + +// int breathRate = item['breathRate'] is int +// ? item['breathRate'] +// : (item['breathRate'] is double +// ? (item['breathRate'] as double).toInt() +// : 0); + +// // 创建新的数据结构 +// return { +// 'breath': breathRate, +// 'heart': heartRate, +// }; +// }).toList(); + +// // 替换原始 dataList 为转换后的数据 +// data['dataList'] = transformedList; +// } + +// // 打印转换后的数据用于调试 +// print('转换后的数据: ${jsonEncode(data)}'); + +// await requestSleepAnalytics(data, mac); +// return null; // 由于是异步调用,这里返回null,实际结果在回调中处理 +// } catch (e) { +// print("发送报告请求异常: $e"); +// await updateDeviceConnectStatus( +// ReportStatus.reportExceptionClose.value, mac, +// remark: "发送报告请求异常: $e"); +// return null; +// } +// } + +// // 调用远程完成接口 +// Future _callRemoteCompleteExperience(String mac, String openId, +// String reason, String reportId, int reportStatus) async { +// try { +// // 调用您的远程完成接口 +// print("调用远程完成接口: $mac, openId: $openId, 原因: $reason, 报告ID: $reportId"); +// // 结束体验 +// await _endExperience( +// mac, openId, "$reason, 报告ID: $reportId", reportStatus); +// } catch (e) { +// print("调用远程完成接口失败: $e"); +// await updateDeviceConnectStatus( +// ReportStatus.reportExceptionClose.value, mac, +// remark: "调用远程完成接口失败: $e"); +// } +// } + +// // 调用远程结束接口 +// Future _callRemoteEndExperience( +// String mac, String openId, String reason, int reportStatus) async { +// try { +// // 调用您的远程完成接口 +// print("调用远程结束接口: $mac, openId: $openId, 原因: $reason"); +// // TODO: 实现具体的远程调用 +// await updateDeviceConnectStatus(reportStatus, mac, remark: reason); +// } catch (e) { +// print("调用远程结束接口失败: $e"); +// } +// } + +// // 通知体验结束 +// void _notifyExperienceEnd(String mac, String openId, String reason) { +// try { +// edm.EasyDartModule.websocket.sendData(jsonEncode({ +// "type": "experience_end", +// "mac": mac, +// "openId": openId, +// "reason": reason, +// "timestamp": DateTime.now().millisecondsSinceEpoch, +// "message": "体验已结束: $reason" +// })); +// } catch (e) { +// print("发送体验结束通知失败: $e"); +// } +// } + +// // 检查是否体验中 +// bool checkUsing(String mac) { +// String normalizedMac = _normalizeMac(mac); +// return deviceStartTimeMap.containsKey(normalizedMac); +// } + +// // 远程通知分析开始 +// Future rpcStartKuaijian(data) async { +// // TODO: 实现远程开始接口 +// } + +// // 开始获取实时数据 +// void startGetBodyData(data) { +// try { +// String mac = _normalizeMac(data['mac']); +// data['mac'] = mac; // 统一格式 + +// // 监听 WebSocket 实时数据 +// CommonVariables.callMap["/vsbs/web/rt/marttress"] = (receivedData) { +// _handleWebSocketData(receivedData); +// }; + +// print("开始监听体征数据"); +// edm.EasyDartModule.websocket.sendData(jsonEncode(WebSocketMessage( +// path: "/vsbs/web/rt/marttress", type: 1, data: {"mac": mac}))); +// } catch (e) { +// edm.EasyDartModule.logger.error("[websocket]获取体征数据异常: $e"); +// } +// } + +// // 处理WebSocket数据 +// Future _handleWebSocketData(dynamic receivedData) async { +// try { +// print("当前心率为: ${receivedData['heartRate']}"); +// print("当前有效数据为: ${processedDataCache['${receivedData['mac']}']?.length}"); +// if (receivedData is! Map) return; + +// // 将Map转换为Map +// final Map data = {}; +// receivedData.forEach((key, value) { +// data[key.toString()] = value; +// }); + +// // 为数据添加时间戳 +// data['timestamp'] = DateTime.now().millisecondsSinceEpoch; + +// // 统一mac格式 +// if (data.containsKey('mac')) { +// String mac = _normalizeMac(data['mac']); +// data['mac'] = mac; + +// // 检查设备是否在体验中 +// if (!checkUsing(mac)) { +// return; // 不在体验中的设备数据直接忽略 +// } + +// // 检查是否已经生成报告,如果已经生成则不再处理数据 +// if (_reportGeneratedMap[mac] ?? false) { +// print("报告已生成,不再处理数据: $mac"); +// return; +// } + +// // 更新最后有效数据时间 +// lastValidDataTime[mac] = data['timestamp']; + +// // 处理离床状态 +// _handleBedStatus(mac, data); + +// // 处理离线状态 +// if (data['status'] == "离线") { +// final openId = deviceUserMap[mac]; +// if (openId != null) { +// await updateDeviceConnectStatus( +// ReportStatus.reportExceptionClose.value, mac, +// remark: "设备离线"); +// _endExperience( +// mac, openId, "设备离线", ReportStatus.reportExceptionClose.value); +// } +// return; +// } + +// // 存储原始数据 +// storeInstantData(data); + +// // 处理数据(包含心率直线检测) +// _processDataWithHeartRateDetection(mac, data); + +// edm.EasyDartModule.logger.info("[websocket]实时体征数据-->$data"); +// } +// } catch (e) { +// print("处理WebSocket数据异常: $e"); +// } +// } + +// // 处理离床状态 +// void _handleBedStatus(String mac, Map data) { +// if (data["inBed"] == "离床") { +// // 记录离床开始时间 +// if (!lastBedStatusTime.containsKey(mac)) { +// lastBedStatusTime[mac] = data['timestamp']; +// } +// } else { +// // 清除离床计时 +// lastBedStatusTime.remove(mac); +// } +// } + +// // 存储原始实时数据 +// void storeInstantData(Map data) { +// try { +// String mac = data['mac']; + +// // 如果不存在该 mac,则先创建一个空 list +// bodyDataCache.putIfAbsent(mac, () => []); + +// // 往对应的 list 中添加数据 +// bodyDataCache[mac]!.add(Map.from(data)); + +// // 限制数据长度(保留足够的数据用于处理) +// if (bodyDataCache[mac]!.length > dataLength * 2) { +// bodyDataCache[mac]!.removeAt(0); +// } +// } catch (e) { +// print("storeInstantData异常: $e"); +// } +// } + +// Future _processDataWithHeartRateDetection( +// String mac, Map data) async { +// try { +// // 检查是否已经生成报告,如果已经生成则不再处理数据 +// if (_reportGeneratedMap[mac] ?? false) { +// return; +// } + +// // 初始化处理数据缓存 +// processedDataCache.putIfAbsent(mac, () => []); +// _heartRateSequenceCache.putIfAbsent(mac, () => []); + +// final processedList = processedDataCache[mac]!; +// final sequenceCache = _heartRateSequenceCache[mac]!; + +// // 检查数据有效性 +// if (data['heartRate'] == -1 || +// data['heartRate'] == 0 || +// data['breathRate'] == -1 || +// data['breathRate'] == 0 || +// data['bodyMotion'] != 0 || +// data['inBed'] != '在床') { +// // 无效数据,重置序列 +// if (sequenceCache.isNotEmpty) { +// sequenceCache.clear(); +// } +// return; +// } + +// // 获取当前心率 +// int currentHeartRate = data['heartRate'] is int +// ? data['heartRate'] +// : (data['heartRate'] is double +// ? (data['heartRate'] as double).toInt() +// : 0); + +// // === 修正的核心逻辑 === + +// // 如果序列为空或当前心率与序列最后心率相同 +// if (sequenceCache.isEmpty || +// (sequenceCache.isNotEmpty && +// sequenceCache.last['heartRate'] == currentHeartRate)) { +// // 添加到连续相同心率序列 +// sequenceCache.add({ +// 'heartRate': currentHeartRate, +// 'data': data, +// 'timestamp': data['timestamp'], +// }); +// } else { +// // 心率发生变化 - 处理之前的序列 +// _processHeartRateSequence(mac, sequenceCache, processedList); + +// // 清空序列,开始新的序列 +// sequenceCache.clear(); +// sequenceCache.add({ +// 'heartRate': currentHeartRate, +// 'data': data, +// 'timestamp': data['timestamp'], +// }); +// } + +// // === 修正的核心逻辑结束 === + +// // 处理初始数据(只执行一次) +// if (processedList.length == initialDataLength && +// !_initialDataProcessed[mac]!) { +// print("开始处理初始数据,数据量: ${processedList.length}"); +// _processInitialData(mac); +// _initialDataProcessed[mac] = true; +// } + +// // 检查是否达到目标数据量 - 修改为只触发一次 +// if (processedList.length >= dataLength && +// !(_reportGeneratingMap[mac] ?? false) && +// !(_reportGeneratedMap[mac] ?? false)) { +// final openId = deviceUserMap[mac]; +// if (openId != null) { +// print("达到目标数据量,开始生成报告: $mac, 数据量: ${processedList.length}"); + +// // 异步生成报告,避免阻塞数据处理 +// Future.delayed(Duration.zero, () { +// _requestSleepAnalytics(mac, openId).then((reportId) { +// if (reportId != null) { +// _callRemoteCompleteExperience(mac, openId, "数据采集完成", reportId, +// ReportStatus.completed.value); +// } else { +// // 报告生成失败,继续收集数据 +// print("报告生成失败,继续收集数据: $mac"); +// } +// }); +// }); +// } +// } +// print("当前有效数据为: ${processedDataCache['$mac']?.length}"); +// } catch (e) { +// print("处理数据异常: $e, MAC=$mac"); +// // 处理数据异常时更新状态 +// if (checkUsing(mac)) { +// await updateDeviceConnectStatus( +// ReportStatus.reportExceptionClose.value, mac, +// remark: "处理数据异常: $e"); +// } +// } +// } + +// // 新增:处理心率序列的辅助方法 +// void _processHeartRateSequence( +// String mac, +// List> sequenceCache, +// List> processedList) { +// if (sequenceCache.isEmpty) return; + +// if (sequenceCache.length >= heartStillTime) { +// // 连续相同心率达到或超过10次 - 只保留第一个和最后一个 +// print("连续相同心率达到${sequenceCache.length}次(>=${heartStillTime}),进行去重处理"); + +// // 第一个数据点 +// final firstData = sequenceCache.first['data']; +// final firstProcessedData = { +// 'mac': mac, +// 'heartRate': firstData['heartRate'], +// 'breathRate': firstData['breathRate'], +// 'timestamp': firstData['timestamp'], +// 'bodyMotion': firstData['bodyMotion'], +// }; + +// // 检查是否重复(与上一个处理的数据比较) +// if (processedList.isEmpty || +// processedList.last['heartRate'] != firstProcessedData['heartRate'] || +// processedList.last['breathRate'] != +// firstProcessedData['breathRate']) { +// processedList.add(firstProcessedData); +// print("添加直线开始数据点: 心率 ${firstProcessedData['heartRate']}"); +// } + +// // 最后一个数据点 +// final lastData = sequenceCache.last['data']; +// final lastProcessedData = { +// 'mac': mac, +// 'heartRate': lastData['heartRate'], +// 'breathRate': lastData['breathRate'], +// 'timestamp': lastData['timestamp'], +// 'bodyMotion': lastData['bodyMotion'], +// }; + +// // 检查是否重复(与上一个处理的数据比较) +// if (processedList.isEmpty || +// processedList.last['heartRate'] != lastProcessedData['heartRate'] || +// processedList.last['breathRate'] != lastProcessedData['breathRate']) { +// processedList.add(lastProcessedData); +// print("添加直线结束数据点: 心率 ${lastProcessedData['heartRate']}"); +// } +// } else { +// // 连续相同心率少于10次 - 全部保留 +// print("连续相同心率${sequenceCache.length}次(<${heartStillTime}),全部保留"); + +// for (var seqData in sequenceCache) { +// final processedData = { +// 'mac': mac, +// 'heartRate': seqData['data']['heartRate'], +// 'breathRate': seqData['data']['breathRate'], +// 'timestamp': seqData['data']['timestamp'], +// 'bodyMotion': seqData['data']['bodyMotion'], +// }; + +// // 检查是否重复(与上一个处理的数据比较) +// // 这里注意:对于连续相同的数据,我们不应该去重,所以去掉这个检查 +// processedList.add(processedData); +// } +// } +// } + +// // 处理初始数据(前3分钟) +// void _processInitialData(String mac) async { +// try { +// final processedList = processedDataCache[mac]!; + +// // 1. 检查数据量是否足够 +// if (processedList.length < initialDataLength ~/ 2) { +// // 数据量少于一半,结束体验 +// final openId = deviceUserMap[mac]; +// if (openId != null) { +// print("初始数据不足,结束体验: $mac, 数据量: ${processedList.length}"); +// await updateDeviceConnectStatus( +// ReportStatus.reportExceptionClose.value, mac, +// remark: "初始数据不足"); +// _endExperience( +// mac, openId, "初始数据不足", ReportStatus.reportExceptionClose.value); +// } +// return; +// } + +// // 2. 计算平均心率 +// int totalHeartRate = 0; +// for (var data in processedList) { +// final heartRate = data['heartRate']; +// if (heartRate is int) { +// totalHeartRate += heartRate; +// } else if (heartRate is num) { +// totalHeartRate += heartRate.toInt(); +// } else if (heartRate is String) { +// totalHeartRate += int.tryParse(heartRate) ?? 0; +// } +// } + +// double avgHeartRate = totalHeartRate / processedList.length; + +// // 3. 计算在平均值±5范围内的数据百分比 +// int inRangeCount = 0; +// for (var data in processedList) { +// final heartRate = data['heartRate']; +// double? hrValue; + +// if (heartRate is int) { +// hrValue = heartRate.toDouble(); +// } else if (heartRate is num) { +// hrValue = heartRate.toDouble(); +// } else if (heartRate is String) { +// hrValue = double.tryParse(heartRate); +// } + +// if (hrValue != null && +// hrValue >= avgHeartRate - standardThreshold && +// hrValue <= avgHeartRate + standardThreshold) { +// inRangeCount++; +// } +// } + +// double inRangePercent = (inRangeCount / processedList.length) * 100; + +// // 4. 如果小于阈值,结束体验 +// if (inRangePercent < totalHeartPercent) { +// final openId = deviceUserMap[mac]; +// if (openId != null) { +// print( +// "心率数据不稳定,结束体验: $mac, 平均心率: $avgHeartRate, 在范围比例: $inRangePercent%"); +// await updateDeviceConnectStatus( +// ReportStatus.reportExceptionClose.value, mac, +// remark: "心率数据不稳定"); +// _endExperience( +// mac, openId, "心率数据不稳定", ReportStatus.reportExceptionClose.value); +// } +// return; +// } + +// print("初始数据处理通过: $mac, 平均心率: $avgHeartRate, 在范围比例: $inRangePercent%"); +// } catch (e) { +// print("处理初始数据异常: $e, MAC=$mac"); +// // 处理初始数据异常时更新状态 +// if (checkUsing(mac)) { +// await updateDeviceConnectStatus( +// ReportStatus.reportExceptionClose.value, mac, +// remark: "处理初始数据异常: $e"); +// } +// } +// } + +// // 获取实时数据 +// Map getInstantData(String mac, String openId) { +// String normalizedMac = _normalizeMac(mac); +// String msg = ""; +// int flag = 1; +// var data; + +// // 检查设备是否在体验中 +// if (!deviceStartTimeMap.containsKey(normalizedMac)) { +// flag = -1; +// msg = "该设备未开始体验"; +// data = null; +// } +// // 检查用户是否匹配 +// else if (deviceUserMap[normalizedMac] != openId) { +// flag = -2; +// msg = "无权查看该设备数据"; +// data = null; +// } +// // 检查是否有缓存数据 +// else if (!bodyDataCache.containsKey(normalizedMac) || +// bodyDataCache[normalizedMac]!.isEmpty) { +// flag = 0; +// msg = "该设备暂无数据"; +// data = null; +// } else { +// // 取最新一次数据 +// data = Map.from(bodyDataCache[normalizedMac]!.last); + +// // 添加进度信息 +// data['process'] = macProcess[normalizedMac] ?? 0; +// data['openId'] = openId; + +// // 添加体验时长 +// final startTime = deviceStartTimeMap[normalizedMac]!; +// final duration = DateTime.now().millisecondsSinceEpoch - startTime; +// data['experienceDuration'] = duration ~/ 1000; // 转换为秒 + +// // 添加有效数据量 +// final processedCount = processedDataCache[normalizedMac]?.length ?? 0; +// data['processedDataCount'] = processedCount; +// data['targetDataCount'] = dataLength; + +// // 添加报告状态 +// data['reportGenerating'] = _reportGeneratingMap[normalizedMac] ?? false; +// data['reportGenerated'] = _reportGeneratedMap[normalizedMac] ?? false; + +// // 添加用户信息(可选) +// data['userInfo'] = userInfoMap[normalizedMac]; +// } + +// return {"msg": msg, "flag": flag, "data": data}; +// } + +// // 停止监听设备数据 +// void _stopListeningDeviceData(String mac) { +// try { +// edm.EasyDartModule.websocket.sendData(jsonEncode( +// WebSocketMessage(path: "/vsbs/web/rt/marttress", type: 2))); +// } catch (e) { +// print("停止监听设备数据失败: $e"); +// } +// } + +// // 获取所有正在体验的设备列表 +// List> getActiveDevices() { +// return deviceStartTimeMap.entries.map((entry) { +// final mac = entry.key; +// return { +// 'mac': mac, +// 'openId': deviceUserMap[mac], +// 'startTime': entry.value, +// 'progress': macProcess[mac] ?? 0, +// 'processedData': processedDataCache[mac]?.length ?? 0, +// 'reportGenerating': _reportGeneratingMap[mac] ?? false, +// 'reportGenerated': _reportGeneratedMap[mac] ?? false, +// 'userInfo': userInfoMap[mac], +// }; +// }).toList(); +// } + +// // 获取设备体验时长 +// int? getDeviceExperienceDuration(String mac) { +// String normalizedMac = _normalizeMac(mac); +// if (deviceStartTimeMap.containsKey(normalizedMac)) { +// final now = DateTime.now().millisecondsSinceEpoch; +// return now - deviceStartTimeMap[normalizedMac]!; +// } +// return null; +// } + +// // 统一mac地址格式 +// String _normalizeMac(String mac) { +// if (mac == null || mac.isEmpty) return ''; + +// String normalized = +// mac.toString().replaceAll(RegExp(r'[:-\s]'), '').toUpperCase().trim(); + +// return normalized; +// } + +// // 调试方法:打印当前状态 +// void printStatus() { +// print("=== AreaService 状态 ==="); +// print("正在体验的设备:"); +// deviceStartTimeMap.forEach((mac, startTime) { +// final openId = deviceUserMap[mac]; +// final progress = macProcess[mac] ?? 0; +// final processedCount = processedDataCache[mac]?.length ?? 0; +// final reportGenerating = _reportGeneratingMap[mac] ?? false; +// final reportGenerated = _reportGeneratedMap[mac] ?? false; +// final userInfo = userInfoMap[mac]; +// print(" $mac (用户: $openId) - 进度: $progress%, 有效数据: $processedCount"); +// print(" 报告状态: 生成中=$reportGenerating, 已生成=$reportGenerated"); +// print( +// " 用户信息: ${userInfo?['username']}, 年龄: ${userInfo?['age']}, 电话: ${userInfo?['phoneNo']}"); +// }); +// print("======================"); +// } + +// checkHaveRun(data) async { +// data['deviceNo'] = data['mac']; +// String serviceAddress = ServiceConstant.service_address; +// String serviceName = ServiceConstant.app_server_service; +// String serviceApi = "/checkreport/${data['mac']}"; +// String queryUrl = "${serviceAddress}${serviceName}${serviceApi}"; +// bool flag = false; +// await requestWithLog( +// logTitle: "APP端提检查快检报告开始体验", +// method: MyHttpMethod.get, +// queryUrl: queryUrl, +// data: data['data'], +// onSuccess: (res) { +// flag = res.data; +// print("[调试][成功][${DateTime.now().toIso8601String()}]: 接收到数据结果为${flag}"); +// }, +// onFailure: (res) { +// flag = true; +// print("[调试][失败][${DateTime.now().toIso8601String()}]: 接收到数据结果为${flag}"); +// }, +// ); +// return flag; +// } + +// Future rpcStart(Map data) async { +// try { +// String serviceAddress = ServiceConstant.service_address; +// String serviceName = ServiceConstant.app_server_service; +// String serviceApi = "/reportsubmit"; +// String queryUrl = "${serviceAddress}${serviceName}${serviceApi}"; +// data['openid'] = data['openId']; +// data['status'] = ReportStatus.experienceing.value; +// await requestWithLog( +// logTitle: "APP端提交快检报告开始体验", +// method: MyHttpMethod.post, +// queryUrl: queryUrl, +// data: data, +// onSuccess: (res) { +// print("通知体验开始成功"); +// }, +// onFailure: (res) { +// print("提交快检报告开始体验失败"); +// }, +// ); +// } catch (e) { +// print("远程调用失败:$e"); +// } +// } + +// Future requestSleepAnalytics( +// Map data, String mac) async { +// try { +// String queryUrl = +// "https://health.ciotcp.com/api/api/h5/getReportByOtherData"; +// int retryCount = 0; +// bool isSuccess = false; + +// while (retryCount < 3 && !isSuccess) { +// await requestWithLog( +// logTitle: "请求实时分析", +// method: MyHttpMethod.post, +// data: data, +// queryUrl: queryUrl, +// onSuccess: (res) async { +// if (res.data == null || res.data == "") { +// retryCount++; +// if (retryCount < 3) { +// print("请求失败,正在尝试第${retryCount}次重试..."); +// } else { +// print("请求失败,已尝试3次,停止重试"); +// await updateDeviceConnectStatus( +// ReportStatus.reportExceptionClose.value, mac, +// remark: "报告请求失败"); +// } +// } else { +// isSuccess = true; +// print("请求成功,报告ID: ${res.data}"); +// print( +// "报告地址: https://health.ciotcp.com/mobile/quickDetail?type=quickCheck&useFrom=Quansi&reportId=${res.data}"); +// String openId = deviceUserMap[mac] ?? ""; + +// await finishDevice(res.data, mac); +// await _endExperience( +// mac, openId, "体验结束", ReportStatus.reportExceptionClose.value, +// rpc: false); +// } +// }, +// onFailure: (res) async { +// if (res.code == 20000 && res.data != null) { +// // 请求成功,通常不应该进入这里,但为了确保 +// isSuccess = true; +// print("请求成功,报告ID: ${res.data}"); +// await finishDevice(res.data, mac); +// } else { +// // 请求失败,重新尝试 +// retryCount++; +// if (retryCount < 3) { +// print("请求失败,正在尝试第${retryCount}次重试..."); +// } else { +// print("请求失败,已尝试3次,停止重试"); +// await updateDeviceConnectStatus( +// ReportStatus.reportExceptionClose.value, mac, +// remark: "报告请求失败"); +// } +// } +// }, +// ); +// } +// if (!isSuccess) { +// print("最终请求失败,无法获取报告数据"); +// await updateDeviceConnectStatus( +// ReportStatus.reportExceptionClose.value, mac, +// remark: "最终请求失败,无法获取报告数据"); +// } +// } catch (e) { +// print("[请求报告失败]:报告异常:$e"); +// print("[微信]:报告异常:$e"); +// await updateDeviceConnectStatus( +// ReportStatus.reportExceptionClose.value, mac, +// remark: "请求报告失败异常: $e"); +// } +// } + +// Future finishDevice(String reportId, String mac) async { +// try { +// // 从 deviceUserMap 中获取对应的 openid +// String? openid = deviceUserMap[mac]; + +// if (openid == null) { +// print("无法找到设备 $mac 对应的用户信息"); +// await updateDeviceConnectStatus( +// ReportStatus.reportExceptionClose.value, mac, +// remark: "无法找到用户信息"); +// return; +// } + +// String serviceAddress = ServiceConstant.service_address; +// String serviceName = ServiceConstant.app_server_service; +// String serviceApi = "/reportfinish"; +// String queryUrl = "${serviceAddress}${serviceName}${serviceApi}"; + +// // 从 userInfoMap 中获取 deviceNo 或使用 mac +// final userInfo = userInfoMap[mac]; +// String deviceNo = userInfo?['deviceNo'] ?? mac; + +// Map finishData = { +// "deviceNo": deviceNo, +// "openid": openid, +// "reportId": reportId, +// }; + +// print("发送报告完成请求: deviceNo=$deviceNo, openid=$openid, reportId=$reportId"); + +// await requestWithLog( +// logTitle: "更新完成状态", +// method: MyHttpMethod.post, +// data: finishData, +// queryUrl: queryUrl, +// onSuccess: (res) { +// print("[微信]:报告完成成功 $finishData"); +// }, +// onFailure: (res) { +// print("[微信]:报告完成失败 $finishData"); +// // 报告完成失败时也要更新状态 +// updateDeviceConnectStatus( +// ReportStatus.reportExceptionClose.value, mac, +// remark: "报告完成失败"); +// }, +// ); +// } catch (e) { +// print("发送报告完成请求异常: $e"); +// await updateDeviceConnectStatus( +// ReportStatus.reportExceptionClose.value, mac, +// remark: "发送报告完成请求异常: $e"); +// } +// } + +// //更新设备状态 +// Future updateDeviceConnectStatus(int status, String mac, +// {String? remark}) async { +// try { +// String serviceAddress = ServiceConstant.service_address; +// String serviceName = ServiceConstant.app_server_service; +// String serviceApi = "/reportupdatestatus"; +// String queryUrl = "${serviceAddress}${serviceName}${serviceApi}"; + +// String? openid = deviceUserMap[mac]; + +// if (openid == null) { +// print("无法找到设备 $mac 对应的用户信息"); +// return; +// } +// // 初始化 data +// Map data = { +// "deviceNo": mac, +// "openid": openid, +// "status": status, +// }; + +// // 如果 remark 不为空,则添加到 data 中 +// if (remark != null && remark.isNotEmpty) { +// data['remark'] = remark; +// } + +// await requestWithLog( +// logTitle: "更新设备处理状态", +// method: MyHttpMethod.post, +// data: data, +// queryUrl: queryUrl, +// onSuccess: (res) { +// print("[微信]:更新状态成功为$data"); +// }, +// onFailure: (res) { +// //更新失败 +// print("[微信]:更新状态失败,数据为$data"); +// }, +// ); +// } catch (e) { +// print("[微信]:更新失状态败-》$e"); +// } +// } + +// checkDeviceState(String mac) async { +// try { +// bool flag = false; +// String queryUrl = +// "https://iot.he-info.cn/api/iot/device/info/status?did=${mac}&token=M5Y3B4Frr6T1ACtwMfTNaSaxE2DT16Tn"; +// await requestWithLog( +// logTitle: "查询设备状态", +// method: MyHttpMethod.get, +// queryUrl: queryUrl, +// onSuccess: (res) { +// flag = (res.data[0]['state']) == 3 || +// (res.data[0]['state']) == 4 +// ? true +// : false; +// }, +// onFailure: (res) { +// //更新失败 +// flag = (res.data[0]['state']) == 3 || +// (res.data[0]['state']) == 4 +// ? true +// : false; +// }, +// ); +// return flag; +// } catch (e) { +// print("获取设备状态失败,数据为$e"); +// return false; +// } +// } +// } diff --git a/bin/service/AreaService.dart b/bin/service/AreaService.dart new file mode 100644 index 0000000..4d0ed08 --- /dev/null +++ b/bin/service/AreaService.dart @@ -0,0 +1,1692 @@ +import 'dart:async'; +import 'dart:convert'; +// import 'dart:math'; + +import 'package:EasyDartModule/EasyDartModule.dart' as edm; + +import '../const/CommonVariables.dart'; +import '../model/WebSocketMessage.dart'; +import '../repository/AreaRepository.dart'; +// import 'package:http/http.dart' as http; + +import '../const/ServiceConstant.dart'; +import '../util/requestWithLog.dart'; +import '../enum/ReportStatus.dart'; + +class AreaService { + final AreaRepository areaRepository = AreaRepository(); + + Map>> bodyDataCache = + {}; // 存储原始实时数据 mac -> list实时数据列表 + Map>> processedDataCache = + {}; // 存储处理过的数据 mac -> list处理数据列表 + Map> userInfoMap = {}; // 存储用户信息 mac -> 用户信息 + Map deviceUserMap = {}; // 设备与用户的映射 mac -> openId + Map macProcess = {}; // 存储检测进度 mac -> 进度百分比 + Map deviceStartTimeMap = {}; // mac -> 开始体验的时间戳(毫秒) + Map deviceTimers = {}; // 设备超时定时器 mac -> Timer + Map lastValidDataTime = {}; // 最后有效数据时间 mac -> timestamp + Map lastBedStatusTime = {}; // 最后离床状态开始时间 mac -> timestamp + + // 新增:进度相关 + Map _progressTimers = {}; // 进度更新定时器 + Map _lastProgressTime = {}; // 最后更新进度的时间 + + // 新增:记录初始数据处理状态 + Map _initialDataProcessed = {}; // 是否已处理过初始数据 + + // 新增:心率直线检测相关 + Map>> _heartRateSequenceCache = + {}; // 存储心率连续相同序列 + Map _inStraightLineMode = {}; // 是否处于直线检测模式 + Map> _lastStraightLineStart = {}; // 直线开始的第一个数据 + + // 新增:报告生成状态管理 + Map _reportGeneratingMap = {}; // mac -> 是否正在生成报告 + Map _reportGeneratedMap = {}; // mac -> 是否已生成报告 + + int dataLength = 300; // 目标有效数据长度 + int initialDataLength = 180; // 初始需要的数据长度(3分钟) + int noDataTimeout = 20 * 1000; // 20秒无数据超时 + int bedOffTimeout = 20 * 1000; // 20秒离床超时 + int totalTimeout = 20 * 60 * 1000; // 20分钟总超时 + int totalHeartPercent = 80; // 心率有效占比 + int standardThreshold = 5; // 允许跳动范围 + int heartStillTime = 10; // 心率直线判断阈值 + + Timer? _offlineCheckTimer; + bool _isTimerRunning = false; + + // Redis 相关常量 + final int _redisExpiryTime = 120; // Redis 缓存过期时间(秒) + + AreaService() { + // 从Redis恢复体验中的设备 + _recoverExperiences(); + // 启动离线检测定时器 + _startOfflineCheckTimer(); + } + + // 从Redis恢复体验中的设备 + Future _recoverExperiences() async { + try { + // 使用keys方法获取所有体验中的设备 + final keys = await edm.EasyDartModule.redis.keys("experience_*"); + + for (var key in keys) { + try { + final experienceData = await edm.EasyDartModule.redis.get(key); + if (experienceData != null) { + final data = jsonDecode(experienceData); + final mac = data['mac']; + final openId = data['openId']; + final startTime = data['startTime']; + final now = DateTime.now().millisecondsSinceEpoch; + + // 如果体验时间超过20分钟,结束体验 + if (now - startTime > totalTimeout) { + await updateDeviceConnectStatus( + ReportStatus.reportExceptionClose.value, mac, + remark: "超时自动结束"); + await _callRemoteEndExperience(mac, openId, "超时自动结束", + ReportStatus.reportExceptionClose.value); + await edm.EasyDartModule.redis.delete(key); + } else { + // 恢复设备体验状态 + deviceStartTimeMap[mac] = startTime; + deviceUserMap[mac] = openId; + + // 恢复用户信息 + final userInfoKey = "user_info_$mac"; + final userInfoData = + await edm.EasyDartModule.redis.get(userInfoKey); + if (userInfoData != null) { + userInfoMap[mac] = jsonDecode(userInfoData); + } + + // 恢复初始数据处理状态 + _initialDataProcessed[mac] = false; + + // 初始化心率序列缓存 + _heartRateSequenceCache[mac] = []; + _inStraightLineMode[mac] = false; + + // 初始化报告状态 + _reportGeneratingMap[mac] = false; + _reportGeneratedMap[mac] = false; + + // 启动设备超时定时器 + _startDeviceTimeoutTimer(mac); + + // 恢复进度定时器 + _startProgressTimer(mac); + + print("从Redis恢复设备体验: $mac, openId: $openId"); + } + } + } catch (e) { + print("恢复设备体验数据失败: $e"); + } + } + } catch (e) { + print("从Redis恢复体验失败: $e"); + } + } + + // 保存体验信息到Redis + Future _saveExperienceToRedis(String mac, Map userInfo, + String openId, int startTime) async { + try { + final key = "experience_$mac"; + final data = { + 'mac': mac, + 'openId': openId, + 'startTime': startTime, + 'saveTime': DateTime.now().millisecondsSinceEpoch, + }; + + // 保存体验信息 + await edm.EasyDartModule.redis.set(key, jsonEncode(data)); + + // 保存用户信息 + final userInfoKey = "user_info_$mac"; + await edm.EasyDartModule.redis.set(userInfoKey, jsonEncode(userInfo)); + + print("保存体验信息到Redis: $mac, openId: $openId"); + } catch (e) { + print("保存体验信息到Redis失败: $e"); + } + } + + // 从Redis删除体验信息 + Future _removeExperienceFromRedis(String mac) async { + try { + await edm.EasyDartModule.redis.delete("experience_$mac"); + await edm.EasyDartModule.redis.delete("user_info_$mac"); + print("从Redis删除体验信息: $mac"); + } catch (e) { + print("从Redis删除体验信息失败: $e"); + } + } + + // 保存process为100的数据到Redis + Future _saveProcess100DataToRedis(String mac, String openId, + String reportId, Map data) async { + try { + final key = "report_${openId}_${mac}"; + final dataToSave = Map.from(data); + dataToSave['reportId'] = reportId; + + await edm.EasyDartModule.redis.setWithExpiry( + key, + jsonEncode(dataToSave), + _redisExpiryTime, + ); + + print("保存process为100的数据到Redis: key=$key, reportId=$reportId"); + } catch (e) { + print("保存process为100的数据到Redis失败: $e"); + } + } + + // 从Redis读取process为100的数据 + Future?> _getProcess100DataFromRedis( + String mac, String openId) async { + try { + final key = "report_${openId}_${mac}"; + final data = await edm.EasyDartModule.redis.get(key); + + if (data != null) { + print("从Redis读取process为100的数据: key=$key"); + return jsonDecode(data); + } + + return null; + } catch (e) { + print("从Redis读取process为100的数据失败: $e"); + return null; + } + } + + // 启动设备超时定时器 + void _startDeviceTimeoutTimer(String mac) { + // 先取消现有的定时器 + _stopDeviceTimeoutTimer(mac); + + // 启动新的定时器 + deviceTimers[mac] = Timer(Duration(milliseconds: totalTimeout), () { + _handleDeviceTimeout(mac); + }); + } + + // 停止设备超时定时器 + void _stopDeviceTimeoutTimer(String mac) { + if (deviceTimers.containsKey(mac) && deviceTimers[mac] != null) { + deviceTimers[mac]!.cancel(); + deviceTimers[mac] = null; + } + } + + // 处理设备超时 + void _handleDeviceTimeout(String mac) async { + final openId = deviceUserMap[mac]; + if (openId != null) { + print("设备超时: $mac, openId: $openId"); + await updateDeviceConnectStatus( + ReportStatus.reportExceptionClose.value, mac, + remark: "体验超时"); + await _endExperience( + mac, openId, "体验超时", ReportStatus.reportExceptionClose.value); + } + } + + // 启动进度更新定时器 + void _startProgressTimer(String mac) { + // 先取消现有的定时器 + _stopProgressTimer(mac); + + // 每秒更新一次进度 + _progressTimers[mac] = Timer.periodic(Duration(seconds: 1), (timer) { + _updateProgress(mac); + }); + + _lastProgressTime[mac] = DateTime.now().millisecondsSinceEpoch; + } + + // 停止进度更新定时器 + void _stopProgressTimer(String mac) { + if (_progressTimers.containsKey(mac) && _progressTimers[mac] != null) { + _progressTimers[mac]!.cancel(); + _progressTimers[mac] = null; + } + _lastProgressTime.remove(mac); + } + + // 更新进度 + void _updateProgress(String mac) { + try { + // 如果设备不在体验中,停止定时器 + if (!checkUsing(mac)) { + _stopProgressTimer(mac); + return; + } + + final startTime = deviceStartTimeMap[mac]; + if (startTime == null) return; + + final now = DateTime.now().millisecondsSinceEpoch; + final duration = now - startTime; + + // 计算基于时间的进度(20分钟 = 1200秒) + int timeBasedProgress = (duration / (20 * 60 * 1000) * 100).toInt(); + + // 计算基于数据的进度 + final processedCount = processedDataCache[mac]?.length ?? 0; + int dataBasedProgress = (processedCount / dataLength * 100).toInt(); + + // 综合进度策略: + // 1. 前期(前2分钟)以时间进度为主 + // 2. 中期(2-5分钟)时间和数据进度结合 + // 3. 后期(5分钟后)以数据进度为主 + + int finalProgress; + + if (duration < 2 * 60 * 1000) { + // 前2分钟 + // 80%时间进度 + 20%数据进度 + finalProgress = + (timeBasedProgress * 0.8 + dataBasedProgress * 0.2).toInt(); + } else if (duration < 5 * 60 * 1000) { + // 2-5分钟 + // 50%时间进度 + 50%数据进度 + finalProgress = + (timeBasedProgress * 0.5 + dataBasedProgress * 0.5).toInt(); + } else { + // 5分钟后 + // 20%时间进度 + 80%数据进度 + finalProgress = + (timeBasedProgress * 0.2 + dataBasedProgress * 0.8).toInt(); + } + + // 确保进度不会减少(用户体验角度) + final int currentProgress = macProcess[mac] ?? 0; + if (finalProgress > currentProgress) { + macProcess[mac] = finalProgress.clamp(0, 100); + } else if (duration > 30 * 1000) { + // 30秒后允许轻微下降,避免卡住 + // 如果有数据但进度不增长,缓慢增加时间进度 + if (processedCount > 0 && currentProgress < 10) { + macProcess[mac] = (currentProgress + 1).clamp(0, 100); + } + } + + // 如果报告已生成或正在生成,进度设为100% + if ((_reportGeneratingMap[mac] ?? false) || + (_reportGeneratedMap[mac] ?? false)) { + macProcess[mac] = 100; + } + + // 记录最后更新时间 + _lastProgressTime[mac] = now; + } catch (e) { + print("更新进度异常: $e, MAC=$mac"); + } + } + + // 析构函数,清理定时器 + void dispose() { + _stopOfflineCheckTimer(); + + // 清理所有设备定时器 + deviceTimers.forEach((mac, timer) { + if (timer != null) { + timer.cancel(); + } + }); + deviceTimers.clear(); + + // 清理所有进度定时器 + _progressTimers.forEach((mac, timer) { + if (timer != null) { + timer.cancel(); + } + }); + _progressTimers.clear(); + + // 清理心率序列缓存 + _heartRateSequenceCache.clear(); + _inStraightLineMode.clear(); + _lastStraightLineStart.clear(); + + // 清理报告状态 + _reportGeneratingMap.clear(); + _reportGeneratedMap.clear(); + } + + // 开始离线检测定时器 + void _startOfflineCheckTimer() { + if (_isTimerRunning) return; + + _isTimerRunning = true; + _offlineCheckTimer = Timer.periodic(Duration(seconds: 1), (timer) { + _checkDeviceOfflineStatus(); + }); + + edm.EasyDartModule.logger.info("离线检测定时器已启动"); + } + + // 停止离线检测定时器 + void _stopOfflineCheckTimer() { + if (_offlineCheckTimer != null) { + _offlineCheckTimer!.cancel(); + _offlineCheckTimer = null; + } + _isTimerRunning = false; + edm.EasyDartModule.logger.info("离线检测定时器已停止"); + } + + // 检查设备离线状态 + void _checkDeviceOfflineStatus() { + try { + final now = DateTime.now().millisecondsSinceEpoch; + + // 检查无数据超时 + lastValidDataTime.forEach((mac, lastTime) { + if (now - lastTime > noDataTimeout) { + print("设备无数据超时: $mac"); + _handleNoDataTimeout(mac); + } + }); + + // 检查离床状态超时 + lastBedStatusTime.forEach((mac, offBedTime) { + if (now - offBedTime > bedOffTimeout) { + print("设备离床超时: $mac"); + _handleBedOffTimeout(mac); + } + }); + } catch (e) { + print("检测离线异常: $e"); + } + } + + // 处理无数据超时 + void _handleNoDataTimeout(String mac) async { + final openId = deviceUserMap[mac]; + if (openId != null) { + await updateDeviceConnectStatus( + ReportStatus.reportExceptionClose.value, mac, + remark: "无数据超时"); + await _endExperience( + mac, openId, "无数据超时", ReportStatus.reportExceptionClose.value); + } + } + + // 处理离床超时 + void _handleBedOffTimeout(String mac) async { + final openId = deviceUserMap[mac]; + if (openId != null) { + await updateDeviceConnectStatus( + ReportStatus.reportExceptionClose.value, mac, + remark: "离床超时"); + await _endExperience( + mac, openId, "离床超时", ReportStatus.reportExceptionClose.value); + } + } + + // 开始快检体验 + Future> startKuaijian(Map data) async { + String msg = ""; + int flag = 1; + + try { + String mac = _normalizeMac(data['mac']); + String openId = data['openId']?.toString() ?? ''; + + if (openId.isEmpty) { + return {"msg": "openId不能为空", "flag": 0}; + } + + bool haveRun = await checkHaveRun(data); + if (haveRun) { + print( + "[调试][${DateTime.now().toIso8601String()}]: 已经在运行,跳过 ${data['mac']}"); + msg = "该设备正在体验中"; + flag = 0; + return {"msg": msg, "flag": flag}; + } + + // 检查该mac是否正在体验中 + bool using = checkUsing(mac); + if (using) { + msg = "该设备正在体验中"; + flag = 0; + return {"msg": msg, "flag": flag}; + } + + bool state = await checkDeviceState(mac); + if (!state) { + msg = "设备离线"; + flag = 0; + return {"msg": msg, "flag": flag}; + } + + // 提取并处理用户信息(设置默认值) + final userInfo = _processUserInfo(data); + + // 2. 记录开始体验时间 + final startTime = DateTime.now().millisecondsSinceEpoch; + deviceStartTimeMap[mac] = startTime; + deviceUserMap[mac] = openId; + userInfoMap[mac] = userInfo; + lastValidDataTime[mac] = startTime; // 初始化最后有效数据时间 + _initialDataProcessed[mac] = false; // 初始化初始数据处理标志 + + // 3. 初始化心率序列相关缓存 + _heartRateSequenceCache[mac] = []; + _inStraightLineMode[mac] = false; + + // 4. 初始化报告状态 + _reportGeneratingMap[mac] = false; + _reportGeneratedMap[mac] = false; + + // 5. 保存到Redis + await _saveExperienceToRedis(mac, userInfo, openId, startTime); + + // 6. 启动设备超时定时器 + _startDeviceTimeoutTimer(mac); + + // 7. 启动进度定时器 + _startProgressTimer(mac); + + edm.EasyDartModule.logger + .info("记录设备开始体验时间: $mac, openId: $openId, 时间: $startTime"); + + // 8. 调用服务号后端通知开始体验 + await rpcStartKuaijian(data); + + // 9. 开始记录实时数据 + startGetBodyData(data); + + //10.更新远程api + await rpcStart(data); + } catch (e) { + print("申请体验报告失败: $e"); + return {"msg": "系统异常", "flag": 0}; + } + + return {"msg": "开始体验成功", "flag": flag}; + } + + // 处理用户信息,设置默认值 + Map _processUserInfo(Map data) { + // 设置默认值 + final defaultValues = { + 'username': '体验用户', + 'age': 30, + 'height': 170, + 'weight': 60, + 'gender': 1, // 1:男, 2:女 + 'phoneNo': '未知', + 'deviceNo': data['mac'] ?? '', + }; + + // 处理用户信息,空值或无效值使用默认值 + final userInfo = { + 'username': + _getValueOrDefault(data['username'], defaultValues['username']), + 'age': _getIntValueOrDefault(data['age'], defaultValues['age']), + 'height': _getIntValueOrDefault(data['height'], defaultValues['height']), + 'weight': _getIntValueOrDefault(data['weight'], defaultValues['weight']), + 'gender': _getIntValueOrDefault(data['gender'], defaultValues['gender']), + 'phoneNo': _getValueOrDefault(data['phoneNo'], defaultValues['phoneNo']), + 'deviceNo': _getValueOrDefault( + data['deviceNo'] ?? data['mac'], defaultValues['deviceNo']), + }; + + // 验证年龄、身高、体重范围 - 修复类型转换问题 + userInfo['age'] = _validateRange( + userInfo['age'] as int, 1, 120, defaultValues['age'] as int); + + userInfo['height'] = _validateRange( + userInfo['height'] as int, 50, 250, defaultValues['height'] as int); + + userInfo['weight'] = _validateRange( + userInfo['weight'] as int, 10, 300, defaultValues['weight'] as int); + + userInfo['gender'] = _validateRange( + userInfo['gender'] as int, 1, 2, defaultValues['gender'] as int); + + print("处理后的用户信息: $userInfo"); + return userInfo; + } + + // 获取字符串值或默认值 + String _getValueOrDefault(dynamic value, String defaultValue) { + if (value == null) return defaultValue; + + final strValue = value.toString().trim(); + if (strValue.isEmpty) return defaultValue; + + return strValue; + } + + // 获取整数值或默认值 + int _getIntValueOrDefault(dynamic value, int defaultValue) { + if (value == null) return defaultValue; + + try { + if (value is String) { + final trimmed = value.trim(); + if (trimmed.isEmpty) return defaultValue; + return int.tryParse(trimmed) ?? defaultValue; + } else if (value is int) { + return value; + } else if (value is double) { + return value.toInt(); + } else if (value is num) { + return value.toInt(); + } + } catch (e) { + print("转换整数值失败: $value, $e"); + } + + return defaultValue; + } + + // 验证数值范围 + int _validateRange(int value, int min, int max, int defaultValue) { + if (value >= min && value <= max) { + return value; + } + return defaultValue; + } + + // 结束快检体验 + Future> endKuaijian(Map data) async { + String msg = ""; + int flag = 1; + + try { + String mac = _normalizeMac(data['mac']); + String openId = data['openId']?.toString() ?? ''; + + if (openId.isEmpty) { + return {"msg": "openId不能为空", "flag": 0}; + } + + // 检查该设备是否在体验中 + if (!checkUsing(mac)) { + return {"msg": "该设备未在体验中", "flag": 0}; + } + + // 检查是否是同一个用户 + if (deviceUserMap[mac] != openId) { + return {"msg": "无权结束该设备的体验", "flag": 0}; + } + + // 检查是否已经在生成报告 + if (_reportGeneratingMap[mac] ?? false) { + return {"msg": "报告正在生成中,请稍候", "flag": 0}; + } + + // 检查是否已经生成报告 + if (_reportGeneratedMap[mac] ?? false) { + return {"msg": "报告已生成,请查看结果", "flag": 0}; + } + + // 获取当前有效数据量 + final processedCount = processedDataCache[mac]?.length ?? 0; + + if (processedCount >= dataLength) { + // 正常完成体验,生成报告 + final reportId = await _requestSleepAnalytics(mac, openId); + if (reportId != null) { + msg = "体验完成,报告ID: $reportId"; + await _callRemoteCompleteExperience( + mac, openId, "正常完成", reportId, ReportStatus.completed.value); + } else { + msg = "体验完成,但生成报告失败"; + await updateDeviceConnectStatus( + ReportStatus.reportExceptionClose.value, mac, + remark: "报告生成失败"); + await _endExperience( + mac, openId, "报告生成失败", ReportStatus.reportExceptionClose.value); + } + } else { + // 提前结束体验 + await updateDeviceConnectStatus(ReportStatus.appNormalClose.value, mac, + remark: "用户主动结束"); + await _endExperience( + mac, openId, "用户主动结束", ReportStatus.appNormalClose.value); + msg = "体验已提前结束"; + } + } catch (e) { + print("结束体验失败: $e"); + return {"msg": "系统异常", "flag": 0}; + } + + return {"msg": msg, "flag": flag}; + } + + // 结束体验的通用方法 + Future _endExperience( + String mac, String openId, String reason, int reportStatus, + {bool rpc = true}) async { + try { + print("结束体验: MAC=$mac, openId=$openId, 原因=$reason"); + + // 1. 调用远程结束接口 + if (rpc) { + await _callRemoteEndExperience(mac, openId, reason, reportStatus); + } + + // 2. 清理本地数据 + deviceStartTimeMap.remove(mac); + deviceUserMap.remove(mac); + userInfoMap.remove(mac); + bodyDataCache.remove(mac); + processedDataCache.remove(mac); + macProcess.remove(mac); + lastValidDataTime.remove(mac); + lastBedStatusTime.remove(mac); + _initialDataProcessed.remove(mac); + + // 3. 清理心率序列相关缓存 + _heartRateSequenceCache.remove(mac); + _inStraightLineMode.remove(mac); + _lastStraightLineStart.remove(mac); + + // 4. 清理报告状态 + _reportGeneratingMap.remove(mac); + _reportGeneratedMap.remove(mac); + + // 5. 停止定时器 + _stopDeviceTimeoutTimer(mac); + _stopProgressTimer(mac); + + // 6. 从Redis删除 + await _removeExperienceFromRedis(mac); + + // 7. 停止监听设备数据 + _stopListeningDeviceData(mac); + + // 8. 通知前端 + _notifyExperienceEnd(mac, openId, reason); + + edm.EasyDartModule.logger.info("体验已结束: $mac, 原因: $reason"); + } catch (e) { + edm.EasyDartModule.logger.error("结束体验异常: $e, MAC=$mac"); + } + } + + // 请求睡眠分析报告 + Future _requestSleepAnalytics(String mac, String openId) async { + try { + // 检查是否已经在生成报告 + if (_reportGeneratingMap[mac] ?? false) { + print("报告已经在生成中,跳过重复请求: $mac"); + return null; + } + + // 检查是否已经生成报告 + if (_reportGeneratedMap[mac] ?? false) { + print("报告已经生成,跳过重复请求: $mac"); + return null; + } + + final userInfo = userInfoMap[mac]; + final processedData = processedDataCache[mac]; + + if (userInfo == null || + processedData == null || + processedData.length < dataLength) { + print("请求报告失败: 数据不足或用户信息缺失"); + await updateDeviceConnectStatus( + ReportStatus.reportExceptionClose.value, mac, + remark: "数据不足或用户信息缺失"); + return null; + } + + // 设置报告正在生成中 + _reportGeneratingMap[mac] = true; + print("开始生成报告: $mac, openId: $openId, 数据量: ${processedData.length}"); + + // 准备请求数据 + final Map requestData = { + "username": userInfo['username'], + "age": userInfo['age'], + "height": userInfo['height'], + "weight": userInfo['weight'], + "gender": userInfo['gender'], + "deviceNo": userInfo['deviceNo'], + "phoneNo": userInfo['phoneNo'], + "dataList": processedData, + }; + + print( + "用户信息: ${userInfo['username']}, 年龄: ${userInfo['age']}, 电话: ${userInfo['phoneNo']}"); + + // 发送HTTP请求 + final reportId = await _sendReportRequest(requestData, mac, openId); + + // 报告生成完成 + _reportGeneratingMap[mac] = false; + + if (reportId != null) { + _reportGeneratedMap[mac] = true; + print("报告生成成功: $reportId"); + return reportId; + } else { + print("报告生成失败"); + await updateDeviceConnectStatus( + ReportStatus.reportExceptionClose.value, mac, + remark: "报告生成失败"); + return null; + } + } catch (e) { + print("请求睡眠分析异常: $e"); + _reportGeneratingMap[mac] = false; + await updateDeviceConnectStatus( + ReportStatus.reportExceptionClose.value, mac, + remark: "请求睡眠分析异常: $e"); + return null; + } + } + + // 发送报告请求 + Future _sendReportRequest( + Map data, String mac, String openId) async { + try { + // 处理 dataList 的数据转换 + if (data['dataList'] != null && data['dataList'] is List) { + List> originalList = + List>.from(data['dataList']); + + // 将原始数据转换为新的格式 + List> transformedList = originalList.map((item) { + // 从原始数据中提取 heartRate 和 breathRate + // 如果字段不存在或为null,则使用默认值0 + int heartRate = item['heartRate'] is int + ? item['heartRate'] + : (item['heartRate'] is double + ? (item['heartRate'] as double).toInt() + : 0); + + int breathRate = item['breathRate'] is int + ? item['breathRate'] + : (item['breathRate'] is double + ? (item['breathRate'] as double).toInt() + : 0); + + // 创建新的数据结构 + return { + 'breath': breathRate, + 'heart': heartRate, + }; + }).toList(); + + // 替换原始 dataList 为转换后的数据 + data['dataList'] = transformedList; + } + + // 打印转换后的数据用于调试 + print('转换后的数据: ${jsonEncode(data)}'); + + await requestSleepAnalytics(data, mac, openId); + return null; // 由于是异步调用,这里返回null,实际结果在回调中处理 + } catch (e) { + print("发送报告请求异常: $e"); + await updateDeviceConnectStatus( + ReportStatus.reportExceptionClose.value, mac, + remark: "发送报告请求异常: $e"); + return null; + } + } + + // 调用远程完成接口 + Future _callRemoteCompleteExperience(String mac, String openId, + String reason, String reportId, int reportStatus) async { + try { + // 调用您的远程完成接口 + print("调用远程完成接口: $mac, openId: $openId, 原因: $reason, 报告ID: $reportId"); + // 结束体验 + await _endExperience( + mac, openId, "$reason, 报告ID: $reportId", reportStatus); + } catch (e) { + print("调用远程完成接口失败: $e"); + await updateDeviceConnectStatus( + ReportStatus.reportExceptionClose.value, mac, + remark: "调用远程完成接口失败: $e"); + } + } + + // 调用远程结束接口 + Future _callRemoteEndExperience( + String mac, String openId, String reason, int reportStatus) async { + try { + // 调用您的远程完成接口 + print("调用远程结束接口: $mac, openId: $openId, 原因: $reason"); + // TODO: 实现具体的远程调用 + await updateDeviceConnectStatus(reportStatus, mac, remark: reason); + } catch (e) { + print("调用远程结束接口失败: $e"); + } + } + + // 通知体验结束 + void _notifyExperienceEnd(String mac, String openId, String reason) { + try { + edm.EasyDartModule.websocket.sendData(jsonEncode({ + "type": "experience_end", + "mac": mac, + "openId": openId, + "reason": reason, + "timestamp": DateTime.now().millisecondsSinceEpoch, + "message": "体验已结束: $reason" + })); + } catch (e) { + print("发送体验结束通知失败: $e"); + } + } + + // 检查是否体验中 + bool checkUsing(String mac) { + String normalizedMac = _normalizeMac(mac); + return deviceStartTimeMap.containsKey(normalizedMac); + } + + // 远程通知分析开始 + Future rpcStartKuaijian(data) async { + // TODO: 实现远程开始接口 + } + + // 开始获取实时数据 + void startGetBodyData(data) { + try { + String mac = _normalizeMac(data['mac']); + data['mac'] = mac; // 统一格式 + + // 监听 WebSocket 实时数据 + CommonVariables.callMap["/vsbs/web/rt/marttress"] = (receivedData) { + _handleWebSocketData(receivedData); + }; + + print("开始监听体征数据"); + edm.EasyDartModule.websocket.sendData(jsonEncode(WebSocketMessage( + path: "/vsbs/web/rt/marttress", type: 1, data: {"mac": mac}))); + } catch (e) { + edm.EasyDartModule.logger.error("[websocket]获取体征数据异常: $e"); + } + } + + // 处理WebSocket数据 + Future _handleWebSocketData(dynamic receivedData) async { + try { + print("当前心率为: ${receivedData['heartRate']}"); + print("当前有效数据为: ${processedDataCache['${receivedData['mac']}']?.length}"); + if (receivedData is! Map) return; + + // 将Map转换为Map + final Map data = {}; + receivedData.forEach((key, value) { + data[key.toString()] = value; + }); + + // 为数据添加时间戳 + data['timestamp'] = DateTime.now().millisecondsSinceEpoch; + + // 统一mac格式 + if (data.containsKey('mac')) { + String mac = _normalizeMac(data['mac']); + data['mac'] = mac; + + // 检查设备是否在体验中 + if (!checkUsing(mac)) { + return; // 不在体验中的设备数据直接忽略 + } + + // 检查是否已经生成报告,如果已经生成则不再处理数据 + if (_reportGeneratedMap[mac] ?? false) { + print("报告已生成,不再处理数据: $mac"); + return; + } + + // 更新最后有效数据时间 + lastValidDataTime[mac] = data['timestamp']; + + // 处理离床状态 + _handleBedStatus(mac, data); + + // 处理离线状态 + if (data['status'] == "离线") { + final openId = deviceUserMap[mac]; + if (openId != null) { + await updateDeviceConnectStatus( + ReportStatus.reportExceptionClose.value, mac, + remark: "设备离线"); + _endExperience( + mac, openId, "设备离线", ReportStatus.reportExceptionClose.value); + } + return; + } + + // 存储原始数据 + storeInstantData(data); + + // 处理数据(包含心率直线检测) + _processDataWithHeartRateDetection(mac, data); + + edm.EasyDartModule.logger.info("[websocket]实时体征数据-->$data"); + } + } catch (e) { + print("处理WebSocket数据异常: $e"); + } + } + + // 处理离床状态 + void _handleBedStatus(String mac, Map data) { + if (data["inBed"] == "离床") { + // 记录离床开始时间 + if (!lastBedStatusTime.containsKey(mac)) { + lastBedStatusTime[mac] = data['timestamp']; + } + } else { + // 清除离床计时 + lastBedStatusTime.remove(mac); + } + } + + // 存储原始实时数据 + void storeInstantData(Map data) { + try { + String mac = data['mac']; + + // 如果不存在该 mac,则先创建一个空 list + bodyDataCache.putIfAbsent(mac, () => []); + + // 往对应的 list 中添加数据 + bodyDataCache[mac]!.add(Map.from(data)); + + // 限制数据长度(保留足够的数据用于处理) + if (bodyDataCache[mac]!.length > dataLength * 2) { + bodyDataCache[mac]!.removeAt(0); + } + } catch (e) { + print("storeInstantData异常: $e"); + } + } + + Future _processDataWithHeartRateDetection( + String mac, Map data) async { + try { + // 检查是否已经生成报告,如果已经生成则不再处理数据 + if (_reportGeneratedMap[mac] ?? false) { + return; + } + + // 初始化处理数据缓存 + processedDataCache.putIfAbsent(mac, () => []); + _heartRateSequenceCache.putIfAbsent(mac, () => []); + + final processedList = processedDataCache[mac]!; + final sequenceCache = _heartRateSequenceCache[mac]!; + + // 检查数据有效性 + if (data['heartRate'] == -1 || + data['heartRate'] == 0 || + data['breathRate'] == -1 || + data['breathRate'] == 0 || + data['bodyMotion'] != 0 || + data['inBed'] != '在床') { + // 无效数据,重置序列 + if (sequenceCache.isNotEmpty) { + sequenceCache.clear(); + } + return; + } + + // 获取当前心率 + int currentHeartRate = data['heartRate'] is int + ? data['heartRate'] + : (data['heartRate'] is double + ? (data['heartRate'] as double).toInt() + : 0); + + // === 修正的核心逻辑 === + + // 如果序列为空或当前心率与序列最后心率相同 + if (sequenceCache.isEmpty || + (sequenceCache.isNotEmpty && + sequenceCache.last['heartRate'] == currentHeartRate)) { + // 添加到连续相同心率序列 + sequenceCache.add({ + 'heartRate': currentHeartRate, + 'data': data, + 'timestamp': data['timestamp'], + }); + } else { + // 心率发生变化 - 处理之前的序列 + _processHeartRateSequence(mac, sequenceCache, processedList); + + // 清空序列,开始新的序列 + sequenceCache.clear(); + sequenceCache.add({ + 'heartRate': currentHeartRate, + 'data': data, + 'timestamp': data['timestamp'], + }); + } + + // === 修正的核心逻辑结束 === + + // 处理初始数据(只执行一次) + if (processedList.length == initialDataLength && + !_initialDataProcessed[mac]!) { + print("开始处理初始数据,数据量: ${processedList.length}"); + _processInitialData(mac); + _initialDataProcessed[mac] = true; + } + + // 检查是否达到目标数据量 - 修改为只触发一次 + if (processedList.length >= dataLength && + !(_reportGeneratingMap[mac] ?? false) && + !(_reportGeneratedMap[mac] ?? false)) { + final openId = deviceUserMap[mac]; + if (openId != null) { + print("达到目标数据量,开始生成报告: $mac, 数据量: ${processedList.length}"); + + // 异步生成报告,避免阻塞数据处理 + Future.delayed(Duration.zero, () { + _requestSleepAnalytics(mac, openId).then((reportId) { + if (reportId != null) { + _callRemoteCompleteExperience(mac, openId, "数据采集完成", reportId, + ReportStatus.completed.value); + } else { + // 报告生成失败,继续收集数据 + print("报告生成失败,继续收集数据: $mac"); + } + }); + }); + } + } + print("当前有效数据为: ${processedDataCache['$mac']?.length}"); + } catch (e) { + print("处理数据异常: $e, MAC=$mac"); + // 处理数据异常时更新状态 + if (checkUsing(mac)) { + await updateDeviceConnectStatus( + ReportStatus.reportExceptionClose.value, mac, + remark: "处理数据异常: $e"); + } + } + } + +// 新增:处理心率序列的辅助方法 + void _processHeartRateSequence( + String mac, + List> sequenceCache, + List> processedList) { + if (sequenceCache.isEmpty) return; + + if (sequenceCache.length >= heartStillTime) { + // 连续相同心率达到或超过10次 - 只保留第一个和最后一个 + print("连续相同心率达到${sequenceCache.length}次(>=${heartStillTime}),进行去重处理"); + + // 第一个数据点 + final firstData = sequenceCache.first['data']; + final firstProcessedData = { + 'mac': mac, + 'heartRate': firstData['heartRate'], + 'breathRate': firstData['breathRate'], + 'timestamp': firstData['timestamp'], + 'bodyMotion': firstData['bodyMotion'], + }; + + // 检查是否重复(与上一个处理的数据比较) + if (processedList.isEmpty || + processedList.last['heartRate'] != firstProcessedData['heartRate'] || + processedList.last['breathRate'] != + firstProcessedData['breathRate']) { + processedList.add(firstProcessedData); + print("添加直线开始数据点: 心率 ${firstProcessedData['heartRate']}"); + } + + // 最后一个数据点 + final lastData = sequenceCache.last['data']; + final lastProcessedData = { + 'mac': mac, + 'heartRate': lastData['heartRate'], + 'breathRate': lastData['breathRate'], + 'timestamp': lastData['timestamp'], + 'bodyMotion': lastData['bodyMotion'], + }; + + // 检查是否重复(与上一个处理的数据比较) + if (processedList.isEmpty || + processedList.last['heartRate'] != lastProcessedData['heartRate'] || + processedList.last['breathRate'] != lastProcessedData['breathRate']) { + processedList.add(lastProcessedData); + print("添加直线结束数据点: 心率 ${lastProcessedData['heartRate']}"); + } + } else { + // 连续相同心率少于10次 - 全部保留 + print("连续相同心率${sequenceCache.length}次(<${heartStillTime}),全部保留"); + + for (var seqData in sequenceCache) { + final processedData = { + 'mac': mac, + 'heartRate': seqData['data']['heartRate'], + 'breathRate': seqData['data']['breathRate'], + 'timestamp': seqData['data']['timestamp'], + 'bodyMotion': seqData['data']['bodyMotion'], + }; + + // 检查是否重复(与上一个处理的数据比较) + // 这里注意:对于连续相同的数据,我们不应该去重,所以去掉这个检查 + processedList.add(processedData); + } + } + } + + // 处理初始数据(前3分钟) + void _processInitialData(String mac) async { + try { + final processedList = processedDataCache[mac]!; + + // 1. 检查数据量是否足够 + if (processedList.length < initialDataLength ~/ 2) { + // 数据量少于一半,结束体验 + final openId = deviceUserMap[mac]; + if (openId != null) { + print("初始数据不足,结束体验: $mac, 数据量: ${processedList.length}"); + await updateDeviceConnectStatus( + ReportStatus.reportExceptionClose.value, mac, + remark: "初始数据不足"); + _endExperience( + mac, openId, "初始数据不足", ReportStatus.reportExceptionClose.value); + } + return; + } + + // 2. 计算平均心率 + int totalHeartRate = 0; + for (var data in processedList) { + final heartRate = data['heartRate']; + if (heartRate is int) { + totalHeartRate += heartRate; + } else if (heartRate is num) { + totalHeartRate += heartRate.toInt(); + } else if (heartRate is String) { + totalHeartRate += int.tryParse(heartRate) ?? 0; + } + } + + double avgHeartRate = totalHeartRate / processedList.length; + + // 3. 计算在平均值±5范围内的数据百分比 + int inRangeCount = 0; + for (var data in processedList) { + final heartRate = data['heartRate']; + double? hrValue; + + if (heartRate is int) { + hrValue = heartRate.toDouble(); + } else if (heartRate is num) { + hrValue = heartRate.toDouble(); + } else if (heartRate is String) { + hrValue = double.tryParse(heartRate); + } + + if (hrValue != null && + hrValue >= avgHeartRate - standardThreshold && + hrValue <= avgHeartRate + standardThreshold) { + inRangeCount++; + } + } + + double inRangePercent = (inRangeCount / processedList.length) * 100; + + // 4. 如果小于阈值,结束体验 + if (inRangePercent < totalHeartPercent) { + final openId = deviceUserMap[mac]; + if (openId != null) { + print( + "心率数据不稳定,结束体验: $mac, 平均心率: $avgHeartRate, 在范围比例: $inRangePercent%"); + await updateDeviceConnectStatus( + ReportStatus.reportExceptionClose.value, mac, + remark: "心率数据不稳定"); + _endExperience( + mac, openId, "心率数据不稳定", ReportStatus.reportExceptionClose.value); + } + return; + } + + print("初始数据处理通过: $mac, 平均心率: $avgHeartRate, 在范围比例: $inRangePercent%"); + } catch (e) { + print("处理初始数据异常: $e, MAC=$mac"); + // 处理初始数据异常时更新状态 + if (checkUsing(mac)) { + await updateDeviceConnectStatus( + ReportStatus.reportExceptionClose.value, mac, + remark: "处理初始数据异常: $e"); + } + } + } + + // 获取实时数据 - 修改后的版本 + Future> getInstantData(String mac, String openId) async { + String normalizedMac = _normalizeMac(mac); + String msg = ""; + int flag = 1; + var data; + + // 检查设备是否在体验中 + if (!deviceStartTimeMap.containsKey(normalizedMac)) { + flag = -1; + msg = "该设备未开始体验"; + data = null; + final redisData = + await _getProcess100DataFromRedis(normalizedMac, openId); + if (redisData != null) { + data = redisData; + flag = 1; + msg = "从Redis读取数据成功"; + } else { + flag = 0; + msg = "该设备暂无数据"; + data = null; + } + } + // 检查用户是否匹配 + else if (deviceUserMap[normalizedMac] != openId) { + flag = -2; + msg = "无权查看该设备数据"; + data = null; + } + // 检查是否有缓存数据 + else if (!bodyDataCache.containsKey(normalizedMac) || + bodyDataCache[normalizedMac]!.isEmpty) { + // 如果没有本地缓存数据,尝试从Redis读取 + final redisData = + await _getProcess100DataFromRedis(normalizedMac, openId); + if (redisData != null) { + data = redisData; + flag = 1; + msg = "从Redis读取数据成功"; + } else { + flag = 0; + msg = "该设备暂无数据"; + data = null; + } + } else { + // 取最新一次数据 + data = Map.from(bodyDataCache[normalizedMac]!.last); + + // 添加进度信息 + data['process'] = macProcess[normalizedMac] ?? 0; + data['openId'] = openId; + + // 添加体验时长 + final startTime = deviceStartTimeMap[normalizedMac]!; + final duration = DateTime.now().millisecondsSinceEpoch - startTime; + data['experienceDuration'] = duration ~/ 1000; // 转换为秒 + + // 添加有效数据量 + final processedCount = processedDataCache[normalizedMac]?.length ?? 0; + data['processedDataCount'] = processedCount; + data['targetDataCount'] = dataLength; + + // 添加报告状态 + data['reportGenerating'] = _reportGeneratingMap[normalizedMac] ?? false; + data['reportGenerated'] = _reportGeneratedMap[normalizedMac] ?? false; + + // 添加用户信息(可选) + data['userInfo'] = userInfoMap[normalizedMac]; + + // 添加空的reportId字段 + data['reportId'] = ''; + } + + return {"msg": msg, "flag": flag, "data": data}; + } + + // 停止监听设备数据 + void _stopListeningDeviceData(String mac) { + try { + edm.EasyDartModule.websocket.sendData(jsonEncode( + WebSocketMessage(path: "/vsbs/web/rt/marttress", type: 2))); + } catch (e) { + print("停止监听设备数据失败: $e"); + } + } + + // 获取所有正在体验的设备列表 + List> getActiveDevices() { + return deviceStartTimeMap.entries.map((entry) { + final mac = entry.key; + return { + 'mac': mac, + 'openId': deviceUserMap[mac], + 'startTime': entry.value, + 'progress': macProcess[mac] ?? 0, + 'processedData': processedDataCache[mac]?.length ?? 0, + 'reportGenerating': _reportGeneratingMap[mac] ?? false, + 'reportGenerated': _reportGeneratedMap[mac] ?? false, + 'userInfo': userInfoMap[mac], + }; + }).toList(); + } + + // 获取设备体验时长 + int? getDeviceExperienceDuration(String mac) { + String normalizedMac = _normalizeMac(mac); + if (deviceStartTimeMap.containsKey(normalizedMac)) { + final now = DateTime.now().millisecondsSinceEpoch; + return now - deviceStartTimeMap[normalizedMac]!; + } + return null; + } + + // 统一mac地址格式 + String _normalizeMac(String mac) { + if (mac == null || mac.isEmpty) return ''; + + String normalized = + mac.toString().replaceAll(RegExp(r'[:-\s]'), '').toUpperCase().trim(); + + return normalized; + } + + // 调试方法:打印当前状态 + void printStatus() { + print("=== AreaService 状态 ==="); + print("正在体验的设备:"); + deviceStartTimeMap.forEach((mac, startTime) { + final openId = deviceUserMap[mac]; + final progress = macProcess[mac] ?? 0; + final processedCount = processedDataCache[mac]?.length ?? 0; + final reportGenerating = _reportGeneratingMap[mac] ?? false; + final reportGenerated = _reportGeneratedMap[mac] ?? false; + final userInfo = userInfoMap[mac]; + print(" $mac (用户: $openId) - 进度: $progress%, 有效数据: $processedCount"); + print(" 报告状态: 生成中=$reportGenerating, 已生成=$reportGenerated"); + print( + " 用户信息: ${userInfo?['username']}, 年龄: ${userInfo?['age']}, 电话: ${userInfo?['phoneNo']}"); + }); + print("======================"); + } + + checkHaveRun(data) async { + data['deviceNo'] = data['mac']; + String serviceAddress = ServiceConstant.service_address; + String serviceName = ServiceConstant.app_server_service; + String serviceApi = "/checkreport/${data['mac']}"; + String queryUrl = "${serviceAddress}${serviceName}${serviceApi}"; + bool flag = false; + await requestWithLog( + logTitle: "APP端提检查快检报告开始体验", + method: MyHttpMethod.get, + queryUrl: queryUrl, + data: data['data'], + onSuccess: (res) { + flag = res.data; + print("[调试][成功][${DateTime.now().toIso8601String()}]: 接收到数据结果为${flag}"); + }, + onFailure: (res) { + flag = true; + print("[调试][失败][${DateTime.now().toIso8601String()}]: 接收到数据结果为${flag}"); + }, + ); + return flag; + } + + Future rpcStart(Map data) async { + try { + String serviceAddress = ServiceConstant.service_address; + String serviceName = ServiceConstant.app_server_service; + String serviceApi = "/reportsubmit"; + String queryUrl = "${serviceAddress}${serviceName}${serviceApi}"; + data['openid'] = data['openId']; + data['status'] = ReportStatus.experienceing.value; + await requestWithLog( + logTitle: "APP端提交快检报告开始体验", + method: MyHttpMethod.post, + queryUrl: queryUrl, + data: data, + onSuccess: (res) { + print("通知体验开始成功"); + }, + onFailure: (res) { + print("提交快检报告开始体验失败"); + }, + ); + } catch (e) { + print("远程调用失败:$e"); + } + } + + Future requestSleepAnalytics( + Map data, String mac, String openId) async { + try { + String queryUrl = + "https://health.ciotcp.com/api/api/h5/getReportByOtherData"; + int retryCount = 0; + bool isSuccess = false; + String? reportId; + + while (retryCount < 3 && !isSuccess) { + await requestWithLog( + logTitle: "请求实时分析", + method: MyHttpMethod.post, + data: data, + queryUrl: queryUrl, + onSuccess: (res) async { + if (res.data == null || res.data == "") { + retryCount++; + if (retryCount < 3) { + print("请求失败,正在尝试第${retryCount}次重试..."); + } else { + print("请求失败,已尝试3次,停止重试"); + await updateDeviceConnectStatus( + ReportStatus.reportExceptionClose.value, mac, + remark: "报告请求失败"); + } + } else { + isSuccess = true; + reportId = res.data; + print("请求成功,报告ID: $reportId"); + print( + "报告地址: https://health.ciotcp.com/mobile/quickDetail?type=quickCheck&useFrom=Quansi&reportId=$reportId"); + + // 保存process为100的数据到Redis + if (bodyDataCache.containsKey(mac) && + bodyDataCache[mac]!.isNotEmpty) { + final lastData = bodyDataCache[mac]!.last; + final process100Data = Map.from(lastData); + process100Data['process'] = 100; // 确保process为100 + await _saveProcess100DataToRedis( + mac, openId, reportId!, process100Data); + } + + await finishDevice(reportId!, mac); + await _endExperience( + mac, openId, "体验结束", ReportStatus.reportExceptionClose.value, + rpc: false); + } + }, + onFailure: (res) async { + if (res.code == 20000 && res.data != null) { + // 请求成功,通常不应该进入这里,但为了确保 + isSuccess = true; + reportId = res.data; + print("请求成功,报告ID: $reportId"); + + // 保存process为100的数据到Redis + if (bodyDataCache.containsKey(mac) && + bodyDataCache[mac]!.isNotEmpty) { + final lastData = bodyDataCache[mac]!.last; + final process100Data = Map.from(lastData); + process100Data['process'] = 100; // 确保process为100 + await _saveProcess100DataToRedis( + mac, openId, reportId!, process100Data); + } + + await finishDevice(reportId!, mac); + } else { + // 请求失败,重新尝试 + retryCount++; + if (retryCount < 3) { + print("请求失败,正在尝试第${retryCount}次重试..."); + } else { + print("请求失败,已尝试3次,停止重试"); + await updateDeviceConnectStatus( + ReportStatus.reportExceptionClose.value, mac, + remark: "报告请求失败"); + } + } + }, + ); + } + if (!isSuccess) { + print("最终请求失败,无法获取报告数据"); + await updateDeviceConnectStatus( + ReportStatus.reportExceptionClose.value, mac, + remark: "最终请求失败,无法获取报告数据"); + } + } catch (e) { + print("[请求报告失败]:报告异常:$e"); + print("[微信]:报告异常:$e"); + await updateDeviceConnectStatus( + ReportStatus.reportExceptionClose.value, mac, + remark: "请求报告失败异常: $e"); + } + } + + Future finishDevice(String reportId, String mac) async { + try { + // 从 deviceUserMap 中获取对应的 openid + String? openid = deviceUserMap[mac]; + + if (openid == null) { + print("无法找到设备 $mac 对应的用户信息"); + await updateDeviceConnectStatus( + ReportStatus.reportExceptionClose.value, mac, + remark: "无法找到用户信息"); + return; + } + + String serviceAddress = ServiceConstant.service_address; + String serviceName = ServiceConstant.app_server_service; + String serviceApi = "/reportfinish"; + String queryUrl = "${serviceAddress}${serviceName}${serviceApi}"; + + // 从 userInfoMap 中获取 deviceNo 或使用 mac + final userInfo = userInfoMap[mac]; + String deviceNo = userInfo?['deviceNo'] ?? mac; + + Map finishData = { + "deviceNo": deviceNo, + "openid": openid, + "reportId": reportId, + }; + + print("发送报告完成请求: deviceNo=$deviceNo, openid=$openid, reportId=$reportId"); + + await requestWithLog( + logTitle: "更新完成状态", + method: MyHttpMethod.post, + data: finishData, + queryUrl: queryUrl, + onSuccess: (res) { + print("[微信]:报告完成成功 $finishData"); + }, + onFailure: (res) { + print("[微信]:报告完成失败 $finishData"); + // 报告完成失败时也要更新状态 + updateDeviceConnectStatus( + ReportStatus.reportExceptionClose.value, mac, + remark: "报告完成失败"); + }, + ); + } catch (e) { + print("发送报告完成请求异常: $e"); + await updateDeviceConnectStatus( + ReportStatus.reportExceptionClose.value, mac, + remark: "发送报告完成请求异常: $e"); + } + } + + //更新设备状态 + Future updateDeviceConnectStatus(int status, String mac, + {String? remark}) async { + try { + String serviceAddress = ServiceConstant.service_address; + String serviceName = ServiceConstant.app_server_service; + String serviceApi = "/reportupdatestatus"; + String queryUrl = "${serviceAddress}${serviceName}${serviceApi}"; + + String? openid = deviceUserMap[mac]; + + if (openid == null) { + print("无法找到设备 $mac 对应的用户信息"); + return; + } + // 初始化 data + Map data = { + "deviceNo": mac, + "openid": openid, + "status": status, + }; + + // 如果 remark 不为空,则添加到 data 中 + if (remark != null && remark.isNotEmpty) { + data['remark'] = remark; + } + + await requestWithLog( + logTitle: "更新设备处理状态", + method: MyHttpMethod.post, + data: data, + queryUrl: queryUrl, + onSuccess: (res) { + print("[微信]:更新状态成功为$data"); + }, + onFailure: (res) { + //更新失败 + print("[微信]:更新状态失败,数据为$data"); + }, + ); + } catch (e) { + print("[微信]:更新失状态败-》$e"); + } + } + + checkDeviceState(String mac) async { + try { + bool flag = false; + String queryUrl = + "https://iot.he-info.cn/api/iot/device/info/status?did=${mac}&token=M5Y3B4Frr6T1ACtwMfTNaSaxE2DT16Tn"; + await requestWithLog( + logTitle: "查询设备状态", + method: MyHttpMethod.get, + queryUrl: queryUrl, + onSuccess: (res) { + flag = (res.data[0]['state']) == 3 || (res.data[0]['state']) == 4 + ? true + : false; + }, + onFailure: (res) { + //更新失败 + flag = (res.data[0]['state']) == 3 || (res.data[0]['state']) == 4 + ? true + : false; + }, + ); + return flag; + } catch (e) { + print("获取设备状态失败,数据为$e"); + return false; + } + } +} diff --git a/bin/service/BedService.dart b/bin/service/BedService.dart new file mode 100644 index 0000000..e80ffa7 --- /dev/null +++ b/bin/service/BedService.dart @@ -0,0 +1,124 @@ +import 'package:EasyDartModule/EasyDartModule.dart'; + +import '../model/Bed.dart'; +import '../model/Person.dart'; +import '../model/Reservation.dart'; +import '../repository/BedRepository.dart'; +import '../enum/DeviceStatus.dart'; + +class BedService { + final BedRepository bedRepository = BedRepository(); + + BedService(); + + // 获取床位列表,支持查询参数 + Future getBedList(Bed query) async { + if (query.device_status != null && query.device_status!.isNotEmpty) { + List status = query.device_status!.split(","); + if (status.length != 2) { + // 查询所有的设备 + var allDevices = + await EasyDartModule.redis.get("oid_${query.tid}_devices"); + if (allDevices != null && allDevices.isNotEmpty) { + List deviceList = allDevices.split(','); + + if (status[0] == '0') { + // 查询离线设备 + List offlineDevices = []; + for (var deviceId in deviceList) { + var isOnline = await EasyDartModule.redis.get("oid_${deviceId}"); + if (isOnline == null) { + offlineDevices.add(deviceId); + } + } + query.deviceIds = offlineDevices; + } + if (status[0] == '1') { + // 查询在线设备 + List onlineDevices = []; + for (var deviceId in deviceList) { + var isOnline = await EasyDartModule.redis.get("oid_${deviceId}"); + if (isOnline != null) { + onlineDevices.add(deviceId); + } + } + query.deviceIds = onlineDevices; + } + } + } + } + List bedList = await bedRepository.fetchBedList(query); + if (bedList.isNotEmpty) { + fillDeviceStatus(bedList); + } + return bedList; + } + + // 获取单个床位信息 + Future getBedById(String bedId) async { + return await bedRepository.fetchBedById(bedId); + } + + // 创建床位 + Future createBed(Bed bed) async { + // 直接将异常抛给调用者 + bed.created_at = DateTime.now().millisecondsSinceEpoch; + bed.deleted = 0; + return await bedRepository.insertBed(bed); + } + + // 更新床位信息 + Future updateBed(String bedId, Bed updatedBed) async { + // 直接将异常抛给调用者 + updatedBed.updated_at = DateTime.now().millisecondsSinceEpoch; + return await bedRepository.updateBed(bedId, updatedBed); + } + + // 删除床位 + Future deleteBed(String bedId) async { + // 直接将异常抛给调用者 + if (bedId == null || bedId.isEmpty) { + return "ID不能为空"; + } + return await bedRepository.deleteBed(bedId); + } + + Future getBedCount(Bed query) async { + return await bedRepository.getBedCount(query); + } + + //查询预约入住信息 + getOrderCheckIn(Reservation query) async { + return await bedRepository.getOrderCheckInList(query); + } + + //设备在离线 + void fillDeviceStatus(List bedList) { + try { + if (bedList.isNotEmpty) { + bedList.forEach((bed) async { + if (bed['device_id'] != null) { + String deviceId = bed['device_id']; + if (deviceId != null && deviceId.isNotEmpty) { + var deviceStatus = + await EasyDartModule.redis.get("mac_$deviceId"); + if (deviceStatus != null) { + bed['device_status'] = DeviceStatus.ONLINE.code; + } else { + bed['device_status'] = DeviceStatus.OFFLONE.code; + } + bed['map_device_status'] = deviceStatus;//地图设备状态 + } + } + }); + } + } catch (e) { + print(e); + } + } + + //更新床位状态 + Future updateBedStatus(String bed_id, int code, Person person) async { + await bedRepository.updateBedStatus(bed_id, code, person); + } +} diff --git a/bin/service/BedTypeService.dart b/bin/service/BedTypeService.dart new file mode 100644 index 0000000..cee57ca --- /dev/null +++ b/bin/service/BedTypeService.dart @@ -0,0 +1,38 @@ +import '../model/BedType.dart'; +import '../repository/BedTypeRepository.dart'; + +class BedTypeService { + final BedTypeRepository bedTypeRepository = BedTypeRepository(); + + BedTypeService(); + + // 获取床位类型列表 + Future getBedTypeList(BedType query) async { + return await bedTypeRepository.fetchBedTypeList(query); + } + + // 添加床位类型 + Future addBedType(BedType bedType) async { + bedType.created_at = DateTime.now().millisecondsSinceEpoch; + bedType.deleted = 0; + return await bedTypeRepository.insertBedType(bedType); + } + + // 更新床位类型 + Future updateBedType(String bedTypeId, BedType updatedBedType) { + updatedBedType.updated_at = DateTime.now().millisecondsSinceEpoch; + return bedTypeRepository.updateBedType(bedTypeId, updatedBedType); + } + + // 删除床位类型 + Future deleteBedType(String bedTypeId) async { + if (bedTypeId == null || bedTypeId.isEmpty) { + return "ID不能为空"; + } + return await bedTypeRepository.deleteBedType(bedTypeId); + } + + Future getBedTypeCount(BedType query) async { + return await bedTypeRepository.getBedTypeCount(query); + } +} \ No newline at end of file diff --git a/bin/service/DictionaryService.dart b/bin/service/DictionaryService.dart new file mode 100644 index 0000000..6874bfc --- /dev/null +++ b/bin/service/DictionaryService.dart @@ -0,0 +1,22 @@ +import '../repository/DictionaryTypeRepository.dart'; +import '../model/DictionaryType.dart'; + +class DictionaryService { + final DictionaryTypeRepository dictionaryRepository = DictionaryTypeRepository(); + + Future> getDictionaryList(DictionaryType query) async { + return await dictionaryRepository.fetchDictionaryList(query); + } + + Future addDictionary(DictionaryType DictionaryType) async { + return await dictionaryRepository.insertDictionary(DictionaryType); + } + + Future updateDictionary(String id, DictionaryType DictionaryType) async { + return await dictionaryRepository.updateDictionary(id, DictionaryType); + } + + Future deleteDictionary(String id) async { + return await dictionaryRepository.deleteDictionary(id); + } +} \ No newline at end of file diff --git a/bin/service/DiseaseTypeService.dart b/bin/service/DiseaseTypeService.dart new file mode 100644 index 0000000..77d38f8 --- /dev/null +++ b/bin/service/DiseaseTypeService.dart @@ -0,0 +1,43 @@ +import '../model/DiseaseType.dart'; +import '../repository/DiseaseTypeRepository.dart'; + +class DiseaseTypeService { + final DiseaseTypeRepository diseaseTypeRepository = DiseaseTypeRepository(); + + DiseaseTypeService(); + + // 获取疾病类型列表 + Future getDiseaseTypeList(DiseaseType query) async { + return await diseaseTypeRepository.fetchDiseaseTypeList(query); + } + + // 添加疾病类型 + Future addDiseaseType(DiseaseType diseaseType) async { + diseaseType.created_at = DateTime.now().millisecondsSinceEpoch; + diseaseType.deleted = 0; + return await diseaseTypeRepository.insertDiseaseType(diseaseType); + } + + // 更新疾病类型 + Future updateDiseaseType(String diseaseTypeId, DiseaseType updatedDiseaseType) { + updatedDiseaseType.updated_at = DateTime.now().millisecondsSinceEpoch; + return diseaseTypeRepository.updateDiseaseType(diseaseTypeId, updatedDiseaseType); + } + + // 删除疾病类型 + Future deleteDiseaseType(String diseaseTypeId) async { + if (diseaseTypeId == null || diseaseTypeId.isEmpty) { + return "ID不能为空"; + } + return await diseaseTypeRepository.deleteDiseaseType(diseaseTypeId); + } + + Future getDiseaseTypeCount(DiseaseType query) async { + return await diseaseTypeRepository.getDiseaseTypeCount(query); + } + + // 获取疾病类型 + Future fetchDiseaseTypesByOrganizationId(String oid) async { + return await diseaseTypeRepository.fetchDiseaseTypeListByOrganization(oid); + } +} \ No newline at end of file diff --git a/bin/service/InstantAlarmService.dart b/bin/service/InstantAlarmService.dart new file mode 100644 index 0000000..839d5e2 --- /dev/null +++ b/bin/service/InstantAlarmService.dart @@ -0,0 +1,12 @@ + + +class InstantAlarmService { + + + InstantAlarmService(); + + void judgeAlarm(var instantData) { + + } + +} \ No newline at end of file diff --git a/bin/service/PersonService.dart b/bin/service/PersonService.dart new file mode 100644 index 0000000..2fa0a41 --- /dev/null +++ b/bin/service/PersonService.dart @@ -0,0 +1,64 @@ +import '../repository/PersonRepository.dart'; +import '../model/Person.dart'; +import '../service/BedService.dart'; + +class PersonService { + final PersonRepository personRepository = PersonRepository(); + final BedService bedService = BedService(); + + // 获取所有人员 + Future getPersonList(Person query, + {int page = 1, int pageSize = 10}) async { + var personList = await personRepository.fetchPersonList( + query, + ); + try { + if (personList.isNotEmpty) { + for (var person in personList) { + if (person['bed_id'] != null && person['bed_id']!.isNotEmpty) { + var bedInfo = await bedService.getBedById(person['bed_id']); + if (bedInfo != null) { + person['device_mac'] = bedInfo!['device_id']; + } + } + } + return personList; + } + } catch (e) { + print(e); + } + + return []; + } + + // 获取单个人员信息 + Future getPersonById(String personId) async { + return await personRepository.fetchPersonById(personId); + } + + // 添加人员 + Future addPerson(Person person) async { + person.created_at = DateTime.now().millisecondsSinceEpoch; + person.deleted = 0; + return await personRepository.insertPerson(person); + } + + // 更新人员信息 + Future updatePerson(String personId, Person updatedPerson) async { + updatedPerson.updated_at = DateTime.now().millisecondsSinceEpoch; + return await personRepository.updatePerson(personId, updatedPerson); + } + + // 删除人员,检查是否有绑定 + Future deletePerson(String personId) async { + return await personRepository.deletePerson(personId); + } + + fetchPersonsByOrganizationId(String oid) async { + return await personRepository.fetchPersonsByOrganizationId(oid); + } + + getPersonCount(Person query) async { + return await personRepository.getPersonCount(query); + } +} diff --git a/bin/service/PersonTypeService.dart b/bin/service/PersonTypeService.dart new file mode 100644 index 0000000..1a4ea3d --- /dev/null +++ b/bin/service/PersonTypeService.dart @@ -0,0 +1,33 @@ +import '../model/PersonType.dart'; +import '../repository/PersonTypeRepository.dart'; + +class PersonTypeService { + final PersonTypeRepository personTypeRepository = PersonTypeRepository(); + + // 获取所有人员类型 + Future getPersonTypeList(PersonType query, {int page = 1, int pageSize = 10}) async { + return await personTypeRepository.fetchPersonTypeList(query, page: page, pageSize: pageSize); + } + + // 添加人员类型 + Future addPersonType(PersonType personType) async { + personType.created_at = DateTime.now().millisecondsSinceEpoch; + personType.deleted = 0; + return await personTypeRepository.insertPersonType(personType); + } + + // 更新人员类型 + Future updatePersonType(String personTypeId, PersonType updatedPersonType) async { + updatedPersonType.updated_at = DateTime.now().millisecondsSinceEpoch; + return await personTypeRepository.updatePersonType(personTypeId, updatedPersonType); + } + + // 删除人员类型,检查是否有人员绑定该类型 + Future deletePersonType(String personTypeId) async { + bool isBoundToPerson = await personTypeRepository.checkPersonTypeBinding(personTypeId); + if (isBoundToPerson) { + return "人员类型已经被绑定,请先解除人员类型绑定."; // 如果有人员绑定,不能删除 + } + return await personTypeRepository.deletePersonType(personTypeId); + } +} \ No newline at end of file diff --git a/bin/service/RoomService.dart b/bin/service/RoomService.dart new file mode 100644 index 0000000..5d899df --- /dev/null +++ b/bin/service/RoomService.dart @@ -0,0 +1,336 @@ +import 'dart:convert'; + +import 'package:EasyDartModule/EasyDartModule.dart'; + +import '../model/Room.dart'; +import '../repository/RoomRepository.dart'; +import '../service/BedService.dart'; +import '../service/PersonService.dart'; + +import '../model/Bed.dart'; +import '../model/Person.dart'; + +import '../const/ServiceConstant.dart'; +import '../const/MessageType.dart'; +import '../const/RuzhuMessageType.dart'; +import '../const/Constants.dart'; +import '../enum/BedStatus.dart'; +import '../enum/MessageStatus.dart'; + +class RoomService { + final RoomRepository roomRepository = RoomRepository(); + final BedService bedService = BedService(); + final PersonService personService = PersonService(); + + RoomService(); + + // 获取房间列表 + Future getRoomList(Room query, + {int page = 1, int pageSize = 10,bool fill = true,}) async { + var roomList = await roomRepository.fetchRoomList(query, + page: page, pageSize: pageSize); + if (roomList != null && roomList.isNotEmpty && fill) { + await fillRoomInfo(roomList); + } + return roomList; + } + + // 获取房间数量 + Future getRoomCount(Room query) async { + return await roomRepository.getRoomCount(query); + } + + // 添加房间 + Future addRoom(Room room) async { + if (room.room_type == null || room.room_type!.isEmpty) { + return "请选择房间类型"; + } + int currentTime = DateTime.now().millisecondsSinceEpoch; + room.created_at = currentTime; + room.deleted = 0; + await roomRepository.insertRoom(room); + return ""; + } + + // 更新房间 + Future updateRoom(String roomId, Room updatedRoom) { + int currentTime = DateTime.now().millisecondsSinceEpoch; + updatedRoom.updated_at = currentTime; + return roomRepository.updateRoom(roomId, updatedRoom); + } + + // 删除房间 + Future deleteRoom(String roomId) async { + if (roomId == null || roomId.isEmpty) { + return "ID不能为空"; + } + return await roomRepository.deleteRoom(roomId); + } + + //办理预约入住 + addOrderCheckIn(data, Map jwt) { + int currentTime = DateTime.now().millisecondsSinceEpoch; + data['create_at'] = currentTime; + data['deleted'] = 0; + data['create_user_id'] = jwt['uid']; + return roomRepository.addOrderCheckIn(data); + } + + //删除预约入住 + delOrderCheckIn(data) { + return roomRepository.delOrderCheckIn(data); + } + + //填充床位信息 + Future fillRoomInfo(List roomList) async { + try { + if (roomList == null || roomList.isEmpty) { + return ""; + } + for (var item in roomList) { + String roomId = item['_id'].toHexString(); + //根据roomid查询床位数 + Bed bedQuery = Bed(); + bedQuery.room_id = roomId; + bedQuery.limit = Constants.default_limit_max.toString(); + List bedList = await bedService.getBedList(bedQuery); + if (bedList == null || bedList.isEmpty) { + item['bed_count'] = 0; //总床位数 + item['bed_use_count'] = 0; //可使用床位数 + } else { + item['bed_count'] = bedList.length; + //根据床位id查询使用数 + try { + String bedIdsString = bedList + .map((bed) { + var id = bed['_id']; + return id is ObjectId ? id.toHexString() : id.toString(); + }) // 提取 _id 字段并转换为字符串 + .where((id) => id != null) // 过滤掉 null 的值 + .join(','); // 用逗号连接成一个字符串 + Person personQuery = Person(); + personQuery.bed_ids = bedIdsString; + personQuery.limit = Constants.default_limit_max.toString(); + var persons = await personService.getPersonList(personQuery, + page: 1, pageSize: Constants.default_limit_max); + if (persons == null || persons.isEmpty) { + item['bed_use_count'] = item['bed_count']; + } else { + item['bed_use_count'] = item['bed_count'] - persons.length; + } + } catch (e) { + print(e); + } + } + } + return ""; + } catch (e) { + print(e); + return ""; + } + } + + //添加预约消息 + Future addReservationMessage(data, Map jwt) async { + //todo 根据jwt取登录用户信息 + data['ruzhu_msg_type'] = RuzhuMessageType.reservation.code; + String serviceAddress = ServiceConstant.service_address; + String serviceName = ServiceConstant.message_service; + String serviceApi = ServiceConstant.addMessage; + String queryUrl = "${serviceAddress}${serviceName}${serviceApi}"; + var createTime = DateTime.now().millisecondsSinceEpoch; + var status = MessageStatus.notify.code; //消息状态 0:无需处理 1:待处理 2:已处理 + var info = { + 'room_id': data['room_id'], + 'bed_id': data['bed_id'], + 'start_time': data['start_time'].toString(), + 'end_time': data['end_time'].toString(), + 'rel_name': data['rel_name'], + 'ship': data['ship'], + 'ruzhu_msg_type': data['ruzhu_msg_type'], + 'create_user_id': jwt['uid'], + 'bed_name':data['bed_name'], + 'room_name':data['room_name'], + }; + var pushData = { + 'level': 1, + 'createTime': createTime, + 'type': MessageType.check_in.code, + 'status': status, + 'tid': jwt['tid'], + 'data': info, + }; + try { + var res = + await EasyDartModule.dio.post(queryUrl, data: jsonEncode(pushData)); + print(res); + } catch (e) { + print(e); + } + } + + //办理入住信息 + addRuzhuCheckIn(data, Map jwt) async { + //添加人员信息 + //todo 如果是已有人员信息?? + int currentTime = DateTime.now().millisecondsSinceEpoch; + Person person = Person(); + person.room_id = data['room_id']; + person.room_name = data['room_name']; + person.bed_id = data['bed_id']; + person.bed_name = data['bed_name']; + person.check_in_start_time = data['start_time']; + person.check_in_end_time = data['end_time']; + person.contact_name = data['rel_name']; + person.person_name = data['person_name']; + person.gender = data['gender']; + person.ethnicity = data['minzu']; + person.person_type_id = data['person_type']; + person.person_type_name = data['person_type_name']; + person.id_card_number = data['cardNo']; + person.phone_number = data['phone']; + person.service_level = data['service_level']; + person.height = data['height']; + person.weight = data['weight']; + person.tid = jwt['tid']; + person.level = jwt['level']; + person.age = data['age']; + person.desc = data['desc']; + person.contact_relationship = data['ship']; + person.contact_phone = data['tel']; + person.oid = jwt['tid']; + person.data_level = jwt['level']; + personService.addPerson(person); + //更改床位状态 + await bedService.updateBedStatus( + data['bed_id'], BedStatus.using.code, person); + //发送入住消息 + addRuzhuMessage(data, jwt); + //添加入住记录 + addRuzhuRecord(data, jwt); + } + + //添加入住消息 + Future addRuzhuMessage(data, Map jwt) async { + data['ruzhu_msg_type'] = RuzhuMessageType.check_in.code; + data['create_user_id'] = jwt['uid']; + data['start_time'] = data['start_time'].toString(); + data['end_time'] = data['end_time'].toString(); + String serviceAddress = ServiceConstant.service_address; + String serviceName = ServiceConstant.message_service; + String serviceApi = ServiceConstant.addMessage; + String queryUrl = "${serviceAddress}${serviceName}${serviceApi}"; + var createTime = DateTime.now().millisecondsSinceEpoch; + var status = MessageStatus.notify.code; //消息状态 0:无需处理 1:待处理 2:已处理 + // var info = { + // 'room_id': data['room_id'], + // 'bed_id': data['bed_id'], + // 'start_time': data['start_time'], + // 'end_time': data['end_time'], + // 'rel_name': data['rel_name'], + // 'ship': data['ship'], + // 'ruzhu_msg_type': data['ruzhu_msg_type'], + // }; + var pushData = { + 'level': 1, + 'createTime': createTime, + 'type': MessageType.check_in.code, + 'status': status, + 'tid': jwt['tid'], + 'data': data, + }; + try { + var res = + await EasyDartModule.dio.post(queryUrl, data: jsonEncode(pushData)); + print(res); + } catch (e) { + print(e); + } + } + + //办理退住 + checkout(data, Map jwt) async { + // 1.更新人员信息 当前正在该床位入住的人员??有什么需要更新,正在入住的房间,床位? + // 2.添加退住记录 + // 3.发送退住消息 + // 4.更新床位状态 + String bedId = data['bed_id']; + data['create_user_id'] = jwt['uid']; + //更新床位状态 + Person person = Person(); + await bedService.updateBedStatus(bedId, BedStatus.no_using.code, person); + person.bed_id = bedId; + List personlist = await personService.getPersonList(person); + try { + if (personlist != null && personlist.isNotEmpty) { + var personSelect = personlist[0]; + // 添加退住记录 + await addCheckOutRecord(data, jwt, personSelect); + //发送退住消息 + await addCheckOutMessage(personSelect, jwt,data); + //更新人员信息 + await personService.updatePerson( + personSelect['_id'].toHexString(), person); + } + } catch (e) { + print(e); + } + } + + //添加入住记录 + void addRuzhuRecord(data, Map jwt) { + //问题 记录人员入住,怎么查询人员入住历史 + int currentTime = DateTime.now().millisecondsSinceEpoch; + data['create_at'] = currentTime; + data['deleted'] = 0; + data['create_user_id'] = jwt['uid']; + roomRepository.addOrderCheckInRuZhuRecord(data); + } + + //添加退住消息 + Future addCheckOutMessage(data, Map jwt, bedInfo) async { + Map info = {}; + info['ruzhu_msg_type'] = RuzhuMessageType.check_out.code; + info['bed_id'] = bedInfo['bed_id']; + info['bed_name'] = bedInfo['bed_name']; + info['room_name'] = bedInfo['room_name']; + info['room_id'] = bedInfo['room_id']; + info['person_id'] = data['_id'].toHexString(); + info['person_name'] = data['person_name']; + String serviceAddress = ServiceConstant.service_address; + String serviceName = ServiceConstant.message_service; + String serviceApi = ServiceConstant.addMessage; + String queryUrl = "${serviceAddress}${serviceName}${serviceApi}"; + var createTime = DateTime.now().millisecondsSinceEpoch; + var status = MessageStatus.notify.code; //消息状态 0:无需处理 1:待处理 2:已处理 + var pushData = { + 'level': 1, + 'createTime': createTime, + 'type': MessageType.check_in.code, + 'status': status, + 'tid': jwt['tid'], + 'data': info, + }; + try { + var res = + await EasyDartModule.dio.post(queryUrl, data: jsonEncode(pushData)); + print(res); + } catch (e) { + print(e); + } + } + + //添加退住记录 + Future addCheckOutRecord( + data, Map jwt, personSelect) async { + //问题 记录人员入住,怎么查询人员入住历史 + int currentTime = DateTime.now().millisecondsSinceEpoch; + data['create_at'] = currentTime; + data['deleted'] = 0; + data['create_user_id'] = jwt['uid']; + data['person_id'] = personSelect['_id']; + data['person_name'] = personSelect['person_name']; + //查询当前使用该床位的人员 + await roomRepository.addCheckOutRecord(data); + } +} diff --git a/bin/service/RoomTypeService.dart b/bin/service/RoomTypeService.dart new file mode 100644 index 0000000..3e98708 --- /dev/null +++ b/bin/service/RoomTypeService.dart @@ -0,0 +1,38 @@ +import '../model/RoomType.dart'; +import '../repository/RoomTypeRepository.dart'; + +class RoomTypeService { + final RoomTypeRepository roomTypeRepository = RoomTypeRepository(); + + RoomTypeService(); + + // 获取房间类型列表 + Future getRoomTypeList(RoomType query) async { + return await roomTypeRepository.fetchRoomTypeList(query); + } + + // 添加房间类型 + Future addRoomType(RoomType roomType) async { + roomType.created_at = DateTime.now().millisecondsSinceEpoch; + roomType.deleted = 0; + return await roomTypeRepository.insertRoomType(roomType); + } + + // 更新房间类型 + Future updateRoomType(String roomTypeId, RoomType updatedRoomType) { + updatedRoomType.updated_at = DateTime.now().millisecondsSinceEpoch; + return roomTypeRepository.updateRoomType(roomTypeId, updatedRoomType); + } + + // 删除房间类型 + Future deleteRoomType(String roomTypeId) async { + if (roomTypeId == null || roomTypeId.isEmpty) { + return "ID不能为空"; + } + return await roomTypeRepository.deleteRoomType(roomTypeId); + } + + Future getRoomTypeCount(RoomType query) async { + return await roomTypeRepository.getRoomTypeCount(query); + } +} diff --git a/bin/service/TokenService.dart b/bin/service/TokenService.dart new file mode 100644 index 0000000..a3b3f16 --- /dev/null +++ b/bin/service/TokenService.dart @@ -0,0 +1,14 @@ +import 'package:EasyDartModule/EasyDartModule.dart'; + +import '../repository/AreaRepository.dart'; + +class TokenService { + final AreaRepository areaRepository = AreaRepository(); + + TokenService(); + + // 获取token信息 + Future getToken(String oid) async { + return await EasyDartModule.redis.get("oid_token_"+oid); + } +} diff --git a/bin/util/MyUtils.dart b/bin/util/MyUtils.dart new file mode 100644 index 0000000..5607de4 --- /dev/null +++ b/bin/util/MyUtils.dart @@ -0,0 +1,95 @@ +import '../model/api_response.dart'; +import '../model/app_uri_status.dart'; + +class MyUtils { + static ApiResponse formatResponse( + ApiResponse res, + String successMsg, + String errorMsg, + ) { + if (res.code == HttpStatusCodes.ok) { + // 成功但 msg 为空时填默认成功提示 + if (res.msg == null || res.msg!.isEmpty) { + res.msg = successMsg; + } + } else { + // 失败且 msg 为空时填默认失败提示 + if (res.msg == null || res.msg!.isEmpty) { + res.msg = errorMsg; + } + } + return res; + } + + // 获取最近24小时的开始时间的毫秒数 + static int getStartOfLast24HoursMilliseconds() { + DateTime now = DateTime.now(); + DateTime startOfLast24Hours = now.subtract(Duration(hours: 24)); + return startOfLast24Hours.millisecondsSinceEpoch; + } + + // 获取当前时间的毫秒数作为最近24小时的结束时间 + static int getEndOfLast24HoursMilliseconds() { + DateTime now = DateTime.now(); + return now.millisecondsSinceEpoch; + } + + static int getStartRangeFromNDaysAgoToNextDay(int n) { + DateTime now = DateTime.now(); + DateTime start = DateTime(now.year, now.month, now.day - n - 1, 18, 0, 0); + DateTime end = start.add(Duration(hours: 24)); + return start.millisecondsSinceEpoch; + } + + static int getEndRangeFromNDaysAgoToNextDay(int n) { + DateTime now = DateTime.now(); + DateTime start = DateTime(now.year, now.month, now.day - n - 1, 18, 0, 0); + DateTime end = start.add(Duration(hours: 24)); + return end.millisecondsSinceEpoch; + } + + // 获取当天前一天的下午18:00的时间戳 + static int getYesterday18Milliseconds() { + DateTime now = DateTime.now(); + DateTime yesterday18 = DateTime(now.year, now.month, now.day - 1, 18, 0, 0); + return yesterday18.millisecondsSinceEpoch; + } + + // 获取当天17:00的时间戳 + static int getToday17Milliseconds() { + DateTime now = DateTime.now(); + DateTime today17 = DateTime(now.year, now.month, now.day, 17, 0, 0); + return today17.millisecondsSinceEpoch; + } + + // 获取前一天的开始时间戳(前一天的00:00:00) + static int getStartOfYesterdayMilliseconds() { + DateTime now = DateTime.now(); + DateTime startOfYesterday = + DateTime(now.year, now.month, now.day - 1, 0, 0, 0); + return startOfYesterday.millisecondsSinceEpoch; + } + + // 获取前一天的结束时间戳(前一天的23:59:59) + static int getEndOfYesterdayMilliseconds() { + DateTime now = DateTime.now(); + DateTime endOfYesterday = + DateTime(now.year, now.month, now.day - 1, 23, 59, 59); + return endOfYesterday.millisecondsSinceEpoch; + } + + // 获取前一天的开始时间戳(前一天的00:00:00) + static int getStartOfCurrentMilliseconds() { + DateTime now = DateTime.now(); + DateTime startOfYesterday = DateTime(now.year, now.month, now.day, 0, 0, 0); + return startOfYesterday.millisecondsSinceEpoch; + } + + // 获取前一天的结束时间戳(前一天的23:59:59) + static int getEndOfCurrentMilliseconds() { + DateTime now = DateTime.now(); + DateTime endOfYesterday = + DateTime(now.year, now.month, now.day, 23, 59, 59); + return endOfYesterday.millisecondsSinceEpoch; + } +} diff --git a/bin/util/requestWithLog.dart b/bin/util/requestWithLog.dart new file mode 100644 index 0000000..f832c97 --- /dev/null +++ b/bin/util/requestWithLog.dart @@ -0,0 +1,102 @@ +import 'dart:convert'; + +import 'package:EasyDartModule/EasyDartModule.dart'; + +import '../model/api_response.dart'; +import '../model/app_uri_status.dart'; +import '../util/MyUtils.dart'; + +Future requestWithLog({ + required String logTitle, + required MyHttpMethod method, + required String queryUrl, + Map? data, + String successMsg = "操作成功", + String errorMsg = "操作失败", + void Function(ApiResponse res)? onSuccess, + void Function(ApiResponse res)? onFailure, +}) async { + EasyDartModule.logger.info(logTitle); + + ApiResponse apiResponse = ApiResponse(code: -1, msg: "请求失败"); + try { + String? language = ""; + if (language != null && language.isNotEmpty) { + if (queryUrl.contains("?")) { + queryUrl += "&lang=$language"; + } else { + queryUrl += "?lang=$language"; + } + } + successMsg = successMsg; + errorMsg = errorMsg; + + var response; + + switch (method) { + case MyHttpMethod.get: + response = await EasyDartModule.dio.get(queryUrl); + break; + case MyHttpMethod.post: + response = data != null + ? await EasyDartModule.dio.post(queryUrl, data: jsonEncode(data)) + : await EasyDartModule.dio.post(queryUrl); + break; + case MyHttpMethod.put: + response = data != null + ? await EasyDartModule.dio.put(queryUrl, data: jsonEncode(data)) + : await EasyDartModule.dio.put(queryUrl); + break; + case MyHttpMethod.delete: + response = data != null + ? await EasyDartModule.dio.delete(queryUrl, data: jsonEncode(data)) + : await EasyDartModule.dio.delete(queryUrl); + break; + } + + if (response != null) { + final responseData = + response.data is String ? jsonDecode(response.data) : response.data; + + apiResponse = ApiResponse.fromJson(responseData, (object) => object, + rawResponse: response); + + if (apiResponse.code == HttpStatusCodes.ok || apiResponse.code == 20000) { + MyUtils.formatResponse(apiResponse, successMsg, errorMsg); + onSuccess?.call(apiResponse); + } else { + print("[网络请求失败:$response]"); + apiResponse.msg = responseData['msg'] ?? errorMsg; + onFailure?.call(apiResponse); + } + + return apiResponse; + } else { + apiResponse = ApiResponse(code: -1, msg: "失败"); + onFailure?.call(apiResponse); + return apiResponse; + } + } catch (e) { + print("[网络请求异常:$e]"); + EasyDartModule.logger.error("$logTitle 失败->$e"); + onFailure?.call(apiResponse); + return apiResponse; + } +} + +enum MyHttpMethod { get, post, put, delete } + +extension HttpMethodExtension on MyHttpMethod { + String get name { + switch (this) { + case MyHttpMethod.get: + return 'GET'; + case MyHttpMethod.post: + return 'POST'; + case MyHttpMethod.put: + return 'PUT'; + case MyHttpMethod.delete: + return 'DELETE'; + } + } +} diff --git a/pubspec.lock b/pubspec.lock new file mode 100644 index 0000000..c50ccaa --- /dev/null +++ b/pubspec.lock @@ -0,0 +1,1132 @@ +# Generated by pub +# See https://dart.dev/tools/pub/glossary#lockfile +packages: + EasyDartModule: + dependency: "direct main" + description: + path: "." + ref: master + resolved-ref: fadc39301e5c57173e5f16c2600bc4c2abd47102 + url: "https://git.he-info.cn/qmqz/easy_dart_module.git" + source: git + version: "1.0.0" + _fe_analyzer_shared: + dependency: transitive + description: + name: _fe_analyzer_shared + sha256: "45cfa8471b89fb6643fe9bf51bd7931a76b8f5ec2d65de4fb176dba8d4f22c77" + url: "https://pub.flutter-io.cn" + source: hosted + version: "73.0.0" + _macros: + dependency: transitive + description: dart + source: sdk + version: "0.3.2" + adaptive_number: + dependency: transitive + description: + name: adaptive_number + sha256: "3a567544e9b5c9c803006f51140ad544aedc79604fd4f3f2c1380003f97c1d77" + url: "https://pub.flutter-io.cn" + source: hosted + version: "1.0.0" + analyzer: + dependency: transitive + description: + name: analyzer + sha256: "4959fec185fe70cce007c57e9ab6983101dbe593d2bf8bbfb4453aaec0cf470a" + url: "https://pub.flutter-io.cn" + source: hosted + version: "6.8.0" + archive: + dependency: transitive + description: + name: archive + sha256: "2fde1607386ab523f7a36bb3e7edb43bd58e6edaf2ffb29d8a6d578b297fdbbd" + url: "https://pub.flutter-io.cn" + source: hosted + version: "4.0.7" + args: + dependency: "direct main" + description: + name: args + sha256: d0481093c50b1da8910eb0bb301626d4d8eb7284aa739614d2b394ee09e3ea04 + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.7.0" + async: + dependency: transitive + description: + name: async + sha256: "758e6d74e971c3e5aceb4110bfd6698efc7f501675bcfe0c775459a8140750eb" + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.13.0" + basic_utils: + dependency: transitive + description: + name: basic_utils + sha256: "2064b21d3c41ed7654bc82cc476fd65542e04d60059b74d5eed490a4da08fc6c" + url: "https://pub.flutter-io.cn" + source: hosted + version: "5.7.0" + boolean_selector: + dependency: transitive + description: + name: boolean_selector + sha256: "8aab1771e1243a5063b8b0ff68042d67334e3feab9e95b9490f9a6ebf73b42ea" + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.1.2" + bson: + dependency: transitive + description: + name: bson + sha256: "9071b154b5cd96482c2e116b015e87acfdc8412630cc8f3aba60c539a8ef5442" + url: "https://pub.flutter-io.cn" + source: hosted + version: "5.0.5" + buffer: + dependency: transitive + description: + name: buffer + sha256: "389da2ec2c16283c8787e0adaede82b1842102f8c8aae2f49003a766c5c6b3d1" + url: "https://pub.flutter-io.cn" + source: hosted + version: "1.2.3" + build: + dependency: transitive + description: + name: build + sha256: "80184af8b6cb3e5c1c4ec6d8544d27711700bc3e6d2efad04238c7b5290889f0" + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.4.1" + build_config: + dependency: transitive + description: + name: build_config + sha256: bf80fcfb46a29945b423bd9aad884590fb1dc69b330a4d4700cac476af1708d1 + url: "https://pub.flutter-io.cn" + source: hosted + version: "1.1.1" + build_daemon: + dependency: transitive + description: + name: build_daemon + sha256: "79b2aef6ac2ed00046867ed354c88778c9c0f029df8a20fe10b5436826721ef9" + url: "https://pub.flutter-io.cn" + source: hosted + version: "4.0.2" + build_resolvers: + dependency: transitive + description: + name: build_resolvers + sha256: "339086358431fa15d7eca8b6a36e5d783728cf025e559b834f4609a1fcfb7b0a" + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.4.2" + build_runner: + dependency: "direct dev" + description: + name: build_runner + sha256: "028819cfb90051c6b5440c7e574d1896f8037e3c96cf17aaeb054c9311cfbf4d" + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.4.13" + build_runner_core: + dependency: transitive + description: + name: build_runner_core + sha256: f8126682b87a7282a339b871298cc12009cb67109cfa1614d6436fb0289193e0 + url: "https://pub.flutter-io.cn" + source: hosted + version: "7.3.2" + built_collection: + dependency: transitive + description: + name: built_collection + sha256: "376e3dd27b51ea877c28d525560790aee2e6fbb5f20e2f85d5081027d94e2100" + url: "https://pub.flutter-io.cn" + source: hosted + version: "5.1.1" + built_value: + dependency: transitive + description: + name: built_value + sha256: ea90e81dc4a25a043d9bee692d20ed6d1c4a1662a28c03a96417446c093ed6b4 + url: "https://pub.flutter-io.cn" + source: hosted + version: "8.9.5" + characters: + dependency: transitive + description: + name: characters + sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605" + url: "https://pub.flutter-io.cn" + source: hosted + version: "1.3.0" + charcode: + dependency: transitive + description: + name: charcode + sha256: fb0f1107cac15a5ea6ef0a6ef71a807b9e4267c713bb93e00e92d737cc8dbd8a + url: "https://pub.flutter-io.cn" + source: hosted + version: "1.4.0" + checked_yaml: + dependency: transitive + description: + name: checked_yaml + sha256: feb6bed21949061731a7a75fc5d2aa727cf160b91af9a3e464c5e3a32e28b5ff + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.0.3" + clock: + dependency: transitive + description: + name: clock + sha256: fddb70d9b5277016c77a80201021d40a2247104d9f4aa7bab7157b7e3f05b84b + url: "https://pub.flutter-io.cn" + source: hosted + version: "1.1.2" + code_builder: + dependency: transitive + description: + name: code_builder + sha256: "0ec10bf4a89e4c613960bf1e8b42c64127021740fb21640c29c909826a5eea3e" + url: "https://pub.flutter-io.cn" + source: hosted + version: "4.10.1" + collection: + dependency: "direct overridden" + description: + name: collection + sha256: "2f5709ae4d3d59dd8f7cd309b4e023046b57d8a6c82130785d2b0e5868084e76" + url: "https://pub.flutter-io.cn" + source: hosted + version: "1.19.1" + convert: + dependency: transitive + description: + name: convert + sha256: b30acd5944035672bc15c6b7a8b47d773e41e2f17de064350988c5d02adb1c68 + url: "https://pub.flutter-io.cn" + source: hosted + version: "3.1.2" + coverage: + dependency: transitive + description: + name: coverage + sha256: e3493833ea012784c740e341952298f1cc77f1f01b1bbc3eb4eecf6984fb7f43 + url: "https://pub.flutter-io.cn" + source: hosted + version: "1.11.1" + cross_file: + dependency: transitive + description: + name: cross_file + sha256: "7caf6a750a0c04effbb52a676dce9a4a592e10ad35c34d6d2d0e4811160d5670" + url: "https://pub.flutter-io.cn" + source: hosted + version: "0.3.4+2" + crypto: + dependency: transitive + description: + name: crypto + sha256: "1e445881f28f22d6140f181e07737b22f1e099a5e1ff94b0af2f9e4a463f4855" + url: "https://pub.flutter-io.cn" + source: hosted + version: "3.0.6" + csslib: + dependency: transitive + description: + name: csslib + sha256: "09bad715f418841f976c77db72d5398dc1253c21fb9c0c7f0b0b985860b2d58e" + url: "https://pub.flutter-io.cn" + source: hosted + version: "1.0.2" + cupertino_icons: + dependency: "direct main" + description: + name: cupertino_icons + sha256: ba631d1c7f7bef6b729a622b7b752645a2d076dba9976925b8f25725a30e1ee6 + url: "https://pub.flutter-io.cn" + source: hosted + version: "1.0.8" + dart_jsonwebtoken: + dependency: "direct main" + description: + name: dart_jsonwebtoken + sha256: "00a0812d2aeaeb0d30bcbc4dd3cee57971dbc0ab2216adf4f0247f37793f15ef" + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.17.0" + dart_style: + dependency: transitive + description: + name: dart_style + sha256: "7856d364b589d1f08986e140938578ed36ed948581fbc3bc9aef1805039ac5ab" + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.3.7" + decimal: + dependency: transitive + description: + name: decimal + sha256: "28239b8b929c1bd8618702e6dbc96e2618cf99770bbe9cb040d6cf56a11e4ec3" + url: "https://pub.flutter-io.cn" + source: hosted + version: "3.2.1" + dio: + dependency: transitive + description: + name: dio + sha256: "253a18bbd4851fecba42f7343a1df3a9a4c1d31a2c1b37e221086b4fa8c8dbc9" + url: "https://pub.flutter-io.cn" + source: hosted + version: "5.8.0+1" + dio_web_adapter: + dependency: transitive + description: + name: dio_web_adapter + sha256: "7586e476d70caecaf1686d21eee7247ea43ef5c345eab9e0cc3583ff13378d78" + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.1.1" + ed25519_edwards: + dependency: transitive + description: + name: ed25519_edwards + sha256: "6ce0112d131327ec6d42beede1e5dfd526069b18ad45dcf654f15074ad9276cd" + url: "https://pub.flutter-io.cn" + source: hosted + version: "0.3.1" + ef: + dependency: "direct main" + description: + path: "." + ref: main + resolved-ref: c95c04d502b867e1b3da1257a68493609c645ce7 + url: "https://gitea.wslpc.real.he-info.cn:94/flutter/ef.git" + source: git + version: "0.0.1" + event_bus: + dependency: transitive + description: + name: event_bus + sha256: "1a55e97923769c286d295240048fc180e7b0768902c3c2e869fe059aafa15304" + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.0.1" + ffi: + dependency: transitive + description: + name: ffi + sha256: "16ed7b077ef01ad6170a3d0c57caa4a112a38d7a2ed5602e0aca9ca6f3d98da6" + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.1.3" + file: + dependency: transitive + description: + name: file + sha256: a3b4f84adafef897088c160faf7dfffb7696046cb13ae90b508c2cbc95d3b8d4 + url: "https://pub.flutter-io.cn" + source: hosted + version: "7.0.1" + file_picker: + dependency: transitive + description: + name: file_picker + sha256: ab13ae8ef5580a411c458d6207b6774a6c237d77ac37011b13994879f68a8810 + url: "https://pub.flutter-io.cn" + source: hosted + version: "8.3.7" + fixnum: + dependency: transitive + description: + name: fixnum + sha256: b6dc7065e46c974bc7c5f143080a6764ec7a4be6da1285ececdc37be96de53be + url: "https://pub.flutter-io.cn" + source: hosted + version: "1.1.1" + flutter: + dependency: "direct main" + description: flutter + source: sdk + version: "0.0.0" + flutter_lints: + dependency: "direct dev" + description: + name: flutter_lints + sha256: "3f41d009ba7172d5ff9be5f6e6e6abb4300e263aab8866d2a0842ed2a70f8f0c" + url: "https://pub.flutter-io.cn" + source: hosted + version: "4.0.0" + flutter_plugin_android_lifecycle: + dependency: transitive + description: + name: flutter_plugin_android_lifecycle + sha256: "1c2b787f99bdca1f3718543f81d38aa1b124817dfeb9fb196201bea85b6134bf" + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.0.26" + flutter_web_plugins: + dependency: transitive + description: flutter + source: sdk + version: "0.0.0" + frontend_server_client: + dependency: transitive + description: + name: frontend_server_client + sha256: f64a0333a82f30b0cca061bc3d143813a486dc086b574bfb233b7c1372427694 + url: "https://pub.flutter-io.cn" + source: hosted + version: "4.0.0" + get: + dependency: transitive + description: + name: get + sha256: "5ed34a7925b85336e15d472cc4cfe7d9ebf4ab8e8b9f688585bf6b50f4c3d79a" + url: "https://pub.flutter-io.cn" + source: hosted + version: "4.7.3" + glob: + dependency: transitive + description: + name: glob + sha256: c3f1ee72c96f8f78935e18aa8cecced9ab132419e8625dc187e1c2408efc20de + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.1.3" + google_identity_services_web: + dependency: transitive + description: + name: google_identity_services_web + sha256: "55580f436822d64c8ff9a77e37d61f5fb1e6c7ec9d632a43ee324e2a05c3c6c9" + url: "https://pub.flutter-io.cn" + source: hosted + version: "0.3.3" + googleapis_auth: + dependency: transitive + description: + name: googleapis_auth + sha256: befd71383a955535060acde8792e7efc11d2fccd03dd1d3ec434e85b68775938 + url: "https://pub.flutter-io.cn" + source: hosted + version: "1.6.0" + graphs: + dependency: transitive + description: + name: graphs + sha256: "741bbf84165310a68ff28fe9e727332eef1407342fca52759cb21ad8177bb8d0" + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.3.2" + grpc: + dependency: transitive + description: + name: grpc + sha256: "30e1edae6846b163a64f6d8716e3443980fe1f7d2d1f086f011d24ea186f2582" + url: "https://pub.flutter-io.cn" + source: hosted + version: "4.0.4" + hive: + dependency: transitive + description: + name: hive + sha256: "8dcf6db979d7933da8217edcec84e9df1bdb4e4edc7fc77dbd5aa74356d6d941" + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.2.3" + hive_flutter: + dependency: transitive + description: + name: hive_flutter + sha256: dca1da446b1d808a51689fb5d0c6c9510c0a2ba01e22805d492c73b68e33eecc + url: "https://pub.flutter-io.cn" + source: hosted + version: "1.1.0" + html: + dependency: transitive + description: + name: html + sha256: "1fc58edeaec4307368c60d59b7e15b9d658b57d7f3125098b6294153c75337ec" + url: "https://pub.flutter-io.cn" + source: hosted + version: "0.15.5" + http: + dependency: "direct dev" + description: + name: http + sha256: fe7ab022b76f3034adc518fb6ea04a82387620e19977665ea18d30a1cf43442f + url: "https://pub.flutter-io.cn" + source: hosted + version: "1.3.0" + http2: + dependency: transitive + description: + name: http2 + sha256: "382d3aefc5bd6dc68c6b892d7664f29b5beb3251611ae946a98d35158a82bbfa" + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.3.1" + http_methods: + dependency: transitive + description: + name: http_methods + sha256: "6bccce8f1ec7b5d701e7921dca35e202d425b57e317ba1a37f2638590e29e566" + url: "https://pub.flutter-io.cn" + source: hosted + version: "1.1.1" + http_multi_server: + dependency: transitive + description: + name: http_multi_server + sha256: aa6199f908078bb1c5efb8d8638d4ae191aac11b311132c3ef48ce352fb52ef8 + url: "https://pub.flutter-io.cn" + source: hosted + version: "3.2.2" + http_parser: + dependency: transitive + description: + name: http_parser + sha256: "178d74305e7866013777bab2c3d8726205dc5a4dd935297175b19a23a2e66571" + url: "https://pub.flutter-io.cn" + source: hosted + version: "4.1.2" + intl: + dependency: "direct main" + description: + name: intl + sha256: "3df61194eb431efc39c4ceba583b95633a403f46c9fd341e550ce0bfa50e9aa5" + url: "https://pub.flutter-io.cn" + source: hosted + version: "0.20.2" + io: + dependency: transitive + description: + name: io + sha256: dfd5a80599cf0165756e3181807ed3e77daf6dd4137caaad72d0b7931597650b + url: "https://pub.flutter-io.cn" + source: hosted + version: "1.0.5" + js: + dependency: transitive + description: + name: js + sha256: c1b2e9b5ea78c45e1a0788d29606ba27dc5f71f019f32ca5140f61ef071838cf + url: "https://pub.flutter-io.cn" + source: hosted + version: "0.7.1" + json_annotation: + dependency: transitive + description: + name: json_annotation + sha256: "1ce844379ca14835a50d2f019a3099f419082cfdd231cd86a142af94dd5c6bb1" + url: "https://pub.flutter-io.cn" + source: hosted + version: "4.9.0" + json_serializable: + dependency: "direct dev" + description: + name: json_serializable + sha256: c2fcb3920cf2b6ae6845954186420fca40bc0a8abcc84903b7801f17d7050d7c + url: "https://pub.flutter-io.cn" + source: hosted + version: "6.9.0" + lints: + dependency: "direct dev" + description: + name: lints + sha256: "976c774dd944a42e83e2467f4cc670daef7eed6295b10b36ae8c85bcbf828235" + url: "https://pub.flutter-io.cn" + source: hosted + version: "4.0.0" + logging: + dependency: transitive + description: + name: logging + sha256: c8245ada5f1717ed44271ed1c26b8ce85ca3228fd2ffdb75468ab01979309d61 + url: "https://pub.flutter-io.cn" + source: hosted + version: "1.3.0" + macros: + dependency: transitive + description: + name: macros + sha256: "0acaed5d6b7eab89f63350bccd82119e6c602df0f391260d0e32b5e23db79536" + url: "https://pub.flutter-io.cn" + source: hosted + version: "0.1.2-main.4" + matcher: + dependency: transitive + description: + name: matcher + sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2 + url: "https://pub.flutter-io.cn" + source: hosted + version: "0.12.17" + material_color_utilities: + dependency: transitive + description: + name: material_color_utilities + sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec + url: "https://pub.flutter-io.cn" + source: hosted + version: "0.11.1" + meta: + dependency: "direct overridden" + description: + name: meta + sha256: e3641ec5d63ebf0d9b41bd43201a66e3fc79a65db5f61fc181f04cd27aab950c + url: "https://pub.flutter-io.cn" + source: hosted + version: "1.16.0" + mime: + dependency: transitive + description: + name: mime + sha256: "41a20518f0cb1256669420fdba0cd90d21561e560ac240f26ef8322e45bb7ed6" + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.0.0" + minio: + dependency: transitive + description: + name: minio + sha256: "9fa3d041237d3a0dabfd14c11f6adbefe71f6973d64192f6f1fc3e174013001e" + url: "https://pub.flutter-io.cn" + source: hosted + version: "3.5.7" + mongo_dart: + dependency: "direct main" + description: + name: mongo_dart + sha256: "5e94f2f7fc779eeab677afd5d98dc63f1f35a6adb4629d4b9d25028a4d06fd21" + url: "https://pub.flutter-io.cn" + source: hosted + version: "0.10.4" + mongo_dart_query: + dependency: transitive + description: + name: mongo_dart_query + sha256: "7a0f3981c3d1df467040e5654696cb0bfde6ec6db86ba313118fb3e873cee657" + url: "https://pub.flutter-io.cn" + source: hosted + version: "5.0.2" + mqtt5_client: + dependency: transitive + description: + name: mqtt5_client + sha256: "9e15d1cd888035bcd5b204325c6678b32858ea3fc94bc1e41d5aa99d3a43f49f" + url: "https://pub.flutter-io.cn" + source: hosted + version: "4.11.0" + node_preamble: + dependency: transitive + description: + name: node_preamble + sha256: "6e7eac89047ab8a8d26cf16127b5ed26de65209847630400f9aefd7cd5c730db" + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.0.2" + package_config: + dependency: transitive + description: + name: package_config + sha256: f096c55ebb7deb7e384101542bfba8c52696c1b56fca2eb62827989ef2353bbc + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.2.0" + packages_extensions: + dependency: transitive + description: + name: packages_extensions + sha256: "1fb328695a9828c80d275ce1650a2bb5947690070de082dfa1dfac7429378daf" + url: "https://pub.flutter-io.cn" + source: hosted + version: "0.1.1" + path: + dependency: transitive + description: + name: path + sha256: "75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5" + url: "https://pub.flutter-io.cn" + source: hosted + version: "1.9.1" + path_provider: + dependency: transitive + description: + name: path_provider + sha256: "50c5dd5b6e1aaf6fb3a78b33f6aa3afca52bf903a8a5298f53101fdaee55bbcd" + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.1.5" + path_provider_android: + dependency: transitive + description: + name: path_provider_android + sha256: "4adf4fd5423ec60a29506c76581bc05854c55e3a0b72d35bb28d661c9686edf2" + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.2.15" + path_provider_foundation: + dependency: transitive + description: + name: path_provider_foundation + sha256: "4843174df4d288f5e29185bd6e72a6fbdf5a4a4602717eed565497429f179942" + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.4.1" + path_provider_linux: + dependency: transitive + description: + name: path_provider_linux + sha256: f7a1fe3a634fe7734c8d3f2766ad746ae2a2884abe22e241a8b301bf5cac3279 + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.2.1" + path_provider_platform_interface: + dependency: transitive + description: + name: path_provider_platform_interface + sha256: "88f5779f72ba699763fa3a3b06aa4bf6de76c8e5de842cf6f29e2e06476c2334" + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.1.2" + path_provider_windows: + dependency: transitive + description: + name: path_provider_windows + sha256: bd6f00dbd873bfb70d0761682da2b3a2c2fccc2b9e84c495821639601d81afe7 + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.3.0" + petitparser: + dependency: transitive + description: + name: petitparser + sha256: "07c8f0b1913bcde1ff0d26e57ace2f3012ccbf2b204e070290dad3bb22797646" + url: "https://pub.flutter-io.cn" + source: hosted + version: "6.1.0" + platform: + dependency: transitive + description: + name: platform + sha256: "5d6b1b0036a5f331ebc77c850ebc8506cbc1e9416c27e59b439f917a902a4984" + url: "https://pub.flutter-io.cn" + source: hosted + version: "3.1.6" + plugin_platform_interface: + dependency: transitive + description: + name: plugin_platform_interface + sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02" + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.1.8" + pointycastle: + dependency: transitive + description: + name: pointycastle + sha256: "4be0097fcf3fd3e8449e53730c631200ebc7b88016acecab2b0da2f0149222fe" + url: "https://pub.flutter-io.cn" + source: hosted + version: "3.9.1" + pool: + dependency: transitive + description: + name: pool + sha256: "20fe868b6314b322ea036ba325e6fc0711a22948856475e2c2b6306e8ab39c2a" + url: "https://pub.flutter-io.cn" + source: hosted + version: "1.5.1" + posix: + dependency: transitive + description: + name: posix + sha256: "6323a5b0fa688b6a010df4905a56b00181479e6d10534cecfecede2aa55add61" + url: "https://pub.flutter-io.cn" + source: hosted + version: "6.0.3" + power_extensions: + dependency: transitive + description: + name: power_extensions + sha256: ad0e8b2420090d996fe8b7fd32cdf02b9b924b6d4fc0fb0b559ff6aa5e24d5b0 + url: "https://pub.flutter-io.cn" + source: hosted + version: "0.2.3" + protobuf: + dependency: transitive + description: + name: protobuf + sha256: fbb0c37d435641d0b84813c1dad41e6fa61ddc880a320bce16b3063ecec35aa6 + url: "https://pub.flutter-io.cn" + source: hosted + version: "4.0.0" + pub_semver: + dependency: transitive + description: + name: pub_semver + sha256: "5bfcf68ca79ef689f8990d1160781b4bad40a3bd5e5218ad4076ddb7f4081585" + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.2.0" + pubspec_parse: + dependency: transitive + description: + name: pubspec_parse + sha256: "81876843eb50dc2e1e5b151792c9a985c5ed2536914115ed04e9c8528f6647b0" + url: "https://pub.flutter-io.cn" + source: hosted + version: "1.4.0" + rational: + dependency: transitive + description: + name: rational + sha256: cb808fb6f1a839e6fc5f7d8cb3b0a10e1db48b3be102de73938c627f0b636336 + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.2.3" + redis: + dependency: transitive + description: + name: redis + sha256: "4a8218ef7b0642ff499147c7a105591208259e2f55f07db0101ace7f82f66cf9" + url: "https://pub.flutter-io.cn" + source: hosted + version: "4.0.0" + sasl_scram: + dependency: transitive + description: + name: sasl_scram + sha256: a47207a436eb650f8fdcf54a2e2587b850dc3caef9973ce01f332b07a6fc9cb9 + url: "https://pub.flutter-io.cn" + source: hosted + version: "0.1.1" + saslprep: + dependency: transitive + description: + name: saslprep + sha256: "3d421d10be9513bf4459c17c5e70e7b8bc718c9fc5ad4ba5eb4f5fd27396f740" + url: "https://pub.flutter-io.cn" + source: hosted + version: "1.0.3" + shelf: + dependency: transitive + description: + name: shelf + sha256: e7dd780a7ffb623c57850b33f43309312fc863fb6aa3d276a754bb299839ef12 + url: "https://pub.flutter-io.cn" + source: hosted + version: "1.4.2" + shelf_multipart: + dependency: "direct main" + description: + name: shelf_multipart + sha256: "6f195cd9a6a0e44887cf00ed9943551de3a3ce889118690bd461b9cebf20382f" + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.0.1" + shelf_packages_handler: + dependency: transitive + description: + name: shelf_packages_handler + sha256: "89f967eca29607c933ba9571d838be31d67f53f6e4ee15147d5dc2934fee1b1e" + url: "https://pub.flutter-io.cn" + source: hosted + version: "3.0.2" + shelf_router: + dependency: transitive + description: + name: shelf_router + sha256: f5e5d492440a7fb165fe1e2e1a623f31f734d3370900070b2b1e0d0428d59864 + url: "https://pub.flutter-io.cn" + source: hosted + version: "1.1.4" + shelf_static: + dependency: transitive + description: + name: shelf_static + sha256: c87c3875f91262785dade62d135760c2c69cb217ac759485334c5857ad89f6e3 + url: "https://pub.flutter-io.cn" + source: hosted + version: "1.1.3" + shelf_web_socket: + dependency: transitive + description: + name: shelf_web_socket + sha256: cc36c297b52866d203dbf9332263c94becc2fe0ceaa9681d07b6ef9807023b67 + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.0.1" + sky_engine: + dependency: transitive + description: flutter + source: sdk + version: "0.0.99" + source_gen: + dependency: transitive + description: + name: source_gen + sha256: "14658ba5f669685cd3d63701d01b31ea748310f7ab854e471962670abcf57832" + url: "https://pub.flutter-io.cn" + source: hosted + version: "1.5.0" + source_helper: + dependency: transitive + description: + name: source_helper + sha256: "86d247119aedce8e63f4751bd9626fc9613255935558447569ad42f9f5b48b3c" + url: "https://pub.flutter-io.cn" + source: hosted + version: "1.3.5" + source_map_stack_trace: + dependency: transitive + description: + name: source_map_stack_trace + sha256: c0713a43e323c3302c2abe2a1cc89aa057a387101ebd280371d6a6c9fa68516b + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.1.2" + source_maps: + dependency: transitive + description: + name: source_maps + sha256: "190222579a448b03896e0ca6eca5998fa810fda630c1d65e2f78b3f638f54812" + url: "https://pub.flutter-io.cn" + source: hosted + version: "0.10.13" + source_span: + dependency: transitive + description: + name: source_span + sha256: "254ee5351d6cb365c859e20ee823c3bb479bf4a293c22d17a9f1bf144ce86f7c" + url: "https://pub.flutter-io.cn" + source: hosted + version: "1.10.1" + sprintf: + dependency: transitive + description: + name: sprintf + sha256: "1fc9ffe69d4df602376b52949af107d8f5703b77cda567c4d7d86a0693120f23" + url: "https://pub.flutter-io.cn" + source: hosted + version: "7.0.0" + stack_trace: + dependency: transitive + description: + name: stack_trace + sha256: "8b27215b45d22309b5cddda1aa2b19bdfec9df0e765f2de506401c071d38d1b1" + url: "https://pub.flutter-io.cn" + source: hosted + version: "1.12.1" + stream_channel: + dependency: transitive + description: + name: stream_channel + sha256: "969e04c80b8bcdf826f8f16579c7b14d780458bd97f56d107d3950fdbeef059d" + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.1.4" + stream_transform: + dependency: transitive + description: + name: stream_transform + sha256: ad47125e588cfd37a9a7f86c7d6356dde8dfe89d071d293f80ca9e9273a33871 + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.1.1" + string_scanner: + dependency: transitive + description: + name: string_scanner + sha256: "921cd31725b72fe181906c6a94d987c78e3b98c2e205b397ea399d4054872b43" + url: "https://pub.flutter-io.cn" + source: hosted + version: "1.4.1" + term_glyph: + dependency: transitive + description: + name: term_glyph + sha256: "7f554798625ea768a7518313e58f83891c7f5024f88e46e7182a4558850a4b8e" + url: "https://pub.flutter-io.cn" + source: hosted + version: "1.2.2" + test: + dependency: "direct dev" + description: + name: test + sha256: "301b213cd241ca982e9ba50266bd3f5bd1ea33f1455554c5abb85d1be0e2d87e" + url: "https://pub.flutter-io.cn" + source: hosted + version: "1.25.15" + test_api: + dependency: transitive + description: + name: test_api + sha256: fb31f383e2ee25fbbfe06b40fe21e1e458d14080e3c67e7ba0acfde4df4e0bbd + url: "https://pub.flutter-io.cn" + source: hosted + version: "0.7.4" + test_core: + dependency: transitive + description: + name: test_core + sha256: "84d17c3486c8dfdbe5e12a50c8ae176d15e2a771b96909a9442b40173649ccaa" + url: "https://pub.flutter-io.cn" + source: hosted + version: "0.6.8" + timing: + dependency: transitive + description: + name: timing + sha256: "62ee18aca144e4a9f29d212f5a4c6a053be252b895ab14b5821996cff4ed90fe" + url: "https://pub.flutter-io.cn" + source: hosted + version: "1.0.2" + typed_data: + dependency: transitive + description: + name: typed_data + sha256: f9049c039ebfeb4cf7a7104a675823cd72dba8297f264b6637062516699fa006 + url: "https://pub.flutter-io.cn" + source: hosted + version: "1.4.0" + universal_html: + dependency: transitive + description: + name: universal_html + sha256: "56536254004e24d9d8cfdb7dbbf09b74cf8df96729f38a2f5c238163e3d58971" + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.2.4" + universal_io: + dependency: transitive + description: + name: universal_io + sha256: "1722b2dcc462b4b2f3ee7d188dad008b6eb4c40bbd03a3de451d82c78bba9aad" + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.2.2" + unorm_dart: + dependency: transitive + description: + name: unorm_dart + sha256: "23d8bf65605401a6a32cff99435fed66ef3dab3ddcad3454059165df46496a3b" + url: "https://pub.flutter-io.cn" + source: hosted + version: "0.3.0" + uuid: + dependency: transitive + description: + name: uuid + sha256: a5be9ef6618a7ac1e964353ef476418026db906c4facdedaa299b7a2e71690ff + url: "https://pub.flutter-io.cn" + source: hosted + version: "4.5.1" + vector_math: + dependency: transitive + description: + name: vector_math + sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.1.4" + vm_service: + dependency: transitive + description: + name: vm_service + sha256: ddfa8d30d89985b96407efce8acbdd124701f96741f2d981ca860662f1c0dc02 + url: "https://pub.flutter-io.cn" + source: hosted + version: "15.0.0" + vy_string_utils: + dependency: transitive + description: + name: vy_string_utils + sha256: "03f4f2ebba283b32623459fa9c47d5c70e085253c7891f5ef7d4fd539c41c078" + url: "https://pub.flutter-io.cn" + source: hosted + version: "0.4.6" + watcher: + dependency: transitive + description: + name: watcher + sha256: "69da27e49efa56a15f8afe8f4438c4ec02eff0a117df1b22ea4aad194fe1c104" + url: "https://pub.flutter-io.cn" + source: hosted + version: "1.1.1" + web: + dependency: transitive + description: + name: web + sha256: "868d88a33d8a87b18ffc05f9f030ba328ffefba92d6c127917a2ba740f9cfe4a" + url: "https://pub.flutter-io.cn" + source: hosted + version: "1.1.1" + web_socket: + dependency: transitive + description: + name: web_socket + sha256: "3c12d96c0c9a4eec095246debcea7b86c0324f22df69893d538fcc6f1b8cce83" + url: "https://pub.flutter-io.cn" + source: hosted + version: "0.1.6" + web_socket_channel: + dependency: transitive + description: + name: web_socket_channel + sha256: "0b8e2457400d8a859b7b2030786835a28a8e80836ef64402abef392ff4f1d0e5" + url: "https://pub.flutter-io.cn" + source: hosted + version: "3.0.2" + webkit_inspection_protocol: + dependency: transitive + description: + name: webkit_inspection_protocol + sha256: "87d3f2333bb240704cd3f1c6b5b7acd8a10e7f0bc28c28dcf14e782014f4a572" + url: "https://pub.flutter-io.cn" + source: hosted + version: "1.2.1" + win32: + dependency: transitive + description: + name: win32 + sha256: daf97c9d80197ed7b619040e86c8ab9a9dad285e7671ee7390f9180cc828a51e + url: "https://pub.flutter-io.cn" + source: hosted + version: "5.10.1" + xdg_directories: + dependency: transitive + description: + name: xdg_directories + sha256: "7a3f37b05d989967cdddcbb571f1ea834867ae2faa29725fd085180e0883aa15" + url: "https://pub.flutter-io.cn" + source: hosted + version: "1.1.0" + xml: + dependency: transitive + description: + name: xml + sha256: b015a8ad1c488f66851d762d3090a21c600e479dc75e68328c52774040cf9226 + url: "https://pub.flutter-io.cn" + source: hosted + version: "6.5.0" + yaml: + dependency: transitive + description: + name: yaml + sha256: b9da305ac7c39faa3f030eccd175340f968459dae4af175130b3fc47e40d76ce + url: "https://pub.flutter-io.cn" + source: hosted + version: "3.1.3" +sdks: + dart: ">=3.5.4 <4.0.0" + flutter: ">=3.24.0" diff --git a/pubspec.yaml b/pubspec.yaml new file mode 100644 index 0000000..33d3730 --- /dev/null +++ b/pubspec.yaml @@ -0,0 +1,42 @@ +name: vsbs_room +description: "A new Flutter project." +publish_to: 'none' + +version: 1.0.0+1 + +environment: + sdk: ^3.5.4 + + +dependencies: + flutter: + sdk: flutter + ef: + git: + url: https://gitea.wslpc.real.he-info.cn:94/flutter/ef.git + ref: main + args: ^2.4.0 + EasyDartModule: + git: + url: https://git.he-info.cn/qmqz/easy_dart_module.git + ref: master + cupertino_icons: ^1.0.8 + mongo_dart: ^0.10.4 + dart_jsonwebtoken: ^2.14.2 + intl: ^0.20.1 + shelf_multipart: ^2.0.1 + +dev_dependencies: + http: ^1.1.0 + lints: ^4.0.0 + test: ^1.24.0 + flutter_lints: ^4.0.0 + build_runner: ^2.4.6 + json_serializable: ^6.8.0 + +dependency_overrides: + meta: ^1.16.0 + collection: ^1.19.0 + +flutter: + uses-material-design: true