初始化
This commit is contained in:
6
BooliveMQTT_Auth/BooliveMQTT_Auth.http
Normal file
6
BooliveMQTT_Auth/BooliveMQTT_Auth.http
Normal file
@@ -0,0 +1,6 @@
|
||||
@BooliveMQTT_Auth_HostAddress = http://localhost:5068
|
||||
|
||||
GET {{BooliveMQTT_Auth_HostAddress}}/weatherforecast/
|
||||
Accept: application/json
|
||||
|
||||
###
|
||||
112
BooliveMQTT_Auth/Common/BaiduAPI.cs
Normal file
112
BooliveMQTT_Auth/Common/BaiduAPI.cs
Normal file
@@ -0,0 +1,112 @@
|
||||
using System.Text;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using RestSharp;
|
||||
|
||||
namespace IotManager.Common
|
||||
{
|
||||
public class BaiduAPI
|
||||
{
|
||||
/// <summary>
|
||||
/// 百度api
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static string GetBaiduIp(string ip)
|
||||
{
|
||||
string location = "";
|
||||
try
|
||||
{
|
||||
string url = $"https://sp0.baidu.com";
|
||||
//WebClient client = new WebClient();
|
||||
RestSharp.RestClient client1 = new RestSharp.RestClient(url);
|
||||
RestSharp.RestRequest request = new RestSharp.RestRequest($"/8aQDcjqpAAV3otqbppnN2DJv/api.php?query={ip}&co=&resource_id=6006&oe=utf8", Method.Get);
|
||||
var buffer = client1.DownloadData(request);
|
||||
//var buffer = client.DownloadData(url);
|
||||
string jsonText = Encoding.UTF8.GetString(buffer);
|
||||
JObject jo = JObject.Parse(jsonText);
|
||||
|
||||
Root root = JsonConvert.DeserializeObject<Root>(jo.ToString());
|
||||
foreach (var item in root.data)
|
||||
{
|
||||
location = item.location;
|
||||
}
|
||||
return location;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
//Console.WriteLine(ex);
|
||||
return location;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public class Root
|
||||
{
|
||||
public List<DataItem> data { get; set; }
|
||||
}
|
||||
public class DataItem
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string ExtendedLocation { get; set; }
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string OriginQuery { get; set; }
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string appinfo { get; set; }
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public int disp_type { get; set; }
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string fetchkey { get; set; }
|
||||
/// <summary>
|
||||
/// 本地局域网
|
||||
/// </summary>
|
||||
public string location { get; set; }
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string origip { get; set; }
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string origipquery { get; set; }
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string resourceid { get; set; }
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public int role_id { get; set; }
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public int shareImage { get; set; }
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public int showLikeShare { get; set; }
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string showlamp { get; set; }
|
||||
/// <summary>
|
||||
/// IP地址查询
|
||||
/// </summary>
|
||||
public string titlecont { get; set; }
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string tplt { get; set; }
|
||||
}
|
||||
}
|
||||
134
BooliveMQTT_Auth/Common/Base64.cs
Normal file
134
BooliveMQTT_Auth/Common/Base64.cs
Normal file
@@ -0,0 +1,134 @@
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
|
||||
namespace IotManager.Common
|
||||
{
|
||||
public class Base64
|
||||
{
|
||||
public static void MainTest()
|
||||
{
|
||||
// 要加密的原始字符串
|
||||
string originalText = "Hello, World!";
|
||||
|
||||
// 加密成Base64字符串
|
||||
string base64EncodedText = EncodeBase64(originalText);
|
||||
Console.WriteLine("Base64 编码结果: " + base64EncodedText);
|
||||
|
||||
// 解密Base64字符串
|
||||
string decodedText = DecodeBase64(base64EncodedText);
|
||||
Console.WriteLine("Base64 解码结果: " + decodedText);
|
||||
}
|
||||
|
||||
// 使用Base64编码字符串
|
||||
public static string EncodeBase64(string text)
|
||||
{
|
||||
byte[] bytesToEncode = Encoding.UTF8.GetBytes(text);
|
||||
string encodedText = Convert.ToBase64String(bytesToEncode);
|
||||
return encodedText;
|
||||
}
|
||||
|
||||
// 使用Base64解码字符串
|
||||
public static string DecodeBase64(string encodedText)
|
||||
{
|
||||
byte[] decodedBytes = Convert.FromBase64String(encodedText);
|
||||
string decodedText = Encoding.UTF8.GetString(decodedBytes);
|
||||
return decodedText;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 使用3DES-MAC签名消息
|
||||
public static string Sign3DESMAC(string key, string message)
|
||||
{
|
||||
byte[] keyBytes = Encoding.UTF8.GetBytes(key);
|
||||
byte[] messageBytes = Encoding.UTF8.GetBytes(message);
|
||||
|
||||
using (TripleDESCryptoServiceProvider des = new TripleDESCryptoServiceProvider())
|
||||
{
|
||||
des.Key = keyBytes;
|
||||
des.Mode = CipherMode.ECB; // 3DES-MAC通常使用ECB模式
|
||||
des.Padding = PaddingMode.PKCS7; // PKCS7填充
|
||||
|
||||
using (HMACMD5 hmac = new HMACMD5(des.Key))
|
||||
{
|
||||
byte[] hashBytes = hmac.ComputeHash(messageBytes);
|
||||
return BitConverter.ToString(hashBytes).Replace("-", "").ToLower();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 验证3DES-MAC签名
|
||||
public static bool Verify3DESMAC(string key, string message, string macToVerify)
|
||||
{
|
||||
string calculatedMAC = Sign3DESMAC(key, message);
|
||||
return string.Equals(calculatedMAC, macToVerify, StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 取前16个字节
|
||||
/// </summary>
|
||||
/// <param name="message"></param>
|
||||
/// <param name="key"></param>
|
||||
/// <returns></returns>
|
||||
public static byte[] ComputeHMACSHA256Short(string message, string key)
|
||||
{
|
||||
using (HMACSHA256 hmac = new HMACSHA256(Encoding.UTF8.GetBytes(key)))
|
||||
{
|
||||
byte[] messageBytes = Encoding.UTF8.GetBytes(message);
|
||||
byte[] fullHash = hmac.ComputeHash(messageBytes);
|
||||
|
||||
// 对完整哈希再做一次SHA256并取前16字节
|
||||
using (SHA256 sha = SHA256.Create())
|
||||
{
|
||||
byte[] rehashed = sha.ComputeHash(fullHash);
|
||||
byte[] result = new byte[16];
|
||||
Array.Copy(rehashed, result, 16);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static byte[] ComputeHMACSHA256(string message, string key)
|
||||
{
|
||||
using (HMACSHA256 hmac = new HMACSHA256(Encoding.UTF8.GetBytes(key)))
|
||||
{
|
||||
byte[] messageBytes = Encoding.UTF8.GetBytes(message);
|
||||
return hmac.ComputeHash(messageBytes);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static bool VerifyHMACSHA256(byte[] message, byte[] key, byte[] expectedMac)
|
||||
{
|
||||
using (HMACSHA256 hmac = new HMACSHA256(key))
|
||||
{
|
||||
byte[] computedMac = hmac.ComputeHash(message);
|
||||
return CryptographicOperations.FixedTimeEquals(computedMac, expectedMac); // 防止时间攻击
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void Test()
|
||||
{
|
||||
string key = "ThisIsASecretKey"; // 密钥长度必须是24字节(192位)
|
||||
string message = "Hello, World!";
|
||||
|
||||
// 使用3DES-MAC签名消息
|
||||
string mac = Sign3DESMAC(key, message);
|
||||
Console.WriteLine("3DES-MAC 签名: " + mac);
|
||||
|
||||
// 验证3DES-MAC签名
|
||||
bool isVerified = Verify3DESMAC(key, message, mac);
|
||||
if (isVerified)
|
||||
{
|
||||
Console.WriteLine("消息验证成功!");
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("消息验证失败!");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
211
BooliveMQTT_Auth/Common/Crypto.cs
Normal file
211
BooliveMQTT_Auth/Common/Crypto.cs
Normal file
@@ -0,0 +1,211 @@
|
||||
using System;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Security.Cryptography;
|
||||
using Microsoft.AspNetCore.Cryptography.KeyDerivation;
|
||||
|
||||
namespace CryptoHelper;
|
||||
|
||||
/// <summary>
|
||||
/// Provides helper methods for hashing/salting and verifying passwords.
|
||||
/// </summary>
|
||||
public static class Crypto
|
||||
{
|
||||
/* =======================
|
||||
* HASHED PASSWORD FORMATS
|
||||
* =======================
|
||||
*
|
||||
* Version 3:
|
||||
* PBKDF2 with HMAC-SHA256, 128-bit salt, 256-bit subkey, 600.000 iterations.
|
||||
* Format: { 0x01, prf (UInt32), iter count (UInt32), salt length (UInt32), salt, subkey }
|
||||
* (All UInt32s are stored big-endian.)
|
||||
*/
|
||||
|
||||
private const int PBKDF2IterCount = 600_000;
|
||||
private const int PBKDF2SubkeyLength = 256 / 8; // 256 bits
|
||||
private const int SaltSize = 128 / 8; // 128 bits
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Returns a hashed representation of the specified <paramref name="password"/>.
|
||||
/// </summary>
|
||||
/// <param name="password">The password to generate a hash value for.</param>
|
||||
/// <returns>The hash value for <paramref name="password" /> as a base-64-encoded string.</returns>
|
||||
/// <exception cref="System.ArgumentNullException"><paramref name="password" /> is null.</exception>
|
||||
public static string HashPassword(string password)
|
||||
{
|
||||
if (password == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(password));
|
||||
}
|
||||
|
||||
return HashPasswordInternal(password);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the specified RFC 2898 hash and password are a cryptographic match.
|
||||
/// </summary>
|
||||
/// <param name="hashedPassword">The previously-computed RFC 2898 hash value as a base-64-encoded string.</param>
|
||||
/// <param name="password">The plaintext password to cryptographically compare with hashedPassword.</param>
|
||||
/// <returns>true if the hash value is a cryptographic match for the password; otherwise, false.</returns>
|
||||
/// <remarks>
|
||||
/// <paramref name="hashedPassword" /> must be of the format of HashPassword (salt + Hash(salt+input).
|
||||
/// </remarks>
|
||||
/// <exception cref="System.ArgumentNullException">
|
||||
/// <paramref name="hashedPassword" /> or <paramref name="password" /> is null.
|
||||
/// </exception>
|
||||
public static bool VerifyHashedPassword(string hashedPassword, string password)
|
||||
{
|
||||
if (hashedPassword == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(hashedPassword));
|
||||
}
|
||||
if (password == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(password));
|
||||
}
|
||||
|
||||
return VerifyHashedPasswordInternal(hashedPassword, password);
|
||||
}
|
||||
|
||||
private static readonly RandomNumberGenerator _rng = RandomNumberGenerator.Create();
|
||||
|
||||
private static string HashPasswordInternal(string password)
|
||||
{
|
||||
var bytes = HashPasswordInternal(password, KeyDerivationPrf.HMACSHA256, PBKDF2IterCount, SaltSize, PBKDF2SubkeyLength);
|
||||
return Convert.ToBase64String(bytes);
|
||||
}
|
||||
|
||||
private static byte[] HashPasswordInternal(
|
||||
string password,
|
||||
KeyDerivationPrf prf,
|
||||
int iterCount,
|
||||
int saltSize,
|
||||
int numBytesRequested)
|
||||
{
|
||||
// Produce a version 3 (see comment above) text hash.
|
||||
var salt = new byte[saltSize];
|
||||
_rng.GetBytes(salt);
|
||||
var subkey = KeyDerivation.Pbkdf2(password, salt, prf, iterCount, numBytesRequested);
|
||||
|
||||
var outputBytes = new byte[13 + salt.Length + subkey.Length];
|
||||
|
||||
// Write format marker.
|
||||
outputBytes[0] = 0x01;
|
||||
|
||||
// Write hashing algorithm version.
|
||||
WriteNetworkByteOrder(outputBytes, 1, (uint)prf);
|
||||
|
||||
// Write iteration count of the algorithm.
|
||||
WriteNetworkByteOrder(outputBytes, 5, (uint)iterCount);
|
||||
|
||||
// Write size of the salt.
|
||||
WriteNetworkByteOrder(outputBytes, 9, (uint)saltSize);
|
||||
|
||||
// Write the salt.
|
||||
Buffer.BlockCopy(salt, 0, outputBytes, 13, salt.Length);
|
||||
|
||||
// Write the subkey.
|
||||
Buffer.BlockCopy(subkey, 0, outputBytes, 13 + saltSize, subkey.Length);
|
||||
return outputBytes;
|
||||
}
|
||||
|
||||
private static bool VerifyHashedPasswordInternal(string hashedPassword, string password)
|
||||
{
|
||||
var decodedHashedPassword = Convert.FromBase64String(hashedPassword);
|
||||
|
||||
if (decodedHashedPassword.Length == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// Verify hashing format.
|
||||
if (decodedHashedPassword[0] != 0x01)
|
||||
{
|
||||
// Unknown format header.
|
||||
return false;
|
||||
}
|
||||
|
||||
// Read hashing algorithm version.
|
||||
var prf = (KeyDerivationPrf)ReadNetworkByteOrder(decodedHashedPassword, 1);
|
||||
|
||||
// Read iteration count of the algorithm.
|
||||
var iterCount = (int)ReadNetworkByteOrder(decodedHashedPassword, 5);
|
||||
|
||||
// Read size of the salt.
|
||||
var saltLength = (int)ReadNetworkByteOrder(decodedHashedPassword, 9);
|
||||
|
||||
// Verify the salt size: >= 128 bits.
|
||||
if (saltLength < 128 / 8)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Read the salt.
|
||||
var salt = new byte[saltLength];
|
||||
Buffer.BlockCopy(decodedHashedPassword, 13, salt, 0, salt.Length);
|
||||
|
||||
// Verify the subkey length >= 128 bits.
|
||||
var subkeyLength = decodedHashedPassword.Length - 13 - salt.Length;
|
||||
if (subkeyLength < 128 / 8)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Read the subkey.
|
||||
var expectedSubkey = new byte[subkeyLength];
|
||||
Buffer.BlockCopy(decodedHashedPassword, 13 + salt.Length, expectedSubkey, 0, expectedSubkey.Length);
|
||||
|
||||
// Hash the given password and verify it against the expected subkey.
|
||||
var actualSubkey = KeyDerivation.Pbkdf2(password, salt, prf, iterCount, subkeyLength);
|
||||
return ByteArraysEqual(actualSubkey, expectedSubkey);
|
||||
}
|
||||
catch
|
||||
{
|
||||
// This should never occur except in the case of a malformed payload, where
|
||||
// we might go off the end of the array. Regardless, a malformed payload
|
||||
// implies verification failed.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static uint ReadNetworkByteOrder(byte[] buffer, int offset)
|
||||
{
|
||||
return ((uint)(buffer[offset + 0]) << 24)
|
||||
| ((uint)(buffer[offset + 1]) << 16)
|
||||
| ((uint)(buffer[offset + 2]) << 8)
|
||||
| ((uint)(buffer[offset + 3]));
|
||||
}
|
||||
|
||||
private static void WriteNetworkByteOrder(byte[] buffer, int offset, uint value)
|
||||
{
|
||||
buffer[offset + 0] = (byte)(value >> 24);
|
||||
buffer[offset + 1] = (byte)(value >> 16);
|
||||
buffer[offset + 2] = (byte)(value >> 8);
|
||||
buffer[offset + 3] = (byte)(value >> 0);
|
||||
}
|
||||
|
||||
// Compares two byte arrays for equality.
|
||||
// The method is specifically written so that the loop is not optimized.
|
||||
[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
|
||||
private static bool ByteArraysEqual(byte[] a, byte[] b)
|
||||
{
|
||||
if (ReferenceEquals(a, b))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (a == null || b == null || a.Length != b.Length)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var areSame = true;
|
||||
for (var i = 0; i < a.Length; i++)
|
||||
{
|
||||
areSame &= (a[i] == b[i]);
|
||||
}
|
||||
return areSame;
|
||||
}
|
||||
}
|
||||
192
BooliveMQTT_Auth/Common/ExcelHelper.cs
Normal file
192
BooliveMQTT_Auth/Common/ExcelHelper.cs
Normal file
@@ -0,0 +1,192 @@
|
||||
using System.Data;
|
||||
using NPOI.HSSF.UserModel;
|
||||
using NPOI.SS.UserModel;
|
||||
using NPOI.XSSF.UserModel;
|
||||
|
||||
namespace IotManager.Common
|
||||
{
|
||||
public class ExcelHelper
|
||||
{
|
||||
public static DataTable ReadExcelToDataTable(string filePath)
|
||||
{
|
||||
DataTable dataTable = new DataTable();
|
||||
|
||||
// 打开 Excel 文件
|
||||
IWorkbook workbook;
|
||||
using (var fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read))
|
||||
{
|
||||
if (filePath.EndsWith(".xlsx"))
|
||||
workbook = new XSSFWorkbook(fileStream); // 读取 .xlsx 文件
|
||||
else if (filePath.EndsWith(".xls"))
|
||||
workbook = new HSSFWorkbook(fileStream); // 读取 .xls 文件
|
||||
else
|
||||
throw new Exception("文件格式不支持,只支持 .xls 和 .xlsx");
|
||||
}
|
||||
|
||||
// 读取第一个工作表
|
||||
var sheet = workbook.GetSheetAt(0);
|
||||
if (sheet == null)
|
||||
throw new Exception("工作表为空!");
|
||||
|
||||
// 获取表头
|
||||
var headerRow = sheet.GetRow(0);
|
||||
if (headerRow == null)
|
||||
throw new Exception("未找到表头行!");
|
||||
|
||||
for (int i = 0; i < headerRow.LastCellNum; i++)
|
||||
{
|
||||
var columnName = headerRow.GetCell(i)?.ToString() ?? $"Column{i}";
|
||||
dataTable.Columns.Add(columnName);
|
||||
}
|
||||
|
||||
// 读取数据行
|
||||
for (int i = 1; i <= sheet.LastRowNum; i++) // 从第 1 行(索引为 1)开始读取
|
||||
{
|
||||
var row = sheet.GetRow(i);
|
||||
if (row == null) continue;
|
||||
|
||||
var dataRow = dataTable.NewRow();
|
||||
for (int j = 0; j < row.LastCellNum; j++)
|
||||
{
|
||||
var cell = row.GetCell(j);
|
||||
dataRow[j] = cell != null ? GetCellValue(cell) : DBNull.Value;
|
||||
}
|
||||
dataTable.Rows.Add(dataRow);
|
||||
}
|
||||
|
||||
return dataTable;
|
||||
}
|
||||
|
||||
static object GetCellValue(ICell cell)
|
||||
{
|
||||
switch (cell.CellType)
|
||||
{
|
||||
case CellType.Numeric:
|
||||
return DateUtil.IsCellDateFormatted(cell) ? cell.DateCellValue : cell.NumericCellValue;
|
||||
case CellType.String:
|
||||
return cell.StringCellValue;
|
||||
case CellType.Boolean:
|
||||
return cell.BooleanCellValue;
|
||||
case CellType.Formula:
|
||||
return cell.CellFormula;
|
||||
case CellType.Blank:
|
||||
return string.Empty;
|
||||
default:
|
||||
return cell.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void CreateNewExcel(string filePath, DataTable dataTable)
|
||||
{
|
||||
IWorkbook workbook;
|
||||
if (filePath.EndsWith(".xlsx"))
|
||||
workbook = new XSSFWorkbook(); // 创建 .xlsx 文件
|
||||
else
|
||||
workbook = new HSSFWorkbook(); // 创建 .xls 文件
|
||||
|
||||
var sheet = workbook.CreateSheet("Sheet1");
|
||||
|
||||
// 写入表头
|
||||
var headerRow = sheet.CreateRow(0);
|
||||
for (int i = 0; i < dataTable.Columns.Count; i++)
|
||||
{
|
||||
headerRow.CreateCell(i).SetCellValue(dataTable.Columns[i].ColumnName);
|
||||
}
|
||||
|
||||
// 写入数据
|
||||
for (int i = 0; i < dataTable.Rows.Count; i++)
|
||||
{
|
||||
var dataRow = sheet.CreateRow(i + 1);
|
||||
for (int j = 0; j < dataTable.Columns.Count; j++)
|
||||
{
|
||||
dataRow.CreateCell(j).SetCellValue(dataTable.Rows[i][j].ToString());
|
||||
}
|
||||
}
|
||||
|
||||
// 保存文件
|
||||
using (var stream = new FileStream(filePath, FileMode.Create, FileAccess.Write))
|
||||
{
|
||||
workbook.Write(stream);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void SetColumnWidthAndRowHeight(IWorkbook workbook, int sheetIndex, int columnIndex, int rowIndex)
|
||||
{
|
||||
var sheet = workbook.GetSheetAt(sheetIndex);
|
||||
|
||||
// 设置列宽(单位是 1/256 字符宽度)
|
||||
sheet.SetColumnWidth(columnIndex, 20 * 256); // 设置第 1 列宽度为 20
|
||||
|
||||
// 设置行高(单位是点数)
|
||||
var row = sheet.GetRow(rowIndex) ?? sheet.CreateRow(rowIndex);
|
||||
row.HeightInPoints = 25; // 设置行高为 25 点
|
||||
}
|
||||
|
||||
public void SetCellStyle(IWorkbook workbook, int sheetIndex, int rowIndex, int colIndex)
|
||||
{
|
||||
var sheet = workbook.GetSheetAt(sheetIndex);
|
||||
var cell = sheet.GetRow(rowIndex).GetCell(colIndex) ?? sheet.GetRow(rowIndex).CreateCell(colIndex);
|
||||
|
||||
var style = workbook.CreateCellStyle();
|
||||
|
||||
// 设置字体
|
||||
var font = workbook.CreateFont();
|
||||
font.FontHeightInPoints = 12;
|
||||
font.FontName = "Arial";
|
||||
font.IsBold = true;
|
||||
style.SetFont(font);
|
||||
|
||||
// 设置边框
|
||||
style.BorderBottom = BorderStyle.Thin;
|
||||
style.BorderLeft = BorderStyle.Thin;
|
||||
style.BorderRight = BorderStyle.Thin;
|
||||
style.BorderTop = BorderStyle.Thin;
|
||||
|
||||
// 设置背景颜色
|
||||
style.FillForegroundColor = IndexedColors.LightBlue.Index;
|
||||
style.FillPattern = FillPattern.SolidForeground;
|
||||
|
||||
cell.CellStyle = style;
|
||||
cell.SetCellValue("示例文本");
|
||||
}
|
||||
public void FullExample(string filePath, DataTable dataTable)
|
||||
{
|
||||
IWorkbook workbook = filePath.EndsWith(".xlsx") ? (IWorkbook)new XSSFWorkbook() : new HSSFWorkbook();
|
||||
var sheet = workbook.CreateSheet("Sheet1");
|
||||
|
||||
// 设置表头
|
||||
var headerRow = sheet.CreateRow(0);
|
||||
for (int i = 0; i < dataTable.Columns.Count; i++)
|
||||
{
|
||||
headerRow.CreateCell(i).SetCellValue(dataTable.Columns[i].ColumnName);
|
||||
}
|
||||
|
||||
// 写入数据
|
||||
for (int i = 0; i < dataTable.Rows.Count; i++)
|
||||
{
|
||||
var dataRow = sheet.CreateRow(i + 1);
|
||||
for (int j = 0; j < dataTable.Columns.Count; j++)
|
||||
{
|
||||
dataRow.CreateCell(j).SetCellValue(dataTable.Rows[i][j].ToString());
|
||||
}
|
||||
}
|
||||
|
||||
// 设置列宽和行高
|
||||
SetColumnWidthAndRowHeight(workbook, 0, 1, 1);
|
||||
|
||||
|
||||
// 设置单元格样式
|
||||
SetCellStyle(workbook, 0, 1, 1);
|
||||
|
||||
// 保存文件
|
||||
using (var stream = new FileStream(filePath, FileMode.Create, FileAccess.Write))
|
||||
{
|
||||
workbook.Write(stream);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
25
BooliveMQTT_Auth/Common/HttpRequest.cs
Normal file
25
BooliveMQTT_Auth/Common/HttpRequest.cs
Normal file
@@ -0,0 +1,25 @@
|
||||
using RestSharp;
|
||||
|
||||
namespace IotManager.Common
|
||||
{
|
||||
public class HttpRequest
|
||||
{
|
||||
public static string BaseUrl = "";
|
||||
public bool SendHttpRequest(string Url,List<string> paramlist)
|
||||
{
|
||||
var options = new RestClientOptions(BaseUrl);
|
||||
var client = new RestClient(options);
|
||||
|
||||
var request = new RestRequest("api/login/Helloooo");
|
||||
request.AddParameter("key", "j76R2968V^aw%2;2");
|
||||
|
||||
RestResponse response = client.ExecutePost(request);
|
||||
string? allow_or_deny = response.Content;
|
||||
if (allow_or_deny.Equals("allow"))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
44
BooliveMQTT_Auth/Common/IdGenerate.cs
Normal file
44
BooliveMQTT_Auth/Common/IdGenerate.cs
Normal file
@@ -0,0 +1,44 @@
|
||||
using Sqids;
|
||||
|
||||
namespace IotManager.Common
|
||||
{
|
||||
public class IdGenerate
|
||||
{
|
||||
public void AAA()
|
||||
{
|
||||
// 使用默认选项创建 SqidsEncoder 实例
|
||||
var sqids = new SqidsEncoder<int>();
|
||||
|
||||
// 编码单个数字
|
||||
var id = sqids.Encode(99);
|
||||
Console.WriteLine($"编码单个数字: {id}"); // 输出:Q8P
|
||||
|
||||
// 解码单个 ID
|
||||
var number = sqids.Decode(id).Single();
|
||||
Console.WriteLine($"解码单个 ID '{id}': {number}"); // 输出:99
|
||||
|
||||
// 编码多个数字
|
||||
var ids = sqids.Encode(7, 8, 9);
|
||||
Console.WriteLine($"编码多个数字 7, 8, 9: {ids}"); // 输出:ylrR3H
|
||||
|
||||
// 解码多个 ID
|
||||
var numbers = sqids.Decode(ids);
|
||||
Console.WriteLine($"解码多个 ID '{ids}': {string.Join(", ", numbers)}"); // 输出:7, 8, 9
|
||||
|
||||
// 使用自定义选项创建 SqidsEncoder 实例
|
||||
var customSqids = new SqidsEncoder<int>(new SqidsOptions
|
||||
{
|
||||
Alphabet = "mTHivO7hx3RAbr1f586SwjNnK2lgpcUVuG09BCtekZdJ4DYFPaWoMLQEsXIqyz",//自定义字母表(注意:字母表至少需要 3 个字符)
|
||||
MinLength = 5,//最小长度,默认情况下,Sqids 使用尽可能少的字符来编码给定的数字。但是,如果你想让你的所有 ID 至少达到一定的长度(例如,为了美观),你可以通过 MinLength 选项进行配置:
|
||||
BlockList = { "whatever", "else", "you", "want" } //自定义黑名单,Sqids 自带一个大的默认黑名单,这将确保常见的诅咒词等永远不会出现在您的 ID 中。您可以像这样向这个默认黑名单添加额外项:
|
||||
});
|
||||
|
||||
// 使用自定义 SqidsEncoder 编码和解码
|
||||
var customId = customSqids.Encode(8899);
|
||||
Console.WriteLine($"使用自定义 SqidsEncoder 编码: {customId}"); // 输出:i1uYg
|
||||
|
||||
var customNumber = customSqids.Decode(customId).Single();
|
||||
Console.WriteLine($"使用自定义 SqidsEncoder 解码: {customNumber}"); // 输出:8899
|
||||
}
|
||||
}
|
||||
}
|
||||
75
BooliveMQTT_Auth/Common/JiaJieMi.cs
Normal file
75
BooliveMQTT_Auth/Common/JiaJieMi.cs
Normal file
@@ -0,0 +1,75 @@
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
|
||||
namespace IotManager.Common
|
||||
{
|
||||
public class JiaJieMi
|
||||
{
|
||||
private static byte[] Keys = { 0xEF, 0xAB, 0x56, 0x78, 0x90, 0x34, 0xCD, 0x12 };
|
||||
|
||||
public static string encryptKey = "20su#pe1r%boolive";
|
||||
/// <summary>
|
||||
/// DES加密字符串
|
||||
/// </summary>
|
||||
/// <param name="encryptString">待加密的字符串</param>
|
||||
/// <param name="encryptKey">加密密钥,要求为8位</param>
|
||||
/// <returns>加密成功返回加密后的字符串,失败返回源串</returns>
|
||||
public static string EncryptString(string encryptString)
|
||||
{
|
||||
try
|
||||
{
|
||||
byte[] rgbKey = Encoding.UTF8.GetBytes(encryptKey.Substring(0, 8));
|
||||
byte[] rgbIV = Keys;
|
||||
byte[] inputByteArray = Encoding.UTF8.GetBytes(encryptString);
|
||||
var dCSP = new DESCryptoServiceProvider();
|
||||
using MemoryStream mStream = new MemoryStream();
|
||||
using CryptoStream cStream = new CryptoStream(mStream, dCSP.CreateEncryptor(rgbKey, rgbIV), CryptoStreamMode.Write);
|
||||
cStream.Write(inputByteArray, 0, inputByteArray.Length);
|
||||
cStream.FlushFinalBlock();
|
||||
return Convert.ToBase64String(mStream.ToArray());
|
||||
}
|
||||
catch
|
||||
{
|
||||
return encryptString;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// DES解密字符串
|
||||
/// </summary>
|
||||
/// <param name="decryptString">待解密的字符串</param>
|
||||
/// <param name="decryptKey">解密密钥,要求为8位,和加密密钥相同</param>
|
||||
/// <returns>解密成功返回解密后的字符串,失败返源串</returns>
|
||||
public static string DecryptString(string decryptString)
|
||||
{
|
||||
try
|
||||
{
|
||||
byte[] rgbKey = Encoding.UTF8.GetBytes(encryptKey.Substring(0, 8));
|
||||
byte[] rgbIV = Keys;
|
||||
byte[] inputByteArray = Convert.FromBase64String(decryptString);
|
||||
var DCSP = new DESCryptoServiceProvider();
|
||||
using MemoryStream mStream = new MemoryStream();
|
||||
using CryptoStream cStream = new CryptoStream(mStream, DCSP.CreateDecryptor(rgbKey, rgbIV), CryptoStreamMode.Write);
|
||||
cStream.Write(inputByteArray, 0, inputByteArray.Length);
|
||||
cStream.FlushFinalBlock();
|
||||
return Encoding.UTF8.GetString(mStream.ToArray());
|
||||
}
|
||||
catch
|
||||
{
|
||||
return decryptString;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static string HashPassword(string pwd)
|
||||
{
|
||||
string v = CryptoHelper.Crypto.HashPassword(pwd);
|
||||
return v;
|
||||
}
|
||||
public static bool VerifyHashedPassword(string encrypwd, string original_pwd)
|
||||
{
|
||||
bool v = CryptoHelper.Crypto.VerifyHashedPassword(encrypwd, original_pwd);
|
||||
return v;
|
||||
}
|
||||
}
|
||||
}
|
||||
29
BooliveMQTT_Auth/Common/MsgSend.cs
Normal file
29
BooliveMQTT_Auth/Common/MsgSend.cs
Normal file
@@ -0,0 +1,29 @@
|
||||
using RestSharp;
|
||||
|
||||
namespace IotManager.Common
|
||||
{
|
||||
public class MsgSend
|
||||
{
|
||||
public static string BaseUrl = "http://blv-rd.tech:19041";
|
||||
public static async Task SendMsg(MsgData data)
|
||||
{
|
||||
var options = new RestClientOptions(BaseUrl);
|
||||
var client = new RestClient(options);
|
||||
|
||||
var request = new RestRequest("/api/CallAndMsg/SendToPhone");
|
||||
request.AddBody(data, ContentType.Json);
|
||||
|
||||
RestResponse response = await client.ExecuteAsync(request, Method.Post);
|
||||
string? allow_or_deny = response.Content;
|
||||
}
|
||||
}
|
||||
public class MsgData
|
||||
{
|
||||
public string? PhoneNumber { get; set; }
|
||||
public string? CallerName { get; set; }
|
||||
public string? Content { get; set; }
|
||||
public string? StartingPoint { get; set; }
|
||||
public string? DeadLine { get; set; }
|
||||
public string? Type { get; set; }
|
||||
}
|
||||
}
|
||||
13
BooliveMQTT_Auth/Common/MyMemoryCache.cs
Normal file
13
BooliveMQTT_Auth/Common/MyMemoryCache.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
using Microsoft.Extensions.Caching.Memory;
|
||||
|
||||
namespace BLW_Log.Models
|
||||
{
|
||||
public class MyMemoryCache
|
||||
{
|
||||
public MemoryCache Cache { get; } = new MemoryCache(
|
||||
new MemoryCacheOptions
|
||||
{
|
||||
SizeLimit = 1024
|
||||
});
|
||||
}
|
||||
}
|
||||
36
BooliveMQTT_Auth/Common/PasswordGenerator.cs
Normal file
36
BooliveMQTT_Auth/Common/PasswordGenerator.cs
Normal file
@@ -0,0 +1,36 @@
|
||||
using System.Security.Cryptography;
|
||||
|
||||
namespace IotManager.Common
|
||||
{
|
||||
public class PasswordGenerator
|
||||
{
|
||||
//private const string ValidChars = "!@#$%^&*()-+={}';.?<>:{}|ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
||||
private const string ValidChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
||||
|
||||
public static string Generate(int length)
|
||||
{
|
||||
using (RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider())
|
||||
{
|
||||
char[] chars = new char[length];
|
||||
byte[] values = new byte[length * sizeof(char)];
|
||||
|
||||
rng.GetBytes(values);
|
||||
Buffer.BlockCopy(values, 0, chars, 0, values.Length);
|
||||
|
||||
return new string(chars.Select(c => ValidChars[c % ValidChars.Length]).ToArray());
|
||||
}
|
||||
}
|
||||
public static string GenerateRandomKey(int length)
|
||||
{
|
||||
byte[] key = new byte[length];
|
||||
|
||||
using (RandomNumberGenerator rng = RandomNumberGenerator.Create())
|
||||
{
|
||||
rng.GetBytes(key); // 填充随机字节
|
||||
}
|
||||
|
||||
string mykey = Convert.ToBase64String(key);
|
||||
return mykey;
|
||||
}
|
||||
}
|
||||
}
|
||||
28
BooliveMQTT_Auth/Common/StaticData.cs
Normal file
28
BooliveMQTT_Auth/Common/StaticData.cs
Normal file
@@ -0,0 +1,28 @@
|
||||
using System.Reflection;
|
||||
using IronPython.Hosting;
|
||||
using Microsoft.Scripting.Hosting;
|
||||
|
||||
namespace IotManager.Common
|
||||
{
|
||||
public class StaticData
|
||||
{
|
||||
public static ScriptEngine eng = Python.CreateEngine();
|
||||
public static ScriptScope scope1 = eng.CreateScope();
|
||||
public static ScriptScope scope2 = eng.CreateScope();
|
||||
public static ScriptScope scope3 = eng.CreateScope();
|
||||
|
||||
public static void GetWebAPIMethod()
|
||||
{
|
||||
eng.Runtime.LoadAssembly(Assembly.GetExecutingAssembly());
|
||||
eng.ExecuteFile("script\\webapi.py", scope1);
|
||||
}
|
||||
public static void GetWebAPIMethod1()
|
||||
{
|
||||
eng.ExecuteFile("script\\CommonData.py", scope2);
|
||||
}
|
||||
public static void GetWebAPIMethod2()
|
||||
{
|
||||
eng.ExecuteFile("script\\b.py", scope1);
|
||||
}
|
||||
}
|
||||
}
|
||||
136
BooliveMQTT_Auth/Controllers/ConfigPYController.cs
Normal file
136
BooliveMQTT_Auth/Controllers/ConfigPYController.cs
Normal file
@@ -0,0 +1,136 @@
|
||||
using System.Text;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Http.HttpResults;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Scripting.Utils;
|
||||
using IotManager.Common;
|
||||
using ViewModels;
|
||||
using CommonEntity;
|
||||
|
||||
namespace SupplierManager.Controllers
|
||||
{
|
||||
[Route("api/[controller]/[action]")]
|
||||
[ApiController]
|
||||
public class ConfigPYController : ControllerBase
|
||||
{
|
||||
[HttpPost()]
|
||||
[Authorize()]
|
||||
public async Task<ReturnInfo> GetConfigString()
|
||||
{
|
||||
ReturnInfo r = new ReturnInfo();
|
||||
try
|
||||
{
|
||||
string[] str = await System.IO.File.ReadAllLinesAsync("script\\webapi.py");
|
||||
|
||||
List<VK> ll = new List<VK>();
|
||||
foreach (var item in str)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(item))
|
||||
{
|
||||
string[] a = item.Split('=');
|
||||
VK v = new VK();
|
||||
v.VarName = a[0];
|
||||
v.VarValue = a[1];
|
||||
ll.Add(v);
|
||||
}
|
||||
}
|
||||
|
||||
r.isok = true;
|
||||
r.response = ll;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
r.isok = false;
|
||||
r.message = ex.Message;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
[HttpPost()]
|
||||
[Authorize()]
|
||||
public ReturnInfo RefreshConfig()
|
||||
{
|
||||
ReturnInfo info = new ReturnInfo();
|
||||
info.isok = true;
|
||||
try
|
||||
{
|
||||
StaticData.GetWebAPIMethod();
|
||||
StaticData.GetWebAPIMethod1();
|
||||
info.message = "Sucess";
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
info.isok = false;
|
||||
info.message = ex.Message;
|
||||
}
|
||||
return info;
|
||||
}
|
||||
|
||||
public class VK
|
||||
{
|
||||
public string VarName { get; set; }
|
||||
public string VarValue { get; set; }
|
||||
}
|
||||
[HttpPost()]
|
||||
[Authorize()]
|
||||
public async Task<ReturnInfo> SaveOrAddConfigString([FromBody] VK data)
|
||||
{
|
||||
ReturnInfo info = new ReturnInfo();
|
||||
info.isok = true;
|
||||
try
|
||||
{
|
||||
var sss = System.IO.File.ReadAllLines("script\\webapi.py", Encoding.UTF8).ToList<string>();
|
||||
for (int i = 0; i < sss.Count; i++)
|
||||
{
|
||||
string item = sss[i];
|
||||
string[] txtdata = item.Split('=');
|
||||
if (txtdata[0].Equals(data.VarName))
|
||||
{
|
||||
txtdata[1] = data.VarValue;
|
||||
sss[i] = txtdata[0] + "=" + txtdata[1];
|
||||
}
|
||||
}
|
||||
bool exists = sss.Any(A => A.StartsWith(data.VarName));
|
||||
|
||||
if (exists == false)
|
||||
{
|
||||
sss.AddRange<string>(new string[] { data.VarName + "=" + data.VarValue });
|
||||
}
|
||||
|
||||
await System.IO.File.WriteAllLinesAsync("script\\webapi.py", sss, Encoding.UTF8);
|
||||
StaticData.GetWebAPIMethod();
|
||||
info.message = "Sucess";
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
info.isok = false;
|
||||
info.message = ex.Message;
|
||||
}
|
||||
return info;
|
||||
}
|
||||
[HttpPost()]
|
||||
[Authorize()]
|
||||
public ReturnInfo GetSingleValue([FromBody] Dictionary<string, string> dic)
|
||||
{
|
||||
ReturnInfo info = new ReturnInfo();
|
||||
info.isok = true;
|
||||
try
|
||||
{
|
||||
string VarValue = dic["VarName"];
|
||||
if (!string.IsNullOrEmpty(VarValue))
|
||||
{
|
||||
var QQQ = StaticData.scope1.GetVariable(VarValue);
|
||||
string str = System.Text.Json.JsonSerializer.Serialize(QQQ);
|
||||
info.response = str;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
info.isok = false;
|
||||
info.message = ex.Message;
|
||||
}
|
||||
return info;
|
||||
}
|
||||
}
|
||||
}
|
||||
472
BooliveMQTT_Auth/Controllers/DeviceinfoesController.cs
Normal file
472
BooliveMQTT_Auth/Controllers/DeviceinfoesController.cs
Normal file
@@ -0,0 +1,472 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text.Json;
|
||||
using System.Threading.Tasks;
|
||||
using Common;
|
||||
using CommonEntity;
|
||||
using IotManager.Common;
|
||||
using LogCap.Common;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.VisualBasic;
|
||||
using MySQLAccess.PGModels;
|
||||
using NLog;
|
||||
using NPOI.OpenXmlFormats.Dml;
|
||||
using Proto.Extensions;
|
||||
using RestSharp;
|
||||
using ViewModels;
|
||||
|
||||
namespace IotManager.Controllers
|
||||
{
|
||||
[Route("api/[controller]/[action]")]
|
||||
[ApiController]
|
||||
public class DeviceinfoesController : ControllerBase
|
||||
{
|
||||
private readonly Logger _logger = LogManager.GetCurrentClassLogger();
|
||||
private readonly PostgresContext _context;
|
||||
|
||||
public DeviceinfoesController(PostgresContext context)
|
||||
{
|
||||
_context = context;
|
||||
}
|
||||
|
||||
// GET: api/Deviceinfoes
|
||||
[HttpPost()]
|
||||
public async Task<ReturnInfo> GetDeviceinfos(QueryAll_Or_Single Q)
|
||||
{
|
||||
ReturnInfo r = new ReturnInfo();
|
||||
try
|
||||
{
|
||||
if (Q.IsAll)
|
||||
{
|
||||
r.isok = true;
|
||||
r.response = await _context.Deviceinfos.ToListAsync();
|
||||
}
|
||||
else
|
||||
{
|
||||
var deviceinfo = await _context.Deviceinfos.FindAsync(Q.ID);
|
||||
if (deviceinfo == null)
|
||||
{
|
||||
r.isok = false;
|
||||
r.message = "找不到此数据";
|
||||
}
|
||||
r.isok = true;
|
||||
r.response = deviceinfo;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
r.isok = false;
|
||||
r.message = ex.Message;
|
||||
}
|
||||
return r;
|
||||
|
||||
}
|
||||
|
||||
[HttpPost()]
|
||||
public async Task<ReturnInfo> GetAllBatchFlag(QueryMachineType S)
|
||||
{
|
||||
ReturnInfo r = new ReturnInfo();
|
||||
try
|
||||
{
|
||||
int one = S.MachineType;
|
||||
var st = S.StartTime;
|
||||
var et = S.EndTime;
|
||||
var ST = DateTime.Parse(st);
|
||||
var ET = DateTime.Parse(et);
|
||||
|
||||
var data = await _context.Deviceinfos.Where(A => A.MachineType == one && A.CreateTime > ST && A.CreateTime <= ET)
|
||||
.GroupBy(d => d.ExcelBatchFlag)
|
||||
.Select(g => new
|
||||
{
|
||||
ExcelBatchFlag = g.Key.ToString(),
|
||||
CreateTime = g.Select(x => x.CreateTime).FirstOrDefault(),
|
||||
Count = g.Count()
|
||||
})
|
||||
.ToListAsync();
|
||||
r.isok = true;
|
||||
r.response = data;
|
||||
return r;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
r.isok = false;
|
||||
r.response = ex.Message;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
[Authorize()]
|
||||
[HttpPost()]
|
||||
public async Task<ReturnInfo> GetDeviceinfosByBatchFlag(Dictionary<string, string> Q)
|
||||
{
|
||||
ReturnInfo r = new ReturnInfo();
|
||||
try
|
||||
{
|
||||
string batchflag = Q["FileBatchFlag"];
|
||||
long NNN = 0L;
|
||||
long.TryParse(batchflag, out NNN);
|
||||
var data = from a in _context.Deviceinfos
|
||||
join b in _context.EmqxLogininfos
|
||||
on a.Uuid equals b.DeviceUuid
|
||||
into DeviceInfo
|
||||
from d in DeviceInfo.DefaultIfEmpty()
|
||||
where a.ExcelBatchFlag == NNN
|
||||
select new { a.DeviceName, a.OrderNo, a.ClientId, a.SecretKey, a.Remark, d.PassWord };
|
||||
|
||||
var data1 = await data.Select(A => new DeviceInfoResponse
|
||||
{
|
||||
DeviceName = A.DeviceName,
|
||||
MO = A.OrderNo,
|
||||
ClientID = A.ClientId,
|
||||
MQTT_Login_Password = A.PassWord,
|
||||
Key = A.SecretKey,
|
||||
Remark = A.Remark
|
||||
}).ToListAsync();
|
||||
r.isok = true;
|
||||
r.response = data1;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
r.isok = false;
|
||||
r.response = ex.Message;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
[Authorize()]
|
||||
[HttpPost()]
|
||||
public async Task<ReturnInfo> EditDeviceinfo(Deviceinfo deviceinfo)
|
||||
{
|
||||
ReturnInfo r = new ReturnInfo();
|
||||
try
|
||||
{
|
||||
if (!DeviceinfoExists(deviceinfo.ClientId))
|
||||
{
|
||||
r.isok = false;
|
||||
r.message = "not found";
|
||||
return r;
|
||||
}
|
||||
|
||||
_context.Entry(deviceinfo).State = EntityState.Modified;
|
||||
await _context.SaveChangesAsync();
|
||||
|
||||
r.isok = true;
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
r.isok = false;
|
||||
r.message = ex.Message;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
public string GetId(string device_name, string uuid)
|
||||
{
|
||||
string NNN = PasswordGenerator.Generate(16);
|
||||
//string data = string.Format("inhaos_{0}_{1}_{2}", device_name, uuid, NNN);
|
||||
//// 密钥,用于生成MAC
|
||||
//string key = "[secNret)Key#&!";
|
||||
//// 计算MAC
|
||||
//byte[] mac = Base64.ComputeHMACSHA256(data, key);
|
||||
//string str = Convert.ToBase64String(mac);
|
||||
return NNN;
|
||||
}
|
||||
|
||||
public record DeviceInfoRequest
|
||||
{
|
||||
public int id { get; set; }
|
||||
public string DeviceName { get; set; }
|
||||
public string MO { get; set; }
|
||||
public int MachineType { get; set; }
|
||||
public string Remark { get; set; }
|
||||
}
|
||||
public record DeviceInfoResponse
|
||||
{
|
||||
public string? DeviceName { get; set; }
|
||||
public string? MO { get; set; }
|
||||
public long? ClientID { get; set; }
|
||||
public string? MQTT_Login_Password { get; set; }
|
||||
public string? Key { get; set; }
|
||||
public string? Remark { get; set; }
|
||||
}
|
||||
public record IdFilter
|
||||
{
|
||||
public int id { get; set; }
|
||||
public string UUID { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设备查询参数
|
||||
/// </summary>
|
||||
public class DeviceQueryParams
|
||||
{
|
||||
public int MachineType { get; set; }
|
||||
public string Mcu_Uuid { get; set; }
|
||||
public int? Brandld { get; set; }
|
||||
}
|
||||
|
||||
|
||||
public class UserData
|
||||
{
|
||||
public string username { get; set; }
|
||||
public string password { get; set; }
|
||||
}
|
||||
|
||||
[HttpPost()]
|
||||
public async Task<string> SendHttpData(List<UserData> userdata)
|
||||
{
|
||||
string resp = "";
|
||||
try
|
||||
{
|
||||
resp = await RedisWriter(userdata);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Error(ex.Message);
|
||||
}
|
||||
return resp;
|
||||
}
|
||||
|
||||
private async Task<string> RedisWriter(List<UserData> userdata)
|
||||
{
|
||||
RestClient client1 = new RestClient("http://iot-manage.uts-data.com:5001");
|
||||
string ti = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff");
|
||||
var request1 = new RestRequest("/api/Values/SetChache", Method.Post);
|
||||
request1.AddJsonBody(userdata);
|
||||
var re = await client1.ExecuteAsync(request1);
|
||||
string resp = re.Content;
|
||||
_logger.Error("Redis缓存:" + resp);
|
||||
return resp;
|
||||
}
|
||||
|
||||
[Authorize()]
|
||||
[HttpPost]
|
||||
public async Task<ReturnInfo> AddDeviceinfo(List<DeviceInfoRequest> List_LLL)
|
||||
{
|
||||
ReturnInfo returnInfo = new ReturnInfo();
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
var QQQ = List_LLL.Select(A => A.DeviceName);
|
||||
var q1 = _context.Deviceinfos.Any(A => QQQ.Contains(A.DeviceName));
|
||||
if (q1)
|
||||
{
|
||||
returnInfo.isok = false;
|
||||
returnInfo.message = "设备名字重复,不可导入";
|
||||
return returnInfo;
|
||||
}
|
||||
var worker = new IdWorker(31, 30);
|
||||
long filebatch = worker.nextId();
|
||||
List<UserData> lll = new List<UserData>();
|
||||
_context.Database.BeginTransaction();
|
||||
var DT = DateTime.Now;
|
||||
var LT = Tools.ToUnixTimestampBySeconds(DT);
|
||||
|
||||
List<Deviceinfo> device_list = new List<Deviceinfo>();
|
||||
List<EmqxLogininfo> login_list = new List<EmqxLogininfo>();
|
||||
foreach (var LLL in List_LLL)
|
||||
{
|
||||
UserData u = new UserData();
|
||||
var LLL1 = new Deviceinfo();
|
||||
var uuid = Guid.NewGuid().ToString("N");
|
||||
|
||||
LLL1.Uuid = uuid;
|
||||
LLL1.DeviceName = LLL.DeviceName;
|
||||
LLL1.OrderNo = LLL.MO;
|
||||
LLL1.MachineType = LLL.MachineType;
|
||||
|
||||
LLL1.SecretKey = PasswordGenerator.Generate(16);
|
||||
LLL1.Remark = LLL.Remark;
|
||||
LLL1.ExcelBatchFlag = filebatch;
|
||||
|
||||
|
||||
LLL1.CreateTime = DT;
|
||||
LLL1.UpdateTime = DT;
|
||||
|
||||
LLL1.CreateTimeUnix = LT;
|
||||
LLL1.UpdateTimeUnix = LT;
|
||||
|
||||
device_list.Add(LLL1);
|
||||
|
||||
// 如果 是MQTT才会
|
||||
if (LLL.MachineType != 1)
|
||||
{
|
||||
EmqxLogininfo l = new EmqxLogininfo();
|
||||
l.DeviceUuid = uuid;
|
||||
l.UserName = LLL.DeviceName;
|
||||
l.PassWord = GetId(l.UserName, uuid);
|
||||
l.UpdateTime = DT;
|
||||
l.UpdateTimeUnix = LT;
|
||||
l.CreateTime = DT;
|
||||
l.CreateTimeUnix = LT;
|
||||
login_list.Add(l);
|
||||
|
||||
u.username = LLL1.DeviceName;
|
||||
u.password = l.PassWord;
|
||||
lll.Add(u);
|
||||
}
|
||||
|
||||
//_context.EmqxLogininfos.Add(l);
|
||||
|
||||
}
|
||||
|
||||
_context.Deviceinfos.AddRange(device_list);
|
||||
_context.EmqxLogininfos.AddRange(login_list);
|
||||
_context.SaveChanges();
|
||||
|
||||
if (lll.Count > 0)
|
||||
{
|
||||
string tr = await RedisWriter(lll);
|
||||
if (!string.IsNullOrEmpty(tr))
|
||||
{
|
||||
var rest = JsonSerializer.Deserialize<ReturnInfo>(tr);
|
||||
if (rest?.isok == false)
|
||||
{
|
||||
throw new Exception("Redis写入失败");
|
||||
}
|
||||
}
|
||||
}
|
||||
_context.Database.CommitTransaction();
|
||||
|
||||
returnInfo.response = filebatch.ToString();
|
||||
returnInfo.isok = true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
returnInfo.isok = false;
|
||||
returnInfo.message = ex.Message;
|
||||
}
|
||||
|
||||
return returnInfo;
|
||||
}
|
||||
|
||||
[HttpPost()]
|
||||
public async Task<ReturnInfo> DeleteDeviceinfo(Dictionary<string, string> data)
|
||||
{
|
||||
ReturnInfo r = new ReturnInfo();
|
||||
try
|
||||
{
|
||||
string id = data["id"];
|
||||
var deviceinfo = await _context.Deviceinfos.FindAsync(id);
|
||||
if (deviceinfo == null)
|
||||
{
|
||||
r.isok = false;
|
||||
r.message = "not found this data";
|
||||
}
|
||||
|
||||
_context.Deviceinfos.Remove(deviceinfo);
|
||||
await _context.SaveChangesAsync();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
r.isok = false;
|
||||
r.isok = true;
|
||||
}
|
||||
return r;
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 条件查询接口 - 根据MachineType、UUID和Brandld查询唯一记录
|
||||
/// </summary>
|
||||
/// <param name="queryParams">查询参数</param>
|
||||
/// <returns>查询结果</returns>
|
||||
[HttpPost]
|
||||
public async Task<ReturnInfo> GetDeviceByCondition(DeviceQueryParams queryParams)
|
||||
{
|
||||
ReturnInfo r = new();
|
||||
try
|
||||
{
|
||||
var query = _context.Deviceinfos
|
||||
.Where(d => d.MachineType == queryParams.MachineType && d.McuUuid.Equals(queryParams.Mcu_Uuid));
|
||||
|
||||
// 如果Brandld不为空,则添加Brandld条件
|
||||
if (queryParams.Brandld != null)
|
||||
{
|
||||
query = query.Where(d => d.Brandld == queryParams.Brandld);
|
||||
}
|
||||
var ddd = query.ToList();
|
||||
var deviceinfo = await query.FirstOrDefaultAsync();
|
||||
r.isok = true;
|
||||
r.response = deviceinfo;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
r.isok = false;
|
||||
r.message = ex.Message;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
private bool DeviceinfoExists(long id)
|
||||
{
|
||||
return _context.Deviceinfos.Any(e => e.ClientId == id);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 条件查询并修改接口
|
||||
/// </summary>
|
||||
/// <param name="queryParams">查询参数</param>
|
||||
/// <returns>查询或更新后的记录</returns>
|
||||
[HttpPost]
|
||||
public async Task<ReturnInfo> GetOrUpdateDevice(DeviceQueryParams queryParams)
|
||||
{
|
||||
ReturnInfo r = new();
|
||||
try
|
||||
{
|
||||
// 第一步:根据条件查询
|
||||
var query = _context.Deviceinfos
|
||||
.Where(d => d.MachineType == queryParams.MachineType && d.McuUuid.Equals(queryParams.Mcu_Uuid));
|
||||
|
||||
// 如果Brandld不为空,则添加Brandld条件
|
||||
if (queryParams.Brandld != null)
|
||||
{
|
||||
query = query.Where(d => d.Brandld == queryParams.Brandld);
|
||||
}
|
||||
|
||||
var deviceinfo = await query.FirstOrDefaultAsync();
|
||||
|
||||
if (deviceinfo == null)
|
||||
{
|
||||
// 第二步:查询ClientId最小,MachineType匹配且Uuid为空的记录
|
||||
var minClientIdQuery = _context.Deviceinfos
|
||||
.Where(d => d.MachineType == queryParams.MachineType && string.IsNullOrEmpty(d.McuUuid))
|
||||
.OrderBy(d => d.ClientId);
|
||||
|
||||
var minClientIdDevice = await minClientIdQuery.FirstOrDefaultAsync();
|
||||
|
||||
if (minClientIdDevice != null)
|
||||
{
|
||||
// 第三步:更新记录
|
||||
minClientIdDevice.McuUuid = queryParams.Mcu_Uuid;
|
||||
minClientIdDevice.Brandld = queryParams.Brandld;
|
||||
minClientIdDevice.UpdateTime = DateTime.Now;
|
||||
minClientIdDevice.UpdateTimeUnix = Tools.ToUnixTimestampBySeconds(DateTime.Now);
|
||||
|
||||
_context.Deviceinfos.Update(minClientIdDevice);
|
||||
await _context.SaveChangesAsync();
|
||||
|
||||
// 第四步:查询更新后的记录
|
||||
deviceinfo = await _context.Deviceinfos.FindAsync(minClientIdDevice.ClientId);
|
||||
}
|
||||
}
|
||||
|
||||
r.isok = true;
|
||||
r.response = deviceinfo;
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
r.isok = false;
|
||||
r.message = ex.Message;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
}
|
||||
}
|
||||
134
BooliveMQTT_Auth/Controllers/FileUploadController.cs
Normal file
134
BooliveMQTT_Auth/Controllers/FileUploadController.cs
Normal file
@@ -0,0 +1,134 @@
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Http.HttpResults;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace SupplierManager.Controllers
|
||||
{
|
||||
[Route("api/[controller]/[action]")]
|
||||
[ApiController]
|
||||
public class FileUploadController : ControllerBase
|
||||
{
|
||||
|
||||
public static string[] FolderG = new string[] {"face" };
|
||||
|
||||
[Authorize()]
|
||||
[HttpPost()]
|
||||
public async Task<IActionResult> UploadFile([FromForm] UploadFileModel model)
|
||||
{
|
||||
if (model.File == null || model.File.Length == 0)
|
||||
{
|
||||
return BadRequest("没有上传任何文件");
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// 获取文件名和扩展名
|
||||
string originalFileName = Path.GetFileNameWithoutExtension(model.File.FileName);
|
||||
string fileExtension = Path.GetExtension(model.File.FileName); // 包含扩展名前的点(如.jpg)
|
||||
|
||||
// 生成8位GUID(取完整GUID的前8位字符)
|
||||
string guidPart = Guid.NewGuid().ToString("N")[..16];
|
||||
|
||||
// 组合新文件名:原文件名_8位GUID.扩展名
|
||||
string newFileName = $"{originalFileName}_{guidPart}{fileExtension}";
|
||||
|
||||
var filePath = Path.Combine(Directory.GetCurrentDirectory(),
|
||||
$"wwwroot/Uploads/{model.Folder}",
|
||||
newFileName);
|
||||
|
||||
using (var stream = new FileStream(filePath, FileMode.Create))
|
||||
{
|
||||
await model.File.CopyToAsync(stream);
|
||||
}
|
||||
return Ok(new { FileName = newFileName });
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return BadRequest(new { Message = ex.Message });
|
||||
}
|
||||
}
|
||||
|
||||
public record DF
|
||||
{
|
||||
public string? FileName { get; set; }
|
||||
}
|
||||
// 示例:通过文件名获取图片
|
||||
[Authorize()]
|
||||
[HttpPost()]
|
||||
public IActionResult DownloadFile([FromBody]DF imageName)
|
||||
{
|
||||
try
|
||||
{
|
||||
// 拼接图片物理路径(假设图片存放在项目的 wwwroot/images 目录下)
|
||||
var imagePath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot/", imageName.FileName);
|
||||
|
||||
// 检查文件是否存在
|
||||
if (!System.IO.File.Exists(imagePath))
|
||||
{
|
||||
return NotFound("Image not found");
|
||||
}
|
||||
if (imageName.FileName.Contains(".."))
|
||||
{
|
||||
return BadRequest("Invalid file name");
|
||||
}
|
||||
|
||||
|
||||
// 读取文件流并返回
|
||||
var imageStream = System.IO.File.OpenRead(imagePath);
|
||||
|
||||
// 根据扩展名自动设置 Content-Type(MIME类型)
|
||||
var mimeType = GetMimeType(imageName.FileName);
|
||||
|
||||
return File(imageStream, mimeType);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return StatusCode(500, $"Internal server error: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
[Authorize()]
|
||||
[HttpPost()]
|
||||
public IActionResult GetFileNameList()
|
||||
{
|
||||
try
|
||||
{
|
||||
// 拼接图片物理路径(假设图片存放在项目的 wwwroot/images 目录下)
|
||||
var filePath = Path.Combine(Directory.GetCurrentDirectory(),
|
||||
$"wwwroot/Download/customization","");
|
||||
|
||||
string[] files= System.IO.Directory.GetFiles(filePath);
|
||||
var myfiles= files.Select(A=>Path.GetFileName(A));
|
||||
return Ok(new { FileNameList = myfiles });
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return StatusCode(500, $"Internal server error: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
// 获取 MIME 类型映射
|
||||
private string GetMimeType(string fileName)
|
||||
{
|
||||
var extension = Path.GetExtension(fileName).ToLowerInvariant();
|
||||
return
|
||||
extension switch
|
||||
{
|
||||
".jpg" => "image/jpeg",
|
||||
".jpeg" => "image/jpeg",
|
||||
".png" => "image/png",
|
||||
".gif" => "image/gif",
|
||||
".xls" =>"application/vnd.ms-excel",
|
||||
".xlsx"=>"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
||||
_ => "application/octet-stream" // 默认类型
|
||||
};
|
||||
}
|
||||
}
|
||||
public class UploadFileModel
|
||||
{
|
||||
public IFormFile File { get; set; }
|
||||
public string Folder { get; set; }
|
||||
}
|
||||
}
|
||||
11
BooliveMQTT_Auth/Controllers/GrafanaMonitorController.cs
Normal file
11
BooliveMQTT_Auth/Controllers/GrafanaMonitorController.cs
Normal file
@@ -0,0 +1,11 @@
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace IotManager.Controllers
|
||||
{
|
||||
[Route("api/[controller]/[action]")]
|
||||
[ApiController]
|
||||
public class GrafanaMonitorController : ControllerBase
|
||||
{
|
||||
}
|
||||
}
|
||||
144
BooliveMQTT_Auth/Controllers/LoginController.cs
Normal file
144
BooliveMQTT_Auth/Controllers/LoginController.cs
Normal file
@@ -0,0 +1,144 @@
|
||||
using System.IdentityModel.Tokens.Jwt;
|
||||
using System.Security.Claims;
|
||||
using System.Security.Cryptography;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.Text;
|
||||
using CommonEntity;
|
||||
using IotManager.Common;
|
||||
using IotManager.private_key;
|
||||
using Jose;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.IdentityModel.Tokens;
|
||||
using MySQLAccess.PGModels;
|
||||
using NLog;
|
||||
using ViewModels;
|
||||
|
||||
namespace IotManager.Controllers
|
||||
{
|
||||
[Route("api/[controller]/[action]")]
|
||||
[ApiController]
|
||||
public class LoginController : ControllerBase
|
||||
{
|
||||
private readonly Logger _logger = LogManager.GetCurrentClassLogger();
|
||||
public IConfiguration? configuration { get; set; }
|
||||
|
||||
private PostgresContext IotServerContext { get; set; }
|
||||
public LoginController(IConfiguration _configuration, PostgresContext iot)
|
||||
{
|
||||
configuration = _configuration;
|
||||
this.IotServerContext = iot;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 登录
|
||||
/// </summary>
|
||||
/// <param name="username">用户名</param>
|
||||
/// <param name="password">密码</param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
public ReturnInfo Login([FromBody] LoginData data)
|
||||
{
|
||||
|
||||
ReturnInfo res = new ReturnInfo();
|
||||
|
||||
try
|
||||
{
|
||||
Userinfo? entity = null;
|
||||
string password = data.password;
|
||||
string username = data.username;
|
||||
string TokenString = "";
|
||||
//using (var q = new IotServerContext())
|
||||
//{
|
||||
entity = IotServerContext.Userinfos.SingleOrDefault(A => A.UserName.Equals(username));
|
||||
if (entity != null)
|
||||
{
|
||||
bool vvv = JiaJieMi.VerifyHashedPassword(entity.PassWord, password);
|
||||
if (vvv == false)
|
||||
{
|
||||
res.isok = false;
|
||||
res.message = "密码错误";
|
||||
}
|
||||
else
|
||||
{
|
||||
TokenString = GetToken(entity);
|
||||
res.isok = true;
|
||||
|
||||
|
||||
ResLoginData r = new ResLoginData();
|
||||
r.AccessToken = TokenString;
|
||||
r.Id = entity.Id;
|
||||
r.Permission = entity.Permission;
|
||||
r.UserName = entity.UserName;
|
||||
r.RealName = entity.RealName;
|
||||
r.CompanyName = entity.CompanyName;
|
||||
|
||||
res.response = r;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
res.isok = false;
|
||||
res.message = "用户不存在";
|
||||
}
|
||||
//}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
res.message = ex.Message;
|
||||
res.isok = false;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
public string GetToken([FromBody] Userinfo? entity)
|
||||
{
|
||||
string TokenString;
|
||||
var claims = new Claim[]
|
||||
{
|
||||
new Claim(ClaimTypes.NameIdentifier, entity.Id.ToString()),
|
||||
new Claim(ClaimTypes.Name, entity.UserName),
|
||||
new Claim(ClaimTypes.Hash,Guid.NewGuid().ToString("N"))
|
||||
};
|
||||
|
||||
var secretByte = Encoding.UTF8.GetBytes(configuration["JwT:SecretKey"]);
|
||||
var signingKey = new SymmetricSecurityKey(secretByte);
|
||||
var a = SecurityAlgorithms.HmacSha256;
|
||||
|
||||
var signingCredentials = new SigningCredentials(signingKey, a);
|
||||
|
||||
//有效期设置为1天signingCredentials //数字名
|
||||
var token = new JwtSecurityToken(
|
||||
issuer: configuration?["JwT:Issuer"],
|
||||
audience: configuration?["JwT:Audience"],//接收
|
||||
claims: claims,//存放的用户信息
|
||||
notBefore: DateTime.UtcNow,//发布时间
|
||||
expires: DateTime.UtcNow.AddHours(12),
|
||||
signingCredentials: signingCredentials
|
||||
);
|
||||
TokenString = new JwtSecurityTokenHandler().WriteToken(token);
|
||||
return TokenString;
|
||||
}
|
||||
|
||||
[HttpPost()]
|
||||
[Authorize()]
|
||||
public string Helloooo(string key)
|
||||
{
|
||||
return "allow";
|
||||
}
|
||||
|
||||
|
||||
[HttpPost()]
|
||||
public string MyTTT(DengLu key)
|
||||
{
|
||||
return "allow";
|
||||
}
|
||||
}
|
||||
public class DengLu
|
||||
{
|
||||
|
||||
public string UserName { get; set; }
|
||||
public string PassWord { get; set; }
|
||||
}
|
||||
}
|
||||
92
BooliveMQTT_Auth/Controllers/MQTTReceiveAPIController.cs
Normal file
92
BooliveMQTT_Auth/Controllers/MQTTReceiveAPIController.cs
Normal file
@@ -0,0 +1,92 @@
|
||||
using System.Text;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using MySQLAccess.PGModels;
|
||||
using Newtonsoft.Json;
|
||||
using NLog;
|
||||
using ViewModels;
|
||||
|
||||
namespace IotManager.Controllers
|
||||
{
|
||||
[Route("api/[controller]/[action]")]
|
||||
[ApiController]
|
||||
public class MQTTReceiveAPIController : ControllerBase
|
||||
{
|
||||
private readonly Logger _logger = LogManager.GetCurrentClassLogger();
|
||||
private readonly IConfiguration? config;
|
||||
private PostgresContext IotServerContext { get; set; }
|
||||
|
||||
public MQTTReceiveAPIController(IConfiguration config, PostgresContext context)
|
||||
{
|
||||
this.config = config;
|
||||
this.IotServerContext = context;
|
||||
}
|
||||
[HttpPost()]
|
||||
public void ReceiveData()
|
||||
{
|
||||
try
|
||||
{
|
||||
var readResult = Request.BodyReader.ReadAsync().Result;
|
||||
Request.BodyReader.AdvanceTo(readResult.Buffer.Start, readResult.Buffer.End);
|
||||
string body = Encoding.UTF8.GetString(readResult.Buffer.FirstSpan);
|
||||
|
||||
if (!string.IsNullOrEmpty(body))
|
||||
{
|
||||
Task.Factory.StartNew((state) =>
|
||||
{
|
||||
string BodyString = state.ToString();
|
||||
_logger.Error(body);
|
||||
var QQQ = System.Text.Json.JsonSerializer.Deserialize<RawPayload>(body);
|
||||
string topic = QQQ.topic;
|
||||
string payload = QQQ.payload;
|
||||
|
||||
//传递过来的数据就是base64的,没有必要再转
|
||||
byte[] bbb = Convert.FromBase64String(payload);
|
||||
string bbb1 = Tools.ByteToString(bbb);
|
||||
|
||||
this._logger.Info("Topic: " + topic);
|
||||
this._logger.Info("PayLoad: " + bbb1);
|
||||
|
||||
|
||||
byte[] NNN1 = Tools.HEXString2ByteArray(bbb1.Replace(" ", ""));
|
||||
//AA 13 00 44 0B 00 FF FF FF FF 61 67 EF 6B E8 2D 2D 0D 0A 2D 2D
|
||||
|
||||
byte Header = NNN1[0];
|
||||
//从1到3之间的元素,不包括3
|
||||
byte[] Len = NNN1[1..3];
|
||||
//byte[] Len = NNN1.AsSpan(1,2);
|
||||
byte[] Pack_SN = NNN1[3..5];
|
||||
|
||||
//重发次数
|
||||
byte RetryCount = NNN1[5];
|
||||
|
||||
//设备编号
|
||||
byte[] DeviceOnlyNo = NNN1[6..10];
|
||||
|
||||
//命令字
|
||||
byte[] Command = NNN1[10..12];
|
||||
|
||||
|
||||
//校验CRC16,小端模式(低地址在前)
|
||||
//校验内容:Pack_Head + Pack_LEN + Pack_SN + Retry_Num + Client_ID + CMD + PARA
|
||||
byte[] CRCCode = NNN1[^8..^6];
|
||||
|
||||
//结尾标志符
|
||||
//// 获取从倒数第三个元素到数组末尾的所有元素
|
||||
byte[] Tail = NNN1[^6..];
|
||||
|
||||
}, body);
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
public class RawPayload
|
||||
{
|
||||
public string topic { get; set; }
|
||||
public string payload { get; set; }
|
||||
}
|
||||
}
|
||||
167
BooliveMQTT_Auth/Controllers/MachineTypesController.cs
Normal file
167
BooliveMQTT_Auth/Controllers/MachineTypesController.cs
Normal file
@@ -0,0 +1,167 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using CommonEntity;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using MySQLAccess.PGModels;
|
||||
|
||||
namespace IotManager.Controllers
|
||||
{
|
||||
[Route("api/[controller]/[action]")]
|
||||
[ApiController]
|
||||
public class MachineTypesController : ControllerBase
|
||||
{
|
||||
private readonly PostgresContext _context;
|
||||
private readonly IConfiguration _config;
|
||||
|
||||
public MachineTypesController(PostgresContext context, IConfiguration config)
|
||||
{
|
||||
_context = context;
|
||||
_config = config;
|
||||
|
||||
}
|
||||
|
||||
// GET: api/MachineTypes
|
||||
[HttpPost()]
|
||||
[Authorize()]
|
||||
public async Task<ReturnInfo> GetMachineTypes(QueryAll_Or_Single Q)
|
||||
{
|
||||
ReturnInfo r = new ReturnInfo();
|
||||
|
||||
try
|
||||
{
|
||||
if (Q.IsAll)
|
||||
{
|
||||
r.isok = true;
|
||||
r.response = await _context.MachineTypes.Where(A=>A.IsDelete==false).ToListAsync();
|
||||
}
|
||||
else
|
||||
{
|
||||
var machineType = await _context.MachineTypes.FindAsync(Q.ID);
|
||||
|
||||
if (machineType == null)
|
||||
{
|
||||
r.isok = false;
|
||||
r.message = "找不到数据";
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
r.isok = false;
|
||||
r.message = ex.Message;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
// PUT: api/MachineTypes/5
|
||||
// To protect from overposting attacks, see https://go.microsoft.com/fwlink/?linkid=2123754
|
||||
[HttpPost()]
|
||||
public async Task<ReturnInfo> EditMachineType(MachineType machineType)
|
||||
{
|
||||
|
||||
ReturnInfo r = new ReturnInfo();
|
||||
try
|
||||
{
|
||||
if (!MachineTypeExistsById(machineType.Id))
|
||||
{
|
||||
r.message = "找不到这条数据";
|
||||
r.isok = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
r.isok = true;
|
||||
machineType.UpdateTime = DateTime.Now;
|
||||
_context.Entry(machineType).State = EntityState.Modified;
|
||||
await _context.SaveChangesAsync();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
r.message = ex.Message;
|
||||
r.isok = false;
|
||||
}
|
||||
return r;
|
||||
|
||||
}
|
||||
|
||||
// POST: api/MachineTypes
|
||||
// To protect from overposting attacks, see https://go.microsoft.com/fwlink/?linkid=2123754
|
||||
[HttpPost]
|
||||
public async Task<ReturnInfo> AddMachineType(MachineType machineType)
|
||||
{
|
||||
|
||||
ReturnInfo r = new ReturnInfo();
|
||||
try
|
||||
{
|
||||
|
||||
if (MachineTypeExists(machineType.DeviceTypeName))
|
||||
{
|
||||
r.isok = false;
|
||||
r.message = "已经存在此机型";
|
||||
}
|
||||
else
|
||||
{
|
||||
machineType.UpdateTime = DateTime.Now;
|
||||
machineType.CreateTime = DateTime.Now;
|
||||
r.isok = true;
|
||||
_context.MachineTypes.Add(machineType);
|
||||
await _context.SaveChangesAsync();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
r.message = ex.Message;
|
||||
r.isok = false;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
// DELETE: api/MachineTypes/5
|
||||
[HttpPost()]
|
||||
public async Task<ReturnInfo> DeleteMachineType(Dictionary<string, int> data)
|
||||
{
|
||||
|
||||
ReturnInfo r = new ReturnInfo();
|
||||
try
|
||||
{
|
||||
var machineType = await _context.MachineTypes.FindAsync(data["id"]);
|
||||
if (machineType == null)
|
||||
{
|
||||
r.isok = false;
|
||||
r.message = "要删除的数据不存在";
|
||||
}
|
||||
else
|
||||
{
|
||||
r.isok = true;
|
||||
machineType.IsDelete = true;
|
||||
machineType.UpdateTime = DateTime.Now;
|
||||
_context.MachineTypes.Update(machineType);
|
||||
await _context.SaveChangesAsync();
|
||||
}
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
r.message = ex.Message;
|
||||
r.isok = false;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
private bool MachineTypeExists(string name)
|
||||
{
|
||||
return _context.MachineTypes.Any(e => e.DeviceTypeName.Equals(name));
|
||||
}
|
||||
|
||||
private bool MachineTypeExistsById(int id)
|
||||
{
|
||||
return _context.MachineTypes.Any(e => e.Id == id);
|
||||
}
|
||||
}
|
||||
}
|
||||
16
BooliveMQTT_Auth/Controllers/QueryAll_Or_Single.cs
Normal file
16
BooliveMQTT_Auth/Controllers/QueryAll_Or_Single.cs
Normal file
@@ -0,0 +1,16 @@
|
||||
namespace IotManager.Controllers
|
||||
{
|
||||
public class QueryAll_Or_Single
|
||||
{
|
||||
public bool IsAll { get; set; }
|
||||
public int ID { get; set; }
|
||||
}
|
||||
|
||||
|
||||
public class QueryMachineType
|
||||
{
|
||||
public int MachineType { get; set; }
|
||||
public string StartTime { get; set; }
|
||||
public string EndTime { get; set; }
|
||||
}
|
||||
}
|
||||
241
BooliveMQTT_Auth/Controllers/RolesController.cs
Normal file
241
BooliveMQTT_Auth/Controllers/RolesController.cs
Normal file
@@ -0,0 +1,241 @@
|
||||
using CommonEntity;
|
||||
using IotManager.Common;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using MySQLAccess.PGModels;
|
||||
using NPOI.OpenXmlFormats.Spreadsheet;
|
||||
using NuGet.Protocol.Plugins;
|
||||
using ViewModels;
|
||||
|
||||
namespace IotManager.Controllers
|
||||
{
|
||||
[Route("api/[controller]/[action]")]
|
||||
[ApiController]
|
||||
public class RolesController : ControllerBase
|
||||
{
|
||||
public PostgresContext q { get; set; }
|
||||
public RolesController(PostgresContext dbcontext)
|
||||
{
|
||||
q = dbcontext;
|
||||
}
|
||||
public class DelData
|
||||
{
|
||||
public int Id { get; set; }
|
||||
}
|
||||
/// <summary>
|
||||
/// 删除角色
|
||||
/// </summary>
|
||||
/// <param name="LLL"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost()]
|
||||
[Authorize()]
|
||||
public ReturnInfo DelRole([FromBody] DelData LLL)
|
||||
{
|
||||
ReturnInfo returnInfo = new();
|
||||
if (LLL.Id == 1)
|
||||
{
|
||||
returnInfo.isok = false;
|
||||
returnInfo.message = "超级管理员不可删除!";
|
||||
return returnInfo;
|
||||
}
|
||||
try
|
||||
{
|
||||
var FFF = q.Roleinfos.FirstOrDefault(A => A.Id == LLL.Id);
|
||||
if (FFF != null)
|
||||
{
|
||||
FFF.IsDelete = true;
|
||||
q.Roleinfos.Update(FFF);
|
||||
q.SaveChanges();
|
||||
returnInfo.isok = true;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
returnInfo.isok = false;
|
||||
returnInfo.message = ex.Message;
|
||||
}
|
||||
return returnInfo;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 修改角色
|
||||
/// </summary>
|
||||
/// <param name="LLL"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost()]
|
||||
[Authorize()]
|
||||
public ReturnInfo EditRole([FromBody] ReturnRole LLL)
|
||||
{
|
||||
ReturnInfo returnInfo = new ReturnInfo();
|
||||
|
||||
try
|
||||
{
|
||||
//using (var q = new IotServerContext())
|
||||
//{
|
||||
var lll = q.Roleinfos.SingleOrDefault(A => A.Id == LLL.Id);
|
||||
if (lll != null)
|
||||
{
|
||||
|
||||
lll.Permission = LLL.Permission;
|
||||
lll.DeviceLicense = LLL.DeviceLicense;
|
||||
lll.UpdateTime = DateTime.Now;
|
||||
|
||||
|
||||
q.Roleinfos.Update(lll);
|
||||
q.SaveChanges();
|
||||
returnInfo.isok = true;
|
||||
}
|
||||
//}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
returnInfo.isok = false;
|
||||
returnInfo.message = ex.Message;
|
||||
}
|
||||
return returnInfo;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取角色信息
|
||||
/// </summary>
|
||||
/// <param name="S"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost()]
|
||||
[Authorize()]
|
||||
public ReturnInfo GetRoleInfo([FromBody] QueryAll_Or_Single S)
|
||||
{
|
||||
ReturnInfo returnInfo = new ReturnInfo();
|
||||
|
||||
try
|
||||
{
|
||||
if (S.IsAll)
|
||||
{
|
||||
returnInfo.isok = true;
|
||||
returnInfo.response = q.Roleinfos.Where(A => A.IsDelete == false).Select(F => new ReturnRole
|
||||
{
|
||||
Id = F.Id,
|
||||
Rolename = F.Rolename,
|
||||
Permission = F.Permission,
|
||||
DeviceLicense = F.DeviceLicense,
|
||||
|
||||
}).ToList();
|
||||
}
|
||||
else
|
||||
{
|
||||
//机型有哪些功能
|
||||
var query = from mt in q.MachineTypes
|
||||
join df in q.MachineTypeFuns on mt.Id equals df.MachineTypeId into dfGroup
|
||||
|
||||
from df in dfGroup.DefaultIfEmpty()
|
||||
//机型功能和 角色联动
|
||||
join rfm in q.RoleFunMappings on df.Id equals rfm.DeviceFunId into rfmGroup
|
||||
|
||||
from rfm in rfmGroup.DefaultIfEmpty()
|
||||
join ri in q.Roleinfos on rfm.RoleId equals ri.Id into riGroup
|
||||
|
||||
from ri in riGroup.DefaultIfEmpty()
|
||||
where ri.Id == S.ID
|
||||
select new
|
||||
{
|
||||
MachineType = mt.Id, //机型
|
||||
MachineFun = df.FunctionName, //功能
|
||||
RoleName = ri.Rolename,
|
||||
Id = ri.Id,
|
||||
};
|
||||
returnInfo.isok = true;
|
||||
//var a = q.Roleinfos.SingleOrDefault(A => A.Id == S.ID);
|
||||
var a = query.FirstOrDefault();
|
||||
if (a != null)
|
||||
{
|
||||
//ReturnRole u = new ReturnRole();
|
||||
//u.Id = a.Id;
|
||||
//u.Rolename = a.Rolename;
|
||||
//u.Permission = a.Permission;
|
||||
returnInfo.response = a;
|
||||
}
|
||||
}
|
||||
//}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
returnInfo.isok = false;
|
||||
returnInfo.message = ex.Message;
|
||||
}
|
||||
return returnInfo;
|
||||
}
|
||||
|
||||
[HttpGet()]
|
||||
public object TTT( )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
/// <summary>
|
||||
/// 新增角色
|
||||
/// </summary>
|
||||
/// <param name="LLL"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost()]
|
||||
//[Authorize()]
|
||||
public ReturnInfo AddRole([FromBody] ReturnRole LLL)
|
||||
{
|
||||
ReturnInfo returnInfo = new ReturnInfo();
|
||||
try
|
||||
{
|
||||
|
||||
Roleinfo lll = new Roleinfo();
|
||||
|
||||
string Rolename = LLL.Rolename;
|
||||
|
||||
lll.Rolename = Rolename;
|
||||
|
||||
lll.IsDelete = false;
|
||||
lll.Permission = LLL.Permission;
|
||||
lll.DeviceLicense = LLL.DeviceLicense;
|
||||
|
||||
lll.CreateTime = DateTime.Now;
|
||||
lll.UpdateTime = DateTime.Now;
|
||||
|
||||
//using (var q = new IotServerContext())
|
||||
//{
|
||||
var Q = q.Roleinfos.Where(A => A.Rolename.Equals(Rolename));
|
||||
if (Q.Count() > 0)
|
||||
{
|
||||
returnInfo.isok = false;
|
||||
returnInfo.message = "此角色名已经存在";
|
||||
}
|
||||
else
|
||||
{
|
||||
q.Roleinfos.Add(lll);
|
||||
returnInfo.isok = true;
|
||||
}
|
||||
q.SaveChanges();
|
||||
//}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
returnInfo.isok = false;
|
||||
returnInfo.message = ex.Message;
|
||||
}
|
||||
return returnInfo;
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 返回角色信息
|
||||
/// </summary>
|
||||
public class ReturnRole
|
||||
{
|
||||
/// <summary>
|
||||
/// 主键
|
||||
/// </summary>
|
||||
public int Id { get; set; } = 0;
|
||||
|
||||
public string? Rolename { get; set; }
|
||||
|
||||
public string? Permission { get; set; }
|
||||
|
||||
public string? DeviceLicense { get; set; }
|
||||
}
|
||||
|
||||
}
|
||||
121
BooliveMQTT_Auth/Controllers/TcpCloseDataController.cs
Normal file
121
BooliveMQTT_Auth/Controllers/TcpCloseDataController.cs
Normal file
@@ -0,0 +1,121 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using CommonEntity;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using MySQLAccess.PGModels;
|
||||
|
||||
namespace IotManager.Controllers
|
||||
{
|
||||
[Route("api/[controller]/[action]")]
|
||||
[ApiController]
|
||||
public class TcpCloseDataController : ControllerBase
|
||||
{
|
||||
private readonly PostgresContext _context;
|
||||
|
||||
public TcpCloseDataController(PostgresContext context)
|
||||
{
|
||||
_context = context;
|
||||
}
|
||||
|
||||
// GET: api/TcpCloseData
|
||||
[Authorize()]
|
||||
[HttpGet]
|
||||
public async Task<ReturnInfo> GetTcpCloseData(int page_size, int page_index, string ip, int port)
|
||||
{
|
||||
ReturnInfo r = new ReturnInfo();
|
||||
try
|
||||
{
|
||||
r.isok = true;
|
||||
r.response = await _context.TcpCloseData.Where(A => A.WwwIp.Equals(ip) && A.WwwPort == port).Skip((page_index - 1) * page_size).Take(page_size).ToListAsync();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
r.isok = false;
|
||||
r.message = ex.Message;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
// GET: api/TcpCloseData/5
|
||||
[HttpGet("{id}")]
|
||||
public async Task<ActionResult<TcpCloseDatum>> GetTcpCloseDatum(long id)
|
||||
{
|
||||
var tcpCloseDatum = await _context.TcpCloseData.FindAsync(id);
|
||||
|
||||
if (tcpCloseDatum == null)
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
return tcpCloseDatum;
|
||||
}
|
||||
|
||||
// PUT: api/TcpCloseData/5
|
||||
// To protect from overposting attacks, see https://go.microsoft.com/fwlink/?linkid=2123754
|
||||
[HttpPut("{id}")]
|
||||
public async Task<IActionResult> PutTcpCloseDatum(long id, TcpCloseDatum tcpCloseDatum)
|
||||
{
|
||||
if (id != tcpCloseDatum.Id)
|
||||
{
|
||||
return BadRequest();
|
||||
}
|
||||
|
||||
_context.Entry(tcpCloseDatum).State = EntityState.Modified;
|
||||
|
||||
try
|
||||
{
|
||||
await _context.SaveChangesAsync();
|
||||
}
|
||||
catch (DbUpdateConcurrencyException)
|
||||
{
|
||||
if (!TcpCloseDatumExists(id))
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
else
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
return NoContent();
|
||||
}
|
||||
|
||||
// POST: api/TcpCloseData
|
||||
// To protect from overposting attacks, see https://go.microsoft.com/fwlink/?linkid=2123754
|
||||
[HttpPost]
|
||||
public async Task<ActionResult<TcpCloseDatum>> PostTcpCloseDatum(TcpCloseDatum tcpCloseDatum)
|
||||
{
|
||||
_context.TcpCloseData.Add(tcpCloseDatum);
|
||||
await _context.SaveChangesAsync();
|
||||
|
||||
return CreatedAtAction("GetTcpCloseDatum", new { id = tcpCloseDatum.Id }, tcpCloseDatum);
|
||||
}
|
||||
|
||||
// DELETE: api/TcpCloseData/5
|
||||
[HttpDelete("{id}")]
|
||||
public async Task<IActionResult> DeleteTcpCloseDatum(long id)
|
||||
{
|
||||
var tcpCloseDatum = await _context.TcpCloseData.FindAsync(id);
|
||||
if (tcpCloseDatum == null)
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
_context.TcpCloseData.Remove(tcpCloseDatum);
|
||||
await _context.SaveChangesAsync();
|
||||
|
||||
return NoContent();
|
||||
}
|
||||
|
||||
private bool TcpCloseDatumExists(long id)
|
||||
{
|
||||
return _context.TcpCloseData.Any(e => e.Id == id);
|
||||
}
|
||||
}
|
||||
}
|
||||
14
BooliveMQTT_Auth/Controllers/TcpController.cs
Normal file
14
BooliveMQTT_Auth/Controllers/TcpController.cs
Normal file
@@ -0,0 +1,14 @@
|
||||
using Common;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using RestSharp;
|
||||
|
||||
namespace IotManager.Controllers
|
||||
{
|
||||
[Route("api/[controller]/[action]")]
|
||||
[ApiController]
|
||||
public class TcpController : ControllerBase
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
344
BooliveMQTT_Auth/Controllers/UsersController.cs
Normal file
344
BooliveMQTT_Auth/Controllers/UsersController.cs
Normal file
@@ -0,0 +1,344 @@
|
||||
using CommonEntity;
|
||||
using IotManager.Common;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using MySQLAccess.PGModels;
|
||||
using ViewModels;
|
||||
|
||||
namespace IotManager.Controllers
|
||||
{
|
||||
[Route("api/[controller]/[action]")]
|
||||
[ApiController]
|
||||
public class UsersController : ControllerBase
|
||||
{
|
||||
public PostgresContext q { get; set; }
|
||||
public UsersController(PostgresContext dbcontext)
|
||||
{
|
||||
q = dbcontext;
|
||||
}
|
||||
public class DelData
|
||||
{
|
||||
public int Id { get; set; }
|
||||
}
|
||||
/// <summary>
|
||||
/// 删除用户
|
||||
/// </summary>
|
||||
/// <param name="LLL"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost()]
|
||||
[Authorize()]
|
||||
public ReturnInfo DelUser([FromBody] DelData LLL)
|
||||
{
|
||||
ReturnInfo returnInfo = new();
|
||||
if (LLL.Id == 2 || LLL.Id == 1)
|
||||
{
|
||||
returnInfo.isok = false;
|
||||
returnInfo.message = "超级管理员不可删除!";
|
||||
return returnInfo;
|
||||
}
|
||||
try
|
||||
{
|
||||
var FFF = q.Userinfos.FirstOrDefault(A => A.Id == LLL.Id);
|
||||
if (FFF != null)
|
||||
{
|
||||
FFF.IsDelete = true;
|
||||
q.Userinfos.Update(FFF);
|
||||
q.SaveChanges();
|
||||
returnInfo.isok = true;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
returnInfo.isok = false;
|
||||
returnInfo.message = ex.Message;
|
||||
}
|
||||
return returnInfo;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 修改用户
|
||||
/// </summary>
|
||||
/// <param name="LLL"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost()]
|
||||
[Authorize()]
|
||||
public ReturnInfo EditUser([FromBody] ReturnUser LLL)
|
||||
{
|
||||
ReturnInfo returnInfo = new ReturnInfo();
|
||||
|
||||
try
|
||||
{
|
||||
//using (var q = new IotServerContext())
|
||||
//{
|
||||
var lll = q.Userinfos.SingleOrDefault(A => A.Id == LLL.Id);
|
||||
if (lll != null)
|
||||
{
|
||||
|
||||
string username = LLL.Username;
|
||||
string? companyName = LLL.CompanyName;
|
||||
string mobile = LLL.Mobile;
|
||||
|
||||
lll.Permission = LLL.Permission;
|
||||
lll.RealName = LLL.Realname;
|
||||
lll.UserName = username;
|
||||
lll.CompanyName = companyName;
|
||||
lll.Mobile = mobile;
|
||||
lll.UpdateTime = DateTime.Now;
|
||||
lll.RoleId = LLL.RoleId;
|
||||
|
||||
string PPP = LLL.Password.Trim();
|
||||
if (!string.IsNullOrWhiteSpace(PPP))
|
||||
{
|
||||
lll.PassWord = JiaJieMi.HashPassword(PPP);
|
||||
lll.PswEncryption = JiaJieMi.EncryptString(PPP);
|
||||
}
|
||||
|
||||
q.Userinfos.Update(lll);
|
||||
q.SaveChanges();
|
||||
returnInfo.isok = true;
|
||||
}
|
||||
//}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
returnInfo.isok = false;
|
||||
returnInfo.message = ex.Message;
|
||||
}
|
||||
return returnInfo;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 重置密码
|
||||
/// </summary>
|
||||
/// <param name="LLL"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost()]
|
||||
[Authorize()]
|
||||
public ReturnInfo ModifyPassWord([FromBody] PWD_Reset LLL)
|
||||
{
|
||||
ReturnInfo returnInfo = new ReturnInfo();
|
||||
try
|
||||
{
|
||||
//using (var q = new IotServerContext())
|
||||
//{
|
||||
var QQQ = q.Userinfos.SingleOrDefault(A => A.Id == LLL.Id);
|
||||
if (QQQ != null)
|
||||
{
|
||||
QQQ.PassWord = JiaJieMi.HashPassword(LLL.PlaintextPwd);
|
||||
QQQ.PswEncryption = JiaJieMi.EncryptString(LLL.PlaintextPwd);
|
||||
q.Userinfos.Update(QQQ);
|
||||
q.SaveChanges();
|
||||
returnInfo.isok = true;
|
||||
}
|
||||
//}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
returnInfo.isok = false;
|
||||
returnInfo.message = ex.Message;
|
||||
}
|
||||
return returnInfo;
|
||||
}
|
||||
/// <summary>
|
||||
/// 新增密码为123456
|
||||
/// </summary>
|
||||
/// <param name="LLL"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost()]
|
||||
[Authorize()]
|
||||
public ReturnInfo ResetPassWord([FromBody] PWD_Reset LLL)
|
||||
{
|
||||
ReturnInfo returnInfo = new ReturnInfo();
|
||||
try
|
||||
{
|
||||
//using (var q = new IotServerContext())
|
||||
//{
|
||||
var Q = q.Userinfos.SingleOrDefault(A => A.Id == LLL.Id);
|
||||
if (Q != null)
|
||||
{
|
||||
Q.PassWord = JiaJieMi.HashPassword("123456");
|
||||
Q.PswEncryption = JiaJieMi.EncryptString("123456");
|
||||
q.Userinfos.Update(Q);
|
||||
q.SaveChanges();
|
||||
returnInfo.isok = true;
|
||||
}
|
||||
//}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
returnInfo.isok = false;
|
||||
returnInfo.message = ex.Message;
|
||||
}
|
||||
return returnInfo;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取用户信息
|
||||
/// </summary>
|
||||
/// <param name="S"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost()]
|
||||
[Authorize()]
|
||||
public ReturnInfo GetUserInfo([FromBody] QueryAll_Or_Single S)
|
||||
{
|
||||
ReturnInfo returnInfo = new ReturnInfo();
|
||||
|
||||
try
|
||||
{
|
||||
//using (var q = new IotServerContext())
|
||||
//{
|
||||
if (S.IsAll)
|
||||
{
|
||||
returnInfo.isok = true;
|
||||
returnInfo.response = q.Userinfos.Where(A => A.IsDelete == false).Select(F => new ReturnUser
|
||||
{
|
||||
Id = F.Id,
|
||||
Username = F.UserName,
|
||||
Realname = F.RealName,
|
||||
CompanyName = F.CompanyName,
|
||||
Mobile = F.Mobile,
|
||||
Permission = F.Permission,
|
||||
RoleId = F.RoleId
|
||||
}).ToList();
|
||||
}
|
||||
else
|
||||
{
|
||||
returnInfo.isok = true;
|
||||
var a = q.Userinfos.SingleOrDefault(A => A.Id == S.ID);
|
||||
if (a != null)
|
||||
{
|
||||
ReturnUser u = new ReturnUser();
|
||||
u.Id = a.Id;
|
||||
u.Username = a.UserName;
|
||||
u.Realname = a.RealName;
|
||||
u.CompanyName = a.CompanyName;
|
||||
u.Mobile = a.Mobile;
|
||||
u.Permission = a.Permission;
|
||||
u.RoleId = a.RoleId;
|
||||
returnInfo.response = u;
|
||||
}
|
||||
}
|
||||
//}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
returnInfo.isok = false;
|
||||
returnInfo.message = ex.Message;
|
||||
}
|
||||
return returnInfo;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 新增用户
|
||||
/// </summary>
|
||||
/// <param name="LLL"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost()]
|
||||
//[Authorize()]
|
||||
public ReturnInfo AddUser([FromBody] ReturnUser LLL)
|
||||
{
|
||||
ReturnInfo returnInfo = new ReturnInfo();
|
||||
try
|
||||
{
|
||||
|
||||
Userinfo lll = new Userinfo();
|
||||
|
||||
string username = LLL.Username;
|
||||
string mobile = LLL.Mobile;
|
||||
|
||||
lll.UserName = username;
|
||||
lll.RealName = LLL.Realname;
|
||||
lll.CompanyName = LLL.CompanyName;
|
||||
lll.Mobile = mobile;
|
||||
lll.IsDelete = false;
|
||||
lll.Permission = LLL.Permission;
|
||||
lll.RoleId = LLL.RoleId;
|
||||
|
||||
lll.CreateTime = DateTime.Now;
|
||||
lll.UpdateTime = DateTime.Now;
|
||||
|
||||
//using (var q = new IotServerContext())
|
||||
//{
|
||||
var Q = q.Userinfos.Where(A => A.UserName.Equals(username));
|
||||
if (Q.Count() > 0)
|
||||
{
|
||||
returnInfo.isok = false;
|
||||
returnInfo.message = "此用户名已经存在";
|
||||
}
|
||||
else
|
||||
{
|
||||
//lll.Password = Tools.HashPassword("123456");
|
||||
//lll.PswEncryption = Tools.EncryptString("123456");
|
||||
|
||||
lll.PassWord = JiaJieMi.HashPassword(LLL.Password.Trim());
|
||||
lll.PswEncryption = JiaJieMi.EncryptString(LLL.Password.Trim());
|
||||
q.Userinfos.Add(lll);
|
||||
returnInfo.isok = true;
|
||||
}
|
||||
q.SaveChanges();
|
||||
//}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
returnInfo.isok = false;
|
||||
returnInfo.message = ex.Message;
|
||||
}
|
||||
return returnInfo;
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 返回用户信息
|
||||
/// </summary>
|
||||
public class ReturnUser
|
||||
{
|
||||
/// <summary>
|
||||
/// 主键
|
||||
/// </summary>
|
||||
public int Id { get; set; } = 0;
|
||||
|
||||
|
||||
public string? Permission { get; set; }
|
||||
/// <summary>
|
||||
/// 用户名(登录名)
|
||||
/// </summary>
|
||||
public string? Username { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 真实姓名
|
||||
/// </summary>
|
||||
public string? Realname { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 所属公司ID
|
||||
/// </summary>
|
||||
public string? CompanyName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 密码
|
||||
/// </summary>
|
||||
public string Password { get; set; } = "";
|
||||
|
||||
/// <summary>
|
||||
/// 密码加密处理
|
||||
/// </summary>
|
||||
public string PswEncryption { get; set; } = "";
|
||||
|
||||
/// <summary>
|
||||
/// 电话号码
|
||||
/// </summary>
|
||||
public string? Mobile { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 角色ID
|
||||
/// </summary>
|
||||
public int? RoleId { get; set; }
|
||||
|
||||
}
|
||||
public class PWD_Reset
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public string PlaintextPwd { get; set; }
|
||||
}
|
||||
|
||||
}
|
||||
160
BooliveMQTT_Auth/Controllers/ValuesController.cs
Normal file
160
BooliveMQTT_Auth/Controllers/ValuesController.cs
Normal file
@@ -0,0 +1,160 @@
|
||||
using System.Data;
|
||||
using System.IdentityModel.Tokens.Jwt;
|
||||
using System.Security.Claims;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using IotManager.Common;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.IdentityModel.Tokens;
|
||||
using NLog;
|
||||
using NPOI.HSSF.UserModel;
|
||||
using NPOI.SS.UserModel;
|
||||
using NPOI.XSSF.UserModel;
|
||||
using IotManager.private_key;
|
||||
using ViewModels;
|
||||
using ViewModels.Data;
|
||||
using CommonEntity;
|
||||
using MySQLAccess.PGModels;
|
||||
|
||||
namespace IotManager.Controllers
|
||||
{
|
||||
[Route("api/[controller]/[action]")]
|
||||
[ApiController]
|
||||
public class ValuesController : ControllerBase
|
||||
{
|
||||
|
||||
private readonly Logger _logger = LogManager.GetCurrentClassLogger();
|
||||
public IConfiguration? configuration { get; set; }
|
||||
public ValuesController(IConfiguration _configuration)
|
||||
{
|
||||
configuration = _configuration;
|
||||
}
|
||||
public string GetId(string device_name,string uuid)
|
||||
{
|
||||
string data = string.Format("boolive_{0}_{1}", device_name, uuid);
|
||||
// 密钥,用于生成MAC
|
||||
string key = "secretKey#&!";
|
||||
// 计算MAC
|
||||
byte[] mac = Base64.ComputeHMACSHA256Short(data, key);
|
||||
string str = Convert.ToBase64String(mac);
|
||||
return str;
|
||||
}
|
||||
|
||||
[HttpGet()]
|
||||
public ReturnInfo GetAllInfo([FromBody] QueryData data)
|
||||
{
|
||||
|
||||
ReturnInfo r = new ReturnInfo();
|
||||
try
|
||||
{
|
||||
using var context = new PostgresContext();
|
||||
var q = from dev in context.Deviceinfos
|
||||
join emqx in context.EmqxLogininfos
|
||||
on dev.Uuid equals emqx.DeviceUuid
|
||||
into devinfo
|
||||
from info in devinfo.DefaultIfEmpty()
|
||||
select new { dev.ClientId, dev.ProductId, dev.DeviceName, dev.SecretKey, info.UserName, info.PassWord };
|
||||
|
||||
var p = q.ToList();
|
||||
r.isok = true;
|
||||
r.response = p;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
r.isok = false;
|
||||
r.message = ex.Message;
|
||||
}
|
||||
return r;
|
||||
|
||||
}
|
||||
|
||||
[HttpPost()]
|
||||
public ReturnInfo AddOrUpdateDeviceInfo([FromBody] BooliveDevice LLL)
|
||||
{
|
||||
ReturnInfo returnInfo = new ReturnInfo();
|
||||
|
||||
try
|
||||
{
|
||||
using var D = new PostgresContext();
|
||||
if (LLL.Id != 0)
|
||||
{
|
||||
var Q = D.Deviceinfos.SingleOrDefault(A => A.ClientId == LLL.Id);
|
||||
Q.DeviceName = LLL.DeviceName;
|
||||
Q.SecretKey = LLL.DeviceSecret;
|
||||
var DT = DateTime.Now;
|
||||
Q.UpdateTime = DT;
|
||||
Q.UpdateTimeUnix = Tools.ToUnixTimestampBySeconds(DT);
|
||||
}
|
||||
else
|
||||
{
|
||||
D.Database.BeginTransaction();
|
||||
var DT = DateTime.Now;
|
||||
var LT = Tools.ToUnixTimestampBySeconds(DT);
|
||||
var LLL1 = new Deviceinfo();
|
||||
|
||||
var uuid = System.Guid.NewGuid().ToString("N");
|
||||
LLL1.Uuid = uuid;
|
||||
LLL1.CreateTime = DT;
|
||||
LLL1.UpdateTime = DT;
|
||||
|
||||
LLL1.CreateTimeUnix = LT;
|
||||
LLL1.UpdateTimeUnix = LT;
|
||||
|
||||
D.Deviceinfos.Add(LLL1);
|
||||
|
||||
EmqxLogininfo l = new EmqxLogininfo();
|
||||
l.DeviceUuid = uuid;
|
||||
l.UserName = LLL.DeviceName;
|
||||
l.PassWord = GetId(l.UserName,uuid);
|
||||
l.UpdateTime = DT;
|
||||
l.UpdateTimeUnix = LT;
|
||||
l.CreateTime = DT;
|
||||
l.CreateTimeUnix = LT;
|
||||
|
||||
D.EmqxLogininfos.Add(l);
|
||||
|
||||
|
||||
D.SaveChanges();
|
||||
D.Database.CommitTransaction();
|
||||
}
|
||||
returnInfo.isok = true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
returnInfo.isok = false;
|
||||
returnInfo.message = ex.Message;
|
||||
}
|
||||
return returnInfo;
|
||||
}
|
||||
|
||||
|
||||
[HttpDelete()]
|
||||
public ReturnInfo DeleteDeviceInfo([FromBody] BooliveDevice LLL)
|
||||
{
|
||||
ReturnInfo r = new ReturnInfo();
|
||||
try
|
||||
{
|
||||
using var Q = new PostgresContext();
|
||||
|
||||
Q.Database.BeginTransaction();
|
||||
var a = Q.Deviceinfos.SingleOrDefault(A => A.ClientId == LLL.Id);
|
||||
Q.Deviceinfos.Remove(a);
|
||||
|
||||
var b = Q.EmqxLogininfos.SingleOrDefault(A => A.DeviceUuid.Equals(a.Uuid));
|
||||
Q.EmqxLogininfos.Remove(b);
|
||||
|
||||
Q.SaveChanges();
|
||||
|
||||
Q.Database.CommitTransaction();
|
||||
r.isok = true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
r.isok = false;
|
||||
r.message = ex.Message;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
}
|
||||
}
|
||||
33
BooliveMQTT_Auth/Controllers/WeatherForecastController.cs
Normal file
33
BooliveMQTT_Auth/Controllers/WeatherForecastController.cs
Normal file
@@ -0,0 +1,33 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace IotManager.Controllers
|
||||
{
|
||||
[ApiController]
|
||||
[Route("[controller]")]
|
||||
public class WeatherForecastController : ControllerBase
|
||||
{
|
||||
private static readonly string[] Summaries = new[]
|
||||
{
|
||||
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
|
||||
};
|
||||
|
||||
private readonly ILogger<WeatherForecastController> _logger;
|
||||
|
||||
public WeatherForecastController(ILogger<WeatherForecastController> logger)
|
||||
{
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public IEnumerable<WeatherForecast> Get()
|
||||
{
|
||||
return Enumerable.Range(1, 5).Select(index => new WeatherForecast
|
||||
{
|
||||
Date = DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
|
||||
TemperatureC = Random.Shared.Next(-20, 55),
|
||||
Summary = Summaries[Random.Shared.Next(Summaries.Length)]
|
||||
})
|
||||
.ToArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
56
BooliveMQTT_Auth/IotManager.csproj
Normal file
56
BooliveMQTT_Auth/IotManager.csproj
Normal file
@@ -0,0 +1,56 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Confluent.Kafka" Version="2.12.0" />
|
||||
<PackageReference Include="IronPython" Version="3.4.2" />
|
||||
<PackageReference Include="IronPython.StdLib" Version="3.4.2" />
|
||||
<PackageReference Include="jose-jwt" Version="5.2.0" />
|
||||
<PackageReference Include="LiteDB" Version="5.0.21" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.16" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="8.0.11">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.Orleans.Client" Version="8.2.0" />
|
||||
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="8.0.7" />
|
||||
<PackageReference Include="MongoDB.Driver.Core" Version="2.30.0" />
|
||||
<PackageReference Include="MQTTnet" Version="5.0.1.1416" />
|
||||
<PackageReference Include="MQTTnet.AspNetCore" Version="5.0.1.1416" />
|
||||
<PackageReference Include="MQTTnet.Extensions.ManagedClient" Version="4.3.7.1207" />
|
||||
<PackageReference Include="NLog" Version="6.0.6" />
|
||||
<PackageReference Include="NLog.Schema" Version="6.0.6" />
|
||||
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="8.0.11" />
|
||||
<PackageReference Include="NPOI" Version="2.7.3" />
|
||||
<PackageReference Include="Proto.Actor" Version="1.7.0" />
|
||||
<PackageReference Include="Quartz" Version="3.15.0" />
|
||||
<PackageReference Include="Quartz.AspNetCore" Version="3.15.0" />
|
||||
<PackageReference Include="RabbitMQ.Client" Version="7.2.0" />
|
||||
<PackageReference Include="RestSharp" Version="113.0.0" />
|
||||
<PackageReference Include="Sqids" Version="3.1.0" />
|
||||
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="8.9.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\CommonEntity\CommonEntity.csproj" />
|
||||
<ProjectReference Include="..\Common\Common.csproj" />
|
||||
<ProjectReference Include="..\IOT_JieKou\IOT_JieKou.csproj" />
|
||||
<ProjectReference Include="..\MySQLAccess\MySQLAccess.csproj" />
|
||||
<ProjectReference Include="..\ViewModels\ViewModels.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Update="script\CommonData.py">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="script\webapi.py">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
5316
BooliveMQTT_Auth/NLog.xsd
Normal file
5316
BooliveMQTT_Auth/NLog.xsd
Normal file
File diff suppressed because it is too large
Load Diff
31
BooliveMQTT_Auth/Para.yaml
Normal file
31
BooliveMQTT_Auth/Para.yaml
Normal file
@@ -0,0 +1,31 @@
|
||||
# HELP device_id Unique identifier of the monitored device
|
||||
# TYPE device_id gauge
|
||||
device_id {1}
|
||||
|
||||
# HELP device_status Operational status (0=offline, 1=normal, 2=warning, 3=fault)
|
||||
# TYPE device_status gauge
|
||||
device_status {2}
|
||||
|
||||
# HELP realtime_value Real-time operational value (unit: custom)
|
||||
# TYPE realtime_value gauge
|
||||
realtime_value {3}
|
||||
|
||||
# HELP environment_value Environmental parameter value
|
||||
# TYPE environment_value gauge
|
||||
environment_value {4}
|
||||
|
||||
# HELP mcu_temperature MCU temperature in Celsius
|
||||
# TYPE mcu_temperature gauge
|
||||
mcu_temperature {5}
|
||||
|
||||
# HELP sensor_temperature Sensor temperature in Celsius
|
||||
# TYPE sensor_temperature gauge
|
||||
sensor_temperature {6}
|
||||
|
||||
# HELP sensor_humidity Sensor humidity in percentage
|
||||
# TYPE sensor_humidity gauge
|
||||
sensor_humidity {7}
|
||||
|
||||
# HELP adc_raw_value Raw ADC reading value
|
||||
# TYPE adc_raw_value gauge
|
||||
adc_raw_value {8}
|
||||
240
BooliveMQTT_Auth/Program.cs
Normal file
240
BooliveMQTT_Auth/Program.cs
Normal file
@@ -0,0 +1,240 @@
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using BLW_Log.Models;
|
||||
using Common;
|
||||
using CommonEntity;
|
||||
using IotManager.Common;
|
||||
using IotManager.job;
|
||||
using IotManager.private_key;
|
||||
using IotManager.services;
|
||||
using MathNet.Numerics.Interpolation;
|
||||
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.IdentityModel.Tokens;
|
||||
using MySQLAccess.PGModels;
|
||||
using Quartz;
|
||||
using RestSharp;
|
||||
using ViewModels;
|
||||
|
||||
namespace IotManager
|
||||
{
|
||||
public class DomainSettings
|
||||
{
|
||||
public string[] Ok { get; set; }
|
||||
}
|
||||
|
||||
public class Program
|
||||
{
|
||||
|
||||
static async Task TTT()
|
||||
{
|
||||
try
|
||||
{
|
||||
using PostgresContext dbcontext = new PostgresContext();
|
||||
var userdata = await dbcontext.Deviceinfos.Select(A => new DeviceCacheInfo { ClientId = A.ClientId, SecretKey = A.SecretKey }).ToListAsync();
|
||||
|
||||
RestClient client1 = new RestClient("http://iot-manage.uts-data.com:5001");
|
||||
string ti = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff");
|
||||
var request1 = new RestRequest("/api/Values/SetDeviceInfoChache", Method.Post);
|
||||
request1.AddJsonBody(userdata);
|
||||
var re = await client1.ExecuteAsync(request1);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
|
||||
}
|
||||
await Task.CompletedTask;
|
||||
}
|
||||
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
|
||||
//var iv = new byte[] { 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff };
|
||||
//byte[] key = new byte[] { 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c };
|
||||
|
||||
//AFC1E534C82933EFA5805F21AFA494DE06534D055D432953299A46A4983614C60B5FA21C19843D
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
|
||||
var domainSettings = builder.Configuration.GetSection("AllowDomain").Get<DomainSettings>();
|
||||
builder.Services.AddSingleton<MyMemoryCache>();
|
||||
CSRedisCacheHelper.Configuration = builder.Configuration;
|
||||
// ע<><D7A2>MQTT<54>ͻ<EFBFBD><CDBB>˷<EFBFBD><CBB7><EFBFBD>
|
||||
// <20><><EFBFBD><EFBFBD>ʱ<EFBFBD>Զ<EFBFBD><D4B6><EFBFBD><EFBFBD><EFBFBD>
|
||||
builder.Services.AddMemoryCache();
|
||||
builder.Services.AddHostedService<MqttClientHostedService>();
|
||||
builder.Services.AddHostedService<Mqtt2RabbitMQ>();
|
||||
//builder.Services.AddHostedService<MyTimer>();
|
||||
|
||||
//builder.Host.UseOrleansClient(ooo=>
|
||||
//{
|
||||
// ooo.UseLocalhostClustering();
|
||||
//});
|
||||
builder.Services.AddControllers();
|
||||
|
||||
//builder.Services.AddDbContext<IotServerContext>(options =>
|
||||
//{
|
||||
// options.UseNpgsql(builder.Configuration.GetConnectionString("PGSqlStr"));
|
||||
//});
|
||||
|
||||
builder.Services.AddDbContextFactory<PostgresContext>(options =>
|
||||
options.UseNpgsql(builder.Configuration.GetConnectionString("PGSqlStr")));
|
||||
|
||||
//builder.Services.AddScoped<IotServerContext>();
|
||||
builder.Services.AddCors(options =>
|
||||
{
|
||||
options.AddPolicy(name: "Vue3",
|
||||
policy =>
|
||||
{
|
||||
//policy.WithOrigins(domainSettings.Ok)
|
||||
policy
|
||||
.AllowAnyOrigin()
|
||||
.AllowAnyHeader()
|
||||
.AllowAnyMethod();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
builder.Services.AddAuthorization();
|
||||
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
|
||||
.AddJwtBearer(option =>
|
||||
{
|
||||
string DefaultKey = "~7#UZ~:-G6HDC7'!1uwq+f@9,zaJ4DH4JdM#PYyc9HxFT.^M7M}i40qM~?^Qt;mF98;21+Zn'67>>04=GOj2]P:-1p;G@ln03^h~19A]gB1308e57#&MtpM4n53UF1N}";
|
||||
var sec = Encoding.UTF8.GetBytes(builder.Configuration["JWT:SecretKey"] ?? DefaultKey);
|
||||
|
||||
|
||||
|
||||
option.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters()
|
||||
{
|
||||
ValidateIssuer = true,
|
||||
ValidateAudience = true,
|
||||
ValidateLifetime = true,
|
||||
|
||||
ValidateIssuerSigningKey = true,
|
||||
ValidIssuer = builder.Configuration["JwT:Issuer"],
|
||||
ValidAudience = builder.Configuration["JwT:Audience"],
|
||||
IssuerSigningKey = new SymmetricSecurityKey(sec)
|
||||
};
|
||||
|
||||
option.Events = new JwtBearerEvents
|
||||
{
|
||||
OnMessageReceived = context =>
|
||||
{
|
||||
var token = context.Request.Headers["token"].FirstOrDefault();
|
||||
if (string.IsNullOrEmpty(token))
|
||||
{
|
||||
// <20><><EFBFBD><EFBFBD>û<EFBFBD><C3BB><EFBFBD>ҵ<EFBFBD> token ͷ<><CDB7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Authorization ͷ<><CDB7>
|
||||
token = context.Request.Headers["Authorization"].FirstOrDefault()?.Split(" ").Last();
|
||||
}
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD>ҵ<EFBFBD><D2B5><EFBFBD> token<65><6E><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>õ<EFBFBD> HttpContext <20><>
|
||||
if (!string.IsNullOrEmpty(token))
|
||||
{
|
||||
context.Token = token;
|
||||
}
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
builder.Services.AddQuartz(q =>
|
||||
{
|
||||
//var jobKey1 = new JobKey("ExcelGenerateJob");
|
||||
//q.AddJob<MyExcel>(opts => opts.WithIdentity(jobKey1));
|
||||
|
||||
//q.AddTrigger(opts => opts
|
||||
// .ForJob(jobKey1)
|
||||
// .WithIdentity("ExcelGenerateJob-trigger")
|
||||
// .StartAt(DateBuilder.TodayAt(h, m, s))
|
||||
// .WithCalendarIntervalSchedule(x => x
|
||||
// .WithIntervalInDays(1)
|
||||
// .InTimeZone(TimeZoneInfo.Local))
|
||||
//);
|
||||
//q.AddTrigger(opts => opts
|
||||
// .ForJob(jobKey1)
|
||||
// .WithIdentity("ExcelGenerateJob-trigger")
|
||||
// .WithCronSchedule("0 0 17 * * ?", (schedule) =>
|
||||
// {
|
||||
// schedule.WithMisfireHandlingInstructionDoNothing().InTimeZone(TimeZoneInfo.Local);
|
||||
// }) // ÿ<><C3BF>17:00
|
||||
//);
|
||||
|
||||
|
||||
///<2F><><EFBFBD>Ļ<EFBFBD><C4BB>Ǽٵ<C7BC>
|
||||
var jobKey2 = new JobKey("ShuJuTongBu");
|
||||
q.AddJob<DataAsync>(opts => opts.WithIdentity(jobKey2));
|
||||
q.AddTrigger(opts => opts
|
||||
.ForJob(jobKey2)
|
||||
.WithIdentity("ShuJuTongBuScan-trigger")
|
||||
.WithCalendarIntervalSchedule(x =>
|
||||
{
|
||||
x.WithIntervalInMinutes(30).Build();
|
||||
//x.WithIntervalInSeconds(2).Build();
|
||||
})
|
||||
);
|
||||
|
||||
//<2F><><EFBFBD>Ļ<EFBFBD><C4BB>Ǽٵ<C7BC>
|
||||
|
||||
|
||||
//var jobKey3 = new JobKey("DeleteFile");
|
||||
//q.AddJob<ExcelScan>(opts => opts.WithIdentity(jobKey3));
|
||||
//q.AddTrigger(opts => opts
|
||||
// .ForJob(jobKey3)
|
||||
// .WithIdentity("DeleteFile-trigger")
|
||||
// .WithCronSchedule("0 0 1 * * ?", (schedule) =>
|
||||
// {
|
||||
// schedule.WithMisfireHandlingInstructionDoNothing().InTimeZone(TimeZoneInfo.Local);
|
||||
// }) // ÿ<><C3BF>17:00
|
||||
//);
|
||||
|
||||
});
|
||||
|
||||
builder.Services.AddQuartzHostedService(q => q.WaitForJobsToComplete = true);
|
||||
var app = builder.Build();
|
||||
app.UseHttpsRedirection();
|
||||
|
||||
app.UseCors("Vue3");
|
||||
app.UseRouting();
|
||||
app.UseAuthentication(); // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֤<EFBFBD>м<EFBFBD><D0BC><EFBFBD>
|
||||
app.UseAuthorization(); // ʹ<><CAB9><EFBFBD><EFBFBD>Ȩ<EFBFBD>м<EFBFBD><D0BC><EFBFBD>
|
||||
|
||||
|
||||
app.MapControllers();
|
||||
|
||||
StaticData.GetWebAPIMethod();
|
||||
StaticData.GetWebAPIMethod1();
|
||||
|
||||
//TTT().Wait();
|
||||
|
||||
//HHH();
|
||||
//IronPython.Runtime.PythonList QQQ = StaticData.scope2.GetVariable("DeviceId");
|
||||
//var QQQC= QQQ.Select(A=>(int)A).ToList();
|
||||
//foreach (var item in QQQC)
|
||||
//{
|
||||
// int a = (int)item;
|
||||
//}
|
||||
//string QQQ1 = Newtonsoft.Json.JsonConvert.SerializeObject(QQQ);
|
||||
//var QQQ2 = Newtonsoft.Json.JsonConvert.DeserializeObject<List<string>>(QQQ1);
|
||||
app.Run();
|
||||
}
|
||||
|
||||
public static void HHH()
|
||||
{
|
||||
byte[] decryptedContent = new byte[] { 0x03, 0x00, 0x04, 0x00 };
|
||||
string HexData = Tools.ByteToString(decryptedContent);
|
||||
//ȼ<><C8BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ:03 00 04 00
|
||||
Console.WriteLine("ȼ<><C8BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ:" + HexData);
|
||||
byte ȼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>״̬ = decryptedContent[0];
|
||||
byte <EFBFBD><EFBFBD><EFBFBD><EFBFBD>״̬1 = decryptedContent[2];
|
||||
//0x04<30>DZ<EFBFBD><C7B1><EFBFBD>
|
||||
//0x03<30><33>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
if (decryptedContent.Length == 4)
|
||||
{
|
||||
if (<EFBFBD><EFBFBD><EFBFBD><EFBFBD>״̬1 == 0x04)
|
||||
{
|
||||
IronPython.Runtime.PythonList QQQ = StaticData.scope2.GetVariable("MobileNo");
|
||||
IronPython.Runtime.PythonList III = StaticData.scope2.GetVariable("DeviceId");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
41
BooliveMQTT_Auth/Properties/launchSettings.json
Normal file
41
BooliveMQTT_Auth/Properties/launchSettings.json
Normal file
@@ -0,0 +1,41 @@
|
||||
{
|
||||
"$schema": "http://json.schemastore.org/launchsettings.json",
|
||||
"iisSettings": {
|
||||
"windowsAuthentication": false,
|
||||
"anonymousAuthentication": true,
|
||||
"iisExpress": {
|
||||
"applicationUrl": "http://localhost:59038",
|
||||
"sslPort": 44363
|
||||
}
|
||||
},
|
||||
"profiles": {
|
||||
"http": {
|
||||
"commandName": "Project",
|
||||
"dotnetRunMessages": true,
|
||||
"launchBrowser": true,
|
||||
"launchUrl": "weatherforecast",
|
||||
"applicationUrl": "http://localhost:5068",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
},
|
||||
"https": {
|
||||
"commandName": "Project",
|
||||
"dotnetRunMessages": true,
|
||||
"launchBrowser": true,
|
||||
"launchUrl": "weatherforecast",
|
||||
"applicationUrl": "https://localhost:7054;http://localhost:5068",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
},
|
||||
"IIS Express": {
|
||||
"commandName": "IISExpress",
|
||||
"launchBrowser": true,
|
||||
"launchUrl": "weatherforecast",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
13
BooliveMQTT_Auth/WeatherForecast.cs
Normal file
13
BooliveMQTT_Auth/WeatherForecast.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
namespace IotManager
|
||||
{
|
||||
public class WeatherForecast
|
||||
{
|
||||
public DateOnly Date { get; set; }
|
||||
|
||||
public int TemperatureC { get; set; }
|
||||
|
||||
public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
|
||||
|
||||
public string? Summary { get; set; }
|
||||
}
|
||||
}
|
||||
8
BooliveMQTT_Auth/appsettings.Development.json
Normal file
8
BooliveMQTT_Auth/appsettings.Development.json
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Information",
|
||||
"Microsoft.AspNetCore": "Warning"
|
||||
}
|
||||
}
|
||||
}
|
||||
35
BooliveMQTT_Auth/appsettings.json
Normal file
35
BooliveMQTT_Auth/appsettings.json
Normal file
@@ -0,0 +1,35 @@
|
||||
{
|
||||
"JwT": {
|
||||
"SecretKey": "5J:%0@.v}CDyz5X5qAe6}QjU)B3Dta'V,.,mKiOY5&Q6N+oM7=?=eFWA.Ctr1q#&z&8J4XlR2l$c\"z-)Ln0]L12uoNq84bX;V5072)nd1tO*Er-*,&C4}_PXc6Ypaw",
|
||||
"Issuer": "宝来威用户管理系统",
|
||||
"Audience": "W*u93xxp*08DnW@%6}5Tjh6bE?;hW"
|
||||
},
|
||||
"MQTT": {
|
||||
"IP": "43.138.217.154",
|
||||
"Port": 9001,
|
||||
"UserName": "admin",
|
||||
"PassWord": "@8xq*BU3+3kuE:Oj"
|
||||
},
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Information",
|
||||
"Microsoft.AspNetCore": "Warning"
|
||||
}
|
||||
},
|
||||
"AllowedHosts": "*",
|
||||
"RabbitMQConfig": {
|
||||
"RabbitMQHost": "172.16.4.132",
|
||||
"RabbitMQPort": 5627,
|
||||
"RabbitMQUserName": "tian",
|
||||
"RabbitMQPWD": "123456"
|
||||
},
|
||||
"ConnectionStrings": {
|
||||
//"PGSqlStr": "Server=localhost;Database=postgres;user id=postgres;password=123456;port=5432;"
|
||||
"PGSqlStr": "Server=localhost;Database=postgres;user id=postgres;password=t3414T\"7wCU.&15]*QFu%_4CDhJI7g2b;port=5432;"
|
||||
},
|
||||
"redis_server_session": "127.0.0.1:6379",
|
||||
"get_redis_auth": "",
|
||||
"AllowDomain": {
|
||||
"Ok": [ "aa", "bbb" ]
|
||||
}
|
||||
}
|
||||
BIN
BooliveMQTT_Auth/build.log
Normal file
BIN
BooliveMQTT_Auth/build.log
Normal file
Binary file not shown.
40
BooliveMQTT_Auth/job/DataAsync.cs
Normal file
40
BooliveMQTT_Auth/job/DataAsync.cs
Normal file
@@ -0,0 +1,40 @@
|
||||
using CommonEntity;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using MySQLAccess.PGModels;
|
||||
using NLog;
|
||||
using Quartz;
|
||||
using RestSharp;
|
||||
|
||||
namespace IotManager.job
|
||||
{
|
||||
public class DataAsync : IJob
|
||||
{
|
||||
private readonly Logger _logger = LogManager.GetCurrentClassLogger();
|
||||
|
||||
public PostgresContext dbcontext { get; set; }
|
||||
public DataAsync(PostgresContext context)
|
||||
{
|
||||
this.dbcontext = context;
|
||||
}
|
||||
public async Task Execute(IJobExecutionContext context)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
//using PostgresContext dbcontext = new PostgresContext();
|
||||
var userdata = await dbcontext.Deviceinfos.Select(A => new DeviceCacheInfo { ClientId = A.ClientId, SecretKey = A.SecretKey }).ToListAsync();
|
||||
|
||||
RestClient client1 = new RestClient("http://iot-manage.uts-data.com:5001");
|
||||
string ti = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff");
|
||||
var request1 = new RestRequest("/api/Values/SetDeviceInfoChache", Method.Post);
|
||||
request1.AddJsonBody(userdata);
|
||||
var re = await client1.ExecuteAsync(request1);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Error("同步设备数据出错了:" + ex.Message);
|
||||
}
|
||||
await Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
}
|
||||
35
BooliveMQTT_Auth/nlog.config
Normal file
35
BooliveMQTT_Auth/nlog.config
Normal file
@@ -0,0 +1,35 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
|
||||
<!-- enable asp.net core layout renderers -->
|
||||
<targets>
|
||||
<!--项目日志保存文件路径说明fileName="${basedir}/保存目录,以年月日的格式创建/${shortdate}/${记录器名称}-${单级记录}-${shortdate}.txt"-->
|
||||
<target name="info_file" xsi:type="File"
|
||||
fileName="${basedir}/Logs/${shortdate}/info_${shortdate}.txt"
|
||||
layout="${longdate}|${level:uppercase=true}|${logger}|${message}|${exception:format=ToString} ${newline} ${stacktrace} ${newline}"
|
||||
archiveFileName="${basedir}/archives/info_${shortdate}-{#####}.txt"
|
||||
archiveAboveSize="102400"
|
||||
archiveNumbering="Sequence"
|
||||
concurrentWrites="true"
|
||||
keepFileOpen="false" />
|
||||
<target name="error_file" xsi:type="File"
|
||||
fileName="${basedir}/Logs/${shortdate}/error_${shortdate}.txt"
|
||||
layout="${longdate}|${level:uppercase=true}|${logger}|${message}|${exception:format=ToString} ${newline} ${stacktrace} ${newline}"
|
||||
archiveFileName="${basedir}/archives/error_${shortdate}-{#####}.txt"
|
||||
archiveAboveSize="102400"
|
||||
archiveNumbering="Sequence"
|
||||
concurrentWrites="true"
|
||||
keepFileOpen="false" />
|
||||
</targets>
|
||||
|
||||
<!--规则配置,final - 最终规则匹配后不处理任何规则-->
|
||||
<!--规则配置,final - 最终规则匹配后不处理任何规则-->
|
||||
<!--定义使用哪个target输出-->
|
||||
<rules>
|
||||
<!-- 优先级从高到低依次为:OFF、FATAL、ERROR、WARN、INFO、DEBUG、TRACE、 ALL -->
|
||||
<!-- 将所有日志输出到文件 -->
|
||||
<logger name="*" minlevel="FATAL" maxlevel="FATAL" writeTo="info_file" />
|
||||
<logger name="*" minlevel="ERROR" maxlevel="ERROR" writeTo="error_file" />
|
||||
</rules>
|
||||
</nlog>
|
||||
72
BooliveMQTT_Auth/private_key/KeyData.cs
Normal file
72
BooliveMQTT_Auth/private_key/KeyData.cs
Normal file
@@ -0,0 +1,72 @@
|
||||
using System.Security.Cryptography;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.Text;
|
||||
using Microsoft.IdentityModel.Tokens;
|
||||
|
||||
namespace IotManager.private_key
|
||||
{
|
||||
public class KeyData
|
||||
{
|
||||
public static readonly string PrivateKey = @"
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEpAIBAAKCAQEAxBDlyX+RJ2IcPLZ+YaVaxw6LHh469yeLDt4E2ers/DbjUo13
|
||||
3ZLRA/n5Hg7S4L92H/IChyBiQLu2lyFXavQLJsfgy984OWCShKFgV6huYsd3a65Y
|
||||
RyjC0mlh6xpsQb4lLrzNlxVLNT0XW6h/Awck5nB7GXzFddYu79CXS5HGK7jl3cIh
|
||||
+PC58akWincAZkAD+NkQJ6SyQiUnl6e9/WJ/uoITNfKcMzLrDEF3Bn4LhXJ0R9n0
|
||||
ErjluDKMs098za6jJqEgxovqA6b0ZgoGyhWb+79a8qu/bneKiF7SzUYrC6/nEAFX
|
||||
1Y8ESnb+gJnrEhT9sY/Y8RSM0li48opXuKluxQIDAQABAoIBADf9R1FqT246syuX
|
||||
RbHmwWyUt5+LLHWF4k0Fk8cTMke3+OSLJ46rrWqASOaPfyLVKgtnVdd2pPgtYq/3
|
||||
wnn1ZPXXIFe3z9t6u3yKhPOjUpp8sZqbd/QiLLhfhanYqs9/WCjnm6IoX4i9gF0Z
|
||||
WePod14jAtQ9cDn9RvwOyhW3dCrpqyHPZh/egNp2jMuAmQ3GhOoO3/Kqr9rUCglM
|
||||
UcCcAqi9UoJi7Y2iWWJJbAe18KNWF8HyldGj3yiy5WQcbJr8KBSAlb5Xr3axIrIV
|
||||
2SA8K6Lf6hQ/hYwN3k/TJ6N/q4XP3ICzKH344RLtxpTEUGitcIEU95P1A679AeaL
|
||||
oXFn3YUCgYEA5j7luDWOX/OFBS1C+vYwBvQ48IU+yERDZcXonylOI+o/HAwod67p
|
||||
qT7uQrCKx0zBBiGj+kbJ0GUS292VvHVTy/I8F7v9KhGg4sTNVpwubsnYKcHp2fyl
|
||||
QY+bEC5cx3QqV2oHWR5EXmYRKHi69agvhRLaPp3q5o9rrG6iQWPxeY8CgYEA2f9D
|
||||
K3BKR9BhKvTefkySVqlV6mcJbJAqRUhE4qf0ajGEwebW2eQNoW+dHuYuPrgBiE19
|
||||
6oclqiua06JBKY6wyLkxlfLAIhYLr4IftqX1WYAK/Ylt5atV22iAP6n8wg0yHaCX
|
||||
eib89xCxKJpG++lGq7QRv5LNZ3KyYbofUpl6YGsCgYEAyDjEDafNEtWyxGiyyYiT
|
||||
BUkVxtsoWIE8VuF+xAHoaMUIcnyEKGfb3AjUqvvZAy1U4d8ZOMicMXPjrX0I/GTP
|
||||
JRiWd1FL+2xvCyR3KC0TF9bA+rcdhCn3D4cxIiYfGneDZpbWowH2FF0P6LDsbDoA
|
||||
cOmPDkrHfg4UZVOkF9cwozMCgYBw1QduN1urGfcBJeb3Vii0REdc4OHm2COY4pQN
|
||||
AMOoJ2NAfXudIcXQVhXsBVXQTqs0Ym+W8UaUcqdbfPLfUKS97+TzaMb7nY+E0wQZ
|
||||
JIL+RSDrI7PHGUyCGO+whAp4Yh4baaCdsApk0rXvfxLYlmBmxPgewRwhvCMKJCzM
|
||||
MvY9awKBgQCJNuMvvGbEOc03PEW28okNqqDpv1KHHjcBgur54KWyA80j0faFcLKr
|
||||
zQ7/NyBJ60BepfDAi7P6Lj5AsFFaQ3VeY8yxMCJy8p5USXgw8+xkdqUM09XXvPzS
|
||||
zN3O6h/yas4xQLXkQqmPVEvv4VVGf16YBHzE3yv+sQCyxV313AGh9Q==
|
||||
-----END RSA PRIVATE KEY-----
|
||||
";
|
||||
|
||||
public static string PublicKey=@"-----BEGIN PUBLIC KEY-----
|
||||
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1EvziSvbI3eETULroiF7
|
||||
1wbYze4aO/yj5A2LN2seiRZNTLKelOnu4svMDwfpKizMfqYvXV9Z2NwUNdFsDd/F
|
||||
Wl2Xfdravzwz4z5u8agQ4Qwd8fVTnaFY5DQLv+6l3nAI01eUxaKHER/FpHSZ48o8
|
||||
CpH/VtzqeS/bA5+LTyMODdETI0fbfutFQS4xUIjoifN2oeggL5grhk39udyKfnwc
|
||||
0WG6086yb9uzr39oA39vKJNKTQqLcDiuLzooBBOq8YuKQ8qnuIt14SdxTrKmeHQ+
|
||||
azKlgPykzA/exTboORPAHpFk99tz6vuMdJBgrx93wt+ljoM8uKV2/J/6CKAOQZzY
|
||||
UQIDAQAB
|
||||
-----END PUBLIC KEY-----
|
||||
";
|
||||
private static SigningCredentials GetKey()
|
||||
{
|
||||
using var rsa = RSA.Create();
|
||||
rsa.ImportFromPem(PrivateKey);
|
||||
|
||||
var signingCredentials = new SigningCredentials(new RsaSecurityKey(rsa), SecurityAlgorithms.RsaSha256)
|
||||
{
|
||||
CryptoProviderFactory = new CryptoProviderFactory { CacheSignatureProviders = false }
|
||||
};
|
||||
return signingCredentials;
|
||||
}
|
||||
|
||||
private static RsaSecurityKey GetPKey()
|
||||
{
|
||||
// 使用 RSA 加载公钥
|
||||
using var rsa = RSA.Create();
|
||||
rsa.ImportFromPem(PrivateKey);
|
||||
|
||||
var securityKey = new RsaSecurityKey(rsa);
|
||||
return securityKey;
|
||||
}
|
||||
}
|
||||
}
|
||||
4
BooliveMQTT_Auth/script/CommonData.py
Normal file
4
BooliveMQTT_Auth/script/CommonData.py
Normal file
@@ -0,0 +1,4 @@
|
||||
Dev_MobileNo=["18283888296","15979026943","13509214696","17637651509"]
|
||||
MobileNo=["13983990118","18290234585","19232563315"]
|
||||
DeviceId=[49,50,62,57]
|
||||
Dev_DeviceId=[71]
|
||||
4
BooliveMQTT_Auth/script/webapi.py
Normal file
4
BooliveMQTT_Auth/script/webapi.py
Normal file
@@ -0,0 +1,4 @@
|
||||
公司管理=["其他","宝来威"]
|
||||
通讯方式=["MQTT","WebSocket","TCP/IP","UDP","Others"]
|
||||
机型类型=["其他","NT-318V"]
|
||||
权限管理=["主页","日志","用户管理","机型管理","字典管理","设备注册","TCPIP测试"]
|
||||
88
BooliveMQTT_Auth/services/KafkaConsume.cs
Normal file
88
BooliveMQTT_Auth/services/KafkaConsume.cs
Normal file
@@ -0,0 +1,88 @@
|
||||
using System.Text;
|
||||
using Common;
|
||||
using CommonEntity;
|
||||
using CommonEntity.RCUEntity;
|
||||
using CommonTools;
|
||||
using Confluent.Kafka;
|
||||
using IOT_JieKou;
|
||||
using NLog;
|
||||
using NPOI.OpenXml4Net.OPC;
|
||||
|
||||
namespace BLWLogServer.Services
|
||||
{
|
||||
public class KafkaConsume : BackgroundService
|
||||
{
|
||||
public IConfiguration Configuration { get; set; }
|
||||
public IClusterClient clusterClient { get; set; }
|
||||
public KafkaConsume(IConfiguration configuration,IClusterClient ccc)
|
||||
{
|
||||
Configuration = configuration;
|
||||
this.clusterClient = ccc;
|
||||
}
|
||||
|
||||
public static Logger logger = NLog.LogManager.GetCurrentClassLogger();
|
||||
|
||||
protected async override Task ExecuteAsync(CancellationToken stoppingToken)
|
||||
{
|
||||
await Task.Factory.StartNew(async () =>
|
||||
{
|
||||
var consumers = new List<Task>();
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
consumers.Add(Task.Run(() => StartConsumer(stoppingToken)));
|
||||
}
|
||||
await Task.WhenAll(consumers);
|
||||
}, TaskCreationOptions.LongRunning);
|
||||
}
|
||||
private async Task StartConsumer(CancellationToken stoppingToken)
|
||||
{
|
||||
string? ipport = Configuration["Kafka:EndPoint"];
|
||||
string? user = Configuration["Kafka:UserName"];
|
||||
string? pwd = Configuration["Kafka:PassWord"];
|
||||
string? mongodbconnectstr = Configuration["Mongodb:Connectstr"];
|
||||
while (!stoppingToken.IsCancellationRequested)
|
||||
{
|
||||
var config = new ConsumerConfig
|
||||
{
|
||||
GroupId = "blwlogserver-consumer-group",
|
||||
AutoOffsetReset = AutoOffsetReset.Earliest,
|
||||
BootstrapServers = ipport,
|
||||
SecurityProtocol = SecurityProtocol.SaslPlaintext,
|
||||
SaslMechanism = SaslMechanism.Plain,
|
||||
SaslUsername = user,
|
||||
SaslPassword = pwd
|
||||
};
|
||||
|
||||
var c = new ConsumerBuilder<string, byte[]>(config).Build();
|
||||
c.Subscribe(KafkaKey.New_RCU_Data_Topic);
|
||||
try
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
var cr = c.Consume(stoppingToken);
|
||||
try
|
||||
{
|
||||
var k = cr.Message.Key;
|
||||
var v = cr.Message.Value;
|
||||
if (k.Equals(KafkaKey.UDPckageAllUDPDataKey))
|
||||
{
|
||||
RCU_UDPData_With_String UDPPPP = MyMessagePacker.FastDeserialize<RCU_UDPData_With_String>(v);
|
||||
string? endpoint1= UDPPPP.endpoint;
|
||||
var cl1= clusterClient.GetGrain<IDataTran>(endpoint1,GrainPrefix.RCU_Grain_Prefix);
|
||||
await cl1.TongXin(UDPPPP);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
logger.Error("Ex出错:" + ex.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
logger.Error("未知错误" + ex.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
918
BooliveMQTT_Auth/services/Mqtt2RabbitMQ.cs
Normal file
918
BooliveMQTT_Auth/services/Mqtt2RabbitMQ.cs
Normal file
@@ -0,0 +1,918 @@
|
||||
|
||||
using Microsoft.EntityFrameworkCore.Metadata;
|
||||
using Newtonsoft.Json;
|
||||
using System.Text;
|
||||
using RabbitMQ.Client;
|
||||
using RabbitMQ.Client.Events;
|
||||
using Microsoft.VisualBasic;
|
||||
using IotManager.Controllers;
|
||||
using NLog;
|
||||
using ViewModels;
|
||||
using System.Threading.Channels;
|
||||
using MySQLAccess.PGModels;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using CommonEntity;
|
||||
using SixLabors.ImageSharp.PixelFormats;
|
||||
using System.Net.WebSockets;
|
||||
using SixLabors.ImageSharp.Processing.Processors.Quantization;
|
||||
using Microsoft.Scripting.Utils;
|
||||
using Newtonsoft.Json.Converters;
|
||||
using Microsoft.Extensions.Caching.Memory;
|
||||
using IotManager.Common;
|
||||
using Microsoft.AspNetCore.Routing.Tree;
|
||||
using Common;
|
||||
|
||||
namespace IotManager.services
|
||||
{
|
||||
public class Mqtt2RabbitMQ : BackgroundService
|
||||
{
|
||||
|
||||
private readonly Logger _logger = LogManager.GetCurrentClassLogger();
|
||||
private readonly IConfiguration Configuration;
|
||||
private readonly IDbContextFactory<PostgresContext> _factory;
|
||||
private IMemoryCache _cache { get; set; }
|
||||
|
||||
public Mqtt2RabbitMQ(IConfiguration config, IDbContextFactory<PostgresContext> db, IMemoryCache cache)
|
||||
{
|
||||
this.Configuration = config;
|
||||
this._factory = db;
|
||||
this._cache = cache;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//public static byte[] IV = new byte[] { 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff };
|
||||
//public static byte[] key = new byte[] { 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c };
|
||||
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
|
||||
{
|
||||
|
||||
while (!stoppingToken.IsCancellationRequested)
|
||||
{
|
||||
try
|
||||
{
|
||||
string? UserHost = Configuration["RabbitMQConfig:RabbitMQHost"];
|
||||
string? Port = Configuration["RabbitMQConfig:RabbitMQPort"];
|
||||
string? UserName = Configuration["RabbitMQConfig:RabbitMQUserName"];
|
||||
string? Password = Configuration["RabbitMQConfig:RabbitMQPWD"];
|
||||
ConnectionFactory factory = new ConnectionFactory();
|
||||
factory.HostName = UserHost;
|
||||
factory.UserName = UserName;
|
||||
factory.Password = Password;
|
||||
factory.VirtualHost = "/";
|
||||
using var connection = await factory.CreateConnectionAsync();
|
||||
|
||||
connection.ConnectionShutdownAsync -= Connection_ConnectionShutdownAsync;
|
||||
connection.ConnectionShutdownAsync += Connection_ConnectionShutdownAsync;
|
||||
using var channel0 = await connection.CreateChannelAsync();
|
||||
using var channel1 = await connection.CreateChannelAsync();
|
||||
using var channel2 = await connection.CreateChannelAsync();
|
||||
using var channel3 = await connection.CreateChannelAsync();
|
||||
using var channel4 = await connection.CreateChannelAsync();
|
||||
//await channel0.QueueDeclareAsync(queue: "mqtt_queue", durable: true, exclusive: false, autoDelete: false, arguments: null);
|
||||
//await channel1.QueueDeclareAsync(queue: "tcp_logdata_queue", durable: true, exclusive: false, autoDelete: false, arguments: null);
|
||||
//await channel2.QueueDeclareAsync(queue: "tcp_data_queue", durable: true, exclusive: false, autoDelete: false, arguments: null);
|
||||
//await channel3.QueueDeclareAsync(queue: "tcp_connect_logdata", durable: true, exclusive: false, autoDelete: false, arguments: null);
|
||||
//await channel4.QueueDeclareAsync(queue: "tcp_send_data", durable: true, exclusive: false, autoDelete: false, arguments: null);
|
||||
|
||||
var consumer0 = new AsyncEventingBasicConsumer(channel0);
|
||||
var consumer1 = new AsyncEventingBasicConsumer(channel1);
|
||||
var consumer2 = new AsyncEventingBasicConsumer(channel2);
|
||||
var consumer3 = new AsyncEventingBasicConsumer(channel3);
|
||||
var consumer4 = new AsyncEventingBasicConsumer(channel4);
|
||||
|
||||
consumer0.ReceivedAsync -= Consumer0_ReceivedAsync;
|
||||
consumer0.ReceivedAsync += Consumer0_ReceivedAsync;
|
||||
|
||||
consumer1.ReceivedAsync -= Consumer1_ReceivedAsync;
|
||||
consumer1.ReceivedAsync += Consumer1_ReceivedAsync;
|
||||
|
||||
consumer2.ReceivedAsync -= Consumer2_ReceivedAsync;
|
||||
consumer2.ReceivedAsync += Consumer2_ReceivedAsync;
|
||||
|
||||
|
||||
consumer3.ReceivedAsync -= Consumer3_ReceivedAsync;
|
||||
consumer3.ReceivedAsync += Consumer3_ReceivedAsync;
|
||||
|
||||
consumer4.ReceivedAsync -= Consumer4_ReceivedAsync;
|
||||
consumer4.ReceivedAsync += Consumer4_ReceivedAsync;
|
||||
|
||||
|
||||
var a = channel0.BasicConsumeAsync(queue: "mqtt_queue", autoAck: false, consumer: consumer0);
|
||||
var b = channel1.BasicConsumeAsync(queue: "tcp_logdata_queue", autoAck: false, consumer: consumer1);
|
||||
var c = channel2.BasicConsumeAsync(queue: "tcp_data_queue", autoAck: false, consumer: consumer2);
|
||||
var d = channel3.BasicConsumeAsync(queue: "tcp_connect_logdata", autoAck: false, consumer: consumer3);
|
||||
var e = channel4.BasicConsumeAsync(queue: "tcp_send_data", autoAck: false, consumer: consumer4);
|
||||
|
||||
await Task.WhenAll(a, b, c, d, e);
|
||||
while (!stoppingToken.IsCancellationRequested)
|
||||
{
|
||||
await Task.Delay(2000,stoppingToken);
|
||||
}
|
||||
}
|
||||
catch (Exception e1)
|
||||
{
|
||||
|
||||
}
|
||||
_logger.Error("这里不会执行的");
|
||||
await Task.Delay(5000);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public class TCPData
|
||||
{
|
||||
public string? endpoint { get; set; }
|
||||
public string? data { get; set; }
|
||||
public long reporttimestamp { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 燃气报警
|
||||
/// </summary>
|
||||
public static byte[] cmd_buning_alert = new byte[] { 0x03, 0x00 };
|
||||
public static byte[] cmd_e = new byte[] { 0x02, 0x00 };
|
||||
|
||||
/// <summary>
|
||||
/// 注册命令
|
||||
/// </summary>
|
||||
public static byte[] cmd_register = new byte[] { 0x01, 0x00 };
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 报警电话
|
||||
/// </summary>
|
||||
/// <param name="DeviceClientId"></param>
|
||||
/// <param name="QQQ1"></param>
|
||||
/// <returns></returns>
|
||||
private async Task 发送短信打电话(uint DeviceClientId, List<string>? QQQ1)
|
||||
{
|
||||
double UIA = 3;
|
||||
foreach (var item in QQQ1)
|
||||
{
|
||||
MsgData ss = new MsgData();
|
||||
ss.PhoneNumber = item.ToString();
|
||||
ss.CallerName = "IOT平台";
|
||||
ss.Content = string.Format("【能泰科技】您的燃气报警器【{0}】触发警报,请尽快 确认处理!", DeviceClientId);
|
||||
ss.StartingPoint = Tools.ToUnixTimestampBySeconds(DateTime.Now).ToString();
|
||||
ss.DeadLine = Tools.ToUnixTimestampBySeconds(DateTime.Now.AddMinutes(UIA)).ToString();
|
||||
ss.Type = "2";
|
||||
await MsgSend.SendMsg(ss);
|
||||
_logger.Error("手机号" + item.ToString() + "发送了短信");
|
||||
|
||||
|
||||
MsgData ss1 = new MsgData();
|
||||
ss1.PhoneNumber = item.ToString();
|
||||
ss1.CallerName = "IOT平台";
|
||||
ss1.Content = "能泰科技 您的燃气报警器触发警报 请尽快处理";
|
||||
ss1.StartingPoint = Tools.ToUnixTimestampBySeconds(DateTime.Now).ToString();
|
||||
ss1.DeadLine = Tools.ToUnixTimestampBySeconds(DateTime.Now.AddMinutes(UIA)).ToString();
|
||||
ss1.Type = "1";
|
||||
await MsgSend.SendMsg(ss1);
|
||||
_logger.Error("手机号" + item.ToString() + "打了电话");
|
||||
UIA = UIA + 2;
|
||||
}
|
||||
}
|
||||
|
||||
private async Task Connection_ConnectionShutdownAsync(object sender, ShutdownEventArgs args)
|
||||
{
|
||||
//if (args.Initiator != ShutdownInitiator.Application)
|
||||
//{
|
||||
// await Task.Delay(5000);
|
||||
//}
|
||||
await Task.CompletedTask;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// TCP 数据解析
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="event_args"></param>
|
||||
/// <returns></returns>
|
||||
private async Task Consumer2_ReceivedAsync(object sender, BasicDeliverEventArgs event_args)
|
||||
{
|
||||
string BODYStr = "";
|
||||
try
|
||||
{
|
||||
|
||||
// 获取 channel 对象
|
||||
var consumer = (AsyncEventingBasicConsumer)sender;
|
||||
var channel = consumer.Channel;
|
||||
await channel.BasicAckAsync(event_args.DeliveryTag, false);
|
||||
|
||||
var body = event_args.Body;
|
||||
//AA 30 00
|
||||
//18 00
|
||||
//00
|
||||
|
||||
//FF FF FF FF
|
||||
//A3 31 DA 24 3B B3 7E 1D F4 F2 E1 CB 5A C8 8A 91 45 2D A8 72 14 AC 8A B2 C3 69 61 42 F9 F8
|
||||
|
||||
//CRC
|
||||
//AA B9
|
||||
|
||||
//尾标志
|
||||
//2D 2D 0D 0A 2D 2D
|
||||
var message = Encoding.UTF8.GetString(body.ToArray());
|
||||
BODYStr = message;
|
||||
TCPData TTT = System.Text.Json.JsonSerializer.Deserialize<TCPData>(message);
|
||||
|
||||
long report_time = TTT.reporttimestamp;
|
||||
DateTime dangqian_time = Tools.ToLocalTimeDateBySeconds(report_time);
|
||||
string TcpEndPoint = TTT.endpoint;
|
||||
string[] data = TcpEndPoint.Split(':');
|
||||
string ip = data[0];
|
||||
short port = 0;
|
||||
short.TryParse(data[1], out port);
|
||||
|
||||
var NNN1 = Tools.HEXString2ByteArray(TTT.data);
|
||||
string OStr = Tools.ByteToString(NNN1);
|
||||
|
||||
//头
|
||||
byte Header = NNN1[0];
|
||||
|
||||
//从1到3之间的元素,不包括3
|
||||
byte[] Len = NNN1[1..3];
|
||||
|
||||
//SN号
|
||||
byte[] Pack_SN = NNN1[3..5];
|
||||
ushort Pack_XUHAO = BitConverter.ToUInt16(Pack_SN.ToArray(), 0);
|
||||
|
||||
//重发次数
|
||||
byte RetryCount = NNN1[5];
|
||||
|
||||
//设备编号
|
||||
byte[] DeviceOnlyNo = NNN1[6..10];
|
||||
//ClientId
|
||||
uint DeviceClientId = BitConverter.ToUInt32(DeviceOnlyNo);
|
||||
|
||||
Console.WriteLine("Client是:" + DeviceClientId);
|
||||
|
||||
|
||||
|
||||
//ushort llf = (ushort)NNN1.Length;
|
||||
//IV内容组成:Pack_Head + Pack_LEN + Pack_SN + Retry_Num + Client_ID + Pack_END
|
||||
//List<byte> IIV = new List<byte>();
|
||||
//IIV.Add(0xAA);
|
||||
//IIV.AddRange(BitConverter.GetBytes(llf));
|
||||
//IIV.AddRange(Pack_SN);
|
||||
//IIV.Add(0x00);
|
||||
//IIV.AddRange(DeviceOnlyNo);
|
||||
//IIV.AddRange(new byte[] { 0x2D, 0x2D, 0x0D, 0x0A, 0x2D, 0x2D });
|
||||
//byte[] New_IV = IIV.ToArray();
|
||||
//Console.WriteLine("IV是" + Tools.ByteToString(New_IV));
|
||||
//AA 30 00 80 01 00 FF FF FF FF 5F C5 64 B3 93 50 FA 3F 48 D0 E9 C0 DD 7E 7C 62 10 E4 AD 4C EA 0D 04 FD 39 4C A7 77 40 18 7F 31 2D 2D 0D 0A 2D 2D
|
||||
|
||||
byte[] GGJ = NNN1[10..^8];
|
||||
//加密key
|
||||
byte[] key = new byte[] { };
|
||||
//byte[] key = new byte[] { 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c };
|
||||
await using var context = _factory.CreateDbContext();
|
||||
|
||||
string Kkey = ConstValue.OnOffLineKey + "_" + TcpEndPoint;
|
||||
var CID = CSRedisCacheHelper.Get<uint>(Kkey);
|
||||
if (CID != 0)
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
CSRedisCacheHelper.Set<uint>(Kkey, DeviceClientId);
|
||||
}
|
||||
//await NewMethod(TcpEndPoint, TcpEndPoint, context);
|
||||
string FinallyKey = "";
|
||||
string cachekey = "SecretKey_" + DeviceClientId.ToString();
|
||||
string str = _cache.Get<string>(cachekey);
|
||||
if (!string.IsNullOrEmpty(str))
|
||||
{
|
||||
FinallyKey = str;
|
||||
}
|
||||
else
|
||||
{
|
||||
var SinData = await context.Deviceinfos.SingleOrDefaultAsync(A => A.ClientId == DeviceClientId);
|
||||
if (SinData != null)
|
||||
{
|
||||
FinallyKey = SinData.SecretKey;
|
||||
_cache.Set<string>(cachekey, FinallyKey, DateTimeOffset.Now.AddMinutes(20));
|
||||
}
|
||||
}
|
||||
if (!string.IsNullOrEmpty(FinallyKey))
|
||||
{
|
||||
key = Encoding.ASCII.GetBytes(FinallyKey);
|
||||
}
|
||||
|
||||
//string HHS= Tools.ByteToString(key);
|
||||
//Console.WriteLine("Key 使用的是:"+HHS);
|
||||
|
||||
//AES_CTR forDecrypting = new AES_CTR(key, New_IV);
|
||||
//byte[] decryptedContent = new byte[GGJ.Length];
|
||||
//forDecrypting.DecryptBytes(decryptedContent, GGJ);
|
||||
|
||||
//byte[] decryptedContent = GGJ;
|
||||
byte[] decryptedContent = Tools.IHIOT_Message_Content_Encrypt(Pack_XUHAO, key, GGJ);
|
||||
string DStr = Tools.ByteToString(decryptedContent);
|
||||
Console.WriteLine("解密结果:" + DStr);
|
||||
|
||||
//命令字
|
||||
byte[] cmd = decryptedContent[0..2];
|
||||
Console.WriteLine("命令字为A:" + Tools.ByteToString(cmd));
|
||||
Console.WriteLine("命令字为B:" + Tools.ByteToString(cmd_e));
|
||||
|
||||
|
||||
List<byte> xianshi = new List<byte>();
|
||||
xianshi.Add(Header);
|
||||
xianshi.AddRange(Len);
|
||||
xianshi.AddRange(Pack_SN);
|
||||
xianshi.Add(RetryCount);
|
||||
xianshi.AddRange(DeviceOnlyNo);
|
||||
xianshi.AddRange(decryptedContent);
|
||||
byte[] CRCCode_F = NNN1[^8..^6];
|
||||
byte[] Tail_F = NNN1[^6..];
|
||||
xianshi.AddRange(CRCCode_F);
|
||||
xianshi.AddRange(Tail_F);
|
||||
string xianshi_str = Tools.ByteToString(xianshi.ToArray());
|
||||
|
||||
if (MqttClientHostedService._mqttClient != null && MqttClientHostedService._mqttClient.IsConnected)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
string endppp = TTT.endpoint;
|
||||
string topic = string.Format("emqtt/tcp/" + endppp);
|
||||
string payload = "";
|
||||
var payloadbyte = new List<byte>();
|
||||
payloadbyte.Add(Header);
|
||||
payloadbyte.AddRange(Len);
|
||||
payloadbyte.AddRange(Pack_SN);
|
||||
payloadbyte.Add(RetryCount);
|
||||
payloadbyte.AddRange(DeviceOnlyNo);
|
||||
payloadbyte.AddRange(decryptedContent);
|
||||
string sss = Tools.ByteToString(payloadbyte.ToArray());
|
||||
_logger.Error("MQTT Pub" + sss);
|
||||
await MqttClientHostedService.PublishAsync(topic, xianshi_str);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
//如果是注册命令
|
||||
if (cmd.ValueEquals(cmd_register))
|
||||
{
|
||||
//P0:启动原因
|
||||
//P1~P32:软件版本号(32Byte)
|
||||
//P33~P48:IMEI(16Byte)
|
||||
//P49~P58: ICCID(20Byte)
|
||||
//P59~P74: 经度16Byte
|
||||
//P75~P90: 纬度 16Byte
|
||||
//P91~P106: MCU软件版本(16Byte)
|
||||
//P107~P123: MCU UUID(16Byte)
|
||||
|
||||
//byte 启动原因 = decryptedContent[0];
|
||||
//byte[] 软件版本号 = decryptedContent[1..33];
|
||||
//byte[] IMEI = decryptedContent[33..49];
|
||||
//byte[] ICCID = decryptedContent[49..59];
|
||||
//byte[] 经度 = decryptedContent[59..75];
|
||||
//byte[] 纬度 = decryptedContent[75..91];
|
||||
//byte[] MCU软件版本 = decryptedContent[91..107];
|
||||
//byte[] MCUUUID = decryptedContent[107..124];
|
||||
|
||||
//P0:启动原因
|
||||
//P1~P2:设备类型ID 2Byte
|
||||
//P3~P4:厂牌ID 2Byte
|
||||
//P5~P6:机型ID 2Byte
|
||||
//P7: MCU软件版本(16Byte)
|
||||
//P8: MCU硬件版本(16Byte)
|
||||
//P9: MCU UUID长度(1Byte)
|
||||
//P10~Pn: MCU UUID(16Byte)
|
||||
|
||||
|
||||
byte 启动原因 = decryptedContent[0];
|
||||
byte[] 设备类型ID = decryptedContent[1..3];
|
||||
byte[] 厂牌ID = decryptedContent[3..5];
|
||||
byte[] 机型ID = decryptedContent[5..7];
|
||||
byte MCU软件版本 = decryptedContent[7];
|
||||
byte MCU硬件版本 = decryptedContent[8];
|
||||
|
||||
byte MCUUUID长度 = decryptedContent[9];
|
||||
byte[] MCUUUID = decryptedContent[10..];
|
||||
|
||||
DeviceRegisterDatum d = new DeviceRegisterDatum();
|
||||
d.ClientId = DeviceClientId;
|
||||
d.ReStartReason = Convert.ToInt16(启动原因).ToString();
|
||||
d.DeviceClassId = Tools.ByteToString(设备类型ID);
|
||||
d.Pid = Tools.ByteToString(厂牌ID);
|
||||
d.DeviceClassId = Tools.ByteToString(机型ID);
|
||||
d.McusoftVersion = MCU软件版本.ToString("X2");
|
||||
d.McuhardVersion = MCU硬件版本.ToString("X2");
|
||||
d.Mcuuuid = Tools.ByteToString(MCUUUID);
|
||||
|
||||
d.CreateTime = DateTime.Now;
|
||||
d.EndPoint = TcpEndPoint;
|
||||
|
||||
if (TcpEndPoint.Contains(":"))
|
||||
{
|
||||
string[] II_PPP = TcpEndPoint.Split(':');
|
||||
string II = II_PPP[0];
|
||||
if (!string.IsNullOrEmpty(II))
|
||||
{
|
||||
d.RealAddress = BaiduAPI.GetBaiduIp(II);
|
||||
}
|
||||
}
|
||||
context.DeviceRegisterData.Add(d);
|
||||
await context.SaveChangesAsync();
|
||||
}
|
||||
//燃气报警
|
||||
if (cmd.ValueEquals(cmd_buning_alert))
|
||||
{
|
||||
string HexData = Tools.ByteToString(decryptedContent);
|
||||
//燃气报警数据为:03 00 04 00
|
||||
Console.WriteLine("燃气报警数据为:" + HexData);
|
||||
byte 燃气报警状态 = decryptedContent[0];
|
||||
byte 报警状态1 = decryptedContent[2];
|
||||
//0x04是报警
|
||||
//0x03是取消报警
|
||||
if (decryptedContent.Length == 4)
|
||||
{
|
||||
if (报警状态1 == 0x04)
|
||||
{
|
||||
if (DeviceClientId == 71)
|
||||
{
|
||||
IronPython.Runtime.PythonList OOO = StaticData.scope2.GetVariable("Dev_MobileNo");
|
||||
var OOO1 = JsonConvert.SerializeObject(OOO);
|
||||
var OOO2 = JsonConvert.DeserializeObject<List<string>>(OOO1);
|
||||
await 发送短信打电话(DeviceClientId, OOO2);
|
||||
}
|
||||
else
|
||||
{
|
||||
IronPython.Runtime.PythonList QQQ = StaticData.scope2.GetVariable("MobileNo");
|
||||
var PPP1 = JsonConvert.SerializeObject(QQQ);
|
||||
var QQQ1 = JsonConvert.DeserializeObject<List<string>>(PPP1);
|
||||
|
||||
IronPython.Runtime.PythonList III = StaticData.scope2.GetVariable("DeviceId");
|
||||
var PPP2 = JsonConvert.SerializeObject(III);
|
||||
var QQQ2 = JsonConvert.DeserializeObject<List<uint>>(PPP2);
|
||||
|
||||
if (QQQ2.Contains(DeviceClientId))
|
||||
{
|
||||
await 发送短信打电话(DeviceClientId, QQQ1);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
DeviceAlertDatum alertDatum = new DeviceAlertDatum();
|
||||
alertDatum.ClientId = DeviceClientId;
|
||||
alertDatum.EndPoint = TcpEndPoint;
|
||||
alertDatum.CreateTime = DateTime.Now;
|
||||
if (TcpEndPoint.Contains(":"))
|
||||
{
|
||||
string[] II_PPP = TcpEndPoint.Split(':');
|
||||
string II = II_PPP[0];
|
||||
if (!string.IsNullOrEmpty(II))
|
||||
{
|
||||
alertDatum.RealAddress = BaiduAPI.GetBaiduIp(II);
|
||||
}
|
||||
}
|
||||
alertDatum.Value = cmd_buning_alert;
|
||||
alertDatum.Value = new byte[] { 燃气报警状态 };
|
||||
context.DeviceAlertData.Add(alertDatum);
|
||||
await context.SaveChangesAsync();
|
||||
}
|
||||
|
||||
//心跳
|
||||
if (cmd.ValueEquals(cmd_e))
|
||||
{
|
||||
byte[] 工作状态 = decryptedContent[2..4];
|
||||
byte[] 实时值 = decryptedContent[4..6];
|
||||
byte[] 环境值 = decryptedContent[6..8];
|
||||
byte[] 背景值 = decryptedContent[8..10];
|
||||
byte[] 差值 = decryptedContent[10..12];
|
||||
byte[] 浓度百分比 = decryptedContent[12..14];
|
||||
byte[] 稳定状态 = decryptedContent[14..16];
|
||||
byte[] 阈值1 = decryptedContent[16..18];
|
||||
byte[] 阈值2 = decryptedContent[18..20];
|
||||
byte[] MCU温度 = decryptedContent[20..22];
|
||||
byte[] 检测故障 = decryptedContent[22..24];
|
||||
byte[] 传感器温度 = decryptedContent[24..26];
|
||||
byte[] 传感器湿度 = decryptedContent[26..28];
|
||||
byte[] 人测试 = decryptedContent[28..30];
|
||||
|
||||
byte[] ADC原始值 = decryptedContent[30..32];
|
||||
byte[] 故障状态码 = decryptedContent[32..];
|
||||
//P28-P29 ADC原始值
|
||||
//P30-P31 故障状态码
|
||||
|
||||
//02 00
|
||||
//02 00
|
||||
//10 01
|
||||
//13 01
|
||||
//10 01
|
||||
//FD FF
|
||||
//00 00
|
||||
//01 00
|
||||
//7D 02
|
||||
//7D 07
|
||||
//6E 00
|
||||
//38 00
|
||||
//1E 00
|
||||
//2F 00
|
||||
//00 00
|
||||
|
||||
//P0~P1:燃气检测:工作状态
|
||||
//P2~P3:燃气检测:实时值
|
||||
//P4~P5:燃气检测:环境值
|
||||
//P6~P7:燃气检测:背景值
|
||||
//P8~P9:燃气检测:差值
|
||||
//P10~P11:燃气检测:浓度百分比
|
||||
//P12~P13:燃气检测:稳定状态
|
||||
//P14~P15:燃气检测:阈值1
|
||||
//P16~P17:燃气检测:阈值2
|
||||
//P18~P19:燃气检测:MCU温度
|
||||
//P20~P21:燃气检测:检测故障
|
||||
//P22~P23:燃气检测:传感器温度
|
||||
//P24~P25:燃气检测:传感器湿度
|
||||
//P26~P27:燃气检测:外部传感器检测有无人状态
|
||||
|
||||
//P28-P29 ADC原始值
|
||||
//P30-P31 故障状态码
|
||||
|
||||
|
||||
|
||||
|
||||
short gongzuo = BitConverter.ToInt16(工作状态.ToArray(), 0);
|
||||
short shishizhi = BitConverter.ToInt16(实时值.ToArray(), 0);
|
||||
short huanjingzhi = BitConverter.ToInt16(环境值.ToArray(), 0);
|
||||
short beijingzhi = BitConverter.ToInt16(背景值.ToArray(), 0);
|
||||
short chazhi = BitConverter.ToInt16(差值.ToArray(), 0);
|
||||
short nongdu = BitConverter.ToInt16(浓度百分比.ToArray(), 0);
|
||||
short wending = BitConverter.ToInt16(稳定状态.ToArray(), 0);
|
||||
short yuzhi1 = BitConverter.ToInt16(阈值1.ToArray(), 0);
|
||||
short yuzhi2 = BitConverter.ToInt16(阈值2.ToArray(), 0);
|
||||
short muc_t = BitConverter.ToInt16(MCU温度.ToArray(), 0);
|
||||
short guzhang = BitConverter.ToInt16(检测故障.ToArray(), 0);
|
||||
short T1 = BitConverter.ToInt16(传感器温度.ToArray(), 0);
|
||||
short H1 = BitConverter.ToInt16(传感器湿度.ToArray(), 0);
|
||||
short humancheck = BitConverter.ToInt16(人测试.ToArray(), 0);
|
||||
ushort adc_original_valuue = BitConverter.ToUInt16(ADC原始值.ToArray(), 0);
|
||||
ushort error_code = BitConverter.ToUInt16(故障状态码.ToArray(), 0);
|
||||
|
||||
short XUHAO = BitConverter.ToInt16(Pack_SN.ToArray(), 0);
|
||||
//string DeviceID= BitConverter.ToInt64(DeviceOnlyNo,0).ToString();
|
||||
//string DeviceID = Tools.Byte4ToLong(DeviceOnlyNo).ToString();
|
||||
string DeviceID = Tools.ByteToString(DeviceOnlyNo);
|
||||
|
||||
//Common.Grafana.
|
||||
//var gdata = Grafana.data;
|
||||
//if (DeviceID.Equals(gdata.device_id))
|
||||
//{
|
||||
// gdata.realtime_value = shishizhi.ToString();
|
||||
// gdata.environment_value = huanjingzhi.ToString();
|
||||
// gdata.mcu_temperature = muc_t.ToString();
|
||||
// gdata.sensor_temperature = T1.ToString();
|
||||
|
||||
// gdata.sensor_humidity = H1.ToString();
|
||||
// gdata.adc_raw_value =adc_original_valuue.ToString();
|
||||
//}
|
||||
|
||||
TcpHeartbeatDatum datum = new TcpHeartbeatDatum()
|
||||
{
|
||||
WorkStatus = gongzuo.ToString(),
|
||||
RealTimeValue = shishizhi.ToString(),
|
||||
EnvValue = huanjingzhi.ToString(),
|
||||
BgValue = beijingzhi.ToString(),
|
||||
DiffValue = chazhi.ToString(),
|
||||
NongDuBaiFenBi = nongdu.ToString(),
|
||||
StableStatus = wending.ToString(),
|
||||
ThresholdValue1 = yuzhi1.ToString(),
|
||||
ThresholdValue2 = yuzhi2.ToString(),
|
||||
McuT = muc_t.ToString(),
|
||||
GuZhangCheck = guzhang.ToString(),
|
||||
Temperature = T1.ToString(),
|
||||
Humidity = H1.ToString(),
|
||||
AnyHuman = humancheck.ToString(),
|
||||
//CreateTime = DateTime.Now,
|
||||
CreateTime = dangqian_time,
|
||||
OriginalDataId = XUHAO,
|
||||
DeviceId = DeviceClientId.ToString(),
|
||||
AdcOriginalValuue = adc_original_valuue.ToString(),
|
||||
ErrorCode = error_code.ToString()
|
||||
};
|
||||
context.TcpHeartbeatData.Add(datum);
|
||||
|
||||
|
||||
Console.WriteLine("写入心跳");
|
||||
//校验CRC16,小端模式(低地址在前)
|
||||
//校验内容:Pack_Head + Pack_LEN + Pack_SN + Retry_Num + Client_ID + CMD + PARA
|
||||
byte[] CRCCode = NNN1[^8..^6];
|
||||
|
||||
//Tools.CRC16
|
||||
//结尾标志符
|
||||
//获取从倒数第三个元素到数组末尾的所有元素
|
||||
byte[] Tail = NNN1[^6..];
|
||||
}
|
||||
|
||||
TcpReceiveDatum tcpReceiveDatum = new TcpReceiveDatum();
|
||||
|
||||
tcpReceiveDatum.ClientId = DeviceClientId;
|
||||
tcpReceiveDatum.CommandType = BitConverter.ToInt16(cmd);
|
||||
tcpReceiveDatum.OriginalData = OStr;
|
||||
tcpReceiveDatum.DencryptData = DStr;
|
||||
tcpReceiveDatum.InsertDate = DateTime.Now;
|
||||
tcpReceiveDatum.InsertUnix = Tools.ToUnixTimestampByMilliseconds(DateTime.Now);
|
||||
tcpReceiveDatum.EndPoint = TcpEndPoint;
|
||||
context.TcpReceiveData.Add(tcpReceiveDatum);
|
||||
await context.SaveChangesAsync();
|
||||
Console.WriteLine("写入数据");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Error("错误的数据为:" + BODYStr);
|
||||
_logger.Error(ex.Message);
|
||||
_logger.Error(ex.StackTrace);
|
||||
}
|
||||
await Task.CompletedTask;
|
||||
}
|
||||
|
||||
private static async Task 设备在线状态(string TcpEndPoint, int CID, PostgresContext context)
|
||||
{
|
||||
var S = await context.DeviceStatuses.SingleOrDefaultAsync(A => A.EndPoint.Equals(TcpEndPoint));
|
||||
if (S != null)
|
||||
{
|
||||
S.Status = ConstValue.OnLine;
|
||||
S.DeviceId = CID;
|
||||
S.UpdateTime = DateTime.Now;
|
||||
S.UpdateTimeUnix = Tools.ToUnixTimestampByMilliseconds(DateTime.Now);
|
||||
context.Update(S);
|
||||
}
|
||||
else
|
||||
{
|
||||
DeviceStatus d = new DeviceStatus();
|
||||
d.EndPoint = TcpEndPoint;
|
||||
d.DeviceId = CID;
|
||||
d.UpdateTime = DateTime.Now;
|
||||
d.UpdateTimeUnix = Tools.ToUnixTimestampByMilliseconds(DateTime.Now);
|
||||
d.Status = ConstValue.OnLine;
|
||||
context.DeviceStatuses.Add(d);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// TCP 断网原因
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="ea"></param>
|
||||
/// <returns></returns>
|
||||
private async Task Consumer1_ReceivedAsync(object sender, BasicDeliverEventArgs ea)
|
||||
{
|
||||
|
||||
try
|
||||
{
|
||||
// 获取 channel 对象
|
||||
var consumer = (AsyncEventingBasicConsumer)sender;
|
||||
var channel = consumer.Channel;
|
||||
await channel.BasicAckAsync(ea.DeliveryTag, false);
|
||||
|
||||
var body = ea.Body;
|
||||
var message = Encoding.UTF8.GetString(body.ToArray());
|
||||
|
||||
_logger.Error("设备断网:" + message);
|
||||
//{"endpoint":"172.16.4.40:31992","close_reason":"tcp_closed","currenttimestamp":1750643082}
|
||||
var T = System.Text.Json.JsonSerializer.Deserialize<TcpCloseReason>(message);
|
||||
|
||||
string[] data = T.endpoint.Split(':');
|
||||
string ip = data[0];
|
||||
int port = 0;
|
||||
int.TryParse(data[1], out port);
|
||||
await using var context = _factory.CreateDbContext();
|
||||
|
||||
|
||||
string E = T.endpoint;
|
||||
var S = await context.DeviceStatuses.SingleOrDefaultAsync(A => A.EndPoint.Equals(E));
|
||||
if (S != null)
|
||||
{
|
||||
S.Status = ConstValue.OffLine;
|
||||
S.UpdateTime = DateTime.Now;
|
||||
S.UpdateTimeUnix = Tools.ToUnixTimestampByMilliseconds(DateTime.Now);
|
||||
context.Update(S);
|
||||
}
|
||||
else
|
||||
{
|
||||
DeviceStatus d = new DeviceStatus();
|
||||
d.EndPoint = E;
|
||||
d.DeviceId = 0;
|
||||
d.UpdateTime = DateTime.Now;
|
||||
d.UpdateTimeUnix = Tools.ToUnixTimestampByMilliseconds(DateTime.Now);
|
||||
d.Status = ConstValue.OffLine;
|
||||
context.DeviceStatuses.Add(d);
|
||||
}
|
||||
await context.SaveChangesAsync();
|
||||
|
||||
|
||||
TcpCloseDatum t = new TcpCloseDatum();
|
||||
t.WwwIp = ip;
|
||||
t.ClientId = T.clientid;
|
||||
t.RealAddress = BaiduAPI.GetBaiduIp(ip);
|
||||
t.WwwPort = port;
|
||||
t.CloseReason = T.close_reason;
|
||||
t.CreatetimeUnix = T.currenttimestamp;
|
||||
context.TcpCloseData.Add(t);
|
||||
await context.SaveChangesAsync();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Error(ex.Message);
|
||||
}
|
||||
await Task.CompletedTask;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// TCP 连接信息
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="ea"></param>
|
||||
/// <returns></returns>
|
||||
private async Task Consumer3_ReceivedAsync(object sender, BasicDeliverEventArgs ea)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
// 获取 channel 对象
|
||||
var consumer = (AsyncEventingBasicConsumer)sender;
|
||||
var channel = consumer.Channel;
|
||||
await channel.BasicAckAsync(ea.DeliveryTag, false);
|
||||
|
||||
var body = ea.Body;
|
||||
var message = Encoding.UTF8.GetString(body.ToArray());
|
||||
|
||||
//{"endpoint":"172.16.4.40:31992","close_reason":"tcp_closed","currenttimestamp":1750643082}
|
||||
var T = System.Text.Json.JsonSerializer.Deserialize<TcpConnectLog>(message);
|
||||
|
||||
string[] data = T.endpoint.Split(':');
|
||||
string ip = data[0];
|
||||
int port = 0;
|
||||
bool bbba = int.TryParse(data[1], out port);
|
||||
if (bbba == false)
|
||||
{
|
||||
_logger.Error("端口出错了:" + message);
|
||||
}
|
||||
await using var context = _factory.CreateDbContext();
|
||||
|
||||
string E = T.endpoint;
|
||||
var S = await context.DeviceStatuses.SingleOrDefaultAsync(A => A.EndPoint.Equals(E));
|
||||
if (S != null)
|
||||
{
|
||||
S.Status = ConstValue.OnLine;
|
||||
S.UpdateTime = DateTime.Now;
|
||||
S.UpdateTimeUnix = Tools.ToUnixTimestampByMilliseconds(DateTime.Now);
|
||||
context.Update(S);
|
||||
}
|
||||
else
|
||||
{
|
||||
DeviceStatus d = new DeviceStatus();
|
||||
d.EndPoint = E;
|
||||
d.DeviceId = 0;
|
||||
d.UpdateTime = DateTime.Now;
|
||||
d.UpdateTimeUnix = Tools.ToUnixTimestampByMilliseconds(DateTime.Now);
|
||||
d.Status = ConstValue.OnLine;
|
||||
context.DeviceStatuses.Add(d);
|
||||
}
|
||||
await context.SaveChangesAsync();
|
||||
|
||||
TcpConnDatum t = new TcpConnDatum();
|
||||
t.WwwIp = ip;
|
||||
t.ClientId = T.clientid;
|
||||
t.RealAddress = BaiduAPI.GetBaiduIp(ip);
|
||||
t.WwwPort = port;
|
||||
t.ConnectTimeUnix = T.currenttimestamp;
|
||||
context.TcpConnData.Add(t);
|
||||
await context.SaveChangesAsync();
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// TCP Send 数据
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="ea"></param>
|
||||
/// <returns></returns>
|
||||
private async Task Consumer4_ReceivedAsync(object sender, BasicDeliverEventArgs ea)
|
||||
{
|
||||
try
|
||||
{
|
||||
// 获取 channel 对象
|
||||
var consumer = (AsyncEventingBasicConsumer)sender;
|
||||
var channel = consumer.Channel;
|
||||
await channel.BasicAckAsync(ea.DeliveryTag, false);
|
||||
|
||||
var body = ea.Body;
|
||||
var message = Encoding.UTF8.GetString(body.ToArray());
|
||||
|
||||
//V= #{clientid=>VVVXXX,endpoint=> E1,send_data=> Data,currenttimestamp=>CurrentTimestamp}
|
||||
//{"clientid":49,"send_data":[170,187,204,221,238],"currenttimestamp":1761200698,"endpoint":"111.55.160.5:4812"}
|
||||
_logger.Error("收到的数据:" + message);
|
||||
|
||||
var T = System.Text.Json.JsonSerializer.Deserialize<TcpSendDataLog>(message);
|
||||
var AAA1232 = T.send_data?.Select(A => Convert.ToByte(A));
|
||||
|
||||
await using var context = _factory.CreateDbContext();
|
||||
|
||||
TcpSendDatum t = new TcpSendDatum();
|
||||
|
||||
t.ClientId = T.clientid;
|
||||
t.SendData = Tools.ByteToString(AAA1232.ToArray());
|
||||
t.CreateTime = DateTime.Now;
|
||||
t.CreateTimeUnix = T.currenttimestamp;
|
||||
t.CommandType = "";
|
||||
context.TcpSendData.Add(t);
|
||||
await context.SaveChangesAsync();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Error("收到数据出异常了:" + ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// MQTT的数据,还没有 开始启用
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="ea"></param>
|
||||
/// <returns></returns>
|
||||
private async Task Consumer0_ReceivedAsync(object sender, BasicDeliverEventArgs ea)
|
||||
{
|
||||
// 获取 channel 对象
|
||||
var consumer = (AsyncEventingBasicConsumer)sender;
|
||||
var channel = consumer.Channel;
|
||||
await channel.BasicAckAsync(ea.DeliveryTag, false);
|
||||
|
||||
var body = ea.Body;
|
||||
var message = Encoding.UTF8.GetString(body.ToArray());
|
||||
Console.WriteLine("收到消息 {0}", message);
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
//if (!string.IsNullOrEmpty(message))
|
||||
//{
|
||||
// Task.Factory.StartNew((state) =>
|
||||
// {
|
||||
|
||||
// }, body);
|
||||
//}
|
||||
//string BodyString = state.ToString();
|
||||
_logger.Error(body);
|
||||
var QQQ = System.Text.Json.JsonSerializer.Deserialize<RawPayload>(message);
|
||||
string topic = QQQ.topic;
|
||||
string payload = QQQ.payload;
|
||||
|
||||
//传递过来的数据就是base64的,没有必要再转
|
||||
byte[] bbb = Convert.FromBase64String(payload);
|
||||
string bbb1 = Tools.ByteToString(bbb);
|
||||
|
||||
this._logger.Info("Topic: " + topic);
|
||||
this._logger.Info("PayLoad: " + bbb1);
|
||||
|
||||
|
||||
byte[] NNN1 = Tools.HEXString2ByteArray(bbb1.Replace(" ", ""));
|
||||
//AA 13 00 44 0B 00 FF FF FF FF 61 67 EF 6B E8 2D 2D 0D 0A 2D 2D
|
||||
|
||||
byte Header = NNN1[0];
|
||||
//从1到3之间的元素,不包括3
|
||||
byte[] Len = NNN1[1..3];
|
||||
//byte[] Len = NNN1.AsSpan(1,2);
|
||||
byte[] Pack_SN = NNN1[3..5];
|
||||
|
||||
//重发次数
|
||||
byte RetryCount = NNN1[5];
|
||||
|
||||
//设备编号
|
||||
byte[] DeviceOnlyNo = NNN1[6..10];
|
||||
|
||||
//命令字
|
||||
byte[] Command = NNN1[10..12];
|
||||
|
||||
|
||||
//校验CRC16,小端模式(低地址在前)
|
||||
//校验内容:Pack_Head + Pack_LEN + Pack_SN + Retry_Num + Client_ID + CMD + PARA
|
||||
byte[] CRCCode = NNN1[^8..^6];
|
||||
|
||||
//结尾标志符
|
||||
//// 获取从倒数第三个元素到数组末尾的所有元素
|
||||
byte[] Tail = NNN1[^6..];
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
|
||||
}
|
||||
await Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
}
|
||||
294
BooliveMQTT_Auth/services/MqttClientHostedService.cs
Normal file
294
BooliveMQTT_Auth/services/MqttClientHostedService.cs
Normal file
@@ -0,0 +1,294 @@
|
||||
|
||||
using Microsoft.VisualBasic;
|
||||
using MQTTnet;
|
||||
using MQTTnet.Protocol;
|
||||
using NLog;
|
||||
using Proto;
|
||||
|
||||
namespace IotManager.services
|
||||
{
|
||||
public class MqttClientHostedService : BackgroundService
|
||||
{
|
||||
public static IMqttClient? _mqttClient;
|
||||
public MqttClientOptions? _options;
|
||||
public static bool IsConnectioned { get; set; }
|
||||
|
||||
public IConfiguration? Configuration { get; set; }
|
||||
|
||||
private static Logger _logger = LogManager.GetCurrentClassLogger();
|
||||
|
||||
// 重连相关变量
|
||||
private readonly SemaphoreSlim _reconnectLock = new(1, 1);
|
||||
private bool _isReconnecting = false;
|
||||
private int _reconnectAttempts = 0;
|
||||
private const int MAX_RECONNECT_ATTEMPTS = 10;
|
||||
private const int RECONNECT_DELAY_SECONDS = 5;
|
||||
|
||||
public MqttClientHostedService(IConfiguration configuration)
|
||||
{
|
||||
Configuration = configuration;
|
||||
}
|
||||
|
||||
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
|
||||
{
|
||||
await InitializeMqttClient();
|
||||
|
||||
// 主循环,持续监控连接状态
|
||||
while (!stoppingToken.IsCancellationRequested)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!IsConnectioned && !_isReconnecting)
|
||||
{
|
||||
await ReconnectWithRetry();
|
||||
}
|
||||
|
||||
// 每30秒检查一次连接状态
|
||||
await Task.Delay(TimeSpan.FromSeconds(30), stoppingToken);
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
// 服务停止
|
||||
break;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Error($"MQTT监控循环异常: {ex.Message}");
|
||||
await Task.Delay(TimeSpan.FromSeconds(10), stoppingToken);
|
||||
}
|
||||
}
|
||||
|
||||
// 清理资源
|
||||
await DisposeAsync();
|
||||
}
|
||||
|
||||
private async Task InitializeMqttClient()
|
||||
{
|
||||
try
|
||||
{
|
||||
var factory = new MQTTnet.MqttClientFactory();
|
||||
_mqttClient = factory.CreateMqttClient();
|
||||
|
||||
|
||||
var IP = Configuration["MQTT:IP"];
|
||||
int Port = 1883;
|
||||
int.TryParse(Configuration["MQTT:Port"], out Port);
|
||||
var UserName = Configuration["MQTT:UserName"];
|
||||
var PWD = Configuration["MQTT:PassWord"];
|
||||
string clientId = "IOTConsumer#" + Guid.NewGuid().ToString("N");
|
||||
|
||||
_options = new MqttClientOptionsBuilder()
|
||||
.WithTcpServer(IP, Port)
|
||||
.WithClientId(clientId)
|
||||
.WithCredentials(UserName, PWD)
|
||||
.WithWillQualityOfServiceLevel(MqttQualityOfServiceLevel.AtMostOnce)
|
||||
.WithProtocolVersion(MQTTnet.Formatter.MqttProtocolVersion.V500)
|
||||
.Build();
|
||||
|
||||
// 注册事件
|
||||
_mqttClient.ConnectedAsync += OnConnectedAsync;
|
||||
_mqttClient.DisconnectedAsync += OnDisconnectedAsync;
|
||||
_mqttClient.ApplicationMessageReceivedAsync += OnApplicationMessageReceivedAsync;
|
||||
|
||||
await ConnectAsync();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Error($"MQTT初始化错误: {ex.Message}");
|
||||
_logger.Error(ex.StackTrace);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task ConnectAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (_mqttClient == null || _options == null)
|
||||
return;
|
||||
|
||||
_logger.Info("正在连接MQTT服务器...");
|
||||
await _mqttClient.ConnectAsync(_options);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Error($"MQTT连接失败: {ex.Message}");
|
||||
IsConnectioned = false;
|
||||
}
|
||||
}
|
||||
|
||||
private async Task OnConnectedAsync(MqttClientConnectedEventArgs arg)
|
||||
{
|
||||
_logger.Info("MQTT连接成功");
|
||||
IsConnectioned = true;
|
||||
_reconnectAttempts = 0; // 重置重连计数
|
||||
|
||||
// 重新订阅主题(如果需要)
|
||||
await ResubscribeTopics();
|
||||
|
||||
await Task.CompletedTask;
|
||||
}
|
||||
|
||||
private async Task OnDisconnectedAsync(MqttClientDisconnectedEventArgs e)
|
||||
{
|
||||
_logger.Warn($"MQTT连接断开,原因: {e.Reason}");
|
||||
IsConnectioned = false;
|
||||
|
||||
// 如果不是正常断开,启动重连
|
||||
if (e.Reason != MqttClientDisconnectReason.NormalDisconnection)
|
||||
{
|
||||
await ReconnectWithRetry();
|
||||
}
|
||||
|
||||
await Task.CompletedTask;
|
||||
}
|
||||
|
||||
private async Task ReconnectWithRetry()
|
||||
{
|
||||
// 使用锁防止多个重连同时进行
|
||||
if (!await _reconnectLock.WaitAsync(0))
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
if (_isReconnecting || IsConnectioned)
|
||||
return;
|
||||
|
||||
_isReconnecting = true;
|
||||
_reconnectAttempts++;
|
||||
|
||||
_logger.Info($"尝试重连MQTT服务器 (第{_reconnectAttempts}次)...");
|
||||
|
||||
// 指数退避策略:重连间隔逐渐增加
|
||||
int delaySeconds = Math.Min(RECONNECT_DELAY_SECONDS * _reconnectAttempts, 300); // 最大5分钟
|
||||
|
||||
await Task.Delay(TimeSpan.FromSeconds(delaySeconds));
|
||||
|
||||
await ConnectAsync();
|
||||
|
||||
// 如果超过最大重连次数,重置计数器
|
||||
if (_reconnectAttempts >= MAX_RECONNECT_ATTEMPTS)
|
||||
{
|
||||
_reconnectAttempts = 0;
|
||||
_logger.Warn("已达到最大重连次数,将重新开始重连计数");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Error($"重连失败: {ex.Message}");
|
||||
}
|
||||
finally
|
||||
{
|
||||
_isReconnecting = false;
|
||||
_reconnectLock.Release();
|
||||
}
|
||||
}
|
||||
|
||||
private async Task ResubscribeTopics()
|
||||
{
|
||||
try
|
||||
{
|
||||
// 这里重新订阅您需要的主题
|
||||
// 例如:await SubscribeAsync("your/topic");
|
||||
_logger.Info("MQTT主题重新订阅完成");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Error($"重新订阅主题失败: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
private async Task OnApplicationMessageReceivedAsync(MqttApplicationMessageReceivedEventArgs arg)
|
||||
{
|
||||
try
|
||||
{
|
||||
var topic = arg.ApplicationMessage.Topic;
|
||||
var payload = arg.ApplicationMessage.ConvertPayloadToString();
|
||||
|
||||
_logger.Debug($"收到MQTT消息 - 主题: {topic}, 负载: {payload}");
|
||||
|
||||
// 处理消息的业务逻辑
|
||||
await ProcessMessage(topic, payload);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Error($"处理MQTT消息异常: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
private async Task ProcessMessage(string topic, string payload)
|
||||
{
|
||||
// 实现您的消息处理逻辑
|
||||
await Task.CompletedTask;
|
||||
}
|
||||
|
||||
public async Task SubscribeAsync(string topic)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (_mqttClient?.IsConnected == true)
|
||||
{
|
||||
var subscribeOptions = new MqttClientSubscribeOptionsBuilder()
|
||||
.WithTopicFilter(topic)
|
||||
.Build();
|
||||
|
||||
await _mqttClient.SubscribeAsync(subscribeOptions);
|
||||
_logger.Info($"成功订阅主题: {topic}");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Error($"订阅主题失败 {topic}: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
public static async Task PublishAsync(string topic, string payload)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (_mqttClient?.IsConnected == true)
|
||||
{
|
||||
var message = new MqttApplicationMessageBuilder()
|
||||
.WithTopic(topic)
|
||||
.WithPayload(payload)
|
||||
.WithQualityOfServiceLevel(MqttQualityOfServiceLevel.AtMostOnce)
|
||||
.Build();
|
||||
|
||||
await _mqttClient.PublishAsync(message);
|
||||
_logger.Debug($"MQTT消息发送成功 - 主题: {topic}");
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.Warn("MQTT客户端未连接,消息发送失败");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Error($"MQTT消息发送失败: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
public async ValueTask DisposeAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (_mqttClient != null)
|
||||
{
|
||||
_mqttClient.ConnectedAsync -= OnConnectedAsync;
|
||||
_mqttClient.DisconnectedAsync -= OnDisconnectedAsync;
|
||||
_mqttClient.ApplicationMessageReceivedAsync -= OnApplicationMessageReceivedAsync;
|
||||
|
||||
if (_mqttClient.IsConnected)
|
||||
{
|
||||
await _mqttClient.DisconnectAsync();
|
||||
}
|
||||
_mqttClient.Dispose();
|
||||
}
|
||||
_logger.Info("MQTT客户端已释放");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Error($"释放MQTT客户端时出错: {ex.Message}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
67
BooliveMQTT_Auth/services/MyTimer.cs
Normal file
67
BooliveMQTT_Auth/services/MyTimer.cs
Normal file
@@ -0,0 +1,67 @@
|
||||
using System.Text;
|
||||
using Common;
|
||||
using NLog;
|
||||
|
||||
namespace IotManager.services
|
||||
{
|
||||
public class MyTimer : BackgroundService
|
||||
{
|
||||
public System.Timers.Timer jiankong_timer = null;
|
||||
public MyTimer()
|
||||
{
|
||||
|
||||
}
|
||||
protected override Task ExecuteAsync(CancellationToken stoppingToken)
|
||||
{
|
||||
jiankong_timer = new System.Timers.Timer();
|
||||
jiankong_timer.Interval = 60000;
|
||||
jiankong_timer.Elapsed += Jiankong_timer_Elapsed;
|
||||
jiankong_timer.Start();
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
public static Logger logger = LogManager.GetCurrentClassLogger();
|
||||
private void Jiankong_timer_Elapsed(object? sender, System.Timers.ElapsedEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
var df = Grafana.data;
|
||||
|
||||
string NewStringData = Grafana.Data;
|
||||
NewStringData = NewStringData.Replace("{1}", df.device_id)
|
||||
.Replace("{2}", df.device_status)
|
||||
.Replace("{3}", df.realtime_value)
|
||||
.Replace("{4}", df.environment_value)
|
||||
.Replace("{5}", df.mcu_temperature)
|
||||
.Replace("{6}", df.sensor_temperature)
|
||||
.Replace("{7}", df.sensor_humidity)
|
||||
.Replace("{8}", df.adc_raw_value);
|
||||
|
||||
|
||||
WanBuJianKong(NewStringData, "1.txt");
|
||||
File.WriteAllText("2.txt", NewStringData, Encoding.UTF8);
|
||||
Console.WriteLine("here");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine(ex.Message);
|
||||
Console.WriteLine(ex.StackTrace);
|
||||
logger.Error(ex.Message);
|
||||
logger.Error(ex.StackTrace);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static void WanBuJianKong(string Data, string SourceTxt)
|
||||
{
|
||||
System.IO.File.WriteAllText(SourceTxt, Data, Encoding.UTF8);
|
||||
// 如果目标文件存在,先删除
|
||||
if (System.IO.File.Exists(Grafana.WaiBuJianKongTargetFileName))
|
||||
{
|
||||
System.IO.File.Delete(Grafana.WaiBuJianKongTargetFileName);
|
||||
}
|
||||
|
||||
// 重命名/移动文件
|
||||
System.IO.File.Move(SourceTxt, Grafana.WaiBuJianKongTargetFileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user