009_DI-Elec/Learun.Application.Web/AppApi/PlotLayoutApiController.cs
2025-09-28 09:28:30 +08:00

525 lines
25 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using Learun.Application.TwoDevelopment.ZZDT_EC;
using Learun.Application.TwoDevelopment.ZZDT_EC.Frame;
using Learun.Util;
using Learun.Util.SqlSugar;
using NPOI.SS.Formula.Functions;
using NPOI.SS.Formula.PTG;
using NPOI.Util.Collections;
using Pipelines.Sockets.Unofficial.Arenas;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Runtime;
using System.Web;
using System.Web.Http;
using System.Windows.Controls;
namespace Learun.Application.Web.AppApi
{
/// <summary>
/// 绘制布置图相关的By YuXH
/// </summary>
[HandlerApiLogin(FilterMode.Ignore)]
public class PlotLayoutApiController : WebApiControllerBase
{
/// <summary>
/// 查找一个图上的所有基点
/// </summary>
/// <param name="keyProp">所属系统 甲板号 区域 的其中一个</param>
/// <param name="keyOperator"></param>
/// <param name="keyValue"></param>
/// <param name="ProjectId"></param>
/// <param name="drawingId"></param>
/// <returns></returns>
[HttpGet]
public IHttpActionResult GetBasePointByDwg(string keyProp, string keyOperator, string keyValue, string ProjectId = "c151f5d4-cbe1-4522-945c-501b1ad990d5", string drawingId = "277d883d-e271-45e4-990b-926585321fa8")
{
var typeTbName = ProjectSugar.TableName<ec_objecttypeEntity>(ProjectId);
var pixelTbName = ProjectSugar.TableName<ec_enginedata_pixelEntity>(ProjectId);
var tagTbName = ProjectSugar.TableName<ec_enginedataEntity>(ProjectId);
var propTbName = ProjectSugar.TableName<ec_enginedata_propertyEntity>(ProjectId);
var listTbName = ProjectSugar.TableName<ec_dataitemEntity>(ProjectId);
var detailTbName = ProjectSugar.TableName<ec_dataitemdetailEntity>(ProjectId);
var typeFilterTbName = ProjectSugar.TableName<ec_objTypeLayoutFilter>(ProjectId);
var typeFilterPTbName = ProjectSugar.TableName<ec_objTypeLayoutFilterP>(ProjectId);
var allFilter = SqlSugarHelper.Db.Queryable<ec_objTypeLayoutFilter>().AS(typeFilterTbName).ToList();
var allFilterP = SqlSugarHelper.Db.Queryable<ec_objTypeLayoutFilterP>().AS(typeFilterPTbName).ToList();
var allType = SqlSugarHelper.Db.Queryable<ec_objecttypeEntity>().AS(typeTbName).ToList();
var pointType = allType.First(x => x.ObjectTypeName == GlobalObject.objectType_Base);
if (pointType == null)
{
return Fail("找不到基点这个对象类型。");
}
#region frame
var frameBll = new FrameBll();
var frameLists = frameBll.GetFrameList(ProjectId);
if (frameLists == null)
{
return Fail("项目数据字典中,没有找到【肋位号】的下拉项中。");// 或者 无法从数据字典中找到对应的那个下拉
}
ec_dataitemBLL ec_DataitemBLL = new ec_dataitemBLL();
var roomLists = ec_DataitemBLL.GetDetailList("RoomNo", "", ProjectId, false);
if (roomLists == null)
{
return Fail("项目数据字典中,没有找到【房间号】的下拉项中。");// 或者 无法从数据字典中找到对应的那个下拉
}
#endregion
var pointsOnDwg = SqlSugarHelper.Db.Queryable<ec_enginedata_pixelEntity>().AS(pixelTbName).
Where(x => x.DrawingFileID == drawingId && x.DeleteFlg==0).ToList();
var pointTags = SqlSugarHelper.Db.Queryable<ec_enginedataEntity>().AS(tagTbName).
Where(x => pointsOnDwg.Select(y => y.EngineDataID).Distinct().Contains(x.EngineDataID)
&& x.ObjectTypeID == pointType.ObjectTypeID).ToList();
var propAll = SqlSugarHelper.Db.Queryable<ec_enginedata_propertyEntity>().AS(propTbName).ToList();
//Where(x => x.PropertyName == GlobalObject.propName_Frame
//|| x.PropertyName == GlobalObject.propName_FrameOff
//|| x.PropertyName == GlobalObject.propName_YOff
//|| x.PropertyName == GlobalObject.propName_System
//|| x.PropertyName == "甲板号"
//|| x.PropertyName == "区域").ToList();
List<layoutTagInfoBrief> res = new List<layoutTagInfoBrief>();
foreach (var pointTag in pointTags)
{
var tagProps = propAll.FindAll(x => x.EngineDataID == pointTag.EngineDataID);
var Prop_Frame = tagProps.FirstOrDefault(x => x.PropertyName == GlobalObject.propName_Frame)?.PropertyValue;
if (Prop_Frame != null)
{
Prop_Frame = Prop_Frame.Split(new string[] { GlobalObject.enum_separator }, StringSplitOptions.None)[0];//插件端对于下拉列表 都是 name || nameEN
}
var Prop_Room = tagProps.FirstOrDefault(x => x.PropertyName == GlobalObject.propName_Room)?.PropertyValue;
if (Prop_Room != null)
{
Prop_Room = Prop_Room.Split(new string[] { GlobalObject.enum_separator }, StringSplitOptions.None)[0];//插件端对于下拉列表 都是 name || nameEN
}
var matchedFrame = frameLists.FirstOrDefault(X => X.Num == Prop_Frame);
var matchedRoom = roomLists.FirstOrDefault(X => X.DataItemName == Prop_Room);
if (matchedFrame == null && matchedRoom == null)
{
//没有
//无效的基点
var layoutTagInvalid = new layoutTagInfoBrief()
{
EngineDataID = pointTag.EngineDataID,
FileId = "",
PixelOnDwg = pointsOnDwg.FirstOrDefault(x => x.EngineDataID == pointTag.EngineDataID)?.PixelCode,
TagNumber = pointTag.TagNumber,
area = "ERR"
};
res.Add(layoutTagInvalid);
continue;
}
double xValue = 0 ;
if (matchedFrame != null)
{
xValue = frameLists.FirstOrDefault(X => X.Num == Prop_Frame).Value;
if (xValue < 400)
{
// 小于400我几乎可以认为此时肋位号用的是m这个单位。因为如果用的是mm400mm的肋位号似乎也太小了。
xValue = 1000 * xValue; // 转成mm
}
}
string strRoom = string.Empty;
if (matchedRoom != null)
{
strRoom = matchedRoom.DataItemName;
}
var Prop_FrameOff = tagProps.FirstOrDefault(x => x.PropertyName == GlobalObject.propName_FrameOff)?.PropertyValue;
var Prop_YOff = tagProps.FirstOrDefault(x => x.PropertyName == GlobalObject.propName_YOff)?.PropertyValue;
var DECK = tagProps.FirstOrDefault(x => x.PropertyName == "甲板号")?.PropertyValue;
var AREA = tagProps.FirstOrDefault(x => x.PropertyName == "区域")?.PropertyValue;
var BasePointProp_scale = tagProps.FirstOrDefault(x => x.PropertyName == "比例");
var layoutTag = new layoutTagInfoBrief()
{
EngineDataID = pointTag.EngineDataID,
FileId = "",
PixelOnDwg = pointsOnDwg.FirstOrDefault(x => x.EngineDataID == pointTag.EngineDataID)?.PixelCode,
TagNumber = pointTag.TagNumber,
X = xValue,
XOff = Prop_FrameOff,
YOff = Prop_YOff,
deck = DECK,
area = AREA,
Scale = BasePointProp_scale == null ? 1 : (double.TryParse(BasePointProp_scale.PropertyValue, out double scale) ? scale : 1),
RoomNo = strRoom
};
res.Add(layoutTag);
}
// 找出area和deck列组合重复的行
var duplicateGroups = res
.GroupBy(r => new { r.area, r.deck, r.RoomNo })
.Where(g => g.Count() > 1)
.ToList();
if (duplicateGroups.Any())
{
return Fail("该图纸上有甲板、房间号信息重复的基点存在。");
}
//这里要考虑下拉列表 带 ||的问题
List<string> matchedTagIds = new List<string>();
//if (keyProp == GlobalObject.propName_System)
//{
//#task 9536
// 筛选出所有以 "a||" 或 "b||" 开头的元素
var validSystems = keyValue.Split(';').ToList();
matchedTagIds = propAll.Where(item =>
item.PropertyName == keyProp &&
validSystems.Any(prefix => item.PropertyValue == prefix) || validSystems.Any(prefix => item.PropertyValue.StartsWith(prefix + GlobalObject.enum_separator))
).Select(X => X.EngineDataID).Distinct().ToList();
//}
//else
//{
// matchedTagIds = propAll.Where(x => x.PropertyName == keyProp
// && (x.PropertyValue == keyValue || x.PropertyValue.StartsWith(keyValue + GlobalObject.enum_separator))).
// Select(X => X.EngineDataID).Distinct().ToList();
//}
//有效范围的设备
var matchedTags = SqlSugarHelper.Db.Queryable<ec_enginedataEntity>().AS(tagTbName).
InnerJoin<ec_objecttypeEntity>((a, b) => a.ObjectTypeID == b.ObjectTypeID).AS<ec_objecttypeEntity>(typeTbName).
Where(a => matchedTagIds.Contains(a.EngineDataID)
&& a.ObjectTypeID != pointType.ObjectTypeID)
.Select((a, b) => new { a.EngineDataID, a.TagNumber, a.ObjectTypeID, b.DefaultLayoutLibFileID })
.ToList();
//有效范围的设备的所有属性
var EquipPropAll = propAll.Where(x => matchedTags.Select(y => y.EngineDataID).Contains(x.EngineDataID)).ToList();
foreach (var basePoint in res)
{
#region
//甲板 区域都和基点一致的设备
var DeckMatchedTagIds = EquipPropAll.Where(x => x.PropertyName == "甲板号" && (x.PropertyValue?.Split(new[] { "||" }, StringSplitOptions.None)[0] == basePoint.deck)).Select(X => X.EngineDataID).ToList();
//var AreaMatchedTagIds = EquipPropAll.Where(x => x.PropertyName == "区域" && x.PropertyValue == basePoint.area).Select(X => X.EngineDataID).ToList();
//#task 9542
var matchPointTagIds = DeckMatchedTagIds;//.Intersect(AreaMatchedTagIds).ToList();
foreach (var matchPointTagId in matchPointTagIds)
{
var tagInfo = matchedTags.FirstOrDefault(X => X.EngineDataID == matchPointTagId);
var tagProps = EquipPropAll.Where(x => x.EngineDataID == matchPointTagId).ToList();
var Prop_Frame = tagProps.FirstOrDefault(x => x.PropertyName == GlobalObject.propName_Frame)?.PropertyValue;
if (Prop_Frame != null)
{
Prop_Frame = Prop_Frame.Split(new string[] { GlobalObject.enum_separator }, StringSplitOptions.None)[0];//插件端对于下拉列表 都是 name || nameEN
}
var Prop_RoomNo = tagProps.FirstOrDefault(x => x.PropertyName == GlobalObject.propName_Room)?.PropertyValue;
if (Prop_RoomNo != null)
{
Prop_RoomNo = Prop_RoomNo.Split(new string[] { GlobalObject.enum_separator }, StringSplitOptions.None)[0];//插件端对于下拉列表 都是 name || nameEN
}
var matchedFrame = frameLists.FirstOrDefault(X => X.Num == Prop_Frame);
var matchedRoom = roomLists.FirstOrDefault(x => x.DataItemName == Prop_RoomNo);
if (matchedFrame == null && matchedRoom == null)
{
var layoutTagInfoInvalid = new layoutTagInfoBrief()
{
EngineDataID = matchPointTagId,
PixelOnDwg = "",
TagNumber = tagInfo.TagNumber,
area = "ERR",
};
basePoint.Tags.Add(layoutTagInfoInvalid);
continue;
}
double xValue = 0;
if (matchedFrame != null)
{
xValue = frameLists.FirstOrDefault(X => X.Num == Prop_Frame).Value;
if (xValue < 400)
{
// 小于400我几乎可以认为此时肋位号用的是m这个单位。因为如果用的是mm400mm的肋位号似乎也太小了。
xValue = 1000 * xValue; // 转成mm
}
}
string strRoom = string.Empty;
if (matchedRoom != null)
{
strRoom = matchedRoom.DataItemName;
}
var Prop_FrameOff = tagProps.FirstOrDefault(x => x.PropertyName == GlobalObject.propName_FrameOff)?.PropertyValue;
var Prop_YOff = tagProps.FirstOrDefault(x => x.PropertyName == GlobalObject.propName_YOff)?.PropertyValue;
var systemProp = tagProps.FirstOrDefault(x => x.PropertyName == GlobalObject.propName_System)?.PropertyValue;
var tagProp = tagProps.FirstOrDefault(x => x.PropertyName == GlobalObject.propName_Tag)?.PropertyValue;
#region
var fileId = tagInfo.DefaultLayoutLibFileID;
var matched = false;
var isNotDefaultSymbol = true;
foreach (var filter in allFilter.Where(x => x.ObjectTypeId == tagInfo.ObjectTypeID))
{
if (matched)
{
//有一个满足就可以了
break;
}
var filterOp = filter.Operator;//and or
var filterPs = allFilterP.Where(x => x.FilterID == filter.SP_ID).ToList();
foreach (var filterP in filterPs)
{
var prop = tagProps.FirstOrDefault(x => x.PropertyName == filterP.PropertyName);
if (prop != null)
{
if (prop.PropertyValue.ToUpper() == filterP.Value.ToUpper())
{
if (filterOp.ToUpper() == "OR")
{
//一个满足即可
matched = true;
fileId = filter.LayoutLibFileID;
isNotDefaultSymbol = false;
break;
}
//如果是and继续看下面的属性先给图例如果有一个不满足会break的,主要是避免只有一个条件的时候
fileId = filter.LayoutLibFileID;
matched = true;
isNotDefaultSymbol = false;
}
else
{
if (filterOp.ToUpper() == "AND")
{
matched = false;
isNotDefaultSymbol = true;
//一个不满足都不满足
break;
}
}
}
else
{
//压根没这个属性,认为不符合
if (filterOp.ToUpper() == "AND")
{
matched = false;
isNotDefaultSymbol = true;
break;
}
}
}
}
#endregion
#region tag number
var TagNumber_Upper = ""; var TagNumber_Lower = "";
var lastDashPos = tagInfo.TagNumber.LastIndexOf('-');//最后一个'-'的位置
if (lastDashPos > 0 && lastDashPos < tagInfo.TagNumber.Length - 1)
{
TagNumber_Upper = tagInfo.TagNumber.Substring(lastDashPos + 1);//tag
TagNumber_Lower = tagInfo.TagNumber.Substring(0, lastDashPos);//system
}
else
{
TagNumber_Upper = tagInfo.TagNumber;//tag
TagNumber_Lower = ""; //system
}
#endregion
var layoutTagInfo = new layoutTagInfoBrief()
{
EngineDataID = matchPointTagId,
FileId = fileId, //2个优先级
IsNotDefaultSymbol = isNotDefaultSymbol,
PixelOnDwg = "",
TagNumber = tagInfo.TagNumber,
TagNumber_Upper = TagNumber_Upper,
TagNumber_Lower = TagNumber_Lower,
System = systemProp,
Tag = tagProp,
X = xValue,
XOff = Prop_FrameOff,
YOff = Prop_YOff,
deck = basePoint.deck,
area = basePoint.area,
Scale = basePoint.Scale,
RoomNo = strRoom
};
basePoint.Tags.Add(layoutTagInfo);
}
#endregion
}
return Success(res);
}
///// <summary>
///// 拿项目的所属系统。所属系统是一个特定的数据字典。至于哪个作为所属系统则从settingAPI里查询
///// </summary>
///// <param name="ProjectId"></param>
///// <returns>返回TreeModel</returns>
//[HttpGet]
//public IHttpActionResult GetSystemList(string ProjectId)
//{
// var ec_propertyBLL = new ec_propertyBLL();
// var ec_dataitemBLL = new ec_dataitemBLL();
// var settings = new ec_projectSettingsBLL();
// List<TreeModel> treeList = new List<TreeModel>();
// var FrameListFlg = settings.GetEntity("所属系统", ProjectId);//???感觉不需要啊
// if (FrameListFlg != null)
// {
// //从setting找属性
// var property = ec_propertyBLL.GetList("{PropertyName:\"" + FrameListFlg.SettingValue + "\",ProjectId:\"" + ProjectId + "\"}").FirstOrDefault();
// if (property != null)
// {
// //从属性去找数据字典
// var res = ec_dataitemBLL.GetDetailList(property.EnumData, "", ProjectId, false);
// foreach (var item in res)
// {
// TreeModel node = new TreeModel();
// node.id = item.DataItemDetailID;
// node.text = item.DataItemName + "," + item.DataItemCode; //名字 + 编码 20230512;
// node.value = item.DataItemCode;
// node.showcheck = false;
// node.checkstate = 0;
// node.isexpand = true;
// node.parentId = item.UpDataItemDetailID == null ? "0" : item.UpDataItemDetailID;
// treeList.Add(node);
// }
// treeList = treeList.ToTree();
// return Success(treeList);
// }
// else
// {
// return Fail($"属性中property表没有找到【{FrameListFlg.SettingValue}】的属性。");
// }
// }
// else
// {
// return Fail("项目设置中projectSettings表没有找到【所属系统】的设置项。");
// }
//}
/// <summary>
/// 根据选中的所属系统返回位号idfileid和md5
/// </summary>
/// <param name="ProjectId"></param>
/// <param name="DataItemNames">数据字典里的枚举值,以逗号分开,不需要带引号</param>
/// <returns>返回List<treeModel>,id是对象idtext是fileIdvalue是MD5</treeModel></returns>
[HttpGet]
[Obsolete]
public IHttpActionResult GetLibraryFileBySelectedSystem(string ProjectId, string DataItemNames)
{
var res = new ec_library_fileService().GetFileOnSystemDwgByTagId(ProjectId, DataItemNames);
return Success(res);
}
/// <summary>
/// 拿项目的肋位号。肋位号是一个特定的数据字典。至于哪个作为肋位号则从settingAPI里查询
/// </summary>
/// <param name="ProjectId"></param>
/// <returns></returns>
[HttpGet]
public IHttpActionResult GetFrameList(string ProjectId)
{
var bll = new FrameBll();
var res = bll.GetFrameList(ProjectId);
if (res == null)
{
return Fail("项目设置中projectSettings表没有找到【肋位号】的设置项中对应的那个下拉。");// 或者 无法从数据字典中找到对应的那个下拉
}
else
{
return Success(res);
}
}
/// <summary>
/// 根据ObjectTypeID查绘制布置图时的图例
/// </summary>
/// <param name="ProjectId"></param>
/// <param name="objectTypeID"></param>
/// <returns>返回一个LibraryFileID属性的json对象</returns>
[HttpGet]
public IHttpActionResult GetLibraryFileByType(string ProjectId, string objectTypeID)
{
//DefaultLayoutLibFileID
var res = new ec_objecttypeBLL().GetEntity(objectTypeID, ProjectId);
if (res == null)
{
return Fail("无效的ObjectTypeID");
}
if (string.IsNullOrEmpty(res.DefaultLayoutLibFileID))
{
return Success("0");
}
else
{
var fileObj = new ec_library_fileBLL().GetEntity(res.DefaultLayoutLibFileID, ProjectId);
if (fileObj != null)
{
return Success(("{LibraryFileID:\"" + res.DefaultLayoutLibFileID + "\"}").ToJObject());
}
else
{
return Success("0");
}
}
}
/// <summary>
/// 查绘制布置图时的图例。
/// </summary>
/// <param name="ProjectId"></param>
/// <returns>返回所有有DefaultLayoutLibFileID的对象类型集合</returns>
[HttpGet]
public IHttpActionResult GetLibraryFileAll(string ProjectId)
{
//获取当前项目的所有对象类型数据
var allObjectData = new ec_objecttypeBLL().GetList("{ProjectId:\"" + ProjectId + "\"}").ToList();
List<ec_objecttypeEntity> resAll = new List<ec_objecttypeEntity>();
var fileBlll = new ec_library_fileBLL();
foreach (var res in allObjectData)
{
if (string.IsNullOrEmpty(res.DefaultLayoutLibFileID))
{
continue;
}
else
{
var fileObj = fileBlll.GetEntity(res.DefaultLayoutLibFileID, ProjectId);
if (fileObj != null)
{
resAll.Add(res);
}
else
{
continue;
}
}
}
return Success(resAll);
}
}
}