Ver código fonte

Merge branch 'test' of http://110.188.24.182:10023/Fengwo/hotline into test

Dun.Jason 3 meses atrás
pai
commit
3e5ed21b73

+ 91 - 91
src/Hotline.Api/Controllers/Bi/BiOrderController.cs

@@ -1916,11 +1916,11 @@ namespace Hotline.Api.Controllers.Bi
                 .Select(o => new CenterReportCallDto
                 {
                     EffectiveCount = SqlFunc.AggregateSum(SqlFunc.IIF(o.OnState == EOnState.On, 1, 0)),//有效
-					InTotal = SqlFunc.AggregateSum(SqlFunc.IIF(o.CallDirection == ECallDirection.In, 1, 0)),//呼入总量
-					OutTotal = SqlFunc.AggregateSum(SqlFunc.IIF(o.CallDirection == ECallDirection.Out, 1, 0)),//呼出总量
-					InConnectionQuantity = SqlFunc.AggregateSum(SqlFunc.IIF(o.CallDirection == ECallDirection.In && o.AnsweredTime != null, 1, 0)),//呼入接通量
-					OutConnectionQuantity = SqlFunc.AggregateSum(SqlFunc.IIF(o.TelNo != "0" && o.CallDirection == ECallDirection.Out && o.AnsweredTime != null, 1, 0)),//呼出接通量
-					InvalidCount = SqlFunc.AggregateSum(SqlFunc.IIF(o.OnState == EOnState.NoOn /*&& o.BeginIvrTime.HasValue && o.BeginQueueTime.HasValue && o.BeginRingTime.HasValue*/, 1, 0)), //无效(排除队列挂断和IVR挂断)
+                    InTotal = SqlFunc.AggregateSum(SqlFunc.IIF(o.CallDirection == ECallDirection.In, 1, 0)),//呼入总量
+                    OutTotal = SqlFunc.AggregateSum(SqlFunc.IIF(o.CallDirection == ECallDirection.Out, 1, 0)),//呼出总量
+                    InConnectionQuantity = SqlFunc.AggregateSum(SqlFunc.IIF(o.CallDirection == ECallDirection.In && o.AnsweredTime != null, 1, 0)),//呼入接通量
+                    OutConnectionQuantity = SqlFunc.AggregateSum(SqlFunc.IIF(o.TelNo != "0" && o.CallDirection == ECallDirection.Out && o.AnsweredTime != null, 1, 0)),//呼出接通量
+                    InvalidCount = SqlFunc.AggregateSum(SqlFunc.IIF(o.OnState == EOnState.NoOn /*&& o.BeginIvrTime.HasValue && o.BeginQueueTime.HasValue && o.BeginRingTime.HasValue*/, 1, 0)), //无效(排除队列挂断和IVR挂断)
                     QueueByeCount = SqlFunc.AggregateSum(SqlFunc.IIF(o.CallDirection == ECallDirection.In && o.QueueTims > 0 && o.RingTimes == 0 && o.OnState == EOnState.NoOn, 1, 0)), //队列挂断
                     IvrByeCount = SqlFunc.AggregateSum(SqlFunc.IIF(o.CallDirection == ECallDirection.In && o.BeginIvrTime.HasValue && !o.BeginQueueTime.HasValue && !o.BeginRingTime.HasValue && o.OnState == EOnState.NoOn, 1, 0)), //IVR挂断
                 })
@@ -2086,8 +2086,8 @@ namespace Hotline.Api.Controllers.Bi
             {
                 sourceChannel.Add(new CenterReportOrderSourceChannelDto
                 {
-					AllCountNum = sourceChannelCount,
-					Name = item.DicDataName,
+                    AllCountNum = sourceChannelCount,
+                    Name = item.DicDataName,
                     Code = item.DicTypeCode,
                     CountNum = sourceChannelData.Find(p => p.Code == item.DicDataValue)?.CountNum ?? 0
                 });
@@ -2495,14 +2495,14 @@ namespace Hotline.Api.Controllers.Bi
 
             if (enterpriseOrderDto2 != null)
             {
-				centerReportStatisticsDto.EnterpriseOrderDto.VisitdCount = enterpriseOrderDto2.VisitdCount;
-				centerReportStatisticsDto.EnterpriseOrderDto.Dissatisfied = enterpriseOrderDto2.Dissatisfied;
-				centerReportStatisticsDto.EnterpriseOrderDto.CityDissatisfied = enterpriseOrderDto2.CityDissatisfied;
-				centerReportStatisticsDto.EnterpriseOrderDto.CountyDissatisfied = enterpriseOrderDto2.CountyDissatisfied;
-				centerReportStatisticsDto.EnterpriseOrderDto.Satisfied = enterpriseOrderDto2.Satisfied;
-				centerReportStatisticsDto.EnterpriseOrderDto.CitySatisfied = enterpriseOrderDto2.CitySatisfied;
-				centerReportStatisticsDto.EnterpriseOrderDto.CountySatisfied = enterpriseOrderDto2.CountySatisfied;
-			}
+                centerReportStatisticsDto.EnterpriseOrderDto.VisitdCount = enterpriseOrderDto2.VisitdCount;
+                centerReportStatisticsDto.EnterpriseOrderDto.Dissatisfied = enterpriseOrderDto2.Dissatisfied;
+                centerReportStatisticsDto.EnterpriseOrderDto.CityDissatisfied = enterpriseOrderDto2.CityDissatisfied;
+                centerReportStatisticsDto.EnterpriseOrderDto.CountyDissatisfied = enterpriseOrderDto2.CountyDissatisfied;
+                centerReportStatisticsDto.EnterpriseOrderDto.Satisfied = enterpriseOrderDto2.Satisfied;
+                centerReportStatisticsDto.EnterpriseOrderDto.CitySatisfied = enterpriseOrderDto2.CitySatisfied;
+                centerReportStatisticsDto.EnterpriseOrderDto.CountySatisfied = enterpriseOrderDto2.CountySatisfied;
+            }
 
             if (listInfo != null && listInfo.Rows.Count > 0 && centerReportStatisticsDto.EnterpriseOrderDto != null)
             {
@@ -2525,65 +2525,65 @@ namespace Hotline.Api.Controllers.Bi
                 centerReportStatisticsDto.EnterpriseOrderDto.CountySatisfied = centerReportStatisticsDto.EnterpriseOrderDto.CountySatisfied + Convert.ToInt32(listInfo.Rows[0]["EnterpriseCountySatisfaction"]);
             }
 
-			#endregion
-
-			#region 企业信件分类
-			//信件来源
-			var enterpriseAcceptTypeData = await _orderRepository.Queryable(false, false, false)
-				.Where(p => p.CreationTime >= StartTime && p.CreationTime <= EndTime && p.IdentityType == EIdentityType.Enterprise)
-				.Select(it => new
-				{
-					AcceptTypeCode = SqlFunc.IIF(SqlFunc.IsNullOrEmpty(it.AcceptTypeCode), "40", it.AcceptTypeCode),
-					FileOrgIsCenter = it.FileOrgIsCenter.HasValue ? it.FileOrgIsCenter : true,
-					CreationTimeHandleDurationWorkday = it.CreationTimeHandleDurationWorkday.HasValue ? it.CenterToOrgHandleDurationWorkday : 0,
-					CenterToOrgHandleDurationWorkday = it.CenterToOrgHandleDurationWorkday.HasValue ? it.CenterToOrgHandleDurationWorkday : 0,
-				})
-				.MergeTable()//将查询出来的结果合并成一个新表
-				 .GroupBy(temp => new { temp.AcceptTypeCode })//对新表进行分组
-				 .Select(temp => new CenterReportOrderSourceChannelDto
-				 {
-					 Code = temp.AcceptTypeCode,
-					 CountNum = SqlFunc.AggregateCount(temp.AcceptTypeCode),
-					 CompletedAging = SqlFunc.AggregateSum(SqlFunc.IIF(temp.FileOrgIsCenter == true, temp.CreationTimeHandleDurationWorkday, temp.CenterToOrgHandleDurationWorkday))
-				 })
-				 .ToListAsync();
-			List<CenterReportOrderSourceChannelDto> enterpriseAcceptType = new();
-			var enterpriseAcceptTypeDic = _sysDicDataCacheManager.GetSysDicDataCache(SysDicTypeConsts.AcceptType);
-			foreach (var item in enterpriseAcceptTypeDic)
-			{
-				enterpriseAcceptType.Add(new CenterReportOrderSourceChannelDto
-				{
-					AllCountNum = sourceChannelCount,
-					Name = item.DicDataName,
-					Code = item.DicTypeCode,
-					CountNum = enterpriseAcceptTypeData.Find(p => p.Code == item.DicDataValue)?.CountNum ?? 0,
-					CompletedAging = enterpriseAcceptTypeData.Find(p => p.Code == item.DicDataValue)?.CompletedAging ?? 0
-				});
-			}
-
-			if (listPurOld != null && listPurOld.Rows.Count > 0 && enterpriseAcceptType != null)
-			{
-				foreach (var item in enterpriseAcceptType)
-				{
-					if (item.Code == "10")
-						item.CountNum = item.CountNum + Convert.ToInt32(listPurOld.Rows[0]["Consult"]);            // 咨询
-					else if (item.Code == "15")
-						item.CountNum = item.CountNum + Convert.ToInt32(listPurOld.Rows[0]["Suggest"]);            // 建议
-					else if (item.Code == "20")
-						item.CountNum = item.CountNum + Convert.ToInt32(listPurOld.Rows[0]["SeekHelp"]);           // 求助
-					else if (item.Code == "25")
-						item.CountNum = item.CountNum + Convert.ToInt32(listPurOld.Rows[0]["Praise"]);             // 表扬
-					else if (item.Code == "30")
-						item.CountNum = item.CountNum + Convert.ToInt32(listPurOld.Rows[0]["Report"]);             // 举报
-					else if (item.Code == "35")
-						item.CountNum = item.CountNum + Convert.ToInt32(listPurOld.Rows[0]["Complaint"]);          // 投诉
-				}
-			}
-
-			centerReportStatisticsDto.EnterpriseCenterReportOrderAcceptTypes = enterpriseAcceptType;
-			#endregion
-
-			return centerReportStatisticsDto;
+            #endregion
+
+            #region 企业信件分类
+            //信件来源
+            var enterpriseAcceptTypeData = await _orderRepository.Queryable(false, false, false)
+                .Where(p => p.CreationTime >= StartTime && p.CreationTime <= EndTime && p.IdentityType == EIdentityType.Enterprise)
+                .Select(it => new
+                {
+                    AcceptTypeCode = SqlFunc.IIF(SqlFunc.IsNullOrEmpty(it.AcceptTypeCode), "40", it.AcceptTypeCode),
+                    FileOrgIsCenter = it.FileOrgIsCenter.HasValue ? it.FileOrgIsCenter : true,
+                    CreationTimeHandleDurationWorkday = it.CreationTimeHandleDurationWorkday.HasValue ? it.CenterToOrgHandleDurationWorkday : 0,
+                    CenterToOrgHandleDurationWorkday = it.CenterToOrgHandleDurationWorkday.HasValue ? it.CenterToOrgHandleDurationWorkday : 0,
+                })
+                .MergeTable()//将查询出来的结果合并成一个新表
+                 .GroupBy(temp => new { temp.AcceptTypeCode })//对新表进行分组
+                 .Select(temp => new CenterReportOrderSourceChannelDto
+                 {
+                     Code = temp.AcceptTypeCode,
+                     CountNum = SqlFunc.AggregateCount(temp.AcceptTypeCode),
+                     CompletedAging = SqlFunc.AggregateSum(SqlFunc.IIF(temp.FileOrgIsCenter == true, temp.CreationTimeHandleDurationWorkday, temp.CenterToOrgHandleDurationWorkday))
+                 })
+                 .ToListAsync();
+            List<CenterReportOrderSourceChannelDto> enterpriseAcceptType = new();
+            var enterpriseAcceptTypeDic = _sysDicDataCacheManager.GetSysDicDataCache(SysDicTypeConsts.AcceptType);
+            foreach (var item in enterpriseAcceptTypeDic)
+            {
+                enterpriseAcceptType.Add(new CenterReportOrderSourceChannelDto
+                {
+                    AllCountNum = sourceChannelCount,
+                    Name = item.DicDataName,
+                    Code = item.DicTypeCode,
+                    CountNum = enterpriseAcceptTypeData.Find(p => p.Code == item.DicDataValue)?.CountNum ?? 0,
+                    CompletedAging = enterpriseAcceptTypeData.Find(p => p.Code == item.DicDataValue)?.CompletedAging ?? 0
+                });
+            }
+
+            if (listPurOld != null && listPurOld.Rows.Count > 0 && enterpriseAcceptType != null)
+            {
+                foreach (var item in enterpriseAcceptType)
+                {
+                    if (item.Code == "10")
+                        item.CountNum = item.CountNum + Convert.ToInt32(listPurOld.Rows[0]["Consult"]);            // 咨询
+                    else if (item.Code == "15")
+                        item.CountNum = item.CountNum + Convert.ToInt32(listPurOld.Rows[0]["Suggest"]);            // 建议
+                    else if (item.Code == "20")
+                        item.CountNum = item.CountNum + Convert.ToInt32(listPurOld.Rows[0]["SeekHelp"]);           // 求助
+                    else if (item.Code == "25")
+                        item.CountNum = item.CountNum + Convert.ToInt32(listPurOld.Rows[0]["Praise"]);             // 表扬
+                    else if (item.Code == "30")
+                        item.CountNum = item.CountNum + Convert.ToInt32(listPurOld.Rows[0]["Report"]);             // 举报
+                    else if (item.Code == "35")
+                        item.CountNum = item.CountNum + Convert.ToInt32(listPurOld.Rows[0]["Complaint"]);          // 投诉
+                }
+            }
+
+            centerReportStatisticsDto.EnterpriseCenterReportOrderAcceptTypes = enterpriseAcceptType;
+            #endregion
+
+            return centerReportStatisticsDto;
         }
 
 
@@ -5597,16 +5597,16 @@ namespace Hotline.Api.Controllers.Bi
         public async Task<List<OrderTsDetails>> GetQueryOrderTsDetailslOrderList(string KeyWord)
         {
             return await _orderTsDetailsRepository.Queryable()
-                .LeftJoin<Order>((ot,o)=>ot.OrderId==o.Id)
+                .LeftJoin<Order>((ot, o) => ot.OrderId == o.Id)
                    .Where((ot, o) => ot.Terms == KeyWord)
-                   .Select((ot, o)=>new OrderTsDetails
+                   .Select((ot, o) => new OrderTsDetails
                    {
-                       Id=ot.Id,
-                       Terms=ot.Terms,
-                       OrderId=o.Id,
-                       Title=o.Title,
-                       No=ot.No
-                   } )
+                       Id = ot.Id,
+                       Terms = ot.Terms,
+                       OrderId = o.Id,
+                       Title = o.Title,
+                       No = ot.No
+                   })
                    .ToListAsync(HttpContext.RequestAborted);
         }
 
@@ -5662,21 +5662,21 @@ namespace Hotline.Api.Controllers.Bi
         /// <summary>
         /// 根据知识库引用查询工单
         /// </summary>
-        /// <param name="KeyWord"></param>
+        /// <param name="dto"></param>
         /// <returns></returns>
         [HttpGet("get_query_knowledge_quote_order_list")]
-        public async Task<List<KnowledgeQuote>> GetQueryKnowledgeQuoteOrderList(string KeyWord)
+        public async Task<List<KnowledgeQuote>> GetQueryKnowledgeQuoteOrderList([FromQuery] PagedKeywordRequest dto)
         {
             return await _knowledgeQuoteRepository.Queryable()
                    .LeftJoin<Order>((kn, o) => kn.OrderId == o.Id)
-                   .Where((kn, o) => kn.KnowledgeId == KeyWord)
-                   .Select((kn, o)=>new KnowledgeQuote
+                   .Where((kn, o) => kn.KnowledgeId == dto.Keyword && kn.CreationTime >= dto.StartTime && kn.CreationTime <= dto.EndTime)
+                   .Select((kn, o) => new KnowledgeQuote
                    {
-                       KnowledgeId=kn.Id,
-                       KnowledgeTitle=o.Title,
-                       OrderId=o.Id,
-                       Title=o.Title,
-                       No=o.No,
+                       KnowledgeId = kn.Id,
+                       KnowledgeTitle = o.Title,
+                       OrderId = o.Id,
+                       Title = o.Title,
+                       No = o.No,
                    })
                    .ToListAsync(HttpContext.RequestAborted);
         }

+ 9 - 5
src/Hotline.Api/Controllers/Bigscreen/DataScreenController.cs

@@ -15,6 +15,7 @@ using Microsoft.AspNetCore.Authorization;
 using Microsoft.AspNetCore.Mvc;
 using Microsoft.Extensions.Options;
 using SqlSugar;
+using System;
 using XF.Domain.Repository;
 
 namespace Hotline.Api.Controllers.Bigscreen
@@ -606,6 +607,7 @@ namespace Hotline.Api.Controllers.Bigscreen
         [HttpGet("order-secondary-statistics")]
         public async Task<SecondaryProcessingOrderStatisticsDto> OrderSecondaryStatistics(DateTime StartTime, DateTime EndTime)
         {
+            DateTime? dateTime = DateTime.Now;
             EndTime = EndTime.AddDays(1).AddSeconds(-1);
             var data = new SecondaryProcessingOrderStatisticsDto
             {
@@ -622,15 +624,17 @@ namespace Hotline.Api.Controllers.Bigscreen
 
                 OrderSoonOverdueCount = await _orderSecondaryHandlingRepository.Queryable()
                 .Includes(x => x.Order)
-                 .Where(x => x.Order.ExpiredStatus == EExpiredStatus.GoingToExpired && x.AuditTime >= StartTime && x.AuditTime <= EndTime
+                 .Where(x => x.Order.Status < EOrderStatus.Filed && dateTime > x.Order.NearlyExpiredTime && dateTime < x.Order.ExpiredTime)
+                 .Where(x => x.AuditTime >= StartTime && x.AuditTime <= EndTime
                  && x.State != ESecondaryHandlingState.NotApply
                  && x.State != ESecondaryHandlingState.Apply && x.State != ESecondaryHandlingState.Refuse)
                  .CountAsync()
             };
             var da = await _orderSecondaryHandlingRepository.Queryable()
-                .LeftJoin<OrderVisit>((os, ov) => os.VisitId == ov.Id)
-                    .LeftJoin<OrderVisitDetail>((os, ov, od) => os.VisitDetailId == od.Id)
-                    .Where((os, ov, od) => ov.VisitTime >= StartTime && ov.VisitTime <= EndTime && os.State != ESecondaryHandlingState.NotApply
+                .LeftJoin<OrderVisit>((os, ov) => os.OrderId == ov.OrderId)
+                    .LeftJoin<OrderVisitDetail>((os, ov, od) => ov.Id == od.VisitId)
+                    .Where((os, ov, od) => ov.VisitState == EVisitState.Visited && od.VisitTarget == EVisitTarget.Org && ov.VisitTime >= StartTime && ov.VisitTime <= EndTime
+                    && os.State != ESecondaryHandlingState.NotApply
                     && os.State != ESecondaryHandlingState.Apply && os.State != ESecondaryHandlingState.Refuse)
                     .Select((os, ov, od) => new SecondarySatisfactionDto()
                     {
@@ -652,7 +656,7 @@ namespace Hotline.Api.Controllers.Bigscreen
         public async Task<List<OrderSecondaryHandlingDto>> OrderSecondaryHandlingDetailQuery()
         {
             var quer = await _orderSecondaryHandlingRepository.Queryable()
-                 .Includes(x=>x.Order)
+                 .Includes(x => x.Order)
                   .Where(x => x.CreationTime.Date == DateTime.Now.Date)
                   .OrderByDescending(x => x.CreationTime)
                   .Take(50)

+ 1 - 0
src/Hotline.Api/Controllers/PlanController.cs

@@ -29,6 +29,7 @@ namespace Hotline.Api.Controllers
     public class PlanController : BaseController
     {
 
+
         #region 注入
 
         private readonly IMapper _mapper;

+ 56 - 0
src/Hotline.Api/Controllers/Snapshot/InviteCodeController.cs

@@ -0,0 +1,56 @@
+using Hotline.Application.Snapshot;
+using Hotline.Repository.SqlSugar.Extensions;
+using Hotline.Share.Dtos;
+using Hotline.Share.Dtos.Snapshot;
+using Hotline.Share.Tools;
+using Hotline.Snapshot;
+using Hotline.Snapshot.Interfaces;
+using Microsoft.AspNetCore.Mvc;
+using System.ComponentModel;
+
+namespace Hotline.Api.Controllers.Snapshot;
+
+/// <summary>
+/// 邀请码管理
+/// </summary>
+[Description("邀请码管理")]
+public class InviteCodeController : BaseController
+{
+    private readonly IInviteCodeApplication _inviteCodeApplication;
+
+    public InviteCodeController(IInviteCodeApplication inviteCodeApplication)
+    {
+        _inviteCodeApplication = inviteCodeApplication;
+    }
+
+    /// <summary>
+    /// 获取添加邀请码基础数据
+    /// </summary>
+    /// <returns></returns>
+    [HttpGet("basedata")]
+    public async Task<Dictionary<string, object>> GetBasedataAsync()
+    {
+        return new Dictionary<string, object>
+        {
+            { "OrgName", await _inviteCodeApplication.GetInviteCodeItemsAsync().Where(m => m.ParentOrgId == null)
+            .Select(m => new Kv{ Key = m.Id, Value = m.OrgName}).ToListAsync() }
+        };
+    }
+
+    /// <summary>
+    /// 获取邀请码集合
+    /// </summary>
+    /// <returns></returns>
+    [HttpGet]
+    public async Task<PagedDto<InviteCode>> GetInviteCodeItemsAsync([FromQuery] GetInviteCodeItemsInDto dto)
+        => (await _inviteCodeApplication.GetInviteCodeItemsAsync().ToPagedListAsync(dto)).ToPaged();
+
+    /// <summary>
+    /// 添加部门邀请码
+    /// </summary>
+    /// <param name="dto"></param>
+    /// <returns></returns>
+    [HttpPost]
+    public async Task AddInviteCodeAsync([FromBody] AddInviteCodeInDto dto)
+        => await _inviteCodeApplication.AddInviteCodeAsync(dto);
+}

+ 17 - 0
src/Hotline.Api/Controllers/Snapshot/RedPackController.cs

@@ -188,6 +188,23 @@ public class RedPackController : BaseController
     public async Task<PagedDto<SnapshotRedPackRecordItemsGuiderOutDto>> GetRedPackRecordGuiderItemsAsync([FromQuery] SnapshotRedPackRecordItemsGuiderInDto dto)
         => (await _redPackApplication.GetRedPackRecordGuiderItemsAsync(dto).ToPagedListAsync(dto)).ToPaged();
 
+    /// <summary>
+    /// 红包发放明细基础数据
+    /// </summary>
+    /// <returns></returns>
+    [HttpGet("record/send/database")]
+    public async Task<Dictionary<string, object>> GetRedPackRecordSendBaseDataAsync()
+    {
+        return new Dictionary<string, object>()
+        {
+            { "industry", await _industryRepository.Queryable()
+            .Select(m => new { m.Id, m.Name })
+            .ToListAsync()},
+            { "sendStatus", EnumExts.GetDescriptions<EReadPackSendStatus>().Where(m => m.Key != 2).ToList() },
+            { "userType", EnumExts.GetDescriptions<EReadPackUserType>() }
+        };
+    }
+
     /// <summary>
     /// 红包发放明细
     /// </summary>

+ 43 - 0
src/Hotline.Application.Tests/Application/InviteCodeApplicationTest.cs

@@ -0,0 +1,43 @@
+using Hotline.Api.Controllers;
+using Hotline.Application.Snapshot;
+using Hotline.Identity.Accounts;
+using Hotline.Identity.Roles;
+using Hotline.Share.Dtos.Snapshot;
+using Hotline.Snapshot.Interfaces;
+using Hotline.Users;
+using Microsoft.AspNetCore.Http;
+using Microsoft.Extensions.DependencyInjection;
+using Shouldly;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using XF.Domain.Repository;
+
+namespace Hotline.Application.Tests.Application;
+public class InviteCodeApplicationTest : TestBase
+{
+    private readonly IInviteCodeApplication _inviteCodeApplication;
+
+    public InviteCodeApplicationTest(IAccountRepository accountRepository, IRepository<Role> roleRepository, UserController userController, IServiceScopeFactory scopeFactory, IRepository<User> userRepository, IHttpContextAccessor httpContextAccessor, IThirdIdentiyService thirdIdentiyService, IThirdAccountRepository thirdAccountRepository, IInviteCodeApplication inviteCodeApplication) : base(accountRepository, roleRepository, userController, scopeFactory, userRepository, httpContextAccessor, thirdIdentiyService, thirdAccountRepository)
+    {
+        _inviteCodeApplication = inviteCodeApplication;
+    }
+
+    [Fact]
+    public async Task InviteCode_Test()
+    {
+        var inDto = new AddInviteCodeInDto
+        {
+            OrgName = "测试部门",
+            BeginCode = 1000,
+            EndCode = 2000,
+        };
+
+        await _inviteCodeApplication.AddInviteCodeAsync(inDto);
+
+        var items = _inviteCodeApplication.GetInviteCodeItemsAsync().ToList();
+        items.Count.ShouldNotBe(0);
+    }
+}

+ 13 - 0
src/Hotline.Application.Tests/Application/RedPackApplicationTest.cs

@@ -60,5 +60,18 @@ public class RedPackApplicationTest : TestBase
         record.ShouldNotBeNull();
         var recordItems = await _redPackApplication.GetRedPackRecordItemsAsync(new SnapshotRedPackRecordItemsInDto { Status =2}).ToListAsync();
         recordItems.Count.ShouldNotBe(0);
+
+        var redPackRecord = recordItems.First();
+        var redPackRecordEntity = await _redPackRecordRepository.GetAsync(redPackRecord.Id);
+        redPackRecordEntity.PickupStatus = ERedPackPickupStatus.Received;
+        redPackRecordEntity.DistributionState = EReadPackSendStatus.Successful;
+        redPackRecordEntity.ReceiveTime = DateTime.Now;
+        await _redPackRecordRepository.UpdateAsync(redPackRecordEntity);
+
+        var sendRecordItems = await _redPackApplication.GetRedPackRecordDetailAsync(new SnapshotRedPackRecordSendInDto
+        {
+            IsReceive = true,
+        }).ToListAsync();
+        sendRecordItems.Count.ShouldNotBe(0);
     }
 }

+ 2 - 1
src/Hotline.Application.Tests/appsettings.Development.json

@@ -68,7 +68,8 @@
         }
     },
     "ConnectionStrings": {
-        "Hotline": "PORT=5432;DATABASE=hotline_dev;HOST=110.188.24.182;PASSWORD=fengwo11!!;USER ID=dev;",
+         "Hotline": "PORT=5432;DATABASE=hotline_dev;HOST=110.188.24.182;PASSWORD=fengwo11!!;USER ID=dev;",
+        //"Hotline": "PORT=5432;DATABASE=hotline;HOST=110.188.24.182;PASSWORD=fengwo11!!;USER ID=dev;",
         "CAP": "PORT=5432;DATABASE=fwmq;HOST=110.188.24.182;PASSWORD=fengwo11!!;USER ID=dev;Search Path=cap"
         //"Hotline": "PORT=5432;DATABASE=hotline;HOST=110.188.24.182;PASSWORD=fengwo11!!;USER ID=dev;"
     },

+ 1 - 1
src/Hotline.Application/Orders/OrderApplication.cs

@@ -3250,7 +3250,7 @@ public class OrderApplication : IOrderApplication, IScopeDependency
         query = query.WhereIF(dto.VisitStateQuery == EVisitStateQuery.Visited, d => d.VisitState == EVisitState.Visited)
             .WhereIF(dto.VisitStateQuery == EVisitStateQuery.SMSUnsatisfied, d => d.VisitState == EVisitState.SMSUnsatisfied)
             .WhereIF(dto.VisitStateQuery == EVisitStateQuery.SMSVisiting, d => d.VisitState == EVisitState.SMSVisiting)
-            .WhereIF(dto.VisitStateQuery == EVisitStateQuery.NoPutThrough, d => d.IsPutThrough == false && d.VisitState != EVisitState.Visited)
+            .WhereIF(dto.VisitStateQuery == EVisitStateQuery.NoPutThrough, d => d.IsPutThrough == false && d.VisitState != EVisitState.Visited && d.VisitState != EVisitState.None)
             .WhereIF(dto.VisitStateQuery == EVisitStateQuery.ChipVoiceVisiting, d => d.VisitState == EVisitState.AiVisiting)//任务 162:回访状态快捷查询条件
             .WhereIF(!string.IsNullOrEmpty(dto.Keyword), d => d.Order.Title.Contains(dto.Keyword!))
             .WhereIF(!string.IsNullOrEmpty(dto.No), d => d.No == dto.No)

+ 15 - 0
src/Hotline.Application/Snapshot/IInviteCodeApplication.cs

@@ -0,0 +1,15 @@
+using Hotline.Share.Dtos.Snapshot;
+using Hotline.Snapshot;
+using SqlSugar;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Hotline.Application.Snapshot;
+public interface IInviteCodeApplication
+{
+    Task AddInviteCodeAsync(AddInviteCodeInDto dto);
+    ISugarQueryable<InviteCode> GetInviteCodeItemsAsync();
+}

+ 42 - 0
src/Hotline.Application/Snapshot/InviteCodeApplication.cs

@@ -0,0 +1,42 @@
+using Hotline.Share.Dtos.Snapshot;
+using Hotline.Snapshot;
+using Hotline.Snapshot.Interfaces;
+using Mapster;
+using SqlSugar;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using XF.Domain.Dependency;
+using XF.Domain.Exceptions;
+
+namespace Hotline.Application.Snapshot;
+public class InviteCodeApplication : IInviteCodeApplication, IScopeDependency
+{
+    private readonly IInviteCodeRepository _inviteCodeRepository;
+
+    public InviteCodeApplication(IInviteCodeRepository inviteCodeRepository)
+    {
+        _inviteCodeRepository = inviteCodeRepository;
+    }
+
+    public async Task AddInviteCodeAsync(AddInviteCodeInDto dto)
+    {
+        if (_inviteCodeRepository.Queryable().Where(m => m.OrgName == dto.OrgName).Any())
+        {
+            throw UserFriendlyException.SameMessage("部门名称已存在");
+        }
+        var entity = dto.Adapt<InviteCode>();
+        if (dto.BeginCode >= dto.EndCode)
+        {
+            throw UserFriendlyException.SameMessage("开始邀请码不能大于结束邀请码");
+        }
+        await _inviteCodeRepository.AddAsync(entity);
+    }
+
+    public ISugarQueryable<InviteCode> GetInviteCodeItemsAsync()
+    {
+        return _inviteCodeRepository.Queryable();
+    }
+}

+ 22 - 1
src/Hotline.Application/Snapshot/RedPackApplication.cs

@@ -466,7 +466,28 @@ public class RedPackApplication : IRedPackApplication, IScopeDependency
 
     public ISugarQueryable<SnapshotRedPackRecordSendOutDto> GetRedPackRecordDetailAsync(SnapshotRedPackRecordSendInDto dto)
     {
-        throw new NotImplementedException();
+        var query = _redPackRecordRepository.Queryable()
+            .LeftJoin<OrderSnapshot>((m , snapshot) => m.OrderId == snapshot.Id)
+            .LeftJoin<Order>((m , snapshot, order) => m.OrderId == order.Id)
+            .Where(m => m.DistributionState != EReadPackSendStatus.Unsend)
+            .WhereIF(dto.Status == 1, m => m.PickupStatus == ERedPackPickupStatus.Received)
+            .WhereIF(dto.Status == 2, m => m.PickupStatus == ERedPackPickupStatus.Back)
+            .WhereIF(dto.Status == 3, m => m.DistributionState == EReadPackSendStatus.Fail)
+            .WhereIF(dto.Status == 4, m => m.PickupStatus == ERedPackPickupStatus.Unreceived)
+            .WhereIF(dto.IndustryId.NotNullOrEmpty(), (m, snapshot) => snapshot.IndustryId == dto.IndustryId)
+            .WhereIF(dto.No.NotNullOrEmpty(), order => order.No.Contains(dto.No))
+            .WhereIF(dto.UserType.HasValue, m => m.PeopleType == dto.UserType)
+            .WhereIF(dto.OpenId.NotNullOrEmpty(), m => m.WXOpenId == dto.OpenId)
+            .WhereIF(dto.SendStatus.HasValue, m => m.DistributionState == dto.SendStatus)
+            .WhereIF(dto.IsReceive.HasValue && dto.IsReceive == true, m => m.PickupStatus == ERedPackPickupStatus.Received)
+            .WhereIF(dto.IsReceive.HasValue && dto.IsReceive == false, m => m.PickupStatus == ERedPackPickupStatus.Unreceived)
+            .WhereIF(dto.BeginCreationTime.HasValue && dto.EndCreationTime.HasValue, m => m.CreationTime >= dto.BeginCreationTime && m.CreationTime <= dto.EndCreationTime)
+            .Select(m => new SnapshotRedPackRecordSendOutDto
+            { 
+                OrderId = m.OrderId,
+                UserType = m.PeopleType
+            }, true);
+        return query;
     }
 
 

+ 18 - 0
src/Hotline.Repository.SqlSugar/Snapshot/InviteCodeRepository.cs

@@ -0,0 +1,18 @@
+using Hotline.Snapshot.Interfaces;
+using Hotline.Snapshot;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using XF.Domain.Dependency;
+using SqlSugar;
+using Hotline.Repository.SqlSugar.DataPermissions;
+
+namespace Hotline.Repository.SqlSugar.Snapshot;
+public class InviteCodeRepository : BaseRepository<InviteCode>, IInviteCodeRepository, IScopeDependency
+{
+    public InviteCodeRepository(ISugarUnitOfWork<HotlineDbContext> uow, IDataPermissionFilterBuilder dataPermissionFilterBuilder) : base(uow, dataPermissionFilterBuilder)
+    {
+    }
+}

+ 1 - 1
src/Hotline.Share/Dtos/Bigscreen/BigscreenDto.cs

@@ -263,7 +263,7 @@ namespace Hotline.Share.Dtos.Bigscreen
 
         public string CalcSatisfiedRate()
         {
-            if (Count == 0 || NoSatisfiedCount == 0)
+            if (Count == 0)
             {
                 return "0.000%";
             }

+ 47 - 0
src/Hotline.Share/Dtos/Snapshot/InviteCodeDto.cs

@@ -0,0 +1,47 @@
+using Hotline.Share.Requests;
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Hotline.Share.Dtos.Snapshot;
+public class InviteCodeDto
+{
+}
+
+public record GetInviteCodeItemsInDto : PagedRequest;
+
+public class AddInviteCodeInDto
+{
+    /// <summary>
+    /// 邀请码开始
+    /// 邀请码开始 -> 结束 范围内的邀请码都有效
+    /// </summary>
+    [Required]
+    public int BeginCode { get; set; }
+
+    /// <summary>
+    /// 邀请码结束
+    /// 邀请码开始 -> 结束 范围内的邀请码都有效
+    /// </summary>
+    [Required]
+    public int EndCode { get; set; }
+
+    /// <summary>
+    /// 部门名称
+    /// </summary>
+    [Required]
+    public string OrgName { get; set; }
+
+    /// <summary>
+    /// 上级部门ID
+    /// </summary>
+    public string ParentOrgId { get; set; }
+
+    /// <summary>
+    /// 邀请码Url
+    /// </summary>
+    public string QRCodeUrl { get; set; }
+}

+ 91 - 1
src/Hotline.Share/Dtos/Snapshot/RedPackRecordDto.cs

@@ -13,7 +13,87 @@ internal class RedPackRecordDto
 }
 
 public class SnapshotRedPackRecordSendOutDto
-{ }
+{
+    /// <summary>
+    /// Id
+    /// </summary>
+    public string Id { get; set; }
+
+    /// <summary>
+    /// 工单Id
+    /// </summary>
+    public string OrderId { get; set; }
+
+    /// <summary>
+    /// No
+    /// </summary>
+    public string No { get; set; }
+
+    /// <summary>
+    /// 用户类型
+    /// </summary>
+    public EReadPackUserType UserType { get; set; }
+
+    /// <summary>
+    /// 用户类型
+    /// </summary>
+    public string UserTypeTxt => UserType.GetDescription();
+
+    /// <summary>
+    /// 行业
+    /// </summary>
+    public string IndustryName { get; set; }
+
+    /// <summary>
+    /// OpenId
+    /// </summary>
+    public string WXOpenId { get; set; }
+
+    /// <summary>
+    /// 商户订单号
+    /// </summary>
+    public string MerchantCode { get; set; }
+
+    /// <summary>
+    /// 金额
+    /// </summary>
+    public double Amount { get; set; }
+
+    /// <summary>
+    /// 发放时间
+    /// </summary>
+    public DateTime CreationTime { get; set; }
+
+    /// <summary>
+    /// 发放状态
+    /// </summary>
+    public EReadPackSendStatus DistributionState { get; set; }
+
+    /// <summary>
+    /// 发放状态
+    /// </summary>
+    public string DistributionStateTxt => DistributionState.GetDescription();
+
+    /// <summary>
+    /// 领取状态
+    /// </summary>
+    public ERedPackPickupStatus PickupStatus { get; set; }
+
+    /// <summary>
+    /// 领取状态
+    /// </summary>
+    public string PickupStatusTxt => PickupStatus.GetDescription();
+
+    /// <summary>
+    /// 领取操作时间
+    /// </summary>
+    public DateTime? ReceiveTime { get; set; }
+
+    /// <summary>
+    /// 备注
+    /// </summary>
+    public string? Remark { get; set; }
+}
 
 public record SnapshotRedPackRecordSendInDto : PagedRequest
 {
@@ -61,6 +141,16 @@ public record SnapshotRedPackRecordSendInDto : PagedRequest
     /// 是否补领
     /// </summary>
     public bool? IsReplace { get; set; }
+
+    /// <summary>
+    /// 发放时间开始
+    /// </summary>
+    public DateTime? BeginCreationTime { get; set; }
+
+    /// <summary>
+    /// 发放时间结束
+    /// </summary>
+    public DateTime? EndCreationTime { get; set; }
 }
 
 public record SnapshotRedPackRecordItemsGuiderInDto : SnapshotRedPackRecordItemsInDto

+ 13 - 0
src/Hotline/Snapshot/Interfaces/IInviteCodeRepository.cs

@@ -0,0 +1,13 @@
+using Microsoft.EntityFrameworkCore.Metadata;
+using SqlSugar;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using XF.Domain.Repository;
+
+namespace Hotline.Snapshot.Interfaces;
+public interface IInviteCodeRepository : IRepository<InviteCode>
+{
+}

+ 31 - 31
src/Hotline/Snapshot/InviteCode.cs

@@ -12,38 +12,38 @@ namespace Hotline.Snapshot;
 /// <summary>
 /// 邀请码
 /// </summary>
-//[Description("邀请码")]
-//public class InviteCode : CreationSoftDeleteEntity
-//{
-//    /// <summary>
-//    /// 邀请码开始
-//    /// 邀请码开始 -> 结束 范围内的邀请码都有效
-//    /// </summary>
-//    [SugarColumn(ColumnDescription = "邀请码开始")]
-//    public string BeginCode { get; set; }
+[Description("邀请码")]
+public class InviteCode : CreationSoftDeleteEntity
+{
+    /// <summary>
+    /// 邀请码开始
+    /// 邀请码开始 -> 结束 范围内的邀请码都有效
+    /// </summary>
+    [SugarColumn(ColumnDescription = "邀请码开始")]
+    public int BeginCode { get; set; }
 
-//    /// <summary>
-//    /// 邀请码结束
-//    /// 邀请码开始 -> 结束 范围内的邀请码都有效
-//    /// </summary>
-//    [SugarColumn(ColumnDescription = "邀请码结束")]
-//    public string EndCode { get; set; }
+    /// <summary>
+    /// 邀请码结束
+    /// 邀请码开始 -> 结束 范围内的邀请码都有效
+    /// </summary>
+    [SugarColumn(ColumnDescription = "邀请码结束")]
+    public int EndCode { get; set; }
 
-//    /// <summary>
-//    /// 部门名称
-//    /// </summary>
-//    [SugarColumn(ColumnDescription = "部门名称")]
-//    public string OrgName { get; set; }
+    /// <summary>
+    /// 部门名称
+    /// </summary>
+    [SugarColumn(ColumnDescription = "部门名称")]
+    public string OrgName { get; set; }
 
-//    /// <summary>
-//    /// 上级部门ID
-//    /// </summary>
-//    [SugarColumn(ColumnDescription = "上级部门ID")]
-//    public string ParentOrgId { get; set; }
+    /// <summary>
+    /// 上级部门ID
+    /// </summary>
+    [SugarColumn(ColumnDescription = "上级部门ID")]
+    public string ParentOrgId { get; set; }
 
-//    /// <summary>
-//    /// 邀请码Url
-//    /// </summary>
-//    [SugarColumn(ColumnDescription = "邀请码Url")]
-//    public string QRCodeUrl { get; set; }
-//}
+    /// <summary>
+    /// 邀请码Url
+    /// </summary>
+    [SugarColumn(ColumnDescription = "邀请码Url")]
+    public string QRCodeUrl { get; set; }
+}