From 3ac7466122bac9f67d596b1e888ea1713591c75c Mon Sep 17 00:00:00 2001 From: Hinse <756681202@qq.com> Date: Thu, 30 Sep 2021 09:27:59 +0800 Subject: [PATCH] =?UTF-8?q?1=E3=80=81=E5=A2=9E=E5=8A=A0=E7=94=9F=E6=88=90?= =?UTF-8?q?=E8=A1=A8=E9=A1=B9=E7=9B=AE=202=E3=80=81=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=E9=98=9F=E5=88=97=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 2 + .../SubscribeInfo/Dtos/SubscribeDto.cs | 85 +++++ .../SubscribeInfo/ISubscribeService.cs | 47 +++ .../SubscribeInfo/SubscribeService.cs | 228 ++++++++++++ .../ThirdApiInfo/IOpenService.cs | 7 + .../ThirdApiInfo/OpenAppService.cs | 14 +- Waste.Application/ThirdApiInfo/OpenService.cs | 332 ++++++------------ Waste.Application/Waste.Application.xml | 184 ++++++++++ Waste.Core/Waste.Core.csproj | 13 +- Waste.CreateDB/CreateTable.cs | 44 +++ Waste.CreateDB/Program.cs | 18 + Waste.CreateDB/Waste.CreateDB.csproj | 16 + Waste.Domain/DataModel/W_DeviceData.cs | 52 +-- Waste.Domain/DataModel/W_DeviceResult.cs | 34 ++ Waste.Web.Core/Startup.cs | 18 + Waste.Web.Entry/Pages/Device/Detail.cshtml | 4 + Waste.Web.Entry/Pages/Device/Detail.cshtml.cs | 16 + Waste.Web.Entry/Pages/Device/Index.cshtml | 3 +- Waste.Web.Entry/appsettings.json | 7 + Waste.sln | 9 + 20 files changed, 866 insertions(+), 267 deletions(-) create mode 100644 Waste.Application/SubscribeInfo/Dtos/SubscribeDto.cs create mode 100644 Waste.Application/SubscribeInfo/ISubscribeService.cs create mode 100644 Waste.Application/SubscribeInfo/SubscribeService.cs create mode 100644 Waste.CreateDB/CreateTable.cs create mode 100644 Waste.CreateDB/Program.cs create mode 100644 Waste.CreateDB/Waste.CreateDB.csproj create mode 100644 Waste.Domain/DataModel/W_DeviceResult.cs create mode 100644 Waste.Web.Entry/Pages/Device/Detail.cshtml create mode 100644 Waste.Web.Entry/Pages/Device/Detail.cshtml.cs diff --git a/.gitignore b/.gitignore index 6166492..c4374d3 100644 --- a/.gitignore +++ b/.gitignore @@ -27,3 +27,5 @@ /.vs /WasteConsoleTest/WasteConsoleTest/obj /WasteConsoleTest/WasteConsoleTest/bin +/Waste.CreateDB/bin/Debug/net5.0 +/Waste.CreateDB/obj diff --git a/Waste.Application/SubscribeInfo/Dtos/SubscribeDto.cs b/Waste.Application/SubscribeInfo/Dtos/SubscribeDto.cs new file mode 100644 index 0000000..c7f5878 --- /dev/null +++ b/Waste.Application/SubscribeInfo/Dtos/SubscribeDto.cs @@ -0,0 +1,85 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Waste.Application.SubscribeInfo +{ + /// + /// 测量记录 + /// + public class ResultS2SDto + { + /// + /// 设备ID + /// + public Guid DeviceId { get; set; } + /// + /// 最近使用时间 + /// + public DateTime? LastHeartTime { get; set; } + /// + /// 记录ID + /// + public Guid ResultId { get; set; } + /// + /// 设备服务商ID + /// + public Guid BusinessId { get; set; } + /// + /// 设备的IMEI + /// + public string imei { get; set; } + /// + /// ICCID + /// + public string iccid { get; set; } + /// + /// IMSI + /// + public string imsi { get; set; } + /// + /// 纬度 + /// + public decimal latitude { get; set; } + /// + /// 经度 + /// + public decimal longtitude { get; set; } + /// + /// 信号强度 + /// + public int gslq { get; set; } + /// + /// 垃圾类型 + /// + public string wastetype { get; set; } + /// + /// 垃圾桶编号 + /// + public string trash { get; set; } + /// + /// 毛重 + /// + public string weight { get; set; } + /// + /// 皮重 + /// + public decimal Tare { get; set; } + } + /// + /// 设备版本信息 + /// + public class DeviceVerS2SDto + { + /// + /// 设备机器码 + /// + public string ecode { get; set; } + /// + /// 版本号 + /// + public string ver { get; set; } + } +} diff --git a/Waste.Application/SubscribeInfo/ISubscribeService.cs b/Waste.Application/SubscribeInfo/ISubscribeService.cs new file mode 100644 index 0000000..aacda7f --- /dev/null +++ b/Waste.Application/SubscribeInfo/ISubscribeService.cs @@ -0,0 +1,47 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Waste.Application.ThirdApiInfo; + +namespace Waste.Application.SubscribeInfo +{ + /// + /// CAP订阅相关接口 + /// + public interface ISubscribeService + { + /// + /// 添加记录 + /// + /// + /// + Task InsertResultAsync(ResultS2SDto data); + /// + /// 更新记录上报结果 + /// + /// + /// + Task UpdateStatusAsync(UpdateStatusDto data); + /// + /// 更新设备开机信息 + /// + /// + /// + Task UpdateRegInfoAsync(Guid deviceid); + /// + /// 心跳数据上报 + /// + /// + /// + Task UpdateHeartInfoAsync(DevHeartRequestDto data); + + /// + /// 更新设备版本信息 + /// + /// + /// + Task UpdateVersionAsync(DeviceVerS2SDto data); + } +} diff --git a/Waste.Application/SubscribeInfo/SubscribeService.cs b/Waste.Application/SubscribeInfo/SubscribeService.cs new file mode 100644 index 0000000..1490470 --- /dev/null +++ b/Waste.Application/SubscribeInfo/SubscribeService.cs @@ -0,0 +1,228 @@ +using DotNetCore.CAP; +using Furion.DependencyInjection; +using Furion.DistributedIDGenerator; +using SqlSugar; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Waste.Application.ThirdApiInfo; +using Waste.Domain; + +namespace Waste.Application.SubscribeInfo +{ + /// + /// CAP订阅相关接口 + /// + public class SubscribeService : ISubscribeService, ICapSubscribe, ITransient + { + private readonly ISqlSugarRepository repository; + private readonly SqlSugarClient dbClient; + public SubscribeService(ISqlSugarRepository sqlSugarRepository) + { + repository = sqlSugarRepository; + dbClient = repository.Context; + } + /// + /// 添加记录 + /// + /// + /// + [CapSubscribe("result.service.insert")] + public async Task InsertResultAsync(ResultS2SDto data) + { + bool isfrist = false; + if (data.LastHeartTime.HasValue && data.LastHeartTime.Value.Date != DateTime.Now.Date) + { + isfrist = true; + } + await dbClient.Ado.UseStoredProcedure().ExecuteCommandAsync("Proc_InsertResult", new + { + deviceid = data.DeviceId, + businessid = data.BusinessId, + resultid = data.ResultId, + imei = data.imei, + iccid = data.iccid, + imsi = data.imsi, + time = DateTime.Now, + latitude = data.latitude, + longitude = data.longtitude, + sign = data.gslq, + city = "", + area = data.trash, + wastetype = data.wastetype, + weigth = data.weight, + isheart = 0, + tare = data.Tare, + isfrist = isfrist + }); + } + + + /// + /// 更新记录上报结果 + /// + /// + /// + [CapSubscribe("result.service.update")] + public async Task UpdateStatusAsync(UpdateStatusDto data) + { + Guid resultid = Guid.Empty; + if (!string.IsNullOrEmpty(data.ResultId) && Guid.TryParse(data.ResultId, out resultid)) + { + if (await dbClient.Queryable().AnyAsync(x => x.ResultId == resultid)) + { + await dbClient.Updateable().SetColumns(x => new W_ResultExt + { + Status = data.status + }).Where(x => x.ResultId == resultid).ExecuteCommandAsync(); + } + else + { + var insertdata = new W_ResultExt + { + Id = IDGen.NextID(), + Status = data.status, + CreateTime = DateTime.Now, + ResultId = resultid + }; + await dbClient.Insertable(insertdata).ExecuteCommandAsync(); + } + } + } + + /// + /// 心跳数据上报 + /// + /// + /// + [CapSubscribe("device.service.postheart")] + public async Task UpdateHeartInfoAsync(DevHeartRequestDto data) + { + var device = await dbClient.Queryable().FirstAsync(x => x.Ecode == data.ECode); + if (device == null) + { + return; + } + if (await dbClient.Queryable().AnyAsync(x => x.DeviceId == device.Id)) + { + //更新设备心跳信息 + if (data.Latitude == 0 || data.Longitude == 0) + { + await dbClient.Updateable() + .SetColumns(x => new W_DeviceData + { + LastBeatTime = DateTime.Now + }) + .Where(x => x.DeviceId == device.Id).ExecuteCommandAsync(); + } + else + { + string longitude = data.Longitude.ToString(); + string Latitude = data.Latitude.ToString(); + await dbClient.Updateable() + .SetColumns(x => new W_DeviceData + { + LastBeatTime = DateTime.Now, + Longitude = longitude, + Latitude = Latitude + }) + .Where(x => x.DeviceId == device.Id).ExecuteCommandAsync(); + } + } + else + { + var insertdata = new W_DeviceData + { + DeviceId = device.Id, + Sign = data.GSLQ.ToString(), + IMSI = data.IMSI, + ICCID = data.ICCID, + IMEI = data.IMEI, + LastBeatTime = DateTime.Now, + Latitude = data.Latitude.ToString(), + Longitude = data.Longitude.ToString() + }; + await dbClient.Insertable(insertdata).ExecuteCommandAsync(); + } + + } + + /// + /// 更新设备开机信息 + /// + /// + /// + [CapSubscribe("device.service.update")] + public async Task UpdateRegInfoAsync(Guid deviceid) + { + //更新开机时间 + if (await dbClient.Queryable().AnyAsync(x => x.DeviceId == deviceid)) + { + await dbClient.Updateable() + .SetColumns(x => new W_DeviceData + { + LastStartTime = DateTime.Now + }) + .Where(x => x.DeviceId == deviceid).ExecuteCommandAsync(); + } + else + { + var insertdata = new W_DeviceData + { + DeviceId = deviceid, + Sign = "", + IMSI = "", + ICCID = "", + IMEI = "", + Latitude = "0", + Longitude = "0", + LastStartTime = DateTime.Now + }; + await dbClient.Insertable(insertdata).ExecuteCommandAsync(); + } + } + + /// + /// 更新设备版本信息 + /// + /// + /// + [CapSubscribe("device.service.updatever")] + public async Task UpdateVersionAsync(DeviceVerS2SDto data) + { + var deivce = await dbClient.Queryable().Select(x=>new W_Device { Id=x.Id}).FirstAsync(x => x.Ecode == data.ecode); + if(deivce == null) + { + return; + } + //更新版本号 + if (await dbClient.Queryable().AnyAsync(x => x.DeviceId == deivce.Id)) + { + await dbClient.Updateable() + .SetColumns(x => new W_DeviceData + { + Version = data.ver + }) + .Where(x => x.DeviceId == deivce.Id).ExecuteCommandAsync(); + } + else + { + var insertdata = new W_DeviceData + { + DeviceId = deivce.Id, + Sign = "", + IMSI = "", + ICCID = "", + IMEI = "", + Latitude = "0", + Longitude = "0", + LastStartTime = DateTime.Now, + Version = data.ver + }; + await dbClient.Insertable(insertdata).ExecuteCommandAsync(); + } + } + } +} diff --git a/Waste.Application/ThirdApiInfo/IOpenService.cs b/Waste.Application/ThirdApiInfo/IOpenService.cs index 77ef8bd..bfd4341 100644 --- a/Waste.Application/ThirdApiInfo/IOpenService.cs +++ b/Waste.Application/ThirdApiInfo/IOpenService.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; +using Waste.Application.SubscribeInfo; namespace Waste.Application.ThirdApiInfo { @@ -37,5 +38,11 @@ namespace Waste.Application.ThirdApiInfo /// /// Task UpdateStatusAsync(UpdateStatusDto data); + /// + /// 更新设备版本信息 + /// + /// + /// + Task UpdateVersionAsync(DeviceVerS2SDto data); } } diff --git a/Waste.Application/ThirdApiInfo/OpenAppService.cs b/Waste.Application/ThirdApiInfo/OpenAppService.cs index 796274f..e7b35e9 100644 --- a/Waste.Application/ThirdApiInfo/OpenAppService.cs +++ b/Waste.Application/ThirdApiInfo/OpenAppService.cs @@ -14,6 +14,7 @@ using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; +using Waste.Application.SubscribeInfo; namespace Waste.Application.ThirdApiInfo { @@ -83,7 +84,7 @@ namespace Waste.Application.ThirdApiInfo /// [HttpPost] [Route("api/reportbug/Post")] - public async Task PostAsync([FromQuery]string ecode="") + public async Task PostAsync([FromQuery] string ecode = "") { var Request = _httpContextAccessor.HttpContext.Request; //先保存上传的图片 @@ -115,7 +116,7 @@ namespace Waste.Application.ThirdApiInfo } else { - string[] _permittedExtensions = {}; + string[] _permittedExtensions = { }; long _fileSizeLimit = 1048576 * 10; string rootname = $"/bugs/{DateTime.Now.ToString("yyyyMMdd")}"; string savefolder = _hostingEnvironment.WebRootPath; @@ -195,7 +196,7 @@ namespace Waste.Application.ThirdApiInfo /// [HttpPost] [Route("api/reportbug/postbug")] - public object PostBug(BugModel bug) + public object PostBug(BugModel bug) { var errmsg = $"机器码:{bug.ecode},位置:{bug.ExceptionPos},信息:{bug.ExceptionInfo}"; return new @@ -218,8 +219,13 @@ namespace Waste.Application.ThirdApiInfo [HttpGet] [QueryParameters] [Route("api/upgrade/get")] - public async Task GetAsync(string type, string ecode = "",int myver=400) + public async Task GetAsync(string type, string ecode = "", int myver = 400) { + await _openService.UpdateVersionAsync(new DeviceVerS2SDto + { + ecode = ecode, + ver = myver.ToString() + }); string rootpath = _hostingEnvironment.WebRootPath; //读取文件,返回升级信息 var path = $"{rootpath}/apks/upgrade/{type}.txt"; diff --git a/Waste.Application/ThirdApiInfo/OpenService.cs b/Waste.Application/ThirdApiInfo/OpenService.cs index dcf621d..1fe5f86 100644 --- a/Waste.Application/ThirdApiInfo/OpenService.cs +++ b/Waste.Application/ThirdApiInfo/OpenService.cs @@ -1,4 +1,5 @@ -using Furion; +using DotNetCore.CAP; +using Furion; using Furion.DependencyInjection; using Furion.DistributedIDGenerator; using Nirvana.Common; @@ -8,6 +9,7 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; +using Waste.Application.SubscribeInfo; using Waste.Domain; namespace Waste.Application.ThirdApiInfo @@ -27,12 +29,14 @@ namespace Waste.Application.ThirdApiInfo private readonly SqlSugarClient dbClient; private readonly ISuZhouService _suZhouService; private readonly ILoggerService _loggerService; - public OpenService(ISqlSugarRepository sqlSugarRepository, ISuZhouService suZhouService, ILoggerService loggerService) + private readonly ICapPublisher _capBus; + public OpenService(ISqlSugarRepository sqlSugarRepository, ISuZhouService suZhouService, ILoggerService loggerService, ICapPublisher capPublisher) { repository = sqlSugarRepository; dbClient = repository.Context; _suZhouService = suZhouService; _loggerService = loggerService; + _capBus = capPublisher; } /// /// 更新上报状态 @@ -41,30 +45,8 @@ namespace Waste.Application.ThirdApiInfo /// public async Task UpdateStatusAsync(UpdateStatusDto data) { - Guid resultid = Guid.Empty; - if (!string.IsNullOrEmpty(data.ResultId) && Guid.TryParse(data.ResultId, out resultid)) - { - if (await dbClient.Queryable().AnyAsync(x => x.ResultId == resultid)) - { - await dbClient.Updateable().SetColumns(x => new W_ResultExt - { - Status = data.status - }).Where(x => x.ResultId == resultid).ExecuteCommandAsync(); - } - else - { - var insertdata = new W_ResultExt - { - Id = IDGen.NextID(), - Status = data.status, - CreateTime = DateTime.Now, - ResultId = resultid - }; - await dbClient.Insertable(insertdata).ExecuteCommandAsync(); - } - return new ResultInfo(ResultState.SUCCESS, "success"); - } - return new ResultInfo(ResultState.SUCCESS, "记录id未找到"); + await _capBus.PublishAsync("result.service.update", data); + return new ResultInfo(ResultState.SUCCESS, "success"); } /// /// 获取设备上报相关信息 @@ -75,155 +57,97 @@ namespace Waste.Application.ThirdApiInfo { //更新上报记录结果 Guid resultid = Guid.Empty; - if (!string.IsNullOrEmpty(data.ResultId) && Guid.TryParse(data.ResultId, out resultid)) + var device = await dbClient.Queryable().FirstAsync(x => x.Ecode == data.ECode); + if (device == null) { - var device = await dbClient.Queryable().FirstAsync(x => x.Ecode == data.ECode); - if (device == null) + return new ResultInfo(ResultState.FAIL, "设备未找到"); + } + var returndata = new GetDevInfoResponseDto + { + ResultId = IDGen.NextID(), + UserId = UserId, + PostUrl = ApiUrl + }; + var devicesecret = await dbClient.Queryable().FirstAsync(x => x.DeviceId == device.Id); + if (devicesecret == null || string.IsNullOrEmpty(devicesecret.Secret) + || string.IsNullOrEmpty(devicesecret.SecretHash) + || string.IsNullOrEmpty(devicesecret.DevId)) + { + return new ResultInfo(ResultState.FAIL, "设备还未获取验证信息"); + } + //解析协议,IC卡数据@垃圾桶编号@厨余垃圾@7.91 + // 00000000003031 40 0F00010009 40 C6E4CBFBC0ACBBF8 40 31352E39 + // 00000000003031 40 000F000002 40 C6E4CBFBC0ACBBF8 40 35312E30 0D0A + if (!string.IsNullOrEmpty(data.data) && data.data.Length > 52) + { + data.data = data.data.Replace(" ", ""); + //收到的为16进制,对数据进行解析,0-4预留,5-垃圾种类,6-垃圾桶大小,7-@,8-12垃圾桶编号,13@,14-21垃圾种类汉字,22@,23-结束重量, OD OA 回车换行 + data.data = data.data.Substring(0, data.data.Length - 4); + var trashhex = data.data.Substring(16, 10); //垃圾桶编号 + var typehex = data.data.Substring(28, 16); //垃圾种类 + var sizehex = data.data.Substring(12, 2);//桶大小,30-小桶,31-大桶 + var weighthex = data.data.Substring(46, data.data.Length - 46); + returndata.trash = HextToDec(trashhex).ToString(); //垃圾桶编号使用10进制 + var type = GetChsFromHex(typehex); + var weight = GetChsFromHex(weighthex); + returndata.type = TrashType(type); + returndata.Weight = weight.ToDouble(); + //计算净重,毛重-皮重=净重,如果净重小于等于0则不上报保存 + returndata.Weight = (returndata.Weight - device.Tare.ToDouble()).ToDouble(2); + if (returndata.Weight <= 0) { - return new ResultInfo(ResultState.FAIL, "设备未找到"); + _loggerService.AddLogger($"{data.ECode},{device.Name},重量小于等于0:{returndata.ToJson()}", 1); + return new ResultInfo(ResultState.FAIL, "无效的重量"); } - var devicesecret = await dbClient.Queryable().FirstAsync(x => x.DeviceId == device.Id); - if (devicesecret == null || string.IsNullOrEmpty(devicesecret.Secret) - || string.IsNullOrEmpty(devicesecret.SecretHash) - || string.IsNullOrEmpty(devicesecret.DevId)) + //检查是否为15分钟内第一次上报 + var time15 = DateTime.Now.AddMinutes(-15); + if (await dbClient.Queryable().AnyAsync(x => x.DeviceId == device.Id && x.LastTrash == returndata.trash && x.LastHeartTime > time15)) { - return new ResultInfo(ResultState.FAIL, "设备还未获取验证信息"); + _loggerService.AddLogger($"{data.ECode},{device.Name},重复垃圾桶编号的数据:{returndata.ToJson()}", 1); + return new ResultInfo(ResultState.FAIL, "15分钟内同一垃圾桶编号上报"); } - int timestamp = _suZhouService.GetUTCTimestamp(); - int noncestr = _suZhouService.GetNonce(); - var result = await dbClient.Queryable().FirstAsync(x => x.Id == resultid); - if (result == null) + returndata.IsSuccessed = true; + //记录数据 + data.IMEI = data.IMEI.ToStr(); + data.ICCID = data.ICCID.ToStr(); + data.IMSI = data.IMSI.ToStr(); + await _capBus.PublishAsync("result.service.insert", new ResultS2SDto { - return new ResultInfo(ResultState.SUCCESS, "记录id未找到"); - } - var returndata = new GetDevInfoResponseDto - { - DeviceId = devicesecret.DevId, - noncestr = noncestr, - timestamp = timestamp, - Secret = devicesecret.Secret, - SecretHash = devicesecret.SecretHash, - UserId = UserId, - PostUrl = ApiUrl, - ScanningTime = timestamp, - ResultId = resultid, - trash = result.Registration, - Weight = result.GrossWeight.ToDouble(), - status = 0, - IsSuccessed = true, - type = TrashType(result.WasteType) - }; - string[] paramlist = new string[] { - returndata.Weight.ToString(),returndata.trash,returndata.type.ToString(),returndata.ScanningTime.ToString(),returndata.status.ToString()}; - returndata.sign = _suZhouService.GetUserApiSign(returndata.Secret, paramlist); - return new ResultInfo(ResultState.SUCCESS, "success", returndata); + BusinessId = device.Businessid, + DeviceId = device.Id, + gslq = data.GSLQ, + iccid = data.ICCID, + imei = data.IMEI, + imsi = data.IMSI, + LastHeartTime = device.LastHeartTime, + latitude = data.Latitude, + longtitude = data.Longitude, + ResultId = returndata.ResultId, + Tare = device.Tare, + trash = returndata.trash, + wastetype = type, + weight = weight + }); } else { - var device = await dbClient.Queryable().FirstAsync(x => x.Ecode == data.ECode); - if (device == null) - { - return new ResultInfo(ResultState.FAIL, "设备未找到"); - } - var returndata = new GetDevInfoResponseDto - { - ResultId = IDGen.NextID(), - UserId = UserId, - PostUrl = ApiUrl - }; - //解析协议,IC卡数据@垃圾桶编号@厨余垃圾@7.91 - // 00000000003031 40 0F00010009 40 C6E4CBFBC0ACBBF8 40 31352E39 - // 00000000003031 40 000F000002 40 C6E4CBFBC0ACBBF8 40 35312E30 0D0A - if (!string.IsNullOrEmpty(data.data) && data.data.Length > 52) - { - data.data = data.data.Replace(" ", ""); - //收到的为16进制,对数据进行解析,0-4预留,5-垃圾种类,6-垃圾桶大小,7-@,8-12垃圾桶编号,13@,14-21垃圾种类汉字,22@,23-结束重量, OD OA 回车换行 - data.data = data.data.Substring(0, data.data.Length - 4); - var trashhex = data.data.Substring(16, 10); //垃圾桶编号 - var typehex = data.data.Substring(28, 16); //垃圾种类 - var sizehex = data.data.Substring(12, 2);//桶大小,30-小桶,31-大桶 - var weighthex = data.data.Substring(46, data.data.Length - 46); - returndata.trash = HextToDec(trashhex).ToString(); //垃圾桶编号使用10进制 - var type = GetChsFromHex(typehex); - var weight = GetChsFromHex(weighthex); - returndata.type = TrashType(type); - returndata.Weight = weight.ToDouble(); - //计算净重,毛重-皮重=净重,如果净重小于等于0则不上报保存 - returndata.Weight = (returndata.Weight - device.Tare.ToDouble()).ToDouble(2); - if (returndata.Weight <= 0) - { - _loggerService.AddLogger($"重量小于等于0:{returndata.ToJson()}", 1); - return new ResultInfo(ResultState.FAIL, "无效的重量"); - } - //检查是否为15分钟内第一次上报 - var time15 = DateTime.Now.AddMinutes(-15); - if (await dbClient.Queryable().AnyAsync(x => x.DeviceId == device.Id && x.Registration == returndata.trash && x.CreateTime > time15)) - { - _loggerService.AddLogger($"重复垃圾桶编号的数据:{returndata.ToJson()}", 1); - return new ResultInfo(ResultState.FAIL, "15分钟内同一垃圾桶编号上报"); - } - returndata.IsSuccessed = true; - //保存测量结果 - var devicedata = await dbClient.Queryable().FirstAsync(x => x.DeviceId == device.Id); - DateTime time = DateTime.Now; - //检查设备是否为今天第一次上报 - bool isfrist = false; - if (device.LastHeartTime.HasValue && device.LastHeartTime.Value.Date != DateTime.Now.Date) - { - isfrist = true; - } - //记录数据 - data.IMEI = data.IMEI.ToStr(); - data.ICCID = data.ICCID.ToStr(); - data.IMSI = data.IMSI.ToStr(); - await dbClient.Ado.UseStoredProcedure().ExecuteCommandAsync("Proc_InsertResult", new - { - deviceid = device.Id, - businessid = device.Businessid, - resultid = returndata.ResultId, - imei = data.IMEI, - iccid = data.ICCID, - imsi = data.IMSI, - time = time, - latitude = data.Latitude, - longitude = data.Longitude, - sign = data.GSLQ, - city = "", - area = returndata.trash, - wastetype = type, - weigth = weight, - isheart = 0, - tare = device.Tare, - isfrist = isfrist - }); - } - else - { - _loggerService.AddLogger($"协议格式不正确:{data.ToJson()}", 1); - return new ResultInfo(ResultState.FAIL, "协议格式不正确"); - } - var devicesecret = await dbClient.Queryable().FirstAsync(x => x.DeviceId == device.Id); - if (devicesecret == null || string.IsNullOrEmpty(devicesecret.Secret) - || string.IsNullOrEmpty(devicesecret.SecretHash) - || string.IsNullOrEmpty(devicesecret.DevId)) - { - return new ResultInfo(ResultState.FAIL, "设备还未获取验证信息"); - } - int timestamp = _suZhouService.GetUTCTimestamp(); - int noncestr = _suZhouService.GetNonce(); - returndata.DeviceId = devicesecret.DevId; - returndata.noncestr = noncestr; - returndata.timestamp = timestamp; - returndata.Secret = devicesecret.Secret; - returndata.SecretHash = devicesecret.SecretHash; - returndata.ScanningTime = timestamp; - string[] paramlist = new string[] { + _loggerService.AddLogger($"{data.ECode},{device.Name},协议格式不正确:{data.ToJson()}", 1); + return new ResultInfo(ResultState.FAIL, "协议格式不正确"); + } + int timestamp = _suZhouService.GetUTCTimestamp(); + int noncestr = _suZhouService.GetNonce(); + returndata.DeviceId = devicesecret.DevId; + returndata.noncestr = noncestr; + returndata.timestamp = timestamp; + returndata.Secret = devicesecret.Secret; + returndata.SecretHash = devicesecret.SecretHash; + returndata.ScanningTime = timestamp; + string[] paramlist = new string[] { returndata.Weight.ToString(),returndata.trash,returndata.type.ToString(),returndata.ScanningTime.ToString(),returndata.status.ToString() }; - returndata.sign = _suZhouService.GetUserApiSign(returndata.Secret, paramlist); - _loggerService.AddLogger($"发送的数据:{returndata.ToJson()}", 1); - return new ResultInfo(ResultState.SUCCESS, "success", returndata); - } + returndata.sign = _suZhouService.GetUserApiSign(returndata.Secret, paramlist); + _loggerService.AddLogger($"{data.ECode},{device.Name},发送的数据:{returndata.ToJson()}", 1); + return new ResultInfo(ResultState.SUCCESS, "success", returndata); } /// /// 16进制转汉字 @@ -314,52 +238,11 @@ namespace Waste.Application.ThirdApiInfo /// public async Task PostHeartAsync(DevHeartRequestDto data) { - var device = await dbClient.Queryable().FirstAsync(x => x.Ecode == data.ECode); - if (device == null) + if (!await dbClient.Queryable().AnyAsync(x => x.Ecode == data.ECode)) { return new ResultInfo(ResultState.FAIL, "设备未找到"); } - if (await dbClient.Queryable().AnyAsync(x => x.DeviceId == device.Id)) - { - //更新设备心跳信息 - if (data.Latitude == 0 || data.Longitude == 0) - { - await dbClient.Updateable() - .SetColumns(x => new W_DeviceData - { - LastBeatTime = DateTime.Now - }) - .Where(x => x.DeviceId == device.Id).ExecuteCommandAsync(); - } - else - { - string longitude = data.Longitude.ToString(); - string Latitude = data.Latitude.ToString(); - await dbClient.Updateable() - .SetColumns(x => new W_DeviceData - { - LastBeatTime = DateTime.Now, - Longitude = longitude, - Latitude = Latitude - }) - .Where(x => x.DeviceId == device.Id).ExecuteCommandAsync(); - } - } - else - { - var insertdata = new W_DeviceData - { - DeviceId = device.Id, - Sign = data.GSLQ.ToString(), - IMSI = data.IMSI, - ICCID = data.ICCID, - IMEI = data.IMEI, - LastBeatTime = DateTime.Now, - Latitude = data.Latitude.ToString(), - Longitude = data.Longitude.ToString() - }; - await dbClient.Insertable(insertdata).ExecuteCommandAsync(); - } + await _capBus.PublishAsync("device.service.postheart", data); return new ResultInfo(ResultState.SUCCESS, "success"); } /// @@ -375,30 +258,8 @@ namespace Waste.Application.ThirdApiInfo return new ResultInfo(ResultState.FAIL, "设备未找到", new DevRegInfoResponseDto()); } //更新开机时间 - if (await dbClient.Queryable().AnyAsync(x => x.DeviceId == device.Id)) - { - await dbClient.Updateable() - .SetColumns(x => new W_DeviceData - { - LastStartTime = DateTime.Now - }) - .Where(x => x.DeviceId == device.Id).ExecuteCommandAsync(); - } - else - { - var insertdata = new W_DeviceData - { - DeviceId = device.Id, - Sign = "", - IMSI = "", - ICCID = "", - IMEI = "", - Latitude = "0", - Longitude = "0", - LastStartTime = DateTime.Now - }; - await dbClient.Insertable(insertdata).ExecuteCommandAsync(); - } + await _capBus.PublishAsync("device.service.update", device.Id); + var data = new DevRegInfoResponseDto { status = 0, @@ -450,5 +311,14 @@ namespace Waste.Application.ThirdApiInfo } return returnStr; } + /// + /// 更新设备版本信息 + /// + /// + /// + public async Task UpdateVersionAsync(DeviceVerS2SDto data) + { + await _capBus.PublishAsync("device.service.updatever", data); + } } } diff --git a/Waste.Application/Waste.Application.xml b/Waste.Application/Waste.Application.xml index 301125c..37baef3 100644 --- a/Waste.Application/Waste.Application.xml +++ b/Waste.Application/Waste.Application.xml @@ -1701,6 +1701,176 @@ + + + 测量记录 + + + + + 设备ID + + + + + 最近使用时间 + + + + + 记录ID + + + + + 设备服务商ID + + + + + 设备的IMEI + + + + + ICCID + + + + + IMSI + + + + + 纬度 + + + + + 经度 + + + + + 信号强度 + + + + + 垃圾类型 + + + + + 垃圾桶编号 + + + + + 毛重 + + + + + 皮重 + + + + + 设备版本信息 + + + + + 设备机器码 + + + + + 版本号 + + + + + CAP订阅相关接口 + + + + + 添加记录 + + + + + + + 更新记录上报结果 + + + + + + + 更新设备开机信息 + + + + + + + 心跳数据上报 + + + + + + + 更新设备版本信息 + + + + + + + CAP订阅相关接口 + + + + + 添加记录 + + + + + + + 更新记录上报结果 + + + + + + + 心跳数据上报 + + + + + + + 更新设备开机信息 + + + + + + + 更新设备版本信息 + + + + 地址列表 @@ -2235,6 +2405,13 @@ + + + 更新设备版本信息 + + + + 开放数据 @@ -2350,6 +2527,13 @@ + + + 更新设备版本信息 + + + + 垃圾分类列表 diff --git a/Waste.Core/Waste.Core.csproj b/Waste.Core/Waste.Core.csproj index 2da47b9..d8db6fa 100644 --- a/Waste.Core/Waste.Core.csproj +++ b/Waste.Core/Waste.Core.csproj @@ -15,11 +15,14 @@ - - - - - + + + + + + + + diff --git a/Waste.CreateDB/CreateTable.cs b/Waste.CreateDB/CreateTable.cs new file mode 100644 index 0000000..38ef20b --- /dev/null +++ b/Waste.CreateDB/CreateTable.cs @@ -0,0 +1,44 @@ +using SqlSugar; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Waste.CreateDB +{ + public class CreateTable + { + public SqlSugarClient Db; + public CreateTable() + { + Db = new SqlSugarClient(new ConnectionConfig() + { + ConnectionString = "Server=123.60.2.99,4331;Database=waste;uid=jutian_user;pwd=jutian1qaz@WSX;", + DbType = DbType.SqlServer,//设置数据库类型 + IsAutoCloseConnection = true,//自动释放数据库,如果存在事务,在事务结束之后释放。 + InitKeyType = InitKeyType.Attribute//从实体特性中读取主键自增列信息 + }); + Db.Aop.OnLogExecuting = (sql, pars) => + { + Console.WriteLine(sql + "\r\n" + Db.Utilities.SerializeObject + (pars.ToDictionary(it => it.ParameterName, it => it.Value))); + Console.WriteLine(); + }; + } + + public void Create(bool Backup = false, int StringDefaultLength = 50, params Type[] types) + { + // Db.CodeFirst.SetStringDefaultLength(StringDefaultLength); + Db.DbMaintenance.CreateDatabase(); + if (Backup) + { + Db.CodeFirst.BackupTable().InitTables(types); + } + else + { + Db.CodeFirst.InitTables(types); + } + } + } +} diff --git a/Waste.CreateDB/Program.cs b/Waste.CreateDB/Program.cs new file mode 100644 index 0000000..5206480 --- /dev/null +++ b/Waste.CreateDB/Program.cs @@ -0,0 +1,18 @@ +using System; +using Waste.Domain; + +namespace Waste.CreateDB +{ + class Program + { + static void Main(string[] args) + { + Console.WriteLine("开始创建表!"); + var context = new CreateTable(); + context.Create(false, 50, + typeof(W_DeviceData), + typeof(W_DeviceResult) + ); + } + } +} diff --git a/Waste.CreateDB/Waste.CreateDB.csproj b/Waste.CreateDB/Waste.CreateDB.csproj new file mode 100644 index 0000000..3aa1983 --- /dev/null +++ b/Waste.CreateDB/Waste.CreateDB.csproj @@ -0,0 +1,16 @@ + + + + Exe + net5.0 + + + + + + + + + + + diff --git a/Waste.Domain/DataModel/W_DeviceData.cs b/Waste.Domain/DataModel/W_DeviceData.cs index b930410..9926ea4 100644 --- a/Waste.Domain/DataModel/W_DeviceData.cs +++ b/Waste.Domain/DataModel/W_DeviceData.cs @@ -1,71 +1,71 @@ using SqlSugar; +using System; namespace Waste.Domain { /// /// 设备信息 /// + [SugarTable("W_DeviceData", TableDescription = "设备信息", IsDisabledUpdateAll = false, IsDisabledDelete = true)] public class W_DeviceData { /// - /// 设备信息 - /// - public W_DeviceData() - { - } - - private System.Guid _DeviceId; - /// - /// + /// 设备ID /// [SugarColumn(IsPrimaryKey = true)] - public System.Guid DeviceId { get { return this._DeviceId; } set { this._DeviceId = value; } } + public Guid DeviceId { get; set; } - private System.String _ICCID; /// /// ICCID /// - public System.String ICCID { get { return this._ICCID; } set { this._ICCID = value?.Trim(); } } + [SugarColumn(ColumnDataType = "varchar(50)", ColumnDescription = "ICCID")] + public string ICCID { get; set; } - private System.String _IMEI; /// /// IMEI /// - public System.String IMEI { get { return this._IMEI; } set { this._IMEI = value?.Trim(); } } - private System.String _IMSI; + [SugarColumn(ColumnDataType = "varchar(50)", ColumnDescription = "IMEI")] + public string IMEI { get; set; } /// /// SIM卡IMSI /// - public System.String IMSI { get { return this._IMSI; } set { this._IMSI = value?.Trim(); } } + [SugarColumn(ColumnDataType = "varchar(50)", ColumnDescription = "SIM卡IMSI")] + public string IMSI { get; set; } - private System.String _Longitude; /// /// 经度 /// - public System.String Longitude { get { return this._Longitude; } set { this._Longitude = value?.Trim(); } } + [SugarColumn(ColumnDataType = "varchar(50)", ColumnDescription = "经度")] + public string Longitude { get; set; } - private System.String _Latitude; /// /// 纬度 /// - public System.String Latitude { get { return this._Latitude; } set { this._Latitude = value?.Trim(); } } + [SugarColumn(ColumnDataType = "varchar(50)", ColumnDescription = "纬度")] + public string Latitude { get; set; } - private System.DateTime? _LastBeatTime; /// /// 最近心跳时间 /// - public System.DateTime? LastBeatTime { get { return this._LastBeatTime; } set { this._LastBeatTime = value; } } + [SugarColumn(IsNullable =true, ColumnDescription = "最近心跳时间")] + public DateTime? LastBeatTime { get; set; } - private System.DateTime? _LastStartTime; /// /// 最近开机时间 /// - public System.DateTime? LastStartTime { get { return this._LastStartTime; } set { this._LastStartTime = value; } } + [SugarColumn(IsNullable =true, ColumnDescription = "最近开机时间")] + public DateTime? LastStartTime { get; set; } - private System.String _Sign; /// /// 信号强度 /// - public System.String Sign { get { return this._Sign; } set { this._Sign = value?.Trim(); } } + [SugarColumn(ColumnDataType = "varchar(100)", ColumnDescription = "信号强度")] + public string Sign { get; set; } + + /// + /// 设备最新的app版本号 + /// + [SugarColumn(ColumnDataType = "varchar(50)", ColumnDescription = "设备最新的app版本号", IsNullable =true)] + public string Version { get; set; } } } diff --git a/Waste.Domain/DataModel/W_DeviceResult.cs b/Waste.Domain/DataModel/W_DeviceResult.cs new file mode 100644 index 0000000..a43c91f --- /dev/null +++ b/Waste.Domain/DataModel/W_DeviceResult.cs @@ -0,0 +1,34 @@ +using SqlSugar; +using System; + +namespace Waste.Domain +{ + /// + /// 设备测量有关数据 + /// + [SugarTable("W_DeviceResult", TableDescription = "设备测量有关数据", IsDisabledUpdateAll = false, IsDisabledDelete = true)] + public class W_DeviceResult + { + /// + /// 设备ID + /// + [SugarColumn(IsPrimaryKey = true)] + public Guid DeviceId { get; set; } + /// + /// 最近使用的垃圾桶编号 + /// + [SugarColumn(ColumnDataType = "varchar(50)", ColumnDescription = "最近使用的垃圾桶编号")] + public string LastTrash { get; set; } + + /// + /// 最近使用时间 + /// + [SugarColumn(ColumnDescription = "最近使用时间")] + public DateTime LastHeartTime { get; set; } + /// + /// 最近的记录ID + /// + [SugarColumn(ColumnDescription = "最近的记录ID")] + public Guid ResultId { get; set; } + } +} diff --git a/Waste.Web.Core/Startup.cs b/Waste.Web.Core/Startup.cs index 3cf1a19..540bef2 100644 --- a/Waste.Web.Core/Startup.cs +++ b/Waste.Web.Core/Startup.cs @@ -10,6 +10,7 @@ using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Nirvana.Common; using Serilog; +using System; using System.Collections.Generic; using System.IO; using System.Threading.Tasks; @@ -21,6 +22,7 @@ namespace Waste.Web.Core { public void ConfigureServices(IServiceCollection services) { + var configuration = App.Configuration; services.AddSession();//使用Session //services.AddJwt(options => //{ @@ -30,6 +32,22 @@ namespace Waste.Web.Core services.AddCorsAccessor(); // services.AddRemoteRequest(); services.AddHttpClient(); + + //添加CAP + services.AddCap(x => { + //配置rabbitmq支持 + string port = configuration["RabbitmqSetting:Port"]; + int p = Convert.ToInt32(port); + x.UseRabbitMQ(opt => { + opt.HostName = configuration["RabbitmqSetting:HostName"]; //配置ip地址 + opt.Port = p;//配置端口 + opt.UserName = configuration["RabbitmqSetting:UserName"];//配置用户名 + opt.Password = configuration["RabbitmqSetting:Password"];//配置Miami + }); + //配置sqlserver支持 + x.UseSqlServer(configuration["RabbitmqSetting:DBConnection"]); + }); + services.AddControllers(options => { options.EnableEndpointRouting = true; }) diff --git a/Waste.Web.Entry/Pages/Device/Detail.cshtml b/Waste.Web.Entry/Pages/Device/Detail.cshtml new file mode 100644 index 0000000..aa72a91 --- /dev/null +++ b/Waste.Web.Entry/Pages/Device/Detail.cshtml @@ -0,0 +1,4 @@ +@page +@model Waste.Web.Entry.Pages.Device.DetailModel +@{ +} diff --git a/Waste.Web.Entry/Pages/Device/Detail.cshtml.cs b/Waste.Web.Entry/Pages/Device/Detail.cshtml.cs new file mode 100644 index 0000000..a4e6ed3 --- /dev/null +++ b/Waste.Web.Entry/Pages/Device/Detail.cshtml.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.RazorPages; + +namespace Waste.Web.Entry.Pages.Device +{ + public class DetailModel : BaseModel + { + public void OnGet() + { + } + } +} diff --git a/Waste.Web.Entry/Pages/Device/Index.cshtml b/Waste.Web.Entry/Pages/Device/Index.cshtml index f438bf7..46473a7 100644 --- a/Waste.Web.Entry/Pages/Device/Index.cshtml +++ b/Waste.Web.Entry/Pages/Device/Index.cshtml @@ -34,6 +34,7 @@