805 lines
34 KiB
C#
805 lines
34 KiB
C#
using DotNetCore.CAP;
|
||
using Furion;
|
||
using Furion.DependencyInjection;
|
||
using Furion.DistributedIDGenerator;
|
||
using Microsoft.Extensions.Caching.Distributed;
|
||
using Nirvana.Common;
|
||
using SqlSugar;
|
||
using System;
|
||
using System.Collections.Generic;
|
||
using System.Linq;
|
||
using System.Text;
|
||
using System.Threading.Tasks;
|
||
using Furion.LinqBuilder;
|
||
using Waste.Application.SubscribeInfo;
|
||
using Waste.Domain;
|
||
using Waste.Domain.DataModel;
|
||
using System.Net.Http;
|
||
using Newtonsoft.Json.Linq;
|
||
|
||
namespace Waste.Application.ThirdApiInfo
|
||
{
|
||
/// <summary>
|
||
/// 设备对接接口
|
||
/// </summary>
|
||
public class OpenService : IOpenService, ITransient
|
||
{
|
||
private static string ApiUrl = App.Configuration["SZDevPlatSetting:ApiUrl"];
|
||
private static string UserId = App.Configuration["SZDevPlatSetting:UserId"];
|
||
private static string ApiSecret = App.Configuration["SZDevPlatSetting:ApiSecret"];
|
||
private static string ApiSecretHash = App.Configuration["SZDevPlatSetting:ApiSecretHash"];
|
||
private static string WebSocketUrl = App.Configuration["SZDevPlatSetting:SocketUrl"];
|
||
|
||
private readonly ISqlSugarRepository<W_Device> repository;
|
||
private readonly SqlSugarClient dbClient;
|
||
private readonly ISuZhouService _suZhouService;
|
||
private readonly ILoggerService _loggerService;
|
||
private readonly ICapPublisher _capBus;
|
||
private readonly IDistributedCache _cahce;
|
||
private readonly IResultService _resultService;
|
||
private readonly IDistributedIDGenerator _idgen;
|
||
|
||
public OpenService(ISqlSugarRepository<W_Device> sqlSugarRepository, ISuZhouService suZhouService, ILoggerService loggerService, ICapPublisher capPublisher, IDistributedCache distributedCache, IResultService resultService, IDistributedIDGenerator distributedIDGenerator)
|
||
{
|
||
repository = sqlSugarRepository;
|
||
dbClient = repository.Context;
|
||
_suZhouService = suZhouService;
|
||
_loggerService = loggerService;
|
||
_capBus = capPublisher;
|
||
_cahce = distributedCache;
|
||
_resultService = resultService;
|
||
_idgen = distributedIDGenerator;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 更新上报状态
|
||
/// </summary>
|
||
/// <param name="data"></param>
|
||
/// <returns></returns>
|
||
public async Task<ResultInfo> UpdateStatusAsync(UpdateStatusDto data)
|
||
{
|
||
//await _capBus.PublishAsync("result.service.update", data);
|
||
//return new ResultInfo(ResultState.SUCCESS, "success");
|
||
Guid resultid = Guid.Empty;
|
||
if (!string.IsNullOrEmpty(data.ResultId) && Guid.TryParse(data.ResultId, out resultid))
|
||
{
|
||
if (await dbClient.Queryable<W_ResultExt>().AnyAsync(x => x.ResultId == resultid))
|
||
{
|
||
await dbClient.Updateable<W_ResultExt>().SetColumns(x => new W_ResultExt
|
||
{
|
||
Status = data.status
|
||
}).Where(x => x.ResultId == resultid).ExecuteCommandAsync();
|
||
}
|
||
else
|
||
{
|
||
var insertdata = new W_ResultExt
|
||
{
|
||
Id = _idgen.Create().ToGuid(),
|
||
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未找到");
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取设备上报相关信息
|
||
/// </summary>
|
||
/// <param name="data"></param>
|
||
/// <returns></returns>
|
||
public async Task<ResultInfo> GetDevInfoAsync(GetDevInfoRequestDto data)
|
||
{
|
||
//更新上报记录结果
|
||
Guid resultid = Guid.Empty;
|
||
//这里进行去重处理
|
||
if (!string.IsNullOrEmpty(data.ResultId) && Guid.TryParse(data.ResultId, out resultid))
|
||
{
|
||
var device = await dbClient.Queryable<W_Device>().FirstAsync(x => x.Ecode == data.ECode);
|
||
if (device == null)
|
||
{
|
||
return new ResultInfo(ResultState.FAIL, "设备未找到");
|
||
}
|
||
var devicesecret = await dbClient.Queryable<W_SZDevice>().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();
|
||
var result = await dbClient.Queryable<W_Result>().FirstAsync(x => x.Id == resultid);
|
||
if (result == null)
|
||
{
|
||
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);
|
||
}
|
||
else
|
||
{
|
||
var device = await dbClient.Queryable<W_Device>().FirstAsync(x => x.Ecode == data.ECode);
|
||
if (device == null)
|
||
{
|
||
return new ResultInfo(ResultState.FAIL, "设备未找到");
|
||
}
|
||
if (device.Status == (int)DeviceStatus.Error)
|
||
{
|
||
return new ResultInfo(ResultState.FAIL, "设备已停止运行");
|
||
}
|
||
var returndata = new GetDevInfoResponseDto
|
||
{
|
||
ResultId = _idgen.Create().ToGuid(),
|
||
UserId = UserId,
|
||
PostUrl = ApiUrl
|
||
};
|
||
var devicesecret = await dbClient.Queryable<W_SZDevice>().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, "设备还未获取验证信息");
|
||
}
|
||
|
||
|
||
// trash@1@62942200205496@4.964 trash@垃圾种类@垃圾桶编号@垃圾重量
|
||
//20250327 添加名称和操作员 trash@5@干垃圾@30654605660104@技术员@0.22 (@干垃圾) 是名称 (@技术员) 是操作员
|
||
if (!string.IsNullOrEmpty(data.data) && data.data.StartsWith("trash@"))
|
||
{
|
||
var arr = data.data.Split('@');
|
||
|
||
if (arr.Length == 4)
|
||
{
|
||
var type = arr.GetListValue(1);
|
||
returndata.trash = arr.GetListValue(2);
|
||
var weight = arr.GetListValue(3);
|
||
var result = await UpdateDevInfo(data, returndata, device, type, weight);
|
||
if (result != null) return result;
|
||
}
|
||
else if (arr.Length == 6)
|
||
{
|
||
var type = arr.GetListValue(1);
|
||
|
||
var typename = arr.GetListValue(2);
|
||
|
||
returndata.trash = arr.GetListValue(3);
|
||
|
||
var name = arr.GetListValue(4);
|
||
|
||
var weight = arr.GetListValue(5);
|
||
|
||
var result = await UpdateDevInfo(data, returndata, device, type, weight, typename, name);
|
||
if (result != null) return result;
|
||
}
|
||
else
|
||
{
|
||
return new ResultInfo(ResultState.FAIL, $"协议格式不正确:{data.ToJson()}");
|
||
}
|
||
}
|
||
//解析协议,IC卡数据@垃圾桶编号@厨余垃圾@7.91
|
||
// 00000000003031 40 0F00010009 40 C6E4CBFBC0ACBBF8 40 31352E39
|
||
// 00000000003031 40 000F000002 40 C6E4CBFBC0ACBBF8 40 35312E30 0D0A
|
||
else 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);
|
||
|
||
var result = await UpdateDevInfo(data, returndata, device, type, weight);
|
||
if (result != null) return result;
|
||
}
|
||
else
|
||
{
|
||
_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($"{data.ECode},{device.Name},发送的数据:{returndata.ToJson()}", 1);
|
||
return new ResultInfo(ResultState.SUCCESS, "success", returndata);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 16进制转10进制
|
||
/// </summary>
|
||
/// <param name="hex"></param>
|
||
/// <returns></returns>
|
||
public long HextToDec(string hex)
|
||
{
|
||
char[] nums = hex.ToCharArray();
|
||
long total = 0;
|
||
try
|
||
{
|
||
for (int i = 0; i < nums.Length; i++)
|
||
{
|
||
String strNum = nums[i].ToString().ToUpper();
|
||
switch (strNum)
|
||
{
|
||
case "A":
|
||
strNum = "10";
|
||
break;
|
||
|
||
case "B":
|
||
strNum = "11";
|
||
break;
|
||
|
||
case "C":
|
||
strNum = "12";
|
||
break;
|
||
|
||
case "D":
|
||
strNum = "13";
|
||
break;
|
||
|
||
case "E":
|
||
strNum = "14";
|
||
break;
|
||
|
||
case "F":
|
||
strNum = "15";
|
||
break;
|
||
|
||
default:
|
||
break;
|
||
}
|
||
double power = Math.Pow(16, Convert.ToDouble(nums.Length - i - 1));
|
||
total += Convert.ToInt64(strNum) * Convert.ToInt64(power);
|
||
}
|
||
}
|
||
catch (System.Exception ex)
|
||
{
|
||
string strErorr = ex.ToString();
|
||
return 0;
|
||
}
|
||
|
||
return total;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 心跳数据上报
|
||
/// </summary>
|
||
/// <param name="data"></param>
|
||
/// <returns></returns>
|
||
public async Task<ResultInfo> PostHeartAsync(DevHeartRequestDto data)
|
||
{
|
||
if (!await dbClient.Queryable<W_Device>().AnyAsync(x => x.Ecode == data.ECode))
|
||
{
|
||
return new ResultInfo(ResultState.FAIL, "设备未找到");
|
||
}
|
||
await _capBus.PublishAsync("device.service.postheart", data);
|
||
return new ResultInfo(ResultState.SUCCESS, "success");
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取设备注册信息,第一次开机使用
|
||
/// </summary>
|
||
/// <param name="ecode"></param>
|
||
/// <returns></returns>
|
||
public async Task<ResultInfo> RegInfoAsync(string ecode)
|
||
{
|
||
var device = await dbClient.Queryable<W_Device>().FirstAsync(x => x.Ecode == ecode);
|
||
if (device == null)
|
||
{
|
||
return new ResultInfo(ResultState.FAIL, "设备未找到", new DevRegInfoResponseDto());
|
||
}
|
||
//更新开机时间
|
||
await _capBus.PublishAsync("device.service.update", device.Id);
|
||
|
||
var data = new DevRegInfoResponseDto
|
||
{
|
||
status = 0,
|
||
WebSocketUrl = WebSocketUrl
|
||
};
|
||
//获取授权信息
|
||
var devicesecret = await dbClient.Queryable<W_SZDevice>().FirstAsync(x => x.DeviceId == device.Id);
|
||
if (devicesecret != null && !string.IsNullOrEmpty(devicesecret.Secret)
|
||
&& !string.IsNullOrEmpty(devicesecret.SecretHash)
|
||
&& !string.IsNullOrEmpty(devicesecret.DevId))
|
||
{
|
||
data.timestamp = _suZhouService.GetUTCTimestamp();
|
||
data.noncestr = _suZhouService.GetNonce();
|
||
data.UserId = UserId;
|
||
data.Secret = devicesecret.Secret;
|
||
data.SecretHash = devicesecret.SecretHash;
|
||
data.DeviceId = devicesecret.DevId.ToString();
|
||
}
|
||
return new ResultInfo(ResultState.SUCCESS, "success", data);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 更新设备版本信息
|
||
/// </summary>
|
||
/// <param name="data"></param>
|
||
/// <returns></returns>
|
||
public async Task UpdateVersionAsync(DeviceVerS2SDto data)
|
||
{
|
||
await _capBus.PublishAsync("device.service.updatever", data);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 通过ailink wifi模式发送的数据
|
||
/// </summary>
|
||
/// <param name="data"></param>
|
||
/// <returns></returns>
|
||
public async Task<object> WifiPostAsync(WifiRequestC2SDto data)
|
||
{
|
||
//记录发送过来的数据
|
||
_loggerService.AddLogger($"wifi发送原始数据,data={data.ToJson()}", 3);
|
||
var successdata = Encoding.UTF8.GetBytes("A901019A");
|
||
var returndata = new
|
||
{
|
||
status = "1",
|
||
data = Convert.ToBase64String(successdata)
|
||
};
|
||
//数据解析
|
||
var result = AnalyProto(data);
|
||
if (!result.ischecked)
|
||
{
|
||
return returndata;
|
||
}
|
||
if (result.databyte.Length == 0)
|
||
{
|
||
return returndata;
|
||
}
|
||
//小于14则表示结束
|
||
if (result.databyte.Length < 14)
|
||
{
|
||
var databytes = await _cahce.GetAsync(result.sn);
|
||
if (databytes != null && databytes.Length > 0)
|
||
{
|
||
await _cahce.RemoveAsync(result.sn);
|
||
byte[] newval = new byte[databytes.Length + result.databyte.Length];
|
||
databytes.CopyTo(newval, 0);
|
||
result.databyte.CopyTo(newval, databytes.Length);
|
||
//解析协议,IC卡数据@垃圾桶编号@厨余垃圾@7.91
|
||
var datahex = BytesToHexStr(databytes);
|
||
datahex = datahex.Replace(" ", "");
|
||
//收到的为16进制,对数据进行解析,0-4预留,5-垃圾种类,6-垃圾桶大小,7-@,8-12垃圾桶编号,13@,14-21垃圾种类汉字,22@,23-结束重量
|
||
var trashhex = datahex.Substring(16, 10); //垃圾桶编号
|
||
var typehex = datahex.Substring(28, 16); //垃圾种类
|
||
var size = datahex.Substring(12, 2);//桶大小,30-小桶,31-大桶
|
||
var weighthex = datahex.Substring(46, datahex.Length - 46);
|
||
string trashno = HextToDec(trashhex).ToString(); //垃圾桶编号使用10进制
|
||
var wastetype = GetChsFromHex(typehex);
|
||
var weight = GetChsFromHex(weighthex);
|
||
await _resultService.InsertResultByWifiAsync(new WifiPackage
|
||
{
|
||
sn = result.sn,
|
||
WasteType = wastetype,
|
||
Weight = weight,
|
||
trashcode = trashno,
|
||
size = size,
|
||
IsHeart = result.IsHeart
|
||
});
|
||
}
|
||
}
|
||
else
|
||
{
|
||
var val = await _cahce.GetAsync(result.sn);
|
||
var time = new DistributedCacheEntryOptions().SetSlidingExpiration(TimeSpan.FromSeconds(30));
|
||
if (val != null && val.Length > 0)
|
||
{
|
||
byte[] newval = new byte[val.Length + result.databyte.Length];
|
||
val.CopyTo(newval, 0);
|
||
result.databyte.CopyTo(newval, val.Length);
|
||
await _cahce.SetAsync(result.sn, newval, time);
|
||
}
|
||
else
|
||
{
|
||
await _cahce.SetAsync(result.sn, result.databyte, time);
|
||
}
|
||
}
|
||
return returndata;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 16进制转汉字
|
||
/// </summary>
|
||
/// <param name="hex"></param>
|
||
/// <returns></returns>
|
||
private string GetChsFromHex(string hex)
|
||
{
|
||
if (hex == null)
|
||
return "";
|
||
if (hex.Length % 2 != 0)
|
||
{
|
||
hex += "20";//空格
|
||
}
|
||
// 需要将 hex 转换成 byte 数组。
|
||
byte[] bytes = new byte[hex.Length / 2];
|
||
for (int i = 0; i < bytes.Length; i++)
|
||
{
|
||
try
|
||
{
|
||
// 每两个字符是一个 byte。
|
||
bytes[i] = byte.Parse(hex.Substring(i * 2, 2),
|
||
System.Globalization.NumberStyles.HexNumber);
|
||
}
|
||
catch
|
||
{
|
||
}
|
||
}
|
||
// 获得 GB2312,Chinese Simplified。
|
||
Encoding chs = Encoding.GetEncoding("gb2312");
|
||
return chs.GetString(bytes);
|
||
}
|
||
|
||
//private int TrashType(string type)
|
||
//{
|
||
// if (type == "厨余垃圾") return 1;
|
||
// else if (type == "可回收物") return 2;
|
||
// else if (type == "有害垃圾") return 3;
|
||
// else if (type == "其他垃圾") return 4;
|
||
// else return 0;
|
||
//}
|
||
//private string TrashTypeTitle(string type)
|
||
//{
|
||
// if (!int.TryParse(type, out var num)) return type;
|
||
// if (num == 1) return "厨余垃圾";
|
||
// else if (num == 2) return "可回收物";
|
||
// else if (num == 3) return "有害垃圾";
|
||
// else if (num == 4) return "其他垃圾";
|
||
// else return "0";
|
||
//}
|
||
|
||
private int TrashType(string type)
|
||
{
|
||
var result = dbClient.Queryable<W_WasteType>().First(s => s.Name == type);
|
||
if (result == null) return 0;
|
||
return int.Parse(result.Code);
|
||
}
|
||
|
||
private string TrashTypeTitle(string type)
|
||
{
|
||
if (!int.TryParse(type, out var num)) return type;
|
||
var result = dbClient.Queryable<W_WasteType>().First(s => s.Code == type || s.Code == "0000" + type);
|
||
if (result == null) return "0";
|
||
return result.Name;
|
||
}
|
||
|
||
private int GetTimestamp(DateTime time)
|
||
{
|
||
DateTime dateTimeStart = TimeZoneInfo.ConvertTimeToUtc(new DateTime(1970, 1, 1, 8, 0, 0));
|
||
int timestamp = Convert.ToInt32((time - dateTimeStart).TotalSeconds);
|
||
return timestamp;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 字节数组转16进制
|
||
/// </summary>
|
||
/// <param name="bt"></param>
|
||
/// <returns></returns>
|
||
private string BytesToHexStr(byte[] bt)
|
||
{
|
||
string returnStr = "";
|
||
if (bt != null)
|
||
{
|
||
for (int i = 0; i < bt.Length; i++)
|
||
{
|
||
returnStr += bt[i].ToString("X2");
|
||
}
|
||
}
|
||
return returnStr;
|
||
}
|
||
|
||
/// <summary>
|
||
/// wifi数据解析
|
||
/// </summary>
|
||
/// <param name="data"></param>
|
||
/// <returns></returns>
|
||
private WifiRequestS2SDto AnalyProto(WifiRequestC2SDto data)
|
||
{
|
||
WifiRequestS2SDto dto = new WifiRequestS2SDto();
|
||
//检查是否为有效的base64数据
|
||
if (!AESEncrypt.IsBase64(data.@params))
|
||
{
|
||
dto.data = data.@params;
|
||
return dto;
|
||
}
|
||
//数据为base64加密
|
||
byte[] resultByte = Convert.FromBase64String(data.@params);
|
||
dto.data = BytesToHexStr(resultByte);
|
||
//574D07884A1882FCC2FE346BA1D80E 00 A903000D0A1A9A
|
||
_loggerService.AddLogger($"wifi结果推送,解析出的数据:{dto.data}", 3);
|
||
int len = resultByte.Count();//数据总长度
|
||
//长度格式是否正确,固定长度为36位
|
||
if (len < 23)
|
||
{
|
||
return dto;
|
||
}
|
||
//前15个字节为sn。中间以 00 分隔。后面为测量结果数据 A9 03 00 0D 0A 1A 9A
|
||
int i = 0;
|
||
byte[] snbyte = new byte[15];
|
||
for (i = 0; i < 15; i++)
|
||
{
|
||
snbyte[i] = resultByte[i];
|
||
}
|
||
dto.sn = BytesToHexStr(snbyte).Replace(" ", "");
|
||
dto.splitstr = ByteToHexStr(resultByte[i]);
|
||
i++;
|
||
dto.Header = ByteToHexStr(resultByte[i]);//固定为A9
|
||
if (dto.Header != "A9") //固定为A9
|
||
{
|
||
return dto;
|
||
}
|
||
string heartstr = ByteToHexStr(resultByte[i + 2]);//是否为测量数据
|
||
if (heartstr != "01")
|
||
{
|
||
dto.IsHeart = true;
|
||
}
|
||
dto.ischecked = true;
|
||
string datalenstr = ByteToHexStr(resultByte[i + 1]); //数据体长度
|
||
int datalen = HextToDec(datalenstr).ToInt();
|
||
i += 3;
|
||
dto.databyte = new byte[datalen - 1];
|
||
for (int j = 0; j < datalen; j++)
|
||
{
|
||
if (i < len - 2)
|
||
{
|
||
dto.databyte[j] = resultByte[i];
|
||
}
|
||
i++;
|
||
}
|
||
return dto;
|
||
}
|
||
|
||
///<summary>
|
||
/// 字节转16进制
|
||
/// </summary>
|
||
/// <param name="bt"></param>
|
||
/// <returns></returns>
|
||
private string ByteToHexStr(byte bt)
|
||
{
|
||
return ((int)bt).ToString("X2");
|
||
}
|
||
|
||
private async Task<ResultInfo> UpdateDevInfo(GetDevInfoRequestDto data, GetDevInfoResponseDto returndata, W_Device device, string type, string weight, string typename = "", string name = "")
|
||
{
|
||
//returndata.type = TrashType(type);
|
||
returndata.type = int.Parse(type);
|
||
|
||
returndata.Weight = weight.ToDouble();
|
||
//计算净重,毛重-皮重=净重,如果净重小于等于0则不上报保存
|
||
returndata.Weight = (returndata.Weight - device.Tare.ToDouble()).ToDouble(2);
|
||
if (returndata.Weight <= 0)
|
||
{
|
||
_loggerService.AddLogger($"{data.ECode},{device.Name},重量小于等于0:{returndata.ToJson()}", 1);
|
||
return new ResultInfo(ResultState.FAIL, "无效的重量");
|
||
}
|
||
//检查是否为15分钟内第一次上报
|
||
//如果是巴城的设备则不使用这个限制
|
||
if (device.Businessid != Guid.Parse("39FCB9DE-404E-68F5-384B-EE2462EAB87C"))
|
||
{
|
||
var time15 = DateTime.Now.AddMinutes(-15);
|
||
if (await dbClient.Queryable<W_DeviceResult>().AnyAsync(x => x.DeviceId == device.Id && x.LastTrash == returndata.trash && x.LastHeartTime > time15))
|
||
{
|
||
_loggerService.AddLogger($"{data.ECode},{device.Name},重复垃圾桶编号的数据:{returndata.ToJson()}", 1);
|
||
return new ResultInfo(ResultState.FAIL, "15分钟内同一垃圾桶编号上报");
|
||
}
|
||
}
|
||
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
|
||
{
|
||
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 = typename.IsNullOrEmpty() == false ? typename : TrashTypeTitle(type),
|
||
weight = weight
|
||
});
|
||
|
||
|
||
if (name.IsNullOrEmpty() == false && typename.IsNullOrEmpty() == false)
|
||
{
|
||
await dbClient.Insertable(new W_MeasureResult
|
||
{
|
||
ResultId = returndata.ResultId,
|
||
WasteSType = "",
|
||
Price = 0.00m,
|
||
Amount = 0.00m,
|
||
OpUser = name,
|
||
UUID = "",
|
||
CreatedTime = DateTime.Now,
|
||
}).ExecuteCommandAsync();
|
||
}
|
||
|
||
//推送数据给第三方
|
||
await _resultService.SendMessageToThird(new SendThirdMessageSubscribeS2SDto
|
||
{
|
||
DeviceId = device.Id,
|
||
WasteSType = "",
|
||
Time = DateTime.Now,
|
||
TrashCode = returndata.trash,
|
||
WasteType = typename.IsNullOrEmpty() == false ? typename : TrashTypeTitle(type),
|
||
Weight = weight.ToDecimal(),
|
||
faccode = device.FacEcode,
|
||
ecode = device.Ecode,
|
||
province = device.Province,
|
||
city = device.City,
|
||
area = device.Area,
|
||
address = device.Address
|
||
});
|
||
return null;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 新增电子秤
|
||
/// </summary>
|
||
/// <param name="data"></param>
|
||
/// <returns></returns>
|
||
public async Task<ResultInfo> AddProductAsync(ProductInfoDto data)
|
||
{
|
||
try
|
||
{
|
||
if (await dbClient.Queryable<W_Product>().AnyAsync(x => x.Uuid == data.uuid))
|
||
{
|
||
return new ResultInfo(ResultState.FAIL, "数据已存在");
|
||
}
|
||
var imageUrl = "";
|
||
if (data.image.IsNullOrEmpty() == false)
|
||
{
|
||
//将图片上传服务器
|
||
// 移除Base64字符串中的前缀(如 "data:image/png;base64,")
|
||
string base64Data = data.image;
|
||
// 将Base64字符串解码为字节数组
|
||
var arr = Convert.FromBase64String(base64Data);
|
||
//把上传完的路径存到数据库
|
||
using (var client = new HttpClient())
|
||
{
|
||
// 创建MultipartFormDataContent对象
|
||
var content = new MultipartFormDataContent();
|
||
|
||
// 添加文件内容到MultipartFormDataContent
|
||
content.Add(new ByteArrayContent(arr), "file", "image.png");
|
||
|
||
// 发送POST请求
|
||
HttpResponseMessage response = await client.PostAsync("https://izzt.jt-sky.com/api/common/uploadimg", content);
|
||
|
||
// 检查响应
|
||
if (response.IsSuccessStatusCode)
|
||
{
|
||
// 假设服务器返回的是JSON格式,包含图片URL
|
||
var responseContent = await response.Content.ReadAsStringAsync();
|
||
|
||
if (responseContent.Contains("success"))
|
||
{
|
||
// 解析JSON
|
||
JObject jsonResponseObject = JObject.Parse(responseContent);
|
||
// 提取URL
|
||
imageUrl = jsonResponseObject["data"]["url"].ToString();
|
||
}
|
||
}
|
||
}
|
||
}
|
||
W_Product insertdata = new W_Product
|
||
{
|
||
Id = Guid.NewGuid().ToString(),
|
||
UserName = data.userName,
|
||
Weight = data.weight.ToString(),
|
||
Image = imageUrl,
|
||
UpperLimit = data.upperLimit.ToString(),
|
||
Unit = data.unit,
|
||
TimeStamp = data.timeStamp.ToString(),
|
||
TareWeight = data.tareWeight.ToString(),
|
||
RecordNo = data.recordNo.ToString(),
|
||
ProductNo = data.productNo,
|
||
ProductName = data.productName,
|
||
ProductId = data.productId.ToString(),
|
||
NetWeight = data.netWeight.ToString(),
|
||
LowerLimit = data.lowerLimit.ToString(),
|
||
IdNames = data.idNames,
|
||
IdValues = data.idValues,
|
||
Date = data.date,
|
||
DateTime = data.dateTime,
|
||
Amount = data.amount.ToString(),
|
||
Uuid = data.uuid,
|
||
UserId = data.userId.ToString(),
|
||
CreateTime = DateTime.Now,
|
||
Video = data.Video
|
||
};
|
||
await dbClient.Insertable(insertdata).ExecuteCommandAsync();
|
||
return new ResultInfo(ResultState.SUCCESS, "success");
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
return new ResultInfo(ResultState.FAIL, ex.Message);
|
||
}
|
||
}
|
||
|
||
public async Task<PageParms<W_Product>> GetProductAsync(QueryParams param)
|
||
{
|
||
try
|
||
{
|
||
RefAsync<int> totalnum = 0;
|
||
var temquery = dbClient.Queryable<W_Product>();
|
||
if (param.queryParam != null && param.queryParam.Count > 0)
|
||
{
|
||
List<IConditionalModel> conModels = new List<IConditionalModel>();
|
||
param.queryParam.ForEach(x =>
|
||
{
|
||
if (!string.IsNullOrEmpty(x.Value))
|
||
{
|
||
conModels.Add(new ConditionalModel()
|
||
{
|
||
FieldName = x.Name,
|
||
ConditionalType = (ConditionalType)x.Type,
|
||
FieldValue = x.Value.Trim()
|
||
});
|
||
}
|
||
});
|
||
if (conModels.Count > 0)
|
||
{
|
||
temquery = temquery.Where(conModels);
|
||
}
|
||
}
|
||
string sorts = string.Format("{0} {1}", param.sort, param.order);
|
||
var query = await temquery.OrderBy(sorts)
|
||
.ToPageListAsync(param.offset, param.limit, totalnum);
|
||
return new PageParms<W_Product>
|
||
{
|
||
page = param.offset,
|
||
Items = query,
|
||
totalnum = totalnum,
|
||
limit = param.limit
|
||
};
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
return new PageParms<W_Product>();
|
||
}
|
||
}
|
||
}
|
||
} |