feat: 优化试压包管理和焊口查询性能

主要改进:
• 添加试压类型字段支持,完善试压包管理功能
• 优化包装管理中的单位工程名称获取逻辑
• 实现焊口查询树形结构缓存机制,提升查询性能
• 修复压力类型显示和空值处理问题
• 更新界面文本描述,提高用户体验
This commit is contained in:
2025-12-01 11:14:50 +08:00
parent ace0e3b5e4
commit 2a191b9233
21 changed files with 470 additions and 277 deletions
@@ -8,6 +8,7 @@ using System.IO;
using System.Linq;
using System.Text;
using AspNet = System.Web.UI.WebControls;
using System.Web.Caching;
namespace FineUIPro.Web.HJGL.InfoQuery
{
@@ -82,13 +83,53 @@ namespace FineUIPro.Web.HJGL.InfoQuery
}
public static List<Model.View_HJGL_WeldJoint> View_HJGL_WeldJoint = new List<Model.View_HJGL_WeldJoint>();
// 缓存相关常量
private const string CACHE_KEY_PREFIX = "UnitWorkTree_";
private static readonly System.Web.Caching.Cache Cache = System.Web.HttpRuntime.Cache;
/// <summary>
/// 创建TreeNode的副本(用于缓存)
/// </summary>
/// <param name="sourceNode">源节点</param>
/// <returns>新节点</returns>
private TreeNode CloneTreeNode(TreeNode sourceNode)
{
if (sourceNode == null) return null;
TreeNode newNode = new TreeNode();
newNode.NodeID = sourceNode.NodeID;
newNode.Text = sourceNode.Text;
newNode.ToolTip = sourceNode.ToolTip;
newNode.CommandName = sourceNode.CommandName;
newNode.Selectable = sourceNode.Selectable;
newNode.EnableClickEvent = sourceNode.EnableClickEvent;
newNode.EnableExpandEvent = sourceNode.EnableExpandEvent;
newNode.Expanded = sourceNode.Expanded;
newNode.Icon = sourceNode.Icon;
// 递归复制子节点
if (sourceNode.Nodes != null && sourceNode.Nodes.Count > 0)
{
foreach (TreeNode childNode in sourceNode.Nodes)
{
TreeNode clonedChild = CloneTreeNode(childNode);
if (clonedChild != null)
{
newNode.Nodes.Add(clonedChild);
}
}
}
return newNode;
}
protected void Page_Load(object sender, EventArgs e)
{
ctlAuditFlow.Url = BLL.Project_SysSetService.GetAvevaNetUrl(this.CurrUser.LoginProjectId);
if (!IsPostBack)
{
this.ddlPageSize.SelectedValue = this.Grid1.PageSize.ToString();
this.InitTreeMenu();//加载树
this.InitTreeMenu_WithCache();//加载树
this.JointComplete = 0;
this.JointNoComplete = 0;
this.JointPre = 0;
@@ -97,10 +138,100 @@ namespace FineUIPro.Web.HJGL.InfoQuery
}
}
#region --
// 优化后的节点处理方法
private void ProcessUnitWorkNodes(List<Model.WBS_UnitWork> unitWorks, TreeNode parentNode,
Dictionary<string, int> pipelineCountDict,
Dictionary<string, string> unitDict)
{
foreach (var unitWork in unitWorks)
{
// 优化: 使用字典查找,避免数据库查询
int pipelineCount = pipelineCountDict.ContainsKey(unitWork.UnitWorkId) ? pipelineCountDict[unitWork.UnitWorkId] : 0;
string unitName = unitDict.ContainsKey(unitWork.UnitId) ? unitDict[unitWork.UnitId] : "未知单位";
TreeNode treeNode = new TreeNode();
treeNode.NodeID = unitWork.UnitWorkId;
treeNode.Text = unitWork.UnitWorkName + "【" + pipelineCount.ToString() + "】管线";
treeNode.ToolTip = "施工单位:" + unitName;
treeNode.CommandName = 1 + "|" + Funs.GetEndPageNumber(pipelineCount, pageSize);
treeNode.EnableClickEvent = true;
treeNode.EnableExpandEvent = true;
parentNode.Nodes.Add(treeNode);
if (pipelineCount > 0)
{
TreeNode newNode = new TreeNode();
newNode.Text = "加载管线...";
newNode.NodeID = "加载管线...";
treeNode.Nodes.Add(newNode);
}
}
}
/// <summary>
/// 加载树
/// 带缓存的树加载方法
/// </summary>
private void InitTreeMenu()
private void InitTreeMenu_WithCache()
{
bool cacheHit = false;
string projectId = this.CurrUser.LoginProjectId;
string cacheKey = CACHE_KEY_PREFIX + projectId;
string searchTerm = this.tvPipeCode.Text.Trim();
// 如果有搜索条件,不使用缓存,直接执行优化查询
if (!string.IsNullOrEmpty(searchTerm))
{
InitTreeMenu_Optimized();
return;
}
// 检查缓存
if (Cache[cacheKey] != null)
{
var cachedData = Cache[cacheKey] as List<TreeNode>;
if (cachedData != null)
{
cacheHit = true;
this.tvControlItem.Nodes.Clear();
foreach (var node in cachedData)
{
this.tvControlItem.Nodes.Add(CloneTreeNode(node));
}
return;
}
}
// 执行优化的初始化逻辑
InitTreeMenu_Optimized();
// 缓存结果
var nodesToCache = new List<TreeNode>();
foreach (TreeNode node in this.tvControlItem.Nodes)
{
nodesToCache.Add(CloneTreeNode(node));
}
Cache.Insert(cacheKey, nodesToCache, null, DateTime.Now.AddMinutes(30), TimeSpan.Zero);
}
/// <summary>
/// 清理项目相关的缓存
/// </summary>
private void ClearProjectCache()
{
string projectId = this.CurrUser.LoginProjectId;
string cacheKey = CACHE_KEY_PREFIX + projectId;
if (Cache[cacheKey] != null)
{
Cache.Remove(cacheKey);
}
}
/// <summary>
/// 优化版本的树加载方法
/// </summary>
private void InitTreeMenu_Optimized()
{
this.tvControlItem.Nodes.Clear();
@@ -118,92 +249,58 @@ namespace FineUIPro.Web.HJGL.InfoQuery
rootNode2.Expanded = true;
this.tvControlItem.Nodes.Add(rootNode2);
var pUnits = (from x in Funs.DB.Project_ProjectUnit where x.ProjectId == this.CurrUser.LoginProjectId select x).ToList();
// 获取当前用户所在单位
var currUnit = pUnits.FirstOrDefault(x => x.UnitId == this.CurrUser.UnitId);
string projectId = this.CurrUser.LoginProjectId;
string searchTerm = this.tvPipeCode.Text.Trim();
// 优化1: 使用单次查询获取所需数据,减少数据库往返次数
var unitWorkList = (from x in Funs.DB.WBS_UnitWork
where x.ProjectId == this.CurrUser.LoginProjectId
&& x.SuperUnitWork == null && x.UnitId != null && x.ProjectType != null
where x.ProjectId == projectId
&& x.SuperUnitWork == null
&& x.UnitId != null
&& x.ProjectType != null
select x).ToList();
List<Model.WBS_UnitWork> unitWork1 = null;
List<Model.WBS_UnitWork> unitWork2 = null;
// 优化2: 批量获取所有相关管线数据,避免N+1查询问题
var unitWorkIds = unitWorkList.Select(x => x.UnitWorkId).ToList();
var pipelineQuery = from p in Funs.DB.HJGL_Pipeline
where p.ProjectId == projectId
&& unitWorkIds.Contains(p.UnitWorkId)
select p;
//// 当前为施工单位,只能操作本单位的数据
//if (currUnit != null && currUnit.UnitType == Const.ProjectUnitType_2)
//{
// unitWork1 = (from x in unitWorkList
// where x.UnitId == this.CurrUser.UnitId && x.ProjectType == "1"
// select x).ToList();
// unitWork2 = (from x in unitWorkList
// where x.UnitId == this.CurrUser.UnitId && x.ProjectType == "2"
// select x).ToList();
//}
//else
//{
unitWork1 = (from x in unitWorkList where x.ProjectType == "1" select x).ToList();
unitWork2 = (from x in unitWorkList where x.ProjectType == "2" select x).ToList();
//}
if (unitWork1.Count() > 0)
// 如果有搜索条件,添加过滤
if (!string.IsNullOrEmpty(searchTerm))
{
foreach (var q in unitWork1)
{
int a = (from x in Funs.DB.HJGL_Pipeline where x.ProjectId == this.CurrUser.LoginProjectId && x.UnitWorkId == q.UnitWorkId select x).Count();
var unitNamesUnitIds = BLL.UnitService.getUnitNamesUnitIds(q.UnitId);
TreeNode tn1 = new TreeNode();
tn1.NodeID = q.UnitWorkId;
tn1.Text = q.UnitWorkName + "【" + a.ToString() + "】" + "管线";
tn1.ToolTip = "施工单位:" + unitNamesUnitIds;
tn1.CommandName = 1 + "|" + Funs.GetEndPageNumber(a, pageSize);
tn1.EnableClickEvent = true;
tn1.EnableExpandEvent = true;
rootNode1.Nodes.Add(tn1);
if (a > 0)
{
// BindNodes(tn1);
TreeNode newNode = new TreeNode();
newNode.Text = "加载管线...";
newNode.NodeID = "加载管线...";
tn1.Nodes.Add(newNode);
}
//if (a > 0)
//{
// BindNodes(tn1);
//}
}
pipelineQuery = pipelineQuery.Where(p => p.PipelineCode.Contains(searchTerm));
}
if (unitWork2.Count() > 0)
{
foreach (var q in unitWork2)
{
int a = (from x in Funs.DB.HJGL_Pipeline
where x.ProjectId == this.CurrUser.LoginProjectId && x.UnitWorkId == q.UnitWorkId
&& x.PipelineCode.Contains(this.tvPipeCode.Text.Trim())
select x).Count();
var unitNamesUnitIds = BLL.UnitService.getUnitNamesUnitIds(q.UnitId);
TreeNode tn2 = new TreeNode();
tn2.NodeID = q.UnitWorkId;
tn2.Text = q.UnitWorkName + "【" + a.ToString() + "】" + "管线";
if (q.UnitWorkId == this.hdUnitWorkId.Text)
{
tn2.Expanded = true;
}
tn2.ToolTip = "施工单位:" + unitNamesUnitIds;
tn2.CommandName = 1 + "|" + Funs.GetEndPageNumber(a, pageSize);
tn2.EnableClickEvent = true;
tn2.EnableExpandEvent = true;
rootNode2.Nodes.Add(tn2);
if (a > 0)
{
// BindNodes(tn2);
TreeNode newNode = new TreeNode();
newNode.Text = "加载管线...";
newNode.NodeID = "加载管线...";
tn2.Nodes.Add(newNode);
}
}
var pipelineCountDict = (from p in pipelineQuery
group p by p.UnitWorkId into g
select new {
UnitWorkId = g.Key,
Count = g.Count()
}).ToDictionary(x => x.UnitWorkId, x => x.Count);
// 优化3: 批量获取单位信息
var unitIds = unitWorkList.Where(x => x.UnitId != null).Select(x => x.UnitId).Distinct().ToList();
var unitDict = (from u in Funs.DB.Base_Unit
where unitIds.Contains(u.UnitId)
select u).ToDictionary(x => x.UnitId, x => x.UnitName);
// 优化4: 使用Dictionary进行快速查找,避免重复查询
List<Model.WBS_UnitWork> unitWork1 = unitWorkList.Where(x => x.ProjectType == "1").ToList();
List<Model.WBS_UnitWork> unitWork2 = unitWorkList.Where(x => x.ProjectType == "2").ToList();
// 处理建筑工程
if (unitWork1.Count > 0)
{
ProcessUnitWorkNodes(unitWork1, rootNode1, pipelineCountDict, unitDict);
}
// 处理安装工程
if (unitWork2.Count > 0)
{
ProcessUnitWorkNodes(unitWork2, rootNode2, pipelineCountDict, unitDict);
}
}
#endregion
@@ -382,7 +479,9 @@ namespace FineUIPro.Web.HJGL.InfoQuery
/// <param name="e"></param>
protected void btnTreeFind_Click(object sender, EventArgs e)
{
this.InitTreeMenu();
// 清理缓存以确保获取最新数据(特别是当搜索条件改变时)
ClearProjectCache();
this.InitTreeMenu_WithCache();
//this.BindGrid3(this.tvControlItem.SelectedNodeID);
}
protected void btnrefresh_Click(object sender, EventArgs e)
@@ -457,7 +556,7 @@ namespace FineUIPro.Web.HJGL.InfoQuery
/// <param name="e"></param>
protected void Tree_TextChanged(object sender, EventArgs e)
{
this.InitTreeMenu();
this.InitTreeMenu_WithCache();
this.BindGrid();
}
protected void btnGetChart_Click(object sender, EventArgs e)