59 Commit-ok e512aa1696 ... eeca2185bf

Szerző SHA1 Üzenet Dátum
  libin eeca2185bf Merge branch 'test' into lib/test 15 órája
  libin e533582b6c 通话记录修改 15 órája
  Dun.Jason d7ac4ab35f Merge branch 'test' of http://110.188.24.182:10023/Fengwo/hotline into test 1 napja
  Dun.Jason 7d8de80397 定时消息 1 napja
  qinchaoyue cc4453f532 Merge branch 'feature/snapshot' into test 1 napja
  qinchaoyue 7b12aea1c2 修复无法新增公告 1 napja
  qinchaoyue c54b936396 Merge branch 'feature/snapshot' into test 1 napja
  qinchaoyue 2dd0d32837 修复异常 1 napja
  qinchaoyue b5bc1b6cd2 Merge branch 'feature/snapshot' into test 1 napja
  qinchaoyue f92c55c953 如果前端没有选额外扣除积分原因就不额外扣除积分 1 napja
  qinchaoyue 7f53aa7a61 Merge branch 'feature/snapshot' into test 1 napja
  qinchaoyue 68ce149dd9 随手拍公告新增反惨 1 napja
  guqiang 3344780a2c Merge branch 'feature/exam' into test 1 napja
  guqiang 8240148912 调整考试选题试题数 1 napja
  qinchaoyue e40a36f0a1 Merge branch 'feature/snapshot' into test 1 napja
  qinchaoyue 633477aedc 公告新增反惨 1 napja
  qinchaoyue 91ce5faa81 Merge branch 'feature/snapshot' into test 1 napja
  qinchaoyue d011da7be2 修复异常 1 napja
  qinchaoyue 9f02da6afc Merge branch 'feature/snapshot' into test 1 napja
  qinchaoyue 4f41f43850 修复异常 1 napja
  guqiang 6a5f09a5b8 Merge branch 'feature/exam' into test 1 napja
  guqiang 797f28243c 调整培训记录接口 1 napja
  qinchaoyue 0ae1d4d102 解决合并冲突 1 napja
  qinchaoyue 8bb3172c39 修复积分排行榜 1 napja
  guqiang 15632d1d42 Merge branch 'feature/exam' into test 1 napja
  guqiang 664c67f7a2 调整课件类型验证 1 napja
  guqiang e67e2e4e80 Merge branch 'feature/exam' into test 1 napja
  guqiang 8d83d5ba1a 添加排序字段 1 napja
  guqiang d98fbeee99 Merge branch 'feature/exam' into test 1 napja
  guqiang c0dd95eb1c 取消必填验证 1 napja
  qinchaoyue fd6e6f8183 增加返回排行榜页面通知内容 1 napja
  tangjiang 2a6dde382a 修改知识库超期未更新查询 1 napja
  tangjiang e86b22d6b1 1 napja
  tangjiang fe6735270a 1 napja
  tangjiang a9ecfd1bfc 1 napja
  tangjiang b92f2f11db 修改知识库超期更新bug 1 napja
  tangjiang 4f09d1d0d0 修改12315拓展信息订单号长度 1 napja
  tangjiang 5784c86833 修改知识库超期未更新统计bug 1 napja
  Dun.Jason b8d86f3832 Merge branch 'test' of http://110.188.24.182:10023/Fengwo/hotline into test 3 napja
  Dun.Jason 2efbc7fb05 查询部门手机号 3 napja
  tangjiang 3d7ca686dc 修改兴唐白名单查询不抛异常 3 napja
  tangjiang e79fad5f18 是否开启白名单查询 3 napja
  tangjiang afb4b6a368 Merge branch 'test' of http://110.188.24.182:10023/Fengwo/hotline into test 3 napja
  tangjiang 78bdb2ab52 黑白名单操作记录新增排序 3 napja
  qinchaoyue c27ff088f9 Merge branch 'feature/snapshot' into test 3 napja
  qinchaoyue 0296df0717 非受理返回不增加积分 3 napja
  guqiang 6bb49c5d97 Merge branch 'feature/exam' into test 3 napja
  guqiang 26957836f0 调整题库编辑接口 3 napja
  guqiang 8cbe9eecc7 Merge branch 'feature/exam' into test 3 napja
  guqiang e9da1d04ce 调整题库修改接口 3 napja
  qinchaoyue 7121e70203 Merge branch 'feature/snapshot' into test 3 napja
  qinchaoyue 6b78a4bbbe 修复设置安全卫士 3 napja
  qinchaoyue a4283f95c9 Merge branch 'feature/snapshot' into test 3 napja
  qinchaoyue fce6aeab8b 修复异常 3 napja
  qinchaoyue a13a95fbf2 Merge branch 'feature/snapshot' into test 3 napja
  qinchaoyue 4ea4a84d45 返回市民Id 3 napja
  qinchaoyue f27f1d442c 设置安全卫士 3 napja
  qinchaoyue caece43095 Merge branch 'feature/snapshot' into test 3 napja
  qinchaoyue c1e79dd808 新增查询条件 3 napja
60 módosított fájl, 434 hozzáadás és 107 törlés
  1. 12 4
      src/Hotline.Api/Controllers/CallNativeContrroller.cs
  2. 3 3
      src/Hotline.Api/Controllers/CorsJobController.cs
  3. 4 2
      src/Hotline.Api/Controllers/HomeController.cs
  4. 2 2
      src/Hotline.Api/Controllers/IdentityController.cs
  5. 1 2
      src/Hotline.Api/Controllers/OrderController.cs
  6. 1 1
      src/Hotline.Api/Controllers/Snapshot/BiSnapshotController.cs
  7. 12 3
      src/Hotline.Api/Controllers/Snapshot/SnapshotBulletinController.cs
  8. 1 0
      src/Hotline.Api/Controllers/Snapshot/SnapshotController.cs
  9. 2 2
      src/Hotline.Api/config/appsettings.Development.json
  10. 1 6
      src/Hotline.Application/Exam/Service/ExamManages/ExtractRuleService.cs
  11. 12 5
      src/Hotline.Application/Exam/Service/Questions/QuestionService.cs
  12. 2 2
      src/Hotline.Application/Exam/Service/TestPapers/TestPaperService.cs
  13. 17 10
      src/Hotline.Application/Exam/Service/Trains/TrainRecordService.cs
  14. 2 2
      src/Hotline.Application/Identity/IIdentityAppService.cs
  15. 3 3
      src/Hotline.Application/Identity/IdentityAppService.cs
  16. 5 0
      src/Hotline.Application/Knowledge/KnowApplication.cs
  17. 1 0
      src/Hotline.Application/Snapshot/Contracts/ISnapshotApplication.cs
  18. 0 0
      src/Hotline.Application/Snapshot/DefaultSnapshotApplication.cs
  19. 2 1
      src/Hotline.Application/Snapshot/RedPackApplication.cs
  20. 42 1
      src/Hotline.Application/Snapshot/SnapshotApplicationBase.cs
  21. 6 9
      src/Hotline.Application/Snapshot/SnapshotBulletinApplication.cs
  22. 14 4
      src/Hotline.Application/Snapshot/SnapshotPointsApplication.cs
  23. 4 1
      src/Hotline.Application/Snapshot/SnapshotUserApplication.cs
  24. 1 1
      src/Hotline.Repository.SqlSugar/CallCenter/TrCallRecordRepository.cs
  25. 0 1
      src/Hotline.Repository.SqlSugar/Exam/Validators/Sourcewares/SourcewareCategoryValidator.cs
  26. 1 0
      src/Hotline.Share/Dtos/Knowledge/KnowedgeStatisticsDto.cs
  27. 5 1
      src/Hotline.Share/Dtos/Snapshot/NotifyDto.cs
  28. 64 0
      src/Hotline.Share/Dtos/Snapshot/PointsDto.cs
  29. 10 2
      src/Hotline.Share/Dtos/Snapshot/SnapshotBulletinDto.cs
  30. 10 0
      src/Hotline.Share/Dtos/Snapshot/SnapshotUserInfoDto.cs
  31. 6 0
      src/Hotline.Share/Dtos/Sourcewares/SourcewareCategoryDto.cs
  32. 1 1
      src/Hotline.Share/Dtos/Sourcewares/SourcewareDto.cs
  33. 1 1
      src/Hotline.Share/Dtos/TrCallCenter/TrTelDao.cs
  34. 28 0
      src/Hotline.Share/Enums/Snapshot/EBulletinShape.cs
  35. 6 0
      src/Hotline.Share/Enums/Snapshot/ENotificationType.cs
  36. 6 0
      src/Hotline.Share/Enums/Snapshot/EPointsSource.cs
  37. 5 0
      src/Hotline.Share/Tools/DataMaskExtensions.cs
  38. 5 0
      src/Hotline/Settings/SettingConstants.cs
  39. 2 1
      src/Hotline/Snapshot/Contracts/ISnapshotPointsDomainService.cs
  40. 7 0
      src/Hotline/Snapshot/Notification.cs
  41. 26 5
      src/Hotline/Snapshot/Services/SnapshotPointsDomainService.cs
  42. 4 3
      src/Hotline/Snapshot/SnapshotBulletin.cs
  43. 5 0
      src/Hotline/Snapshot/SnapshotPointsRecord.cs
  44. 0 1
      src/Hotline/Validators/Exams/ExamManages/UpdateRuleTagDtoValidator.cs
  45. 0 1
      src/Hotline/Validators/Exams/ExamManages/UpdateTagQuestionDtoValidator.cs
  46. 0 1
      src/Hotline/Validators/Exams/Questions/UpdateQuestionOptionsDtoValidator.cs
  47. 0 1
      src/Hotline/Validators/Exams/Questions/UpdateQuestionSourcewareDtoValidator.cs
  48. 0 1
      src/Hotline/Validators/Exams/Questions/UpdateQuestionTagDtoValidator.cs
  49. 0 2
      src/Hotline/Validators/Exams/Sourcewares/AddSourcewareDtoValidator.cs
  50. 0 1
      src/Hotline/Validators/Exams/Sourcewares/UpdateSourcewareDtoValidator.cs
  51. 0 2
      src/Hotline/Validators/Exams/TestPapers/UpdateTestPaperItemDtoValidator.cs
  52. 0 2
      src/Hotline/Validators/Exams/TestPapers/UpdateTestPaperRuleDtoValidator.cs
  53. 1 1
      src/Hotline/Validators/Order/AddOrderDtoValidator.cs
  54. 35 3
      test/Hotline.Tests/Application/OrderSnapshotApplicationTest.cs
  55. 40 5
      test/Hotline.Tests/Application/PointsRecordApplicationTest.cs
  56. 2 2
      test/Hotline.Tests/Application/SnapshotApplicationTest.cs
  57. 5 5
      test/Hotline.Tests/Application/SnapshotBulletionApplicationTest.cs
  58. 1 0
      test/Hotline.Tests/Application/SnapshotUserApplicationTest.cs
  59. 2 0
      test/Hotline.Tests/Mock/Interfaces/IOrderServiceStartWorkflow.cs
  60. 6 0
      test/Hotline.Tests/Mock/OrderServiceStartWorkflow.cs

+ 12 - 4
src/Hotline.Api/Controllers/CallNativeContrroller.cs

@@ -255,6 +255,7 @@ namespace Hotline.Api.Controllers
                 .WhereIF(!string.IsNullOrEmpty(dto.LogAction), p => p.LogAction == dto.LogAction)
                 .WhereIF(!string.IsNullOrEmpty(dto.UserName), p => p.CreatorName == dto.UserName)
                 .WhereIF(!string.IsNullOrEmpty(dto.PhoneNum), p => p.PhoneNum == dto.PhoneNum)
+                .OrderByDescending(p => p.CreationTime)
                 .ToPagedListAsync(dto, HttpContext.RequestAborted);
             return new PagedDto<WhiteBlackLog>(total, items);
         }
@@ -267,11 +268,18 @@ namespace Hotline.Api.Controllers
         [HttpGet("verify-white-list/{phone}")]
         public async Task<bool> VerifyWhiteList(string phone)
         {
-            var isEx = await _db.Queryable<XingtangWhitePhone>().Where(p => p.Phone == phone && p.ValidDateTime >= DateTime.Now).AnyAsync();
-            if (isEx)
-                return true;
-            else
+            try
+            {
+                var isEx = await _db.Queryable<XingtangWhitePhone>().Where(p => p.Phone == phone && p.ValidDateTime >= DateTime.Now).AnyAsync();
+                if (isEx)
+                    return true;
+                else
+                    return false;
+            }
+            catch (Exception)
+            {
                 return false;
+            }
         }
         #endregion
     }

+ 3 - 3
src/Hotline.Api/Controllers/CorsJobController.cs

@@ -36,7 +36,7 @@ namespace Hotline.Api.Controllers
         /// 0 30 09,14 * * ?
         /// </summary>
         /// <returns></returns>
-        [HttpGet("send-overtime-sms")]
+        [HttpPost("send-overtime-sms")]
         [AllowAnonymous]
         public async Task SendOverTimeSms()
         {
@@ -48,7 +48,7 @@ namespace Hotline.Api.Controllers
         /// 0 0/1 * * * ?
         /// </summary>
         /// <returns></returns>
-        [HttpGet("send-todaywaitnum")]
+        [HttpPost("send-todaywaitnum")]
         [AllowAnonymous]
         public async Task SendToDayWaitNum()
         {
@@ -68,7 +68,7 @@ namespace Hotline.Api.Controllers
         /// 0/5 * * * * ?
         /// </summary>
         /// <returns></returns>
-        [HttpGet("send-currentwaitnum")]
+        [HttpPost("send-currentwaitnum")]
         [AllowAnonymous]
         public async Task SendCurrentWaitNum()
         {

+ 4 - 2
src/Hotline.Api/Controllers/HomeController.cs

@@ -212,7 +212,7 @@ public class HomeController : BaseController
             OldHotlineOrderState = _systemSettingCacheManager.GetSetting(SettingConstants.OldHotlineOrderState).SettingValue[0],
             FileExt = _systemSettingCacheManager.GetSetting(SettingConstants.FileExt).SettingValue[0],
             NationalPlatformWordLimit = int.Parse(_systemSettingCacheManager.GetSetting(SettingConstants.NationalPlatformWordLimit).SettingValue[0]),
-            HandleOpinionWordLimit= int.Parse(_systemSettingCacheManager.GetSetting(SettingConstants.HandleOpinionWordLimit).SettingValue[0]),
+            HandleOpinionWordLimit = int.Parse(_systemSettingCacheManager.GetSetting(SettingConstants.HandleOpinionWordLimit).SettingValue[0]),
             CallInOpenType = int.Parse(_systemSettingCacheManager.GetSetting(SettingConstants.CallInOpenType).SettingValue[0]),
             Snapshot = _systemSettingCacheManager.Snapshot,
             IsTelRest = bool.Parse(_systemSettingCacheManager.GetSetting(SettingConstants.IsTelRest).SettingValue[0]),
@@ -224,7 +224,9 @@ public class HomeController : BaseController
             RecordDownLoadPrefix = _systemSettingCacheManager.GetSetting(SettingConstants.RecordDownLoadPrefix).SettingValue?.FirstOrDefault(),
             Luzhouhcp = bool.Parse(_systemSettingCacheManager.GetSetting(SettingConstants.LuZhouHaoChaPing).SettingValue[0]),
             LocationCenter = locationCenter,
-            IsEarly = bool.Parse(_systemSettingCacheManager.GetSetting(SettingConstants.IsEarly).SettingValue[0])
+            IsEarly = bool.Parse(_systemSettingCacheManager.GetSetting(SettingConstants.IsEarly).SettingValue[0]),
+            IsOpenWhiteList = bool.Parse(_systemSettingCacheManager.GetSetting(SettingConstants.IsOpenWhiteList).SettingValue[0])
+
         };
         return rsp;
     }

+ 2 - 2
src/Hotline.Api/Controllers/IdentityController.cs

@@ -119,7 +119,7 @@ jxrWXHbT1FB6DqkdOnBbQqS1Azqz5HxLlSyEK3F60e3SgB5iZsDZ
     [AllowAnonymous]
     [HttpPost("third/token")]
     public async Task<Dictionary<string, object>> GetThirdTokenAsync([FromBody] ThirdTokenInDto dto)
-        => await _identityAppService.GetThredTokenAsync(dto, HttpContext.RequestAborted);
+        => await _identityAppService.GetThirdTokenAsync(dto, HttpContext.RequestAborted);
 
 
     /// <summary>
@@ -130,7 +130,7 @@ jxrWXHbT1FB6DqkdOnBbQqS1Azqz5HxLlSyEK3F60e3SgB5iZsDZ
     [LogFilterAlpha("老系统微信用户登录")]
     [HttpPost("third/login")]
     public async Task<Dictionary<string, object>> GetThirdLoginAsync([FromBody] ThirdOpenIdInDto dto)
-            => await _identityAppService.GetThredTokenAsync(dto, HttpContext.RequestAborted);
+            => await _identityAppService.GetThirdTokenAsync(dto, HttpContext.RequestAborted);
 
     /// <summary>
     /// 根据OpenId刷新令牌

+ 1 - 2
src/Hotline.Api/Controllers/OrderController.cs

@@ -3719,8 +3719,7 @@ public class OrderController : BaseController
         var acceptSmsRoleIds = _systemSettingCacheManager.GetSetting(SettingConstants.AcceptSmsRoleIds)?.SettingValue;
         //查询部门所有账号
         var userlist = await _userRepository.Queryable().Where(x =>
-            x.OrgId == orgCode && !string.IsNullOrEmpty(x.PhoneNo) &&
-            x.Roles.Any(d => acceptSmsRoleIds.Contains(d.Id))).ToListAsync();
+            x.OrgId == orgCode && !string.IsNullOrEmpty(x.PhoneNo)).ToListAsync();
         if (userlist != null && userlist.Count > 0)
         {
             k.Key = userlist[0].Name;

+ 1 - 1
src/Hotline.Api/Controllers/Snapshot/BiSnapshotController.cs

@@ -334,6 +334,6 @@ public class BiSnapshotController : BaseController
     /// <param name="dto"></param>
     /// <returns></returns>
     [HttpGet("county_points")]
-    public async Task<IList<SnapshotCountyPointsStatisticsOutDto>> Get([FromQuery] SnapshotCountyPointsStatisticsInDto dto)
+    public async Task<IList<SnapshotCountyPointsStatisticsOutDto>> GetAreaPointsStatistics([FromQuery] SnapshotCountyPointsStatisticsInDto dto)
         => await _biSnapshotApplication.GetAreaPointsStatistics(dto).ToListAsync(HttpContext.RequestAborted);
 }

+ 12 - 3
src/Hotline.Api/Controllers/Snapshot/SnapshotBulletinController.cs

@@ -57,12 +57,21 @@ public class SnapshotBulletinController : BaseController
     {
         var model = await _bulletinRepository.Queryable()
             .Includes(x => x.ExaminMan)
-            .FirstAsync(x => x.Id == id, HttpContext.RequestAborted);
+            .FirstAsync(x => x.Id == id, HttpContext.RequestAborted)
+            ?? throw UserFriendlyException.SameMessage("公告不存在");
 
         if (model != null && !string.IsNullOrEmpty(model.Content))
             model.Content = _bulletinApplication.GetSiteUrls(model.Content);
 
-        return model.Adapt<SnapshotBulletinDetailOutDto>();
+        var outDto = model.Adapt<SnapshotBulletinDetailOutDto>();
+        if (outDto.SafetyTypeId.NotNullOrEmpty())
+        {
+            outDto.SafetyTypeNames = await _safetyTypeRepository.Queryable()
+                .Where(m => outDto.SafetyTypeId.Contains(m.Id))
+                .Select(m => m.Name)
+                .ToListAsync();
+        }
+        return outDto;
     }
 
     /// <summary>
@@ -180,7 +189,7 @@ public class SnapshotBulletinController : BaseController
     public async Task<object> BulletinAddBaseData()
     {
         var safetyTypes = await _safetyTypeRepository.Queryable()
-            .Select(m => new SystemDicDataOutDto { Id =  m.Id, DicDataName = m.Name , DicDataValue = m.Id})
+            .Select(m => new SystemDicDataOutDto { Id = m.Id, DicDataName = m.Name, DicDataValue = m.Id })
             .ToListAsync(HttpContext.RequestAborted);
         var rsp = new
         {

+ 1 - 0
src/Hotline.Api/Controllers/Snapshot/SnapshotController.cs

@@ -32,6 +32,7 @@ using XF.Domain.Authentications;
 using XF.Domain.Exceptions;
 using XF.Domain.Filters;
 using XF.Domain.Repository;
+using BulletinOutDto = Hotline.Share.Dtos.Article.BulletinOutDto;
 
 namespace Hotline.Api.Controllers.Snapshot;
 

+ 2 - 2
src/Hotline.Api/config/appsettings.Development.json

@@ -68,13 +68,13 @@
     }
   },
     "ConnectionStrings": {
-        "Hotline": "PORT=5432;DATABASE=hotline;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;"
     },
   "Cache": {
     "Host": "110.188.24.182",
     "Port": 50179,
     "Password": "fengwo123!$!$",
-    "Database": 3 //hl:3, dev:5, test:2, demo:4
+    "Database": 5 //hl:3, dev:5, test:2, demo:4
   },
   "Swagger": true,
   "AccLog":  false,

+ 1 - 6
src/Hotline.Application/Exam/Service/ExamManages/ExtractRuleService.cs

@@ -211,7 +211,6 @@ namespace Hotline.Application.Exam.Service.ExamManages
             var expression = tagQuestionRequest.GetExpression();
             var questionTagTable = new ExamRepository<ExamQuestionTag>(_uow, _dataPermissionFilterBuilder, _serviceProvider).Queryable().Where(expression);
             var questionTable = new ExamRepository<ExamQuestion>(_uow, _dataPermissionFilterBuilder, _serviceProvider).Queryable();
-
             var queryable = questionTagTable.LeftJoin(questionTable, (t, q) => t.QuestionId == q.Id)
                 .GroupBy((t, q) => new { t.TagId, q.QuestionType })
                 .OrderBy((t, q) => t.TagId)
@@ -219,11 +218,7 @@ namespace Hotline.Application.Exam.Service.ExamManages
                 {
                     TagId = t.TagId,
                     QuestionType = q.QuestionType,
-                    TotalCount = SqlFunc.AggregateCount(new
-                    {
-                        TagId = t.TagId,
-                        QuestionType = q.QuestionType,
-                    })
+                    TotalCount = SqlFunc.AggregateCount(q.Id!=null)
                 });
 
             return await queryable.ToListAsync();

+ 12 - 5
src/Hotline.Application/Exam/Service/Questions/QuestionService.cs

@@ -36,11 +36,6 @@ using Hotline.Exams.ExamManages;
 using Hotline.Exams.Questions;
 using Hotline.Repository.SqlSugar.Exam.Repositories;
 using Hotline.Share.Dtos.TestPapers;
-using ExamQuestion = Hotline.Exams.Questions.ExamQuestion;
-using ExamQuestionAnswer = Hotline.Exams.Questions.ExamQuestionAnswer;
-using ExamQuestionKnowladge = Hotline.Exams.Questions.ExamQuestionKnowladge;
-using ExamQuestionOptions = Hotline.Exams.Questions.ExamQuestionOptions;
-using ExamQuestionSourceware = Hotline.Exams.Questions.ExamQuestionSourceware;
 using Hotline.Repository.SqlSugar.Exam.Service;
 using Hotline.Repository.SqlSugar.Exam.Extensions;
 
@@ -753,6 +748,10 @@ namespace Hotline.Application.Exam.Service.Questions
 
             actionRequest.QuestionSourcewareDtos.ResolveOperationStatus(all);
 
+            _addQuestionDto.QuestionSourcewareDtos = _mapper.Map<List<UpdateQuestionSourcewareDto>, List<AddQuestionSourcewareDto>>(actionRequest.QuestionSourcewareDtos);
+
+            _addQuestionDto.QuestionSourcewareDtos.ResolveOperationStatus();
+
             questionSourcewares.AddRangeExt(await AddSourcewares(_addQuestionDto, cancellationToken));
 
             questionSourcewares.AddRangeExt(await UpdateSourcewares(actionRequest, all, cancellationToken));
@@ -776,6 +775,10 @@ namespace Hotline.Application.Exam.Service.Questions
 
             actionRequest.QuestionKnowladgeDtos.ResolveOperationStatus(all);
 
+            _addQuestionDto.QuestionKnowladgeDtos = _mapper.Map<List<UpdateQuestionKnowladgeDto>, List<AddQuestionKnowladgeDto>>(actionRequest.QuestionKnowladgeDtos);
+
+            _addQuestionDto.QuestionKnowladgeDtos.ResolveOperationStatus();
+
             questionKnowladges.AddRangeExt(await AddKnowladges(_addQuestionDto, cancellationToken));
 
             questionKnowladges.AddRangeExt(await UpdateKnowladges(actionRequest, all, cancellationToken));
@@ -860,6 +863,8 @@ namespace Hotline.Application.Exam.Service.Questions
 
             actionRequest.QuestionOptionsDtos.ResolveOperationStatus(all);
 
+            _addQuestionDto.QuestionOptionsDtos = _mapper.Map<List<UpdateQuestionOptionsDto>, List<AddQuestionOptionsDto>>(actionRequest.QuestionOptionsDtos);
+
             _addQuestionDto.QuestionOptionsDtos.ResolveOperationStatus();
 
             questionOptions.AddRangeExt(await AddQuestionOptions(_addQuestionDto, cancellationToken));
@@ -885,6 +890,8 @@ namespace Hotline.Application.Exam.Service.Questions
 
             actionRequest.QuestionTagDtos.ResolveOperationStatus(all);
 
+            _addQuestionDto.QuestionTagDtos = _mapper.Map<List<UpdateQuestionTagDto>, List<AddQuestionTagDto>>(actionRequest.QuestionTagDtos);
+
             questionTags.AddRangeExt(await AddQuestionTags(_addQuestionDto, cancellationToken));
 
             questionTags.AddRangeExt(await UpdateQuestionTags(actionRequest, all, cancellationToken));

+ 2 - 2
src/Hotline.Application/Exam/Service/TestPapers/TestPaperService.cs

@@ -394,10 +394,10 @@ namespace Hotline.Application.Exam.Service.TestPapers
             var tagQuestionTable = tagQuestionRepository.Queryable().Where(expression);
             var questionTable = quesitonRepository.Queryable().Where(questionExpression);
 
-            var taqQuestions = await tagQuestionTable.LeftJoin(questionTable, (t, q) => t.QuestionId == q.Id)
+            var taqQuestions = await tagQuestionTable.InnerJoin(questionTable, (t, q) => t.QuestionId == q.Id)
                 .Select((t, q) => new TagQuestionCountViewResponse
                 {
-                    TotalCount = SqlFunc.AggregateCount(t.Id)
+                    TotalCount = SqlFunc.AggregateCount(q.Id!=null)
                 })
                 .ToListAsync();
 

+ 17 - 10
src/Hotline.Application/Exam/Service/Trains/TrainRecordService.cs

@@ -296,6 +296,18 @@ namespace Hotline.Application.Exam.Service.Trains
         }
 
         private SqlSugar.ISugarQueryable<SimpleQuestionDto> QueryQuestions(EntityQueryRequest entityQueryRequest)
+        {
+            SqlSugar.ISugarQueryable<ExamTrainRecord, ExamTrainPlan, ExamTrainPlanTemplate, ExamTrainPractice> queryable = QuestionQueryable(entityQueryRequest);
+
+            var result = queryable.Select((r, p, tpt, tp) => new SimpleQuestionDto
+            {
+                Title = tp.Title,
+                Id = tp.Id
+            });
+            return result;
+        }
+
+        private SqlSugar.ISugarQueryable<ExamTrainRecord, ExamTrainPlan, ExamTrainPlanTemplate, ExamTrainPractice> QuestionQueryable(EntityQueryRequest entityQueryRequest)
         {
             var trainPlanRepository = new ExamRepository<ExamTrainPlan>(_uow, _dataPermissionFilterBuilder, _serviceProvider);
             var trainPracticeRepository = new ExamRepository<ExamTrainPractice>(_uow, _dataPermissionFilterBuilder, _serviceProvider);
@@ -308,26 +320,21 @@ namespace Hotline.Application.Exam.Service.Trains
 
             var queryable = trainRecordTable.InnerJoin(trainPlanTable, (r, p) => r.TrainPlanId == p.Id)
                 .InnerJoin(trainPlanTemplateTable, (r, p, tpt) => p.Id == tpt.TrainPlanId)
-                .InnerJoin(trainPracticeTable, (r, p, tpt, tp) => tpt.Id == tp.TrainTemplateId)
-                .Select((r, p, tpt, tp) => new SimpleQuestionDto
-                {
-                    Title = tp.Title,
-                    Id = tp.Id
-                });
+                .InnerJoin(trainPracticeTable, (r, p, tpt, tp) => tpt.TrainTemplateId == tp.TrainTemplateId);
             return queryable;
         }
 
         private async Task<List<SimpleKnowladgeDto>> GetKnowladges(EntityQueryRequest entityQueryRequest)
         {
-            var questionTable = QueryQuestions(entityQueryRequest);
+            var questionTable = QuestionQueryable(entityQueryRequest);
             var questionSourcewareRepository = new ExamRepository<ExamPracticeQuestionSourceware>(_uow, _dataPermissionFilterBuilder, _serviceProvider);
             var sourcewareRepository = new ExamRepository<KnowledgeBase.Knowledge>(_uow, _dataPermissionFilterBuilder, _serviceProvider);
             var questionSourcewareTable = questionSourcewareRepository.Queryable();
             var sourcewareTable = sourcewareRepository.Queryable();
 
-            var queryable = questionTable.InnerJoin(questionSourcewareTable, (r, p) => r.Id == p.QuestionId)
-                .InnerJoin(sourcewareTable, (r, p, sw) => p.SourcewareId == sw.Id)
-                .Select((r, p, sw) => new SimpleKnowladgeDto
+            var queryable = questionTable.InnerJoin(questionSourcewareTable, (r, p, tpt, tp, ExamPracticeQuestionSourceware) => r.Id == ExamPracticeQuestionSourceware.QuestionId)
+                .InnerJoin(sourcewareTable, (r, p, tpt, tp, ExamPracticeQuestionSourceware,sw) => ExamPracticeQuestionSourceware.SourcewareId == sw.Id)
+                .Select((r, p, tpt, tp, ExamPracticeQuestionSourceware, sw) => new SimpleKnowladgeDto
                 {
                     Title = sw.Title,
                     Id = sw.Id

+ 2 - 2
src/Hotline.Application/Identity/IIdentityAppService.cs

@@ -20,7 +20,7 @@ namespace Hotline.Application.Identity
         /// <param name="dto"></param>
         /// <returns></returns>
         /// <exception cref="UserFriendlyException"></exception>
-        Task<Dictionary<string, object>> GetThredTokenAsync(ThirdTokenInDto dto, CancellationToken token);
+        Task<Dictionary<string, object>> GetThirdTokenAsync(ThirdTokenInDto dto, CancellationToken token);
 
         /// <summary>
         /// 第三方登录
@@ -28,7 +28,7 @@ namespace Hotline.Application.Identity
         /// <param name="dto"></param>
         /// <param name="token"></param>
         /// <returns></returns>
-        Task<Dictionary<string, object>> GetThredTokenAsync(ThirdOpenIdInDto dto, CancellationToken token);
+        Task<Dictionary<string, object>> GetThirdTokenAsync(ThirdOpenIdInDto dto, CancellationToken token);
 
         /// <summary>
         /// 根据OpenId刷新令牌

+ 3 - 3
src/Hotline.Application/Identity/IdentityAppService.cs

@@ -330,7 +330,7 @@ public class IdentityAppService : IIdentityAppService, IScopeDependency
     /// <param name="dto"></param>
     /// <returns></returns>
     /// <exception cref="UserFriendlyException"></exception>
-    public async Task<Dictionary<string, object>> GetThredTokenAsync(ThirdTokenInDto dto, CancellationToken token)
+    public async Task<Dictionary<string, object>> GetThirdTokenAsync(ThirdTokenInDto dto, CancellationToken token)
     {
         var thirdDto = dto.Adapt<ThirdTokenDto>();
         thirdDto = await _thirdAccountDomainFactory.GetThirdParameterAsync(thirdDto, token);
@@ -345,10 +345,10 @@ public class IdentityAppService : IIdentityAppService, IScopeDependency
             ThirdType = dto.ThirdType,
             PhoneNumber = phone.PhoneNumber
         };
-        return await GetThredTokenAsync(inDto, token);
+        return await GetThirdTokenAsync(inDto, token);
     }
 
-    public async Task<Dictionary<string, object>> GetThredTokenAsync(ThirdOpenIdInDto dto, CancellationToken token)
+    public async Task<Dictionary<string, object>> GetThirdTokenAsync(ThirdOpenIdInDto dto, CancellationToken token)
     {
         var thirdAccount = await _thirdAccountRepository.GetByOpenIdAsync(dto.OpenId, token);
 

+ 5 - 0
src/Hotline.Application/Knowledge/KnowApplication.cs

@@ -523,11 +523,16 @@ namespace Hotline.Application.Knowledge
                     .WhereIF(dto.StartTime.HasValue, p => p.LastModificationTime >= dto.StartTime)
                     .WhereIF(dto.EndTime.HasValue, p => p.LastModificationTime <= dto.EndTime)
                     .WhereIF(!string.IsNullOrEmpty(dto.Keyword), p => p.SourceOrganize.Name.Contains(dto.Keyword))
+                  //  .GroupBy(p => new { p.SourceOrganize.Name, p.LastModificationTime })
                     .Select(p => new KnowedgeStatisticsDto
                     {
+                       // Index = SqlFunc.RowNumber($"{p.LastModificationTime} desc "),\
+                       Index= SqlFunc.RowNumber($"{p.LastModificationTime} desc ", $"{p.SourceOrganize.Name}"),
                         LastModificationTime = p.LastModificationTime,
                         OrgName = p.SourceOrganize.Name
                     })
+                    .MergeTable()
+                    .Where(p => p.Index == 1)
                     .OrderByDescending(p => p.LastModificationTime);
         }
     }

+ 1 - 0
src/Hotline.Application/Snapshot/Contracts/ISnapshotApplication.cs

@@ -2,6 +2,7 @@
 using Hotline.Share.Dtos.Article;
 using Hotline.Share.Dtos.Snapshot;
 using Hotline.Snapshot;
+using BulletinOutDto = Hotline.Share.Dtos.Article.BulletinOutDto;
 
 namespace Hotline.Application.Snapshot.Contracts;
 public interface ISnapshotApplication

A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 0 - 0
src/Hotline.Application/Snapshot/DefaultSnapshotApplication.cs


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

@@ -148,7 +148,8 @@ public class RedPackApplication : IRedPackApplication, IScopeDependency
             await _redPackRecordRepository.AddAsync(entity);
         }
         await _redPackAuditRepository.UpdateAsync(redPackAudit, token);
-        await _snapshotPointsDomainService.AddPointsAsync(order.Id, EPointsSource.Audit, dto.PointsStatus, dto.ExtraDeductedPoints);
+        await _snapshotPointsDomainService
+            .AddPointsAsync(order.Id, EPointsSource.Audit, dto.PointsStatus, dto.ExtraDeductedPoints, dto.ExtraDeductionPointsTypeName);
         if (dto.IsSendSms)
         {
             var smsTemplate = await _snapshotSMSTemplateRepository.GetAsync(dto.SMSTemplateId);

+ 42 - 1
src/Hotline.Application/Snapshot/SnapshotApplicationBase.cs

@@ -41,6 +41,7 @@ using Hotline.Settings.Hotspots;
 using Microsoft.Extensions.Options;
 using XF.Utility.MQ;
 using System.Threading;
+using BulletinOutDto = Hotline.Share.Dtos.Article.BulletinOutDto;
 using NPOI.SS.Formula.Functions;
 
 namespace Hotline.Application.Snapshot;
@@ -398,7 +399,7 @@ public abstract class SnapshotApplicationBase
     {
         var items = await _notificationReceiverRepository.Queryable()
             .LeftJoin<Notification>((m , notify) => m.NotificationId == notify.Id)
-            .Where(m => m.ReceiverId == _sessionContext.UserId)
+            .Where((m, notify) => m.ReceiverId == _sessionContext.UserId && dto.NotifyType == notify.NotifyType)
             .Select((m, notify) => new GetNotifyOutDto 
             {
                 NotificationId = m.NotificationId,
@@ -1058,6 +1059,46 @@ public abstract class SnapshotApplicationBase
             item.Insert(0, my);
         }
         outDto.Ranks = item;
+
+
+        outDto.VideoBulletin = await _notificationReceiverRepository.Queryable()
+            .LeftJoin<Notification>((receiver, notify) => notify.Id == receiver.NotificationId)
+            .LeftJoin<SnapshotBulletin>((receiver, notify, bulletin) => bulletin.Id == notify.ExternalId)
+            .Where((receiver, notify) => receiver.ReceiverId == _sessionContext.UserId)
+            .GroupBy((receiver, notify, bulletin) => new 
+            {
+                notify.Title,
+                notify.ExternalId,
+                bulletin.SnapshotBulletinTypeName,
+                bulletin.VideoCoverImgUrl,
+                notify.CreationTime
+            })
+            .OrderByDescending((receiver, notify) => notify.CreationTime)
+            .Select((receiver, notify, bulletin) => new VideoBulletinOutDto
+            {
+                Title = notify.Title,
+                BulletinId = notify.ExternalId,
+                UnReadCount = SqlFunc.AggregateSum(SqlFunc.IIF( receiver.IsRead == false, 1, 0)),
+                SnapshotBulletinTypeName = bulletin.SnapshotBulletinTypeName,
+                VideoCoverImgUrl = bulletin.VideoCoverImgUrl,
+            }).FirstAsync();
+
+        outDto.Bulletins = new PointsBulletinOutDto
+        {
+            Items = await _notificationReceiverRepository.Queryable()
+                .LeftJoin<Notification>((receiver, notify) => notify.Id == receiver.NotificationId)
+                .Select((receiver, notify) => new PointsBulletinItemsOutDto
+                {
+                    BulletinId = notify.ExternalId,
+                    Title = notify.Title,
+                }, true)
+                .Take(2)
+                .ToListAsync(),
+            UnReadCount = await _notificationReceiverRepository.Queryable()
+            .Where(m => m.IsRead == false && m.ReceiverId == _sessionContext.UserId)
+            .CountAsync()
+        };
+
         return outDto;
     }
     #endregion

+ 6 - 9
src/Hotline.Application/Snapshot/SnapshotBulletinApplication.cs

@@ -1,5 +1,4 @@
-using DocumentFormat.OpenXml.Vml.Office;
-using DotNetCore.CAP;
+using DotNetCore.CAP;
 using Hotline.Application.Snapshot.Contracts;
 using Hotline.Caching.Interfaces;
 using Hotline.Orders;
@@ -14,14 +13,9 @@ using Hotline.Snapshot;
 using Hotline.Snapshot.Contracts;
 using Hotline.Snapshot.IRepository;
 using Mapster;
-using Microsoft.AspNetCore.Http;
 using SqlSugar;
-using System;
-using System.Collections.Generic;
-using System.Linq;
 using System.Text;
 using System.Text.RegularExpressions;
-using System.Threading.Tasks;
 using XF.Domain.Authentications;
 using XF.Domain.Dependency;
 using XF.Domain.Exceptions;
@@ -85,7 +79,7 @@ public class SnapshotBulletinApplication : ISnapshotBulletinApplication, IScopeD
         await _bulletinRepository.GetAsync(bullutionId, token)
             .Then(async bulletion =>
             {
-                if (bulletion!.IsSnapshot == false) return;
+                if (bulletion!.SnapshotBulletinTypeId != "aqws") return;
                 if (bulletion!.SafetyTypeId!.IsNullOrEmpty()) return;
                 foreach (var safetyTypeId in bulletion!.SafetyTypeId!)
                 {
@@ -99,10 +93,11 @@ public class SnapshotBulletinApplication : ISnapshotBulletinApplication, IScopeD
                         {
                             var inDto = bulletion.Adapt<AddNotifyInDto>();
                             inDto.UserIds = citizenIds;
-                            if (bulletion.VideoPath.NotNullOrEmpty())
+                            if (bulletion.Shape != null && bulletion.Shape == EBulletinShape.Video)
                             {
                                 inDto.NotifyType = ENotificationType.Video;
                             }
+                            inDto.ExternalId = bulletion.Id;
                             await _notificationDomainService.AddNotifyAsync(inDto, token);
                         });
                 }
@@ -192,6 +187,8 @@ public class SnapshotBulletinApplication : ISnapshotBulletinApplication, IScopeD
         var model = dto.Adapt<SnapshotBulletin>();
         model.BulletinState = EBulletinState.Draft;
         model.ReadedNum = 0;
+        if (model.Content.IsNullOrEmpty())
+            model.Content = " ";
         if (model.BulletinTime.HasValue == false) model.BulletinTime = DateTime.Now;
         return await _bulletinRepository.AddAsync(model, token);
     }

+ 14 - 4
src/Hotline.Application/Snapshot/SnapshotPointsApplication.cs

@@ -4,6 +4,7 @@ using Hotline.Share.Dtos.Snapshot;
 using Hotline.Share.Enums.CallCenter;
 using Hotline.Share.Enums.Snapshot;
 using Hotline.Share.Tools;
+using Hotline.Snapshot;
 using Hotline.Snapshot.IRepository;
 using SqlSugar;
 using System;
@@ -60,7 +61,6 @@ public class SnapshotPointsApplication : ISnapshotPointsApplication, IScopeDepen
 
     public async Task UpdateIsSecurityMaxAsync(UpdateIsSecurityMaxAsync dto, CancellationToken token)
     {
-        // TODO 紧急
         await _citizenRepository.Updateable()
             .SetColumns(citizen => citizen.IsSecurityMax, dto.IsSecurityMax)
             .Where(citizen => citizen.Id == dto.UserId)
@@ -73,11 +73,21 @@ public class SnapshotPointsApplication : ISnapshotPointsApplication, IScopeDepen
             {
                 await _safetyTypeRepository.Queryable()
                     .Where(m => m.Name == "安全卫士")
-                    .Select(m => m.Id)
                     .FirstAsync(token)
-                    .Then(async id =>
+                    .Then(async safetyType =>
                     {
-                        //citizen.
+                        if (dto.IsSecurityMax)
+                            citizen.SafetyTypes.Add(safetyType);
+                        else
+                        {
+                            var delete = citizen.SafetyTypes.Where(m => m.Name == "安全卫士").ToList();
+                            foreach (var item in delete)
+                            {
+                                citizen.SafetyTypes.Remove(item);
+                            }
+                        }
+                        await _citizenRepository.UpdateNav(citizen).Include(m => m.SafetyTypes)
+                                .ExecuteCommandAsync();
                     });
             });
     }

+ 4 - 1
src/Hotline.Application/Snapshot/SnapshotUserApplication.cs

@@ -61,6 +61,9 @@ public class SnapshotUserApplication : ISnapshotUserApplication, IScopeDependenc
             .LeftJoin<CitizenRelationSafetyType>((citizen, relation) => citizen.Id == relation.CitizenId)
             .LeftJoin<SafetyType>((citizen, relation, safety) => relation.SafetyTypeId == safety.Id)
             .WhereIF(dto.SafetyTypeId.NotNullOrEmpty(), (citizen, relation, safety) => safety.Id == dto.SafetyTypeId)
+            .WhereIF(dto.Name.NotNullOrEmpty(), (citizen, relation, safety) => citizen.Name.Contains(dto.Name))
+            .WhereIF(dto.PhoneNumber.NotNullOrEmpty(), (citizen, relation, safety) => citizen.PhoneNumber.Contains(dto.PhoneNumber))
+            .Where((citizen, relation, safety) => safety.Id != null)
             .Select((citizen, relation, safety) => new CitizenRelationSafetyTypeOutDto
             {
                 CitizenId = citizen.Id,
@@ -95,7 +98,7 @@ public class SnapshotUserApplication : ISnapshotUserApplication, IScopeDependenc
         var query = _citizenRepository.Queryable(includeDeleted: true)
             .LeftJoin<ThirdAccount>((citizen, third) => citizen.Id == third.ExternalId)
             .WhereIF(dto.PhoneNumber.NotNullOrEmpty(), (citizen, third) => citizen.PhoneNumber.Contains(dto.PhoneNumber))
-            .Select((citizen, third) => new GetThirdCitizenOutDto(), true);
+            .Select((citizen, third) => new GetThirdCitizenOutDto { CitizenId = citizen.Id}, true);
 #if DEBUG
         var sql = query.ToSqlString();
 #endif

+ 1 - 1
src/Hotline.Repository.SqlSugar/CallCenter/TrCallRecordRepository.cs

@@ -285,7 +285,7 @@ namespace Hotline.Repository.SqlSugar.CallCenter
                  .WhereIF(!string.IsNullOrEmpty(dto.SensitiveWord), d => SqlFunc.JsonArrayAny(d.Sensitive, dto.SensitiveWord))
                  .WhereIF(dto.IsAiAnswered == true, x => string.IsNullOrEmpty(x.UserId) == true && x.BeginIvrTime.HasValue && x.EndIvrTime.HasValue)
                  .WhereIF(dto.PhoneTypes != null, x => x.PhoneTypes == dto.PhoneTypes)
-                 .WhereIF(dto.QuerySelf.HasValue && dto.QuerySelf == true, x => x.UserId == _sessionContext.UserId)
+                 .WhereIF(dto.QuerySelf == 1, x => x.UserId == _sessionContext.UserId)
                  .OrderByDescending(x => x.CreatedTime);
         }
 

+ 0 - 1
src/Hotline.Repository.SqlSugar/Exam/Validators/Sourcewares/SourcewareCategoryValidator.cs

@@ -46,7 +46,6 @@ namespace Exam.Repository.Sqlsugar.Validators.Sourcewares
         {
             base.BaseValidateRule();
             RuleFor(m => m.Name).NotEmpty().WithMessage(x => string.Format(ExamErrorMessage.IsRequired, x.GetType().GetDescription(nameof(ExamSourcewareCategory.Name))));
-            RuleFor(m => m.SortIndex).NotEmpty().WithMessage(x => string.Format(ExamErrorMessage.IsRequired, x.GetType().GetDescription(nameof(ExamSourcewareCategory.SortIndex))));
         }
 
         protected override void ValidateRuleWithAdd()

+ 1 - 0
src/Hotline.Share/Dtos/Knowledge/KnowedgeStatisticsDto.cs

@@ -2,6 +2,7 @@
 {
     public class KnowedgeStatisticsDto
     {
+        public int Index { get; set; }
         public string? OrgName { get; set; }
 
         public DateTime? LastModificationTime { get; set; }

+ 5 - 1
src/Hotline.Share/Dtos/Snapshot/NotifyDto.cs

@@ -29,6 +29,8 @@ public class AddNotifyInDto
     /// </summary>
     public ENotificationType NotifyType { get; set; }
 
+    public string ExternalId { get; set; }
+
     /// <summary>
     /// 用户
     /// </summary>
@@ -38,7 +40,9 @@ public class AddNotifyInDto
 public class GetNotifyInDto : QueryFixedDto
 {
     /// <summary>
-    /// 消息类型
+    /// 消息类型:
+    /// 0: 通知公告
+    /// 1: 宣传视频
     /// </summary>
     public ENotificationType NotifyType { get; set; }
 }

+ 64 - 0
src/Hotline.Share/Dtos/Snapshot/PointsDto.cs

@@ -115,6 +115,70 @@ public class PointsRankOutDto
     /// 排行
     /// </summary>
     public IList<PointsRankUserDto> Ranks { get; set; }
+
+    /// <summary>
+    /// 视频公告
+    /// </summary>
+    public VideoBulletinOutDto VideoBulletin { get; set; }
+
+    /// <summary>
+    /// 通知公告
+    /// </summary>
+    public PointsBulletinOutDto Bulletins { get; set; }
+}
+
+public class PointsBulletinOutDto
+{
+    /// <summary>
+    /// 未读个数
+    /// </summary>
+    public int UnReadCount { get; set; }
+
+    /// <summary>
+    /// Summary
+    /// </summary>
+    public IList<PointsBulletinItemsOutDto> Items { get; set; }
+}
+
+public class PointsBulletinItemsOutDto
+{
+    /// <summary>
+    /// Id
+    /// </summary>
+    public string BulletinId { get; set; }
+
+    /// <summary>
+    /// 标题
+    /// </summary>
+    public string Title { get; set; }
+}
+
+public class VideoBulletinOutDto
+{
+    /// <summary>
+    /// Id
+    /// </summary>
+    public string BulletinId { get; set; }
+
+    /// <summary>
+    /// 标题
+    /// </summary>
+    public string Title { get; set; }
+
+    /// <summary>
+    /// 栏目
+    /// </summary>
+    public string SnapshotBulletinTypeName { get; set; }
+
+    /// <summary>
+    /// 视频封面
+    /// </summary>
+    public string VideoCoverImgUrl { get; set; }
+
+    /// <summary>
+    /// 未读个数
+    /// </summary>
+    public int UnReadCount { get; set; }
 }
 
 public class PointsRankUserDto

+ 10 - 2
src/Hotline.Share/Dtos/Snapshot/SnapshotBulletinDto.cs

@@ -1,5 +1,6 @@
 using Hotline.Share.Dtos.Users;
 using Hotline.Share.Enums.Article;
+using Hotline.Share.Enums.Snapshot;
 using Hotline.Share.Requests;
 using System;
 using System.Collections.Generic;
@@ -163,6 +164,11 @@ public class SnapshotBulletinDetailOutDto : UpdateSnapshotBulletinInDto
     /// 上下架
     /// </summary>
     public bool IsArrive { get; set; }
+
+    /// <summary>
+    /// 类型
+    /// </summary>
+    public IList<string> SafetyTypeNames { get; set; }
 }
 
 public class UpdateSnapshotBulletinInDto : AddSnapshotBulletinInDto
@@ -256,9 +262,11 @@ public class AddSnapshotBulletinInDto
     public bool IsPopup { get; set; }
 
     /// <summary>
-    /// 是否随手拍
+    /// 公告形式
+    /// 0: 消息
+    /// 1: 视频
     /// </summary>
-    public bool? IsSnapshot { get; set; }
+    public EBulletinShape? Shape { get; set; }
 
     /// <summary>
     /// 志愿者类型Id

+ 10 - 0
src/Hotline.Share/Dtos/Snapshot/SnapshotUserInfoDto.cs

@@ -57,6 +57,16 @@ public record CitizenRelationSafetyTypeInDto : PagedRequest
     /// 志愿者类型
     /// </summary>
     public string? SafetyTypeId { get; set; }
+
+    /// <summary>
+    /// 名字
+    /// </summary>
+    public string? Name { get; set; }
+
+    /// <summary>
+    /// 手机号码
+    /// </summary>
+    public string? PhoneNumber { get; set; }
 }
 
 public class CitizenRelationSafetyTypeOutDto

+ 6 - 0
src/Hotline.Share/Dtos/Sourcewares/SourcewareCategoryDto.cs

@@ -27,6 +27,12 @@ namespace Hotline.Share.Dtos.Sourcewares
         /// </summary>
         [Description("父级ID")]
         public string ParentId { get; set; }
+
+        /// <summary>
+        /// 排序
+        /// </summary>
+        [Description("排序")]
+        public int? SortIndex { get; set; }
     }
 
     /// <summary>

+ 1 - 1
src/Hotline.Share/Dtos/Sourcewares/SourcewareDto.cs

@@ -33,7 +33,7 @@ namespace Hotline.Share.Dtos.Sourcewares
         /// 课件分类Id
         /// </summary>
         [Description("课件分类Id")]
-        public string CategoryId { get; set; }
+        public string? CategoryId { get; set; }
 
         /// <summary>
         /// 附件Id

+ 1 - 1
src/Hotline.Share/Dtos/TrCallCenter/TrTelDao.cs

@@ -581,7 +581,7 @@ namespace Hotline.Share.Dtos.TrCallCenter
         /// <summary>
         /// 是否自己的通话记录
         /// </summary>
-        public bool? QuerySelf { get; set; }
+        public int? QuerySelf { get; set; }
     }
 
 

+ 28 - 0
src/Hotline.Share/Enums/Snapshot/EBulletinShape.cs

@@ -0,0 +1,28 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Hotline.Share.Enums.Snapshot;
+
+/// <summary>
+/// 公告形式
+/// 0: 消息
+/// 1: 视频
+/// </summary>
+public enum EBulletinShape
+{
+    /// <summary>
+    /// 消息
+    /// </summary>
+    [Description("消息")]
+    Message = 0,
+
+    /// <summary>
+    /// 视频
+    /// </summary>
+    [Description("视频")]
+    Video = 1
+}

+ 6 - 0
src/Hotline.Share/Enums/Snapshot/ENotificationType.cs

@@ -9,9 +9,15 @@ namespace Hotline.Share.Enums.Snapshot;
 
 public enum ENotificationType
 {
+    /// <summary>
+    /// 通知公告
+    /// </summary>
     [Description("消息")]
     Message = 0,
 
+    /// <summary>
+    /// 宣传视频
+    /// </summary>
     [Description("视频")]
     Video = 1
 }

+ 6 - 0
src/Hotline.Share/Enums/Snapshot/EPointsSource.cs

@@ -21,6 +21,12 @@ public enum EPointsSource
     [Description("审核积分")]
     Audit = 1,
 
+    /// <summary>
+    /// 额外扣除
+    /// </summary>
+    [Description("额外扣除")]
+    AuditDeduct = 2,
+
     /// <summary>
     /// 积分兑换
     /// </summary>

+ 5 - 0
src/Hotline.Share/Tools/DataMaskExtensions.cs

@@ -10,6 +10,9 @@ public static class DataMaskExtensions
 {
     public static string Mask(this string original, int startIndex = 0, int length = 4)
     {
+        if (original.IsNullOrEmpty()) return original;
+        if (original.Length <= startIndex + length) return original;
+
         var headStr = original.Substring(0, startIndex);
         var tailStr = original.Substring(startIndex + length);
         var sb = new StringBuilder(length);
@@ -23,12 +26,14 @@ public static class DataMaskExtensions
 
     public static string MaskPhoneNumber(this string original)
     {
+        if (original.IsNullOrEmpty()) return original;
         if (original.Length < 11) return string.Empty;
         return original.Mask(3, 4);
     }
 
     public static string MaskIdCard(this string original)
     {
+        if (original.IsNullOrEmpty()) return original;
         return original.Mask(3, 12);
     }
 }

+ 5 - 0
src/Hotline/Settings/SettingConstants.cs

@@ -820,5 +820,10 @@ namespace Hotline.Settings
         /// 话务管理未接允许关联工单
         /// </summary>
         public const string IsCallBindOrder = "IsCallBindOrder";
+
+        /// <summary>
+        /// 是否开启白名单查询
+        /// </summary>
+        public const string IsOpenWhiteList = "IsOpenWhiteList";
     }
 }

+ 2 - 1
src/Hotline/Snapshot/Contracts/ISnapshotPointsDomainService.cs

@@ -19,6 +19,7 @@ public interface ISnapshotPointsDomainService
     /// <param name="source"></param>
     /// <param name="status"></param>
     /// <param name="extraDeductedPoints"></param>
+    /// <param name="extraDeductionPointsTypeName">额外扣除原因</param>
     /// <returns></returns>
-    Task AddPointsAsync(string orderId, EPointsSource source, ESnapshotSMSStatus? status, int? extraDeductedPoints);
+    Task AddPointsAsync(string orderId, EPointsSource source, ESnapshotSMSStatus? status, int? extraDeductedPoints, string? extraDeductionPointsTypeName = "");
 }

+ 7 - 0
src/Hotline/Snapshot/Notification.cs

@@ -1,4 +1,5 @@
 using Hotline.Share.Enums.Snapshot;
+using SqlSugar;
 using System;
 using System.Collections.Generic;
 using System.Linq;
@@ -24,4 +25,10 @@ public class Notification : CreationSoftDeleteEntity
     /// 类型
     /// </summary>
     public ENotificationType NotifyType { get; set; }
+
+    /// <summary>
+    /// 外部业务唯一标识
+    /// </summary>
+    [SugarColumn(ColumnDescription = "外部业务唯一标识")]
+    public string? ExternalId { get; set; }
 }

+ 26 - 5
src/Hotline/Snapshot/Services/SnapshotPointsDomainService.cs

@@ -1,4 +1,6 @@
-using Hotline.Share.Enums.Snapshot;
+using Hotline.Orders;
+using Hotline.Share.Enums.Snapshot;
+using Hotline.Share.Tools;
 using Hotline.Snapshot.Contracts;
 using Hotline.Snapshot.IRepository;
 using System;
@@ -22,16 +24,26 @@ public class SnapshotPointsDomainService : ISnapshotPointsDomainService, IScopeD
         _pointsRecordRepository = snapshotPointsRecordRepository;
     }
 
-    public async Task AddPointsAsync(string orderId, EPointsSource source, ESnapshotSMSStatus? status, int? extraDeductedPoints)
+    public async Task AddPointsAsync(string orderId, EPointsSource source, ESnapshotSMSStatus? status, int? extraDeductedPoints, string? extraDeductionPointsTypeName = "")
     {
         if (status == null) return;
         var order = await _orderSnapshotRepository.Queryable()
             .LeftJoin<Industry>((snapshot, industry) => snapshot.IndustryId == industry.Id)
+            .LeftJoin<Order>((snapshot, industry, order) => order.Id == snapshot.Id)
             .Where((snapshot, industry) => snapshot.Id == orderId)
-            .Select((snapshot, industry) => new { snapshot.Id, industry.ReportPoints , industry.ArgeePoints , industry.RefusePoints,  industry.Name,
-                snapshot.CreatorId})
+            .Select((snapshot, industry, order) => new 
+            {
+                snapshot.Id,
+                industry.ReportPoints,
+                industry.ArgeePoints, 
+                industry.RefusePoints,
+                industry.Name,
+                snapshot.CreatorId,
+                order.HotspotId
+            })
             .FirstAsync();
         if (order == null) return;
+        if (order.HotspotId != null && order.HotspotId.StartsWith("18") == true) return;
         
         if (order.ReportPoints.HasValue == false)
             throw new UserFriendlyException($"{order.Name} 行业未配置积分");
@@ -51,8 +63,17 @@ public class SnapshotPointsDomainService : ISnapshotPointsDomainService, IScopeD
         if (source == EPointsSource.Audit && status == ESnapshotSMSStatus.Refuse)
         {
             points.Direction = Share.Enums.CallCenter.EPointsDirection.Out;
-            points.Points = order.RefusePoints ?? 0 + extraDeductedPoints ?? 0;
+            points.Points = order.RefusePoints ?? 0;
             points.Points *= -1;
+
+            if (extraDeductionPointsTypeName.NotNullOrEmpty() && extraDeductedPoints != null && extraDeductedPoints != 0)
+            {
+                var ex = points.ToJson().FromJson<SnapshotPointsRecord>();
+                ex.Source = EPointsSource.AuditDeduct;
+                ex.Points = extraDeductedPoints.Value * -1;
+                ex.Remark = extraDeductionPointsTypeName;
+                await _pointsRecordRepository.AddAsync(ex);
+            }
         }
         await _pointsRecordRepository.AddAsync(points);
     }

+ 4 - 3
src/Hotline/Snapshot/SnapshotBulletin.cs

@@ -1,5 +1,6 @@
 using Hotline.Share.Dtos;
 using Hotline.Share.Enums.Article;
+using Hotline.Share.Enums.Snapshot;
 using Hotline.Users;
 using SqlSugar;
 using System.ComponentModel;
@@ -177,10 +178,10 @@ public class SnapshotBulletin : CreationEntity
     }
 
     /// <summary>
-    /// 是否随手拍
+    /// 公告形式
     /// </summary>
-    [SugarColumn(ColumnDescription = "是否随手拍")]
-    public bool? IsSnapshot { get; set; }
+    [SugarColumn(ColumnDescription = "公告形式")]
+    public EBulletinShape? Shape { get; set; }
 
     /// <summary>
     /// 志愿者类型Id

+ 5 - 0
src/Hotline/Snapshot/SnapshotPointsRecord.cs

@@ -37,4 +37,9 @@ public class SnapshotPointsRecord : CreationEntity
     public int Points { get; set; }
 
     public string OrderId { get; set; }
+
+    /// <summary>
+    /// 备注
+    /// </summary>
+    public string? Remark { get; set; }
 }

+ 0 - 1
src/Hotline/Validators/Exams/ExamManages/UpdateRuleTagDtoValidator.cs

@@ -11,7 +11,6 @@ namespace Hotline.Validators.Exams.ExamManages
     {
         public UpdateRuleTagDtoValidator()
         {
-            RuleFor(m => m.Id).NotEmpty().WithMessage(x => string.Format(ExamErrorMessage.IsRequired, x.GetType().GetDescription(nameof(ExamTag.Id))));
             RuleFor(m => m.TagId).NotEmpty().WithMessage(x => string.Format(ExamErrorMessage.IsRequired, typeof(ExamTag).GetDescription()));
         }
     }

+ 0 - 1
src/Hotline/Validators/Exams/ExamManages/UpdateTagQuestionDtoValidator.cs

@@ -11,7 +11,6 @@ namespace Hotline.Validators.Exams.ExamManages
     {
         public UpdateTagQuestionDtoValidator()
         {
-            RuleFor(m => m.Id).NotEmpty().WithMessage(x => string.Format(ExamErrorMessage.IsRequired, x.GetType().GetDescription(nameof(ExamTagQuestion.Id))));
             RuleFor(m => m.QuestionType).NotNull().WithMessage(x => string.Format(ExamErrorMessage.IsRequired, x.GetType().GetDescription(nameof(ExamTagQuestion.QuestionType))));
             RuleFor(m => m.Count).NotEmpty().WithMessage(x => string.Format(ExamErrorMessage.IsRequired, x.GetType().GetDescription(nameof(ExamTagQuestion.Count))));
             RuleFor(m => m.TagId).NotEmpty().WithMessage(x => string.Format(ExamErrorMessage.IsRequired, typeof(ExamTag).GetDescription()));

+ 0 - 1
src/Hotline/Validators/Exams/Questions/UpdateQuestionOptionsDtoValidator.cs

@@ -11,7 +11,6 @@ namespace Hotline.Validators.Exams
         public UpdateQuestionOptionsDtoValidator()
         {
             RuleFor(m => m.Content).NotEmpty().WithMessage(x => string.Format(ExamErrorMessage.IsRequired, x.GetType().GetDescription(nameof(ExamQuestionOptions.Content))));
-            RuleFor(m => m.Id).NotEmpty().WithMessage(x => string.Format(ExamErrorMessage.IsRequired, x.GetType().GetDescription(nameof(ExamQuestionOptions.Id))));
         }
     }
 }

+ 0 - 1
src/Hotline/Validators/Exams/Questions/UpdateQuestionSourcewareDtoValidator.cs

@@ -13,7 +13,6 @@ namespace Hotline.Validators.Exams.Questions
         public UpdateQuestionSourcewareDtoValidator()
         {
             RuleFor(m => m.SourcewareId).NotEmpty().WithMessage(x => string.Format(ExamErrorMessage.IsRequired, typeof(ExamSourceware).GetDescription()));
-            RuleFor(m => m.Id).NotEmpty().WithMessage(x => string.Format(ExamErrorMessage.IsRequired, x.GetType().GetDescription(nameof(ExamPracticeQuestionSourceware.Id))));
         }
     }
 }

+ 0 - 1
src/Hotline/Validators/Exams/Questions/UpdateQuestionTagDtoValidator.cs

@@ -13,7 +13,6 @@ namespace Hotline.Validators.Exams.Questions
         public UpdateQuestionTagDtoValidator()
         {
             RuleFor(m => m.TagId).NotEmpty().WithMessage(x => string.Format(ExamErrorMessage.IsRequired, typeof(ExamTag).GetDescription()));
-            RuleFor(m=>m.Id).NotEmpty().WithMessage(x => string.Format(ExamErrorMessage.IsRequired, x.GetType().GetDescription(nameof(ExamQuestionTag.Id))));
         }
     }
 }

+ 0 - 2
src/Hotline/Validators/Exams/Sourcewares/AddSourcewareDtoValidator.cs

@@ -16,8 +16,6 @@ namespace Hotline.Validators.Exams
         public AddSourcewareDtoValidator()
         {
             RuleFor(m => m.Name).NotEmpty().WithMessage(x => string.Format(ExamErrorMessage.IsRequired, x.GetType().GetDescription(nameof(ExamSourceware.Name))));
-            RuleFor(m => m.CategoryId).NotEmpty().WithMessage(x => string.Format(ExamErrorMessage.IsRequired, typeof(ExamSourcewareCategory).GetDescription()));
-
         }
     }
 }

+ 0 - 1
src/Hotline/Validators/Exams/Sourcewares/UpdateSourcewareDtoValidator.cs

@@ -12,7 +12,6 @@ namespace Hotline.Validators.Exams
         {
             RuleFor(m => m.Id).NotEmpty().WithMessage(x => string.Format(ExamErrorMessage.IsRequired, x.GetType().GetDescription(nameof(ExamSourceware.Id))));
             RuleFor(m => m.Name).NotEmpty().WithMessage(x => string.Format(ExamErrorMessage.IsRequired, x.GetType().GetDescription(nameof(ExamSourceware.Name))));
-            RuleFor(m => m.CategoryId).NotEmpty().WithMessage(x => string.Format(ExamErrorMessage.IsRequired, typeof(ExamSourcewareCategory).GetDescription()));   
         }
     }
 }

+ 0 - 2
src/Hotline/Validators/Exams/TestPapers/UpdateTestPaperItemDtoValidator.cs

@@ -13,8 +13,6 @@ namespace Hotline.Validators.Exams.TestPapers
         public UpdateTestPaperItemDtoValidator()
         {
             RuleFor(m => m.QuestionId).NotEmpty().WithMessage(x => string.Format(ExamErrorMessage.IsRequired, typeof(ExamQuestion).GetDescription()));
-
-            RuleFor(m => m.Id).NotEmpty().WithMessage(x => string.Format(ExamErrorMessage.IsRequired, x.GetType().GetDescription(nameof(ExamTestPaperItem.Id))));
         }
     }
 }

+ 0 - 2
src/Hotline/Validators/Exams/TestPapers/UpdateTestPaperRuleDtoValidator.cs

@@ -14,8 +14,6 @@ namespace Hotline.Validators.Exams.TestPapers
             RuleFor(m => m.QuestionType).NotNull().WithMessage(x => string.Format(ExamErrorMessage.IsRequired, x.GetType().GetDescription(nameof(ExamTestPaperRule.QuestionType))));
 
             RuleFor(m => m.Count).NotNull().WithMessage(x => string.Format(ExamErrorMessage.IsRequired, x.GetType().GetDescription(nameof(ExamTestPaperRule.QuestionType))));
-
-            RuleFor(m => m.Id).NotEmpty().WithMessage(x => string.Format(ExamErrorMessage.IsRequired, x.GetType().GetDescription(nameof(ExamTestPaperRule.Id))));
         }
     }
 }

+ 1 - 1
src/Hotline/Validators/Order/AddOrderDtoValidator.cs

@@ -114,7 +114,7 @@ public class AddOrderDtoValidator : AbstractValidator<AddOrderDto>
         #endregion
 
         #region 投诉详情
-        RuleFor(d => d.OrderExtension.ExternalOrderNo).MaximumLength(15).When(d => d.OrderExtension != null).WithMessage("订单号最多15字符");
+        RuleFor(d => d.OrderExtension.ExternalOrderNo).MaxLengthWithChineseChar(45).When(d => d.OrderExtension != null).WithMessage("订单号最多45字符");
         RuleFor(d => d.OrderExtension.Patentee).MaxLengthWithChineseChar(50).When(d => d.OrderExtension != null).WithMessage("专利权人最多50字符");
         RuleFor(d => d.OrderExtension.PatentName).MaxLengthWithChineseChar(200).When(d => d.OrderExtension != null).WithMessage("专利名称最多200字符");
         RuleFor(d => d.OrderExtension.PatentNo).MaxLengthWithChineseChar(50).When(d => d.OrderExtension != null).WithMessage("专利号最多50字符");

+ 35 - 3
test/Hotline.Tests/Application/OrderSnapshotApplicationTest.cs

@@ -11,6 +11,7 @@ using Hotline.Repository.SqlSugar.Snapshot;
 using Hotline.Settings;
 using Hotline.Share.Dtos;
 using Hotline.Share.Dtos.Snapshot;
+using Hotline.Share.Enums.CallCenter;
 using Hotline.Share.Enums.Snapshot;
 using Hotline.Share.Requests;
 using Hotline.Share.Tools;
@@ -112,6 +113,37 @@ public class OrderSnapshotApplicationTest : TestBase
             });
     }
 
+    [Theory]
+    [InlineData(true)]
+    [InlineData(false)]
+    public async Task SnapshotOrder_AddPoints_Test(bool 是受理范围)
+    {
+        var order = _orderServiceMock.CreateSnapshotOrder(SetWeiXin, "安全隐患")
+            .StepHandle(async order =>
+            {
+                if (是受理范围 == false)
+                {
+                    var entity = _orderRepository.Get(order.Id);
+                    entity.HotspotId = "181301";
+                    await _orderRepository.UpdateAsync(entity);
+                }
+            })
+            .办理到一级部门(SetZuoXi)
+            .办理到归档(Set一级部门, data =>
+            {
+                data.CompliantType = ECompliantType.First;
+                data.VerifyType = "现场";
+                data.IsCheckList = true;
+            }).GetCreateResult();
+        var points = await _pointsRecordRepository.Queryable()
+            .Where(m => m.OrderId == order.Id && m.Direction == EPointsDirection.In && m.Source == EPointsSource.Report)
+            .FirstAsync();
+        if (是受理范围)
+            points.ShouldNotBeNull();
+        else
+            points.ShouldBeNull();
+    }
+
     /// <summary>
     /// 随手拍网格员超时:
     /// </summary>
@@ -267,7 +299,7 @@ public class OrderSnapshotApplicationTest : TestBase
                 baseData.AuditTypeCode.ShouldNotBeNull();
                 baseData.Amount.ShouldNotBeNull();
 
-                var specialRedAuditItems = await _redPackApplication.GetRedPackSpecialAuditItems(new SnapshotOrderAuditItemsInDto() { PageIndex = 1, PageSize = 10 , No = order.No, Status = 1}).ToListAsync();
+                var specialRedAuditItems = await _redPackApplication.GetRedPackSpecialAuditItems(new SnapshotOrderAuditItemsInDto() { PageIndex = 1, PageSize = 10, No = order.No, Status = 1 }).ToListAsync();
                 var specialRedAudit = specialRedAuditItems.FirstOrDefault();
                 specialRedAudit.ShouldNotBeNull();
                 var a = _systemDicDataCacheManager.SnapshotReplenishType.First();
@@ -288,7 +320,7 @@ public class OrderSnapshotApplicationTest : TestBase
                 };
 
                 await _redPackApplication.UpdateRedPackSpecialRecordAsync(inDto); // 补充发放
-                specialRedAuditItems = await _redPackApplication.GetRedPackSpecialAuditItems(new SnapshotOrderAuditItemsInDto() { PageIndex = 1, PageSize = 10 , Status = 1, No = order.No}).ToListAsync();
+                specialRedAuditItems = await _redPackApplication.GetRedPackSpecialAuditItems(new SnapshotOrderAuditItemsInDto() { PageIndex = 1, PageSize = 10, Status = 1, No = order.No }).ToListAsync();
                 specialRedAudit = specialRedAuditItems.First();
                 specialRedAudit.ShouldNotBeNull();
                 specialRedAudit.BankCardNo.ShouldBe(inDto.BankCardNo);
@@ -329,7 +361,7 @@ public class OrderSnapshotApplicationTest : TestBase
                 }); // 添加备注
 
                 SetWeiXin();
-                redPackItems =  await _snapshotApplication.GetRedPacksAsync(new RedPacksInDto() { Status = ERedPackPickupStatus.Received }, CancellationToken.None);
+                redPackItems = await _snapshotApplication.GetRedPacksAsync(new RedPacksInDto() { Status = ERedPackPickupStatus.Received }, CancellationToken.None);
                 redPackRecord = redPackItems.Where(m => m.OrderId == order.Id).FirstOrDefault();
                 redPackRecord.ShouldNotBeNull();
                 redPackRecord.Amount.ShouldBe(11);

+ 40 - 5
test/Hotline.Tests/Application/PointsRecordApplicationTest.cs

@@ -2,8 +2,11 @@
 using Hotline.Application.Snapshot.Contracts;
 using Hotline.Identity.Accounts;
 using Hotline.Identity.Roles;
+using Hotline.Orders;
 using Hotline.Settings;
 using Hotline.Share.Dtos.Snapshot;
+using Hotline.Share.Tools;
+using Hotline.Snapshot.IRepository;
 using Hotline.ThirdAccountDomainServices;
 using Hotline.ThirdAccountDomainServices.Interfaces;
 using Hotline.Users;
@@ -15,6 +18,7 @@ using System.Collections.Generic;
 using System.Linq;
 using System.Text;
 using System.Threading.Tasks;
+using XF.Domain.Authentications;
 using XF.Domain.Cache;
 using XF.Domain.Repository;
 
@@ -24,10 +28,17 @@ public class PointsRecordApplicationTest : TestBase
 {
     private readonly ISnapshotPointsApplication _pointsRecordApplication;
     private readonly ISnapshotApplication _snapshotApplication;
-    public PointsRecordApplicationTest(IAccountRepository accountRepository, IRepository<Role> roleRepository, UserController userController, IServiceScopeFactory scopeFactory, IRepository<User> userRepository, IHttpContextAccessor httpContextAccessor, IThirdIdentiyService thirdIdentiyService, IThirdAccountRepository thirdAccountRepository, ITypedCache<SystemSetting> cacheSettingData, ThirdAccounSupplierFactory thirdAccountDomainFactory, ISnapshotPointsApplication pointsRecordApplication, ISnapshotApplication snapshotApplication, IServiceProvider serviceProvider) : base(accountRepository, roleRepository, userController, scopeFactory, userRepository, httpContextAccessor, thirdIdentiyService, thirdAccountRepository, cacheSettingData, thirdAccountDomainFactory, serviceProvider)
+    private readonly ISessionContext _sessionContext;
+    private readonly ICitizenRepository _citizenRepository;
+    private readonly ISafetyTypeRepository _safetyTypeRepository;
+
+    public PointsRecordApplicationTest(IAccountRepository accountRepository, IRepository<Role> roleRepository, UserController userController, IServiceScopeFactory scopeFactory, IRepository<User> userRepository, IHttpContextAccessor httpContextAccessor, IThirdIdentiyService thirdIdentiyService, IThirdAccountRepository thirdAccountRepository, ITypedCache<SystemSetting> cacheSettingData, ThirdAccounSupplierFactory thirdAccountDomainFactory, ISnapshotPointsApplication pointsRecordApplication, ISnapshotApplication snapshotApplication, IServiceProvider serviceProvider, ISessionContext sessionContext, ICitizenRepository citizenRepository, ISafetyTypeRepository safetyTypeRepository) : base(accountRepository, roleRepository, userController, scopeFactory, userRepository, httpContextAccessor, thirdIdentiyService, thirdAccountRepository, cacheSettingData, thirdAccountDomainFactory, serviceProvider)
     {
         _pointsRecordApplication = pointsRecordApplication;
         _snapshotApplication = snapshotApplication;
+        _sessionContext = sessionContext;
+        _citizenRepository = citizenRepository;
+        _safetyTypeRepository = safetyTypeRepository;
     }
 
     [Fact]
@@ -42,15 +53,39 @@ public class PointsRecordApplicationTest : TestBase
         items.ShouldNotBeNull();
     }
 
+    [Fact]
+    public async Task UpdateIsSecurityMax_Test()
+    {
+        SetWeiXin();
+        var inDto = new UpdateIsSecurityMaxAsync
+        {
+            UserId = _sessionContext.UserId,
+            IsSecurityMax = false
+        };
+        await _pointsRecordApplication.UpdateIsSecurityMaxAsync(inDto, CancellationToken.None);
+        var citizen = await _citizenRepository.Queryable()
+            .Where(m => m.Id == inDto.UserId)
+            .Includes(m => m.SafetyTypes)
+            .FirstAsync();
+        citizen.SafetyTypes.Any(m => m.Name == "安全卫士").ShouldBeFalse();
+
+        inDto.IsSecurityMax = true;
+        await _pointsRecordApplication.UpdateIsSecurityMaxAsync(inDto, CancellationToken.None);
+        citizen = await _citizenRepository.Queryable()
+            .Where(m => m.Id == inDto.UserId)
+            .Includes(m => m.SafetyTypes)
+            .FirstAsync();
+        citizen.SafetyTypes.Any(m => m.Name == "安全卫士").ShouldBeTrue();
+    }
+
     [Fact]
     public async Task GetPointsRank_Test()
     {
         SetWeiXin();
         var item = await _snapshotApplication.GetPointsRankAsync();
         item.ShouldNotBeNull();
-        foreach (var a in item.Ranks)
-        {
-            var s = a.PhoneNumber;
-        }
+        item.Bulletins.Items.Any(m => m.Title.IsNullOrEmpty()).ShouldBeFalse();
+        item.Bulletins.Items.Any(m => m.BulletinId.IsNullOrEmpty()).ShouldBeFalse();
+        item.VideoBulletin.ShouldNotBeNull();
     }
 }

+ 2 - 2
test/Hotline.Tests/Application/SnapshotApplicationTest.cs

@@ -251,7 +251,7 @@ public class SnapshotApplicationTest : TestBase
     [Fact]
     public async Task RefreshTokenAsync()
     {
-        var token = await _identityAppService.GetThredTokenAsync(new ThirdTokenInDto(), CancellationToken.None);
+        var token = await _identityAppService.GetThirdTokenAsync(new ThirdTokenInDto(), CancellationToken.None);
         var newToken = await _identityAppService.RefreshTokenAsync(token["OpenId"].ToString(), CancellationToken.None);
         newToken.ShouldNotBeNull();
         newToken["OpenId"].ShouldBe(token["OpenId"].ToString());
@@ -265,7 +265,7 @@ public class SnapshotApplicationTest : TestBase
     [Fact]
     public async Task GetThirdToken_Test()
     {
-        var result = await _identityAppService.GetThredTokenAsync(new ThirdTokenInDto { AppType = EAppType.Snapshot, ThirdType = EThirdType.WeChat, LoginCode = "0c3Adhll2zDMBe413rnl2KvEym2AdhlH" }, CancellationToken.None);
+        var result = await _identityAppService.GetThirdTokenAsync(new ThirdTokenInDto { AppType = EAppType.Snapshot, ThirdType = EThirdType.WeChat,   LoginCode = "0c3Adhll2zDMBe413rnl2KvEym2AdhlH" }, CancellationToken.None);
         result["PhoneNumber"].ToString().ShouldNotBeNullOrEmpty();
     }
 

+ 5 - 5
test/Hotline.Tests/Application/SnapshotBulletionApplicationTest.cs

@@ -51,7 +51,7 @@ public class SnapshotBulletionApplicationTest : TestBase
     public async Task Bulletin_Test()
     {
         SetWeiXin();
-        var bulletinType =  _systemDicDataCacheManager.SnapshotBulletinType.First();
+        var bulletinType =  _systemDicDataCacheManager.SnapshotBulletinType.First(m => m.DicDataName == "安全卫士");
         var safetyType = await _safetyTypeRepository.Queryable().FirstAsync();
         var addRelationInDto = new AddCitizenRelationSafetyTypeInDto { SafetyTypeId = safetyType.Id, CitizenIds = [_sessionContext.UserId] };
         await _snapshotUserApplication.AddCitizenRelationSafetyType(addRelationInDto, CancellationToken.None);
@@ -60,7 +60,7 @@ public class SnapshotBulletionApplicationTest : TestBase
             Title = "测试公告" + DateTime.Now.ToLongDateTimeString(),
             Content = "没什么内容",
             BulletinTime = DateTime.Now,
-            IsSnapshot = true,
+            Shape = Share.Enums.Snapshot.EBulletinShape.Video,
             BulletinTypeId = bulletinType.DicDataValue,
             BulletinTypeName = bulletinType.DicDataName,
             SafetyTypeId = [safetyType.Id],
@@ -69,7 +69,7 @@ public class SnapshotBulletionApplicationTest : TestBase
         };
         var bulletinId = await _snapshotBulletinApplication.AddBulletinAsync(inDto, CancellationToken.None);
         var bulletin = await _bulletinRepository.GetAsync(bulletinId);
-        bulletin.IsSnapshot.ShouldBe(true);
+        bulletin.Shape.ShouldBe(Share.Enums.Snapshot.EBulletinShape.Video);
         bulletin.SafetyTypeId.First().ShouldBe(safetyType.Id);
         bulletin.VideoPath.ShouldBe(inDto.VideoPath);
         bulletin.VideoCoverImgUrl.ShouldBe(inDto.VideoCoverImgUrl);
@@ -81,11 +81,11 @@ public class SnapshotBulletionApplicationTest : TestBase
             Reason = "审核通过"
         };
         await _snapshotBulletinApplication.ExamineBulletinAsync(examineDto, CancellationToken.None);
-        Thread.Sleep(5 * 1000);
+        Thread.Sleep(10 * 1000);
         //await _snapshotBulletinApplication.NotifyUserAsync(bulletinId, CancellationToken.None);
 
 
-        var notifyItems = await _snapshotApplication.GetNotificationAsync(new GetNotifyInDto(), CancellationToken.None);
+        var notifyItems = await _snapshotApplication.GetNotificationAsync(new GetNotifyInDto { NotifyType = Share.Enums.Snapshot.ENotificationType.Video}, CancellationToken.None);
         notifyItems.Any(m => m.Title == inDto.Title).ShouldBeTrue();
     }
 }

+ 1 - 0
test/Hotline.Tests/Application/SnapshotUserApplicationTest.cs

@@ -101,6 +101,7 @@ public class SnapshotUserApplicationTest : TestBase
         await _snapshotUserApplication.DeleteCitizenRelationSafetyAsync(deleteInDto);
 
         items = await _snapshotUserApplication.GetCitizenRelationSafetyType(inDto).ToListAsync();
+        items.Any(m => m.SafetyTypeId.IsNullOrEmpty()).ShouldBeFalse();
         item = items.FirstOrDefault(m => m.CitizenId == citizen.Id && m.SafetyTypeId == safetyType.Id);
         item.ShouldBeNull();
         inDto = new CitizenRelationSafetyTypeInDto

+ 2 - 0
test/Hotline.Tests/Mock/Interfaces/IOrderServiceStartWorkflow.cs

@@ -13,4 +13,6 @@ public interface IOrderServiceStartWorkflow
     CreateOrderOutDto GetCreateResult();
     OrderServiceMock 办理到一级部门(Action action = null);
     OrderServiceMock 办理到归档(Action action = null);
+
+    IOrderServiceStartWorkflow StepHandle(Func<CreateOrderOutDto, Task> handle);
 }

+ 6 - 0
test/Hotline.Tests/Mock/OrderServiceStartWorkflow.cs

@@ -46,6 +46,12 @@ public class OrderServiceStartWorkflow : IOrderServiceStartWorkflow
         return _orderServiceMock.CreateOrderOutDto;
     }
 
+    public IOrderServiceStartWorkflow StepHandle(Func<CreateOrderOutDto, Task> handle)
+    {
+        handle(_orderServiceMock.CreateOrderOutDto).GetAwaiter().GetResult();
+        return this;
+    }
+
     public OrderServiceMock 办理到一级部门(Action action = null)
     {
         action?.Invoke();

Nem az összes módosított fájl került megjelenítésre, mert túl sok fájl változott