diff --git a/Framework/YLErp.Core/DBModels/ClientBlackLog.cs b/Framework/YLErp.Core/DBModels/ClientBlackLog.cs new file mode 100644 index 00000000..54bcf093 --- /dev/null +++ b/Framework/YLErp.Core/DBModels/ClientBlackLog.cs @@ -0,0 +1,32 @@ +using System.ComponentModel.DataAnnotations.Schema; + +namespace YLErp.DBModels +{ + /// + /// 客户黑名单审批及操作日志。 + /// + [Table("client_blacklog")] + public class ClientBlackLog + { + public long id { get; set; } + + public int ClientBlackId { get; set; } + + public string Changes { get; set; } + + public string OptType { get; set; } + + public string DataType { get; set; } + + public int OptId { get; set; } + + public string OptName { get; set; } + + public DateTime OptDate { get; set; } + } + + [NotMapped] + public class ClientBlackLogDto : ClientBlackLog + { + } +} diff --git a/Framework/YLErp.Core/DBModels/Client_Black.cs b/Framework/YLErp.Core/DBModels/Client_Black.cs index 306d3cdd..7fb31970 100644 --- a/Framework/YLErp.Core/DBModels/Client_Black.cs +++ b/Framework/YLErp.Core/DBModels/Client_Black.cs @@ -10,6 +10,13 @@ namespace YLErp.Model [Table("client_black")] public class client_black : DBModelWithOperator, IDataEntity, IDataTraceV2, IClonable { + public const string 未提交 = "未提交"; + public const string 新增审批中 = "新增审批中"; + public const string 新增已拒绝 = "新增已拒绝"; + public const string 已加入 = "已加入"; + public const string 删除审批中 = "删除审批中"; + public const string 删除已拒绝 = "删除已拒绝"; + /// /// 客户名称 /// @@ -25,6 +32,26 @@ namespace YLErp.Model [DataChange] public string Remarks { get; set; } + [DisplayName("提交审批时间")] + public DateTime? ApprovalOptDate { get; set; } + + [DisplayName("提交审批人")] + public string ApprovalOptName { get; set; } + + public int ApprovalProcess { get; set; } + + [DisplayName("状态")] + public string State { get; set; } = ""; + + [DisplayName("创建人")] + public int? creator_id { get; set; } + + [DisplayName("创建人")] + public string creator_name { get; set; } + + [DisplayName("创建时间")] + public DateTime? creator_time { get; set; } + public client_black Clone() { return (client_black)MemberwiseClone(); diff --git a/UnitTestProject/Modules/ClientModule/ClientBlackApprovalPolicyTests.cs b/UnitTestProject/Modules/ClientModule/ClientBlackApprovalPolicyTests.cs new file mode 100644 index 00000000..47534e8f --- /dev/null +++ b/UnitTestProject/Modules/ClientModule/ClientBlackApprovalPolicyTests.cs @@ -0,0 +1,121 @@ +using YLErp.Model; + +namespace YLErp.Modules.ClientModule.Tests +{ + [TestClass] + public class ClientBlackApprovalPolicyTests + { + [DataTestMethod] + [DataRow(client_black.未提交, false)] + [DataRow(client_black.新增审批中, false)] + [DataRow(client_black.新增已拒绝, false)] + [DataRow(client_black.已加入, true)] + [DataRow(client_black.删除审批中, true)] + [DataRow(client_black.删除已拒绝, true)] + public void IsEffective_OnlyAppliedOrPendingRemovalStatesAreEffective(string state, bool expected) + { + Assert.AreEqual(expected, ClientBlackApprovalPolicy.IsEffective(state)); + } + + [DataTestMethod] + [DataRow(client_black.未提交, true)] + [DataRow(client_black.新增已拒绝, true)] + [DataRow(client_black.新增审批中, false)] + [DataRow(client_black.已加入, false)] + [DataRow(client_black.删除审批中, false)] + [DataRow(client_black.删除已拒绝, false)] + public void CanSubmitAddition_OnlyDraftOrRejectedAdditionCanSubmit(string state, bool expected) + { + Assert.AreEqual(expected, ClientBlackApprovalPolicy.CanSubmitAddition(state)); + } + + [DataTestMethod] + [DataRow(client_black.已加入, true)] + [DataRow(client_black.删除已拒绝, true)] + [DataRow(client_black.未提交, false)] + [DataRow(client_black.新增审批中, false)] + [DataRow(client_black.新增已拒绝, false)] + [DataRow(client_black.删除审批中, false)] + public void CanRequestRemoval_OnlyEffectiveNonPendingRemovalStatesCanRequest(string state, bool expected) + { + Assert.AreEqual(expected, ClientBlackApprovalPolicy.CanRequestRemoval(state)); + } + + [DataTestMethod] + [DataRow(client_black.新增审批中, 1, true)] + [DataRow(client_black.删除审批中, 1, true)] + [DataRow(client_black.新增审批中, 2, false)] + [DataRow(client_black.删除审批中, 2, false)] + [DataRow(client_black.未提交, 0, false)] + public void CanWithdraw_OnlyFirstApprovalNodeCanWithdraw(string state, int approvalProcess, bool expected) + { + Assert.AreEqual(expected, ClientBlackApprovalPolicy.CanWithdraw(state, approvalProcess)); + } + + [DataTestMethod] + [DataRow(client_black.新增审批中, client_black.新增已拒绝)] + [DataRow(client_black.删除审批中, client_black.删除已拒绝)] + public void RejectedState_DistinguishesAdditionAndRemoval(string state, string expected) + { + Assert.AreEqual(expected, ClientBlackApprovalPolicy.GetRejectedState(state)); + } + + [DataTestMethod] + [DataRow(client_black.新增审批中, client_black.未提交, 0)] + [DataRow(client_black.删除审批中, client_black.已加入, -2)] + public void WithdrawState_RestoresStateBeforeSubmission(string state, string expectedState, int expectedProcess) + { + var result = ClientBlackApprovalPolicy.GetWithdrawResult(state); + + Assert.AreEqual(expectedState, result.State); + Assert.AreEqual(expectedProcess, result.ApprovalProcess); + } + + [DataTestMethod] + [DataRow(client_black.新增审批中, client_black.已加入, false)] + [DataRow(client_black.删除审批中, null, true)] + public void GetFinalResult_AdditionAppliesAndRemovalDeletes(string state, string expectedState, bool expectedDelete) + { + var result = ClientBlackApprovalPolicy.GetFinalResult(state); + + Assert.AreEqual(expectedState, result.State); + Assert.AreEqual(expectedDelete, result.ShouldDelete); + } + + [DataTestMethod] + [DataRow(false, client_black.已加入, -2, true)] + [DataRow(true, client_black.未提交, 0, false)] + public void GetAdditionResult_OnlyEffectiveWithoutApprovalProcess(bool hasApprovalProcess, string expectedState, int expectedProcess, bool expectedEffective) + { + var result = ClientBlackApprovalPolicy.GetAdditionResult(hasApprovalProcess); + + Assert.AreEqual(expectedState, result.State); + Assert.AreEqual(expectedProcess, result.ApprovalProcess); + Assert.AreEqual(expectedEffective, result.IsEffective); + } + + [DataTestMethod] + [DataRow(false, client_black.已加入, -2, true)] + [DataRow(true, client_black.删除审批中, 1, false)] + public void GetRemovalResult_OnlyDeletesImmediatelyWithoutApprovalProcess(bool hasApprovalProcess, string expectedState, int expectedProcess, bool expectedDelete) + { + var result = ClientBlackApprovalPolicy.GetRemovalResult(hasApprovalProcess); + + Assert.AreEqual(expectedState, result.State); + Assert.AreEqual(expectedProcess, result.ApprovalProcess); + Assert.AreEqual(expectedDelete, result.ShouldDelete); + } + + [DataTestMethod] + [DataRow(client_black.未提交, true)] + [DataRow(client_black.新增已拒绝, true)] + [DataRow(client_black.新增审批中, false)] + [DataRow(client_black.删除审批中, false)] + [DataRow(client_black.已加入, true)] + [DataRow(client_black.删除已拒绝, true)] + public void CanReplaceRemarks_ApprovalPendingRowsCannotBeOverwritten(string state, bool expected) + { + Assert.AreEqual(expected, ClientBlackApprovalPolicy.CanReplaceRemarks(state)); + } + } +} diff --git a/YLErpDAL/DataBase/ClientDBContext.cs b/YLErpDAL/DataBase/ClientDBContext.cs index c7098ab9..d210be40 100644 --- a/YLErpDAL/DataBase/ClientDBContext.cs +++ b/YLErpDAL/DataBase/ClientDBContext.cs @@ -19,6 +19,8 @@ namespace BaseOUDAL public DbSet client_black { get; set; } + public DbSet client_blacklog { get; set; } + public DbSet client_file { get; set; } public DbSet client_file_audit { get; set; } @@ -57,4 +59,4 @@ namespace BaseOUDAL public DbSet client_customer_manage { get; set; } } -} \ No newline at end of file +} diff --git a/YLErpDAL/Model/ClientBlackApprovalQueryRes.cs b/YLErpDAL/Model/ClientBlackApprovalQueryRes.cs new file mode 100644 index 00000000..92658cab --- /dev/null +++ b/YLErpDAL/Model/ClientBlackApprovalQueryRes.cs @@ -0,0 +1,20 @@ +namespace YLErp.Model +{ + public class ClientBlackApprovalQueryRes + { + public int id { get; set; } + public string EncryptId { get; set; } + public string ProcessStatus { get; set; } + public int ProcessOrderId { get; set; } + public string ProcessRoleName { get; set; } + public string ClientName { get; set; } + public int ProcessRoleId { get; set; } + public string Comments { get; set; } + public string ApprovalOptName { get; set; } + public DateTime? ApprovalOptDate { get; set; } + public string State { get; set; } + public int? creator_id { get; set; } + public string creator_name { get; set; } + public DateTime? creator_time { get; set; } + } +} diff --git a/YLErpDAL/Model/ClientBlackAuditReq.cs b/YLErpDAL/Model/ClientBlackAuditReq.cs new file mode 100644 index 00000000..7cf85003 --- /dev/null +++ b/YLErpDAL/Model/ClientBlackAuditReq.cs @@ -0,0 +1,18 @@ +using YLErp.Helpers; + +namespace YLErp.Model +{ + /// + /// 黑名单审批请求。 + /// + public class ClientBlackAuditReq + { + public string enid { get; set; } + + public int id => DataProtectHelper.DecryptInt(enid); + + public string status { get; set; } + + public string auditComment { get; set; } + } +} diff --git a/YLErpDAL/Model/clientblackReq.cs b/YLErpDAL/Model/clientblackReq.cs index 47cf73de..f7b8f958 100644 --- a/YLErpDAL/Model/clientblackReq.cs +++ b/YLErpDAL/Model/clientblackReq.cs @@ -14,6 +14,12 @@ namespace YLErp.Model /// public string Name { get; set; } + public DateTime? DateFromOptDate { get; set; } + + public DateTime? DateToOptDate { get; set; } + + public string ClientBlackStates { get; set; } + } } diff --git a/YLErpDAL/Modules/ClientModule/ClientBlackApprovalPolicy.cs b/YLErpDAL/Modules/ClientModule/ClientBlackApprovalPolicy.cs new file mode 100644 index 00000000..b880f82b --- /dev/null +++ b/YLErpDAL/Modules/ClientModule/ClientBlackApprovalPolicy.cs @@ -0,0 +1,89 @@ +using YLErp.Model; + +namespace YLErp.Modules.ClientModule +{ + public static class ClientBlackApprovalPolicy + { + public static readonly string[] EffectiveStates = + { + client_black.已加入, + client_black.删除审批中, + client_black.删除已拒绝 + }; + + public static bool IsEffective(string state) + { + return EffectiveStates.Contains(state); + } + + public static bool CanSubmitAddition(string state) + { + return state == client_black.未提交 || state == client_black.新增已拒绝; + } + + public static ClientBlackAdditionResult GetAdditionResult(bool hasApprovalProcess) + { + return hasApprovalProcess + ? new ClientBlackAdditionResult(client_black.未提交, 0, false) + : new ClientBlackAdditionResult(client_black.已加入, -2, true); + } + + public static bool CanRequestRemoval(string state) + { + return state == client_black.已加入 || state == client_black.删除已拒绝; + } + + public static ClientBlackRemovalResult GetRemovalResult(bool hasApprovalProcess) + { + return hasApprovalProcess + ? new ClientBlackRemovalResult(client_black.删除审批中, 1, false) + : new ClientBlackRemovalResult(client_black.已加入, -2, true); + } + + public static bool CanReplaceRemarks(string state) + { + return state != client_black.新增审批中 && state != client_black.删除审批中; + } + + public static bool CanWithdraw(string state, int approvalProcess) + { + return approvalProcess == 1 && + (state == client_black.新增审批中 || state == client_black.删除审批中); + } + + public static string GetRejectedState(string state) + { + return state switch + { + client_black.新增审批中 => client_black.新增已拒绝, + client_black.删除审批中 => client_black.删除已拒绝, + _ => throw new ArgumentException("当前状态不允许拒绝审批", nameof(state)) + }; + } + + public static ClientBlackWithdrawResult GetWithdrawResult(string state) + { + return state switch + { + client_black.新增审批中 => new ClientBlackWithdrawResult(client_black.未提交, 0), + client_black.删除审批中 => new ClientBlackWithdrawResult(client_black.已加入, -2), + _ => throw new ArgumentException("当前状态不允许撤回审批", nameof(state)) + }; + } + + public static ClientBlackFinalResult GetFinalResult(string state) + { + return state switch + { + client_black.新增审批中 => new ClientBlackFinalResult(client_black.已加入, false), + client_black.删除审批中 => new ClientBlackFinalResult(null, true), + _ => throw new ArgumentException("当前状态不允许完成审批", nameof(state)) + }; + } + } + + public readonly record struct ClientBlackWithdrawResult(string State, int ApprovalProcess); + public readonly record struct ClientBlackFinalResult(string State, bool ShouldDelete); + public readonly record struct ClientBlackAdditionResult(string State, int ApprovalProcess, bool IsEffective); + public readonly record struct ClientBlackRemovalResult(string State, int ApprovalProcess, bool ShouldDelete); +} diff --git a/YLErpDAL/Modules/ClientModule/ClientBlackService.cs b/YLErpDAL/Modules/ClientModule/ClientBlackService.cs index 894dec2a..edd40593 100644 --- a/YLErpDAL/Modules/ClientModule/ClientBlackService.cs +++ b/YLErpDAL/Modules/ClientModule/ClientBlackService.cs @@ -41,6 +41,19 @@ namespace YLErp.Modules.ClientModule { predicate = predicate.And(d => d.Name.Contains(req.Name)); } + if (!string.IsNullOrEmpty(req.ClientBlackStates)) + { + var states = req.ClientBlackStates.Split(',', StringSplitOptions.RemoveEmptyEntries); + predicate = predicate.And(d => states.Contains(d.State)); + } + if (req.DateFromOptDate.HasValue) + { + predicate = predicate.And(d => d.OptDate >= req.DateFromOptDate.Value); + } + if (req.DateToOptDate.HasValue) + { + predicate = predicate.And(d => d.OptDate < req.DateToOptDate.Value.AddDays(1)); + } } var query = DbContext.client_black.AsNoTracking().Where(predicate); @@ -93,6 +106,314 @@ namespace YLErp.Modules.ClientModule return retListResult; } + public List ProcessList() + { + return DbContextFactory.GetYLDbContext().approvalprocess + .Where(s => s.processType == "ClientBlackProcess") + .OrderBy(s => s.order) + .ToList(); + } + + public void DeleteClientBlack(IEnumerable ids) + { + var idList = ids?.Distinct().ToList() ?? new List(); + if (idList.Count == 0) + { + throw new ServiceException("请选择要移出的黑名单客户"); + } + + var rows = DbContext.client_black.Where(x => idList.Contains(x.id)).ToList(); + if (rows.Count != idList.Count) + { + throw new ServiceException("未找到要删除的数据"); + } + + var hasProcess = ProcessList().Any(); + foreach (var row in rows) + { + if (!ClientBlackApprovalPolicy.CanRequestRemoval(row.State)) + { + throw new ServiceException($"黑名单客户{row.Name}当前状态不允许移出"); + } + + if (hasProcess) + { + var result = ClientBlackApprovalPolicy.GetRemovalResult(true); + row.State = result.State; + row.ApprovalProcess = result.ApprovalProcess; + row.ApprovalOptName = UserName; + row.ApprovalOptDate = DateTime.Now; + ClientBlackCategoryLog(row.id, client_black.删除审批中); + } + else + { + RemoveEffectiveBlack(row); + } + } + + DbContext.SaveChanges(); + } + + public void WithdrawApprovalClientBlack(List ids, out int withdrawCount, out string msg) + { + withdrawCount = 0; + msg = ""; + var rows = DbContext.client_black.Where(x => ids.Contains(x.id)).ToList(); + foreach (var row in rows) + { + if (!ClientBlackApprovalPolicy.CanWithdraw(row.State, row.ApprovalProcess)) + { + if (row.ApprovalProcess > 1) + { + msg += row.Name + ","; + } + continue; + } + + var result = ClientBlackApprovalPolicy.GetWithdrawResult(row.State); + row.State = result.State; + row.ApprovalProcess = result.ApprovalProcess; + row.ApprovalOptName = null; + row.ApprovalOptDate = null; + ClientBlackCategoryLog(row.id, row.State); + withdrawCount++; + } + DbContext.SaveChanges(); + } + + public void SubmitApprovalClientBlack(List ids) + { + var rows = DbContext.client_black.Where(x => ids.Contains(x.id)).ToList(); + var process = ProcessList(); + foreach (var row in rows) + { + if (!ClientBlackApprovalPolicy.CanSubmitAddition(row.State)) + { + continue; + } + + if (process.Count == 0) + { + row.State = client_black.已加入; + row.ApprovalProcess = -2; + row.ApprovalOptName = UserName; + row.ApprovalOptDate = DateTime.Now; + var notifications = new List<(Client oldClient, Client newClient)>(); + ApplyEffectiveAddition(row.Name, notifications); + ClientBlackCategoryLog(row.id, client_black.已加入, "未设置审批流程,直接通过"); + DbContext.SaveChanges(); + SendClientNotifications(notifications); + continue; + } + + row.State = client_black.新增审批中; + row.ApprovalProcess = 1; + row.ApprovalOptName = UserName; + row.ApprovalOptDate = DateTime.Now; + ClientBlackCategoryLog(row.id, client_black.新增审批中); + } + DbContext.SaveChanges(); + } + + public string AuditClientBlack(ClientBlackAuditReq req, bool isBatch = false, string optType = "") + { + var row = DbContext.client_black.Find(req.id); + if (row == null) + { + throw new ServiceException("审批失败,系统中没有该黑名单记录"); + } + if (row.State != client_black.新增审批中 && row.State != client_black.删除审批中) + { + throw new ServiceException("当前黑名单不在审批中"); + } + + var process = ProcessList(); + var currentNode = process.FirstOrDefault(x => x.order == row.ApprovalProcess); + if (currentNode == null || !UserBLL.GetRolesByUserId(UserId).Any(x => x.Id == currentNode.roleId)) + { + throw new ServiceException("当前用户无权审批该节点"); + } + if (req.status == "reject") + { + row.State = ClientBlackApprovalPolicy.GetRejectedState(row.State); + row.ApprovalProcess = -1; + row.ApprovalOptDate = DateTime.Now; + row.OptId = UserId; + row.OptName = UserName; + row.OptDate = DateTime.Now; + ClientBlackCategoryLog(row.id, row.State, req.auditComment); + DbContext.SaveChanges(); + return "提交成功"; + } + + if (req.status != "pass") + { + throw new ServiceException("status参数不支持:" + req.status); + } + + var nextNode = process.FirstOrDefault(x => x.order > row.ApprovalProcess); + if (nextNode != null) + { + row.ApprovalProcess = nextNode.order; + row.ApprovalOptDate = DateTime.Now; + row.OptId = UserId; + row.OptName = UserName; + row.OptDate = DateTime.Now; + ClientBlackCategoryLog(row.id, row.State, req.auditComment); + DbContext.SaveChanges(); + return "提交成功"; + } + + var final = ClientBlackApprovalPolicy.GetFinalResult(row.State); + if (final.ShouldDelete) + { + RemoveEffectiveBlack(row, req.auditComment, isBatch ? optType : null); + DbContext.SaveChanges(); + } + else + { + row.State = final.State; + row.ApprovalProcess = -2; + row.ApprovalOptDate = DateTime.Now; + var notifications = new List<(Client oldClient, Client newClient)>(); + ApplyEffectiveAddition(row.Name, notifications); + ClientBlackCategoryLog(row.id, isBatch ? optType : row.State, req.auditComment); + DbContext.SaveChanges(); + SendClientNotifications(notifications); + } + return "提交成功"; + } + + public SearchListResult ClientBlackApprovalQuery(ClientBlackReq req) + { + var process = ProcessList(); + var predicate = PredicateBuilder.Create(x => x.ApprovalProcess > 0); + if (!string.IsNullOrWhiteSpace(req.Name)) + { + predicate = predicate.And(x => x.Name.Contains(req.Name)); + } + var query = from row in DbContext.client_black.AsNoTracking().Where(predicate) + select new ClientBlackApprovalQueryRes + { + id = row.id, + EncryptId = row.EncryptId, + ProcessOrderId = row.ApprovalProcess, + ProcessRoleId = 0, + ProcessStatus = "审批中 流程" + (row.ApprovalProcess - 1) + "/" + process.Count, + State = row.State, + ClientName = row.Name, + Comments = row.Remarks, + ApprovalOptName = row.ApprovalOptName, + ApprovalOptDate = row.ApprovalOptDate, + creator_id = row.creator_id, + creator_name = row.creator_name, + creator_time = row.creator_time + }; + if (string.IsNullOrEmpty(req.sidx)) + { + req.sidx = "ApprovalOptDate"; + req.sord = "desc"; + } + var result = query.OrderByDescending(x => x.ApprovalOptDate).ToSearchList(req); + var roles = new ErpBaseContext().Roles + .Select(x => new { x.Id, x.Name }) + .ToDictionary(x => x.Id, x => x.Name); + foreach (var item in result.rows) + { + var node = process.FirstOrDefault(x => x.order == item.ProcessOrderId); + if (node == null) + { + continue; + } + + item.ProcessRoleId = node.roleId; + item.ProcessRoleName = roles.TryGetValue(node.roleId, out var roleName) ? roleName : string.Empty; + } + return result; + } + + private void ApplyEffectiveAddition(string name, List<(Client oldClient, Client newClient)> notifications) + { + var client = DbContext.client.FirstOrDefault(c => c.Name == name); + if (client == null) + { + return; + } + var dt = DateTime.Now; + var oldClient = client.Clone(); + if (client.ProcessStatus == "已开户") + { + client.ProcessOrderId = -4; + client.ProcessStatus = "已休眠"; + client.OptId = UserId; + client.OptName = UserName; + client.OptDate = dt; + DbContext.ClientAuditLog.Add(new ClientAuditLog + { + ClientId = client.id, + OptType = "休眠", + Changes = string.Empty, + DataType = "00", + OptId = UserId, + OptName = UserName, + OptDate = dt + }); + notifications.Add((oldClient, client)); + } + DbContext.ClientAuditLog.Add(new ClientAuditLog + { + ClientId = client.id, + OptType = "加入黑名单", + Changes = string.Empty, + DataType = "00", + OptId = UserId, + OptName = UserName, + OptDate = dt + }); + } + + private void RemoveEffectiveBlack(client_black row, string changes = null, string optType = null) + { + var client = DbContext.client.FirstOrDefault(c => c.Name == row.Name); + if (client != null) + { + DbContext.ClientAuditLog.Add(new ClientAuditLog + { + ClientId = client.id, + OptType = "移除黑名单", + Changes = string.Empty, + DataType = "00", + OptId = UserId, + OptName = UserName, + OptDate = DateTime.Now + }); + } + DbContext.client_black.Remove(row); + ClientBlackCategoryLog(row.id, optType ?? "已删除", changes); + } + + private void SendClientNotifications(List<(Client oldClient, Client newClient)> notifications) + { + foreach (var (oldClient, newClient) in notifications) + { + new ClientKafkaService(_kafkaProduce).Send(newClient, oldClient); + } + } + + public void ClientBlackCategoryLog(int clientblackId, string optType, string changes = null) + { + DbContext.client_blacklog.Add(new ClientBlackLog + { + ClientBlackId = clientblackId, + OptType = optType, + Changes = changes, + DataType = "00", + OptId = UserId, + OptName = UserName, + OptDate = DateTime.Now + }); + } + /// /// 客户黑名单导入 /// @@ -165,37 +486,47 @@ namespace YLErp.Modules.ClientModule public void AddClientBlack(IEnumerable list, bool checkStatus) { + var inputList = list?.ToList() ?? new List(); var errMsgList = new List(); - var nameList = list.Select(O => O.Name); - var dbList = DbContext.client_black.Where(O => nameList.Contains(O.Name)); + var nameList = inputList.Select(O => O.Name).ToList(); + var dbList = DbContext.client_black.Where(O => nameList.Contains(O.Name)).ToList(); + foreach (var item in dbList) + { + var obj = inputList.FirstOrDefault(O => O.Name.Equals(item.Name, StringComparison.OrdinalIgnoreCase)); + if (obj == null) + { + continue; + } + if (!ClientBlackApprovalPolicy.CanReplaceRemarks(item.State)) + { + throw new ServiceException("黑名单客户在审批中无法修改!"); + } + if (checkStatus && !string.IsNullOrWhiteSpace(item.Remarks) && item.Remarks != obj.Remarks) + { + errMsgList.Add($"{item.Name}"); + } + } if (checkStatus) { - foreach (var item in dbList) - { - var obj = list.First(O => O.Name.Equals(item.Name, StringComparison.OrdinalIgnoreCase)); - if (!string.IsNullOrWhiteSpace(item.Remarks) && item.Remarks != obj.Remarks) - { - errMsgList.Add($"{item.Name}"); - continue; - } - } if (errMsgList.Count > 0) { var msg = ""; if (errMsgList.Count <= 5) { - msg = $"客户:{string.Join(",", errMsgList)},备注已存在,是否替换?"; + msg = $"客户:{string.Join(",", errMsgList)}当前已在黑名单中,本次将修改备注,备注已存在,是否确认?"; } else { - msg = $"{string.Join(",", errMsgList.Take(5))} 等{errMsgList.Count}个客户,备注已存在,是否替换?"; + msg = $"{string.Join(",", errMsgList.Take(5))} 等{errMsgList.Count}个客户当前已在黑名单中,本次将修改备注,备注已存在,是否确认?"; } throw new ServiceException(msg); } } // 在外部定义列表来保存需要通知的客户对 var clientsToNotify = new List<(Client oldClient, Client newClient)>(); - foreach (var item in list) + var newItems = new List(); + var processList = ProcessList(); + foreach (var item in inputList) { if (string.IsNullOrWhiteSpace(item.Name)) { @@ -206,61 +537,45 @@ namespace YLErp.Modules.ClientModule item.OptId = UserId; item.OptName = UserName; item.OptDate = DateTime.Now; - var clientexistence = DbContext.client.FirstOrDefault(c => c.Name == item.Name); - if (clientexistence != null) + var existing = dbList.FirstOrDefault(x => x.Name.Equals(item.Name, StringComparison.OrdinalIgnoreCase)); + if (existing != null) { - var dt = DateTime.Now; - if (clientexistence.ProcessStatus == "已开户") + var oldRemarks = existing.Remarks; + existing.Remarks = item.Remarks; + existing.OptId = UserId; + existing.OptName = UserName; + existing.OptDate = DateTime.Now; + if (oldRemarks != existing.Remarks) { - var oldClient= clientexistence.Clone(); - clientexistence.ProcessOrderId = -4; - clientexistence.ProcessStatus = "已休眠"; - clientexistence.OptId = UserId; - clientexistence.OptName = UserName; - clientexistence.OptDate = dt; - - DbContext.ClientAuditLog.Add(new ClientAuditLog - { - ClientId = clientexistence.id, - OptType = "休眠", - Changes = string.Empty, - DataType = "00", - OptId = UserId, - OptName = UserName, - OptDate = dt - }); - // 如果原有状态是已开户,添加到通知列表 - if (oldClient != null) - { - clientsToNotify.Add((oldClient, clientexistence)); - } + ClientBlackCategoryLog(existing.id, "修改备注", $"备注:{oldRemarks ?? string.Empty} -> {existing.Remarks ?? string.Empty}"); } - ///日志记录 - DbContext.ClientAuditLog.Add(new ClientAuditLog - { - ClientId = clientexistence.id, - OptType = "加入黑名单", - Changes = string.Empty, - DataType = "00", - OptId = UserId, - OptName = UserName, - OptDate = dt - }); + continue; } + var additionResult = ClientBlackApprovalPolicy.GetAdditionResult(processList.Any()); + item.State = additionResult.State; + item.ApprovalProcess = additionResult.ApprovalProcess; + item.creator_id = UserId; + item.creator_name = UserName; + item.creator_time = DateTime.Now; + if (additionResult.IsEffective) + { + ApplyEffectiveAddition(item.Name, clientsToNotify); + } + newItems.Add(item); } - if (dbList.Any()) + DbContext.client_black.AddRange(newItems); + DbContext.SaveChanges(); + foreach (var item in newItems) { - DbContext.client_black.RemoveRange(dbList); - DbContext.SaveChanges(); + ClientBlackCategoryLog(item.id, item.State); } - DbContext.client_black.AddRange(list); DbContext.SaveChanges(); // 发送Kafka消息 foreach (var (oldClient, newClient) in clientsToNotify) { new ClientKafkaService(_kafkaProduce).Send(newClient, oldClient); } - var importHasTagClientNames = list.Where(p => p.Tags != null && p.Tags.Count > 0).Select(p => p.Name).Distinct().ToList(); + var importHasTagClientNames = inputList.Where(p => p.Tags != null && p.Tags.Count > 0).Select(p => p.Name).Distinct().ToList(); if (importHasTagClientNames != null && importHasTagClientNames.Count > 0) { var dbClients = DbContext.client.AsNoTracking().Where(p => importHasTagClientNames.Contains(p.Name)).Select(p => new ClientSimpleDto @@ -273,7 +588,7 @@ namespace YLErp.Modules.ClientModule var tagService = new TagService(OptUser); dbClients.ForEach(p => { - var importInfo = list.FirstOrDefault(d => d.Name.Equals(p.Name)); + var importInfo = inputList.FirstOrDefault(d => d.Name.Equals(p.Name)); if (importInfo != null) { tagService.SetClientTagForClientImport(new TagModule.Dto.SetClientTagForClientEditRequest { ClientId = p.id, Tags = importInfo.Tags }); diff --git a/YLErpDAL/Modules/ClientModule/ClientImportService.cs b/YLErpDAL/Modules/ClientModule/ClientImportService.cs index 4914a9c2..a59cf971 100644 --- a/YLErpDAL/Modules/ClientModule/ClientImportService.cs +++ b/YLErpDAL/Modules/ClientModule/ClientImportService.cs @@ -317,7 +317,7 @@ namespace YLErp.Modules.ClientModule { return "第" + rowNum + "行客户类别,机构属性,客户性质关联性质有误,导入失败"; } - if (DbContext.client_black.Any(c => c.Name == Name)) + if (DbContext.client_black.Any(c => c.Name == Name && ClientBlackApprovalPolicy.EffectiveStates.Contains(c.State))) { return $"客户'{Name}'已经存在于黑名单中”"; } @@ -1070,7 +1070,7 @@ namespace YLErp.Modules.ClientModule } } } - if (DbContext.client_black.Any(c => c.Name == Name)) + if (DbContext.client_black.Any(c => c.Name == Name && ClientBlackApprovalPolicy.EffectiveStates.Contains(c.State))) { return "" + Name + "客户已经存在于黑名单中”"; } @@ -1733,7 +1733,7 @@ namespace YLErp.Modules.ClientModule //默认为1 IsReceiveEmail = 1; - if (DbContext.client_black.Any(c => c.Name == Name)) + if (DbContext.client_black.Any(c => c.Name == Name && ClientBlackApprovalPolicy.EffectiveStates.Contains(c.State))) { return "" + Name + "客户已经存在于黑名单中"; } diff --git a/YLErpDAL/Modules/ClientModule/ClientProcessLogService.cs b/YLErpDAL/Modules/ClientModule/ClientProcessLogService.cs index d39d0a1e..68dc2e69 100644 --- a/YLErpDAL/Modules/ClientModule/ClientProcessLogService.cs +++ b/YLErpDAL/Modules/ClientModule/ClientProcessLogService.cs @@ -130,7 +130,7 @@ namespace YLErp.Modules.ClientModule try { - if (DbContext.client_black.Any(c => c.Name == client.Name)) + if (DbContext.client_black.Any(c => c.Name == client.Name && ClientBlackApprovalPolicy.EffectiveStates.Contains(c.State))) { client.RejectOrderId = client.ApprovalOrderId; client.ApprovalOrderId = -1; diff --git a/YLErpDAL/Modules/ClientModule/ClientProcessService.cs b/YLErpDAL/Modules/ClientModule/ClientProcessService.cs index 414d2b08..ba2554e3 100644 --- a/YLErpDAL/Modules/ClientModule/ClientProcessService.cs +++ b/YLErpDAL/Modules/ClientModule/ClientProcessService.cs @@ -158,7 +158,7 @@ namespace YLErp.Modules.ClientModule throw new ServiceException("客户名称 必须填写"); } - if (DbContext.client_black.Any(c => c.Name == req.Name)) + if (DbContext.client_black.Any(c => c.Name == req.Name && ClientBlackApprovalPolicy.EffectiveStates.Contains(c.State))) { throw new ServiceException("该客户为黑名单客户,无法进行下一步操作"); } diff --git a/YLErpDAL/Modules/ClientModule/ClientSaveService.cs b/YLErpDAL/Modules/ClientModule/ClientSaveService.cs index b56b4083..358160d1 100644 --- a/YLErpDAL/Modules/ClientModule/ClientSaveService.cs +++ b/YLErpDAL/Modules/ClientModule/ClientSaveService.cs @@ -703,7 +703,7 @@ namespace YLErp.Modules.ClientModule //新增时,新的客户名如果在黑名单里,不允许新增 //修改时,旧的客户名如果在黑名单里,不允许修改 - if (!isAddNew && !req.Name.Equals(blackNameForCheck) && DbContext.client_black.Any(x => x.Name == blackNameForCheck)) + if (!isAddNew && !req.Name.Equals(blackNameForCheck) && DbContext.client_black.Any(x => x.Name == blackNameForCheck && ClientBlackApprovalPolicy.EffectiveStates.Contains(x.State))) { throw new ServiceException("该客户为黑名单客户," + (req.id > 0 ? "不允许修改客户名称" : "不允许新增")); } diff --git a/YLErpDAL/Modules/SystemModule/ApprovalProcessService.cs b/YLErpDAL/Modules/SystemModule/ApprovalProcessService.cs index ae140dd0..4e9be366 100644 --- a/YLErpDAL/Modules/SystemModule/ApprovalProcessService.cs +++ b/YLErpDAL/Modules/SystemModule/ApprovalProcessService.cs @@ -7,6 +7,7 @@ using System.Linq.Expressions; using YLErp.BLL.Eod; using YLErp.DBModels; using YLErp.Helpers; +using YLErp.Model; using YLErp.Model.Enum; using YLErp.Modules.TradeModule; @@ -28,6 +29,17 @@ namespace YLErp.Modules.SystemModule { var clientQuery = DataCacheProvider.GetClientDataSource().AsQueryable(); + if (type == "ClientBlackProcess") + { + var clientdb = DbContextFactory.GetClientDbContext(OptUser); + if (clientdb.client_black.Any(x => x.State == client_black.新增审批中 || x.State == client_black.删除审批中)) + { + throw new ServiceException(data == null || data.Count == 0 + ? "有黑名单在审批中,不能删除审批流程!" + : "有黑名单在审批中,不能修改审批流程!"); + } + } + var delList = DbContext.approvalprocess.Where(s => s.processType == type).ToArray(); DbContext.approvalprocess.RemoveRange(delList); diff --git a/YLErpWeb/App_Data/FunctionRight.xml b/YLErpWeb/App_Data/FunctionRight.xml index eccba1c4..a19f257c 100644 --- a/YLErpWeb/App_Data/FunctionRight.xml +++ b/YLErpWeb/App_Data/FunctionRight.xml @@ -129,8 +129,11 @@ + + + diff --git a/YLErpWeb/App_Data/Menus.txt b/YLErpWeb/App_Data/Menus.txt index 506f2a79..5ab7f56e 100644 --- a/YLErpWeb/App_Data/Menus.txt +++ b/YLErpWeb/App_Data/Menus.txt @@ -63,6 +63,7 @@ {Name:"客户列表",Rights:["客户管理-客户查看"],Url:"client/ClientList"}, {Name:"客户审批",Rights:["客户管理-客户审批"],Url:"clientApproval/openingclientList"}, {Name:"黑名单客户",Rights:["客户管理-黑名单客户"],Url:"clientblack/clientblacklist"}, + {Name:"黑名单审批",Rights:["客户管理-黑名单审批"],Url:"clientblack/clientblackApproval"}, {Name:"授信管理",Rights:["客户管理-授信管理"],Url:"credit/creditList"}, {Name:"资信评级",Rights:["客户管理-资信评级"],Url:"client_rating/List"}, {Name:"机构账号设置",Rights:["客户管理-机构账号设置"],Url:"v3/client/account"} @@ -107,4 +108,4 @@ {Name:"做市账户",Rights:["系统管理-做市账户"],Url:"TrsAccountManage/Index"} ] } -] \ No newline at end of file +] diff --git a/YLErpWeb/Common/UserInfoRight.cs b/YLErpWeb/Common/UserInfoRight.cs index cf0989bd..30bc8b5a 100644 --- a/YLErpWeb/Common/UserInfoRight.cs +++ b/YLErpWeb/Common/UserInfoRight.cs @@ -251,6 +251,12 @@ namespace YLErp.Web /// public bool 黑名单客户管理 => _user.HasRight("客户管理-黑名单客户管理"); + public bool 黑名单审批 => _user.HasRight("客户管理-黑名单审批"); + + public bool 黑名单客户提交审批 => _user.HasRight("客户管理-黑名单客户提交审批"); + + public bool 黑名单客户撤回提交审批 => _user.HasRight("客户管理-黑名单客户撤回提交审批"); + /// /// 客户管理-黑名单客户 /// diff --git a/YLErpWeb/Controllers/AccountOpeningProcessController.cs b/YLErpWeb/Controllers/AccountOpeningProcessController.cs index 9d45614a..0b2af318 100644 --- a/YLErpWeb/Controllers/AccountOpeningProcessController.cs +++ b/YLErpWeb/Controllers/AccountOpeningProcessController.cs @@ -93,7 +93,8 @@ namespace YLErp.Web.Controllers var creditProcess = list.Where(s => s.processType == "CreditProcess").OrderBy(s => s.order).ToList(); var outCashProcess = list.Where(s => s.processType == "OutCashProcess").OrderBy(s => s.order).ToList(); var clientProcess = list.Where(s => s.processType == "ClientProcess").OrderBy(s => s.order).ThenBy(s => s.parentNode).ThenBy(s => s.node).ToList(); - return Json(new { OpenProcess = openProcess, TradeProcess = tradeProcess, CloseProcess = closeProcess, CreditProcess = creditProcess, OutCashProcess= outCashProcess,ClientProcess = clientProcess }); + var clientBlackProcess = list.Where(s => s.processType == "ClientBlackProcess").OrderBy(s => s.order).ThenBy(s => s.parentNode).ThenBy(s => s.node).ToList(); + return Json(new { OpenProcess = openProcess, TradeProcess = tradeProcess, CloseProcess = closeProcess, CreditProcess = creditProcess, OutCashProcess= outCashProcess,ClientProcess = clientProcess, ClientBlackProcess = clientBlackProcess }); } @@ -232,4 +233,4 @@ namespace YLErp.Web.Controllers return Json(sList); } } -} \ No newline at end of file +} diff --git a/YLErpWeb/Controllers/clientController.cs b/YLErpWeb/Controllers/clientController.cs index 93f8c645..f1aaae6d 100644 --- a/YLErpWeb/Controllers/clientController.cs +++ b/YLErpWeb/Controllers/clientController.cs @@ -2529,7 +2529,7 @@ namespace YLErp.Web.Controllers return JsonError(error); } var clientblack = clientDB.client_black.FirstOrDefault(c => c.Name == client.Name); - if (clientblack != null) + if (clientblack != null && YLErp.Modules.ClientModule.ClientBlackApprovalPolicy.IsEffective(clientblack.State)) { return JsonError("该客户为黑名单客户,禁止取消休眠"); } @@ -3402,4 +3402,4 @@ namespace YLErp.Web.Controllers return JsonSuccess(); } } -} \ No newline at end of file +} diff --git a/YLErpWeb/Controllers/clientblackController.cs b/YLErpWeb/Controllers/clientblackController.cs index fc912195..9fe1d7ae 100644 --- a/YLErpWeb/Controllers/clientblackController.cs +++ b/YLErpWeb/Controllers/clientblackController.cs @@ -5,6 +5,19 @@ namespace YLErp.Web.Controllers { public class clientblackController : BaseController { + public static List GetClientBlackStates() + { + return new List + { + new() { Text = client_black.未提交, Value = client_black.未提交 }, + new() { Text = client_black.新增审批中, Value = client_black.新增审批中 }, + new() { Text = client_black.新增已拒绝, Value = client_black.新增已拒绝 }, + new() { Text = client_black.已加入, Value = client_black.已加入 }, + new() { Text = client_black.删除审批中, Value = client_black.删除审批中 }, + new() { Text = client_black.删除已拒绝, Value = client_black.删除已拒绝 } + }; + } + [MyAuthorize("客户管理-黑名单客户")] public ActionResult clientblacklist() { @@ -55,38 +68,75 @@ namespace YLErp.Web.Controllers } public ActionResult DeleteClientBlack(string ids) { - var datalist = ids.Split(','); - var list = new List(); - foreach (var item in datalist) + try { - var data = clientDB.client_black.Find(int.Parse(item)); - if (data == null) - { - return JsonError("未找到要删除的数据"); - } - else - { - var clitid = clientDB.client.Where(c => c.Name == data.Name).FirstOrDefault(); - if (clitid != null) - { - clientDB.ClientAuditLog.Add(new ClientAuditLog - { - ClientId = clitid.id, - OptType = "移除黑名单", - Changes = string.Empty, - DataType = "00", - OptId = UserId, - OptName = UserName, - OptDate = DateTime.Now - }); - } - - clientDB.client_black.Remove(data); - } - + var datalist = ids.Split(',', StringSplitOptions.RemoveEmptyEntries).Select(int.Parse).ToList(); + var service = new ClientBlackService(CurUser); + service.DeleteClientBlack(datalist); + return JsonSuccess(service.ProcessList().Any() ? "已经提交删除审批!" : "删除成功"); } - clientDB.SaveChanges(); - return JsonSuccess("删除成功"); + catch (Exception ex) + { + return JsonError(ex.GetBaseException().Message); + } + } + + [MyAuthorize("客户管理-黑名单审批")] + public ActionResult clientblackApproval() + { + return View(); + } + + [HttpPost, MyAuthorize("客户管理-黑名单审批")] + public JsonResult clientblackApprovalQuery(ClientBlackReq req) + { + return Json(new ClientBlackService(CurUser).ClientBlackApprovalQuery(req)); + } + + [HttpPost, MyAuthorize("客户管理-黑名单客户提交审批")] + public JsonResult clientblackSubmit(string ids) + { + var idList = ids.Split(',', StringSplitOptions.RemoveEmptyEntries).Select(int.Parse).ToList(); + new ClientBlackService(CurUser).SubmitApprovalClientBlack(idList); + return JsonSuccess("提交审批成功"); + } + + [HttpPost, MyAuthorize("客户管理-黑名单客户撤回提交审批")] + public JsonResult clientblackWithdraw(string ids) + { + var idList = ids.Split(',', StringSplitOptions.RemoveEmptyEntries).Select(int.Parse).ToList(); + new ClientBlackService(CurUser).WithdrawApprovalClientBlack(idList, out var withdrawCount, out var msg); + if (withdrawCount == 0) + { + return JsonError(string.IsNullOrWhiteSpace(msg) + ? "所选记录当前状态无法撤回审批" + : $"以下记录已进入后续节点无法撤回:{msg}"); + } + return JsonSuccess("撤回审批成功" + (string.IsNullOrWhiteSpace(msg) ? "" : $",以下记录已进入后续节点无法撤回:{msg}")); + } + + [HttpPost, MyAuthorize("客户管理-黑名单审批")] + public JsonResult Auditclientblack(ClientBlackAuditReq req) + { + new ClientBlackService(CurUser).AuditClientBlack(req); + return JsonSuccess("审批成功"); + } + + [MyAuthorize("客户管理-黑名单审批")] + public ActionResult clientblackView(string enid) + { + var id = DataProtectHelper.DecryptInt(enid); + var item = clientDB.client_black.FirstOrDefault(x => x.id == id); + return View(item); + } + + [MyAuthorize("客户管理-黑名单客户")] + public ActionResult clientblackLogList(int id) + { + var logs = clientDB.client_blacklog.Where(x => x.ClientBlackId == id) + .OrderByDescending(x => x.id) + .ToList(); + return View(logs); } @@ -101,4 +151,4 @@ namespace YLErp.Web.Controllers return File(bytes, xlsxMimeType, $"黑名单导出-{DateTime.Now:yyyy-MM-dd}.xlsx"); } } -} \ No newline at end of file +} diff --git a/YLErpWeb/Views/AccountOpeningProcess/Index.cshtml b/YLErpWeb/Views/AccountOpeningProcess/Index.cshtml index 2ecdfefc..a2bbcced 100644 --- a/YLErpWeb/Views/AccountOpeningProcess/Index.cshtml +++ b/YLErpWeb/Views/AccountOpeningProcess/Index.cshtml @@ -786,6 +786,46 @@ +
+
黑名单审批流程
+
+
+
+
申请人
+
+
+
+ +
+
+
+ +
+
+
结束流程
+
+
+
diff --git a/YLErpWeb/Views/clientblack/clientblackApproval.cshtml b/YLErpWeb/Views/clientblack/clientblackApproval.cshtml new file mode 100644 index 00000000..566df422 --- /dev/null +++ b/YLErpWeb/Views/clientblack/clientblackApproval.cshtml @@ -0,0 +1,74 @@ +@{ + ViewBag.Title = "黑名单客户审批"; + Layout = "~/Views/Shared/_MainLayout.cshtml"; + var pageObj = new + { + roles = UserBLL.GetRolesByUserId(CurUser.UserId).Select(x => x.Id) + }; +} +@section CSS{ + + +} +@section JS{ + +} +
+ + + @MyControls.SearchBtn() +
+@Html.Raw(JqGridSimple.OutTable()) diff --git a/YLErpWeb/Views/clientblack/clientblackLogList.cshtml b/YLErpWeb/Views/clientblack/clientblackLogList.cshtml new file mode 100644 index 00000000..6ccf41ad --- /dev/null +++ b/YLErpWeb/Views/clientblack/clientblackLogList.cshtml @@ -0,0 +1,14 @@ +@model IEnumerable +@{ + ViewBag.Title = "黑名单操作历史"; + Layout = "~/Views/Shared/_InfoLayout.cshtml"; +} + + + + @foreach (var item in Model ?? Enumerable.Empty()) + { + + } + +
时间操作人操作内容说明
@item.OptDate.ToString("yyyy-MM-dd HH:mm:ss")@item.OptName@item.OptType@item.Changes
diff --git a/YLErpWeb/Views/clientblack/clientblackView.cshtml b/YLErpWeb/Views/clientblack/clientblackView.cshtml new file mode 100644 index 00000000..1192edf4 --- /dev/null +++ b/YLErpWeb/Views/clientblack/clientblackView.cshtml @@ -0,0 +1,45 @@ +@using YLErp.Modules.ClientModule +@model YLErp.Model.client_black +@{ + ViewBag.Title = "黑名单客户审批"; + Layout = "~/Views/Shared/_InfoLayout.cshtml"; + var process = new ClientBlackService(CurUser).ProcessList(); + var currentNode = process.FirstOrDefault(x => x.order == Model?.ApprovalProcess); + var canAudit = currentNode != null && UserBLL.GetRolesByUserId(CurUser.UserId).Any(x => x.Id == currentNode.roleId); +} +@section JS { + +} +
+
+ @if (canAudit) + { + @MyControls.Btn("审批通过", "audit('pass');") + @MyControls.Btn("拒绝", "audit('reject');") + } +
+
+
+ + + + + + + + + + + +
客户名称@Model?.Name
黑名单备注@Model?.Remarks
审批状态@Model?.State
提交审批人@Model?.ApprovalOptName
提交审批时间@Model?.ApprovalOptDate?.ToString("yyyy-MM-dd HH:mm:ss")
审批说明
+
diff --git a/YLErpWeb/Views/clientblack/clientblacklist.cshtml b/YLErpWeb/Views/clientblack/clientblacklist.cshtml index 7ab08bb0..d8821a20 100644 --- a/YLErpWeb/Views/clientblack/clientblacklist.cshtml +++ b/YLErpWeb/Views/clientblack/clientblacklist.cshtml @@ -51,10 +51,10 @@ var colModelGrid = [{ name: 'id', label: 'id', index: 'id', width: 0, hidden: true, optionHide: true }, { - name: 'opt', label: '操作', index: 'opt', width: 150, align: 'left', hidden: !page.canEdit, optionHide: !page.canEdit, sortable: false, + name: 'opt', label: '操作', index: 'opt', width: 200, align: 'left', hidden: !page.canEdit, optionHide: !page.canEdit, sortable: false, formatter: function (cellValue, options, rowObject) { if (page.canEdit) { - var html = ("") + var html = ("") .template(rowObject.id); return html; } @@ -65,7 +65,9 @@ }, { name: 'Name', label: '客户名称', index: 'Name', width: 260 }, { - name: 'Remarks', label: '备注', index: 'Remarks', width: 500 + name: 'Remarks', label: '备注', index: 'Remarks', width: 500 + }, { + name: 'State', label: '状态', index: 'State', width: 120 }, { name: 'OptName', label: '操作人', index: 'OptName', width: 150 }, { @@ -146,7 +148,7 @@ function SearchClick(isSearchclick) { var listGrid = $('#listGrid'); listGrid.appendPostData({ Name: $("#Name").val() }); - listGrid.appendPostData({ OptName: $("#OptName").val() }); + listGrid.appendPostData({ ClientBlackStates: $("#ClientBlackStates").val()?.join(',') || '' }); if (typeof (isSearchclick) != "undefined" && isSearchclick) { //点击搜索时默认第一页 listGrid.jqGrid('setGridParam', {page: 1}); @@ -241,6 +243,19 @@ }); }) } + function ClientBlackSubmit() { + var ids = main.GetGridIds($('#listGrid')); + if (!ids.length) { main.message('请选择要提交的数据!'); return; } + main.post('/clientblack/clientblackSubmit', { ids: ids.toString() }).done(function () { SearchClick(); }); + } + function ClientBlackWithdraw() { + var ids = main.GetGridIds($('#listGrid')); + if (!ids.length) { main.message('请选择要撤回的数据!'); return; } + main.post('/clientblack/clientblackWithdraw', { ids: ids.toString() }).done(function () { SearchClick(); }); + } + function clientblackLogView(id) { + main.open('操作历史', '/clientblack/clientblackLogList?id=' + id, { area: ['1000px', '75%'] }); + } } @@ -267,6 +282,7 @@
+ @Html.MyAceDropdownInput("ClientBlackStates", "状态", clientblackController.GetClientBlackStates()) @if (CurUser.客户管理.黑名单客户管理) { @@ -275,6 +291,14 @@ } + @if (CurUser.客户管理.黑名单客户提交审批) + { + + } + @if (CurUser.客户管理.黑名单客户撤回提交审批) + { + + }
-@Html.Raw(JqGridSimple.OutTable()) \ No newline at end of file +@Html.Raw(JqGridSimple.OutTable()) diff --git a/YLErpWeb/wwwroot/Scripts/app/system/Approvalprocess.js b/YLErpWeb/wwwroot/Scripts/app/system/Approvalprocess.js index cff6d111..68c4b3a8 100644 --- a/YLErpWeb/wwwroot/Scripts/app/system/Approvalprocess.js +++ b/YLErpWeb/wwwroot/Scripts/app/system/Approvalprocess.js @@ -53,7 +53,8 @@ var app = new Vue({ { text: '交易新增与修改', value: '2' }, { text: '交易了结', value: '6' }, /* { text: '资信与授信', value: '3' },*/ - { text: '出金', value: '4' } + { text: '出金', value: '4' }, + { text: '黑名单', value: '7' } ], isOpen: false, @@ -62,12 +63,14 @@ var app = new Vue({ isCredit: false, isOutCash: false, isClient: false, + isClientBlack: false, openItems: [], clientItems: [], tradeItems: [], closeItems: [], creditItems: [], outCashItems: [], + clientBlackItems: [], openCounter: 0, tradeCounter: 0, creditCounter: 0, @@ -140,6 +143,7 @@ var app = new Vue({ thisObj.isCredit = false; thisObj.isOutCash = false; thisObj.isClient = false; + thisObj.isClientBlack = false; } else if (thisObj.selected === '2') { thisObj.isOpen = false; thisObj.isTrade = true; @@ -147,6 +151,7 @@ var app = new Vue({ thisObj.isCredit = false; thisObj.isOutCash = false; thisObj.isClient = false; + thisObj.isClientBlack = false; } else if (thisObj.selected === '6') { // 需求②:交易了结流程 thisObj.isOpen = false; thisObj.isTrade = false; @@ -154,6 +159,7 @@ var app = new Vue({ thisObj.isCredit = false; thisObj.isOutCash = false; thisObj.isClient = false; + thisObj.isClientBlack = false; } else if (thisObj.selected === '3') { thisObj.isOpen = false; thisObj.isTrade = false; @@ -161,6 +167,7 @@ var app = new Vue({ thisObj.isCredit = true; thisObj.isOutCash = false; thisObj.isClient = false; + thisObj.isClientBlack = false; } else if (thisObj.selected === '4') { thisObj.isOpen = false; @@ -169,6 +176,7 @@ var app = new Vue({ thisObj.isCredit = false; thisObj.isOutCash = true; thisObj.isClient = false; + thisObj.isClientBlack = false; } else if (thisObj.selected === '5') { thisObj.isOpen = false; @@ -177,6 +185,16 @@ var app = new Vue({ thisObj.isCredit = false; thisObj.isOutCash = false; thisObj.isClient = true; + thisObj.isClientBlack = false; + } + else if (thisObj.selected === '7') { + thisObj.isOpen = false; + thisObj.isTrade = false; + thisObj.isClose = false; + thisObj.isCredit = false; + thisObj.isOutCash = false; + thisObj.isClient = false; + thisObj.isClientBlack = true; } else { thisObj.isOpen = false; @@ -185,6 +203,7 @@ var app = new Vue({ thisObj.isCredit = false; thisObj.isOutCash = false; thisObj.isClient = false; + thisObj.isClientBlack = false; } thisObj.getProcess(); }, @@ -385,6 +404,18 @@ var app = new Vue({ thisObj.addCloseNode(index, child, node); return; } + else if (selectType === "7") { //黑名单 + var item = { + Type: 'ClientBlackProcess', + Index: index + 1, + SelectValue: 0 + }; + thisObj.clientBlackItems.splice(index, 0, item); + thisObj.clientBlackItems.forEach(function (x, itemIndex) { + x.Index = itemIndex + 1; + }); + return; + } }, delProcess: function (openItem) { @@ -417,6 +448,14 @@ var app = new Vue({ }); return; } + else if (selectType === "7") {//黑名单 + var index = thisObj.clientBlackItems.indexOf(openItem); + thisObj.clientBlackItems.splice(index, 1); + thisObj.clientBlackItems.forEach(function (x, itemIndex) { + x.Index = itemIndex + 1; + }); + return; + } }, addOpenProcess(index, child, node) { var thisObj = this; @@ -528,6 +567,10 @@ var app = new Vue({ thisObj.saveCloseProcess(); return; } + else if (selectType === "7") { //黑名单 + thisObj.clientBlackOk(); + return; + } }, openOk() { var thisObj = this; @@ -857,6 +900,38 @@ var app = new Vue({ }); } }, + clientBlackOk() { + var thisObj = this; + var items = thisObj.clientBlackItems; + for (var i = 0; i < items.length; i++) { + if (items[i].SelectValue === "" || items[i].SelectValue === 0) { + main.message('流程中断,请重新选择'); + return; + } + for (var j = i + 1; j < items.length; j++) { + if (parseInt(items[i].SelectValue) === parseInt(items[j].SelectValue)) { + main.message('流程包含重复项,请重新选择'); + return; + } + } + } + + if (items.length > 0) { + main.confirm("确认修改黑名单审批流程?", function () { + main.post("/AccountOpeningProcess/AddProcess", + { type: "ClientBlackProcess", data: items }, + { async: false }).done(function () { + thisObj.getProcess(); + }); + }); + } else { + main.confirm("删除审批流程后,黑名单变更会直接生效,确认删除?", function () { + main.post("/AccountOpeningProcess/AddProcess", + { type: "ClientBlackProcess" }, + { async: false }); + }); + } + }, getProcess() { var thisObj = this; thisObj.openItems = []; @@ -865,6 +940,7 @@ var app = new Vue({ thisObj.creditItems = []; thisObj.outCashItems = []; thisObj.clientItems = []; + thisObj.clientBlackItems = []; main.post("/AccountOpeningProcess/GetProcess", {}, { async: false }).done( @@ -945,6 +1021,14 @@ var app = new Vue({ triggerCondition: value.triggerCondition }); }); + (res.ClientBlackProcess || []).forEach(function (value) { + thisObj.clientBlackItems.push({ + id: value.id, + Type: value.processType, + Index: value.order, + SelectValue: value.roleId + }); + }); // 需求①:加载后把 triggerCondition(JSON)解析为结构化对象供 UI 编辑 ['openItems', 'tradeItems', 'closeItems', 'clientItems'].forEach(function (arr) { thisObj[arr].forEach(function (item) {