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