using System.Text; using DS.Module.Core; using DS.Module.Core.Data; using DS.Module.Core.Extensions; using DS.WMS.Core.Fee.Dtos; using DS.WMS.Core.Flow.Dtos; using DS.WMS.Core.Flow.Entity; using DS.WMS.Core.Flow.Interface; using DS.WMS.Core.Info.Dtos; using DS.WMS.Core.Info.Entity; using DS.WMS.Core.Info.Interface; using DS.WMS.Core.Sys.Entity; using DS.WMS.Core.TaskInteraction.Dtos; using DS.WMS.Core.TaskInteraction.Interface; using Masuit.Tools.Systems; using Microsoft.Extensions.DependencyInjection; using SqlSugar; namespace DS.WMS.Core.Info.Method { /// /// 往来单位干系人 /// public class ClientStakeholderService : ServiceBase, IClientStakeholderService { const TaskBaseTypeEnum CLIENT_STAKEHOLDER_TASK = TaskBaseTypeEnum.CLIENT_STAKEHOLDER_AUDIT; const TaskBaseTypeEnum CLIENT_STAKEHOLDER_TASK_DISPUTE = TaskBaseTypeEnum.CLIENT_STAKEHOLDER_DISPUTE; Lazy flowService; Lazy taskService; /// /// 初始化 /// /// public ClientStakeholderService(IServiceProvider serviceProvider) : base(serviceProvider) { flowService = new Lazy(serviceProvider.GetRequiredService()); taskService = new Lazy(serviceProvider.GetRequiredService()); } #region 审核 /// /// 提交审核 /// /// /// public async Task SubmitAuditAsync(IdModel idModel) { //long.TryParse(idModel.Id, out long clientId); //var list = await TenantDb.Queryable() // .InnerJoin((x, y) => x.ClientId == y.Id) // .WhereIF(idModel.Ids?.Length > 0, (x, y) => idModel.Ids.Contains(x.Id)) // .WhereIF(clientId > 0, (x, y) => x.ClientId == clientId && x.Status == StakeholderStatus.Uncommitted) // .Select((x, y) => new InfoClientStakeholder // { // ClientId = x.ClientId, // Status = x.Status, // UserName = x.UserName, // ClientShortName = y.ShortName // }).ToListAsync(); var list = await TenantDb.Queryable() .InnerJoin((x, y) => x.ClientId == y.Id) .Where((x, y) => idModel.Ids.Contains(x.Id)) .Select((x, y) => new InfoClientStakeholder { ClientId = x.ClientId, Status = x.Status, UserName = x.UserName, ClientShortName = y.ShortName }).ToListAsync(); if (list.Count == 0) return DataResult.FailedWithDesc(nameof(MultiLanguageConst.NoAuditItems)); if (list.Exists(x => x.Status == StakeholderStatus.Pending)) return DataResult.FailedWithDesc(nameof(MultiLanguageConst.ItemsAreAuditing)); //var groups = list.GroupBy(x => new { x.ClientId, x.ClientShortName }).ToList(); var taskType = CLIENT_STAKEHOLDER_TASK; if (idModel.Value is TaskBaseTypeEnum auditType) taskType = auditType; if (await taskService.Value.HasAuthorizedAsync()) { var requests = list.Select(x => new TaskCreationRequest { BusinessId = x.Id, TaskTypeName = taskType.ToString(), TaskTitle = $"【{taskType.GetDescription()}】{x.ClientShortName} {x.UserName}" }); //var requests = groups.Select(x => new TaskCreationRequest //{ // BusinessId = x.Key.ClientId, // TaskTypeName = taskType.ToString(), // TaskTitle = $"【{taskType.GetDescription()}】{x.Key.ClientShortName} {string.Join("|", x.Select(y => y.UserName))}" //}); await TenantDb.Ado.BeginTranAsync(); try { DataResult result; foreach (var request in requests) { result = await taskService.Value.CreateTaskAsync(request, false); if (!result.Succeeded) return result; } await TenantDb.Updateable().Where(x => idModel.Ids.Contains(x.Id)) .SetColumns(x => x.Status == StakeholderStatus.Pending).ExecuteCommandAsync(); await TenantDb.Ado.CommitTranAsync(); return DataResult.Success; } catch (Exception ex) { await TenantDb.Ado.RollbackTranAsync(); await ex.LogAsync(Db); return DataResult.FailedWithDesc(nameof(MultiLanguageConst.Operation_Failed)); } } var template = await FindTemplateAsync(taskType); if (template == null) return DataResult.FailedWithDesc(nameof(MultiLanguageConst.TemplateNotFound)); //foreach (var g in groups) //{ // var result = flowService.Value.CreateFlowInstance(new CreateFlowInstanceReq // { // BusinessId = g.Key.ClientId, // TemplateId = template.Id // }); // if (!result.Succeeded || result.Data is not FlowInstance instance) // return result; // result = flowService.Value.StartFlowInstance(instance.Id.ToString()); // if (!result.Succeeded) // return result; //} foreach (var item in list) { var result = flowService.Value.CreateFlowInstance(new CreateFlowInstanceReq { BusinessId = item.Id, TemplateId = template.Id }); if (!result.Succeeded || result.Data is not FlowInstance instance) return result; result = flowService.Value.StartFlowInstance(instance.Id.ToString()); if (!result.Succeeded) return result; } var ids = list.Select(x => x.Id); var rows = await TenantDb.Updateable().Where(x => ids.Contains(x.Id)) .SetColumns(x => x.Status == StakeholderStatus.Pending).ExecuteCommandAsync(); return rows > 0 ? DataResult.Success : DataResult.FailedWithDesc(nameof(MultiLanguageConst.Operation_Failed)); } /// /// 执行审核 /// /// /// public async Task AuditAsync(AuditRequest request) { if (await taskService.Value.HasAuthorizedAsync()) { return await taskService.Value.AuditAsync(new TaskAuditRequest { Ids = request.Ids, Remark = request.Remark, Result = request.Result, TaskTypeName = CLIENT_STAKEHOLDER_TASK.ToString() }); } var list = await flowService.Value.GetInstanceByBSIdAsync(CLIENT_STAKEHOLDER_TASK, ids: request.Ids); if (list.Count != request.Ids.Length) return DataResult.FailedWithDesc(nameof(MultiLanguageConst.NotInAudit)); foreach (var item in list) { var result = await flowService.Value.AuditAsync(new FlowAuditInfo { AuditNote = request.Remark, Status = request.Result, Instance = item }); if (!result.Succeeded) return result; } return DataResult.Success; } /// /// 撤销审核 /// /// /// public async Task WithdrawAsync(IdModel idModel) { DataResult result; if (await taskService.Value.HasAuthorizedAsync()) { await TenantDb.Ado.BeginTranAsync(); try { for (int i = 0; i < idModel.Ids.Length; i++) { result = await taskService.Value.WithdrawAsync(new TaskRequest { BusinessId = idModel.Ids[i], TaskTypeName = CLIENT_STAKEHOLDER_TASK.ToString() }, false); if (!result.Succeeded) { return result; } } await TenantDb.Updateable().Where(x => idModel.Ids.Contains(x.Id)) .SetColumns(x => x.Status == StakeholderStatus.Uncommitted) .SetColumns(x => x.Remark == null) .ExecuteCommandAsync(); await TenantDb.Ado.CommitTranAsync(); return DataResult.Success; } catch { await TenantDb.Ado.RollbackTranAsync(); return DataResult.FailedWithDesc(nameof(MultiLanguageConst.Operation_Failed)); } } var list = await flowService.Value.GetInstanceByBSIdAsync(CLIENT_STAKEHOLDER_TASK, ids: idModel.Ids); if (list.Count != idModel.Ids.Length) return DataResult.FailedWithDesc(nameof(MultiLanguageConst.NotInAudit)); result = await flowService.Value.WithdrawAsync(idModel.Ids); if (!result.Succeeded) return result; int rows = await TenantDb.Updateable().Where(x => idModel.Ids.Contains(x.Id)) .SetColumns(x => x.Status == StakeholderStatus.Uncommitted).ExecuteCommandAsync(); return rows > 0 ? DataResult.Success : DataResult.FailedWithDesc(nameof(MultiLanguageConst.Operation_Failed)); } /// /// 审核完成回调 /// /// 回调信息 /// public async Task AuditCallbackAsync(FlowCallback callback) { if (callback.AuditType != CLIENT_STAKEHOLDER_TASK || callback.AuditType != CLIENT_STAKEHOLDER_TASK_DISPUTE) return DataResult.FailedWithDesc(nameof(MultiLanguageConst.AuditUnauthorization)); //var list = await TenantDb.Queryable().Where(x => x.ClientId == callback.BusinessId) // .Select(x => new InfoClientStakeholder // { // Id = callback.BusinessId, // Remark = callback.RejectReason // }).ToListAsync(); var list = await TenantDb.Queryable().Where(x => x.Id == callback.BusinessId) .Select(x => new InfoClientStakeholder { Id = callback.BusinessId, Remark = callback.RejectReason }).ToListAsync(); foreach (var item in list) { item.Status = callback.FlowStatus == FlowStatusEnum.Approve ? StakeholderStatus.Approved : StakeholderStatus.Rejected; } await TenantDb.Ado.BeginTranAsync(); try { int rows = await TenantDb.Updateable(list).UpdateColumns(x => new { x.Remark, x.Status }).ExecuteCommandAsync(); ////如果状态为驳回则发起争议审核 //if (callback.FlowStatus == FlowStatusEnum.Reject && callback.AuditType == CLIENT_STAKEHOLDER_TASK) //{ // var result = await SubmitAuditAsync(new IdModel // { // Id = callback.BusinessId.ToString(), // Value = CLIENT_STAKEHOLDER_TASK_DISPUTE // }); // if (!result.Succeeded) // return result; //} await TenantDb.Ado.CommitTranAsync(); return DataResult.Success; } catch (Exception ex) { await TenantDb.Ado.RollbackTranAsync(); await ex.LogAsync(Db); return DataResult.FailedWithDesc(nameof(MultiLanguageConst.Operation_Failed)); } } #endregion /// /// 导入 /// /// /// public async Task ImportAsync(List list) { var clientNames = list.Select(x => x.CustomerName).Distinct(); var clients = await TenantDb.Queryable().Where(x => clientNames.Contains(x.ShortName) || clientNames.Contains(x.Description)) .Select(x => new { x.Id, x.ShortName, x.Description, x.OrgId }).ToListAsync(); var userCodes = list.Select(x => x.StakeholderName).Distinct(); var users = await Db.Queryable().Where(x => userCodes.Contains(x.UserName)).Select(x => new { x.Id, x.UserName, x.UserCode }).ToListAsync(); StringBuilder sb = new(); List stakeholders = new(list.Count); long userId = long.Parse(User.UserId); DateTime dtNow = DateTime.Now.Date; foreach (var model in list) { if (dtNow > model.EndDate) continue; var client = clients.Find(x => x.ShortName == model.CustomerName || x.Description == model.CustomerName); if (client == null) { sb.Append("," + model.CustomerName); continue; } var user = users.Find(x => x.UserName == model.StakeholderName); if (user == null) { sb.Append("," + model.StakeholderName); continue; } InfoClientStakeholder stakeholder = new() { ClientId = client.Id, UserId = user.Id, UserName = model.StakeholderName, StartDate = model.StartDate, EndDate = model.EndDate, Status = StakeholderStatus.Approved, Remark = "系统导入", CreateBy = userId, CreateByName = User.UserName, CreateTime = dtNow }; stakeholders.Add(stakeholder); } //if (sb.Length > 0) //{ // sb.Remove(0, 1); // return DataResult.Failed("下列数据匹配不到客户/供应商或干系人信息:" + sb.ToString()); //} await TenantDb.Ado.BeginTranAsync(); try { await TenantDb.Fastest().BulkCopyAsync(stakeholders); await TenantDb.Ado.CommitTranAsync(); return DataResult.Success; } catch (Exception ex) { await TenantDb.Ado.RollbackTranAsync(); await ex.LogAsync(Db); return DataResult.Failed("导入失败:" + ex.Message); } } /// /// 列表 /// /// /// public async Task>> GetListAsync(PageRequest request) { //序列化查询条件 var whereList = request.GetConditionalModels(Db); var result = await TenantDb.Queryable() .Where(whereList) .ToQueryPageAsync(request.PageCondition); if (result.Data?.Count > 0) { var ids = result.Data.Select(x => x.ClientId).Distinct(); var clients = await TenantDb.Queryable().Where(x => ids.Contains(x.Id)) .Select(x => new { x.Id, x.ShortName }).ToListAsync(); foreach (var item in result.Data) { item.ClientShortName = clients.Find(x => x.Id == item.ClientId)?.ShortName; } } return result; } /// /// 获取客户干系人 /// /// /// public async Task> GetAsync(long id) { var model = await TenantDb.Queryable().FirstAsync(x => x.Id == id); return DataResult.Success(model); } /// /// 创建/更新客户干系人 /// /// 干系人 /// public async Task EditAsync(params InfoClientStakeholder[] stakeholders) { var result = await IsAvailableAsync(stakeholders); if (!result.Succeeded) return result; var userId = long.Parse(User.UserId); var dtNow = DateTime.Now; for (var i = 0; i < stakeholders.Length; i++) { var item = stakeholders[i]; item.CreateBy = userId; item.CreateByName = User.UserName; item.CreateTime = dtNow; } await TenantDb.Storageable(stakeholders).DefaultAddElseUpdate().ExecuteCommandAsync(); result = DataResult.Success; result.Data = stakeholders; return result; } /// /// 创建客户干系人并提交审核 /// /// 干系人 /// public async Task AddSubmitAsync(InfoClientStakeholder stakeholder) { var result = await IsAvailableAsync(stakeholder); if (!result.Succeeded) return result; stakeholder.CreateBy = long.Parse(User.UserId); stakeholder.CreateByName = User.UserName; stakeholder.CreateTime = DateTime.Now; await TenantDb.Insertable(stakeholder).ExecuteCommandAsync(); return await SubmitAuditAsync(new IdModel { Id = stakeholder.Id.ToString(), Ids = [stakeholder.Id] }); } /// /// 检查干系人是否存在 /// /// 干系人 /// public async Task IsAvailableAsync(params InfoClientStakeholder[] stakeholders) { var dtNow = DateTime.Now.Date; var clientId = stakeholders[0].ClientId; var ids1 = stakeholders.Select(x => x.UserId); var ids2 = stakeholders.Where(x => x.Id > 0).Select(x => x.Id); var expr = Expressionable.Create() .And(x => x.ClientId == clientId && ids1.Contains(x.UserId) && SqlFunc.Between(dtNow, x.StartDate, x.EndDate)) .AndIF(ids2.Any(), x => !ids2.Contains(x.Id)); if (await TenantDb.Queryable().AnyAsync(expr.ToExpression())) { var result = DataResult.FailedWithDesc(nameof(MultiLanguageConst.StakeholderExist)); result.Code = ResultCode.Fail; result.Data = stakeholders; return result; } return DataResult.Success; } /// /// 删除干系人 /// /// /// public async Task DeleteAsync(params long[] ids) { await TenantDb.Deleteable() .Where(x => ids.Contains(x.Id)).ExecuteCommandAsync(); return DataResult.Success; } } }