feat(hjgl): 支持按焊口匹配和回写管线材料

管线材料导入需要关联到具体焊口,并允许按材料编码匹配库存后回写
材料主编码。新增 HJGL_PipeLineMat 的焊口和材料编码字段,材料匹配、
任务生成和出库关系同步按焊口维度处理,避免仅按组件匹配导致材料
范围不准确。
This commit is contained in:
2026-06-11 10:39:58 +08:00
parent c48972cc60
commit 201443e437
15 changed files with 488 additions and 206 deletions
@@ -70,21 +70,21 @@ namespace FineUIPro.Web.HJGL.WeldingManage
}
}
public Dictionary<string, HashSet<string>> priorityComponents
public Dictionary<string, HashSet<string>> priorityWeldJoints
{
get
{
var value = ViewState["priorityComponents"] as Dictionary<string, HashSet<string>>;
var value = ViewState["priorityWeldJoints"] as Dictionary<string, HashSet<string>>;
if (value == null)
{
value = new Dictionary<string, HashSet<string>>();
ViewState["priorityComponents"] = value;
ViewState["priorityWeldJoints"] = value;
}
return value;
}
set
{
ViewState["priorityComponents"] = value;
ViewState["priorityWeldJoints"] = value;
}
}
@@ -104,7 +104,7 @@ namespace FineUIPro.Web.HJGL.WeldingManage
; HJGL_MaterialService.materialStockItems_FIELD = new List<Model.MaterialStockItem>();
HJGL_MaterialService.materialStockItems_SHOP = new List<Model.MaterialStockItem>();
dicSeclectPipeLine = new Dictionary<string, string>();
priorityComponents = new Dictionary<string, HashSet<string>>();
priorityWeldJoints = new Dictionary<string, HashSet<string>>();
var pipeline = (from x in Funs.DB.HJGL_Pipeline
where x.ProjectId == this.CurrUser.LoginProjectId
select x.FlowingSection).Distinct().ToList();
@@ -377,14 +377,25 @@ namespace FineUIPro.Web.HJGL.WeldingManage
#region
private void BindGrid()
{
string strSql = @"SELECT lib.MaterialCode,lib.MaterialName,lib.MaterialUnit,
lib.MaterialSpec,lib.MaterialMade,lib.MaterialDef,sum(pipe.Number)as Number ,
string strSql = @"SELECT ISNULL(pipe.MaterialCode2, lib.Code) AS MaterialCode,
ISNULL(lib.MaterialName, libCode.MaterialName) AS MaterialName,
ISNULL(lib.MaterialUnit, libCode.MaterialUnit) AS MaterialUnit,
ISNULL(lib.MaterialSpec, libCode.MaterialSpec) AS MaterialSpec,
ISNULL(lib.MaterialMade, libCode.MaterialMade) AS MaterialMade,
ISNULL(lib.MaterialDef, libCode.MaterialDef) AS MaterialDef,
sum(pipe.Number)as Number ,
'0' as MatchNum,'否' AS CheckState
FROM dbo.HJGL_PipeLineMat pipe
LEFT JOIN dbo.HJGL_MaterialCodeLib lib ON lib.MaterialCode = pipe.MaterialCode
LEFT JOIN dbo.HJGL_Pipeline line ON line.PipelineId = pipe.PipelineId
OUTER APPLY (SELECT TOP 1 * FROM dbo.HJGL_MaterialCodeLib codeLib WHERE codeLib.ProjectId=line.ProjectId AND codeLib.Code=pipe.MaterialCode2 ORDER BY codeLib.MaterialCode) libCode
WHERE PipelineId=@PipelineId
group by lib.MaterialCode,lib.MaterialName,lib.MaterialUnit,
lib.MaterialSpec,lib.MaterialMade,lib.MaterialDef ";
group by ISNULL(pipe.MaterialCode2, lib.Code),
ISNULL(lib.MaterialName, libCode.MaterialName),
ISNULL(lib.MaterialUnit, libCode.MaterialUnit),
ISNULL(lib.MaterialSpec, libCode.MaterialSpec),
ISNULL(lib.MaterialMade, libCode.MaterialMade),
ISNULL(lib.MaterialDef, libCode.MaterialDef) ";
List<SqlParameter> listStr = new List<SqlParameter>();
listStr.Add(new SqlParameter("@PipelineId", this.tvControlItem.SelectedNodeID));
SqlParameter[] parameter = listStr.ToArray();
@@ -394,7 +405,7 @@ namespace FineUIPro.Web.HJGL.WeldingManage
Grid1.DataSource = dt;
Grid1.DataBind();
}
void BindGrid2()
void BindGrid2(IEnumerable<string> keepSelectedPipelineIds = null)
{
//var result = tw_PipeMatMatchOutputs
// .GroupBy(item => new { item.PipelineId, item.PipelineCode,item.UnitWorkName }) // 按 PipelineId 和 PipelineCode 分组
@@ -424,6 +435,7 @@ namespace FineUIPro.Web.HJGL.WeldingManage
Rate = Math.Round((decimal)output.Average(item => item.MatchRate) * 100, 2);
lbRate.Text = "匹配率:" + Rate.ToString() + "%";
}*/
var keepSelectedList = keepSelectedPipelineIds == null ? new List<string>() : keepSelectedPipelineIds.Where(x => !string.IsNullOrEmpty(x)).Distinct().ToList();
var selectList = new List<string>();
for (int i = 0; i < Grid2.Rows.Count; i++)
{
@@ -443,7 +455,12 @@ namespace FineUIPro.Web.HJGL.WeldingManage
}
if (cbSelectCom.Checked)
{
Grid2.SelectedRowIDArray = selectList.ToArray();
selectList.AddRange(keepSelectedList);
Grid2.SelectedRowIDArray = selectList.Distinct().ToArray();
}
else if (keepSelectedList.Any())
{
Grid2.SelectedRowIDArray = keepSelectedList.ToArray();
}
}
@@ -486,7 +503,9 @@ namespace FineUIPro.Web.HJGL.WeldingManage
private void BindMaterialDetail(string pipelineId)
{
var tb = tw_PipeMatMatchOutputs.Where(x => x.PipelineId == pipelineId).ToList();
var tb = GetNoTaskMaterialDetails()
.Where(x => x.PipelineId == pipelineId)
.ToList();
Grid1.DataSource = tb;
Grid1.DataBind();
@@ -499,7 +518,7 @@ namespace FineUIPro.Web.HJGL.WeldingManage
continue;
}
if (IsPriorityComponent(model.PipelineId, model.PrefabricatedComponents))
if (IsPriorityWeldJoint(model.PipelineId, model.WeldJointId))
{
Grid1.Rows[i].RowCssClass = "priority";
selectList.Add(model.Id);
@@ -513,30 +532,54 @@ namespace FineUIPro.Web.HJGL.WeldingManage
Grid1.SelectedRowIDArray = selectList.ToArray();
}
private bool IsPriorityComponent(string pipelineId, string prefabricatedComponents)
private List<Tw_PipeMatMatchOutput> GetNoTaskMaterialDetails()
{
return !string.IsNullOrEmpty(pipelineId)
&& !string.IsNullOrEmpty(prefabricatedComponents)
&& priorityComponents.ContainsKey(pipelineId)
&& priorityComponents[pipelineId].Contains(prefabricatedComponents);
var matchOutputs = tw_PipeMatMatchOutputs ?? new List<Tw_PipeMatMatchOutput>();
var weldJointIds = matchOutputs
.Where(x => !string.IsNullOrEmpty(x.WeldJointId))
.Select(x => x.WeldJointId)
.Distinct()
.ToList();
if (!weldJointIds.Any())
{
return matchOutputs;
}
var taskWeldJointIds = Funs.DB.HJGL_WeldTask
.Where(x => weldJointIds.Contains(x.WeldJointId))
.Select(x => x.WeldJointId)
.Distinct()
.ToList();
return matchOutputs
.Where(x => string.IsNullOrEmpty(x.WeldJointId) || !taskWeldJointIds.Contains(x.WeldJointId))
.ToList();
}
private Dictionary<string, List<string>> GetPriorityComponentList()
private bool IsPriorityWeldJoint(string pipelineId, string weldJointId)
{
return priorityComponents
return !string.IsNullOrEmpty(pipelineId)
&& !string.IsNullOrEmpty(weldJointId)
&& priorityWeldJoints.ContainsKey(pipelineId)
&& priorityWeldJoints[pipelineId].Contains(weldJointId);
}
private Dictionary<string, List<string>> GetPriorityWeldJointList()
{
return priorityWeldJoints
.Where(x => x.Value != null && x.Value.Any())
.ToDictionary(x => x.Key, x => x.Value.ToList());
}
private void RefreshMatchResult()
{
var keepSelectedPipelineIds = Grid2.SelectedRowIDArray == null ? new List<string>() : Grid2.SelectedRowIDArray.ToList();
tw_PipeMatMatchOutputs = TwArrivalStatisticsService.GetPipeMatMatch(
this.CurrUser.LoginProjectId,
dicSeclectPipeLine.Keys.ToList(),
drpWarehouse.SelectedValue,
GetPriorityComponentList());
GetPriorityWeldJointList());
BindGrid3();
BindGrid2();
BindGrid2(keepSelectedPipelineIds);
}
protected void Grid2_RowClick(object sender, GridRowClickEventArgs e)
@@ -692,7 +735,7 @@ namespace FineUIPro.Web.HJGL.WeldingManage
foreach (string rowId in Grid3.SelectedRowIDArray)
{
dicSeclectPipeLine.Remove(rowId);
priorityComponents.Remove(rowId);
priorityWeldJoints.Remove(rowId);
var node = tvControlItem.FindNode(rowId);
if (node != null)
{
@@ -713,38 +756,85 @@ namespace FineUIPro.Web.HJGL.WeldingManage
return;
}
var selectedComponents = new HashSet<string>();
var selectedWeldJoints = new HashSet<string>();
foreach (int rowIndex in Grid1.SelectedRowIndexArray)
{
if (Grid1.DataKeys[rowIndex].Length < 3)
if (Grid1.DataKeys[rowIndex].Length < 4)
{
continue;
}
string pipelineId = Grid1.DataKeys[rowIndex][1]?.ToString();
string componentCode = Grid1.DataKeys[rowIndex][2]?.ToString();
if (pipelineId == selectedPipelineId && !string.IsNullOrEmpty(componentCode))
string weldJointId = Grid1.DataKeys[rowIndex][3]?.ToString();
if (pipelineId == selectedPipelineId && !string.IsNullOrEmpty(weldJointId))
{
selectedComponents.Add(componentCode);
selectedWeldJoints.Add(weldJointId);
}
}
if (selectedComponents.Any())
if (selectedWeldJoints.Any())
{
priorityComponents[selectedPipelineId] = selectedComponents;
priorityWeldJoints[selectedPipelineId] = selectedWeldJoints;
}
else
{
priorityComponents.Remove(selectedPipelineId);
priorityWeldJoints.Remove(selectedPipelineId);
}
var keepSelectedPipelineIds = Grid2.SelectedRowIDArray == null ? new List<string>() : Grid2.SelectedRowIDArray.ToList();
if (!keepSelectedPipelineIds.Contains(selectedPipelineId))
{
keepSelectedPipelineIds.Add(selectedPipelineId);
}
RefreshMatchResult();
Grid2.SelectedRowIDArray = keepSelectedPipelineIds.Distinct().ToArray();
BindMaterialDetail(selectedPipelineId);
}
protected void btnConfirmMaterialCode_Click(object sender, EventArgs e)
{
if (Grid2.SelectedRowIDArray == null || !Grid2.SelectedRowIDArray.Any())
{
ShowNotify("请先选择需要保存匹配结果的管线!", MessageBoxIcon.Warning);
return;
}
if (tw_PipeMatMatchOutputs == null || !tw_PipeMatMatchOutputs.Any())
{
RefreshMatchResult();
}
var selectedPipelineIds = Grid2.SelectedRowIDArray.ToList();
var matchedMaterials = tw_PipeMatMatchOutputs
.Where(x => selectedPipelineIds.Contains(x.PipelineId))
.ToList();
if (!matchedMaterials.Any())
{
ShowNotify("未找到保存的材料匹配明细!", MessageBoxIcon.Warning);
return;
}
var invalidMaterials = matchedMaterials
.Where(x => string.IsNullOrEmpty(x.MatchMaterialCode) || (x.MatchRate ?? 0) < 1)
.ToList();
/* if (invalidMaterials.Any())
{
ShowNotify("存在未100%匹配的材料,不能反写材料主编码!", MessageBoxIcon.Warning);
return;
}*/
int count = BLL.PipelineMatService.UpdateMaterialCodeByMatchOutputs(matchedMaterials);
ShowNotify("已保存材料主编码" + count.ToString() + "条!", MessageBoxIcon.Success);
RefreshMatchResult();
if (Grid2.SelectedRowIDArray.Any())
{
BindMaterialDetail(Grid2.SelectedRowIDArray.First());
}
}
protected void btnGenTask_Click(object sender, EventArgs e)
{
if (Grid2.SelectedRowIDArray.Count() > 0)
if (GetSelectedWeldJointIdsFromGrid1().Any())
{
if (SaveTask())
{
@@ -760,23 +850,30 @@ namespace FineUIPro.Web.HJGL.WeldingManage
}
else
{
ShowNotify("请先选择需要发起任单的管线", MessageBoxIcon.Warning);
ShowNotify("请先在材料匹配明细中选择需要生成任务单的焊口", MessageBoxIcon.Warning);
}
}
private bool SaveTask()
{
var selectedWeldJointIds = GetSelectedWeldJointIdsFromGrid1();
if (!selectedWeldJointIds.Any())
{
ShowNotify("请先在材料匹配明细中选择需要生成任务单的焊口!", MessageBoxIcon.Warning);
return false;
}
var weldingRods = from x in Funs.DB.Base_Consumables where x.ConsumablesType == "2" select x;
var weldingWires = from x in Funs.DB.Base_Consumables where x.ConsumablesType == "1" select x;
var selectedWeldJointIdList = selectedWeldJointIds.ToList();
var selectRowId = (from x in Funs.DB.View_HJGL_NoWeldJointFind
where Grid2.SelectedRowIDArray.ToList().Contains(x.PipelineId) && x.WeldingDailyId == null &&
where selectedWeldJointIdList.Contains(x.WeldJointId) && x.WeldingDailyId == null &&
x.WeldTaskId == null && x.WeldingMethodCode != null
select x).ToList();
Dictionary<string, string> unitworkTaskCode = new Dictionary<string, string>();
Dictionary<string, string> unitworkSerialNumber = new Dictionary<string, string>();
Dictionary<int, string> matchPipeline = new Dictionary<int, string>();
foreach (var rowIndex in Grid2.SelectedRowIndexArray)
for (int rowIndex = 0; rowIndex < Grid2.Rows.Count; rowIndex++)
{
matchPipeline.Add(rowIndex + 1, Grid2.Rows[rowIndex].RowID);
}
@@ -784,16 +881,6 @@ namespace FineUIPro.Web.HJGL.WeldingManage
{
selectRowId = selectRowId.Where(x => x.JointAttribute == "预制口").ToList();
}
var priorityWeldJointIds = GetPriorityWeldJointIds(Grid2.SelectedRowIDArray.ToList());
if (priorityWeldJointIds.Any())
{
if (priorityWeldJointIds.Any(x => !x.Value.Any()))
{
ShowNotify("选中组件未找到关联焊口,无法按组件生成任务单!", MessageBoxIcon.Warning);
return false;
}
selectRowId = selectRowId.Where(x => !priorityWeldJointIds.ContainsKey(x.PipelineId) || priorityWeldJointIds[x.PipelineId].Contains(x.WeldJointId)).ToList();
}
if (!selectRowId.Any())
{
ShowNotify("未找到可生成任务单的焊口!", MessageBoxIcon.Warning);
@@ -909,28 +996,41 @@ namespace FineUIPro.Web.HJGL.WeldingManage
return true;
}
private HashSet<string> GetSelectedWeldJointIdsFromGrid1()
{
var selectedWeldJointIds = new HashSet<string>();
if (Grid1.SelectedRowIndexArray == null)
{
return selectedWeldJointIds;
}
foreach (int rowIndex in Grid1.SelectedRowIndexArray)
{
if (Grid1.DataKeys[rowIndex].Length < 4)
{
continue;
}
string weldJointId = Grid1.DataKeys[rowIndex][3]?.ToString();
if (!string.IsNullOrEmpty(weldJointId))
{
selectedWeldJointIds.Add(weldJointId);
}
}
return selectedWeldJointIds;
}
private Dictionary<string, HashSet<string>> GetPriorityWeldJointIds(List<string> selectedPipelineIds)
{
var result = new Dictionary<string, HashSet<string>>();
var selectedPriority = priorityComponents
var selectedPriority = priorityWeldJoints
.Where(x => selectedPipelineIds.Contains(x.Key) && x.Value != null && x.Value.Any())
.ToList();
foreach (var item in selectedPriority)
{
string pipelineId = item.Key;
var componentCodes = item.Value.ToList();
var weldJointIds = (from joint in Funs.DB.HJGL_Pipeline_ComponentJoint
join weldJoint in Funs.DB.HJGL_WeldJoint on joint.WeldJointId equals weldJoint.WeldJointId
join component in Funs.DB.HJGL_Pipeline_Component on joint.PipelineComponentId equals component.PipelineComponentId into componentJoin
from componentItem in componentJoin.DefaultIfEmpty()
where joint.WeldJointId != null
&& weldJoint.PipelineId == pipelineId
&& ((componentItem != null && componentCodes.Contains(componentItem.PipelineComponentCode))
|| componentCodes.Contains(joint.PipelineComponentCode))
select joint.WeldJointId).Distinct().ToList();
result[pipelineId] = new HashSet<string>(weldJointIds);
result[item.Key] = new HashSet<string>(item.Value);
}
return result;