diff --git a/.dockerignore b/.dockerignore
new file mode 100644
index 0000000..3729ff0
--- /dev/null
+++ b/.dockerignore
@@ -0,0 +1,25 @@
+**/.classpath
+**/.dockerignore
+**/.env
+**/.git
+**/.gitignore
+**/.project
+**/.settings
+**/.toolstarget
+**/.vs
+**/.vscode
+**/*.*proj.user
+**/*.dbmdl
+**/*.jfm
+**/azds.yaml
+**/bin
+**/charts
+**/docker-compose*
+**/Dockerfile*
+**/node_modules
+**/npm-debug.log
+**/obj
+**/secrets.dev.yaml
+**/values.dev.yaml
+LICENSE
+README.md
\ No newline at end of file
diff --git a/langguanApi.sln b/langguanApi.sln
new file mode 100644
index 0000000..dfe9989
--- /dev/null
+++ b/langguanApi.sln
@@ -0,0 +1,25 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.7.34221.43
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "langguanApi", "langguanApi\langguanApi.csproj", "{99745E10-D0AE-46BC-B23E-A24483532FEF}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {99745E10-D0AE-46BC-B23E-A24483532FEF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {99745E10-D0AE-46BC-B23E-A24483532FEF}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {99745E10-D0AE-46BC-B23E-A24483532FEF}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {99745E10-D0AE-46BC-B23E-A24483532FEF}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {9FA08BD4-39EF-4F6E-B3C9-990729D8ED1A}
+ EndGlobalSection
+EndGlobal
diff --git a/langguanApi.xml b/langguanApi.xml
new file mode 100644
index 0000000..ae06537
--- /dev/null
+++ b/langguanApi.xml
@@ -0,0 +1,1255 @@
+
+
+
+ langguanApi
+
+
+
+
+ 缓存管理
+
+
+
+
+ 缓存数据
+
+
+
+
+ 缓存时间秒,0=int.max ,
+
+
+
+
+ sub
+
+
+
+
+ 缓存天气信息
+
+
+
+
+ redis 服务地址
+
+
+
+
+ redis 端口
+
+
+
+
+ redis 连接密码
+
+
+
+
+ 自定义Key
+
+
+
+
+ 默认数据库索引
+
+
+
+
+ 转换数据库连接字符串
+
+
+
+
+
+
+
+
+
+
+
+
+ 列表
+
+
+
+
+
+
+ 新加
+
+
+
+
+
+
+ 删除
+
+
+
+
+
+
+ 更新
+
+
+
+
+
+
+ 获取指定设备的历史数据
+
+
+
+
+
+
+ 首页view
+
+
+
+
+
+ 注入生命周期
+
+
+
+
+ Transient
+
+
+
+
+ Scoped
+
+
+
+
+ Singleton
+
+
+
+
+
+
+
+
+
+ 注入类型
+
+
+
+
+ 服务注入
+
+
+
+
+ 服务注入
+
+ 注入类型
+
+
+
+ 服务注入
+
+ 服务的接口类型
+ 注入的类型
+
+
+
+ 自动注入
+
+
+
+
+
+
+
+
+
+
+
+ 服务自动注入
+
+ 需要自动注入服务的服务集合
+ 应用于每个Assembly的筛选函数
+ 指定的注入类型不在可注入的范围内
+ 指定注入的类型未实现任何服务
+ 输入的参数错误:1、注入的类型未实现指定的服务。2、指定的服务不是Interface类型
+ 自动注入服务后的服务集合
+
+
+
+ add redis service
+
+
+
+
+
+
+
+
+
+
+
+
+ 日志
+
+
+
+
+ 构参
+
+
+
+
+
+ 重写
+
+
+
+
+
+
+ Api返回结果
+
+
+
+
+ code=0成功。1失败
+
+
+
+
+ 结果
+
+
+
+
+ 消息
+
+
+
+
+ base model
+
+
+
+
+ //标记主键
+
+
+
+
+ //指明数据库中字段名为CreateDateTime
+
+
+
+
+ 标记删除
+
+
+
+
+ basemodel
+
+
+
+
+
+
+
+
+
+ a34004=PM2.5浓度,a34002=PM10,a34001=tsp浓度
+
+
+
+
+ 命令编码
+
+
+
+
+ 心跳包
+
+
+
+
+ 工控机向上位机上传分钟数据
+
+
+
+
+ 工控机向上位机上传小时数据
+
+
+
+
+ 工控机向上位机上传日数据
+
+
+
+
+ 工控机向上位机上传实时数据
+
+
+
+
+ 上位机向工控机返回应答
+
+
+
+
+ CP指令
+
+
+
+
+ 数据时间信息
+
+
+
+
+ 污染物信息
+
+
+
+
+ 解析
+
+
+
+
+
+
+ 序列化
+
+
+
+
+
+ 数据段
+
+
+
+
+ 默认应答系统编码
+
+
+
+
+ 请求编号
+
+
+ yyyyMMddHHmmssZZZ 取当前系统时间, 精确到毫秒值, 用来唯一标识一次命令交互
+
+
+
+
+ 系统编号
+
+
+
+
+ 命令编码
+ 详见附录 2
+
+
+
+
+ 访问密码
+ 对接时提供给各个对接站点
+
+
+
+
+ 设备唯一标识
+ 对接时提供给各个对接站点
+
+
+
+
+ 拆分包及应答标志
+
+
+
+
+ 总包数
+ PNUM 指示本次通讯中总共包含的包数,注:不分包时可以没有本字段,与标志位有关
+
+
+
+
+ 包号
+ PNO 指示当前数据包的包号,注: 不分包时可以没有本字段,与标志位有关
+
+
+
+
+ 指令
+ CP=&&数据区&&( 详见表 5 )
+
+
+
+
+ 解析
+
+
+
+
+
+
+
+ 序列化
+
+
+
+
+
+ 设备信息
+
+
+
+
+ HJ212_2017
+
+
+
+
+ 数据帧头
+
+
+
+
+ 数据长度
+
+
+
+
+ 数据头
+
+
+
+
+
+
+
+
+
+ CRC校验
+
+
+
+
+
+
+
+
+
+
+
+ 判断数据是否通过校验
+
+ 原始数据
+ 是否通过
+
+
+
+ 污染物因子编码
+
+
+
+
+ 设备ID
+
+
+
+
+ PM2.5浓度
+
+
+
+
+ PM10浓度
+
+
+
+
+ TSP浓度
+
+
+
+
+ 温度
+
+
+
+
+ 湿度
+
+
+
+
+ 大气压
+
+
+
+
+ 风速
+
+
+
+
+ 风向
+
+
+
+
+ 检测仪器数据标记
+
+
+
+
+ 正常(有效)
+ 在线监控(监测)仪器仪表工作正常
+
+
+
+
+ 无效
+ 在线监控(监测)仪器仪表停运
+
+
+
+
+ 无效
+ 在线监控(监测)仪器仪表处于维护期间产生的数据
+
+
+
+
+ 有效
+ 手工输入的设定值
+
+
+
+
+ 无效
+ 在线监控(监测)仪器仪表故障
+
+
+
+
+ 无效
+ 在线监控(监测)仪器仪表处于校准状态
+
+
+
+
+ 无效
+ 在线监控(监测)仪器仪表采样数值超过测量上限
+
+
+
+
+ 无效
+ 在线监控(监测)仪器仪表与数采仪通讯异常
+
+
+
+
+ 无效(有效数据不足)
+
+
+ 按照5分钟、1小时均值计算要求,所获取的有效数据个数不足
+
+
+
+
+ 通讯包
+
+
+
+
+ 默认头
+
+
+
+
+ 默认尾
+
+
+
+
+ 包头
+
+
+
+
+ 数据段长度
+
+
+
+
+ 数据段
+
+
+
+
+ CRC校验码
+
+
+
+
+ 包尾
+
+
+
+
+ CRC16校验
+
+ 需要校验的字符串
+ CRC16 校验码
+
+
+
+ 解析
+
+
+
+
+
+
+
+ 序列化
+
+
+
+
+
+ 拆分包及应答标志
+
+
+
+
+ 命令是否应答:1-应答,0-不应答
+
+
+
+
+ 是否有数据包序号:1 - 数据包中包含包号和总包数两部分,0 - 数据包中不包含包号和总包数两部分
+
+
+
+
+ 标准版本号
+ 000000 表示标准 HJ/T212-2005
+ 000001 表示本次标准修订版本号
+
+
+
+
+ 解析
+
+
+
+
+
+
+ 序列化
+
+
+
+
+
+ 获取取第index位
+
+
+ index从0开始
+
+
+
+
+
+
+
+ 将第index位设为1
+
+
+ index从0开始
+
+
+
+
+
+
+
+ 将第index位设为0
+
+
+ index从0开始
+
+
+
+
+
+
+
+ 将第index位取反
+
+
+ index从0开始
+
+
+
+
+
+
+
+ 污染物信息
+
+
+
+
+ 约定的无效值
+
+
+
+
+ 污染物因子编码
+
+
+
+
+ 污染物实时采样数据
+
+
+ 默认值为约定的无效值
+
+
+
+
+ 污染物指定时问内平均值
+
+
+ 默认值为约定的无效值
+
+
+
+
+ 污染物指定时问内最大值
+
+
+ 默认值为约定的无效值
+
+
+
+
+ 污染物指定时问内最小值
+
+
+ 默认值为约定的无效值
+
+
+
+
+ 污染物指定时问内累计值
+
+
+ 默认值为约定的无效值
+
+
+
+
+ 检测仪器数据标记
+
+
+
+
+ 回应代码集
+
+
+
+
+ 执行成功
+
+
+
+
+ 执行失败,但不知道原因
+
+
+
+
+ 执行失败,命令请求条件错误
+
+
+
+
+ 通讯超时
+
+
+
+
+ 系统繁忙不能执行
+
+
+
+
+ 系统时间异常
+
+
+
+
+ 没有数据
+
+
+
+
+ 心跳包
+
+
+
+
+ 新加
+
+
+
+
+
+
+ 分页取数据
+
+
+
+
+
+
+ 构造
+
+
+
+
+
+
+ 获取所有
+
+
+
+
+
+ 获取单个
+
+
+
+
+
+
+ 创建
+
+
+
+
+
+
+ 更新
+
+
+
+
+
+
+ 删除
+
+
+
+
+
+ 根据id删除
+
+
+
+
+
+ 取列表
+
+
+
+
+
+ 取单条
+
+
+
+
+
+
+ 新增
+
+
+
+
+
+
+ 新增
+
+
+
+
+
+
+ 更新
+
+
+
+
+
+
+
+ 删除
+
+
+
+
+
+
+ 表达式取数据
+
+
+
+
+
+
+ filter查找
+
+
+
+
+
+
+ filterdefinition
+
+
+
+
+
+
+ 是否存在
+
+
+
+
+
+
+ 分页取数据
+
+
+
+
+
+
+
+ 新加
+
+
+
+
+
+
+ 是否存在
+
+
+
+
+
+
+ 更新
+
+
+
+
+
+
+ remove
+
+
+
+
+
+
+ 分页取数据
+
+
+
+
+
+
+ 新加数据
+
+
+
+
+
+
+
+ 最近10个小时的数据
+
+
+
+
+
+
+ 按设备号查询数据
+
+
+
+
+
+
+ 实时的数据
+
+
+
+
+
+ 缓冲器
+
+
+
+
+ 最大连接数
+
+
+
+
+ 服务IP地址
+
+
+
+
+ 服务端口号
+
+
+
+
+ 客户端列表
+
+
+
+
+ IP终端
+
+
+
+
+ 服务端Socket
+
+
+
+
+ 启动服务
+
+
+
+
+
+ 收到数据事件
+
+
+
+
+ 发送数据事件
+
+
+
+
+
+
+
+
+
+
+ 引发收到数据事件
+
+
+
+
+ 引发发送数据事件
+
+
+
+
+
+
+
+ 获取分包缓存
+
+
+
+
+
+
+
+
+
+
+ 应答
+
+
+
+
+ HomeService
+
+
+
+
+ HomeService
+
+
+
+
+
+
+ view
+
+
+
+
+
+ ping service
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ping
+
+
+
+
+
+
+ 爬气象局的天气数据%
+
+
+
+
+
+ 54511
+
+
+
+
+ 北京
+
+
+
+
+ 中国, 北京, 北京
+
+
+
+
+ Precipitation
+
+
+
+
+ Temperature
+
+
+
+
+ Pressure
+
+
+
+
+ Humidity
+
+
+
+
+ 东北风
+
+
+
+
+ WindDirectionDegree
+
+
+
+
+ WindSpeed
+
+
+
+
+ 微风
+
+
+
+
+
+
+
+
+
+ Location
+
+
+
+
+ Now
+
+
+
+
+ Alarm
+
+
+
+
+ 2024/01/15 10:05
+
+
+
+
+ success
+
+
+
+
+ Code
+
+
+
+
+ Data
+
+
+
+
+ 暂存服务
+
+
+
+
diff --git a/langguanApi/.config/dotnet-tools.json b/langguanApi/.config/dotnet-tools.json
new file mode 100644
index 0000000..b0e38ab
--- /dev/null
+++ b/langguanApi/.config/dotnet-tools.json
@@ -0,0 +1,5 @@
+{
+ "version": 1,
+ "isRoot": true,
+ "tools": {}
+}
\ No newline at end of file
diff --git a/langguanApi/Common/CacheManager.cs b/langguanApi/Common/CacheManager.cs
new file mode 100644
index 0000000..4a7637d
--- /dev/null
+++ b/langguanApi/Common/CacheManager.cs
@@ -0,0 +1,41 @@
+using langguanApi.Common.Redis;
+using langguanApi.Extensions.AutoDI;
+using Newtonsoft.Json;
+using StackExchange.Redis;
+
+namespace langguanApi.Common
+{
+ ///
+ /// 缓存管理
+ ///
+ [ServiceInjection(InjectionType.Singleton)]
+ public class CacheManager
+ {
+ private readonly IDatabase _redisDatabase;
+ public CacheManager(RedisHelper redisHelper)
+ {
+ _redisDatabase = redisHelper._database;
+ }
+ ///
+ /// 缓存数据
+ ///
+ ///
+ ///
+ ///
+ /// 缓存时间秒,0=int.max ,
+ ///
+ public async Task GetConvertVale(string cacheKey, Func> dataFetcher, int seconds = 0)
+ {
+ var cacheData = await _redisDatabase.StringGetAsync(cacheKey);
+ if (cacheData.IsNull)
+ {
+ var temp = await dataFetcher();
+ cacheData = JsonConvert.SerializeObject(temp);
+ seconds = seconds == 0 ? int.MaxValue : seconds;
+ await _redisDatabase.StringSetAsync(cacheKey, cacheData, TimeSpan.FromSeconds(seconds), When.NotExists);
+ return temp;
+ }
+ return JsonConvert.DeserializeObject(cacheData);
+ }
+ }
+}
diff --git a/langguanApi/Common/Redis/RedisHelper.cs b/langguanApi/Common/Redis/RedisHelper.cs
new file mode 100644
index 0000000..22fa2b4
--- /dev/null
+++ b/langguanApi/Common/Redis/RedisHelper.cs
@@ -0,0 +1,20 @@
+using StackExchange.Redis;
+
+namespace langguanApi.Common.Redis
+{
+ public class RedisHelper
+ {
+ public IDatabase _database;
+ ///
+ /// sub
+ ///
+ public ISubscriber _subscriber;
+ public RedisHelper()
+ {
+ // var con = RedisOptions.Default.GetConnect();
+ IConnectionMultiplexer connection = ConnectionMultiplexer.Connect(RedisOptions.Default.GetConnect());
+ _subscriber = connection.GetSubscriber();
+ _database = connection.GetDatabase(RedisOptions.Default.Index);
+ }
+ }
+}
diff --git a/langguanApi/Common/Redis/RedisKeylist.cs b/langguanApi/Common/Redis/RedisKeylist.cs
new file mode 100644
index 0000000..295fbd5
--- /dev/null
+++ b/langguanApi/Common/Redis/RedisKeylist.cs
@@ -0,0 +1,11 @@
+namespace langguanApi.Common.Redis
+{
+ public class RedisKeylist
+ {
+ public static string UserLoginInfo = "UserLoginInfo";
+ ///
+ /// 缓存天气信息
+ ///
+ public static string Weather = "weather";
+ }
+}
diff --git a/langguanApi/Common/Redis/RedisOptions.cs b/langguanApi/Common/Redis/RedisOptions.cs
new file mode 100644
index 0000000..bb15439
--- /dev/null
+++ b/langguanApi/Common/Redis/RedisOptions.cs
@@ -0,0 +1,54 @@
+namespace langguanApi.Common.Redis
+{
+ public class RedisOptions
+ {
+ public static readonly RedisOptions Default = new RedisOptions();
+ public RedisOptions()
+ {
+ this.Server = null;
+ this.Port = 6379;
+ this.Password = null;
+ this.Key = null;
+ this.Index = 0;
+ }
+
+ ///
+ /// redis 服务地址
+ ///
+ public string Server { get; set; }
+
+ ///
+ /// redis 端口
+ ///
+ public int Port { get; set; }
+
+ ///
+ /// redis 连接密码
+ ///
+ public string Password { get; set; }
+
+ ///
+ /// 自定义Key
+ ///
+ public string Key { get; set; }
+
+ ///
+ /// 默认数据库索引
+ ///
+ public int Index { get; set; }
+ public string Connection { get; set; }
+
+ ///
+ /// 转换数据库连接字符串
+ ///
+ ///
+ ///
+ public string GetConnect()
+ {
+ if (string.IsNullOrWhiteSpace(Password))
+ return $"{Server}";
+ else
+ return $"{Server},password={Password}";
+ }
+ }
+}
diff --git a/langguanApi/Controllers/DeviceController.cs b/langguanApi/Controllers/DeviceController.cs
new file mode 100644
index 0000000..0807df7
--- /dev/null
+++ b/langguanApi/Controllers/DeviceController.cs
@@ -0,0 +1,67 @@
+using langguanApi.Model;
+using langguanApi.Model.Dto;
+using langguanApi.Service;
+using Microsoft.AspNetCore.Mvc;
+
+namespace langguanApi.Controllers
+{
+ [Route("api/[controller]/[action]")]
+ [ApiController]
+ public class DeviceController : ControllerBase
+ {
+ private readonly DeviceService _deviceService;
+ ///
+ ///
+ ///
+ ///
+ public DeviceController(DeviceService deviceService)
+ {
+ _deviceService = deviceService;
+ }
+ ///
+ /// 列表
+ ///
+ ///
+ ///
+ [HttpGet]
+ public async Task Getpage([FromQuery] reqpage input)
+ {
+ var result = await _deviceService.GetPage(input);
+ return Ok(result);
+ }
+ ///
+ ///新加
+ ///
+ ///
+ ///
+ [HttpPost]
+ public async Task Addd([FromBody] DeviceDto input)
+ {
+ var result = await _deviceService.Add(input);
+ return Ok(result);
+ }
+ ///
+ /// 删除
+ ///
+ ///
+ ///
+ [HttpDelete]
+ public async Task Remove(IEnumerable ids)
+ {
+ var result = await _deviceService.remove(ids);
+ return Ok(result);
+ }
+ ///
+ /// 更新
+ ///
+ ///
+ ///
+ [HttpPut]
+ public async Task update([FromBody] DeviceDto input)
+ {
+ var result = await _deviceService.update(input);
+ return Ok(result);
+ }
+
+ }
+}
diff --git a/langguanApi/Controllers/HJ212Controller.cs b/langguanApi/Controllers/HJ212Controller.cs
new file mode 100644
index 0000000..316db85
--- /dev/null
+++ b/langguanApi/Controllers/HJ212Controller.cs
@@ -0,0 +1,30 @@
+using langguanApi.Service;
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc;
+
+namespace langguanApi.Controllers
+{
+ [Route("api/[controller]")]
+ [ApiController]
+ public class HJ212Controller : ControllerBase
+ {
+ private readonly Hj212Service _hj212Service;
+
+ public HJ212Controller(Hj212Service hj212Service)
+ {
+ _hj212Service = hj212Service;
+ }
+
+ ///
+ /// 获取指定设备的历史数据
+ ///
+ ///
+ ///
+ [HttpGet]
+ public async Task Get(string mn)
+ {
+ var resul = await _hj212Service.GetViewByDeviceMn(mn);
+ return Ok(resul);
+ }
+ }
+}
diff --git a/langguanApi/Controllers/HomeController.cs b/langguanApi/Controllers/HomeController.cs
new file mode 100644
index 0000000..c1797f2
--- /dev/null
+++ b/langguanApi/Controllers/HomeController.cs
@@ -0,0 +1,45 @@
+using langguanApi.Model;
+using langguanApi.Service;
+using langguanApi.Service.HJ212;
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc;
+using System.Text;
+
+namespace langguanApi.Controllers
+{
+ [Route("api/[controller]")]
+ [ApiController]
+ public class HomeController : ControllerBase
+ {
+ private readonly HomeService _homeService;
+ public HomeController(HomeService homeService)
+ {
+ _homeService = homeService;
+ }
+ ///
+ /// 首页view
+ ///
+ ///
+ [HttpGet("view")]
+ public async Task View()
+ {
+ return Ok( await _homeService.View() );
+
+ }
+ [HttpGet("test")]
+ ///
+ /// test
+ ///
+ /// 数字
+ /// 字符串
+ ///
+ public async Task test(int num = 1, string key = "")
+ {
+ // string rawText = "数据报:##0250QN=20240424224800000;ST=22;CN=2011;PW=123456;MN=LGYC022024690001;Flag=5;CP=&&DataTime=20240424224800;a34001-Rtd=356.2";
+ //NetPackage netPackage = NetPackage.Parse(rawText, null);
+ //((NetServer)Server).RaiseReceivedData(this, netPackage, rawText);
+ return Ok();
+ }
+
+ }
+}
diff --git a/langguanApi/Dockerfile b/langguanApi/Dockerfile
new file mode 100644
index 0000000..bdf067d
--- /dev/null
+++ b/langguanApi/Dockerfile
@@ -0,0 +1,21 @@
+#See https://aka.ms/customizecontainer to learn how to customize your debug container and how Visual Studio uses this Dockerfile to build your images for faster debugging.
+
+FROM mcr.microsoft.com/dotnet/aspnet:6.0-alpine AS base
+WORKDIR /app
+EXPOSE 80
+
+#FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
+#WORKDIR /src
+#COPY ["langguanApi/langguanApi.csproj", "langguanApi/"]
+#RUN dotnet restore "langguanApi/langguanApi.csproj"
+COPY . .
+#WORKDIR "/src/langguanApi"
+#RUN dotnet build "langguanApi.csproj" -c Release -o /app/build
+#
+#FROM build AS publish
+#RUN dotnet publish "langguanApi.csproj" -c Release -o /app/publish /p:UseAppHost=false
+#
+#FROM base AS final
+#WORKDIR /app
+#COPY --from=publish /app/publish .
+ENTRYPOINT ["dotnet", "langguanApi.dll"]
\ No newline at end of file
diff --git a/langguanApi/Extensions/AutoDI/InjectionType.cs b/langguanApi/Extensions/AutoDI/InjectionType.cs
new file mode 100644
index 0000000..7b88f2b
--- /dev/null
+++ b/langguanApi/Extensions/AutoDI/InjectionType.cs
@@ -0,0 +1,23 @@
+namespace langguanApi.Extensions.AutoDI
+{
+ ///
+ /// 注入生命周期
+ ///
+ public enum InjectionType
+ {
+ ///
+ /// Transient
+ ///
+ Transient,
+
+ ///
+ /// Scoped
+ ///
+ Scoped,
+
+ ///
+ /// Singleton
+ ///
+ Singleton
+ }
+}
diff --git a/langguanApi/Extensions/AutoDI/ServiceInjectionAttribute.cs b/langguanApi/Extensions/AutoDI/ServiceInjectionAttribute.cs
new file mode 100644
index 0000000..72ab0b2
--- /dev/null
+++ b/langguanApi/Extensions/AutoDI/ServiceInjectionAttribute.cs
@@ -0,0 +1,43 @@
+namespace langguanApi.Extensions.AutoDI
+{
+ [AttributeUsage(AttributeTargets.Class)]
+ public class ServiceInjectionAttribute : Attribute
+ {
+ ///
+ ///
+ ///
+ public Type InterfaceType { get; set; }
+
+ ///
+ /// 注入类型
+ ///
+ public InjectionType InjectionType { get; }
+
+ ///
+ /// 服务注入
+ ///
+ public ServiceInjectionAttribute()
+ {
+ InjectionType = InjectionType.Scoped;
+ }
+
+ ///
+ /// 服务注入
+ ///
+ /// 注入类型
+ public ServiceInjectionAttribute(InjectionType injectionType)
+ {
+ InjectionType = injectionType;
+ }
+ ///
+ /// 服务注入
+ ///
+ /// 服务的接口类型
+ /// 注入的类型
+ public ServiceInjectionAttribute(Type interfaceType, InjectionType injectionType)
+ {
+ InterfaceType = interfaceType;
+ InjectionType = injectionType;
+ }
+ }
+}
diff --git a/langguanApi/Extensions/AutoDI/ServicesAutoInjectionExtension.cs b/langguanApi/Extensions/AutoDI/ServicesAutoInjectionExtension.cs
new file mode 100644
index 0000000..cb1719a
--- /dev/null
+++ b/langguanApi/Extensions/AutoDI/ServicesAutoInjectionExtension.cs
@@ -0,0 +1,70 @@
+using System.Reflection;
+
+namespace langguanApi.Extensions.AutoDI
+{
+ ///
+ /// 自动注入
+ ///
+ public static class AutoDIExtensions
+ {
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static IServiceCollection ServicesAutoInjectionExtension(this IServiceCollection serviceCollection)
+ {
+ var directory = AppDomain.CurrentDomain.BaseDirectory;
+ var types = Directory.GetFiles(directory, "*.dll", SearchOption.TopDirectoryOnly)
+ .Select(Assembly.LoadFrom)
+ .SelectMany(a => a.GetTypes());
+ Injection(serviceCollection, types);
+ return serviceCollection;
+ }
+ ///
+ /// 服务自动注入
+ ///
+ /// 需要自动注入服务的服务集合
+ /// 应用于每个Assembly的筛选函数
+ /// 指定的注入类型不在可注入的范围内
+ /// 指定注入的类型未实现任何服务
+ /// 输入的参数错误:1、注入的类型未实现指定的服务。2、指定的服务不是Interface类型
+ /// 自动注入服务后的服务集合
+ public static IServiceCollection ServicesAutoInjection(this IServiceCollection serviceCollection, Func selector)
+ {
+ var directory = AppDomain.CurrentDomain.BaseDirectory;
+ var types = Directory.GetFiles(directory, "*.dll", SearchOption.TopDirectoryOnly)
+ .Select(Assembly.LoadFrom)
+ .Where(selector)
+ .SelectMany(a => a.GetTypes());
+
+ Injection(serviceCollection, types);
+
+ return serviceCollection;
+ }
+ // 注入逻辑
+ private static void Injection(IServiceCollection serviceCollection, IEnumerable types)
+ {
+ foreach (var type in types)
+ {
+ var attribute = type.GetCustomAttribute();
+ if (attribute == null) continue;
+ switch (attribute.InjectionType)
+ {
+ case InjectionType.Transient:
+ serviceCollection.AddTransient(type);
+ break;
+ case InjectionType.Scoped:
+ serviceCollection.AddScoped(type);
+ break;
+ case InjectionType.Singleton:
+ serviceCollection.AddSingleton(type);
+ break;
+ default:
+ throw new ArgumentOutOfRangeException();
+ }
+ }
+
+ }
+ }
+}
diff --git a/langguanApi/Extensions/RedisExtension.cs b/langguanApi/Extensions/RedisExtension.cs
new file mode 100644
index 0000000..fd53aac
--- /dev/null
+++ b/langguanApi/Extensions/RedisExtension.cs
@@ -0,0 +1,21 @@
+using langguanApi.Common.Redis;
+
+namespace langguanApi.Extensions
+{
+ public static class RedisExtension
+ {
+ ///
+ /// add redis service
+ ///
+ ///
+ ///
+ public static void AddRedis(this IServiceCollection services, Action redisOptions)
+ {
+ services.AddSingleton();
+ if (redisOptions != null)
+ {
+ redisOptions.Invoke(RedisOptions.Default);
+ }
+ }
+ }
+}
diff --git a/langguanApi/Extensions/SocketExtension.cs b/langguanApi/Extensions/SocketExtension.cs
new file mode 100644
index 0000000..62f34f7
--- /dev/null
+++ b/langguanApi/Extensions/SocketExtension.cs
@@ -0,0 +1,22 @@
+using langguanApi.Service;
+
+namespace langguanApi.Extensions
+{
+ public static class SocketExtension
+ {
+ ///
+ ///
+ ///
+ ///
+ public static void AddSocketService(this IServiceCollection services)
+ {
+ // services.AddSingleton();
+ services.AddTransient();
+ services.AddTransient();
+
+ IServiceProvider serviceProvider = services.BuildServiceProvider();
+ _ = serviceProvider.GetService().Start();
+ serviceProvider.GetService().CreatTask();
+ }
+ }
+}
diff --git a/langguanApi/Middleware/CustomerExceptionFilter.cs b/langguanApi/Middleware/CustomerExceptionFilter.cs
new file mode 100644
index 0000000..58a073e
--- /dev/null
+++ b/langguanApi/Middleware/CustomerExceptionFilter.cs
@@ -0,0 +1,39 @@
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.AspNetCore.Mvc.Filters;
+
+namespace langguanApi.Middleware
+{
+ public class CustomerExceptionFilter : IAsyncExceptionFilter
+ {
+ ///
+ /// 日志
+ ///
+ public ILogger _logger;
+ ///
+ /// 构参
+ ///
+ ///
+ public CustomerExceptionFilter(ILoggerFactory loggerFactory)
+ {
+ _logger = loggerFactory.CreateLogger();
+ }
+ ///
+ /// 重写
+ ///
+ ///
+ ///
+ public Task OnExceptionAsync(ExceptionContext context)
+ {
+ if (context.ExceptionHandled == false)
+ {
+ var json = new { cdoe = -1, msg = context.Exception.Message, data = context.Exception.Data };
+ context.HttpContext.Response.StatusCode = 400;
+ context.Result = new JsonResult(json);
+ }
+ _logger.LogError($"请求出现异常,地址:{context.HttpContext?.Request?.Path},请求方式:{context.HttpContext.Request.Method},异常信息:{context.Exception.Message}");
+ //记录异常已经处理
+ context.ExceptionHandled = true;
+ return Task.CompletedTask;
+ }
+ }
+}
diff --git a/langguanApi/Model/Alert.cs b/langguanApi/Model/Alert.cs
new file mode 100644
index 0000000..d6ee4e5
--- /dev/null
+++ b/langguanApi/Model/Alert.cs
@@ -0,0 +1,7 @@
+namespace langguanApi.Model
+{
+ public class Alert : BaseModel
+ {
+ public string DeviceMn { get; set; }
+ }
+}
diff --git a/langguanApi/Model/ApiResult.cs b/langguanApi/Model/ApiResult.cs
new file mode 100644
index 0000000..23e2e36
--- /dev/null
+++ b/langguanApi/Model/ApiResult.cs
@@ -0,0 +1,21 @@
+namespace langguanApi.Model
+{
+ ///
+ /// Api返回结果
+ ///
+ public class ApiResult
+ {
+ ///
+ /// code=0成功。1失败
+ ///
+ public int code { get; set; } = 0;
+ ///
+ /// 结果
+ ///
+ public object data { get; set; }
+ ///
+ /// 消息
+ ///
+ public string msg { get; set; }
+ }
+}
diff --git a/langguanApi/Model/BaseModel.cs b/langguanApi/Model/BaseModel.cs
new file mode 100644
index 0000000..4d977c4
--- /dev/null
+++ b/langguanApi/Model/BaseModel.cs
@@ -0,0 +1,40 @@
+using MongoDB.Bson;
+using MongoDB.Bson.Serialization.Attributes;
+
+namespace langguanApi.Model
+{
+ ///
+ /// base model
+ ///
+ public class BaseModel
+ {
+ ///
+ /// //标记主键
+ ///
+ [BsonId]
+ [BsonRepresentation(BsonType.ObjectId)] //参数类型 , 无需赋值
+ public string Id { get; set; }
+
+ ///
+ /// //指明数据库中字段名为CreateDateTime
+ ///
+ [BsonElement(nameof(CreateDateTime))] //指明数据库中字段名为CreateDateTime
+
+ public DateTime CreateDateTime { get; set; }
+
+ ///
+ /// 标记删除
+ ///
+ //[BsonElement(nameof(IsDelete))]
+ public bool IsDelete { get; set; }=false;
+
+ ///
+ /// basemodel
+ ///
+ public BaseModel()
+ {
+ CreateDateTime = DateTime.Now;
+ IsDelete = false;
+ }
+ }
+}
diff --git a/langguanApi/Model/CommandNumber.cs b/langguanApi/Model/CommandNumber.cs
new file mode 100644
index 0000000..3712305
--- /dev/null
+++ b/langguanApi/Model/CommandNumber.cs
@@ -0,0 +1,38 @@
+namespace langguanApi.Model
+{
+ ///
+ /// 命令编码
+ ///
+ public enum CommandNumber
+ {
+ ///
+ /// 心跳包
+ ///
+ HeartbeatPackage = 1062,
+
+ ///
+ /// 工控机向上位机上传分钟数据
+ ///
+ UploadMinuteData = 2051,
+
+ ///
+ /// 工控机向上位机上传小时数据
+ ///
+ UploadHourlyData = 2061,
+
+ ///
+ /// 工控机向上位机上传日数据
+ ///
+ UploadDailyData = 2031,
+
+ ///
+ /// 工控机向上位机上传实时数据
+ ///
+ UploadRealTimeData = 2011,
+
+ ///
+ /// 上位机向工控机返回应答
+ ///
+ DataResponse = 9014
+ }
+}
diff --git a/langguanApi/Model/CpCommand.cs b/langguanApi/Model/CpCommand.cs
new file mode 100644
index 0000000..217cd5b
--- /dev/null
+++ b/langguanApi/Model/CpCommand.cs
@@ -0,0 +1,114 @@
+using IceCoffee.Common.Extensions;
+using System.Reflection;
+
+namespace langguanApi.Model
+{
+ ///
+ /// CP指令
+ ///
+ public class CpCommand
+ {
+ public ResponseCode ExeRtn { get; set; }
+
+ ///
+ /// 数据时间信息
+ ///
+ public DateTime DataTime { get; set; }
+
+ ///
+ /// 污染物信息
+ ///
+ public List PollutantInfo { get; set; }
+
+ ///
+ /// 解析
+ ///
+ ///
+ ///
+ public static CpCommand Parse(string cp)
+ {
+ var cpCommand = new CpCommand();
+
+ cpCommand.PollutantInfo = new List();
+
+ cpCommand.DataTime = DateTime.ParseExact(cp.GetMidStr("DataTime=", ";"), "yyyyMMddHHmmss", null);
+ cp = cp.Substring(24);
+ foreach (string project in cp.Split(';', StringSplitOptions.RemoveEmptyEntries))
+ {
+ var pollutantInfo = new PollutantInfo();
+
+ string[] classes = project.Split(',');
+ foreach (string @class in classes)
+ {
+ string[] keyValue = @class.Split('=');
+ string key = keyValue[0];
+ string value = keyValue[1];
+
+ string[] factorCodeType = key.Split('-');
+ string factorCode = factorCodeType[0];
+ string type = factorCodeType[1];
+
+ pollutantInfo.FactorCode = (FactorCode)Enum.Parse(typeof(FactorCode), factorCode);
+
+ switch (type)
+ {
+ case nameof(Model.PollutantInfo.Rtd):
+ if (string.IsNullOrEmpty(value) == false && decimal.TryParse(value, out decimal rtd))
+ {
+ pollutantInfo.Rtd = rtd;
+ }
+ break;
+ case nameof(Model.PollutantInfo.Avg):
+ if (string.IsNullOrEmpty(value) == false && decimal.TryParse(value, out decimal avg))
+ {
+ pollutantInfo.Avg = avg;
+ }
+ break;
+ case nameof(Model.PollutantInfo.Max):
+ if (string.IsNullOrEmpty(value) == false && decimal.TryParse(value, out decimal max))
+ {
+ pollutantInfo.Max = max;
+ }
+ break;
+ case nameof(Model.PollutantInfo.Min):
+ if (string.IsNullOrEmpty(value) == false && decimal.TryParse(value, out decimal min))
+ {
+ pollutantInfo.Min = min;
+ }
+ break;
+ case nameof(Model.PollutantInfo.Cou):
+ if (string.IsNullOrEmpty(value) == false && decimal.TryParse(value, out decimal cou))
+ {
+ pollutantInfo.Cou = cou;
+ }
+ break;
+ case nameof(Model.PollutantInfo.Flag):
+ pollutantInfo.Flag = (InstrumentationDataFlag)Enum.Parse(typeof(InstrumentationDataFlag), value);
+ break;
+ default:
+ throw new Exception("无效的CP指令字段名");
+ }
+ }
+
+ cpCommand.PollutantInfo.Add(pollutantInfo);
+ }
+
+ return cpCommand;
+ //}
+ //catch (Exception ex)
+ //{
+ // Console.WriteLine($"Error in CpCommand.Parse:{ex.Message}");
+ // throw new Exception("Error in CpCommand.Parse", ex);
+ //}
+ }
+
+ ///
+ /// 序列化
+ ///
+ ///
+ public string Serialize()
+ {
+ return "ExeRtn=" + (int)ExeRtn;
+ }
+ }
+}
diff --git a/langguanApi/Model/DataSegment.cs b/langguanApi/Model/DataSegment.cs
new file mode 100644
index 0000000..4b11695
--- /dev/null
+++ b/langguanApi/Model/DataSegment.cs
@@ -0,0 +1,152 @@
+using IceCoffee.Common.Extensions;
+using System.Text;
+
+namespace langguanApi.Model
+{
+ ///
+ /// 数据段
+ ///
+ public class DataSegment
+ {
+ ///
+ /// 默认应答系统编码
+ ///
+ public const string ResponseST = "91";
+
+ ///
+ /// 请求编号
+ ///
+ ///
+ /// yyyyMMddHHmmssZZZ 取当前系统时间, 精确到毫秒值, 用来唯一标识一次命令交互
+ ///
+ public string QN { get; set; }
+
+ ///
+ /// 系统编号
+ ///
+ public string ST { get; set; }
+
+ ///
+ /// 命令编码
+ /// 详见附录 2
+ ///
+ public CommandNumber CN { get; set; }
+
+ ///
+ /// 访问密码
+ /// 对接时提供给各个对接站点
+ ///
+ public string PW { get; set; }
+
+ ///
+ /// 设备唯一标识
+ /// 对接时提供给各个对接站点
+ ///
+ public string MN { get; set; }
+
+ ///
+ /// 拆分包及应答标志
+ ///
+ public PackageFlag PackageFlag { get; set; }
+
+ ///
+ /// 总包数
+ /// PNUM 指示本次通讯中总共包含的包数,注:不分包时可以没有本字段,与标志位有关
+ ///
+ public int PNUM { get; set; }
+
+ ///
+ /// 包号
+ /// PNO 指示当前数据包的包号,注: 不分包时可以没有本字段,与标志位有关
+ ///
+ public int PNO { get; set; }
+
+ ///
+ /// 指令
+ /// CP=&&数据区&&( 详见表 5 )
+ ///
+ public CpCommand CpCommand { get; set; }
+
+ ///
+ /// 解析
+ ///
+ ///
+ ///
+ ///
+ public static DataSegment Parse(string data, Func unpackCacheFunc)
+ {
+ DataSegment dataSegment = new DataSegment();
+ try
+ {
+ int outEnd;
+ dataSegment.QN = data.GetMidStr("QN=", ";", out outEnd);
+
+ if (outEnd < 0)
+ {
+ outEnd = 0;
+ }
+
+ dataSegment.ST = data.GetMidStr("ST=", ";", out outEnd, outEnd);
+ dataSegment.CN = (CommandNumber)int.Parse(data.GetMidStr("CN=", ";", out outEnd, outEnd));
+ dataSegment.PW = data.GetMidStr("PW=", ";", out outEnd, outEnd);
+ dataSegment.MN = data.GetMidStr("MN=", ";", out outEnd, outEnd);
+
+ string packageFlag = data.GetMidStr("Flag=", ";", out outEnd, outEnd);
+ if (string.IsNullOrEmpty(packageFlag) || int.TryParse(packageFlag, out _) == false || outEnd < 0)
+ {
+ outEnd = 0;
+ }
+ else
+ {
+ dataSegment.PackageFlag = PackageFlag.Parse(packageFlag);
+ }
+
+ if (dataSegment.PackageFlag != null && dataSegment.PackageFlag.D == 1)
+ {
+ // 分包
+ dataSegment.PNUM = int.Parse(data.GetMidStr("PNUM=", ";", out outEnd, outEnd));
+ dataSegment.PNO = int.Parse(data.GetMidStr("PNO=", ";", out outEnd, outEnd));
+
+ string cp = data.GetMidStr("CP=&&", "&&", out outEnd, outEnd);
+ var cache = unpackCacheFunc.Invoke();
+ if (dataSegment.PNO == 1)// 第一个包
+ {
+ cache.Append(cp);
+ }
+ else if (dataSegment.PNUM == dataSegment.PNO)// 最后一个包
+ {
+ cache.Append(cp.Substring(23));
+ dataSegment.CpCommand = CpCommand.Parse(cache.ToString());
+ cache.Clear();
+ }
+ else// 中间的包
+ {
+ cache.Append(cp.Substring(23));// 23 - DataTime=20170920100000; 留分号
+ }
+ }
+ else
+ {
+ string cp = data.GetMidStr("CP=&&", "&&", out outEnd, outEnd);
+ // 过滤心跳包
+ dataSegment.CpCommand = dataSegment.CN == CommandNumber.HeartbeatPackage ? new CpCommand() : CpCommand.Parse(cp);
+ }
+ return dataSegment;
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine($"Error in DataSegment.Parse:{ex.Message}");
+
+ }
+ return dataSegment;
+ }
+
+ ///
+ /// 序列化
+ ///
+ ///
+ public string Serialize()
+ {
+ return $"QN={QN};ST={ST};CN={(int)CN};PW={PW};MN={MN};Flag={PackageFlag.Serialize()};CP=&&{CpCommand.Serialize()}&&";
+ }
+ }
+}
diff --git a/langguanApi/Model/Device.cs b/langguanApi/Model/Device.cs
new file mode 100644
index 0000000..9c51adb
--- /dev/null
+++ b/langguanApi/Model/Device.cs
@@ -0,0 +1,16 @@
+namespace langguanApi.Model
+{
+ ///
+ /// 设备信息
+ ///
+ public class Device : BaseModel
+ {
+ public string deviceMN { get; set; }
+ public string Name { get; set; }
+ public string Ip { get; set; }
+ public double lng { get; set; }
+ public double lat { get; set; }
+ public string desricption { get; set; }
+ public int state { get; set; }
+ }
+}
diff --git a/langguanApi/Model/Dto/AddDevice.cs b/langguanApi/Model/Dto/AddDevice.cs
new file mode 100644
index 0000000..76c3330
--- /dev/null
+++ b/langguanApi/Model/Dto/AddDevice.cs
@@ -0,0 +1,13 @@
+namespace langguanApi.Model.Dto
+{
+ public class DeviceDto
+ {
+ public string deviceMN { get; set; }
+ public string Name { get; set; }
+ public string Ip { get; set; }
+ public double lng { get; set; }
+ public double lat { get; set; }
+ public string desricption { get; set; }
+ public int state { get; set; }
+ }
+}
diff --git a/langguanApi/Model/Dto/HJ212_2017.cs b/langguanApi/Model/Dto/HJ212_2017.cs
new file mode 100644
index 0000000..59a1633
--- /dev/null
+++ b/langguanApi/Model/Dto/HJ212_2017.cs
@@ -0,0 +1,143 @@
+using System.Text;
+
+namespace langguanApi.Model.Dto
+{
+ ///
+ /// HJ212_2017
+ ///
+ public class HJ212_2017
+ {
+ ///
+ /// 数据帧头
+ ///
+ public string header { get; set; }
+ ///
+ /// 数据长度
+ ///
+ public string data_length { get; set; }
+
+ ///
+ /// 数据头
+ ///
+ public Dictionary DATA_HEAD { get; set; }
+ ///
+ ///
+ ///
+ public Dictionary CP { get; set; }
+ ///
+ /// CRC校验
+ ///
+ public string CRC { get; set; }
+ ///
+ ///
+ ///
+ ///
+ ///
+ public bool DecodeData(string Text)
+ {
+ try
+ {
+ if (Text.Length < 12 || !Text.StartsWith("##"))
+ {
+ Console.WriteLine("不是HJ212协议的报文!");
+ return false;
+ }
+ Console.WriteLine($"开始解码数据:");
+ Text = Text.ToUpper().Replace(";CP=", "").Replace(" ", "");//有些厂家协议不很标准,有的大小写不一致,此处强制转大写字母
+ header = Text.Substring(0, 2);
+ data_length = Text.Substring(2, 4);
+ string[] data_0 = Text.Substring(6, Text.Length - 6).Split(new char[] { '&', '&' }, StringSplitOptions.RemoveEmptyEntries);
+ string[] data_1 = data_0[0].Split(new char[] { ';' });
+ DATA_HEAD = new Dictionary();
+ for (int h = 0; h < data_1.Length; h++)
+ {
+ string[] d_1 = data_1[h].Split(new char[] { '=' });
+ DATA_HEAD.Add(d_1[0], d_1[1]);
+ }
+ string[] data_2 = data_0[1].Split(new char[] { ';' });
+ CP = new Dictionary();
+ for (int i = 0; i < data_2.Length; i++)
+ {
+ string[] d_6 = data_2[i].Split(new char[] { ',' });
+ for (int j = 0; j < d_6.Length; j++)
+ {
+ string[] d_7 = d_6[j].Split(new char[] { '=' });
+ CP.Add(d_7[0].Replace("-RTD", ""), d_7[1]);
+ }
+ }
+ CRC = data_0[2];
+ return true;
+ }
+ catch (Exception ex)
+ {
+ //数据接收不完整
+ Console.WriteLine($" 解码失败:err:{ex},数据有问题," + Text);
+ //throw;
+ return false;
+ }
+ }
+
+
+ ///
+ /// 判断数据是否通过校验
+ ///
+ /// 原始数据
+ /// 是否通过
+ public bool Crc16(string Text)
+ {
+ try
+ {
+ string CRC = Text.Substring(Text.Length - 4, 4);
+
+ Text = Text.Substring(Text.IndexOf("QN"));
+ Text = Text.Substring(0, Text.Length - 4);
+
+ byte[] bytes = Encoding.ASCII.GetBytes(Text);
+ int crcRegister = 0xFFFF;
+ for (int i = 0; i < bytes.Length; i++)
+ {
+ crcRegister = (crcRegister >> 8) ^ bytes[i];
+ for (int j = 0; j < 8; j++)
+ {
+ int check = crcRegister & 0x0001;
+ crcRegister >>= 1;
+ if (check == 0x0001)
+ {
+ crcRegister ^= 0xA001;
+ }
+ }
+ }
+ string result = string.Format("{0:X}", crcRegister);//转十六进制
+ for (int i = result.Length; i < 4; i++)//补足 4 位
+ {
+ result = "0" + result;
+ }
+ //LogApi.WriteLog("计算校验码:" + result);
+ if (result == CRC)
+ {
+ return true;
+ }
+ else
+ {
+ Console.WriteLine("校验码有误," + CRC);
+ Console.WriteLine("待校验数据:" + Text);
+ Console.WriteLine("计算校验码:" + result);
+ //LogApi.WriteLog("校验码有误:" + CRC);
+ //LogApi.WriteLog("待校验数据:" + Text);
+ //LogApi.WriteLog("计算校验码:" + result);
+ return false;
+
+
+ }
+ }
+ catch (Exception)
+ {
+ Console.WriteLine("数据校验:数据有问题:" + Text);
+ //数据接收不完整
+ return false;
+ //throw;
+ }
+
+ }
+ }
+}
diff --git a/langguanApi/Model/FactorCode.cs b/langguanApi/Model/FactorCode.cs
new file mode 100644
index 0000000..5678686
--- /dev/null
+++ b/langguanApi/Model/FactorCode.cs
@@ -0,0 +1,422 @@
+namespace langguanApi.Model
+{
+ ///
+ /// 污染物因子编码
+ ///
+ public enum FactorCode
+ {
+ #region VOCs 在线检测仪因子编码
+ a24901,
+ a24904,
+ a24905,
+ a24042,
+ a25002,
+ a24036,
+ a24908,
+ a24909,
+ a24910,
+ a24012,
+ a24043,
+ a24084,
+ a24911,
+ a25003,
+ a24912,
+ a24913,
+ a24070,
+ a25004,
+ a25008,
+ a25038,
+ a25006,
+ a24044,
+ a25034,
+ a25033,
+ a25902,
+ a25014,
+ a25021,
+ a25901,
+ a25019,
+ a24068,
+ a25020,
+ a25903,
+ a25904,
+ a24914,
+ a24915,
+ a24001,
+ a24045,
+ a24002,
+ a24053,
+ a24038,
+ a24037,
+ a24079,
+ a24064,
+ a24919,
+ a24063,
+ a24902,
+ a24041,
+ a24039,
+ a24077,
+ a24074,
+ a24076,
+ a24907,
+ a24903,
+ a24011,
+ a24061,
+ a24906,
+ a31002,
+ a31005,
+
+ #region 甲烷和非甲烷总烃分析仪因子编码
+ a05002,
+ a99999,
+ a24088,
+ #endregion
+
+ a24072,
+ a05009,
+ a05014,
+ a24099,
+ a24058,
+ a24046,
+ a24078,
+ a24008,
+ a24015,
+ a24916,
+ a31004,
+ a31003,
+ a24047,
+ a05013,
+ a31024,
+ a99009,
+ a24003,
+ a28006,
+ a31015,
+ a24016,
+ a31900,
+ a24111,
+ a24004,
+ a24018,
+ a24005,
+ a24017,
+ a24049,
+ a24917,
+ a24027,
+ a31010,
+ a31026,
+ a24007,
+ a24112,
+ a24054,
+ a24019,
+ a24050,
+ a31009,
+ a24034,
+ a25010,
+ a24009,
+ a24020,
+ a25012,
+ a25011,
+ a30003,
+ a30008,
+ a99051,
+ a29026,
+ a29017,
+ a31025,
+ a24110,
+ a25072,
+ a29015,
+ a31030,
+ a31027,
+ a24006,
+ a25013,
+ a25068,
+ a25015,
+ a24113,
+ a25059,
+ a31001,
+ a31016,
+ a31018,
+ a31020,
+ a24102,
+ a30001,
+ a25905,
+ a24918,
+ a28900,
+ a28010,
+ a30002,
+ a30023,
+ a28001,
+ a24059,
+ a24944,
+ #endregion
+
+ #region 气象五参数在线监测仪因子编码
+ a01030,
+ a01004,
+ a01007,
+ a01008,
+ a06001,
+ a01001,
+ #endregion
+
+ #region 氮氧化物分析仪
+ a21003,
+ a21004,
+ a21002,
+ a21029,
+ #endregion
+
+ #region 常规六参因子编码
+ a34004,
+ a34002,
+ a21026,
+ // a21004,
+ a21005,
+ #endregion
+
+ #region 在线离子色谱仪因子编码
+ a06010,
+ a06011,
+ a06013,
+ a06009,
+ a06012,
+ a06005,
+ a06006,
+ a06019,
+ a06008,
+ a21001,
+ a20109,
+ // a21026,
+ a20110,
+ a21024,
+ // a21004,
+ a06007,
+ a06015,
+ a06018,
+ a06021,
+ a06017,
+ a06022,
+ a06023,
+ a06024,
+ a06025,
+ a06026,
+ a06027,
+ a06028,
+ a06029,
+ a06030,
+ a06031,
+ a06032,
+ a06033,
+ a34007,
+ a34006,
+ a34047,
+ a34048,
+ a34049,
+ a20044,
+ a20072,
+ a20058,
+ a20033,
+ a20026,
+ a20104,
+ a20041,
+ a20064,
+ a20111,
+ a20055,
+ a20095,
+ a20004,
+ a20092,
+ a20101,
+ a20012,
+ a20007,
+ a20029,
+ a20068,
+ a20038,
+ a20061,
+ a20112,
+ a20113,
+ a20089,
+ a20114,
+ a20115,
+ a20086,
+ a20116,
+ a20117,
+ a20118,
+ a20119,
+ a20079,
+ a20120,
+ a20002,
+ a20121,
+ a20075,
+ a20052,
+ a20122,
+ a20123,
+ a21012,
+ a20124,
+ a20107,
+ a20125,
+ a20126,
+ a20127,
+ a20128,
+ a20129,
+ a20098,
+ a20020,
+ a01031,
+ a01032,
+ a01029,
+ a01033,
+ a01034,
+ a01035,
+ a01036,
+ a01037,
+ // a01001,
+ // a01004,
+ a01038,
+ a01039,
+ // a06001,
+ a01022,
+ a01023,
+ // a34002,
+ // a34004,
+ a01024,
+ a19006,
+ a01025,
+ a01026,
+ a01020,
+ a01027,
+ a01028,
+ // a01029,
+ // a01022,
+ // a01023,
+ a05024,
+ a19999,
+ a19998,
+ a19997,
+ a19996,
+ a19995,
+ a19994,
+ a19993,
+ #endregion
+
+ #region 气监测因子编码表(引用 HJ 524-2009)
+ a00000,
+ //a01001,
+ a01002,
+ a01006,
+ //a01007,
+ //a01008,
+ a01010,
+ a01011,
+ a01012,
+ a01013,
+ a01014,
+ a01015,
+ a01016,
+ a01017,
+ a01901,
+ a01902,
+ a05001,
+ //a05002,
+ a05008,
+ //a05009,
+ //a05013,
+ a19001,
+ //a20007,
+ a20016,
+ a20025,
+ //a20026,
+ a20043,
+ //a20044,
+ a20057,
+ //a20058,
+ a20063,
+ a20091,
+ //a21001,
+ //a21002,
+ //a21003,
+ //a21004,
+ //a21005,
+ a21017,
+ a21018,
+ a21022,
+ //a21024,
+ //a21026,
+ a21028,
+ a23001,
+ //a24003,
+ //a24004,
+ //a24005,
+ //a24006,
+ //a24007,
+ //a24008,
+ //a24009,
+ //a24015,
+ //a24016,
+ //a24017,
+ //a24018,
+ //a24019,
+ //a24020,
+ //a24027,
+ //a24034,
+ //a24036,
+ //a24042,
+ //a24043,
+ //a24046,
+ //a24047,
+ //a24049,
+ //a24050,
+ //a24053,
+ //a24054,
+ //a24072,
+ //a24078,
+ a24087,
+ //a24088,
+ //a24099,
+ //a24110,
+ //a24111,
+ //a24112,
+ //a24113,
+ //a25002,
+ //a25003,
+ //a25004,
+ a25005,
+ //a25006,
+ a25007,
+ //a25008,
+ //a25010,
+ //a25011,
+ //a25012,
+ //a25013,
+ //a25014,
+ //a25015,
+ //a25019,
+ //a25020,
+ //a25021,
+ a25023,
+ //a25038,
+ a25044,
+ //a25072,
+ a26001,
+ //a29017,
+ //a29026,
+ //a30001,
+ //a30008,
+ a30022,
+ //a31001,
+ //a31002,
+ //a31024,
+ //a31025,
+ //a31030,
+ a34001,
+ //a34002,
+ //a34004,
+ a34005,
+ a34011,
+ a34013,
+ a34017,
+ a34038,
+ a34039,
+ a34040,
+ a99010,
+ a99049,
+ //a99051,
+ #endregion
+ }
+}
diff --git a/langguanApi/Model/HJ212.cs b/langguanApi/Model/HJ212.cs
new file mode 100644
index 0000000..eadc538
--- /dev/null
+++ b/langguanApi/Model/HJ212.cs
@@ -0,0 +1,49 @@
+using Swashbuckle.AspNetCore.SwaggerUI;
+using System.ComponentModel;
+using System.Reflection.Metadata;
+
+namespace langguanApi.Model
+{
+ public class HJ212 : BaseModel
+ {
+ ///
+ /// 设备ID
+ ///
+ public string deviceMN { get; set; }
+ ///
+ /// PM2.5浓度
+ ///
+ public double a34004 { get; set; }
+ ///
+ /// PM10浓度
+ ///
+ public double a34002 { get; set; }
+ ///
+ /// TSP浓度
+ ///
+ public double a34001 { get; set; }
+ ///
+ /// 温度
+ ///
+ public double a01001 { get; set; }
+ ///
+ /// 湿度
+ ///
+ public double a01002 { get; set; }
+ ///
+ /// 大气压
+ ///
+ public double a01006 { get; set; }
+ ///
+ /// 风速
+ ///
+ public double a01007 { get; set; }
+ ///
+ /// 风向
+ ///
+ public double a01008 { get; set; }
+ public double lat { get; set; }
+ public double lng { get; set; }
+
+ }
+}
diff --git a/langguanApi/Model/InstrumentationDataFlag.cs b/langguanApi/Model/InstrumentationDataFlag.cs
new file mode 100644
index 0000000..b5126ed
--- /dev/null
+++ b/langguanApi/Model/InstrumentationDataFlag.cs
@@ -0,0 +1,64 @@
+namespace langguanApi.Model
+{
+ ///
+ /// 检测仪器数据标记
+ ///
+ public enum InstrumentationDataFlag
+ {
+ ///
+ /// 正常(有效)
+ /// 在线监控(监测)仪器仪表工作正常
+ ///
+ N,
+
+ ///
+ /// 无效
+ /// 在线监控(监测)仪器仪表停运
+ ///
+ F,
+
+ ///
+ /// 无效
+ /// 在线监控(监测)仪器仪表处于维护期间产生的数据
+ ///
+ M,
+
+ ///
+ /// 有效
+ /// 手工输入的设定值
+ ///
+ S,
+
+ ///
+ /// 无效
+ /// 在线监控(监测)仪器仪表故障
+ ///
+ D,
+
+ ///
+ /// 无效
+ /// 在线监控(监测)仪器仪表处于校准状态
+ ///
+ C,
+
+ ///
+ /// 无效
+ /// 在线监控(监测)仪器仪表采样数值超过测量上限
+ ///
+ T,
+
+ ///
+ /// 无效
+ /// 在线监控(监测)仪器仪表与数采仪通讯异常
+ ///
+ B,
+
+ ///
+ /// 无效(有效数据不足)
+ ///
+ ///
+ /// 按照5分钟、1小时均值计算要求,所获取的有效数据个数不足
+ ///
+ H
+ }
+}
diff --git a/langguanApi/Model/NetPackage.cs b/langguanApi/Model/NetPackage.cs
new file mode 100644
index 0000000..6d2ceff
--- /dev/null
+++ b/langguanApi/Model/NetPackage.cs
@@ -0,0 +1,119 @@
+using System.Text;
+
+namespace langguanApi.Model
+{
+ ///
+ /// 通讯包
+ ///
+ public class NetPackage
+ {
+ ///
+ /// 默认头
+ ///
+ public const string FixedHead = "##";
+ ///
+ /// 默认尾
+ ///
+ public const string FixedTail = "\r\n";
+
+ ///
+ /// 包头
+ ///
+ public string Head { get; set; }
+
+ ///
+ /// 数据段长度
+ ///
+ public int DataSegmentLength { get; set; }
+
+ ///
+ /// 数据段
+ ///
+ public DataSegment DataSegment { get; set; }
+
+ ///
+ /// CRC校验码
+ ///
+ public string CrcCode { get; set; }
+
+ ///
+ /// 包尾
+ ///
+ public string Tail { get; set; }
+
+ ///
+ /// CRC16校验
+ ///
+ /// 需要校验的字符串
+ /// CRC16 校验码
+ private static string CRC16(string arg)
+ {
+ char[] puchMsg = arg.ToCharArray();
+ uint i, j, crc_reg, check;
+ crc_reg = 0xFFFF;
+ for (i = 0; i < puchMsg.Length; i++)
+ {
+ crc_reg = (crc_reg >> 8) ^ puchMsg[i];
+ for (j = 0; j < 8; j++)
+ {
+ check = crc_reg & 0x0001;
+ crc_reg >>= 1;
+ if (check == 0x0001)
+ {
+ crc_reg ^= 0xA001;
+ }
+ }
+ }
+
+ return crc_reg.ToString("X2").PadLeft(4, '0');
+ }
+
+ ///
+ /// 解析
+ ///
+ ///
+ ///
+ ///
+ public static NetPackage Parse(string line, Func unpackCacheFunc = null)
+ {
+ try
+ {
+ NetPackage netPackage = new NetPackage();
+ netPackage.Head = line.Substring(0, 2);
+ netPackage.DataSegmentLength = int.Parse(line.Substring(2, 4));
+
+ string dataSegment = line.Substring(6, netPackage.DataSegmentLength);
+
+ string crcCode = line.Substring(6 + netPackage.DataSegmentLength, 4);
+ string calcCrcCode = CRC16(dataSegment);
+ if (crcCode != calcCrcCode)
+ {
+ throw new Exception("CRC校验失败 " + line);
+ }
+
+ netPackage.DataSegment = DataSegment.Parse(dataSegment, unpackCacheFunc);
+ netPackage.CrcCode = crcCode;
+ netPackage.Tail = line.Substring(10 + netPackage.DataSegmentLength);
+
+ return netPackage;
+ }
+ catch (Exception ex)
+ {
+ throw new Exception("Error in NetPackage.Parse", ex);
+ }
+ }
+
+ ///
+ /// 序列化
+ ///
+ ///
+ public string Serialize()
+ {
+ string dataSegment = DataSegment.Serialize();
+ DataSegmentLength = dataSegment.Length;
+ CrcCode = CRC16(dataSegment);
+
+ return $"{Head}{DataSegmentLength.ToString().PadLeft(4, '0')}{dataSegment}{CrcCode}{Tail}";
+ }
+ }
+}
diff --git a/langguanApi/Model/PackageFlag.cs b/langguanApi/Model/PackageFlag.cs
new file mode 100644
index 0000000..99d962c
--- /dev/null
+++ b/langguanApi/Model/PackageFlag.cs
@@ -0,0 +1,117 @@
+namespace langguanApi.Model
+{
+ ///
+ /// 拆分包及应答标志
+ ///
+ public class PackageFlag
+ {
+ public byte V5 { get; set; }
+ public byte V4 { get; set; }
+ public byte V3 { get; set; }
+ public byte V2 { get; set; }
+ public byte V1 { get; set; }
+ public byte V0 { get; set; }
+
+ ///
+ /// 命令是否应答:1-应答,0-不应答
+ ///
+ public byte A { get; set; }
+
+ ///
+ /// 是否有数据包序号:1 - 数据包中包含包号和总包数两部分,0 - 数据包中不包含包号和总包数两部分
+ ///
+ public byte D { get; set; }
+
+ ///
+ /// 标准版本号
+ /// 000000 表示标准 HJ/T212-2005
+ /// 000001 表示本次标准修订版本号
+ ///
+ public string Version
+ {
+ get
+ {
+ return $"{V5}{V4}{V3}{V2}{V1}{V0}";
+ }
+ }
+
+ ///
+ /// 解析
+ ///
+ ///
+ ///
+ public static PackageFlag Parse(string data)
+ {
+ byte flag = byte.Parse(data);
+ return new PackageFlag()
+ {
+
+ V5 = GetBit(flag, 7),
+ V4 = GetBit(flag, 6),
+ V3 = GetBit(flag, 5),
+ V2 = GetBit(flag, 4),
+ V1 = GetBit(flag, 3),
+ V0 = GetBit(flag, 2),
+ D = GetBit(flag, 1),
+ A = GetBit(flag, 0)
+ };
+ }
+
+ ///
+ /// 序列化
+ ///
+ ///
+ public string Serialize()
+ {
+ return Convert.ToInt32($"{V5}{V4}{V3}{V2}{V1}{V0}{D}{A}", 2).ToString();
+ }
+
+ ///
+ /// 获取取第index位
+ ///
+ ///
+ /// index从0开始
+ ///
+ ///
+ ///
+ ///
+ private static byte GetBit(byte b, int index)
+ {
+ // (byte)((from & (0xFF << (index * 8))) >> (index * 8))
+ return ((b & (1 << index)) > 0) ? (byte)1 : (byte)0;
+ }
+
+ ///
+ /// 将第index位设为1
+ ///
+ ///
+ /// index从0开始
+ ///
+ ///
+ ///
+ ///
+ private static byte SetBit(byte b, int index) { return (byte)(b | (1 << index)); }
+
+ ///
+ /// 将第index位设为0
+ ///
+ ///
+ /// index从0开始
+ ///
+ ///
+ ///
+ ///
+ private static byte ClearBit(byte b, int index) { return (byte)(b & (byte.MaxValue - (1 << index))); }
+
+ ///
+ /// 将第index位取反
+ ///
+ ///
+ /// index从0开始
+ ///
+ ///
+ ///
+ ///
+ private static byte ReverseBit(byte b, int index) { return (byte)(b ^ (byte)(1 << index)); }
+ }
+}
diff --git a/langguanApi/Model/PollutantInfo.cs b/langguanApi/Model/PollutantInfo.cs
new file mode 100644
index 0000000..d05d021
--- /dev/null
+++ b/langguanApi/Model/PollutantInfo.cs
@@ -0,0 +1,63 @@
+namespace langguanApi.Model
+{
+ ///
+ /// 污染物信息
+ ///
+ public class PollutantInfo
+ {
+ ///
+ /// 约定的无效值
+ ///
+ public const decimal InvaildValue = -9999;
+
+ ///
+ /// 污染物因子编码
+ ///
+ public FactorCode FactorCode { get; set; }
+
+ ///
+ /// 污染物实时采样数据
+ ///
+ ///
+ /// 默认值为约定的无效值
+ ///
+ public decimal Rtd { get; set; } = InvaildValue;
+
+ ///
+ /// 污染物指定时问内平均值
+ ///
+ ///
+ /// 默认值为约定的无效值
+ ///
+ public decimal Avg { get; set; } = InvaildValue;
+
+ ///
+ /// 污染物指定时问内最大值
+ ///
+ ///
+ /// 默认值为约定的无效值
+ ///
+ public decimal Max { get; set; } = InvaildValue;
+
+ ///
+ /// 污染物指定时问内最小值
+ ///
+ ///
+ /// 默认值为约定的无效值
+ ///
+ public decimal Min { get; set; } = InvaildValue;
+
+ ///
+ /// 污染物指定时问内累计值
+ ///
+ ///
+ /// 默认值为约定的无效值
+ ///
+ public decimal Cou { get; set; } = InvaildValue;
+
+ ///
+ /// 检测仪器数据标记
+ ///
+ public InstrumentationDataFlag Flag { get; set; }
+ }
+}
diff --git a/langguanApi/Model/ReqPaing.cs b/langguanApi/Model/ReqPaing.cs
new file mode 100644
index 0000000..dccc6f7
--- /dev/null
+++ b/langguanApi/Model/ReqPaing.cs
@@ -0,0 +1,13 @@
+namespace langguanApi.Model
+{
+ public class ReqPaing
+ {
+ public int pageSize { get; set; } = 10;
+ public int current { get; set; } = 1;
+ }
+ public class reqpage : ReqPaing
+ {
+ public string key { get; set;
+ }
+ }
+}
diff --git a/langguanApi/Model/ResponseCode.cs b/langguanApi/Model/ResponseCode.cs
new file mode 100644
index 0000000..a8cedaf
--- /dev/null
+++ b/langguanApi/Model/ResponseCode.cs
@@ -0,0 +1,48 @@
+namespace langguanApi.Model
+{
+ ///
+ /// 回应代码集
+ ///
+ public enum ResponseCode
+ {
+ ///
+ /// 执行成功
+ ///
+ ExecSucceeded = 1,
+
+ ///
+ /// 执行失败,但不知道原因
+ ///
+ ExecutionFailed_DoNotKnowReason = 2,
+
+ ///
+ /// 执行失败,命令请求条件错误
+ ///
+ ExecutionFailed_InvalidCommand = 3,
+
+ ///
+ /// 通讯超时
+ ///
+ CommunicationTimeout = 4,
+
+ ///
+ /// 系统繁忙不能执行
+ ///
+ SystemBusy = 5,
+
+ ///
+ /// 系统时间异常
+ ///
+ InvalidSystemTime = 6,
+
+ ///
+ /// 没有数据
+ ///
+ NoneData = 100,
+
+ ///
+ /// 心跳包
+ ///
+ HeartbeatPackage = 300
+ }
+}
diff --git a/langguanApi/Model/columnView.cs b/langguanApi/Model/columnView.cs
new file mode 100644
index 0000000..414b947
--- /dev/null
+++ b/langguanApi/Model/columnView.cs
@@ -0,0 +1,15 @@
+namespace langguanApi.Model
+{
+ public class columnView
+ {
+ ///
+ ///
+ ///
+ public string hour { get; set; }
+ ///
+ /// a34004=PM2.5浓度,a34002=PM10,a34001=tsp浓度
+ ///
+ public string type { get; set; }
+ public double value { get; set; }
+ }
+}
diff --git a/langguanApi/Program.cs b/langguanApi/Program.cs
new file mode 100644
index 0000000..4959dc1
--- /dev/null
+++ b/langguanApi/Program.cs
@@ -0,0 +1,94 @@
+using langguanApi.Common.Redis;
+using langguanApi.Extensions;
+using langguanApi.Extensions.AutoDI;
+using langguanApi.Middleware;
+using Microsoft.Extensions.Configuration;
+using Microsoft.OpenApi.Models;
+using System.Text.Json;
+
+var builder = WebApplication.CreateBuilder(args);
+
+
+// Add services to the container.
+
+builder.Services.AddControllers(options =>
+{
+ options.Filters.Add();
+}).AddNewtonsoftJson(option =>
+{
+ option.SerializerSettings.ContractResolver = new Newtonsoft.Json.Serialization.DefaultContractResolver();
+ option.SerializerSettings.DateFormatString = "yyyy-MM-dd HH:mm:ss";
+
+}).AddJsonOptions(option =>
+{
+ option.JsonSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;
+});
+//swagger
+builder.Services.AddSwaggerGen(
+ options =>
+ {
+ options.SwaggerDoc("v1", new OpenApiInfo()
+ {
+ Title = "Title",
+ Version = "v1",
+ Description = "Description",
+ });
+ var path = Path.Combine(AppContext.BaseDirectory, "langguanApi.xml");
+ options.IncludeXmlComments(path, true);
+ options.OrderActionsBy(_ => _.RelativePath);
+ });
+// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
+builder.Services.AddEndpointsApiExplorer();
+
+//redis
+var redisoptions = builder.Configuration.GetSection("Redis").Get();
+if (redisoptions != null)
+{
+ builder.Services.AddRedis(options =>
+ {
+ options.Port = redisoptions.Port;
+ options.Server = redisoptions.Server;
+ options.Index = redisoptions.Index;
+ options.Password = redisoptions.Password;
+ options.Key = redisoptions.Key;
+ });
+}
+//Զע
+builder.Services.ServicesAutoInjectionExtension();
+builder.Services.AddSocketService();
+//cross domain
+builder.Services.AddCors(options =>
+{
+ options.AddPolicy("CorsPolicy", builder =>
+ {
+ builder.AllowAnyOrigin();
+ builder.AllowAnyMethod();
+ builder.AllowAnyHeader();
+ });
+});
+
+var app = builder.Build();
+ServiceLocator.Instance = app.Services;
+
+
+// Configure the HTTP request pipeline.
+if (app.Environment.IsDevelopment())
+{
+ app.UseSwagger();
+ app.UseSwaggerUI();
+}
+app.UseSwagger();
+app.UseSwaggerUI();
+app.UseCors("CorsPolicy");
+//app.UseAuthorization();
+
+app.MapControllers();
+
+app.Run();
+///
+/// ݴ
+///
+public static class ServiceLocator
+{
+ public static IServiceProvider Instance { get; set; }
+}
diff --git a/langguanApi/Properties/launchSettings.json b/langguanApi/Properties/launchSettings.json
new file mode 100644
index 0000000..e51933f
--- /dev/null
+++ b/langguanApi/Properties/launchSettings.json
@@ -0,0 +1,40 @@
+{
+ "profiles": {
+ "langguanApi": {
+ "commandName": "Project",
+ "launchBrowser": true,
+ "launchUrl": "swagger",
+ "environmentVariables": {
+ "ASPNETCORE_ENVIRONMENT": "Development"
+ },
+ "dotnetRunMessages": true,
+ "applicationUrl": "http://localhost:5254"
+ },
+ "IIS Express": {
+ "commandName": "IISExpress",
+ "launchBrowser": true,
+ "launchUrl": "swagger",
+ "environmentVariables": {
+ "ASPNETCORE_ENVIRONMENT": "Development"
+ }
+ },
+ "Docker": {
+ "commandName": "Docker",
+ "launchBrowser": true,
+ "launchUrl": "{Scheme}://{ServiceHost}:{ServicePort}/swagger",
+ "environmentVariables": {
+ "ASPNETCORE_URLS": "http://+:80"
+ },
+ "publishAllPorts": true
+ }
+ },
+ "$schema": "https://json.schemastore.org/launchsettings.json",
+ "iisSettings": {
+ "windowsAuthentication": false,
+ "anonymousAuthentication": true,
+ "iisExpress": {
+ "applicationUrl": "http://localhost:9471",
+ "sslPort": 0
+ }
+ }
+}
\ No newline at end of file
diff --git a/langguanApi/Service/AlertService.cs b/langguanApi/Service/AlertService.cs
new file mode 100644
index 0000000..b7e598f
--- /dev/null
+++ b/langguanApi/Service/AlertService.cs
@@ -0,0 +1,43 @@
+using langguanApi.Extensions.AutoDI;
+using langguanApi.Model;
+using langguanApi.Model.Dto;
+using System.Linq.Expressions;
+
+namespace langguanApi.Service
+{
+ [ServiceInjection(InjectionType.Transient)]
+ public class AlertService : BaseService
+ {
+ public AlertService(IConfiguration config) : base(config, nameof(Device))
+ {
+ }
+ ///
+ /// 新加
+ ///
+ ///
+ ///
+ public async Task Add(Alert input)
+ {
+ if (input != null)
+ {
+ await base.CreateAsync(input);
+ return new ApiResult { code = 0, msg = "" };
+ }
+ return new ApiResult { code = -1, msg = "" }; ;
+ }
+ ///
+ /// 分页取数据
+ ///
+ ///
+ ///
+ public async Task