using Microsoft.AspNetCore.Http; using OpenAuth.App.BaseApp.Base; using OpenAuth.App.Interface; using OpenAuth.Repository; using OpenAuth.Repository.Domain; using OpenAuth.Repository.Domain.workflow; using SqlSugar; namespace workflow; public class WorkflowEngineApp : SqlSugarBaseApp { private readonly ISqlSugarClient _sqlSugar; private readonly IAuth _auth; // 修正:私有字段命名为 _auth,与注入一致 // 构造函数:注入 IAuth 赋值给 _auth public WorkflowEngineApp(ISugarUnitOfWork unitWork, ISimpleClient repository, IAuth auth) : base(unitWork, repository, auth) { _sqlSugar = Repository.AsSugarClient(); _auth = auth; // 赋值:将注入的 auth 赋值给私有字段 _auth } #region 私有辅助方法(不变) private void ValidatePageParam(PageQueryInput pageInput) { pageInput.PageIndex = pageInput.PageIndex < 1 ? 1 : pageInput.PageIndex; pageInput.PageSize = pageInput.PageSize < 1 ? 10 : pageInput.PageSize; pageInput.PageSize = pageInput.PageSize > 100 ? 100 : pageInput.PageSize; } private string GenerateBusinessNumber() => Guid.NewGuid().ToString("N").ToLower(); private string GenerateFormId() => Guid.NewGuid().ToString("N"); private PageQueryOutput WrapPageResult(PageQueryInput pageInput, long totalCount, List dataList) { return new PageQueryOutput { PageIndex = pageInput.PageIndex, PageSize = pageInput.PageSize, TotalCount = totalCount, TotalPages = (int)Math.Ceiling((double)totalCount / pageInput.PageSize), DataList = dataList }; } #endregion #region 按角色ID查询用户名(不变,已适配 First 写法) public string GetUserNameByRoleId(long roleId) { if (roleId <= 0) return string.Empty; try { var sql = @"select u.* from sys_user u left join sys_userrole r on u.""id"" = r.""user_id"" where r.""role_id"" = @RoleId"; var hasData = _sqlSugar.SqlQueryable(sql) .AddParameters(new { RoleId = roleId }) .Any(); if (!hasData) return string.Empty; var user = _sqlSugar.SqlQueryable(sql) .AddParameters(new { RoleId = roleId }) .First(); return user?.Name ?? string.Empty; } catch (Exception ex) { Console.WriteLine($"查询用户姓名失败:{ex.Message}"); return string.Empty; } } #endregion #region 流程核心业务(修正:SetColumns 实体初始化写法 + _auth 调用) public long InitiateAssessmentFlow(long userId, string userName, InitiateAssessmentFlowRequest request) { if (string.IsNullOrEmpty(request.FlowCode) || string.IsNullOrEmpty(request.Title)) throw new ArgumentException("流程编码和表单标题不能为空"); var businessNumber = string.IsNullOrEmpty(request.BusinessNumber) ? GenerateBusinessNumber() : request.BusinessNumber; var formId = GenerateFormId(); var hasTemplate = _sqlSugar.Queryable() .Where(t => t.FlowCode == request.FlowCode && t.IsEnabled) .Any(); if (!hasTemplate) throw new Exception($"流程模板 {request.FlowCode} 不存在或未启用"); var flowTemplate = _sqlSugar.Queryable() .Where(t => t.FlowCode == request.FlowCode && t.IsEnabled) .First(); long instanceId = 0; try { UnitWork.Db.Ado.BeginTran(); var assessmentForm = new IllegalConstructionAssessment { Id = formId, Title = request.Title, BusinessNumber = businessNumber, Type = request.Type, Attachments = request.Attachments, AcceptanceTime = request.AcceptanceTime ?? DateTime.Now, ReceiveTime = request.ReceiveTime, Status = request.Status ?? "Submitted", CreateTime = DateTime.Now, CreateUser = userName, Remark = request.Remark }; Repository.Insert(assessmentForm); var flowInstance = new FlowInstance { TemplateId = flowTemplate.TemplateId, BusinessNo = businessNumber, FlowStatus = assessmentForm.Status, InitiatorId = userId, InitiatorName = userName, CreateTime = DateTime.Now }; instanceId = _sqlSugar.Insertable(flowInstance).ExecuteReturnIdentity(); var flowWorkitem = new FlowWorkitem { InstanceId = instanceId, BusinessNo = businessNumber, HandlerId = userId, HandlerName = userName, NodeName = "发起节点", WorkitemStatus = "ToDo", CreateTime = DateTime.Now }; _sqlSugar.Insertable(flowWorkitem).ExecuteCommand(); UnitWork.Db.Ado.CommitTran(); } catch (Exception ex) { UnitWork.Db.Ado.RollbackTran(); throw new Exception($"发起流程失败:{ex.Message}"); } return instanceId; } public AssessmentFlowUnionResult? QueryAssessmentFlowByBusinessNo(string businessNumber) { if (string.IsNullOrEmpty(businessNumber)) throw new ArgumentException("业务编号不能为空"); var hasData = _sqlSugar .Queryable((a, fi, ft, fw) => new JoinQueryInfos( JoinType.Inner, a.BusinessNumber == fi.BusinessNo, JoinType.Inner, fi.TemplateId == ft.TemplateId, JoinType.Inner, fi.InstanceId == fw.InstanceId && fw.WorkitemStatus == "ToDo")) .Where((a, fi, ft, fw) => a.BusinessNumber == businessNumber) .Any(); if (!hasData) return null; return _sqlSugar .Queryable((a, fi, ft, fw) => new JoinQueryInfos( JoinType.Inner, a.BusinessNumber == fi.BusinessNo, JoinType.Inner, fi.TemplateId == ft.TemplateId, JoinType.Inner, fi.InstanceId == fw.InstanceId && fw.WorkitemStatus == "ToDo")) .Where((a, fi, ft, fw) => a.BusinessNumber == businessNumber) .Select((a, fi, ft, fw) => new AssessmentFlowUnionResult { FormId = a.Id, Title = a.Title, BusinessNumber = a.BusinessNumber, Type = a.Type, Attachments = a.Attachments, AcceptanceTime = a.AcceptanceTime, FlowInstanceId = fi.InstanceId, FlowName = ft.FlowName, CurrentNodeName = fw.NodeName, FlowStatus = fi.FlowStatus, InitiatorName = fi.InitiatorName, FlowCreateTime = fi.CreateTime, FlowFinishTime = fi.FinishTime }) .First(); } public bool UpdateAssessmentForm(IllegalConstructionAssessment form, long userId) { if (form == null || string.IsNullOrEmpty(form.Id)) throw new ArgumentException("表单数据无效"); // 修正:调用 _auth(私有字段),不再是 Auth var currentUser = _auth.GetCurrentUser()?.User; if (currentUser == null) throw new Exception("未获取到当前登录用户"); try { UnitWork.Db.Ado.BeginTran(); form.UpdateTime = DateTime.Now; form.UpdateUser = currentUser.Name; //Repository.AsUpdateable(newProject).IgnoreNullColumns().ExecuteCommandAsync(); var updateCount = Repository.AsUpdateable(form).IgnoreColumns().ExecuteCommand(); if (!string.IsNullOrEmpty(form.Status)) { // 修正:SetColumns 改为 实体初始化写法 _sqlSugar.Updateable() .SetColumns(fi => new FlowInstance() { FlowStatus = form.Status, FinishTime = form.Status == "Completed" ? DateTime.Now : (DateTime?)null }) .Where(fi => fi.BusinessNo == form.BusinessNumber) .ExecuteCommand(); } UnitWork.Db.Ado.CommitTran(); return updateCount > 0; } catch (Exception ex) { UnitWork.Db.Ado.RollbackTran(); throw new Exception($"更新表单失败:{ex.Message}"); } } public PageQueryOutput QueryAllAssessmentForms(PageQueryInput pageInput) { ValidatePageParam(pageInput); var query = _sqlSugar.Queryable((a, fi, ft, fw) => new JoinQueryInfos( JoinType.Inner, a.BusinessNumber == fi.BusinessNo, JoinType.Inner, fi.TemplateId == ft.TemplateId, JoinType.Inner, fi.InstanceId == fw.InstanceId)); if (!string.IsNullOrEmpty(pageInput.Status)) query = query.Where((a, fi, ft, fw) => a.Status == pageInput.Status); var queryProjection = query.Select((a, fi, ft, fw) => new AssessmentFlowUnionResult { FormId = a.Id, Title = a.Title, BusinessNumber = a.BusinessNumber, Type = a.Type, Attachments = a.Attachments, AcceptanceTime = a.AcceptanceTime, FlowInstanceId = fi.InstanceId, FlowName = ft.FlowName, CurrentNodeName = fw.NodeName, FlowStatus = fi.FlowStatus, InitiatorName = fi.InitiatorName, FlowCreateTime = fi.CreateTime, FlowFinishTime = fi.FinishTime }); long totalCount = queryProjection.Count(); var dataList = queryProjection .Skip((pageInput.PageIndex - 1) * pageInput.PageSize) .Take(pageInput.PageSize) .ToList(); return new PageQueryOutput { PageIndex = pageInput.PageIndex, PageSize = pageInput.PageSize, TotalCount = totalCount, TotalPages = (int)Math.Ceiling((double)totalCount / pageInput.PageSize), DataList = dataList }; } #endregion #region 待办/已办/拟办查询(不变) public PageQueryOutput QueryMyDraft(long userId, PageQueryInput pageInput) { ValidatePageParam(pageInput); var query = _sqlSugar.Queryable((fw, fi, ft) => new JoinQueryInfos( JoinType.Inner, fw.InstanceId == fi.InstanceId, JoinType.Inner, fi.TemplateId == ft.TemplateId)) .Where((fw, fi, ft) => fw.HandlerId == userId && fw.WorkitemStatus == "Draft") .Select((fw, fi, ft) => new FlowQueryResult { InstanceId = fi.InstanceId, BusinessNo = fi.BusinessNo, FlowName = ft.FlowName, FlowStatus = fi.FlowStatus, NodeName = fw.NodeName, InitiatorName = fi.InitiatorName, CreateTime = fi.CreateTime, FinishTime = fi.FinishTime }); return WrapPageResult(pageInput, query.Count(), query.Skip((pageInput.PageIndex - 1) * pageInput.PageSize).Take(pageInput.PageSize).ToList()); } public PageQueryOutput QueryMyToDo(long userId, PageQueryInput pageInput) { ValidatePageParam(pageInput); var query = _sqlSugar.Queryable((fw, fi, ft) => new JoinQueryInfos( JoinType.Inner, fw.InstanceId == fi.InstanceId, JoinType.Inner, fi.TemplateId == ft.TemplateId)) .Where((fw, fi, ft) => fw.HandlerId == userId && fw.WorkitemStatus == "ToDo") .Select((fw, fi, ft) => new FlowQueryResult { InstanceId = fi.InstanceId, BusinessNo = fi.BusinessNo, FlowName = ft.FlowName, FlowStatus = fi.FlowStatus, NodeName = fw.NodeName, InitiatorName = fi.InitiatorName, CreateTime = fi.CreateTime, FinishTime = fi.FinishTime }); return WrapPageResult(pageInput, query.Count(), query.Skip((pageInput.PageIndex - 1) * pageInput.PageSize).Take(pageInput.PageSize).ToList()); } public PageQueryOutput QueryMyDone(long userId, PageQueryInput pageInput) { ValidatePageParam(pageInput); var query = _sqlSugar.Queryable((fw, fi, ft) => new JoinQueryInfos( JoinType.Inner, fw.InstanceId == fi.InstanceId, JoinType.Inner, fi.TemplateId == ft.TemplateId)) .Where((fw, fi, ft) => fw.HandlerId == userId && fw.WorkitemStatus == "Done") .Select((fw, fi, ft) => new FlowQueryResult { InstanceId = fi.InstanceId, BusinessNo = fi.BusinessNo, FlowName = ft.FlowName, FlowStatus = fi.FlowStatus, NodeName = fw.NodeName, InitiatorName = fi.InitiatorName, CreateTime = fi.CreateTime, FinishTime = fi.FinishTime }); return WrapPageResult(pageInput, query.Count(), query.Skip((pageInput.PageIndex - 1) * pageInput.PageSize).Take(pageInput.PageSize).ToList()); } #endregion #region 待办项处理(核心修正:SetColumns 实体初始化 + _auth 调用) public bool ClaimDraftWorkitem(long workitemId, long userId, string userName) { if (workitemId <= 0 || userId <= 0) return false; // 修正:SetColumns 改为 实体初始化写法(批量赋值) var updateCount = _sqlSugar.Updateable() .SetColumns(fw => new FlowWorkitem() { WorkitemStatus = "ToDo", HandlerId = userId, HandlerName = userName }) .Where(fw => fw.WorkitemId == workitemId && fw.WorkitemStatus == "Draft") .ExecuteCommand(); return updateCount > 0; } public bool HandleWorkitem(long userId, string userName, HandleWorkitemRequest request) { if (request == null || request.WorkitemId <= 0 || string.IsNullOrEmpty(request.HandleResult)) throw new ArgumentException("处理参数无效"); try { UnitWork.Db.Ado.BeginTran(); // 修正:SetColumns 实体初始化写法 var updateCount = _sqlSugar.Updateable() .SetColumns(fw => new FlowWorkitem() { WorkitemStatus = "Done", HandleTime = DateTime.Now }) .Where(fw => fw.WorkitemId == request.WorkitemId && fw.HandlerId == userId) .ExecuteCommand(); var hasWorkitem = _sqlSugar.Queryable() .Where(fw => fw.WorkitemId == request.WorkitemId) .Any(); if (!hasWorkitem) { UnitWork.Db.Ado.RollbackTran(); return false; } var workitem = _sqlSugar.Queryable() .Where(fw => fw.WorkitemId == request.WorkitemId) .First(); var flowStatus = request.HandleResult.Equals("Pass", StringComparison.OrdinalIgnoreCase) ? "Auditing" : "Rejected"; // 修正:SetColumns 实体初始化写法 _sqlSugar.Updateable() .SetColumns(fi => new FlowInstance() { FlowStatus = flowStatus }) .Where(fi => fi.InstanceId == workitem.InstanceId) .ExecuteCommand(); UnitWork.Db.Ado.CommitTran(); return updateCount > 0; } catch (Exception ex) { UnitWork.Db.Ado.RollbackTran(); throw new Exception($"处理待办失败:{ex.Message}"); } } #endregion }