diff --git a/Common/LayerData.cs b/Common/LayerData.cs new file mode 100644 index 0000000..1557348 --- /dev/null +++ b/Common/LayerData.cs @@ -0,0 +1,63 @@ +using System.Text.Json; +using System.Text.Json.Nodes; +using OMS.NET.DbClass; + +namespace OMS.NET.Common +{ + public class LayerData + { + public string? TemplateId { get; set; } + public long LayerId { get; set; } + public bool HasChange { get; set; } = false; + public string Type { get; set; } + public JsonNode? Members { get; set; } + public JsonNode? Structure { get; set; } + public int Phase { get; set; } = 1; + + public LayerData(long layerId, string type) + { + LayerId = layerId; + Type = type; + } + + public LayerData(string? templateId, MapLayer layer) + { + TemplateId = templateId; + LayerId = layer.Id; + Type = layer.Type; + Members = (layer.Type == "order") ? JsonNode.Parse(layer.Members) : JsonNode.Parse(Util.Base64ToJson(layer.Members)); + Structure = string.IsNullOrEmpty(layer.Structure) ? null : JsonNode.Parse(Util.Base64ToJson(layer.Structure)); + Phase = layer.Phase; + } + + public void AppendElement(long itemId, string ItemType) + { + if (this.Type == "order") + { + GlobalArea.Log.Error($"order图层不能添加{ItemType}元素"); + return; + } + if (this.Members![itemId.ToString()] == null) + { + this.Members![itemId.ToString()] = ItemType; + this.Structure!.AsArray().Add(itemId); + this.HasChange = true; + //上传图层到数据库 + MapLayer mapLayer = ConvertToMapLayer(); + MapLayer.Update(mapLayer); + } + } + + public MapLayer ConvertToMapLayer() + { + return new MapLayer() + { + Id = this.LayerId, + Type = this.Type, + Members = (this.Type == "order") ? this.Members!.ToString() : Util.JsonToBase64(this.Members!.ToString()), + Structure = (this.Structure == null) ? "" : Util.JsonToBase64(this.Structure!.ToString()), + Phase = this.Phase + }; + } + } +} \ No newline at end of file diff --git a/Common/Utils.cs b/Common/Utils.cs index 0ff551b..3d114c9 100644 --- a/Common/Utils.cs +++ b/Common/Utils.cs @@ -1,5 +1,6 @@ using System.Text; using System.Text.Json; +using System.Text.Json.Nodes; using System.Text.Json.Serialization; namespace OMS.NET.Common @@ -22,49 +23,49 @@ namespace OMS.NET.Common PropertyNameCaseInsensitive = true,//属性名忽略大小写 }; - public static string DetailsToBase64(object obj) + public static string ObjToBase64(object obj) { string utf8 = JsonSerializer.Serialize(obj, options); return Convert.ToBase64String(Encoding.UTF8.GetBytes(utf8)); } - //=========================================================== - public static List PointsFromBase64(string base64) + public static string JsonToBase64(string json) { - string utf8 = Encoding.UTF8.GetString(Convert.FromBase64String(base64)); - return JsonSerializer.Deserialize>(utf8, options) ?? new List(); + return Convert.ToBase64String(Encoding.UTF8.GetBytes(json)); } - public static Point? PointFromBase64(string base64) + public static string Base64ToJson(string base64) { - string utf8 = Encoding.UTF8.GetString(Convert.FromBase64String(base64)); - return JsonSerializer.Deserialize(utf8, options); + return Encoding.UTF8.GetString(Convert.FromBase64String(base64)); } + // public static JsonNode? JsonNodeFromJson(string json) + // { + // return JsonNode.Parse(json); + // } + //=========================================================== - public static List> DetailsFromBase64(string base64) + + public static List PointsFromBase64(string base64) { - string utf8 = Encoding.UTF8.GetString(Convert.FromBase64String(base64)); - return JsonSerializer.Deserialize>>(utf8, options) ?? new List>(); + string utf8 = Base64ToJson(base64); + return PointsFromJson(utf8); } - public static Dictionary MembersFromBase64(string base64) + public static List PointsFromJson(string json) { - string utf8 = Encoding.UTF8.GetString(Convert.FromBase64String(base64)); - return JsonSerializer.Deserialize>(utf8, options) ?? new Dictionary(); + return JsonSerializer.Deserialize>(json, options) ?? new List(); } - public static List OrderMembersFromBase64(string base64) + public static Point PointFromBase64(string base64) { - //string utf8 = Encoding.UTF8.GetString(Convert.FromBase64String(base64)); - return JsonSerializer.Deserialize>(base64, options) ?? new List(); + string utf8 = Base64ToJson(base64); + return PointFromJson(utf8); } - public static List StructuresFromBase64(string base64) + public static Point PointFromJson(string json) { - string utf8 = Encoding.UTF8.GetString(Convert.FromBase64String(base64)); - return JsonSerializer.Deserialize>(utf8, options) ?? new List(); + return JsonSerializer.Deserialize(json, options) ?? throw new Exception("转化point类型失败:" + json); } - } } \ No newline at end of file diff --git a/Common/Validations.cs b/Common/Validations.cs new file mode 100644 index 0000000..88993f4 --- /dev/null +++ b/Common/Validations.cs @@ -0,0 +1,19 @@ +using System.Text.RegularExpressions; + +namespace OMS.NET.Common +{ + public static class Validations + { + /// + /// 验证颜色值是否有效 + /// + /// + /// + public static bool IsHexColor(string color) + { + // Regex for hex color code (with or without #) + var hexColorRegex = new Regex(@"^#?[0-9A-Fa-f]{6}$"); + return hexColorRegex.IsMatch(color); + } + } +} \ No newline at end of file diff --git a/DbClass/MapData.cs b/DbClass/MapData.cs index a0d11f9..244674c 100644 --- a/DbClass/MapData.cs +++ b/DbClass/MapData.cs @@ -21,7 +21,7 @@ namespace OMS.NET.DbClass public MapData() { - this.Id = 0; + this.Id = -1; this.Type = ""; this.Points = ""; this.Point = ""; diff --git a/GlobalArea.cs b/GlobalArea.cs index 31cd056..3a1c6af 100644 --- a/GlobalArea.cs +++ b/GlobalArea.cs @@ -1,6 +1,7 @@ using System.Net; using System.Security.Cryptography; using System.Text; +using System.Text.Json; using OMS.NET.Common; using OMS.NET.DbClass; @@ -78,11 +79,17 @@ namespace OMS.NET } } - // public static string GetLoginEmailByID(string wsid){ - // lock (_UserConnectListLock){ - // return _UserConnectList.First(u => u.ID == wsid).UserEmail!; - // } - // } + /// + /// 通过wsid查询连接的Email信息 + /// + /// Email信息,可能是空字符串 + public static string GetLoginEmailByID(string wsid) + { + lock (_UserConnectListLock) + { + return _UserConnectList.First(u => u.ID == wsid).UserEmail!; + } + } public static bool LoginCheckByEmail(string email) { @@ -280,6 +287,46 @@ namespace OMS.NET } } + private static readonly List _LayerDataList = new(); + private static readonly object _LayerDataListLock = new(); + + /// + /// 从数据库中构建layerid 和 templateid的对应关系 + /// + public static void BuildLayerData() + { + List mapLayer = MapLayer.GetMapLayerList(); + lock (_LayerDataListLock) + { + foreach (MapLayer layer in mapLayer) + { + LayerData layerData = new(null, layer); + if (layerData.Type != "order") + { + string temId = layerData.Structure!.AsArray().ElementAt(1)!["template"]!["id"]!.GetValue(); + layerData.TemplateId = temId; + } + _LayerDataList.Add(layerData); + Console.WriteLine($"{layerData.TemplateId}--{layerData.LayerId}"); + } + } + } + + public static LayerData? GetLayerDataByTemplateId(string templateId) + { + lock (_LayerDataListLock) + { + try + { + return _LayerDataList.Where(x => x.TemplateId == templateId).First(); + } + catch + { + Log.Warn("通过模板id未获取到图层数据"); + return null; + } + } + } #endregion /// @@ -298,5 +345,12 @@ namespace OMS.NET } } } + + public static string GetCurrentTime() + { + string format = "yyyy-MM-dd HH:mm:ss"; + return DateTime.Now.ToString(format); + } + } } \ No newline at end of file diff --git a/Instructs/AddElementBroadcastInstruct.cs b/Instructs/AddElementBroadcastInstruct.cs new file mode 100644 index 0000000..2213a6d --- /dev/null +++ b/Instructs/AddElementBroadcastInstruct.cs @@ -0,0 +1,134 @@ + +using System.Text; +using System.Text.Json; +using OMS.NET.Common; +using OMS.NET.DbClass; + +namespace OMS.NET.Instructs +{ + public class AddElementBroadcastInstruct : BroadcastInstuct + { + public AddElementBroadcastInstruct() + { + Type = "broadcast"; + } + + public override Task Handler(string wsid) + { + return Task.Run(() => + { + if (GlobalArea.LoginCheckByID(wsid)) + { + //从Data中解析数据,收到的是json文本类型 + if (Data?.GetType() == typeof(JsonElement)) + { + try + { + string id = Data.GetProperty("id").GetString() ?? ""; + string type = Data.GetProperty("type").GetString() ?? ""; + string points = Data.GetProperty("points").GetString() ?? ""; + string point = Data.GetProperty("point").GetString() ?? ""; + string? color = Data.GetProperty("color").GetString(); + int? width = Data.GetProperty("width").GetInt32(); + string? childRelations = Data.GetProperty("childRelations").GetString(); + string? fatherRelations = Data.GetProperty("fatherRelations").GetString(); + string? childNodes = Data.GetProperty("childNodes").GetString(); + string? fatherNode = Data.GetProperty("fatherNode").GetString(); + string? details = Data.GetProperty("details").GetString(); + string? custom = Data.GetProperty("custom").GetString(); + //validations todo + //假设所有数据均合法 + MapData mapData = new() + { + Type = type, + Points = Util.JsonToBase64(points), + Point = Util.JsonToBase64(point), + Color = color, + Width = width, + ChildRelations = childRelations, + FatherRelations = fatherRelations, + ChildNodes = childNodes, + FatherNode = fatherNode, + Details = Util.JsonToBase64(details), + Custom = Util.JsonToBase64(custom) + }; + //保存点到数据库 + MapData.Add(mapData); + //获取图层id + if (Data.GetProperty("custom").TryGetProperty("tmpId", out JsonElement tmpIdNode)) + { + string tmpId = tmpIdNode.GetString() ?? throw new Exception("tmpId不能为空"); + LayerData? layer = GlobalArea.GetLayerDataByTemplateId(tmpId); + if (layer != null && mapData.Id != -1) + { + layer.AppendElement(mapData.Id, mapData.Type);//包括数据库操作 + //准备回复广播 + string conveyor = GlobalArea.GetLoginEmailByID(wsid); + string time = GlobalArea.GetCurrentTime(); + ResponseOrBroadcastInstructs.Add(new BroadcastInstuct() + { + IsResponse = true, + Class = this.Class, + Conveyor = conveyor, + Time = time, + Data = mapData,//todo get sth base64 + }); + ResponseOrBroadcastInstructs.Add(new BroadcastInstuct() + { + IsBroadcast = true, + Class = "updateLayerData", + Conveyor = conveyor, + Time = time, + Data = new + { + id = layer.LayerId, + members = layer.Members!.ToString(), + structure = layer.Structure!.ToString(), + } + }); + ResponseOrBroadcastInstructs.Add(new SendErrorInstuct() + { + IsResponse = true, + Class = "upload", + Conveyor = conveyor, + Time = GlobalArea.GetCurrentTime(), + Data = new Dictionary() + { + {"vid",id}, + {"rid",mapData.Id} + }, + + }); + + } + + } + else + { + throw new Exception("未找到 tmpId"); + } + + } + catch (Exception ex) + { + Console.WriteLine(ex.Message); + ResponseOrBroadcastInstructs.Add(new SendErrorInstuct() + { + IsResponse = true, + Class = "upload", + Conveyor = GlobalArea.GetLoginEmailByID(wsid), + Time = GlobalArea.GetCurrentTime(), + Data = new + { + source = Data, + message = ex.Message, + }, + + }); + } + } + } + }); + } + } +} \ No newline at end of file diff --git a/Instructs/Instruct.cs b/Instructs/Instruct.cs index c37ec24..0f25cfb 100644 --- a/Instructs/Instruct.cs +++ b/Instructs/Instruct.cs @@ -58,7 +58,10 @@ namespace OMS.NET.Instructs "broadcast" => classValue switch { //广播指令继承结构 - "" => JsonSerializer.Deserialize(root.GetRawText(), options), + "point" => JsonSerializer.Deserialize(root.GetRawText(), options), + "line" => JsonSerializer.Deserialize(root.GetRawText(), options), + "area" => JsonSerializer.Deserialize(root.GetRawText(), options), + "curve" => JsonSerializer.Deserialize(root.GetRawText(), options), _ => JsonSerializer.Deserialize(root.GetRawText(), options) }, _ => null diff --git a/Program.cs b/Program.cs index 6da2346..9c26ba6 100644 --- a/Program.cs +++ b/Program.cs @@ -14,10 +14,11 @@ namespace OMS.NET { try { - //判断是否满足运行条件 GlobalArea.LoadServerConfig();//加载服务器配置 默认server.yaml GlobalArea.LoadRsaPkey();//加载rsa私钥 默认.pkey DbCheck(); + //预加载一些数据以方便后面的处理 + GlobalArea.BuildLayerData(); //开启ws监听 var wssv = new WebSocketServer(Convert.ToInt16(GlobalArea.ServerConfig.ListenPort), false);