diff --git a/Cis.Application/Cb/Common/CbInfo.cs b/Cis.Application/Cb/Common/CbInfo.cs
index f64368f..b612a81 100644
--- a/Cis.Application/Cb/Common/CbInfo.cs
+++ b/Cis.Application/Cb/Common/CbInfo.cs
@@ -22,7 +22,7 @@ public class CbInfo
#region Database Info
///
- /// 数据库名
+ /// 数据库标识
///
public const string DbName = SqlSugarConst.DefaultConfigId;
diff --git a/Cis.Application/Cb/Service/CbCameraService.cs b/Cis.Application/Cb/Service/CbCameraService.cs
index 165cffb..156e370 100644
--- a/Cis.Application/Cb/Service/CbCameraService.cs
+++ b/Cis.Application/Cb/Service/CbCameraService.cs
@@ -1,5 +1,4 @@
using Newtonsoft.Json.Linq;
-using System.Runtime.InteropServices;
namespace Cis.Application.Cb;
@@ -22,7 +21,7 @@ public class CbCameraService : IDynamicApiController, ITransient
return entity;
}
- public async Task> GetList(string queryJson)
+ public async Task> GetList(string queryJson = "")
{
JObject queryObj = queryJson.ToJObject();
List list = await _cbCameraRep.AsQueryable()
diff --git a/Cis.Application/Cis.Application.xml b/Cis.Application/Cis.Application.xml
index 4107b98..45840b3 100644
--- a/Cis.Application/Cis.Application.xml
+++ b/Cis.Application/Cis.Application.xml
@@ -21,7 +21,7 @@
- 数据库名
+ 数据库标识
@@ -86,7 +86,7 @@
- 数据库名
+ 数据库标识
@@ -99,6 +99,16 @@
CmMarkGroup 表描述
+
+
+ CmMarkLabel 表名
+
+
+
+
+ CmMarkLabel 表描述
+
+
标记分组表
@@ -119,11 +129,106 @@
备注
+
+
+ 标记标签表
+
+
+
+
+ 名称
+
+
+
+
+ Pan 位置
+
+
+
+
+ Tilt 位置
+
+
+
+
+ Zoom 位置
+
+
+
+
+ 备注
+
+
+
+
+ 相机 Id
+
+
+
+
+ 标记组 Id
+
+
标记分组服务
+
+
+ 标记标签服务
+
+
+
+
+ Ptz 信息
+
+
+
+
+ Pan
+
+
+
+
+ Tilt
+
+
+
+
+ Zoom
+
+
+
+
+ Ptz Api 接口
+
+
+
+
+ Ptz Api
+
+
+
+
+ PtzServer选项
+
+
+
+
+ 服务类别
+
+
+
+
+ 服务IP
+
+
+
+
+ 服务端口
+
+
配置应用所需服务,在该方法中可以添加应用所需要的功能或服务
@@ -154,7 +259,7 @@
- 数据库名
+ 数据库标识
@@ -257,5 +362,15 @@
系统字典类型服务
+
+
+ 数据库标识
+
+
+
+
+ TbPtzCamera 表名
+
+
diff --git a/Cis.Application/Cm/Common/CmInfo.cs b/Cis.Application/Cm/Common/CmInfo.cs
index f82d8e1..abfda16 100644
--- a/Cis.Application/Cm/Common/CmInfo.cs
+++ b/Cis.Application/Cm/Common/CmInfo.cs
@@ -22,7 +22,7 @@ public class CmInfo
#region Database Info
///
- /// 数据库名
+ /// 数据库标识
///
public const string DbName = SqlSugarConst.DefaultConfigId;
@@ -40,5 +40,15 @@ public class CmInfo
///
public const string CmMarkGroupTbDesc = "标记分组表";
+ ///
+ /// CmMarkLabel 表名
+ ///
+ public const string CmMarkLabelTbName = "cm_mark_label";
+
+ ///
+ /// CmMarkLabel 表描述
+ ///
+ public const string CmMarkLabelTbDesc = "标记标签表";
+
#endregion Table Info
}
\ No newline at end of file
diff --git a/Cis.Application/Cm/Entity/CmMarkLabel.cs b/Cis.Application/Cm/Entity/CmMarkLabel.cs
new file mode 100644
index 0000000..bb0429a
--- /dev/null
+++ b/Cis.Application/Cm/Entity/CmMarkLabel.cs
@@ -0,0 +1,52 @@
+namespace Cis.Application.Cm;
+
+///
+/// 标记标签表
+///
+[SugarTable(CmInfo.CmMarkLabelTbName, CmInfo.CmMarkLabelTbDesc)]
+[Tenant(CmInfo.DbName)]
+public class CmMarkLabel : EntityBase
+{
+ ///
+ /// 名称
+ ///
+ [SugarColumn(ColumnDescription = "名称", Length = 64)]
+ public string Name { get; set; }
+
+ ///
+ /// Pan 位置
+ ///
+ [SugarColumn(ColumnDescription = "Pan位置")]
+ public double PanPosition { get; set; }
+
+ ///
+ /// Tilt 位置
+ ///
+ [SugarColumn(ColumnDescription = "Tilt位置")]
+ public double TiltPosition { get; set; }
+
+ ///
+ /// Zoom 位置
+ ///
+ [SugarColumn(ColumnDescription = "Zoom位置")]
+ public double ZoomPosition { get; set; }
+
+ ///
+ /// 备注
+ ///
+ [SugarColumn(ColumnDescription = "备注", Length = 256)]
+ [MaxLength(256)]
+ public string Remark { get; set; }
+
+ ///
+ /// 相机 Id
+ ///
+ [SugarColumn(ColumnDescription = "相机Id")]
+ public long CbCameraId { get; set; }
+
+ ///
+ /// 标记组 Id
+ ///
+ [SugarColumn(ColumnDescription = "标记组Id")]
+ public long CmMarkGroupId { get; set; }
+}
\ No newline at end of file
diff --git a/Cis.Application/Cm/Service/CmMarkGroupService.cs b/Cis.Application/Cm/Service/CmMarkGroupService.cs
index faabdb0..2cf1302 100644
--- a/Cis.Application/Cm/Service/CmMarkGroupService.cs
+++ b/Cis.Application/Cm/Service/CmMarkGroupService.cs
@@ -1,4 +1,6 @@
-namespace Cis.Application.Cm;
+using Newtonsoft.Json.Linq;
+
+namespace Cis.Application.Cm;
///
/// 标记分组服务
@@ -12,4 +14,42 @@ public class CmMarkGroupService : IDynamicApiController, ITransient
{
_cmMarkGroupRep = cmMarkGroupRep;
}
+
+ public async Task Get(long id)
+ {
+ CmMarkGroup entity = await _cmMarkGroupRep.GetByIdAsync(id);
+ return entity;
+ }
+
+ public async Task> GetList(string queryJson)
+ {
+ JObject queryObj = queryJson.ToJObject();
+ List list = await _cmMarkGroupRep.AsQueryable()
+ .ToListAsync();
+ return list;
+ }
+
+ public async Task> GetPageList(string queryJson, string pagination)
+ {
+ Pagination pageObj = pagination.ToObject();
+ JObject queryObj = queryJson.ToJObject();
+ List list = await _cmMarkGroupRep.AsQueryable()
+ .ToPageListAsync(pageObj.Index, pageObj.Size);
+ return list;
+ }
+
+ public async Task Add(CmMarkGroup entity)
+ {
+ await _cmMarkGroupRep.InsertAsync(entity);
+ }
+
+ public async Task Update(CmMarkGroup entity)
+ {
+ await _cmMarkGroupRep.UpdateAsync(entity);
+ }
+
+ public async Task Delete(CmMarkGroup entity)
+ {
+ await _cmMarkGroupRep.DeleteAsync(entity);
+ }
}
\ No newline at end of file
diff --git a/Cis.Application/Cm/Service/CmMarkLabelService.cs b/Cis.Application/Cm/Service/CmMarkLabelService.cs
new file mode 100644
index 0000000..3df7e79
--- /dev/null
+++ b/Cis.Application/Cm/Service/CmMarkLabelService.cs
@@ -0,0 +1,55 @@
+using Newtonsoft.Json.Linq;
+
+namespace Cis.Application.Cm;
+
+///
+/// 标记标签服务
+///
+[ApiDescriptionSettings(CmInfo.GroupName, Order = CmInfo.GroupOrder)]
+public class CmMarkLabelService : IDynamicApiController, ITransient
+{
+ private readonly SqlSugarRepository _cmMarkLabelRep;
+
+ public CmMarkLabelService(SqlSugarRepository cmMarkLabelRep)
+ {
+ _cmMarkLabelRep = cmMarkLabelRep;
+ }
+
+ public async Task Get(long id)
+ {
+ CmMarkLabel entity = await _cmMarkLabelRep.GetByIdAsync(id);
+ return entity;
+ }
+
+ public async Task> GetList(string queryJson = "")
+ {
+ JObject queryObj = queryJson.ToJObject();
+ List list = await _cmMarkLabelRep.AsQueryable()
+ .ToListAsync();
+ return list;
+ }
+
+ public async Task> GetPageList(string queryJson, string pagination)
+ {
+ Pagination pageObj = pagination.ToObject();
+ JObject queryObj = queryJson.ToJObject();
+ List list = await _cmMarkLabelRep.AsQueryable()
+ .ToPageListAsync(pageObj.Index, pageObj.Size);
+ return list;
+ }
+
+ public async Task Add(CmMarkLabel entity)
+ {
+ await _cmMarkLabelRep.InsertAsync(entity);
+ }
+
+ public async Task Update(CmMarkLabel entity)
+ {
+ await _cmMarkLabelRep.UpdateAsync(entity);
+ }
+
+ public async Task Delete(CmMarkLabel entity)
+ {
+ await _cmMarkLabelRep.DeleteAsync(entity);
+ }
+}
\ No newline at end of file
diff --git a/Cis.Application/Core/Algo/MarkSearcherBase.cs b/Cis.Application/Core/Algo/MarkSearcherBase.cs
new file mode 100644
index 0000000..033a34b
--- /dev/null
+++ b/Cis.Application/Core/Algo/MarkSearcherBase.cs
@@ -0,0 +1,6 @@
+namespace Cis.Application.Core;
+
+public class MarkSearcherBase
+{
+
+}
\ No newline at end of file
diff --git a/Cis.Application/Core/Api/IPtzApi.cs b/Cis.Application/Core/Api/IPtzApi.cs
new file mode 100644
index 0000000..e3461e5
--- /dev/null
+++ b/Cis.Application/Core/Api/IPtzApi.cs
@@ -0,0 +1,9 @@
+namespace Cis.Application.Core;
+
+///
+/// Ptz Api 接口
+///
+public interface IPtzApi
+{
+
+}
\ No newline at end of file
diff --git a/Cis.Application/Core/Api/PtzServerApi.cs b/Cis.Application/Core/Api/PtzServerApi.cs
new file mode 100644
index 0000000..4f65872
--- /dev/null
+++ b/Cis.Application/Core/Api/PtzServerApi.cs
@@ -0,0 +1,198 @@
+using System.Net.Sockets;
+using System.Runtime.InteropServices;
+
+namespace Cis.Application.Core;
+
+///
+/// Ptz Api
+///
+public class PtzServerApi : IPtzApi, ISingleton
+{
+ #region Attr
+
+ private TcpClient _tcpClient { get; set; }
+
+ private NetworkStream _stream { get; set; }
+
+ #endregion Attr
+
+ public PtzServerApi()
+ {
+ PtzServerOptions options = App.GetOptions();
+ _tcpClient = new TcpClient(options.Ip, options.Port);
+ //创建一个 networkstream 用来写入和读取数据
+ _stream = _tcpClient.GetStream();
+ }
+
+ public RequestRealControl GetPtzInfo(int cameraId)
+ {
+ RequestRealControl realControl = new();
+ try
+ {
+ string recieve_string = string.Empty;
+ realControl.token = 666;
+
+ realControl.CameraInfo.cameraid = cameraId;
+ realControl.Status = true;
+ realControl.realControlType = RealControlType.PTZINFO_GET_;
+ byte[] data = StructToByte(realControl);
+ _stream.Write(data, 0, data.Length);
+
+ byte[] recieve_byte = new byte[_tcpClient.ReceiveBufferSize];
+ _stream.Read(recieve_byte, 0, (int)_tcpClient.ReceiveBufferSize);
+ //stream.BeginRead(recieve_byte, 0, (int)tcp_client.ReceiveBufferSize,EndRead, stream);
+ realControl = (RequestRealControl)BytetoStruct(recieve_byte, typeof(RequestRealControl));
+ if (realControl.PTZPositionInfo.FT < 0)
+ {
+ realControl.PTZPositionInfo.FT = 3600 + realControl.PTZPositionInfo.FT;
+ }
+ }
+ catch (Exception)
+ {
+ realControl = default;
+ }
+ return realControl;
+ }
+
+ public static byte[] StructToByte(object structObj)
+ {
+ //获取结构体大小
+ int size = Marshal.SizeOf(structObj);
+
+ byte[] data = new byte[size];
+
+ //分配内存空间
+ IntPtr structPtr = Marshal.AllocHGlobal(size);
+ // 将结构体数据复制到内存空间
+ Marshal.StructureToPtr(structObj, structPtr, false);
+ // 将内存空间的数据拷贝到byte数组
+ Marshal.Copy(structPtr, data, 0, size);
+ //释放内存
+ Marshal.FreeHGlobal(structPtr);
+ return data;
+ }
+
+ public static object BytetoStruct(byte[] bytes, Type type)
+ {
+ object obj = new object();
+ try
+ {
+ byte[] temp = bytes;
+ // 获取结构体大小
+ int size = Marshal.SizeOf(type);
+ if (size > bytes.Length)
+ return null;
+ // 分配结构体内存空间
+ IntPtr structPtr = Marshal.AllocHGlobal(size);
+ // 将byte数组内容拷贝到内存中
+ Marshal.Copy(temp, 0, structPtr, size);
+
+ // 将内存空间转化为目标结构体
+ obj = Marshal.PtrToStructure(structPtr, type);
+ //释放内存
+ Marshal.FreeHGlobal(structPtr);
+ }
+ catch (Exception)
+ {
+ }
+ return obj;
+ }
+
+}
+
+#region 与ptz服务交互使用结构体
+
+//----------------------------------------------------------------------------------------
+// 与ptz服务交互使用结构体
+//----------------------------------------------------------------------------------------
+//注意这个属性不能少
+[StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
+public struct RequestRealControl
+{
+ public int token;
+
+ public CameraInfo CameraInfo;
+
+ public RealControlType realControlType;
+
+ //请求时 状态 true:开始;false:结束 答复时:true:成功;其他:失败
+ public bool Status;
+
+ public PresentInfo PresentInfo;
+
+ public PTZPosInfo PTZPositionInfo;
+ //int数组,SizeConst表示数组的个数,在转换成
+ //byte数组前必须先初始化数组,再使用,初始化
+ //的数组长度必须和SizeConst一致,例test = new int[6];
+ //[MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
+ //public int[] test;
+}
+
+[StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 4)]
+public struct CameraInfo
+{
+ public int cameraid;
+
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 40)]
+ public char[] ip;
+
+ public ushort port;
+
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 80)]
+ private char[] user;
+
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 80)]
+ private char[] password;
+}
+
+[StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 4)]
+public struct PresentInfo
+{
+ public int presentNo;//预置位编号
+
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
+ private char[] PresentName; // 预置位名称
+}
+
+[StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 4)]
+public struct PTZPosInfo
+{
+ public int FP;//p信息
+ public int FT;//T信息
+ public int FZ;//Z信息
+ public int TitlePosMin;//描述点垂直参数min
+ public int ZoomPosMin;//描述点变倍参数min
+
+ public float FHorWidth;//水平宽度 精确到小数点后两位 *10000
+ public float FVerWidth;//垂直宽度 精确到小数点后两位 *10000
+ public float FFold;//zoom=1没变时的焦距 精确到小数点后两位 *100
+
+ public int CameraType;
+}
+
+public enum RealControlType
+{
+ MOVE_UP_ = 1,
+ MOVE_DOWN_,
+ MOVE_LEFT_,
+ MOVE_RIGHT_,
+ MOVE_LEFTUP_,
+ MOVE_LEFTDOWN_,
+ MOVE_RIGHTUP_,
+ MOVE_RIGHTDOWN_,
+
+ ZOOM_IN_,
+ ZOOM_OUT_,
+ FOCUS_NEAR_,
+ FOCUS_FAR_,
+ IRIS_OPEN_,
+ IRIS_CLOSE_,
+
+ PRESET_SET_,
+ PRESET_CALL_,
+
+ PTZINFO_GET_,
+ PTZINFO_SET_
+}
+
+#endregion 与ptz服务交互使用结构体
\ No newline at end of file
diff --git a/Cis.Application/Core/Center/CameraDataCenter.cs b/Cis.Application/Core/Center/CameraDataCenter.cs
new file mode 100644
index 0000000..5dc864b
--- /dev/null
+++ b/Cis.Application/Core/Center/CameraDataCenter.cs
@@ -0,0 +1,113 @@
+using Cis.Application.Cb;
+using Cis.Application.Cm;
+using Cis.Application.Tb;
+using System.Collections.Concurrent;
+
+namespace Cis.Application.Core;
+
+public class CameraDataCenter
+{
+ #region Attr
+
+ private Thread _thread { get; set; }
+ private List _tbPtzCameraList { get; set; }
+ private ConcurrentDictionary _cameraPtzInfoDict { get; set; }
+
+ private readonly SqlSugarRepository _cbCameraRep;
+ private readonly SqlSugarRepository _cmMarkLableRep;
+ private readonly SqlSugarRepository _tbPtzCameraRep;
+ private readonly PtzServerApi _ptzServerApi;
+
+ #endregion Attr
+
+ public CameraDataCenter()
+ {
+ _cbCameraRep = App.GetService>();
+ _cmMarkLableRep = App.GetService>();
+ _tbPtzCameraRep = App.GetService>();
+ _ptzServerApi = App.GetService();
+ Init();
+ }
+
+ private void Init()
+ {
+ // 初始化 tbPtzCameraList
+ _tbPtzCameraList = _tbPtzCameraRep.GetList();
+ // 根据 Ip 去重
+ _tbPtzCameraList = _tbPtzCameraList.Where((a, i) => _tbPtzCameraList.FindIndex(b => b.Ip == a.Ip) == i).ToList();
+
+ // 初始化 ptzInfoDict
+ _cameraPtzInfoDict = new ConcurrentDictionary();
+
+ // 初始化 thread
+ _thread = new Thread(WorkLoop)
+ {
+ IsBackground = true// 设置后台线程
+ };
+ _thread.Start();
+ }
+
+ private void LazyInit()
+ {
+ // 初始化 tbPtzCameraList
+ _tbPtzCameraList = new();
+
+ // 初始化 ptzInfoDict
+ _cameraPtzInfoDict = new ConcurrentDictionary();
+
+ // 初始化 thread
+ _thread = new Thread(WorkLoop)
+ {
+ IsBackground = true// 设置后台线程
+ };
+ _thread.Start();
+ }
+
+ #region Loop
+
+ private void WorkLoop()
+ {
+ while (true)
+ {
+ GetPtzInfoByApi();
+ Thread.Sleep(10000);
+ }
+ }
+
+ private void GetPtzInfoByApi()
+ {
+ foreach (TbPtzCamera item in _tbPtzCameraList)
+ {
+ RequestRealControl rrc = _ptzServerApi.GetPtzInfo(item.CameraId);
+ CameraCalcInfo ptzInfo = new()
+ {
+ Pan = rrc.PTZPositionInfo.FP,
+ Tilt = rrc.PTZPositionInfo.FT,
+ Zoom = rrc.PTZPositionInfo.FZ
+ };
+ _cameraPtzInfoDict[item.Ip] = ptzInfo;
+ }
+ }
+
+ private void Calc()
+ {
+ }
+
+ #endregion Loop
+
+ #region external call
+
+ public bool GetCamera(string ip)
+ {
+ return false;
+ }
+
+ public bool ActiveCamera(string ip)
+ {
+
+
+ return false;
+ }
+
+ #endregion external call
+}
\ No newline at end of file
diff --git a/Cis.Application/Core/Common/Options.cs b/Cis.Application/Core/Common/Options.cs
new file mode 100644
index 0000000..c121c2a
--- /dev/null
+++ b/Cis.Application/Core/Common/Options.cs
@@ -0,0 +1,22 @@
+namespace Cis.Application.Core;
+
+///
+/// PtzServer选项
+///
+public class PtzServerOptions : IConfigurableOptions
+{
+ ///
+ /// 服务类别
+ ///
+ public string Type { get; set; }
+
+ ///
+ /// 服务IP
+ ///
+ public string Ip { get; set; }
+
+ ///
+ /// 服务端口
+ ///
+ public int Port { get; set; }
+}
\ No newline at end of file
diff --git a/Cis.Application/Core/Entity/CameraCalcInfo.cs b/Cis.Application/Core/Entity/CameraCalcInfo.cs
new file mode 100644
index 0000000..e34c9b6
--- /dev/null
+++ b/Cis.Application/Core/Entity/CameraCalcInfo.cs
@@ -0,0 +1,32 @@
+namespace Cis.Application.Core;
+
+///
+/// 相机 Ptz 信息
+///
+public class CameraCalcInfo
+{
+ ///
+ /// 图像的宽度
+ ///
+ public int ImageWidth { get; set; } = 1920;
+
+ ///
+ /// 图像的宽度
+ ///
+ public int ImageHeight { get; set; } = 1080;
+
+ ///
+ /// Pan
+ ///
+ public double Pan { get; set; }
+
+ ///
+ /// Tilt
+ ///
+ public double Tilt { get; set; }
+
+ ///
+ /// Zoom
+ ///
+ public double Zoom { get; set; }
+}
\ No newline at end of file
diff --git a/Cis.Application/Core/Service/MarkSearchService.cs b/Cis.Application/Core/Service/MarkSearchService.cs
new file mode 100644
index 0000000..0432a26
--- /dev/null
+++ b/Cis.Application/Core/Service/MarkSearchService.cs
@@ -0,0 +1,22 @@
+using Cis.Application.Cm;
+
+namespace Cis.Application.Core;
+
+[ApiDescriptionSettings(CmInfo.GroupName, Order = CmInfo.GroupOrder)]
+public class MarkSearchService : IDynamicApiController, ITransient
+{
+ #region Attr
+
+ private CameraDataCenter _cameraDataCenter { get; set; }
+
+ #endregion Attr
+
+ public MarkSearchService(CameraDataCenter cameraDataCenter)
+ {
+ _cameraDataCenter = cameraDataCenter;
+ }
+
+ public void ActivateCamera()
+ {
+ }
+}
\ No newline at end of file
diff --git a/Cis.Application/GlobalUsings.cs b/Cis.Application/GlobalUsings.cs
index a7568c4..76b15eb 100644
--- a/Cis.Application/GlobalUsings.cs
+++ b/Cis.Application/GlobalUsings.cs
@@ -1,5 +1,6 @@
global using Cis.Core;
global using Furion;
+global using Furion.ConfigurableOptions;
global using Furion.DependencyInjection;
global using Furion.DynamicApiController;
global using Microsoft.AspNetCore.Mvc;
diff --git a/Cis.Application/Startup.cs b/Cis.Application/Startup.cs
index d88de9c..19a7348 100644
--- a/Cis.Application/Startup.cs
+++ b/Cis.Application/Startup.cs
@@ -1,4 +1,5 @@
-using Microsoft.AspNetCore.Builder;
+using Cis.Application.Core;
+using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
@@ -12,8 +13,11 @@ public class Startup : AppStartup
///
///
public void ConfigureServices(IServiceCollection services)
- {
- }
+ {
+ services.AddConfigurableOptions();
+
+ services.AddSingleton(new CameraDataCenter());
+ }
///
/// 配置应用请求处理管道
@@ -21,6 +25,6 @@ public class Startup : AppStartup
///
///
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
- {
- }
+ {
+ }
}
\ No newline at end of file
diff --git a/Cis.Application/Sys/Common/SysInfo.cs b/Cis.Application/Sys/Common/SysInfo.cs
index 3ffb68d..dbeea07 100644
--- a/Cis.Application/Sys/Common/SysInfo.cs
+++ b/Cis.Application/Sys/Common/SysInfo.cs
@@ -22,7 +22,7 @@ public class SysInfo
#region Database Info
///
- /// 数据库名
+ /// 数据库标识
///
public const string DbName = SqlSugarConst.DefaultConfigId;
diff --git a/Cis.Application/Sys/Service/SysDictDataService.cs b/Cis.Application/Sys/Service/SysDictDataService.cs
index 0ac8c68..6042140 100644
--- a/Cis.Application/Sys/Service/SysDictDataService.cs
+++ b/Cis.Application/Sys/Service/SysDictDataService.cs
@@ -1,4 +1,6 @@
-namespace Cis.Application.Sys;
+using Newtonsoft.Json.Linq;
+
+namespace Cis.Application.Sys;
///
/// 系统字典值服务
@@ -13,4 +15,41 @@ public class SysDictDataService : IDynamicApiController, ITransient
_sysDictDataRep = sysDictDataRep;
}
+ public async Task Get(long id)
+ {
+ SysDictData entity = await _sysDictDataRep.GetByIdAsync(id);
+ return entity;
+ }
+
+ public async Task> GetList(string queryJson)
+ {
+ JObject queryObj = queryJson.ToJObject();
+ List list = await _sysDictDataRep.AsQueryable()
+ .ToListAsync();
+ return list;
+ }
+
+ public async Task> GetPageList(string queryJson, string pagination)
+ {
+ Pagination pageObj = pagination.ToObject();
+ JObject queryObj = queryJson.ToJObject();
+ List list = await _sysDictDataRep.AsQueryable()
+ .ToPageListAsync(pageObj.Index, pageObj.Size);
+ return list;
+ }
+
+ public async Task Add(SysDictData entity)
+ {
+ await _sysDictDataRep.InsertAsync(entity);
+ }
+
+ public async Task Update(SysDictData entity)
+ {
+ await _sysDictDataRep.UpdateAsync(entity);
+ }
+
+ public async Task Delete(SysDictData entity)
+ {
+ await _sysDictDataRep.DeleteAsync(entity);
+ }
}
\ No newline at end of file
diff --git a/Cis.Application/Sys/Service/SysDictTypeService.cs b/Cis.Application/Sys/Service/SysDictTypeService.cs
index 74c1b17..4c9763b 100644
--- a/Cis.Application/Sys/Service/SysDictTypeService.cs
+++ b/Cis.Application/Sys/Service/SysDictTypeService.cs
@@ -1,4 +1,7 @@
-namespace Cis.Application.Sys;
+using Cis.Application.Cm;
+using Newtonsoft.Json.Linq;
+
+namespace Cis.Application.Sys;
///
/// 系统字典类型服务
@@ -12,4 +15,42 @@ public class SysDictTypeService : IDynamicApiController, ITransient
{
_sysDictTypeRep = sysDictTypeRep;
}
+
+ public async Task Get(long id)
+ {
+ SysDictType entity = await _sysDictTypeRep.GetByIdAsync(id);
+ return entity;
+ }
+
+ public async Task> GetList(string queryJson)
+ {
+ JObject queryObj = queryJson.ToJObject();
+ List list = await _sysDictTypeRep.AsQueryable()
+ .ToListAsync();
+ return list;
+ }
+
+ public async Task> GetPageList(string queryJson, string pagination)
+ {
+ Pagination pageObj = pagination.ToObject();
+ JObject queryObj = queryJson.ToJObject();
+ List list = await _sysDictTypeRep.AsQueryable()
+ .ToPageListAsync(pageObj.Index, pageObj.Size);
+ return list;
+ }
+
+ public async Task Add(SysDictType entity)
+ {
+ await _sysDictTypeRep.InsertAsync(entity);
+ }
+
+ public async Task Update(SysDictType entity)
+ {
+ await _sysDictTypeRep.UpdateAsync(entity);
+ }
+
+ public async Task Delete(SysDictType entity)
+ {
+ await _sysDictTypeRep.DeleteAsync(entity);
+ }
}
\ No newline at end of file
diff --git a/Cis.Application/Tb/Common/TbInfo.cs b/Cis.Application/Tb/Common/TbInfo.cs
new file mode 100644
index 0000000..135f94d
--- /dev/null
+++ b/Cis.Application/Tb/Common/TbInfo.cs
@@ -0,0 +1,29 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Cis.Application.Tb;
+
+public class TbInfo
+{
+ #region Database Info
+
+ ///
+ /// 数据库标识
+ ///
+ public const string DbName = "serverdb";
+
+ #endregion Database Info
+
+ #region Table Info
+
+ ///
+ /// TbPtzCamera 表名
+ ///
+ public const string TbPtzCameraTbName = "tb_ptzcamera";
+
+ #endregion Table Info
+}
+
diff --git a/Cis.Application/Tb/Entity/TbPtzCamera.cs b/Cis.Application/Tb/Entity/TbPtzCamera.cs
new file mode 100644
index 0000000..6f75ea8
--- /dev/null
+++ b/Cis.Application/Tb/Entity/TbPtzCamera.cs
@@ -0,0 +1,28 @@
+namespace Cis.Application.Tb;
+
+[SugarTable(TbInfo.TbPtzCameraTbName)]
+[Tenant(TbInfo.DbName)]
+public class TbPtzCamera
+{
+ public int Id { get; set; }
+
+ public int Type { get; set; }
+
+ public string Ip { get; set; }
+
+ public int Port { get; set; }
+
+ public string User { get; set; }
+
+ public string Pass { get; set; }
+
+ public int CameraId { get; set; }
+
+ public double PanPosition { get; set; }
+
+ public double TitlePosition { get; set; }
+
+ public double ZoomPosition { get; set; }
+
+ public byte Request { get; set; }
+}
\ No newline at end of file
diff --git a/Cis.Application/Tb/Service/TbPtzCameraService.cs b/Cis.Application/Tb/Service/TbPtzCameraService.cs
new file mode 100644
index 0000000..03cb5bf
--- /dev/null
+++ b/Cis.Application/Tb/Service/TbPtzCameraService.cs
@@ -0,0 +1,51 @@
+using Newtonsoft.Json.Linq;
+
+namespace Cis.Application.Tb;
+
+public class TbPtzCameraService : ITransient
+{
+ private readonly SqlSugarRepository _tbPtzCameraRep;
+
+ public TbPtzCameraService(SqlSugarRepository tbPtzCameraRep)
+ {
+ _tbPtzCameraRep = tbPtzCameraRep;
+ }
+
+ public async Task Get(int id)
+ {
+ TbPtzCamera entity = await _tbPtzCameraRep.GetByIdAsync(id);
+ return entity;
+ }
+
+ public async Task> GetList(string queryJson = "")
+ {
+ JObject queryObj = !string.IsNullOrEmpty(queryJson) ? queryJson.ToJObject():default;
+ List list = await _tbPtzCameraRep.AsQueryable()
+ .ToListAsync();
+ return list;
+ }
+
+ public async Task> GetPageList(string pagination, string queryJson = "")
+ {
+ Pagination pageObj = pagination.ToObject();
+ JObject queryObj = queryJson.ToJObject();
+ List list = await _tbPtzCameraRep.AsQueryable()
+ .ToPageListAsync(pageObj.Index, pageObj.Size);
+ return list;
+ }
+
+ public async Task Add(TbPtzCamera entity)
+ {
+ await _tbPtzCameraRep.InsertAsync(entity);
+ }
+
+ public async Task Update(TbPtzCamera entity)
+ {
+ await _tbPtzCameraRep.UpdateAsync(entity);
+ }
+
+ public async Task Delete(TbPtzCamera entity)
+ {
+ await _tbPtzCameraRep.DeleteAsync(entity);
+ }
+}
\ No newline at end of file
diff --git a/Cis.Core/Cis.Core.csproj b/Cis.Core/Cis.Core.csproj
index 6530dd8..27ffbae 100644
--- a/Cis.Core/Cis.Core.csproj
+++ b/Cis.Core/Cis.Core.csproj
@@ -22,11 +22,16 @@
+
+
+
+
+
diff --git a/Cis.Core/Cis.Core.xml b/Cis.Core/Cis.Core.xml
index 310f220..30c9dce 100644
--- a/Cis.Core/Cis.Core.xml
+++ b/Cis.Core/Cis.Core.xml
@@ -110,6 +110,90 @@
页码数
+
+
+ 全局规范化结果
+
+
+
+
+ 异常返回值
+
+
+
+
+
+
+
+ 成功返回值
+
+
+
+
+
+
+
+ 验证失败返回值
+
+
+
+
+
+
+
+ 特定状态码返回值
+
+
+
+
+
+
+
+
+ 返回 RESTful 风格结果集
+
+
+
+
+
+
+
+
+
+ 全局返回结果
+
+
+
+
+
+ 状态码
+
+
+
+
+ 类型success、warning、error
+
+
+
+
+ 错误信息
+
+
+
+
+ 数据
+
+
+
+
+ 附加数据
+
+
+
+
+ 时间戳
+
+
缓存类型枚举
@@ -397,89 +481,5 @@
-
-
- 全局规范化结果
-
-
-
-
- 异常返回值
-
-
-
-
-
-
-
- 成功返回值
-
-
-
-
-
-
-
- 验证失败返回值
-
-
-
-
-
-
-
- 特定状态码返回值
-
-
-
-
-
-
-
-
- 返回 RESTful 风格结果集
-
-
-
-
-
-
-
-
-
- 全局返回结果
-
-
-
-
-
- 状态码
-
-
-
-
- 类型success、warning、error
-
-
-
-
- 错误信息
-
-
-
-
- 数据
-
-
-
-
- 附加数据
-
-
-
-
- 时间戳
-
-
diff --git a/Cis.Core/CoreConfig.json b/Cis.Core/CoreConfig.json
index b6deb2e..471e3b9 100644
--- a/Cis.Core/CoreConfig.json
+++ b/Cis.Core/CoreConfig.json
@@ -10,7 +10,13 @@
//"ConnectionString": "DataSource=./cis.db",
//"DbType": "PostgreSQL",
//"ConnectionString": "HOST=127.0.0.1;PORT=5432;USER ID=pgsql;PASSWORD=123456;DATABASE=cis;",
- "EnableInitDb": false, // 启用库表初始化
+ "EnableInitDb": false // 启用库表初始化
+ },
+ {
+ "ConfigId": "serverdb",
+ "DbType": "MySql",
+ "ConnectionString": "Data Source=127.0.0.1;port=3306;User ID=root;Password=123456;Database=serverdb;pooling=true;sslmode=none;CharSet=utf8;",
+ "EnableInitDb": false // 启用库表初始化
}
]
},
@@ -18,12 +24,17 @@
"CacheType": "Redis", // Memory、Redis
"RedisConnectionString": "127.0.0.1:6379;password=123456;db=2"
},
- "SnowId": {
- "WorkerId": 5 // 取值范围0~63,默认1
+ "PTZServer": {
+ "Type": "",
+ "Ip": "127.0.0.1",
+ "Port": "7022"
+ },
+ "AppSettings": {
+ "InjectSpecificationDocument": true // 生产环境是否开启Swagger
},
"SpecificationDocumentSettings": {
- "DocumentTitle": "Swagger",//默认标题
- "DefaultGroupName": "Default"//默认分组名称
+ "DocumentTitle": "Swagger", //默认标题
+ "DefaultGroupName": "Default" //默认分组名称
},
"DynamicApiControllerSettings": {
"DefaultRoutePrefix": "api", //默认路由前缀
@@ -33,8 +44,30 @@
"AsLowerCamelCase": true, //启用小驼峰命名(首字母小写)
"UrlParameterization": true // 方法参数
},
- "AppSettings": {
- "InjectSpecificationDocument": true // 生产环境是否开启Swagger
+ "Logging": {
+ "LogLevel": {
+ "Default": "Information",
+ "Microsoft.AspNetCore": "Warning"
+ },
+ "File": {
+ "Enabled": true, // 启用文件日志
+ "FileName": "logs/{0:yyyyMMdd}_{1}.log", // 日志文件
+ "Append": true, // 追加覆盖
+ // "MinimumLevel": "Information", // 日志级别
+ "FileSizeLimitBytes": 10485760, // 10M=10*1024*1024
+ "MaxRollingFiles": 30 // 只保留30个文件
+ },
+ "Monitor": {
+ "GlobalEnabled": true, // 启用全局拦截日志
+ "IncludeOfMethods": [], // 拦截特定方法,当GlobalEnabled=false有效
+ "ExcludeOfMethods": [], // 排除特定方法,当GlobalEnabled=true有效
+ "BahLogLevel": "Information", // Oops.Oh 和 Oops.Bah 业务日志输出级别
+ "WithReturnValue": true, // 配置是否包含返回值,默认true
+ "ReturnValueThreshold": 0 // 配置返回值字符串阈值,默认0全量输出
+ }
+ },
+ "SnowId": {
+ "WorkerId": 5 // 取值范围0~63,默认1
},
"CorsAccessorSettings": {
"WithExposedHeaders": [
@@ -43,4 +76,4 @@
"environment"
]
}
-}
+}
\ No newline at end of file
diff --git a/Cis.Core/Util/RespParamProvider.cs b/Cis.Core/Entity/RespParamProvider.cs
similarity index 100%
rename from Cis.Core/Util/RespParamProvider.cs
rename to Cis.Core/Entity/RespParamProvider.cs
diff --git a/Cis.Web.Core/Startup.cs b/Cis.Web.Core/Startup.cs
index 6f1206e..5248263 100644
--- a/Cis.Web.Core/Startup.cs
+++ b/Cis.Web.Core/Startup.cs
@@ -4,12 +4,16 @@ using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
+using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
+using System;
+using System.IO;
using Yitter.IdGenerator;
namespace Cis.Web.Core;
+[AppStartup(1000)]
public class Startup : AppStartup
{
///
@@ -39,12 +43,30 @@ public class Startup : AppStartup
.AddNewtonsoftJson(options =>
{
options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); // 首字母小写(驼峰样式)
+ options.SerializerSettings.DateTimeZoneHandling = DateTimeZoneHandling.Local;// 设置本地时区
options.SerializerSettings.DateFormatString = "yyyy-MM-dd HH:mm:ss"; // 时间格式化
options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore; // 忽略循环引用
options.SerializerSettings.NullValueHandling = NullValueHandling.Ignore; // 忽略空值
})
.AddInjectWithUnifyResult();
+ // 日志记录
+ if (App.GetConfig("Logging:File:Enabled")) // 日志写入文件
+ {
+ Array.ForEach(new[] { LogLevel.Information, LogLevel.Warning, LogLevel.Error }, logLevel =>
+ {
+ services.AddFileLogging(options =>
+ {
+ options.FileNameRule = fileName => string.Format(fileName, DateTime.Now, logLevel.ToString()); // 每天创建一个文件
+ options.WriteFilter = logMsg => logMsg.LogLevel == logLevel; // 日志级别
+ options.HandleWriteError = (writeError) => // 写入失败时启用备用文件
+ {
+ writeError.UseRollbackFileName(Path.GetFileNameWithoutExtension(writeError.CurrentFileName) + "-oops" + Path.GetExtension(writeError.CurrentFileName));
+ };
+ });
+ });
+ }
+
// 配置雪花Id算法机器码
YitIdHelper.SetIdGenerator(new IdGeneratorOptions
{
diff --git a/Cis.Web.Entry/Cis.Web.Entry.csproj b/Cis.Web.Entry/Cis.Web.Entry.csproj
index 2ddaf1d..6392984 100644
--- a/Cis.Web.Entry/Cis.Web.Entry.csproj
+++ b/Cis.Web.Entry/Cis.Web.Entry.csproj
@@ -10,8 +10,4 @@
-
-
-
-
diff --git a/Cis.Web.Entry/wwwroot/images/logo.png b/Cis.Web.Entry/wwwroot/images/logo.png
new file mode 100644
index 0000000..eff5511
Binary files /dev/null and b/Cis.Web.Entry/wwwroot/images/logo.png differ