diff --git a/SGGL/BLL/CLGL/TwArrivalStatisticsService.cs b/SGGL/BLL/CLGL/TwArrivalStatisticsService.cs index 71b767b2..81697dda 100644 --- a/SGGL/BLL/CLGL/TwArrivalStatisticsService.cs +++ b/SGGL/BLL/CLGL/TwArrivalStatisticsService.cs @@ -136,9 +136,11 @@ namespace BLL foreach (var material in requiredMaterials) { material.Id = Guid.NewGuid().ToString(); + // 材料导入只保存材料编码 Code,匹配时按 Code 从库存中挑选实际材料主编码 PipeLineMatCode。 var stock = matchByMaterialCodeLibCode ? stockList .Where(x => x.Code == material.MaterialCode && (x.StockNum ?? 0) > 0) + // 优先选择库存能覆盖本条需求的材料主编码,再按主编码稳定排序,保证匹配结果可复现。 .OrderByDescending(x => (x.StockNum ?? 0) >= (material.NeedNum ?? 0)) .ThenBy(x => x.PipeLineMatCode) .FirstOrDefault() @@ -157,8 +159,9 @@ namespace BLL material.MatchRateString = Math.Round((decimal)(material.MatchRate ?? 0) * 100, 2).ToString() + "%"; } + // 这里保存的是本次计算匹配到的临时材料主编码;是否已反写以 HJGL_PipeLineMat.MaterialCode 为准。 material.MatchMaterialCode = stock?.PipeLineMatCode; - //修改stockList对应的库存数量 + // 本轮匹配会连续消耗同一库存快照,防止后续材料重复占用已匹配数量。 if (stock != null) { stock.StockNum -= material.MatchNum; @@ -268,7 +271,8 @@ namespace BLL join m in db.WBS_UnitWork on z.UnitWorkId equals m.UnitWorkId join w in db.HJGL_WeldJoint on x.WeldJointId equals w.WeldJointId into weldJoin from w in weldJoin.DefaultIfEmpty() - where z.ProjectId == projectId && pipelineIds.Contains(z.PipelineId) && x.PrefabricatedComponents != "" //x.PrefabricatedComponents!="" 用于筛选非散件材料 + // 材料匹配只处理所需量大于0的非散件材料,避免零用量明细占用库存或影响焊口生成任务单判断。 + where z.ProjectId == projectId && pipelineIds.Contains(z.PipelineId) && x.PrefabricatedComponents != "" && (x.Number ?? 0) > 0 select new { PipeLineMat = x, @@ -302,18 +306,21 @@ namespace BLL var requiredMaterials = pipeLineMats.Select(x => { HJGL_MaterialCodeLib lib = null; + // 已反写材料主编码时,优先按 MaterialCode 精确取材料库信息。 if (!string.IsNullOrEmpty(x.PipeLineMat.MaterialCode) && libByMaterialCode.ContainsKey(x.PipeLineMat.MaterialCode)) { lib = libByMaterialCode[x.PipeLineMat.MaterialCode]; } + // 未反写时只能按导入材料编码 Code 找候选材料库,用于展示材料名称、规格等基础信息。 else if (!string.IsNullOrEmpty(x.PipeLineMat.MaterialCode2) && libByCode.ContainsKey(x.PipeLineMat.MaterialCode2)) { lib = libByCode[x.PipeLineMat.MaterialCode2]; } + // MaterialCode 对外展示导入材料编码,避免把临时匹配出的材料主编码误当成已确认结果。 string code = !string.IsNullOrEmpty(x.PipeLineMat.MaterialCode2) ? x.PipeLineMat.MaterialCode2 : lib?.Code; return new Tw_PipeMatMatchOutput - { + { Id = Guid.NewGuid().ToString(), PipeLineMatId = x.PipeLineMat.PipeLineMatId, PipelineId = x.PipeLineMat.PipelineId, @@ -341,6 +348,7 @@ namespace BLL var pipelineMaterials = requiredMaterials.Where(x => x.PipelineId == id).ToList(); if (priorityWeldJoints != null && priorityWeldJoints.ContainsKey(id) && priorityWeldJoints[id] != null && priorityWeldJoints[id].Any()) { + // 手动优先焊口只改变本次匹配消耗顺序,不写入长期规则。 var weldJointIds = priorityWeldJoints[id]; newRequiredMaterials.AddRange(pipelineMaterials .Where(x => weldJointIds.Contains(x.WeldJointId)) diff --git a/SGGL/BLL/HJGL/WeldingManage/WeldJointService.cs b/SGGL/BLL/HJGL/WeldingManage/WeldJointService.cs index 5c3ce0dd..96f318b2 100644 --- a/SGGL/BLL/HJGL/WeldingManage/WeldJointService.cs +++ b/SGGL/BLL/HJGL/WeldingManage/WeldJointService.cs @@ -465,6 +465,8 @@ namespace BLL baseQuery = baseQuery.Where(x => x.PipelineCode.Contains(model.PipelineCode)); if (!string.IsNullOrEmpty(model.WeldJointCode)) baseQuery = baseQuery.Where(x => x.WeldJointCode.Contains(model.WeldJointCode)); + if (!string.IsNullOrEmpty(model.IsWeldOK)) + baseQuery = baseQuery.Where(x => x.IsWeldOK == model.IsWeldOK); //构建排序 baseQuery = baseQuery.OrderBy(x => x.PipelineId).ThenBy(x => x.WeldJointCode); @@ -483,6 +485,8 @@ namespace BLL baseQuery = baseQuery.Where(x => x.PipelineCode.Contains(model.PipelineCode)); if (!string.IsNullOrEmpty(model.WeldJointCode)) baseQuery = baseQuery.Where(x => x.WeldJointCode.Contains(model.WeldJointCode)); + if (!string.IsNullOrEmpty(model.IsWeldOK)) + baseQuery = baseQuery.Where(x => x.IsWeldOK == model.IsWeldOK); return baseQuery.ToList(); } @@ -502,6 +506,8 @@ namespace BLL baseQuery = baseQuery.Where(x => x.PipelineCode.Contains(model.PipelineCode)); if (!string.IsNullOrEmpty(model.WeldJointCode)) baseQuery = baseQuery.Where(x => x.WeldJointCode.Contains(model.WeldJointCode)); + if (!string.IsNullOrEmpty(model.IsWeldOK)) + baseQuery = baseQuery.Where(x => x.IsWeldOK == model.IsWeldOK); // 阶段三:排序与分页控制(索引优化关键) var orderedQuery = baseQuery.OrderBy(x => x.PipelineId).ThenBy(x => x.WeldJointCode); diff --git a/SGGL/FineUIPro.Web/Controls/Fastreport.aspx.cs b/SGGL/FineUIPro.Web/Controls/Fastreport.aspx.cs index 9165301e..aff7e584 100644 --- a/SGGL/FineUIPro.Web/Controls/Fastreport.aspx.cs +++ b/SGGL/FineUIPro.Web/Controls/Fastreport.aspx.cs @@ -43,14 +43,6 @@ namespace FineUIPro.Web.Controls { throw new System.IO.FileNotFoundException("打印模板不存在!", ReportPath); } - if (dataTables != null && dataTables.Count > 0) - { - for (int i = 0; i < dataTables.Count; i++) - { - WebReport1.RegisterData(dataTables[i], dataTables[i].TableName); - } - - } WebReport1.Report.Load(ReportPath); if (WebReport1.Report.Dictionary.Connections.Count > 0) { @@ -61,6 +53,15 @@ namespace FineUIPro.Web.Controls WebReport1.Report.Save(ReportPath); } } + // 先加载模板,再注册运行时数据,避免 Load 过程把已注册数据源覆盖掉。 + if (dataTables != null && dataTables.Count > 0) + { + for (int i = 0; i < dataTables.Count; i++) + { + WebReport1.RegisterData(dataTables[i], dataTables[i].TableName); + } + + } WebReport1.ReportFile = ReportPath; WebReport1.PdfShowPrintDialog = false; WebReport1.Prepare(); diff --git a/SGGL/FineUIPro.Web/File/Fastreport/材料入库条码.frx b/SGGL/FineUIPro.Web/File/Fastreport/材料入库条码.frx index feb3e7b7..f6dc57ce 100644 --- a/SGGL/FineUIPro.Web/File/Fastreport/材料入库条码.frx +++ b/SGGL/FineUIPro.Web/File/Fastreport/材料入库条码.frx @@ -1,5 +1,5 @@  - + @@ -18,9 +18,9 @@ - + - + diff --git a/SGGL/FineUIPro.Web/File/Fastreport/焊口打印.frx b/SGGL/FineUIPro.Web/File/Fastreport/焊口打印.frx index aff64738..8123c073 100644 --- a/SGGL/FineUIPro.Web/File/Fastreport/焊口打印.frx +++ b/SGGL/FineUIPro.Web/File/Fastreport/焊口打印.frx @@ -1,5 +1,5 @@  - + using System; using System.Collections; using System.Collections.Generic; @@ -99,7 +99,7 @@ namespace FastReport } - + diff --git a/SGGL/FineUIPro.Web/File/Fastreport/焊口铭牌.frx b/SGGL/FineUIPro.Web/File/Fastreport/焊口铭牌.frx new file mode 100644 index 00000000..a3bec0e2 --- /dev/null +++ b/SGGL/FineUIPro.Web/File/Fastreport/焊口铭牌.frx @@ -0,0 +1,113 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/SGGL/FineUIPro.Web/File/Fastreport/管道焊接任务单.frx b/SGGL/FineUIPro.Web/File/Fastreport/管道焊接任务单.frx index d901b971..df01acda 100644 --- a/SGGL/FineUIPro.Web/File/Fastreport/管道焊接任务单.frx +++ b/SGGL/FineUIPro.Web/File/Fastreport/管道焊接任务单.frx @@ -78,11 +78,16 @@ namespace FastReport - - - - + + + + + + + + + @@ -147,30 +152,45 @@ namespace FastReport - - - - - - - + + + + + + + + + + + + - - - - + + + + + + + + + - - - - + + + + + + + + + diff --git a/SGGL/FineUIPro.Web/HJGL/InfoQuery/JointQuery.aspx b/SGGL/FineUIPro.Web/HJGL/InfoQuery/JointQuery.aspx index d3b4b83b..dea4a8ee 100644 --- a/SGGL/FineUIPro.Web/HJGL/InfoQuery/JointQuery.aspx +++ b/SGGL/FineUIPro.Web/HJGL/InfoQuery/JointQuery.aspx @@ -67,6 +67,12 @@ + + + + + + + diff --git a/SGGL/FineUIPro.Web/HJGL/InfoQuery/JointQuery.aspx.cs b/SGGL/FineUIPro.Web/HJGL/InfoQuery/JointQuery.aspx.cs index ed50d01b..d75e5a03 100644 --- a/SGGL/FineUIPro.Web/HJGL/InfoQuery/JointQuery.aspx.cs +++ b/SGGL/FineUIPro.Web/HJGL/InfoQuery/JointQuery.aspx.cs @@ -378,14 +378,11 @@ namespace FineUIPro.Web.HJGL.InfoQuery private void BindGrid() { - Model.View_HJGL_WeldJoint model = new Model.View_HJGL_WeldJoint(); - model.ProjectId = this.CurrUser.LoginProjectId; - model.WeldJointCode = this.txtWeldJointCode.Text; + Model.View_HJGL_WeldJoint model = GetCurrentWeldJointQueryModel(); if (this.tvControlItem.SelectedNode.CommandName.Split('|').Count() == 2) { model.UnitWorkId = this.tvControlItem.SelectedNodeID; - model.WeldJointCode = this.txtWeldJointCode.Text; var list = BLL.WeldJointService.GetDataBymodel(model, Grid1.PageIndex, Grid1.PageSize); Grid1.RecordCount = list.Total; Grid1.DataSource = list.Data; @@ -403,6 +400,36 @@ namespace FineUIPro.Web.HJGL.InfoQuery } } + /// + /// 汇总当前焊口台账查询条件,保证列表、导出和打印使用同一套过滤规则。 + /// + private Model.View_HJGL_WeldJoint GetCurrentWeldJointQueryModel() + { + return new Model.View_HJGL_WeldJoint + { + ProjectId = this.CurrUser.LoginProjectId, + WeldJointCode = this.txtWeldJointCode.Text.Trim(), + IsWeldOK = this.ddlWeldState.SelectedValue + }; + } + + /// + /// 按当前树节点和筛选条件获取焊口铭牌待打印焊口。 + /// + private List GetCurrentWeldJointList() + { + Model.View_HJGL_WeldJoint model = GetCurrentWeldJointQueryModel(); + if (this.tvControlItem.SelectedNode.CommandName.Split('|').Count() == 2) + { + model.UnitWorkId = this.tvControlItem.SelectedNodeID; + } + else if (this.tvControlItem.SelectedNode.CommandName == "管线") + { + model.PipelineId = this.tvControlItem.SelectedNodeID; + } + return BLL.WeldJointService.GetViewWeldJointsBymodel(model); + } + private void get3DParmeter_weldjoint(List model) { if (model.Any()) @@ -577,7 +604,7 @@ namespace FineUIPro.Web.HJGL.InfoQuery string fileName = ""; if (this.tvControlItem.SelectedNode.CommandName.Split('|').Count() == 2) //单位工程 { - Model.View_HJGL_WeldJoint model = new Model.View_HJGL_WeldJoint(); + Model.View_HJGL_WeldJoint model = GetCurrentWeldJointQueryModel(); model.UnitWorkId = this.tvControlItem.SelectedNodeID; var list = BLL.WeldJointService.GetViewWeldJointsBymodel(model); View_HJGL_WeldJoint = list; @@ -585,6 +612,8 @@ namespace FineUIPro.Web.HJGL.InfoQuery } else if (this.tvControlItem.SelectedNode.CommandName == "管线") { + var list = GetCurrentWeldJointList(); + View_HJGL_WeldJoint = list; fileName = PipelineService.GetPipelineByPipelineId(this.tvControlItem.SelectedNodeID)?.PipelineCode; } @@ -737,8 +766,11 @@ namespace FineUIPro.Web.HJGL.InfoQuery { if (this.tvControlItem.SelectedNode.CommandName.Split('|').Count() == 2) { + var currentQuery = GetCurrentWeldJointQueryModel(); var q = (from x in Funs.DB.View_HJGL_WeldJoint where x.ProjectId == this.CurrUser.LoginProjectId && x.UnitWorkId == this.tvControlItem.SelectedNodeID + && (string.IsNullOrEmpty(currentQuery.WeldJointCode) || x.WeldJointCode.Contains(currentQuery.WeldJointCode)) + && (string.IsNullOrEmpty(currentQuery.IsWeldOK) || x.IsWeldOK == currentQuery.IsWeldOK) select new { PipelineId = x.PipelineId, @@ -787,6 +819,206 @@ namespace FineUIPro.Web.HJGL.InfoQuery } } + + /// + /// 打印当前筛选范围内的焊口铭牌。 + /// + protected void btnPrintJointNameplate_Click(object sender, EventArgs e) + { + if (this.Grid1.SelectedRowIDArray == null || this.Grid1.SelectedRowIDArray.Length == 0) + { + Alert.Show("请选择要打印的焊口"); + return; + } + + var weldJointList = GetSelectedWeldJointList(); + if (weldJointList == null || weldJointList.Count == 0) + { + Alert.Show("当前条件下没有可打印的焊口"); + return; + } + + var tb = BuildWeldJointNameplateTable(weldJointList); + if (tb == null || tb.Rows.Count == 0) + { + Alert.Show("当前条件下没有可打印的焊口"); + return; + } + + BLL.FastReportService.ResetData(); + tb.TableName = "Table1"; + BLL.FastReportService.AddFastreportTable(tb); + + string rootPath = Server.MapPath("~/"); + string initTemplatePath = "File\\Fastreport\\焊口铭牌.frx"; + if (File.Exists(rootPath + initTemplatePath)) + { + PageContext.RegisterStartupScript(Window2.GetShowReference(String.Format("~/Controls/Fastreport.aspx?ReportPath={0}", rootPath + initTemplatePath))); + } + } + + /// + /// 获取当前勾选的焊口。 + /// + private List GetSelectedWeldJointList() + { + var ids = this.Grid1.SelectedRowIDArray; + if (ids == null || ids.Length == 0) + { + return new List(); + } + + List list = new List(); + foreach (string id in ids) + { + var item = WeldJointService.GetViewWeldJointById(id); + if (item != null) + { + list.Add(item); + } + } + + return list; + } + + /// + /// 组装焊口铭牌打印数据,材料列优先使用已反写主编码对应的材料库信息。 + /// + private DataTable BuildWeldJointNameplateTable(List weldJointList) + { + DataTable tb = new DataTable(); + // FastReport 对中文字段名兼容性不稳定,这里统一改成 ASCII 列名,模板只负责显示中文表头。 + tb.Columns.Add("PipelineCode", typeof(string)); + tb.Columns.Add("SegmentCode", typeof(string)); + tb.Columns.Add("WeldJointNo", typeof(string)); + tb.Columns.Add("MaterialText", typeof(string)); + tb.Columns.Add("Spec", typeof(string)); + tb.Columns.Add("DesignTemperature", typeof(string)); + tb.Columns.Add("MaterialCode1", typeof(string)); + tb.Columns.Add("MaterialCode2", typeof(string)); + tb.Columns.Add("HeatNo1", typeof(string)); + tb.Columns.Add("BatchNo1", typeof(string)); + tb.Columns.Add("Material1Code", typeof(string)); + tb.Columns.Add("Material2Code", typeof(string)); + tb.Columns.Add("HeatNo2", typeof(string)); + tb.Columns.Add("BatchNo2", typeof(string)); + tb.Columns.Add("WelderCode", typeof(string)); + tb.Columns.Add("WeldingDate", typeof(string)); + tb.Columns.Add("WeldCheck", typeof(string)); + tb.Columns.Add("CheckDate", typeof(string)); + tb.Columns.Add("CleanCheck", typeof(string)); + tb.Columns.Add("CleanCheckDate", typeof(string)); + tb.Columns.Add("WeldJointId", typeof(string)); + + var jointIds = weldJointList.Select(x => x.WeldJointId).Where(x => !string.IsNullOrEmpty(x)).Distinct().ToList(); + var pipelineIds = weldJointList.Select(x => x.PipelineId).Where(x => !string.IsNullOrEmpty(x)).Distinct().ToList(); + var materialRows = (from x in Funs.DB.HJGL_PipeLineMat + where jointIds.Contains(x.WeldJointId) && pipelineIds.Contains(x.PipelineId) + orderby x.WeldJointId, x.Number, x.PipeLineMatId + select x).ToList(); + + var materialCodes = materialRows.Where(x => !string.IsNullOrEmpty(x.MaterialCode)).Select(x => x.MaterialCode).Distinct().ToList(); + var materialCode2s = materialRows.Where(x => !string.IsNullOrEmpty(x.MaterialCode2)).Select(x => x.MaterialCode2).Distinct().ToList(); + var libsByMaterialCode = Funs.DB.HJGL_MaterialCodeLib.Where(x => materialCodes.Contains(x.MaterialCode)).ToList().GroupBy(x => x.MaterialCode).ToDictionary(x => x.Key, x => x.First()); + var libsByCode = Funs.DB.HJGL_MaterialCodeLib.Where(x => materialCode2s.Contains(x.Code)).ToList().GroupBy(x => x.Code).ToDictionary(x => x.Key, x => x.First()); + + foreach (var joint in weldJointList) + { + var rows = materialRows.Where(x => x.WeldJointId == joint.WeldJointId).ToList(); + var row1 = rows.FirstOrDefault(); + var row2 = rows.Skip(1).FirstOrDefault(); + + // 预制组件号按现有业务即预制组件编码显示,避免和管线号混淆。 + string preCode = row1 == null ? string.Empty : row1.PrefabricatedComponents; + if (string.IsNullOrEmpty(preCode)) + { + preCode = joint.TaskCode; + } + + // 焊口号只显示末级编号,和焊口贴纸二维码对应的展示一致,避免带管线前缀。 + string weldJointNo = joint.WeldJointCode; + if (!string.IsNullOrEmpty(weldJointNo) && weldJointNo.Contains("/")) + { + weldJointNo = weldJointNo.Substring(weldJointNo.LastIndexOf("/") + 1); + } + + // 优先用已反写主编码匹配材料库;没有主编码时,用导入材料编码 Code 兜底。 + HJGL_MaterialCodeLib lib1 = GetMaterialLib(row1, libsByMaterialCode, libsByCode); + HJGL_MaterialCodeLib lib2 = GetMaterialLib(row2, libsByMaterialCode, libsByCode); + + DataRow dr = tb.NewRow(); + dr["PipelineCode"] = joint.PipelineCode; + dr["SegmentCode"] = preCode; + dr["WeldJointNo"] = weldJointNo; + dr["MaterialText"] = string.IsNullOrEmpty(joint.Material1Code) ? joint.Material2Code : joint.Material1Code; + dr["Spec"] = joint.Specification; + dr["DesignTemperature"] = joint.PreTemperature; + dr["MaterialCode1"] = GetMaterialDisplayCode(row1, lib1); + dr["HeatNo1"] = lib1 == null ? string.Empty : lib1.HeatNo; + dr["BatchNo1"] = lib1 == null ? string.Empty : lib1.BatchNo; + dr["MaterialCode2"] = GetMaterialDisplayCode(row2, lib2); + dr["HeatNo2"] = lib2 == null ? string.Empty : lib2.HeatNo; + dr["BatchNo2"] = lib2 == null ? string.Empty : lib2.BatchNo; + dr["WelderCode"] = string.IsNullOrEmpty(joint.WelderCode) ? (string.IsNullOrEmpty(joint.BackingWelderCode) ? joint.CoverWelderCode : joint.BackingWelderCode) : joint.WelderCode; + dr["WeldingDate"] = joint.WeldingDate; + dr["WeldCheck"] = joint.CheckResult; + dr["CheckDate"] = joint.AuditDate == null ? string.Empty : joint.AuditDate.Value.ToString("yyyy-MM-dd"); + dr["CleanCheck"] = joint.IsHotProessStr; + dr["CleanCheckDate"] = joint.AuditDate2 == null ? string.Empty : joint.AuditDate2.Value.ToString("yyyy-MM-dd"); + dr["WeldJointId"] = joint.WeldJointId; + dr["Material1Code"] = joint.Material1Code; + dr["Material2Code"] = joint.Material2Code; + tb.Rows.Add(dr); + } + + return tb; + } + + /// + /// 获取材料库记录,优先按主编码,其次按导入编码。 + /// + private HJGL_MaterialCodeLib GetMaterialLib(HJGL_PipeLineMat row, Dictionary libsByMaterialCode, Dictionary libsByCode) + { + if (row == null) + { + return null; + } + + if (!string.IsNullOrEmpty(row.MaterialCode) && libsByMaterialCode.ContainsKey(row.MaterialCode)) + { + return libsByMaterialCode[row.MaterialCode]; + } + + if (!string.IsNullOrEmpty(row.MaterialCode2) && libsByCode.ContainsKey(row.MaterialCode2)) + { + return libsByCode[row.MaterialCode2]; + } + + return null; + } + + /// + /// 返回打印用物料编码,优先显示导入编码。 + /// + private string GetMaterialDisplayCode(HJGL_PipeLineMat row, HJGL_MaterialCodeLib lib) + { + if (row == null) + { + return string.Empty; + } + + if (!string.IsNullOrEmpty(row.MaterialCode2)) + { + return row.MaterialCode2; + } + + if (lib != null) + { + return lib.Code; + } + + return row.MaterialCode; + } /// /// 导出方法 /// @@ -873,4 +1105,4 @@ namespace FineUIPro.Web.HJGL.InfoQuery } -} \ No newline at end of file +} diff --git a/SGGL/FineUIPro.Web/HJGL/InfoQuery/JointQuery.aspx.designer.cs b/SGGL/FineUIPro.Web/HJGL/InfoQuery/JointQuery.aspx.designer.cs index 5ec8576e..daa99b3d 100644 --- a/SGGL/FineUIPro.Web/HJGL/InfoQuery/JointQuery.aspx.designer.cs +++ b/SGGL/FineUIPro.Web/HJGL/InfoQuery/JointQuery.aspx.designer.cs @@ -155,7 +155,16 @@ namespace FineUIPro.Web.HJGL.InfoQuery { /// 若要进行修改,请将字段声明从设计器文件移到代码隐藏文件。 /// protected global::FineUIPro.TextBox txtWeldJointCode; - + + /// + /// ddlWeldState 控件。 + /// + /// + /// 自动生成的字段。 + /// 若要进行修改,请将字段声明从设计器文件移到代码隐藏文件。 + /// + protected global::FineUIPro.DropDownList ddlWeldState; + /// /// ToolbarFill2 控件。 /// @@ -191,6 +200,15 @@ namespace FineUIPro.Web.HJGL.InfoQuery { /// 若要进行修改,请将字段声明从设计器文件移到代码隐藏文件。 /// protected global::FineUIPro.Button btnOutNoComPipeline; + + /// + /// btnPrintJointNameplate 控件。 + /// + /// + /// 自动生成的字段。 + /// 若要进行修改,请将字段声明从设计器文件移到代码隐藏文件。 + /// + protected global::FineUIPro.Button btnPrintJointNameplate; /// /// btnGetChart 控件。 diff --git a/SGGL/FineUIPro.Web/HJGL/WeldingManage/WeldMatMatch.aspx b/SGGL/FineUIPro.Web/HJGL/WeldingManage/WeldMatMatch.aspx index fb520189..935cc52d 100644 --- a/SGGL/FineUIPro.Web/HJGL/WeldingManage/WeldMatMatch.aspx +++ b/SGGL/FineUIPro.Web/HJGL/WeldingManage/WeldMatMatch.aspx @@ -146,7 +146,6 @@ - @@ -155,6 +154,10 @@ + + + + @@ -188,7 +191,7 @@ + SortField="PipelineCode" SortDirection="ASC" OnSort="Grid1_Sort" EnableCheckBoxSelect="true" EnableSummary="true" SummaryPosition="Bottom" > + /// 页面首次加载时初始化仓库、流水段、匹配状态和左侧WBS管线树。 + /// + /// 事件源。 + /// 事件参数。 protected void Page_Load(object sender, EventArgs e) { //ctlAuditFlow.Url = BLL.Project_SysSetService.GetAvevaNetUrl(this.CurrUser.LoginProjectId); @@ -220,6 +225,10 @@ namespace FineUIPro.Web.HJGL.WeldingManage } } } + /// + /// 按分页方式向试压包节点追加管线子节点。 + /// + /// 需要加载管线的试压包树节点。 private void BindNodes(TreeNode node) { //var NowComPipelineCode = PipelineService.GetNoComPipelinesByUnitWordId(node.NodeID); @@ -266,6 +275,11 @@ namespace FineUIPro.Web.HJGL.WeldingManage } } + /// + /// 统计单位工程下各试压包可参与材料匹配的管线数量。 + /// + /// 单位工程ID。 + /// 可参与材料匹配的管线数量。 private int GetUnitWorkTestPackagePipelineCount(string unitWorkId) { var testPackageIds = (from x in Funs.DB.PTP_TestPackage @@ -275,6 +289,10 @@ namespace FineUIPro.Web.HJGL.WeldingManage return testPackageIds.Select(x => GetTestPackagePipelineList(x).Count()).Sum(); } + /// + /// 为单位工程节点绑定包含管线的试压包节点。 + /// + /// 单位工程树节点。 private void BindTestPackageNodes(TreeNode unitWorkNode) { var testPackages = (from x in Funs.DB.PTP_TestPackage @@ -308,6 +326,11 @@ namespace FineUIPro.Web.HJGL.WeldingManage } } + /// + /// 获取指定试压包下当前仓库、区域和筛选条件内尚未完成出库的管线。 + /// + /// 试压包ID。 + /// 符合材料匹配入口条件的管线列表。 private List GetTestPackagePipelineList(string ptpId) { var completeInOutPlanDetailRelationList = from x in Funs.DB.Tw_InOutPlanDetail_Relation @@ -334,6 +357,11 @@ namespace FineUIPro.Web.HJGL.WeldingManage return pipeline.Distinct().ToList(); } + /// + /// 展开试压包节点时懒加载管线节点。 + /// + /// 事件源。 + /// 树节点事件参数。 protected void tvControlItem_TreeNodeExpanded(object sender, TreeNodeEventArgs e) { if (e.Node.Nodes[0].NodeID == "加载管线...") @@ -345,6 +373,11 @@ namespace FineUIPro.Web.HJGL.WeldingManage #endregion + /// + /// 按当前筛选条件重新加载左侧WBS管线树。 + /// + /// 事件源。 + /// 事件参数。 protected void btnTreeFind_Click(object sender, EventArgs e) { this.InitTreeMenu(); @@ -375,6 +408,9 @@ namespace FineUIPro.Web.HJGL.WeldingManage #endregion #region 数据绑定 + /// + /// 绑定当前选中管线的材料汇总信息。 + /// private void BindGrid() { string strSql = @"SELECT ISNULL(pipe.MaterialCode2, lib.Code) AS MaterialCode, @@ -469,6 +505,9 @@ namespace FineUIPro.Web.HJGL.WeldingManage } } + /// + /// 绑定已加入匹配的管线列表,并标识正在出库中的管线。 + /// void BindGrid3() { @@ -492,6 +531,11 @@ namespace FineUIPro.Web.HJGL.WeldingManage #endregion #region 表格事件 + /// + /// 材料匹配明细行绑定事件,保留历史行样式扩展入口。 + /// + /// 事件源。 + /// Grid行绑定事件参数。 protected void Grid1_RowDataBound(object sender, GridRowEventArgs e) { // DataRowView row = e.DataItem as DataRowView; @@ -506,16 +550,27 @@ namespace FineUIPro.Web.HJGL.WeldingManage } + /// + /// 绑定指定管线的材料匹配明细,设置行颜色、优先焊口选中状态和可生成任务单合计。 + /// + /// 管线ID。 private void BindMaterialDetail(string pipelineId) { // 任务单只允许从未生成任务单的焊口材料中选择,避免重复生成焊接任务。 var tb = GetNoTaskMaterialDetails() .Where(x => x.PipelineId == pipelineId) + // 明细固定按管线号、预制组件号、焊口号、材料编码排序,便于同一焊口材料连续展示。 + .OrderBy(x => x.PipelineCode) + .ThenBy(x => x.PrefabricatedComponents) + .ThenBy(x => x.WeldJointCode) + .ThenBy(x => x.MaterialCode) .ToList(); Grid1.DataSource = tb; Grid1.DataBind(); var selectList = new List(); + // 明细行绿色必须以数据库已反写字段判断,不能用本次匹配结果中的 MatchMaterialCode。 + var confirmedPipeLineMatIds = GetConfirmedPipeLineMatIds(tb); for (int i = 0; i < Grid1.Rows.Count; i++) { var model = Grid1.Rows[i].DataItem as Tw_PipeMatMatchOutput; @@ -524,10 +579,19 @@ namespace FineUIPro.Web.HJGL.WeldingManage continue; } - if (IsPriorityWeldJoint(model.PipelineId, model.WeldJointId)) + bool isPriority = IsPriorityWeldJoint(model.PipelineId, model.WeldJointId); + if (isPriority) + { + selectList.Add(model.Id); + } + + if (IsMaterialCodeConfirmed(model, confirmedPipeLineMatIds)) + { + Grid1.Rows[i].RowCssClass = "green"; + } + else if (isPriority) { Grid1.Rows[i].RowCssClass = "priority"; - selectList.Add(model.Id); } else if (model.MatchRate < 1 || model.MatchRate == null) { @@ -536,6 +600,22 @@ namespace FineUIPro.Web.HJGL.WeldingManage } Grid1.SelectedRowIDArray = selectList.ToArray(); + BindTaskWeldJointSummary(tb); + } + + /// + /// 在材料明细底部汇总当前明细中真正可生成任务单的焊口数量。 + /// + /// 当前展示的材料匹配明细。 + private void BindTaskWeldJointSummary(List materialDetails) + { + // 合计行复用生成任务单的同一套判断,保证页面显示数量和按钮实际生成数量一致。 + int taskWeldJointCount = GetTaskWeldJointIdsFromMaterialDetails(materialDetails).Count; + JObject summary = new JObject(); + summary.Add("PipelineCode", "合计"); + summary.Add("PrefabricatedComponents", "可生成任务单焊口数:"); + summary.Add("WeldJointCode", taskWeldJointCount.ToString()); + Grid1.SummaryData = summary; } /// @@ -565,6 +645,12 @@ namespace FineUIPro.Web.HJGL.WeldingManage .ToList(); } + /// + /// 判断焊口是否被用户设置为当前管线的本次优先匹配焊口。 + /// + /// 管线ID。 + /// 焊口ID。 + /// 已设置优先匹配返回 true,否则返回 false。 private bool IsPriorityWeldJoint(string pipelineId, string weldJointId) { return !string.IsNullOrEmpty(pipelineId) @@ -573,6 +659,61 @@ namespace FineUIPro.Web.HJGL.WeldingManage && priorityWeldJoints[pipelineId].Contains(weldJointId); } + /// + /// 获取材料明细中已持久化反写材料主编码的管线材料ID集合。 + /// + /// 材料匹配明细。 + /// 已反写材料主编码的管线材料ID集合。 + private HashSet GetConfirmedPipeLineMatIds(IEnumerable materialDetails) + { + // 已反写材料主编码的唯一可信来源是 HJGL_PipeLineMat.MaterialCode。 + var pipeLineMatIds = materialDetails == null + ? new List() + : materialDetails + .Where(x => x != null && !string.IsNullOrEmpty(x.PipeLineMatId)) + .Select(x => x.PipeLineMatId) + .Distinct() + .ToList(); + if (!pipeLineMatIds.Any()) + { + return new HashSet(); + } + + var confirmedIds = Funs.DB.HJGL_PipeLineMat + .Where(x => pipeLineMatIds.Contains(x.PipeLineMatId) && x.MaterialCode != null && x.MaterialCode != "") + .Select(x => x.PipeLineMatId) + .ToList(); + return new HashSet(confirmedIds); + } + + /// + /// 判断单条材料明细是否已经反写材料主编码。 + /// + /// 材料匹配明细。 + /// 已反写材料主编码的管线材料ID集合。 + /// 已反写返回 true,否则返回 false。 + private bool IsMaterialCodeConfirmed(Tw_PipeMatMatchOutput model, HashSet confirmedPipeLineMatIds) + { + return model != null + && confirmedPipeLineMatIds != null + && !string.IsNullOrEmpty(model.PipeLineMatId) + && confirmedPipeLineMatIds.Contains(model.PipeLineMatId); + } + + /// + /// 显示材料匹配颜色和任务单生成规则说明。 + /// + /// 事件源。 + /// 事件参数。 + protected void btnMatchHelp_Click(object sender, EventArgs e) + { + Alert.ShowInTop("1、管线绿色为匹配率100%,明细绿色为已反写材料主编码,红色为匹配率小于100%,蓝色为手动优先焊口。
2、一个焊口可能对应多条材料明细,该焊口全部有效明细已反写材料主编码后才允许一键生成任务单。
3、焊口已进行焊前准备,匹配了焊评才能生成任务单", "说明", MessageBoxIcon.Information); + } + + /// + /// 将本次优先匹配焊口状态转换为匹配服务需要的管线-焊口列表结构。 + /// + /// 管线ID到优先焊口ID列表的映射。 private Dictionary> GetPriorityWeldJointList() { return priorityWeldJoints @@ -580,6 +721,9 @@ namespace FineUIPro.Web.HJGL.WeldingManage .ToDictionary(x => x.Key, x => x.Value.ToList()); } + /// + /// 重新计算材料匹配结果,并在刷新管线汇总后恢复原有管线勾选状态。 + /// private void RefreshMatchResult() { // 重新匹配库存会刷新管线汇总表,先暂存选择状态,绑定完成后再恢复。 @@ -593,11 +737,21 @@ namespace FineUIPro.Web.HJGL.WeldingManage BindGrid2(keepSelectedPipelineIds); } + /// + /// 点击材料匹配管线汇总行时刷新该管线的材料明细。 + /// + /// 事件源。 + /// Grid行点击事件参数。 protected void Grid2_RowClick(object sender, GridRowClickEventArgs e) { BindMaterialDetail(Grid2.SelectedRowID); } + /// + /// 点击材料明细行时联动三维模型定位当前管线或单位工程。 + /// + /// 事件源。 + /// Grid行点击事件参数。 protected void Grid1_RowClick(object sender, GridRowClickEventArgs e) { Model.Parameter3D parameter3D = new Model.Parameter3D(); @@ -632,6 +786,11 @@ namespace FineUIPro.Web.HJGL.WeldingManage //ctlAuditFlow.data = parameter3D; //ctlAuditFlow.BindData(); } + /// + /// 记录材料明细排序字段,并按当前选中管线重新绑定明细。 + /// + /// 事件源。 + /// Grid排序事件参数。 protected void Grid1_Sort(object sender, GridSortEventArgs e) { Grid1.SortDirection = e.SortDirection; @@ -650,6 +809,11 @@ namespace FineUIPro.Web.HJGL.WeldingManage #region 按钮事件 + /// + /// 刷新三维模型参数,按当前树节点定位单位工程或管线。 + /// + /// 事件源。 + /// 事件参数。 protected void btnrefresh_Click(object sender, EventArgs e) { if (!string.IsNullOrEmpty(this.tvControlItem.SelectedNodeID)) @@ -713,6 +877,11 @@ namespace FineUIPro.Web.HJGL.WeldingManage } + /// + /// 打开单位工程材料匹配统计窗口。 + /// + /// 事件源。 + /// 事件参数。 protected void btnStatisticsMat_Click(object sender, EventArgs e) { Model.WBS_UnitWork unitWork = BLL.UnitWorkService.GetUnitWorkByUnitWorkId(this.tvControlItem.SelectedNodeID); @@ -726,6 +895,11 @@ namespace FineUIPro.Web.HJGL.WeldingManage } } + /// + /// 将左侧勾选的管线加入本次材料匹配范围并刷新匹配结果。 + /// + /// 事件源。 + /// 事件参数。 protected void btnAddPipelineMatchMat_Click(object sender, EventArgs e) { var selectNodes = tvControlItem.GetCheckedNodes(); @@ -739,6 +913,11 @@ namespace FineUIPro.Web.HJGL.WeldingManage RefreshMatchResult(); } + /// + /// 从本次材料匹配范围移除选中管线,并清理对应的优先焊口状态。 + /// + /// 事件源。 + /// 事件参数。 protected void btnDeletePipelineMatchMat_Click(object sender, EventArgs e) { if (Grid3.SelectedRowIDArray != null && Grid3.SelectedRowIDArray.Any()) @@ -757,7 +936,11 @@ namespace FineUIPro.Web.HJGL.WeldingManage RefreshMatchResult(); } } - + /// + /// 优先匹配选中焊口 + /// + /// + /// protected void btnPriorityComponents_Click(object sender, EventArgs e) { string selectedPipelineId = Grid2.SelectedRowID; @@ -804,6 +987,11 @@ namespace FineUIPro.Web.HJGL.WeldingManage BindMaterialDetail(selectedPipelineId); } + /// + /// 将当前选中管线的匹配结果反写到管线材料主编码。 + /// + /// 事件源。 + /// 事件参数。 protected void btnConfirmMaterialCode_Click(object sender, EventArgs e) { if (Grid2.SelectedRowIDArray == null || !Grid2.SelectedRowIDArray.Any()) @@ -845,44 +1033,58 @@ namespace FineUIPro.Web.HJGL.WeldingManage } } + /// + /// 按 Grid2 选中管线下可生成任务单的焊口批量生成焊接任务单。 + /// + /// 事件源。 + /// 事件参数。 protected void btnGenTask_Click(object sender, EventArgs e) { - if (GetSelectedWeldJointIdsFromGrid1().Any()) + if (Grid2.SelectedRowIDArray == null || !Grid2.SelectedRowIDArray.Any()) { - if (SaveTask()) - { - ShowNotify("生成任务单成功!", MessageBoxIcon.Warning); - // Alert.Show("生成任务单成功!", MessageBoxIcon.Warning); - Grid1.DataSource = null; - Grid1.DataBind(); - Grid2.DataSource = null; - Grid2.DataBind(); - Grid3.DataSource = null; - Grid3.DataBind(); - } + ShowNotify("请先在材料匹配列表中选择需要生成任务单的管线!", MessageBoxIcon.Warning); + return; } - else + + // 生成任务单按 Grid2 勾选管线批量取焊口,不再要求用户在 Grid1 明细逐条勾选。 + var selectedWeldJointIds = GetTaskWeldJointIdsFromSelectedPipelines(); + if (!selectedWeldJointIds.Any()) { - ShowNotify("请先在材料匹配明细中选择需要生成任务单的焊口!", MessageBoxIcon.Warning); + ShowNotify("选中管线中没有已反写材料主编码的可生成任务单焊口!", MessageBoxIcon.Warning); + return; + } + + if (SaveTask(selectedWeldJointIds)) + { + ShowNotify("生成任务单成功!", MessageBoxIcon.Warning); + // Alert.Show("生成任务单成功!", MessageBoxIcon.Warning); + Grid1.DataSource = null; + Grid1.DataBind(); + BindTaskWeldJointSummary(new List()); + Grid2.DataSource = null; + Grid2.DataBind(); + Grid3.DataSource = null; + Grid3.DataBind(); } } - private bool SaveTask() + + /// + /// 根据已通过材料齐套和任务单条件过滤的焊口生成焊接任务单。 + /// + /// 待生成任务单的焊口ID集合。 + /// 生成成功返回 true;校验失败或无可生成焊口返回 false。 + private bool SaveTask(HashSet selectedWeldJointIds) { - var selectedWeldJointIds = GetSelectedWeldJointIdsFromGrid1(); - if (!selectedWeldJointIds.Any()) + if (selectedWeldJointIds == null || !selectedWeldJointIds.Any()) { - ShowNotify("请先在材料匹配明细中选择需要生成任务单的焊口!", MessageBoxIcon.Warning); + 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 selectedWeldJointIdList.Contains(x.WeldJointId) && x.WeldingDailyId == null && - x.WeldTaskId == null && x.WeldingMethodCode != null - select x).ToList(); + var selectRowId = GetTaskableWeldJointRows(selectedWeldJointIdList); Dictionary unitworkTaskCode = new Dictionary(); Dictionary unitworkSerialNumber = new Dictionary(); @@ -892,10 +1094,6 @@ namespace FineUIPro.Web.HJGL.WeldingManage { matchPipeline.Add(rowIndex + 1, Grid2.Rows[rowIndex].RowID); } - if (PipeArea == "1") //工厂预制的管线,则只选择预制口 - { - selectRowId = selectRowId.Where(x => x.JointAttribute == "预制口").ToList(); - } if (!selectRowId.Any()) { ShowNotify("未找到可生成任务单的焊口!", MessageBoxIcon.Warning); @@ -1012,33 +1210,89 @@ namespace FineUIPro.Web.HJGL.WeldingManage } /// - /// 从材料匹配明细 Grid1 中提取用户选中的焊口ID。 + /// 按任务单实际生成规则过滤可生成任务单的焊口视图数据。 /// - private HashSet GetSelectedWeldJointIdsFromGrid1() + /// 候选焊口ID集合。 + /// 符合任务单生成条件的焊口视图数据。 + private List GetTaskableWeldJointRows(IEnumerable weldJointIds) { - var selectedWeldJointIds = new HashSet(); - if (Grid1.SelectedRowIndexArray == null) + var weldJointIdList = weldJointIds == null + ? new List() + : weldJointIds.Where(x => !string.IsNullOrEmpty(x)).Distinct().ToList(); + if (!weldJointIdList.Any()) { - return selectedWeldJointIds; + return new List(); } - foreach (int rowIndex in Grid1.SelectedRowIndexArray) + // 合计行和生成按钮必须共用同一套可生成条件:未生成日报、未生成任务单、已维护焊接方法。 + var taskableRows = (from x in Funs.DB.View_HJGL_NoWeldJointFind + where weldJointIdList.Contains(x.WeldJointId) + && x.WeldingDailyId == null + && x.WeldTaskId == null + && x.WeldingMethodCode != null + select x).ToList(); + if (PipeArea == "1") { - if (Grid1.DataKeys[rowIndex].Length < 4) - { - continue; - } - - string weldJointId = Grid1.DataKeys[rowIndex][3]?.ToString(); - if (!string.IsNullOrEmpty(weldJointId)) - { - selectedWeldJointIds.Add(weldJointId); - } + // 工厂预制材料匹配只允许预制口生成任务单,现场安装页面不套用该限制。 + taskableRows = taskableRows.Where(x => x.JointAttribute == "预制口").ToList(); } - return selectedWeldJointIds; + return taskableRows; } + /// + /// 从 Grid2 选中的管线中收集可生成任务单的焊口ID。 + /// + /// 可生成任务单的焊口ID集合。 + private HashSet GetTaskWeldJointIdsFromSelectedPipelines() + { + // Grid2 的选中管线是任务单生成范围,Grid1 当前展示哪条管线不影响批量生成。 + var selectedPipelineIds = Grid2.SelectedRowIDArray == null + ? new HashSet() + : new HashSet(Grid2.SelectedRowIDArray.Where(x => !string.IsNullOrEmpty(x))); + if (!selectedPipelineIds.Any()) + { + return new HashSet(); + } + + var materialDetails = GetNoTaskMaterialDetails() + // 生成任务单只校验参与匹配的有效材料明细,零用量材料不参与焊口材料齐套判断。 + .Where(x => selectedPipelineIds.Contains(x.PipelineId) && !string.IsNullOrEmpty(x.WeldJointId) && (x.NeedNum ?? 0) > 0) + .ToList(); + return GetTaskWeldJointIdsFromMaterialDetails(materialDetails); + } + + /// + /// 根据材料明细判断焊口是否材料齐套且满足任务单生成条件。 + /// + /// 候选材料匹配明细。 + /// 可生成任务单的焊口ID集合。 + private HashSet GetTaskWeldJointIdsFromMaterialDetails(List materialDetails) + { + if (materialDetails == null || !materialDetails.Any()) + { + return new HashSet(); + } + + materialDetails = materialDetails + .Where(x => x != null && !string.IsNullOrEmpty(x.WeldJointId) && (x.NeedNum ?? 0) > 0) + .ToList(); + // 同一焊口可能有多条有效材料明细,所有明细都反写材料主编码后才算可生成任务单。 + var confirmedPipeLineMatIds = GetConfirmedPipeLineMatIds(materialDetails); + + var weldJointIds = materialDetails + .GroupBy(x => x.WeldJointId) + .Where(x => x.All(y => IsMaterialCodeConfirmed(y, confirmedPipeLineMatIds))) + .Select(x => x.Key); + // 材料齐套后还要继续套用任务单视图条件,保证合计数量和点击生成按钮的实际范围一致。 + return new HashSet(GetTaskableWeldJointRows(weldJointIds).Select(x => x.WeldJointId)); + } + + /// + /// 获取指定管线范围内的优先匹配焊口集合。 + /// + /// 管线ID列表。 + /// 管线ID到优先焊口ID集合的映射。 private Dictionary> GetPriorityWeldJointIds(List selectedPipelineIds) { var result = new Dictionary>(); @@ -1054,6 +1308,12 @@ namespace FineUIPro.Web.HJGL.WeldingManage return result; } + /// + /// 判断焊材钢号类别是否能覆盖母材类别。 + /// + /// 焊材钢号类别。 + /// 母材类别。 + /// 能覆盖返回 true,否则返回 false。 private bool IsCoverClass(string wpsClass, string matClass) { bool isCover = false; @@ -1081,6 +1341,11 @@ namespace FineUIPro.Web.HJGL.WeldingManage #endregion + /// + /// 仓库切换后刷新当前仓库ID并重新加载左侧管线树。 + /// + /// 事件源。 + /// 事件参数。 protected void drpWarehouse_SelectedIndexChanged(object sender, EventArgs e) { WarehouseId = Base_WarehouseService.GetWarehouseList(this.CurrUser.LoginProjectId) diff --git a/SGGL/FineUIPro.Web/HJGL/WeldingManage/WeldMatMatch.aspx.designer.cs b/SGGL/FineUIPro.Web/HJGL/WeldingManage/WeldMatMatch.aspx.designer.cs index d66e65e6..0b438536 100644 --- a/SGGL/FineUIPro.Web/HJGL/WeldingManage/WeldMatMatch.aspx.designer.cs +++ b/SGGL/FineUIPro.Web/HJGL/WeldingManage/WeldMatMatch.aspx.designer.cs @@ -248,15 +248,6 @@ namespace FineUIPro.Web.HJGL.WeldingManage /// protected global::FineUIPro.Label lbRate; - /// - /// lbNote 控件。 - /// - /// - /// 自动生成的字段。 - /// 若要进行修改,请将字段声明从设计器文件移到代码隐藏文件。 - /// - protected global::FineUIPro.Label lbNote; - /// /// btnPriorityComponents 控件。 /// @@ -293,6 +284,24 @@ namespace FineUIPro.Web.HJGL.WeldingManage /// protected global::FineUIPro.CheckBox cbSelectCom; + /// + /// ToolbarFill1 控件。 + /// + /// + /// 自动生成的字段。 + /// 若要进行修改,请将字段声明从设计器文件移到代码隐藏文件。 + /// + protected global::FineUIPro.ToolbarFill ToolbarFill1; + + /// + /// btnMatchHelp 控件。 + /// + /// + /// 自动生成的字段。 + /// 若要进行修改,请将字段声明从设计器文件移到代码隐藏文件。 + /// + protected global::FineUIPro.Button btnMatchHelp; + /// /// Grid2 控件。 /// diff --git a/SGGL/FineUIPro.Web/HJGL/WeldingManage/WeldTask.aspx.cs b/SGGL/FineUIPro.Web/HJGL/WeldingManage/WeldTask.aspx.cs index bca9532f..a5897acd 100644 --- a/SGGL/FineUIPro.Web/HJGL/WeldingManage/WeldTask.aspx.cs +++ b/SGGL/FineUIPro.Web/HJGL/WeldingManage/WeldTask.aspx.cs @@ -1533,33 +1533,64 @@ namespace FineUIPro.Web.HJGL.WeldingManage // 添加列 dataTable.Columns.Add("PipelineCode", typeof(string)); dataTable.Columns.Add("FlowingSection", typeof(string)); + dataTable.Columns.Add("WeldJointCode", typeof(string)); dataTable.Columns.Add("MaterialCode", typeof(string)); + dataTable.Columns.Add("BatchNo", typeof(string)); + dataTable.Columns.Add("NeedNum", typeof(string)); + dataTable.Columns.Add("MaterialMade", typeof(string)); dataTable.Columns.Add("MaterialSpec", typeof(string)); - dataTable.Columns.Add("MatchRate", typeof(string)); - dataTable.Columns.Add("Dia", typeof(string)); + dataTable.Columns.Add("PaintCode", typeof(string)); + dataTable.Columns.Add("WeldingSize", typeof(string)); + dataTable.Columns.Add("Remark", typeof(string)); - foreach (string pipeline in pipelines) + var taskWeldJointIds = weldTaskList.Where(x => !string.IsNullOrEmpty(x.WeldJointId)) + .Select(x => x.WeldJointId).Distinct().ToList(); + var pipelineList = Funs.DB.HJGL_Pipeline.Where(x => pipelines.Contains(x.PipelineId)).ToList(); + var printMaterials = (from x in Funs.DB.HJGL_PipeLineMat + join y in Funs.DB.HJGL_MaterialCodeLib on x.MaterialCode equals y.MaterialCode + where pipelines.Contains(x.PipelineId) + && taskWeldJointIds.Contains(x.WeldJointId) + && x.PrefabricatedComponents != null + select new + { + x.PipelineId, + x.WeldJointId, + x.MaterialCode, + x.Number, + y.Code, + y.HeatNo, + y.BatchNo, + y.MaterialMade, + y.MaterialSpec + }).ToList(); + var sortedTaskList = weldTaskList.OrderBy(x => x.PipeLineSortIndex).ThenBy(x => x.WeldJointCode).ToList(); + + foreach (var task in sortedTaskList) { - DataRow dr = dataTable.NewRow(); - var pipelineModel = PipelineService.GetPipelineByPipelineId(pipeline); - if (pipelineModel == null) + var taskMaterials = printMaterials.Where(x => x.WeldJointId == task.WeldJointId) + .OrderBy(x => x.Code).ToList(); + if (!taskMaterials.Any()) { - continue; + taskMaterials.Add(null); } - dr["PipelineCode"] = pipelineModel.PipelineCode; - dr["FlowingSection"] = pipelineModel.FlowingSection; - // 管线基础资料可能未维护材质,打印时保留空值,避免整张任务单打印失败。 - var materialModel = string.IsNullOrEmpty(pipelineModel.MaterialId) ? null : Base_MaterialService.GetMaterialByMaterialId(pipelineModel.MaterialId); - dr["MaterialCode"] = materialModel?.MaterialCode ?? string.Empty; - dr["MaterialSpec"] = string.Join(",", weldTaskList.Select(x => x.Specification).Distinct().ToList()); - // 匹配率计算依赖管线仓库,未维护仓库时按0显示,避免基础资料缺项阻断打印。 - var warehouseModel = string.IsNullOrEmpty(pipelineModel.WarehouseId) ? null : Base_WarehouseService.GetWarehouseByWarehouseId(pipelineModel.WarehouseId); - var matchRate = warehouseModel == null ? 0 : TwArrivalStatisticsService.GetPipeMatch(pipeline) ?? 0; - dr["MatchRate"] = Math.Round(matchRate * 100, 2).ToString() + "%"; - dr["Dia"] = weldTaskList.Where(x => x.PipelineId == pipeline).Sum(x => x.Size ?? 0) - .ToString(); - dataTable.Rows.Add(dr); + foreach (var material in taskMaterials) + { + DataRow dr = dataTable.NewRow(); + dr["PipelineCode"] = task.PipelineCode; + dr["FlowingSection"] = pipelineList.FirstOrDefault(x => x.PipelineId == task.PipelineId)?.FlowingSection ?? string.Empty; + dr["WeldJointCode"] = !string.IsNullOrEmpty(task.PipelineCode) ? task.WeldJointCode.Replace(task.PipelineCode + "/", "") : task.WeldJointCode; + dr["MaterialCode"] = material?.Code ?? material?.MaterialCode ?? string.Empty; + dr["BatchNo"] = material == null ? string.Empty : string.Join("/", new[] { material.HeatNo, material.BatchNo }.Where(x => !string.IsNullOrEmpty(x))); + dr["NeedNum"] = material?.Number != null ? material.Number.Value.ToString("0.##") : string.Empty; + dr["MaterialMade"] = material?.MaterialMade ?? string.Empty; + dr["MaterialSpec"] = material?.MaterialSpec ?? string.Empty; + // 当前焊接任务单取数链路未维护油漆号,先输出空列,避免模板字段缺失。 + dr["PaintCode"] = string.Empty; + dr["WeldingSize"] = task.Size.HasValue ? task.Size.Value.ToString("0.##") : string.Empty; + dr["Remark"] = string.Empty; + dataTable.Rows.Add(dr); + } } BLL.FastReportService.AddFastreportTable(Table1); BLL.FastReportService.AddFastreportTable(dataTable);