feat(hjgl): 完善焊接任务与质量管理流程

This commit is contained in:
2026-08-19 17:13:33 +08:00
parent 08792e0dc8
commit 679e9f6cec
68 changed files with 2481 additions and 1170 deletions
+465 -183
View File
@@ -4,11 +4,37 @@ using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Transactions;
namespace BLL
{
public partial class WeldingDailyService
{
private const string AutoHotProcessRemark = "焊接日报审核自动生成";
private const int AuditStatePendingTeam = 0;
private const int AuditStatePendingProfessional = 1;
private const int AuditStateApproved = 2;
private sealed class WeldingDailyTempSaveContext
{
public Model.View_HJGL_WeldJoint Joint { get; set; }
public Model.HJGL_WeldTask WeldTask { get; set; }
public DateTime WeldingDate { get; set; }
public string SubmitPersonId { get; set; }
public string CoverWelderId { get; set; }
public string BackingWelderId { get; set; }
public string JointAttribute { get; set; }
public string WeldingLocationId { get; set; }
public string ProjectId { get; set; }
public string UnitId { get; set; }
public string UnitWorkId { get; set; }
public string WeldingMode { get; set; }
public string WeldingMethodId { get; set; }
public string WeldTypeId { get; set; }
public string WeldingWire { get; set; }
public string WeldingRod { get; set; }
public int? WelderType { get; set; }
}
/// <summary>
///获取焊接日报信息
/// </summary>
@@ -312,34 +338,29 @@ namespace BLL
return new List<Model.WeldingDailyTempDetailItem>();
}
using (Model.SGGLDB db = new Model.SGGLDB(Funs.ConnString))
var query = QueryPendingWeldingDailyTempDetails().AsQueryable();
query = query.Where(x => x.ProjectId == projectId);
if (!string.IsNullOrEmpty(unitWorkId))
{
var query = QueryPendingWeldingDailyTempDetails(db);
query = query.Where(x => x.ProjectId == projectId);
if (!string.IsNullOrEmpty(unitWorkId))
{
query = query.Where(x => x.UnitWorkId == unitWorkId);
}
if (weldingDate.HasValue)
{
DateTime startDate = weldingDate.Value.Date;
DateTime endDate = startDate.AddDays(1);
query = query.Where(x => x.WeldingDate >= startDate && x.WeldingDate < endDate);
}
if (!string.IsNullOrEmpty(pipelineCode))
{
query = query.Where(x => x.PipelineCode != null && x.PipelineCode.Contains(pipelineCode));
}
if (!string.IsNullOrEmpty(welderCode))
{
query = query.Where(x => (x.CoverWelderCode != null && x.CoverWelderCode.Contains(welderCode))
|| (x.BackingWelderCode != null && x.BackingWelderCode.Contains(welderCode)));
}
var data = query.OrderBy(x => x.PipelineCode).ThenBy(x => x.WeldJointCode).ToList();
SetWeldingDailyTempDetailAttachUrls(db, data);
return data;
query = query.Where(x => x.UnitWorkId == unitWorkId);
}
if (weldingDate.HasValue)
{
DateTime startDate = weldingDate.Value.Date;
DateTime endDate = startDate.AddDays(1);
query = query.Where(x => x.WeldingDate >= startDate && x.WeldingDate < endDate);
}
if (!string.IsNullOrEmpty(pipelineCode))
{
query = query.Where(x => x.PipelineCode != null && x.PipelineCode.Contains(pipelineCode));
}
if (!string.IsNullOrEmpty(welderCode))
{
query = query.Where(x => (x.CoverWelderCode != null && x.CoverWelderCode.Contains(welderCode))
|| (x.BackingWelderCode != null && x.BackingWelderCode.Contains(welderCode)));
}
return query.OrderBy(x => x.PipelineCode).ThenBy(x => x.WeldJointCode).ToList();
}
/// <summary>
@@ -354,24 +375,19 @@ namespace BLL
return null;
}
using (Model.SGGLDB db = new Model.SGGLDB(Funs.ConnString))
{
var data = QueryPendingWeldingDailyTempDetails(db)
.Where(x => x.TempDetailId == tempDetailId)
.Take(1)
.ToList();
SetWeldingDailyTempDetailAttachUrls(db, data);
return data.FirstOrDefault();
}
return QueryPendingWeldingDailyTempDetails().FirstOrDefault(x => x.TempDetailId == tempDetailId);
}
/// <summary>
/// 构造待审核查询。PC端列表和接口列表、明细均从这里读取,确保字段映射和待审核状态一致。
/// </summary>
private static System.Linq.IQueryable<Model.WeldingDailyTempDetailItem> QueryPendingWeldingDailyTempDetails(Model.SGGLDB db)
private static List<Model.WeldingDailyTempDetailItem> QueryPendingWeldingDailyTempDetails()
{
// 待审核模块只展示 AuditState=0;审核、删除仍复用本类下方已有批量业务方法。
return from temp in db.HJGL_WeldingDailyTempDetail
List<Model.WeldingDailyTempDetailItem> data;
using (Model.SGGLDB db = new Model.SGGLDB(Funs.ConnString))
{
// 查询必须在数据上下文释放前物化,避免返回失效的延迟查询。
data = (from temp in db.HJGL_WeldingDailyTempDetail
join jotItem in db.View_HJGL_WeldJoint on temp.WeldJointId equals jotItem.WeldJointId into jotItems
from jot in jotItems.DefaultIfEmpty()
join coverItem in db.SitePerson_Person on temp.CoverWelderId equals coverItem.PersonId into coverItems
@@ -380,9 +396,21 @@ namespace BLL
from backingWelder in backingItems.DefaultIfEmpty()
join locationItem in db.Base_WeldingLocation on temp.WeldingLocationId equals locationItem.WeldingLocationId into locationItems
from location in locationItems.DefaultIfEmpty()
join weldTypeItem in db.Base_WeldType on temp.WeldTypeId equals weldTypeItem.WeldTypeId into weldTypeItems
from weldType in weldTypeItems.DefaultIfEmpty()
join weldingMethodItem in db.Base_WeldingMethod on temp.WeldingMethodId equals weldingMethodItem.WeldingMethodId into weldingMethodItems
from weldingMethod in weldingMethodItems.DefaultIfEmpty()
join weldingWireItem in db.Base_Consumables on temp.WeldingWire equals weldingWireItem.ConsumablesId into weldingWireItems
from weldingWire in weldingWireItems.DefaultIfEmpty()
join weldingRodItem in db.Base_Consumables on temp.WeldingRod equals weldingRodItem.ConsumablesId into weldingRodItems
from weldingRod in weldingRodItems.DefaultIfEmpty()
join submitItem in db.Person_Persons on temp.SubmitPersonId equals submitItem.PersonId into submitItems
from submitPerson in submitItems.DefaultIfEmpty()
where temp.AuditState == 0
join teamAuditItem in db.Person_Persons on temp.TeamAuditMan equals teamAuditItem.PersonId into teamAuditItems
from teamAuditPerson in teamAuditItems.DefaultIfEmpty()
join professionalAuditItem in db.Person_Persons on temp.ProfessionalAuditMan equals professionalAuditItem.PersonId into professionalAuditItems
from professionalAuditPerson in professionalAuditItems.DefaultIfEmpty()
where temp.AuditState < AuditStateApproved
select new Model.WeldingDailyTempDetailItem
{
TempDetailId = temp.TempDetailId,
@@ -408,10 +436,14 @@ namespace BLL
Size = jot == null ? (decimal?)null : jot.Size,
Dia = jot == null ? (decimal?)null : jot.Dia,
Thickness = jot == null ? (decimal?)null : jot.Thickness,
WeldTypeCode = jot == null ? null : jot.WeldTypeCode,
WeldingMethodCode = jot == null ? null : jot.WeldingMethodCode,
WeldingWireCode = jot == null ? null : jot.WeldingWireCode,
WeldingRodCode = jot == null ? null : jot.WeldingRodCode,
WeldTypeId = temp.WeldTypeId ?? (jot == null ? null : jot.WeldTypeId),
WeldTypeCode = weldType == null ? (jot == null ? null : jot.WeldTypeCode) : weldType.WeldTypeCode,
WeldingMethodId = temp.WeldingMethodId ?? (jot == null ? null : jot.WeldingMethodId),
WeldingMethodCode = weldingMethod == null ? (jot == null ? null : jot.WeldingMethodCode) : weldingMethod.WeldingMethodCode,
WeldingWire = temp.WeldingWire ?? (jot == null ? null : jot.WeldingWire),
WeldingWireCode = weldingWire == null ? (jot == null ? null : jot.WeldingWireCode) : weldingWire.ConsumablesCode,
WeldingRod = temp.WeldingRod ?? (jot == null ? null : jot.WeldingRod),
WeldingRodCode = weldingRod == null ? (jot == null ? null : jot.WeldingRodCode) : weldingRod.ConsumablesCode,
SubmitPersonId = temp.SubmitPersonId,
SubmitPersonName = submitPerson == null ? null : submitPerson.PersonName,
SubmitDate = temp.SubmitDate,
@@ -419,15 +451,24 @@ namespace BLL
AuditState = temp.AuditState,
AuditMan = temp.AuditMan,
AuditDate = temp.AuditDate,
AuditRemark = temp.AuditRemark
};
AuditRemark = temp.AuditRemark,
TeamAuditMan = temp.TeamAuditMan,
TeamAuditManName = teamAuditPerson == null ? null : teamAuditPerson.PersonName,
TeamAuditDate = temp.TeamAuditDate,
ProfessionalAuditMan = temp.ProfessionalAuditMan,
ProfessionalAuditManName = professionalAuditPerson == null ? null : professionalAuditPerson.PersonName,
ProfessionalAuditDate = temp.ProfessionalAuditDate,
AuditStateText = temp.AuditState == AuditStatePendingTeam ? "待班组审核" : "待专工审核"
}).ToList();
}
SetWeldingDailyTempDetailAttachUrls(data);
return data;
}
/// <summary>
/// 按待审核明细ID批量回写焊前、焊后附件地址。
/// </summary>
private static void SetWeldingDailyTempDetailAttachUrls(Model.SGGLDB db,
List<Model.WeldingDailyTempDetailItem> data)
private static void SetWeldingDailyTempDetailAttachUrls(List<Model.WeldingDailyTempDetailItem> data)
{
if (data == null || data.Count == 0)
{
@@ -439,12 +480,16 @@ namespace BLL
x.TempDetailId + "#Before",
x.TempDetailId + "#After"
}).ToList();
var attachUrlMap = db.AttachFile
.Where(x => x.MenuId == Const.HJGL_WeldReportMenuId && toKeyIds.Contains(x.ToKeyId))
.Select(x => new { x.ToKeyId, x.AttachUrl })
.ToList()
.GroupBy(x => x.ToKeyId)
.ToDictionary(x => x.Key, x => x.Select(y => y.AttachUrl).FirstOrDefault());
Dictionary<string, string> attachUrlMap;
using (Model.SGGLDB db = new Model.SGGLDB(Funs.ConnString))
{
attachUrlMap = db.AttachFile
.Where(x => x.MenuId == Const.HJGL_WeldReportMenuId && toKeyIds.Contains(x.ToKeyId))
.Select(x => new { x.ToKeyId, x.AttachUrl })
.ToList()
.GroupBy(x => x.ToKeyId)
.ToDictionary(x => x.Key, x => x.Select(y => y.AttachUrl).FirstOrDefault());
}
foreach (var item in data)
{
@@ -479,14 +524,15 @@ namespace BLL
/// <returns>错误信息</returns>
public static string SaveWeldingDailyTempDetailByMobile(string weldJointId, string personId, string time, string weldingLocationId, int welderType)
{
return SaveWeldingDailyTempDetailByMobile(weldJointId, personId, time, weldingLocationId, welderType, null, null);
return SaveWeldingDailyTempDetailByMobile(weldJointId, personId, time, weldingLocationId, welderType, null, null, null, null);
}
/// <summary>
/// 移动端按焊口保存焊接日报待审核明细,并按需同步焊接方法和焊缝类型
/// 移动端按焊口保存焊接日报待审核明细及实际焊接工艺快照
/// </summary>
public static string SaveWeldingDailyTempDetailByMobile(string weldJointId, string personId, string time,
string weldingLocationId, int welderType, string weldingMethodId, string weldTypeId)
string weldingLocationId, int welderType, string weldingMethodId, string weldTypeId,
string weldingWire, string weldingRod)
{
string res = string.Empty;
using (Model.SGGLDB db = new Model.SGGLDB(Funs.ConnString))
@@ -507,7 +553,7 @@ namespace BLL
}
var joint = db.View_HJGL_WeldJoint.FirstOrDefault(x => x.WeldJointId == weldJointId);
string err = CheckWeldingDailyTempJoint(db, joint, weldingLocationId);
string err = CheckWeldingDailyTempJoint(joint, weldingLocationId);
if (!string.IsNullOrEmpty(err))
{
return err;
@@ -515,38 +561,39 @@ namespace BLL
var weldTask = db.HJGL_WeldTask.FirstOrDefault(x => x.WeldJointId == joint.WeldJointId);
var weldJoint = db.HJGL_WeldJoint.FirstOrDefault(x => x.WeldJointId == joint.WeldJointId);
if (weldJoint == null)
{
return "焊口不存在";
}
// 兼容旧版小程序:只有两个参数同时存在时才成对更新,避免焊口工艺信息出现半更新。
if (!string.IsNullOrWhiteSpace(weldingMethodId) && !string.IsNullOrWhiteSpace(weldTypeId))
string parameterError = ValidatePendingWeldingParameters(weldingMethodId, weldTypeId, weldingWire, weldingRod);
if (!string.IsNullOrEmpty(parameterError))
{
weldJoint.WeldingMethodId = weldingMethodId;
weldJoint.WeldTypeId = weldTypeId;
return parameterError;
}
var pending = GetPendingTempDetail(db, weldJointId, weldingDate);
string coverWelderId = pending != null ? pending.CoverWelderId : weldJoint.CoverWelderId;
string backingWelderId = pending != null ? pending.BackingWelderId : weldJoint.BackingWelderId;
if (welderType == 0)
{
coverWelderId = personId;
backingWelderId = personId;
}
else if (welderType == 1)
{
backingWelderId = personId;
}
else if (welderType == 2)
{
coverWelderId = personId;
}
else
if (welderType < 0 || welderType > 2)
{
return "焊工类型不正确";
}
SaveWeldingDailyTempDetail(db, joint, weldTask, weldingDate, personId, coverWelderId, backingWelderId,
joint.JointAttribute, weldingLocationId, joint.ProjectId, null, null, joint.WeldingMode);
db.SubmitChanges();
SaveWeldingDailyTempDetail(new WeldingDailyTempSaveContext
{
Joint = joint,
WeldTask = weldTask,
WeldingDate = weldingDate,
SubmitPersonId = personId,
CoverWelderId = weldJoint.CoverWelderId,
BackingWelderId = weldJoint.BackingWelderId,
JointAttribute = joint.JointAttribute,
WeldingLocationId = weldingLocationId,
ProjectId = joint.ProjectId,
WeldingMode = joint.WeldingMode,
WeldingMethodId = weldingMethodId,
WeldTypeId = weldTypeId,
WeldingWire = weldingWire,
WeldingRod = weldingRod,
WelderType = welderType
});
}
catch (Exception ex)
{
@@ -595,7 +642,7 @@ namespace BLL
}
var joint = db.View_HJGL_WeldJoint.FirstOrDefault(x => x.WeldJointId == weldJointId);
string err = CheckWeldingDailyTempJoint(db, joint, weldingLocationId);
string err = CheckWeldingDailyTempJoint(joint, weldingLocationId);
if (!string.IsNullOrEmpty(err))
{
return err;
@@ -613,9 +660,21 @@ namespace BLL
}
var weldTask = db.HJGL_WeldTask.FirstOrDefault(x => x.WeldJointId == weldJointId);
SaveWeldingDailyTempDetail(db, joint, weldTask, weldingDate, submitPersonId, coverWelderId, backingWelderId,
jointAttribute, weldingLocationId, projectId, unitId, unitWorkId, weldingMode);
db.SubmitChanges();
SaveWeldingDailyTempDetail(new WeldingDailyTempSaveContext
{
Joint = joint,
WeldTask = weldTask,
WeldingDate = weldingDate,
SubmitPersonId = submitPersonId,
CoverWelderId = coverWelderId,
BackingWelderId = backingWelderId,
JointAttribute = jointAttribute,
WeldingLocationId = weldingLocationId,
ProjectId = projectId,
UnitId = unitId,
UnitWorkId = unitWorkId,
WeldingMode = weldingMode
});
}
catch (Exception ex)
{
@@ -627,7 +686,46 @@ namespace BLL
}
/// <summary>
/// 审核通过焊接日报待审核明细
/// 班组审核焊接日报待审核明细,只记录班组审核留痕,不生成正式日报。
/// </summary>
public static string TeamAuditWeldingDailyTempDetails(string[] tempDetailIds, string auditMan)
{
if (tempDetailIds == null || tempDetailIds.Length == 0) return "请选择要审核的记录";
if (string.IsNullOrWhiteSpace(auditMan)) return "班组审核人不能为空";
string errlog = string.Empty;
using (var scope = new TransactionScope())
{
foreach (string id in tempDetailIds.Where(x => !string.IsNullOrEmpty(x)).Distinct())
{
var detail = GetLockedWeldingDailyTempDetail(id);
if (detail == null)
{
errlog += "待审核记录不存在;";
continue;
}
if (detail.AuditState != AuditStatePendingTeam)
{
errlog += "记录不是待班组审核状态;";
continue;
}
if (!HasCompleteWelders(detail))
{
// 班组审核后记录不再允许补录,必须在状态流转前保证两类焊工完整。
errlog += "焊口待审核记录未选择完整焊工;";
continue;
}
detail.TeamAuditMan = auditMan;
detail.TeamAuditDate = DateTime.Now;
detail.AuditState = AuditStatePendingProfessional;
}
Funs.DB.SubmitChanges();
scope.Complete();
}
return errlog;
}
/// <summary>
/// 专工审核通过焊接日报待审核明细,并生成正式日报及热处理委托。
/// </summary>
/// <param name="tempDetailIds">待审核明细ID集合</param>
/// <param name="auditMan">审核人</param>
@@ -639,61 +737,90 @@ namespace BLL
{
return "请选择要审核的记录";
}
if (string.IsNullOrWhiteSpace(auditMan)) return "专工审核人不能为空";
foreach (string tempDetailId in tempDetailIds.Where(x => !string.IsNullOrEmpty(x)).Distinct())
var sharedConnection = (SqlConnection)Funs.DB.Connection;
bool closeConnection = sharedConnection.State != ConnectionState.Open;
try
{
var tempDetail = Funs.DB.HJGL_WeldingDailyTempDetail.FirstOrDefault(x => x.TempDetailId == tempDetailId);
if (tempDetail == null)
using (var scope = new TransactionScope())
{
errlog += "待审核记录不存在;";
continue;
}
if (tempDetail.AuditState != 0)
{
errlog += "焊口待审核记录已审核;";
continue;
}
if (string.IsNullOrEmpty(tempDetail.CoverWelderId) || string.IsNullOrEmpty(tempDetail.BackingWelderId))
{
errlog += "焊口待审核记录未选择完整焊工;";
continue;
}
// 整个专工审核事务保持单一连接
if (closeConnection) sharedConnection.Open();
foreach (string tempDetailId in tempDetailIds.Where(x => !string.IsNullOrEmpty(x)).Distinct())
{
var tempDetail = GetLockedWeldingDailyTempDetail(tempDetailId);
if (tempDetail == null)
{
errlog += "待审核记录不存在;";
continue;
}
if (tempDetail.AuditState != AuditStatePendingProfessional || !tempDetail.TeamAuditDate.HasValue)
{
errlog += "焊口待审核记录尚未完成班组审核;";
continue;
}
if (!HasCompleteWelders(tempDetail))
{
errlog += "焊口待审核记录未选择完整焊工;";
continue;
}
var weldJoint = BLL.WeldJointService.GetWeldJointByWeldJointId(tempDetail.WeldJointId);
if (weldJoint == null)
{
errlog += "焊口不存在;";
continue;
}
if (!string.IsNullOrEmpty(weldJoint.WeldingDailyId))
{
errlog += "焊口【" + weldJoint.WeldJointCode + "】已生成焊接日报;";
continue;
}
var weldJoint = BLL.WeldJointService.GetWeldJointByWeldJointId(tempDetail.WeldJointId);
if (weldJoint == null)
{
errlog += "焊口不存在;";
continue;
}
if (!string.IsNullOrEmpty(weldJoint.WeldingDailyId))
{
errlog += "焊口【" + weldJoint.WeldJointCode + "】已生成焊接日报;";
continue;
}
var batchC = BLL.Project_SysSetService.GetSysSetBySetId("5", tempDetail.ProjectId);
if (batchC == null)
{
errlog += "请设置项目的组批条件;";
continue;
}
var batchC = BLL.Project_SysSetService.GetSysSetBySetId("5", tempDetail.ProjectId);
if (batchC == null)
{
errlog += "请设置项目的组批条件;";
continue;
}
var weldingDaily = GetOrCreateWeldingDailyByTempDetail(tempDetail);
string itemErr = InsertWeldingDailyItem(tempDetail.WeldJointId, tempDetail.CoverWelderId, tempDetail.BackingWelderId,
tempDetail.JointAttribute, weldingDaily.WeldingDate, batchC.SetValue, true, weldingDaily.WeldingDailyId,
tempDetail.ProjectId, tempDetail.WeldingLocationId);
if (!string.IsNullOrEmpty(itemErr))
{
errlog += itemErr;
continue;
}
var weldingDaily = GetOrCreateWeldingDailyByTempDetail(tempDetail);
BLL.HJGL_PipelineComponentjointService.UpdateStateByWeldJointId(tempDetail.WeldJointId, (DateTime)weldingDaily.WeldingDate);//更改预制口实际时间和状态
PipelineService.UpdataDateByWeldJointId(tempDetail.WeldJointId);//更改安装口时间和状态
tempDetail.AuditState = 1;
tempDetail.AuditMan = auditMan;
tempDetail.AuditDate = DateTime.Now;
Funs.DB.SubmitChanges();
// 实际工艺参数在专工审核事务内才回写焊口,审核失败时与正式日报一起回滚。
weldJoint.WeldingMethodId = FirstNotEmpty(tempDetail.WeldingMethodId, weldJoint.WeldingMethodId);
weldJoint.WeldTypeId = FirstNotEmpty(tempDetail.WeldTypeId, weldJoint.WeldTypeId);
weldJoint.WeldingWire = FirstNotEmpty(tempDetail.WeldingWire, weldJoint.WeldingWire);
weldJoint.WeldingRod = FirstNotEmpty(tempDetail.WeldingRod, weldJoint.WeldingRod);
Funs.DB.SubmitChanges();
string itemErr = InsertWeldingDailyItem(tempDetail.WeldJointId, tempDetail.CoverWelderId, tempDetail.BackingWelderId,
tempDetail.JointAttribute, weldingDaily.WeldingDate, batchC.SetValue, true, weldingDaily.WeldingDailyId,
tempDetail.ProjectId, tempDetail.WeldingLocationId, sharedConnection);
if (!string.IsNullOrEmpty(itemErr))
{
// 正式日报、焊口状态、组批和自动热处理委托必须整体成功,任一步失败即回滚本次审核。
throw new InvalidOperationException(itemErr);
}
BLL.HJGL_PipelineComponentjointService.UpdateStateByWeldJointId(tempDetail.WeldJointId, (DateTime)weldingDaily.WeldingDate);
PipelineService.UpdataDateByWeldJointId(tempDetail.WeldJointId);
tempDetail.AuditState = AuditStateApproved;
tempDetail.ProfessionalAuditMan = auditMan;
tempDetail.ProfessionalAuditDate = DateTime.Now;
// 旧字段继续镜像专工审核信息,兼容历史查询和报表。
tempDetail.AuditMan = auditMan;
tempDetail.AuditDate = tempDetail.ProfessionalAuditDate;
EnsureAutomaticHotProcessTrust(tempDetail, weldJoint, auditMan);
Funs.DB.SubmitChanges();
}
scope.Complete();
}
}
finally
{
// 在 TransactionScope 完成提交或回滚后再释放连接。
if (closeConnection && sharedConnection.State != ConnectionState.Closed) sharedConnection.Close();
}
return errlog;
@@ -719,7 +846,7 @@ namespace BLL
{
continue;
}
if (tempDetail.AuditState != 0)
if (tempDetail.AuditState != AuditStatePendingTeam)
{
errlog += "已审核记录不能删除;";
continue;
@@ -730,66 +857,210 @@ namespace BLL
return errlog;
}
private static string CheckWeldingDailyTempJoint(Model.SGGLDB db, Model.View_HJGL_WeldJoint joint, string weldingLocationId)
/// <summary>
/// 将需要热处理的焊口归入焊接完成日期当天的自动热处理委托。
/// </summary>
private static void EnsureAutomaticHotProcessTrust(Model.HJGL_WeldingDailyTempDetail tempDetail,
Model.HJGL_WeldJoint weldJoint, string auditMan)
{
if (joint == null)
if (weldJoint.IsHotProess != true) return;
if (Funs.DB.HJGL_HotProess_TrustItem.Any(x => x.WeldJointId == weldJoint.WeldJointId)) return;
DateTime processDate = tempDetail.WeldingDate.Date;
var trust = Funs.DB.HJGL_HotProess_Trust.FirstOrDefault(x => x.ProjectId == tempDetail.ProjectId
&& x.UnitWorkId == tempDetail.UnitWorkId && x.ProessDate.HasValue
&& x.ProessDate.Value >= processDate && x.ProessDate.Value < processDate.AddDays(1)
&& x.Remark == AutoHotProcessRemark);
if (trust == null)
{
return "焊口不存在";
// 在当前事务内锁定同项目、单位工程编号范围,防止并发审核产生重复流水号。
var lockedNumbers = Funs.DB.ExecuteQuery<string>(
"SELECT HotProessTrustNo FROM dbo.HJGL_HotProess_Trust WITH (UPDLOCK,HOLDLOCK) WHERE ProjectId={0} AND UnitWorkId={1}",
tempDetail.ProjectId, tempDetail.UnitWorkId).ToList();
var unitWork = Funs.DB.WBS_UnitWork.FirstOrDefault(x => x.UnitWorkId == tempDetail.UnitWorkId);
string unitWorkName = unitWork == null ? string.Empty : unitWork.UnitWorkName;
string prefix = "FCC-" + unitWorkName + "-RCL-SPCECC-";
int serial = lockedNumbers.Where(x => !string.IsNullOrEmpty(x) && x.StartsWith(prefix))
.Select(ParseTrailingSerial).DefaultIfEmpty(0).Max() + 1;
if (serial > 999) throw new InvalidOperationException("热处理委托编号三位流水号已用完。");
trust = new Model.HJGL_HotProess_Trust
{
HotProessTrustId = SQLHelper.GetNewID(),
HotProessTrustNo = prefix + serial.ToString("D3"),
ProessDate = processDate,
ProjectId = tempDetail.ProjectId,
UnitWorkId = tempDetail.UnitWorkId,
UnitId = tempDetail.UnitId,
Tabler = auditMan,
Remark = AutoHotProcessRemark
};
Funs.DB.HJGL_HotProess_Trust.InsertOnSubmit(trust);
}
if (!string.IsNullOrEmpty(joint.WeldingDailyId))
Funs.DB.HJGL_HotProess_TrustItem.InsertOnSubmit(new Model.HJGL_HotProess_TrustItem
{
return "焊口【" + joint.WeldJointCode + "】已生成焊接日报,不能提交待审核";
}
if (!string.IsNullOrEmpty(weldingLocationId))
HotProessTrustItemId = SQLHelper.GetNewID(),
HotProessTrustId = trust.HotProessTrustId,
WeldJointId = weldJoint.WeldJointId,
IsCompleted = false
});
}
private static int ParseTrailingSerial(string code)
{
if (string.IsNullOrEmpty(code)) return 0;
int separator = code.LastIndexOf('-');
int value;
return separator >= 0 && int.TryParse(code.Substring(separator + 1), out value) ? value : 0;
}
private static string CheckWeldingDailyTempJoint(Model.View_HJGL_WeldJoint joint, string weldingLocationId)
{
using (Model.SGGLDB db = new Model.SGGLDB(Funs.ConnString))
{
var weldingLocationModel = db.Base_WeldingLocation.FirstOrDefault(x => x.WeldingLocationId == weldingLocationId);
if (weldingLocationModel == null)
if (joint == null)
{
return "焊口不存在";
}
if (!string.IsNullOrEmpty(joint.WeldingDailyId))
{
return "焊口【" + joint.WeldJointCode + "】已生成焊接日报,不能提交待审核";
}
if (!string.IsNullOrEmpty(weldingLocationId)
&& !db.Base_WeldingLocation.Any(x => x.WeldingLocationId == weldingLocationId))
{
return "焊口位置不存在";
}
return string.Empty;
}
return string.Empty;
}
private static Model.HJGL_WeldingDailyTempDetail GetPendingTempDetail(Model.SGGLDB db, string weldJointId, DateTime weldingDate)
private static Model.HJGL_WeldingDailyTempDetail GetLockedWeldingDailyTempDetail(string tempDetailId)
{
return db.HJGL_WeldingDailyTempDetail.FirstOrDefault(x => x.WeldJointId == weldJointId
&& x.WeldingDate >= weldingDate.Date
&& x.WeldingDate < weldingDate.Date.AddDays(1)
&& x.AuditState == 0);
}
private static void SaveWeldingDailyTempDetail(Model.SGGLDB db, Model.View_HJGL_WeldJoint joint, Model.HJGL_WeldTask weldTask,
DateTime weldingDate, string submitPersonId, string coverWelderId, string backingWelderId, string jointAttribute,
string weldingLocationId, string projectId, string unitId, string unitWorkId, string weldingMode)
{
var pending = GetPendingTempDetail(db, joint.WeldJointId, weldingDate);
if (pending == null)
// 审核事务内锁定状态行,避免并发审核覆盖审核人和状态。
Funs.DB.ExecuteQuery<int>(
"SELECT AuditState FROM dbo.HJGL_WeldingDailyTempDetail WITH (UPDLOCK,HOLDLOCK) WHERE TempDetailId={0}", tempDetailId)
.FirstOrDefault();
var detail = Funs.DB.HJGL_WeldingDailyTempDetail.FirstOrDefault(x => x.TempDetailId == tempDetailId);
if (detail != null)
{
pending = new Model.HJGL_WeldingDailyTempDetail
{
TempDetailId = Guid.NewGuid().ToString(),
WeldJointId = joint.WeldJointId,
WeldingDate = weldingDate.Date,
AuditState = 0,
SubmitDate = DateTime.Now
};
db.HJGL_WeldingDailyTempDetail.InsertOnSubmit(pending);
Funs.DB.Refresh(System.Data.Linq.RefreshMode.OverwriteCurrentValues, detail);
}
pending.ProjectId = !string.IsNullOrEmpty(projectId) ? projectId : joint.ProjectId;
pending.UnitId = !string.IsNullOrEmpty(unitId) ? unitId : (weldTask != null && !string.IsNullOrEmpty(weldTask.UnitId) ? weldTask.UnitId : joint.UnitId);
pending.UnitWorkId = !string.IsNullOrEmpty(unitWorkId) ? unitWorkId : joint.UnitWorkId;
pending.CoverWelderId = coverWelderId;
pending.BackingWelderId = backingWelderId;
pending.JointAttribute = !string.IsNullOrEmpty(jointAttribute) ? jointAttribute : joint.JointAttribute;
pending.WeldingLocationId = !string.IsNullOrEmpty(weldingLocationId) ? weldingLocationId : joint.WeldingLocationId;
pending.WeldingMode = !string.IsNullOrEmpty(weldingMode) ? weldingMode : joint.WeldingMode;
pending.SubmitPersonId = submitPersonId;
pending.SubmitDate = DateTime.Now;
return detail;
}
private static Model.HJGL_WeldingDaily GetOrCreateWeldingDailyByTempDetail(Model.HJGL_WeldingDailyTempDetail tempDetail)
private static bool HasCompleteWelders(Model.HJGL_WeldingDailyTempDetail detail)
{
return detail != null
&& !string.IsNullOrEmpty(detail.CoverWelderId)
&& !string.IsNullOrEmpty(detail.BackingWelderId);
}
private static void SaveWeldingDailyTempDetail(WeldingDailyTempSaveContext context)
{
using (Model.SGGLDB db = new Model.SGGLDB(Funs.ConnString))
{
DateTime startDate = context.WeldingDate.Date;
DateTime endDate = startDate.AddDays(1);
var existingDetails = db.HJGL_WeldingDailyTempDetail
.Where(x => x.WeldJointId == context.Joint.WeldJointId
&& x.WeldingDate >= startDate
&& x.WeldingDate < endDate)
.ToList();
if (existingDetails.Any(x => x.AuditState == AuditStatePendingProfessional))
{
// 状态1已形成班组审核留痕,禁止再次提交生成另一条状态0记录。
throw new InvalidOperationException("焊口【" + context.Joint.WeldJointCode + "】当日记录已完成班组审核,不能重复提交");
}
var pending = existingDetails.FirstOrDefault(x => x.AuditState == AuditStatePendingTeam);
if (pending == null)
{
pending = new Model.HJGL_WeldingDailyTempDetail
{
TempDetailId = Guid.NewGuid().ToString(),
WeldJointId = context.Joint.WeldJointId,
WeldingDate = context.WeldingDate.Date,
AuditState = AuditStatePendingTeam,
SubmitDate = DateTime.Now
};
db.HJGL_WeldingDailyTempDetail.InsertOnSubmit(pending);
}
string coverWelderId = context.CoverWelderId;
string backingWelderId = context.BackingWelderId;
if (context.WelderType.HasValue)
{
// 移动端支持打底、盖面分次提交,优先保留当前待审核记录已经提交的焊工。
coverWelderId = !string.IsNullOrEmpty(pending.CoverWelderId) ? pending.CoverWelderId : coverWelderId;
backingWelderId = !string.IsNullOrEmpty(pending.BackingWelderId) ? pending.BackingWelderId : backingWelderId;
if (context.WelderType.Value == 0 || context.WelderType.Value == 2)
{
coverWelderId = context.SubmitPersonId;
}
if (context.WelderType.Value == 0 || context.WelderType.Value == 1)
{
backingWelderId = context.SubmitPersonId;
}
}
pending.ProjectId = !string.IsNullOrEmpty(context.ProjectId) ? context.ProjectId : context.Joint.ProjectId;
pending.UnitId = !string.IsNullOrEmpty(context.UnitId) ? context.UnitId
: (context.WeldTask != null && !string.IsNullOrEmpty(context.WeldTask.UnitId) ? context.WeldTask.UnitId : context.Joint.UnitId);
pending.UnitWorkId = !string.IsNullOrEmpty(context.UnitWorkId) ? context.UnitWorkId : context.Joint.UnitWorkId;
pending.CoverWelderId = coverWelderId;
pending.BackingWelderId = backingWelderId;
pending.JointAttribute = !string.IsNullOrEmpty(context.JointAttribute) ? context.JointAttribute : context.Joint.JointAttribute;
pending.WeldingLocationId = !string.IsNullOrEmpty(context.WeldingLocationId) ? context.WeldingLocationId : context.Joint.WeldingLocationId;
pending.WeldingMode = !string.IsNullOrEmpty(context.WeldingMode) ? context.WeldingMode : context.Joint.WeldingMode;
// 同一焊口可能由打底、盖面分次提交;未传参数时保留已有快照,再回退到焊口当前值。
pending.WeldingMethodId = FirstNotEmpty(context.WeldingMethodId, pending.WeldingMethodId, context.Joint.WeldingMethodId);
pending.WeldTypeId = FirstNotEmpty(context.WeldTypeId, pending.WeldTypeId, context.Joint.WeldTypeId);
pending.WeldingWire = FirstNotEmpty(context.WeldingWire, pending.WeldingWire, context.Joint.WeldingWire);
pending.WeldingRod = FirstNotEmpty(context.WeldingRod, pending.WeldingRod, context.Joint.WeldingRod);
pending.SubmitPersonId = context.SubmitPersonId;
pending.SubmitDate = DateTime.Now;
db.SubmitChanges();
}
}
private static string ValidatePendingWeldingParameters(string weldingMethodId,
string weldTypeId, string weldingWire, string weldingRod)
{
using (Model.SGGLDB db = new Model.SGGLDB(Funs.ConnString))
{
if (!string.IsNullOrWhiteSpace(weldingMethodId)
&& !db.Base_WeldingMethod.Any(x => x.WeldingMethodId == weldingMethodId))
{
return "焊接方法不存在";
}
if (!string.IsNullOrWhiteSpace(weldTypeId)
&& !db.Base_WeldType.Any(x => x.WeldTypeId == weldTypeId))
{
return "焊缝类型不存在";
}
if (!string.IsNullOrWhiteSpace(weldingWire)
&& !db.Base_Consumables.Any(x => x.ConsumablesId == weldingWire && x.ConsumablesType == "1"))
{
return "焊丝不存在或焊材类型不正确";
}
if (!string.IsNullOrWhiteSpace(weldingRod)
&& !db.Base_Consumables.Any(x => x.ConsumablesId == weldingRod && x.ConsumablesType == "2"))
{
return "焊条不存在或焊材类型不正确";
}
return string.Empty;
}
}
private static string FirstNotEmpty(params string[] values)
{
return values == null ? null : values.FirstOrDefault(x => !string.IsNullOrWhiteSpace(x));
}
private static Model.HJGL_WeldingDaily GetOrCreateWeldingDailyByTempDetail(
Model.HJGL_WeldingDailyTempDetail tempDetail)
{
var weldingDaily = Funs.DB.HJGL_WeldingDaily.FirstOrDefault(x => x.UnitWorkId == tempDetail.UnitWorkId
&& x.WeldingDate >= tempDetail.WeldingDate.Date
@@ -802,10 +1073,18 @@ namespace BLL
var submitUnitwork = Funs.DB.WBS_UnitWork.FirstOrDefault(x => x.UnitWorkId == tempDetail.UnitWorkId);
string unitWorkName = submitUnitwork != null ? submitUnitwork.UnitWorkName : string.Empty;
string perfix = string.Format("{0:yyyyMMdd}", tempDetail.WeldingDate) + "-" + unitWorkName + "-";
// 直接读取当前最大编号并在内存中生成三位流水号,不再调用 SpGetThreeNumber。
string maxNumber = Funs.DB.HJGL_WeldingDaily
.Where(x => x.ProjectId == tempDetail.ProjectId
&& x.WeldingDailyCode != null
&& x.WeldingDailyCode.StartsWith(perfix))
.Select(x => x.WeldingDailyCode)
.OrderByDescending(x => x)
.FirstOrDefault();
weldingDaily = new Model.HJGL_WeldingDaily
{
WeldingDailyId = Guid.NewGuid().ToString(),
WeldingDailyCode = BLL.SQLHelper.RunProcNewId("SpGetThreeNumber", "dbo.HJGL_WeldingDaily", "WeldingDailyCode", tempDetail.ProjectId, perfix),
WeldingDailyCode = Funs.GetThreeNumber(maxNumber, perfix),
WeldingDate = tempDetail.WeldingDate.Date,
ProjectId = tempDetail.ProjectId,
UnitWorkId = tempDetail.UnitWorkId,
@@ -837,7 +1116,9 @@ namespace BLL
/// <param name="projectId">项目ID</param>
/// <param name="weldingLocationId">焊接位置ID</param>
/// <returns>错误信息</returns>
private static string InsertWeldingDailyItem(string weldJointId, string coverWelderId, string backingWelderId, string jointAttribute, DateTime? weldingDate, string batchCondition, bool isSave, string weldingDailyId, string projectId, string weldingLocationId)
private static string InsertWeldingDailyItem(string weldJointId, string coverWelderId, string backingWelderId,
string jointAttribute, DateTime? weldingDate, string batchCondition, bool isSave, string weldingDailyId,
string projectId, string weldingLocationId, SqlConnection sharedConnection)
{
string errlog = string.Empty;
var newWeldJoint = BLL.WeldJointService.GetWeldJointByWeldJointId(weldJointId);
@@ -872,7 +1153,8 @@ namespace BLL
// 更新焊口号 修改固定焊口号后 +G
BLL.WeldJointService.UpdateWeldJointAddG(newWeldJoint.WeldJointId, newWeldJoint.JointAttribute, Const.BtnAdd);
errlog = PointBatchService.AddBatchByWeldJointId(weldJointId, weldingDate, batchCondition);//自动组批
errlog = PointBatchService.AddBatchByWeldJointId(
weldJointId, weldingDate, batchCondition, sharedConnection);//自动组批
}
}
else