Explorar el Código

Merge branch 'master' of http://git.fwt.com/Hotline/hotline

dss hace 2 años
padre
commit
71a5381ac3

+ 4 - 7
src/Hotline.Api/Controllers/OrderController.cs

@@ -67,7 +67,7 @@ public class OrderController : BaseController
     [HttpGet]
     public async Task<PagedDto<OrderDto>> Query([FromQuery] QueryOrderDto dto)
     {
-        var (total, items) = await _orderRepository.Queryable()
+        var (total, items) = await _orderRepository.Queryable(workflowFilter: false)
             .Includes(d => d.Employee)
             .WhereIF(!string.IsNullOrEmpty(dto.Keyword), d => d.Title.Contains(dto.Keyword) || d.No.Contains(dto.Keyword))
             .WhereIF(!string.IsNullOrEmpty(dto.Content), d => d.Content.Contains(dto.Content))
@@ -113,7 +113,7 @@ public class OrderController : BaseController
     [HttpGet("{id}")]
     public async Task<OrderDto> Get(string id)
     {
-        var order = await _orderRepository.Queryable()
+        var order = await _orderRepository.Queryable(workflowFilter: false)
             .Includes(d => d.Employee)
             .Includes(d => d.OrderComplain)
             .Includes(d => d.OrderReport)
@@ -166,10 +166,7 @@ public class OrderController : BaseController
         if (order.Status != EOrderStatus.Temporary)
             throw UserFriendlyException.SameMessage("非草稿工单不可编辑");
         _mapper.Map(dto, order);
-        await _orderRepository.UpdateNav(order)
-            .Include(d => d.OrderComplain)
-            .Include(d => d.OrderReport)
-            .ExecuteCommandAsync();
+        await _orderRepository.UpdateOrderNavAsync(order, HttpContext.RequestAborted);
     }
 
     /// <summary>
@@ -188,7 +185,7 @@ public class OrderController : BaseController
             throw UserFriendlyException.SameMessage("工单已发起流程");
 
         var definition = await _definitionDomainService.GetLastVersionDefinitionByModuleCodeAsync(
-            WorkflowModuleConsts.TelRestApply, HttpContext.RequestAborted);
+            WorkflowModuleConsts.OrderManage, HttpContext.RequestAborted);
         if (definition is null)
             throw UserFriendlyException.SameMessage("未配置流程模板");
         dto.DefinitionCode = definition.Code;

+ 17 - 0
src/Hotline.Api/StartupHelper.cs

@@ -6,6 +6,7 @@ using MapsterMapper;
 using Microsoft.AspNetCore.Authentication.JwtBearer;
 using Microsoft.IdentityModel.Tokens;
 using Microsoft.OpenApi.Models;
+using XF.Domain.Entities;
 using XF.Domain.Options;
 
 namespace Hotline.Api
@@ -165,6 +166,22 @@ namespace Hotline.Api
         public static IServiceCollection RegisterMapper(this IServiceCollection services)
         {
             var config = TypeAdapterConfig.GlobalSettings;
+            config.ForDestinationType<IDataPermission>()
+                .Ignore(d => d.CreatorId)
+                .Ignore(d => d.CreatorOrgId)
+                .Ignore(d => d.CreatorOrgCode)
+                .Ignore(d => d.AreaId);
+            config.ForDestinationType<IWorkflow>()
+                .Ignore(d => d.WorkflowId)
+                .Ignore(d => d.ExpiredTimeConfigId)
+                .Ignore(d => d.AssignOrgCodes)
+                .Ignore(d => d.AssignUserIds);
+            config.ForDestinationType<IHasCreationTime>()
+                .Ignore(d => d.CreationTime);
+            config.ForDestinationType<IHasDeletionTime>().Ignore(d => d.DeletionTime);
+            config.ForDestinationType<ISoftDelete>().Ignore(d => d.IsDeleted);
+            config.ForDestinationType<IHasModificationTime>().Ignore(d => d.LastModificationTime);
+
             services.AddSingleton(config);
             services.AddScoped<IMapper, ServiceMapper>();
 

+ 5 - 5
src/Hotline.Application/Mappers/MapperConfigs.cs

@@ -17,11 +17,11 @@ namespace Hotline.Application.Mappers
     {
         public void Register(TypeAdapterConfig config)
         {
-            config.NewConfig<AddBlacklistDto, Blacklist>()
+            config.ForType<AddBlacklistDto, Blacklist>()
                 .Ignore(d => d.Expired)
                 .AfterMapping((s, t) => t.InitExpired());
 
-            config.NewConfig<AddUserDto, User>()
+            config.ForType<AddUserDto, User>()
                 .Map(d => d.Name, x => x.Name ?? x.UserName);
 
             config.NewConfig<User, UserDto>()
@@ -39,17 +39,17 @@ namespace Hotline.Application.Mappers
 
             #region workflow
 
-            config.NewConfig<UpdateDefinitionDto, Definition>()
+            config.ForType<UpdateDefinitionDto, Definition>()
                 .Ignore(d => d.Id);
 
-            config.NewConfig<WorkflowStep, WorkflowStep>()
+            config.ForType<WorkflowStep, WorkflowStep>()
                 .Ignore(d => d.Id);
 
             #endregion
 
             #region order
 
-            config.NewConfig<Order, OrderDto>()
+            config.ForType<Order, OrderDto>()
                 .IgnoreIf((s, d) => s.OrderComplain == null, d => d.OrderComplain)
                 .IgnoreIf((s, d) => s.OrderReport == null, d => d.OrderReport)
                 .IgnoreIf((s, d) => s.Employee == null, d => d.EmployeeName, d => d.EmployeeStaffNo)

+ 30 - 2
src/Hotline.Repository.SqlSugar/BaseRepositoryWorkflow.cs

@@ -17,11 +17,39 @@ public abstract class BaseRepositoryWorkflow<TEntity> : BaseRepository<TEntity>,
         _dataPermissionFilterBuilder = dataPermissionFilterBuilder;
     }
 
-    public ISugarQueryable<TEntity> Queryable(bool includeDeleted = false)
+    public ISugarQueryable<TEntity> Queryable(bool permissionVerify = false, bool includeDeleted = false, bool workflowFilter = true)
     {
         if (includeDeleted)
             Db.QueryFilter.Clear();
 
-        return Db.Queryable<TEntity>().WorkflowDataFiltering(_dataPermissionFilterBuilder);
+        //return Db.Queryable<TEntity>().WorkflowDataFiltering(_dataPermissionFilterBuilder);
+        var query = Db.Queryable<TEntity>();
+        if (permissionVerify)
+            query = query.DataPermissionFiltering(_dataPermissionFilterBuilder);
+
+        if (workflowFilter)
+            query = query.WorkflowDataFiltering(_dataPermissionFilterBuilder);
+        return query;
+    }
+
+    public async Task<string> AddAsync(TEntity entity, CancellationToken cancellationToken = default)
+    {
+        entity.InitDatePermission(_dataPermissionFilterBuilder.DataPermissionManager)
+            .AssignToCreator(_dataPermissionFilterBuilder.DataPermissionManager);
+        var excEntity = await Db.Insertable(entity).ExecuteReturnEntityAsync();
+        return excEntity.Id;
+    }
+
+    /// <summary>
+    /// 批量插入(应用场景:小数据量,超出1万条建议另行实现)
+    /// </summary>
+    /// <param name="entities"></param>
+    /// <param name="cancellationToken"></param>
+    /// <returns></returns>
+    public async Task AddRangeAsync(List<TEntity> entities, CancellationToken cancellationToken = default)
+    {
+        entities.ForEach(d => d.InitDatePermission(_dataPermissionFilterBuilder.DataPermissionManager)
+                .AssignToCreator(_dataPermissionFilterBuilder.DataPermissionManager));
+        await Db.Insertable(entities).ExecuteCommandAsync();
     }
 }

+ 29 - 21
src/Hotline.Repository.SqlSugar/DataPermissions/DataPermissionFilterBuilder.cs

@@ -43,30 +43,38 @@ public class DataPermissionFilterBuilder : IDataPermissionFilterBuilder, IScopeD
     {
         var userId = _sessionContext.RequiredUserId;
         var orgCode = _sessionContext.RequiredOrgCode;
-        var queryFilterType = DataPermissionManager.GetQueryFilter<TEntity>(_sessionContext);
 
-        switch (queryFilterType)
-        {
-            case EAuthorityType.Create:
-                return d => d.CreatorId == userId
-                            || d.AssignUserIds.Contains(userId)
-                            || d.AssignOrgCodes.Contains(orgCode);
-            case EAuthorityType.Org:
-                return d => d.CreatorOrgCode == orgCode
-                            || d.AssignUserIds.Contains(userId)
-                            || d.AssignOrgCodes.Contains(orgCode)
-                    ;
-            case EAuthorityType.OrgAndBelow:
-                return d => d.CreatorOrgCode.StartsWith(orgCode)
-                            || d.AssignUserIds.Contains(userId)
-                            || d.AssignOrgCodes.Contains(orgCode);
-            case EAuthorityType.All:
-                return d => true;
-            default:
-                return d => d.AssignUserIds.Contains(userId) || d.AssignOrgCodes.Contains(orgCode);
-        }
+        return d => d.AssignUserIds.Contains(userId) || d.AssignOrgCodes.Contains(orgCode);
     }
 
+    //public Expression<Func<TEntity, bool>> BuildIncludeFlowData<TEntity>() where TEntity : class, IEntity<string>, IDataPermission, IWorkflow, new()
+    //{
+    //    var userId = _sessionContext.RequiredUserId;
+    //    var orgCode = _sessionContext.RequiredOrgCode;
+    //    var queryFilterType = DataPermissionManager.GetQueryFilter<TEntity>(_sessionContext);
+
+    //    switch (queryFilterType)
+    //    {
+    //        case EAuthorityType.Create:
+    //            return d => d.CreatorId == userId
+    //                        || d.AssignUserIds.Contains(userId)
+    //                        || d.AssignOrgCodes.Contains(orgCode);
+    //        case EAuthorityType.Org:
+    //            return d => d.CreatorOrgCode == orgCode
+    //                        || d.AssignUserIds.Contains(userId)
+    //                        || d.AssignOrgCodes.Contains(orgCode)
+    //                ;
+    //        case EAuthorityType.OrgAndBelow:
+    //            return d => d.CreatorOrgCode.StartsWith(orgCode)
+    //                        || d.AssignUserIds.Contains(userId)
+    //                        || d.AssignOrgCodes.Contains(orgCode);
+    //        case EAuthorityType.All:
+    //            return d => true;
+    //        default:
+    //            return d => d.AssignUserIds.Contains(userId) || d.AssignOrgCodes.Contains(orgCode);
+    //    }
+    //}
+
     //private static bool FlowDataFiltering<TEntity>(TEntity entity, string userId, string orgCode, string[] roles) where TEntity : class, IEntity<string>, IDataPermission, IWorkflow, new()
     //{
     //    if (entity.AssignUserIds.Contains(userId)) return true;

+ 8 - 0
src/Hotline.Repository.SqlSugar/Extensions/DataPermissionExtensions.cs

@@ -25,5 +25,13 @@ namespace Hotline.Repository.SqlSugar.Extensions
             entity.CreateDataPermission(orgId, departmentCode, creatorId, areaId);
             return entity;
         }
+
+        public static TEntity AssignToCreator<TEntity>(this TEntity entity, IDataPermissionManager dataPermissionManager)
+            where TEntity : class, IEntity<string>, IDataPermission, IWorkflow, new()
+        {
+            var (orgId, departmentCode, creatorId, areaId) = dataPermissionManager.GetDataPermissionOptions();
+            entity.Assign(EFlowAssignType.User, creatorId);
+            return entity;
+        }
     }
 }

+ 1 - 1
src/Hotline.Repository.SqlSugar/Extensions/SqlSugarStartupExtensions.cs

@@ -172,7 +172,7 @@ namespace Hotline.Repository.SqlSugar.Extensions
             /***写AOP等方法***/
             db.Aop.OnLogExecuting = (sql, pars) =>
             {
-                //Log.Information(sql);
+                Log.Information(sql);
             };
             db.Aop.OnError = (exp) =>//SQL报错
             {

+ 24 - 0
src/Hotline.Repository.SqlSugar/Orders/OrderRepository.cs

@@ -3,6 +3,7 @@ using System.Collections.Generic;
 using System.Linq;
 using System.Text;
 using System.Threading.Tasks;
+using Hotline.Identity.Roles;
 using Hotline.Orders;
 using Hotline.Repository.SqlSugar.DataPermissions;
 using Hotline.Repository.SqlSugar.Extensions;
@@ -47,5 +48,28 @@ namespace Hotline.Repository.SqlSugar.Orders
             }
             return order.Id;
         }
+
+        public async Task UpdateOrderNavAsync(Order order, CancellationToken cancellationToken)
+        {
+            if (order.OrderType == EOrderType.MarketSupervisionBy12315)
+            {
+                if (order.AcceptType == EAcceptType.Complain)
+                {
+                    await UpdateNav(order).Include(d => d.OrderComplain).ExecuteCommandAsync();
+                }
+                else if (order.AcceptType == EAcceptType.Report)
+                {
+                    await UpdateNav(order).Include(d => d.OrderReport).ExecuteCommandAsync();
+                }
+                else
+                {
+                    throw UserFriendlyException.SameMessage("12315工单不支持该受理类型");
+                }
+            }
+            else
+            {
+                await UpdateAsync(order, cancellationToken);
+            }
+        }
     }
 }

+ 3 - 3
src/Hotline.Repository.SqlSugar/System/SystemOrganizeRepository.cs

@@ -15,7 +15,7 @@ namespace Hotline.Repository.SqlSugar.System
         public async Task<IReadOnlyList<SystemOrganize>> GetOrgJson()
         {
             var list = await Db.Queryable<SystemOrganize>()
-                .ToTreeAsync(x => x.Children, it => it.ParentId, "");
+                .ToTreeAsync(x => x.Children, it => it.ParentId, null);
             return list;
         }
 
@@ -23,7 +23,7 @@ namespace Hotline.Repository.SqlSugar.System
         {
             var list = await Db.Queryable<SystemOrganize>()
                 .Where(x => x.IsEnable)
-                .ToTreeAsync(x => x.Children, it => it.ParentId, "");
+                .ToTreeAsync(x => x.Children, it => it.ParentId, null);
             return list;
         }
 
@@ -34,7 +34,7 @@ namespace Hotline.Repository.SqlSugar.System
                 .OrderByDescending(x => x.OrgCode)
                 .FirstAsync(x => x.ParentId == parentId);
             //如果存在下级
-            if (model!=null)
+            if (model != null)
             {
                 //return $"{int.Parse(model.OrgCode) +1:###}";
                 //return (int.Parse(model.OrgCode) + 1).ToString().PadLeft(3,'0');

+ 6 - 3
src/Hotline.Share/Dtos/Order/OrderDto.cs

@@ -3,6 +3,7 @@ using System.Collections.Generic;
 using System.Linq;
 using System.Text;
 using System.Threading.Tasks;
+using Hotline.Share.Dtos.FlowEngine;
 using Hotline.Share.Enums.Order;
 using XF.Utility.EnumExtensions;
 
@@ -20,13 +21,13 @@ namespace Hotline.Share.Dtos.Order
         /// <summary>
         /// 到达当前节点时间
         /// </summary>
-        public DateTime CurrentStepTime { get; set; }
+        public DateTime? CurrentStepTime { get; set; }
 
         /// <summary>
         /// 工单状态
         /// </summary>
         public EOrderStatus Status { get; set; }
-
+        
         /// <summary>
         /// 开始时间
         /// </summary>
@@ -74,7 +75,7 @@ namespace Hotline.Share.Dtos.Order
         /// 超期时间描述(需求:超期3天、0.5天后超期)
         /// </summary>
         public string ExpiredText => CalculateExpiredText();
-
+        
         private string CalculateExpiredText()
         {
             //todo 完整处理方案:1.创建待过期表,Id,过期时间,即将过期时间等字段。2.延迟消息通知处理过期,删除子表数据,处理order过期状态字段。3.此处即可采用expiredStatus进行判断
@@ -92,6 +93,8 @@ namespace Hotline.Share.Dtos.Order
                     return "超期不到1天";
             }
         }
+
+        public WorkflowDto Workflow { get; set; }
     }
 
     public class UpdateOrderDto : AddOrderDto

+ 1 - 0
src/Hotline/Orders/IOrderRepository.cs

@@ -10,5 +10,6 @@ namespace Hotline.Orders
     public interface IOrderRepository : IRepositoryWorkflow<Order>
     {
         Task<string> AddOrderNavAsync(Order order, CancellationToken cancellationToken);
+        Task UpdateOrderNavAsync(Order order, CancellationToken cancellationToken);
     }
 }

+ 2 - 0
src/Hotline/Orders/Order.cs

@@ -27,11 +27,13 @@ namespace Hotline.Orders
         /// <summary>
         /// 来电号码
         /// </summary>
+        [SugarColumn(IsNullable = true)]
         public string? FromPhone { get; set; }
 
         /// <summary>
         /// 转接号码(转接来源)
         /// </summary>
+        [SugarColumn(IsNullable = true)]
         public string? TransferPhone { get; set; }
 
         /// <summary>

+ 4 - 2
src/Hotline/Settings/SystemOrganize.cs

@@ -34,12 +34,14 @@ public class SystemOrganize : CreationEntity
     /// <summary>
     /// 上级ID
     /// </summary>
-    public string ParentId { get; set; }
+    [SugarColumn(IsIgnore = true)]
+    public string? ParentId { get; set; }
 
     /// <summary>
     /// 上级名称
     /// </summary>
-    public string ParentName { get; set; }
+    [SugarColumn(IsIgnore = true)]
+    public string? ParentName { get; set; }
 
     /// <summary>
     /// 是否启用

+ 7 - 7
src/XF.Domain.Repository/Entity.cs

@@ -15,25 +15,25 @@ public abstract class Entity : IEntity<string>, IDomainEvents, IDataPermission,
     /// 组织Id
     /// </summary>
     [SugarColumn(ColumnDescription = "组织Id", IsNullable = true)]
-    public string? CreatorOrgId { get; private set; }
+    public string? CreatorOrgId { get; set; }
 
     /// <summary>
     /// 组织编码
     /// </summary>
     [SugarColumn(ColumnDescription = "组织编码", IsNullable = true)]
-    public string? CreatorOrgCode { get; private set; }
+    public string? CreatorOrgCode { get; set; }
 
     /// <summary>
     /// 创建人
     /// </summary>
     [SugarColumn(ColumnDescription = "创建人", IsNullable = true)]
-    public string? CreatorId { get; private set; }
+    public string? CreatorId { get; set; }
 
     /// <summary>
     /// 赋值部门Id
     /// </summary>
     [SugarColumn(ColumnDescription = "数据权限区域Id", IsNullable = true)]
-    public string AreaId { get; private set; }
+    public string AreaId { get; set; }
 
     public void CreateDataPermission(string orgId, string orgCode, string creatorId, string? areaId)
     {
@@ -75,10 +75,10 @@ public abstract class SoftDeleteEntity : Entity, IHasDeletionTime, ISoftDelete
     /// 删除时间
     /// </summary>
     [SugarColumn(ColumnDescription = "删除时间")]
-    public DateTime? DeletionTime { get; private set; }
+    public DateTime? DeletionTime { get; set; }
 
     [SugarColumn(ColumnDescription = "是否删除")]
-    public bool IsDeleted { get; private set; }
+    public bool IsDeleted { get; set; }
 
     public void SoftDelete()
     {
@@ -93,7 +93,7 @@ public abstract class SoftDeleteEntity : Entity, IHasDeletionTime, ISoftDelete
 public abstract class CreationSoftDeleteEntity : CreationEntity, IHasDeletionTime, ISoftDelete
 {
     [SugarColumn(ColumnDescription = "是否删除")]
-    public bool IsDeleted { get; private set; }
+    public bool IsDeleted { get; set; }
 
     /// <summary>
     /// 删除时间

+ 1 - 1
src/XF.Domain.Repository/IRepositoryWorkflow.cs

@@ -13,7 +13,7 @@ namespace XF.Domain.Repository
         where TEntity : class, IEntity<string>, new()
         where TKey : IEquatable<TKey>
     {
-        ISugarQueryable<TEntity> Queryable(bool includeDeleted = false);
+        ISugarQueryable<TEntity> Queryable(bool permissionVerify = false, bool includeDeleted = false, bool workflowFilter = true);
     }
 
     public interface IRepositoryWorkflow<TEntity> : IRepositoryWorkflow<TEntity, string> where TEntity : class, IEntity<string>, new()