Compare commits

...

60 Commits

Author SHA1 Message Date
zhaozhenjing e864eecb3d [MODIFY]短信发送修改,用户修改手机号优化 4 weeks ago
zhaozhenjing d45a891f41 [MODIFY]查询修改 1 month ago
zhaozhenjing a48ae2e79a [MODIFY]增加用户手机号校验 2 months ago
zhaozhenjing e1799fc3b8 [MODIFY]修改短信调用方式, 2 months ago
zhaozhenjing 4fb3f4ae20 [MODIFY]权限修改 2 months ago
zhaozhenjing cdec9117c6 [MODIFY]优化导出逻辑 2 months ago
zhaozhenjing 9612645071 [MODIFY]修改readme 2 months ago
zhaozhenjing c384f24cc1 [MODIFY]短信增加接收人字段,修改人员修改界面的老bug 2 months ago
zhaozhenjing a40f4beea1 [MODIFY]修改测试bug 2 months ago
zhaozhenjing 5ee99b0d21 [MODIFY]增加职位判断,前端按钮根据不同职位进行不同适配 2 months ago
zhaozhenjing 1d2253a523 [MODIFY]测试问题修改,导出功能开发 2 months ago
zhaozhenjing 4b39b2c425 [MODIFY]问题bug修改 2 months ago
zhaozhenjing 60f16c0469 [MODIFY]增加导出功能 2 months ago
zhaozhenjing ff6d3b8c7b [MODIFY]20251016提出的bug修改提交 2 months ago
zhaozhenjing bb106ceee4 [MODIFY]增加短信查看接口 2 months ago
zhaozhenjing 925a4486b9 [MODIFY]增加短线提示,短信配置提到外层 2 months ago
zhaozhenjing da940af097 [MODIFY]增加待审批短信通知、审批完成短信通知 2 months ago
zhaozhenjing 8fa25031cd [MODIFY]增加短信推送逻辑,注释短信登陆校验 2 months ago
zhaozhenjing 606b06b05f [MODIFY]文件传输增大接收数,信息弹窗校验 2 months ago
zhaozhenjing 0b5a5b85fa [MODIFY]提测bug修改,多接口增加数据权限控制 2 months ago
zhaozhenjing 72ed50cb47 Merge branch 'develop' into dev-zzj 3 months ago
zhaozhenjing 7e6de39fa8 [MODIFY]打开job 3 months ago
wangping 8c38a8e2e5 GetToken新增字段兼容APP 3 months ago
wangping cb5071bffb APP认证报错 3 months ago
wangping 474d481b5e Merge branch 'dev_wp' into develop 3 months ago
wangping 24ea9e097e 登录接口兼容APP 3 months ago
zhaozhenjing 0d3c190ad7 [MODIFY]查询bug,前台查询条件不生效 3 months ago
zhaozhenjing 55d0c24d99 Merge branch 'develop' into dev-zzj 3 months ago
wangping bbac947787 腾讯云短信接入,验证码接口调整 3 months ago
zhaozhenjing 157056efb8 [MODIFY]接口增加条件,已完结的案子不显示 3 months ago
zhaozhenjing 82264d99fc Merge branch 'develop' into dev-zzj 3 months ago
zhaozhenjing a86a5aa087 [MODIFY] 越界预警增加权限校验 3 months ago
wangping f7764bf88a 添加案件时,写入监管人单位 3 months ago
zhaozhenjing 639a6fb3a4 [MODIFY] 越界审批增加权限校验 3 months ago
zhaozhenjing 1560949db5 [MODIFY] 消息推送功能增加权限校验 3 months ago
zhaozhenjing 5b924548c0 [MODIFY] APP打卡增加数据校验 3 months ago
zhaozhenjing 109a0ceeac Merge branch 'develop' into dev-zzj 3 months ago
zhaozhenjing 1b878776b8 [MODIFY] 增加权限校验 3 months ago
wangping 136ff1f656 短信相关接口与模型 3 months ago
zhaozhenjing 94f5feaac8 [MODIFY] 学习记录增加查询限制 3 months ago
zhaozhenjing 241450ddf1 [MODIFY] 定位分布功能增加权限控制 3 months ago
zhaozhenjing 46a26db1f8 [MODIFY] APP认证增加权限校验 3 months ago
zhaozhenjing 64c5ca915e [MODIFY] 打卡记录统计功能增加条件限制 3 months ago
zhaozhenjing 496946447e [MODIFY]违规统计功能增加权限验证 3 months ago
zhaozhenjing 8b48feaba4 [MODIFY]办案时长统计增加权限限制 3 months ago
zhaozhenjing 9fa91adcfc Merge branch 'develop' into dev-zzj 3 months ago
zhaozhenjing 70e44379a2 [MODIFY]案件类型统计功能优化查询 3 months ago
wangping f5472e4fea 案件导出 3 months ago
wangping 848fd84f84 部分BUG处理,登录信息是否管理员,涉案人员,涉案人员导出 3 months ago
wangping c80799db6d 合并 3 months ago
zhaozhenjing e67dd34993 [MODIFY]越界预警统计、越界申请统计、在线学习分析功能的权限增加 3 months ago
wangping ceb68d34e8 涉案人员查询,涉案人员导出查询,涉案人员导出 3 months ago
zhaozhenjing b8808ffee1 Merge branch 'develop' into dev-zzj 3 months ago
zhaozhenjing ec3758b0bf 合并 3 months ago
zhaozhenjing 33214a4252 []忽略配置文件 3 months ago
zhaozhenjing a392df1ccb [MODIFY]单位管理功能新增时增加limit字段的填充,删除单位时,修改父级单位的limit 3 months ago
wangping 30b6a27ec5 Merge branch 'develop' into dev_wp 3 months ago
wangping 3b4e13dbd2 limits从unit表获取 3 months ago
zhaozhenjing c2d3a2f012 [MODIFY]单位管理功能 3 months ago
wangping 819d13915c 用户登录信息新增查询界限limits,案件管理查询新增查询界限条件 3 months ago
  1. 8
      .gitignore
  2. 35
      .vscode/launch.json
  3. 41
      .vscode/tasks.json
  4. 156
      README.md
  5. 46
      src/1.datas/ATS.NonCustodial.Domain/Entities/Admins/AppSMS.cs
  6. 9
      src/1.datas/ATS.NonCustodial.Domain/Entities/Admins/App_Unitcode.cs
  7. 5
      src/1.datas/ATS.NonCustodial.Domain/Entities/Business/AppBusinessApplication.cs
  8. 6
      src/1.datas/ATS.NonCustodial.Domain/Entities/Business/CaseManagements/AppCaseManagement.cs
  9. 7
      src/1.datas/ATS.NonCustodial.Domain/Entities/Business/CaseManagements/AppCaseSupervisedPerson.cs
  10. 2
      src/1.datas/ATS.NonCustodial.Domain/Entities/Business/CaseManagements/AppCaseSupervisor.cs
  11. 1
      src/2.services/ATS.NonCustodial.Application/ATS.NonCustodial.Application.csproj
  12. 3
      src/2.services/ATS.NonCustodial.Application/AutoMapperProfile/AdminBusinessProfile.cs
  13. 45
      src/2.services/ATS.NonCustodial.Application/Base/AdminCommonService.cs
  14. 11
      src/2.services/ATS.NonCustodial.Application/Impl/Admins/AppDictionaryService.cs
  15. 27
      src/2.services/ATS.NonCustodial.Application/Impl/Admins/AuthService.cs
  16. 593
      src/2.services/ATS.NonCustodial.Application/Impl/Admins/SMSService.cs
  17. 155
      src/2.services/ATS.NonCustodial.Application/Impl/Admins/UnitcodeService.cs
  18. 161
      src/2.services/ATS.NonCustodial.Application/Impl/Admins/UserService.cs
  19. 16
      src/2.services/ATS.NonCustodial.Application/Impl/Business/AppAnnouncementService.cs
  20. 147
      src/2.services/ATS.NonCustodial.Application/Impl/Business/AppBusinessApplicationService.cs
  21. 7
      src/2.services/ATS.NonCustodial.Application/Impl/Business/AppDeviceManagementService.cs
  22. 88
      src/2.services/ATS.NonCustodial.Application/Impl/Business/AppEarlyWarningService.cs
  23. 139
      src/2.services/ATS.NonCustodial.Application/Impl/Business/AppManagementService.cs
  24. 106
      src/2.services/ATS.NonCustodial.Application/Impl/Business/AppPunchRecordService.cs
  25. 408
      src/2.services/ATS.NonCustodial.Application/Impl/Business/AppViolationStatisticsService.cs
  26. 295
      src/2.services/ATS.NonCustodial.Application/Impl/Business/CaseManagements/AppCaseManagementService.cs
  27. 12
      src/2.services/ATS.NonCustodial.Application/Impl/Business/CaseManagements/AppSupervisedPersonService.cs
  28. 34
      src/2.services/ATS.NonCustodial.Application/Impl/Business/MaterialManager/AppFileAccessRecordsService.cs
  29. 2
      src/2.services/ATS.NonCustodial.Application/Impl/Business/MaterialManager/AppFileDescriptorService.cs
  30. 10
      src/2.services/ATS.NonCustodial.Application/Impl/Logs/OperationLogService.cs
  31. 7
      src/3.contracts/ATS.NonCustodial.Application.Contracts/Interfaces/Admins/Auth/IAuthService.cs
  32. 14
      src/3.contracts/ATS.NonCustodial.Application.Contracts/Interfaces/Admins/Auth/Output/AuthLoginOutput.cs
  33. 53
      src/3.contracts/ATS.NonCustodial.Application.Contracts/Interfaces/Admins/SMS/ISMSService.cs
  34. 33
      src/3.contracts/ATS.NonCustodial.Application.Contracts/Interfaces/Admins/SMS/Input/SmsGetpageInput.cs
  35. 55
      src/3.contracts/ATS.NonCustodial.Application.Contracts/Interfaces/Admins/SMS/Output/SmsListDto.cs
  36. 7
      src/3.contracts/ATS.NonCustodial.Application.Contracts/Interfaces/Admins/Unitcode/Output/UnitcodeListOutput.cs
  37. 4
      src/3.contracts/ATS.NonCustodial.Application.Contracts/Interfaces/Admins/User/IUserService.cs
  38. 5
      src/3.contracts/ATS.NonCustodial.Application.Contracts/Interfaces/Admins/User/Input/UserAddInput.cs
  39. 10
      src/3.contracts/ATS.NonCustodial.Application.Contracts/Interfaces/Admins/User/Input/UserUpdateInput.cs
  40. 5
      src/3.contracts/ATS.NonCustodial.Application.Contracts/Interfaces/Business/AppBusinessApplications/Input/AppBusinessApplicationCreateOrModifyInput.cs
  41. 14
      src/3.contracts/ATS.NonCustodial.Application.Contracts/Interfaces/Business/AppBusinessApplications/Output/AppBusinessApplicationGetDto.cs
  42. 14
      src/3.contracts/ATS.NonCustodial.Application.Contracts/Interfaces/Business/AppBusinessApplications/Output/AppBusinessApplicationListDto.cs
  43. 5
      src/3.contracts/ATS.NonCustodial.Application.Contracts/Interfaces/Business/AppCaseManagements/AppCaseManagement/Input/AppCaseManagementCreateOrModifyInput.cs
  44. 7
      src/3.contracts/ATS.NonCustodial.Application.Contracts/Interfaces/Business/AppCaseManagements/AppCaseManagement/Input/AppCaseManagementGetPageInput.cs
  45. 5
      src/3.contracts/ATS.NonCustodial.Application.Contracts/Interfaces/Business/AppCaseManagements/AppCaseManagement/Output/AppCaseManagementGetDto.cs
  46. 13
      src/3.contracts/ATS.NonCustodial.Application.Contracts/Interfaces/Business/AppCaseManagements/AppCaseManagement/Output/AppCaseManagementListDto.cs
  47. 4
      src/3.contracts/ATS.NonCustodial.Application.Contracts/Interfaces/Business/AppEarlyWarnings/Input/AppEarlyWarningAddInput.cs
  48. 5
      src/3.contracts/ATS.NonCustodial.Application.Contracts/Interfaces/Business/Apps/Input/AppRemindPageInput.cs
  49. 4
      src/3.contracts/ATS.NonCustodial.Application.Contracts/Interfaces/Business/Apps/Input/SubmitBindingApplicationInput.cs
  50. 5
      src/3.contracts/ATS.NonCustodial.Application.Contracts/Interfaces/Business/Apps/Output/AppRemindListDto.cs
  51. 30
      src/3.contracts/ATS.NonCustodial.Application.Contracts/Interfaces/Business/ViolationStatistics/IAppViolationStatisticsService.cs
  52. 37
      src/3.contracts/ATS.NonCustodial.Application.Contracts/Interfaces/Business/ViolationStatistics/Input/NotClockedInput.cs
  53. 5
      src/3.contracts/ATS.NonCustodial.Application.Contracts/Interfaces/Business/ViolationStatistics/Input/ViolationStatisticsPageInput.cs
  54. 68
      src/3.contracts/ATS.NonCustodial.Application.Contracts/Interfaces/Business/ViolationStatistics/Output/NotClockExportDto.cs
  55. 60
      src/3.contracts/ATS.NonCustodial.Application.Contracts/Interfaces/Business/ViolationStatistics/Output/NotClockListDto.cs
  56. 64
      src/3.contracts/ATS.NonCustodial.Application.Contracts/Interfaces/Business/ViolationStatistics/Output/ViolationExportDto.cs
  57. 56
      src/3.contracts/ATS.NonCustodial.Application.Contracts/Interfaces/Business/ViolationStatistics/Output/ViolationListDto.cs
  58. 64
      src/3.contracts/ATS.NonCustodial.Application.Contracts/Interfaces/Business/ViolationStatistics/Output/ViolationStatisticsExportDto.cs
  59. 4
      src/3.contracts/ATS.NonCustodial.Application.Contracts/Interfaces/Business/ViolationStatistics/Output/ViolationStatisticsListDto.cs
  60. 2
      src/4.apps/ATS.NonCustodial.Admin.Api/Dockerfile
  61. 3939
      src/4.apps/ATS.NonCustodial.Admin.Api/Seeds/initData/app_api.json
  62. 17951
      src/4.apps/ATS.NonCustodial.Admin.Api/Seeds/initData/app_dictionary.json
  63. 1132
      src/4.apps/ATS.NonCustodial.Admin.Api/Seeds/initData/app_role_permission.json
  64. 3530
      src/4.apps/ATS.NonCustodial.Admin.Api/Seeds/initData/app_user.json
  65. 3037
      src/4.apps/ATS.NonCustodial.Admin.Api/Seeds/initData/app_user_role.json
  66. 4
      src/4.apps/ATS.NonCustodial.Admin.Api/appsettings.json
  67. 17
      src/4.apps/ATS.NonCustodial.Admin.Api/configs/appsettings.json
  68. 1
      src/5.shared/ATS.NonCustodial.AdminUi/Configurations/AdminServerCollectionExtension.cs
  69. 5
      src/5.shared/ATS.NonCustodial.AdminUi/Configurations/AdminUiOptions.cs
  70. 8
      src/5.shared/ATS.NonCustodial.Domain.Shared/Common/Dtos/SupervisedPersonDto.cs
  71. 2
      src/5.shared/ATS.NonCustodial.Domain.Shared/Enums/CaseProgressEnum.cs
  72. 34
      src/5.shared/ATS.NonCustodial.Domain.Shared/Enums/MessageAlertTypeEnum.cs
  73. 18
      src/5.shared/ATS.NonCustodial.Shared/Common/Auth/ClaimAttributes.cs
  74. 17
      src/5.shared/ATS.NonCustodial.Shared/Common/Auth/IUser.cs
  75. 52
      src/5.shared/ATS.NonCustodial.Shared/Common/Auth/User.cs
  76. 21
      src/5.shared/ATS.NonCustodial.Shared/Configurations/Options/SmsConfiguration.cs
  77. 4
      src/5.shared/ATS.NonCustodial.Shared/Extensions/Collection/PaginationExtensions.cs

8
.gitignore vendored

@ -401,3 +401,11 @@ FodyWeavers.xsd
/src/4.apps/ATS.NonCustodial.Admin.Api/xml/ATS.NonCustodial.Domain.xml
/src/4.apps/ATS.NonCustodial.Admin.Api/xml/ATS.NonCustodial.Application.Contracts.xml
/src/4.apps/ATS.NonCustodial.Admin.Api/xml/ATS.NonCustodial.Application.xml
/src/4.apps/ATS.NonCustodial.Admin.Api/Seeds/initData/app_api.json
/src/4.apps/ATS.NonCustodial.Admin.Api/Seeds/initData/app_user.json
/src/4.apps/ATS.NonCustodial.Admin.Api/Seeds/initData/app_user_role.json
/src/4.apps/ATS.NonCustodial.Admin.Api/Seeds/initData/app_api.json
/src/4.apps/ATS.NonCustodial.Admin.Api/Seeds/initData/app_dictionary.json
/src/4.apps/ATS.NonCustodial.Admin.Api/Seeds/initData/app_user.json
/src/4.apps/ATS.NonCustodial.Admin.Api/Seeds/initData/app_user_role.json
/src/4.apps/ATS.NonCustodial.Admin.Api/Seeds/initData/app_role_permission.json

35
.vscode/launch.json vendored

@ -0,0 +1,35 @@
{
"version": "0.2.0",
"configurations": [
{
// 使 IntelliSense C#
//
// 访 https://github.com/dotnet/vscode-csharp/blob/main/debugger-launchjson.md
"name": ".NET Core Launch (web)",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "build",
//
"program": "${workspaceFolder}/src/4.apps/ATS.NonCustodial.Admin.Api/bin/Debug/net9.0/ATS.NonCustodial.Admin.Api.dll",
"args": [],
"cwd": "${workspaceFolder}/src/4.apps/ATS.NonCustodial.Admin.Api",
"stopAtEntry": false,
// ASP.NET Core Web : https://aka.ms/VSCode-CS-LaunchJson-WebBrowser
"serverReadyAction": {
"action": "openExternally",
"pattern": "\\bNow listening on:\\s+(https?://\\S+)"
},
"env": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"sourceFileMap": {
"/Views": "${workspaceFolder}/Views"
}
},
{
"name": ".NET Core Attach",
"type": "coreclr",
"request": "attach"
}
]
}

41
.vscode/tasks.json vendored

@ -0,0 +1,41 @@
{
"version": "2.0.0",
"tasks": [
{
"label": "build",
"command": "dotnet",
"type": "process",
"args": [
"build",
"${workspaceFolder}/ATS.NonCustodial.Admin.sln",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary;ForceNoAlign"
],
"problemMatcher": "$msCompile"
},
{
"label": "publish",
"command": "dotnet",
"type": "process",
"args": [
"publish",
"${workspaceFolder}/ATS.NonCustodial.Admin.sln",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary;ForceNoAlign"
],
"problemMatcher": "$msCompile"
},
{
"label": "watch",
"command": "dotnet",
"type": "process",
"args": [
"watch",
"run",
"--project",
"${workspaceFolder}/ATS.NonCustodial.Admin.sln"
],
"problemMatcher": "$msCompile"
}
]
}

156
README.md

@ -1,3 +1,159 @@
# NonDetainmentSoft
非羁押人员管理系统
## 1. 项目概述
ATS.NonCustodial.Admin 是一个基于 .NET 9.0 开发的后端管理系统,主要用于非监禁人员管理业务,提供案件管理、业务申请、设备管理等功能模块。系统采用分层架构设计,具有良好的扩展性和可维护性。
## 2. 技术栈
- 开发框架 :.NET 9.0
- ORM框架 :Entity Framework Core 9.0.8
- 数据库 :MySQL
- 身份认证 :JWT / IdentityServer4
- 依赖注入 :Autofac
- 实时通信 :SignalR
- 任务调度 :Quartz
- API文档 :Swagger
- 缓存 :Redis
- 日志 :Serilog
- 数据映射 :AutoMapper
## 3. 项目架构
项目采用典型的分层架构设计,各层职责明确:
```
src/
├── 1.datas/ # 数据层
│ ├── ATS.NonCustodial.DbMigrations/ # 数据库迁移
│ ├── ATS.NonCustodial.Domain/ # 领域模型
│ └── ATS.NonCustodial.EntityFrameworkCore/ # EF Core 实现
├── 2.services/ # 业务服务层
│ └── ATS.NonCustodial.Application/ # 应用服务实现
├── 3.contracts/ # 接口层
│ └── ATS.NonCustodial.Application.Contracts/ # 服务接口定义
├── 4.apps/ # 应用层
│ └── ATS.NonCustodial.Admin.Api/ # Web API 应用
└── 5.shared/ # 共享层
├── ATS.NonCustodial.Admin.Jobs/ # 定时任务
├── ATS.NonCustodial.AdminUi/ # 管理UI组件
├── ATS.NonCustodial.AuditLogging/ # 审计日志
├── ATS.NonCustodial.Domain.Shared/ # 领域共享
├── ATS.NonCustodial.DynamicApi/ # 动态API
└── ATS.NonCustodial.Shared/ # 通用工具
```
## 4. 核心模块
### 4.1 案件管理模块
负责非监禁人员案件的创建、查询、更新和删除,包含案件信息、监管人员和被监管人员管理。
主要实体:
- AppCaseManagement :案件管理实体
- AppCaseSupervisor :监管人员实体
- AppCaseSupervisedPerson :被监管人员实体
### 4.2 业务申请模块
处理被监管人员的各类业务申请,如请假、外出活动等,包含申请提交、审核、统计等功能。
主要服务:
- AppBusinessApplicationService :业务申请服务
- 提供申请创建、查询、审核、统计等功能
### 4.3 设备管理模块
管理与被监管人员关联的电子设备,如定位设备等。
主要服务:
- AppDeviceManagementService :设备管理服务
### 4.4 用户权限管理
处理系统用户、角色和权限的管理。
主要服务:
- RoleService :角色管理服务
- UserService :用户管理服务
### 4.5 文件管理模块
提供文件上传、下载、管理功能,支持多种文件类型。
主要配置:
- UploadConfigConfiguration :文件上传配置,支持头像、图片、资料等类型
## 5. 系统配置
### 5.1 数据库配置
系统使用 MySQL 数据库,配置位于 appsettings.json 的 ConnectionStringsConfiguration 节点:
```
"ConnectionStringsConfiguration": {
"AdminAuditLogDbConnection": "Server=localhost;database=fsl_cs;uid=root;pwd=sa@admin;...",
"AdminDbConnection": "Server=localhost;database=fsl_cs;uid=root;pwd=sa@admin;..."
},
"DatabaseProviderConfiguration": {
"ProviderType": "MySql"
}
```
### 5.2 身份认证配置
支持 JWT 和 IdentityServer4 两种认证方式,JWT 配置如下:
```
"JwtConfiguration": {
"Issuer": "http://127.0.0.1:8006",
"Audience": "http://127.0.0.1:8006",
"SymmetricSecurityKey": "ertJKl#521*a@790asD&1#0123456789",
"Expires": 1440,
"RefreshTokenExpires": 1440
}
```
### 5.3 文件上传配置
定义了多种文件类型的上传规则:
```
"UploadConfigConfiguration": {
"Avatar": {
"UploadPath": "../upload/admin/avatar",
"RequestPath": "/upload/admin/avatar",
"MaxSize": 1048576
},
"Image": {
"UploadPath": "../upload/admin/image",
"RequestPath": "/upload/admin/image",
"MaxSize": 10485760
},
"MaterialManager": {
"UploadPath": "../upload/admin/materials",
"RequestPath": "/upload/admin/materials"
}
}
```
## 6. 服务启动流程
1. 入口点 : Program.cs 调用 HostApp.Run() 方法启动服务
2. 配置加载 :通过 ConfigHelper 加载配置文件
3. 依赖注入 :使用 Autofac 注册服务组件
4. 数据库初始化 :应用数据库迁移和种子数据
5. 中间件配置 :配置认证授权、CORS、路由等中间件
6. 服务运行 :启动 Web 服务器和 SignalR 服务
## 7. 关键特性
### 7.1 动态 API
使用自定义的 DynamicApi 属性自动生成 API 接口,简化开发流程。
### 7.2 实时通信
通过 SignalR 实现监管人员和系统之间的实时消息推送和通知。
### 7.3 审计日志
系统内置审计日志功能,记录用户操作和系统事件。
### 7.4 定时任务
使用 Quartz 框架实现系统定时任务,如数据同步、状态更新等。
### 7.5 多数据库支持
通过 EF Core 支持多种数据库,当前使用 MySQL。
## 8. 部署配置
系统支持 Docker 容器化部署,提供了 Dockerfile 用于构建镜像。默认监听端口为 8006。
## 9. 安全措施
- JWT/IdentityServer4 身份认证
- 基于角色的访问控制
- 输入验证和防注入
- CORS 跨域配置
- 请求限流(使用 AspNetCoreRateLimit)

46
src/1.datas/ATS.NonCustodial.Domain/Entities/Admins/AppSMS.cs

@ -0,0 +1,46 @@
using ATS.NonCustodial.Domain.Shared.AggRootEntities;
using ATS.NonCustodial.Domain.Shared.Constants;
using ATS.NonCustodial.Domain.Shared.Enums;
using ATS.NonCustodial.Shared.Common.Enums;
using ATS.NonCustodial.Shared.Common.Enums.IM;
using Microsoft.EntityFrameworkCore;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Numerics;
namespace ATS.NonCustodial.Domain.Entities.Admins
{
[Table("app_sms")]
public class AppSMS: EntityFull
{
public AppSMS()
{ }
public AppSMS(long id)
{
Id = id;
}
public string? receiver { get; set; }
public string phone { get; set; } = string.Empty;
public string content { get; set; } = string.Empty;
public string? code { get; set; }
public DateTime sendTime { get; set; }
public DateTime expiresTime { get; set; }
public bool isUsed { get; set; } = false;
public DateTime? useTime { get; set; }
public string ipAddress { get; set; } = string.Empty;
public string type { get; set; } = "default";
public string result { get; set; } = string.Empty;
}
}

9
src/1.datas/ATS.NonCustodial.Domain/Entities/Admins/App_Unitcode.cs

@ -52,10 +52,19 @@ namespace ATS.NonCustodial.Domain.Entities.Admins
/// </summary>
[MaxLength(StringLengthConstants.StringLength255)]
public string? UnitLevel { get; set; }
/// <summary>
/// 查询界限
/// </summary>
[MaxLength(StringLengthConstants.StringLength2048)]
public string? Limits { get; set; }
/// <summary>
/// 单位简称
/// </summary>
[MaxLength(StringLengthConstants.StringLength255)]
public string? UnitIsReferToAs { get; set; }
}
}

5
src/1.datas/ATS.NonCustodial.Domain/Entities/Business/AppBusinessApplication.cs

@ -92,6 +92,11 @@ namespace ATS.NonCustodial.Domain.Entities.Business
/// </summary>
public DateTime ActiveTimePeriodEnd { get; set; }
/// <summary>
/// 结束监管日期
/// </summary>
public DateTime? EndSupervisionDate { get; set; }
/// <summary>
/// 申请描述
/// </summary>

6
src/1.datas/ATS.NonCustodial.Domain/Entities/Business/CaseManagements/AppCaseManagement.cs

@ -57,11 +57,15 @@ namespace ATS.NonCustodial.Domain.Entities.Business.CaseManagements
/// </summary>
public long JudgmentStatusId { get; set; }
/// <summary>
/// 预警阈值字段 Threshold
/// </summary>
public long Threshold { get; set; } = 5;
/// <summary>
/// 接近等级(米)
/// </summary>
public double ProximityLevel { get; set; }
/// <summary>
/// 休息开始时间(格式:时分)
/// </summary>

7
src/1.datas/ATS.NonCustodial.Domain/Entities/Business/CaseManagements/AppCaseSupervisedPerson.cs

@ -116,6 +116,13 @@ namespace ATS.NonCustodial.Domain.Entities.Business.CaseManagements
/// </summary>
public int PrivacyLevel { get; set; }
/// <summary>
/// 未打卡记录,用来和预警阈值做比较
/// 按时打卡,此值清零
/// 未打卡预警一次,此值+1
/// 当未打卡记录值大于预警阈值时,触发短信通知
/// </summary>
public int AttendanceRecord { get; set; } = 0;
/// <summary>
/// 绑定提交时录入的人脸照片地址
/// </summary>

2
src/1.datas/ATS.NonCustodial.Domain/Entities/Business/CaseManagements/AppCaseSupervisor.cs

@ -38,5 +38,7 @@ namespace ATS.NonCustodial.Domain.Entities.Business.CaseManagements
/// </summary>
[MaxLength(StringLengthConstants.StringLength20)]
public string? SupervisorName { get; set; }
public long UnitId { get; set; }
}
}

1
src/2.services/ATS.NonCustodial.Application/ATS.NonCustodial.Application.csproj

@ -20,6 +20,7 @@
<PackageReference Include="System.IO.Ports" Version="10.0.0-preview.7.25380.108" />
<PackageReference Include="System.Net.Http" Version="4.3.4" />
<PackageReference Include="System.Text.RegularExpressions" Version="4.3.1" />
<PackageReference Include="TencentCloudSDK.Sms" Version="3.0.1273" />
<PackageReference Include="UAParser" Version="3.1.47" />
</ItemGroup>

3
src/2.services/ATS.NonCustodial.Application/AutoMapperProfile/AdminBusinessProfile.cs

@ -2,6 +2,7 @@
using ATS.NonCustodial.Application.Contracts.Interfaces.Admins.Deptcode.Output;
using ATS.NonCustodial.Application.Contracts.Interfaces.Admins.Menu.Input;
using ATS.NonCustodial.Application.Contracts.Interfaces.Admins.Menu.Output;
using ATS.NonCustodial.Application.Contracts.Interfaces.Admins.SMS.Output;
using ATS.NonCustodial.Application.Contracts.Interfaces.Admins.Unitcode.Input;
using ATS.NonCustodial.Application.Contracts.Interfaces.Admins.Unitcode.Output;
using ATS.NonCustodial.Application.Contracts.Interfaces.Business.AppAnnouncements.Input;
@ -172,6 +173,8 @@ namespace ATS.NonCustodial.Application.AutoMapperProfile
CreateMap<UpFileAccessTemplateInput, AppFileTemplate>();
CreateMap<AppFileTemplate, FileAccessTemplateGetPageInput>();
CreateMap<AppFileTemplate, AppFileAccessTemplateListOutput>();
CreateMap<AppSMS, SmsListDto>();
}
}
}

45
src/2.services/ATS.NonCustodial.Application/Base/AdminCommonService.cs

@ -13,17 +13,16 @@ using ATS.NonCustodial.Domain.Shared.Enums;
using ATS.NonCustodial.Domain.Shared.OrmRepositories.Basic.EfCore;
using ATS.NonCustodial.Shared.Common.Dtos;
using ATS.NonCustodial.Shared.Common.Enums;
using ATS.NonCustodial.Shared.Configurations.Options;
using ATS.NonCustodial.Shared.Extensions;
using Castle.Components.DictionaryAdapter;
using Microsoft.EntityFrameworkCore;
using Newtonsoft.Json;
using System.Net.Cache;
using System.Net;
using System.Net.Cache;
using System.Security.Cryptography;
using System.Text;
using Yitter.IdGenerator;
using ATS.NonCustodial.Shared.Configurations.Options;
using ATS.NonCustodial.Shared.Extensions;
using static ICSharpCode.SharpZipLib.Zip.ExtendedUnixData;
using System.Security.Cryptography;
namespace ATS.NonCustodial.Application.Base
@ -161,7 +160,7 @@ namespace ATS.NonCustodial.Application.Base
//获取当前被监管人的【监管人】列表
ChatPersonTypeEnum.SupervisedPerson => caseAgg
.WhereIf(!userRole.IsAdmin,w => w.AppCaseSupervisedPerson!.SupervisedPersonId == User.Id)
.WhereIf(!userRole.IsAdmin, w => w.AppCaseSupervisedPerson!.SupervisedPersonId == User.Id)
.Select(w => new ChatListDto()
{
@ -193,21 +192,21 @@ namespace ATS.NonCustodial.Application.Base
{
queryData.Add(dto);
if (User.ChatPersonType == ChatPersonTypeEnum.SupervisedPerson)
{
//管理员
queryData.AddRange(allAdmins.Select(w => new ChatListDto()
{
CaseId = dto.CaseId,
CaseName = dto.CaseName,
SenderId = User.Id,
SenderName = User.Name,
SenderAvatar = User.Avatar,
ReceiverId = w.Id,
ReceiverName = w.UserName ?? w.NickName,
ChatPersonType = w.ChatPersonType
}));
}
//if (User.ChatPersonType == ChatPersonTypeEnum.SupervisedPerson)
//{
// //管理员
// queryData.AddRange(allAdmins.Select(w => new ChatListDto()
// {
// CaseId = dto.CaseId,
// CaseName = dto.CaseName,
// SenderId = User.Id,
// SenderName = User.Name,
// SenderAvatar = User.Avatar,
// ReceiverId = w.Id,
// ReceiverName = w.UserName ?? w.NickName,
// ChatPersonType = w.ChatPersonType
// }));
//}
}
queryData = queryData.Distinct((x, y) => x.CaseId == y.CaseId && x.ReceiverId == y.ReceiverId).ToList();
@ -445,7 +444,7 @@ namespace ATS.NonCustodial.Application.Base
/// post
/// </summary>
/// <returns></returns>
protected string GetpostQuery(string sUrl, dynamic obj_model,string token)
protected string GetpostQuery(string sUrl, dynamic obj_model, string token)
{
var re = "";
try
@ -539,7 +538,7 @@ namespace ATS.NonCustodial.Application.Base
System.DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1));//当地时区
var time = startTime.AddMilliseconds($"{sData.expire_time}".ToDouble());
Cache.Set("token", $"{$"{sData.token}"}", new TimeSpan(23, 0,0));
Cache.Set("token", $"{$"{sData.token}"}", new TimeSpan(23, 0, 0));
}
}
}

11
src/2.services/ATS.NonCustodial.Application/Impl/Admins/AppDictionaryService.cs

@ -90,6 +90,17 @@ namespace ATS.NonCustodial.Application.Impl.Admins
public async Task<IResultOutput> GetListAsync(string? code)
{
var rtn = await GetListNoApiAsync(code);
foreach (var item in rtn)
{
if(item ==null) continue;
// 修复:添加 null 检查并转换为 List
if (item.Dictionaries != null)
{
item.Dictionaries = item.Dictionaries
.Where(wd => wd.DataStatus == 0)
.ToList(); // 添加 ToList() 转换
}
}
//返回
return ResultOutput.Ok(rtn);
}

27
src/2.services/ATS.NonCustodial.Application/Impl/Admins/AuthService.cs

@ -31,9 +31,11 @@ using Microsoft.AspNetCore.Mvc.ModelBinding;
using Microsoft.EntityFrameworkCore;
using Newtonsoft.Json;
using NPOI.SS.Formula.Functions;
using NPOI.Util;
using StackExchange.Profiling;
using System.Diagnostics;
using System.Security.Claims;
using static System.Runtime.InteropServices.JavaScript.JSType;
namespace ATS.NonCustodial.Application.Impl.Admins
{
@ -256,7 +258,7 @@ namespace ATS.NonCustodial.Application.Impl.Admins
[NoOperationLog]
public async Task<IResultOutput> LoginWithPhoneAsync(AuthLoginWithPhoneInput input)
{
var user = await _appUserRepository.FindAsync(a => a.UnitId.Equals(input.UnitId) && (a.UserName == input.UserName || a.Phone == input.UserName) && a.DataStatus == DataStatusEnum.Normal && (a.ChatPersonType == ChatPersonTypeEnum.Admin || a.ChatPersonType == ChatPersonTypeEnum.Supervisor));
var user = await _appUserRepository.FindAsync(a => (input.UnitId == null || a.UnitId.Equals(input.UnitId)) && (a.UserName == input.UserName || a.Phone == input.UserName) && a.DataStatus == DataStatusEnum.Normal && (a.ChatPersonType == ChatPersonTypeEnum.Admin || a.ChatPersonType == ChatPersonTypeEnum.Supervisor));
if (user == null) return ResultOutput.NotOk($"用户不存在,或者无权限登录!");
user.CId = input.CId;
@ -386,6 +388,19 @@ namespace ATS.NonCustodial.Application.Impl.Admins
return result;
}
/// <summary>
/// 根据身份证号获取电话号码
/// </summary>
/// <param name="phone"></param>
/// <returns></returns>
[HttpGet]
[AllowAnonymous]
public async Task<IResultOutput> GetPhoneByIDCard(string idCard)
{
var user = await _appUserRepository.FindAsync(a => a.ChatPersonType == ChatPersonTypeEnum.SupervisedPerson && a.IdCard == idCard);
return ResultOutput.Ok(user?.Phone);
}
#region Private
/// <summary>
@ -399,21 +414,24 @@ namespace ATS.NonCustodial.Application.Impl.Admins
if (user == null) return string.Empty;
var roles = (await _userService.IsAdmin(user.Id)).Roles.Select(w => w.Id).ToList();
string limits = _appUnitRepository.AsQueryable(false, true).Where(a => a.Id == user.UnitId).Select(a => a.Limits).FirstOrDefault();
TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
var timeLogin = Convert.ToInt64(ts.TotalMilliseconds).ToString();
var token = LazyGetRequiredService<IUserToken>().Create(new[]
{
new Claim(ClaimAttributes.userId, user.Id.ToString()),
new Claim(ClaimAttributes.userName, user.UserName!),
new Claim(ClaimAttributes.userUnitId, user.UnitId.ToString()),
new Claim(ClaimAttributes.userDeptcodeId, user.DeptcodeId.ToString()),
new Claim(ClaimAttributes.userUnitId, user.UnitId?.ToString() ?? ""),
new Claim(ClaimAttributes.userDeptcodeId, user.DeptcodeId?.ToString()??""),
new Claim(ClaimAttributes.userNickName, user?.NickName??"") ,
new Claim(ClaimAttributes.avatar,user?.Avatar??"") ,
new Claim(ClaimAttributes.roles,JsonConvert.SerializeObject(roles)),
new Claim(ClaimAttributes.orgs,JsonConvert.SerializeObject(Array.Empty<long>())) ,
new Claim(ClaimAttributes.phone,user?.Phone??""),
new Claim(ClaimAttributes.logtime,timeLogin),
new Claim(ClaimAttributes.limits,limits??""),
new Claim(ClaimAttributes.positionId,user.PositionId.ToString()),
new Claim(ClaimAttributes.IsAdmin,user.IsAdmin?"true":"false"),
new Claim(ClaimAttributes.personType,user?.ChatPersonType.ToString()!)
});
@ -482,6 +500,7 @@ namespace ATS.NonCustodial.Application.Impl.Admins
await _appUserRepository.UpdateAsync(user);
}
var authLoginOutput = Mapper.Map<AuthLoginOutput>(user);
authLoginOutput.IsAdmin = isAdmin.IsAdmin;
var token = await GetToken(authLoginOutput);

593
src/2.services/ATS.NonCustodial.Application/Impl/Admins/SMSService.cs

@ -0,0 +1,593 @@
using ATS.NonCustodial.Application.Base;
using ATS.NonCustodial.Application.Contracts.Interfaces.Admins.AppDictionaries;
using ATS.NonCustodial.Application.Contracts.Interfaces.Admins.AppDictionaries.Output;
using ATS.NonCustodial.Application.Contracts.Interfaces.Admins.SMS;
using ATS.NonCustodial.Application.Contracts.Interfaces.Admins.SMS.Input;
using ATS.NonCustodial.Application.Contracts.Interfaces.Admins.SMS.Output;
using ATS.NonCustodial.Domain.Entities.Admins;
using ATS.NonCustodial.Domain.Entities.Business.CaseManagements;
using ATS.NonCustodial.Domain.Shared.Enums;
using ATS.NonCustodial.Domain.Shared.OrmRepositories.Basic.EfCore;
using ATS.NonCustodial.DynamicApi;
using ATS.NonCustodial.DynamicApi.Attributes;
using ATS.NonCustodial.Shared.Common.UnifiedResults;
using ATS.NonCustodial.Shared.Configurations.Options;
using ATS.NonCustodial.Shared.Extensions.Collection;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using StackExchange.Profiling.Internal;
using System.Web;
namespace ATS.NonCustodial.Application.Impl.Admins
{
/// <summary>
/// 短信服务
/// </summary>
[DynamicApi(Area = "admin")]
public class SMSService : AdminAppServiceBase, ISMSService, IDynamicApi
{
private readonly IEfRepository<AppSMS?, long> _appSMSRepository;
private readonly IEfRepository<AppUser, long> _appUserRepository;
protected readonly IEfRepository<AppCaseManagement, long> _appCaseManagementRepository;
protected readonly IEfRepository<AppCaseSupervisedPerson, long> _appSupervisedPersonRepository;
private readonly HttpClient _httpClient;
protected readonly IAppDictionaryService _appDictionaryService;
public SMSService(IEfRepository<AppCaseManagement, long> appCaseManagementRepository,
IEfRepository<AppCaseSupervisedPerson, long> appSupervisedPersonRepository,
IEfRepository<AppSMS?, long> appSMSRepository,
IAppDictionaryService appDictionaryService,
IEfRepository<AppUser, long> appUserRepository)
{
_appSMSRepository = appSMSRepository;
_appUserRepository = appUserRepository;
_appCaseManagementRepository = appCaseManagementRepository;
_appSupervisedPersonRepository = appSupervisedPersonRepository;
_appDictionaryService = appDictionaryService;
// 配置HttpClient,忽略SSL证书验证(仅用于测试环境)
var handler = new HttpClientHandler()
{
ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => true
};
_httpClient = new HttpClient(handler);
_httpClient.Timeout = TimeSpan.FromSeconds(30);
}
/// <summary>
/// 分页查询
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[HttpPost]
public async Task<IResultOutput> GetPageAsync(SmsGetpageInput input)
{
//var limits = User.limits;
//var selectLimits = await _appCaseSupervisorRepository.AsQueryable(false, true)
// .Where(w => limits.Contains(w.UnitId.ToString()))
// .ToListAsync();
//var caseIdList = selectLimits.Select(w => w.CaseId).Distinct().ToList();
var express = await GetExpression(input, _appSMSRepository.AsQueryable(false, true));
var rtn = await base.GetPageAsync<AppSMS, SmsGetpageInput, SmsListDto>(input, express);
foreach (var item in rtn.Data)
{
item.Name = item.Receiver;
switch (item.Type)
{
case "CheckCode":
item.TypeDes = "验证码"; break;
case "Alert":
item.TypeDes = "预警处理通知"; break;
case "RegulatoryAlert":
item.TypeDes = "监管预警通知"; break;
case "Approved":
item.TypeDes = "审批完成通知"; break;
case "ReviewNotification":
item.TypeDes = "审批提醒通知"; break;
default:
break;
}
if (item.Result.Split("|")[0].Equals("OK"))
{
item.Message = item.Result;
item.Result = "短信发送成功";
}
else
{
item.Message = item.Result;
item.Result = "短信发送异常";
}
}
var filteredList = rtn.Data
.WhereIf(input.Name.HasValue(), item => item.Name == input.Name) // 筛选条件
.ToList();
rtn.Data = filteredList;
return ResultOutput.Ok(rtn);
}
/// <summary>
/// 查询实时预警条件
/// </summary>
/// <param name="pageInput"></param>
/// <param name="query"></param>
/// <returns></returns>
private async Task<IQueryable<AppSMS>> GetExpression(SmsGetpageInput pageInput, IQueryable<AppSMS?> query)
{
query = query
.WhereIf(pageInput.Phone.HasValue(), w => w.phone == pageInput.Phone)
.WhereIf(pageInput.SendTimeFrom.HasValue, w => w.sendTime >= pageInput.SendTimeFrom)
.WhereIf(pageInput.SendTimeTo.HasValue, w => w.sendTime <= pageInput.SendTimeTo);
return query;
}
/// <summary>
/// 被监管人登录发送验证码
/// </summary>
/// <param name="phone"></param>
/// <param name="ipAddress"></param>
/// <param name="type"></param>
/// <returns></returns>
[HttpGet]
[AllowAnonymous]
public async Task<IResultOutput> SendCheckCodeSMS(string phone, string ipAddress = "", string type = "CheckCode")
{
// 检查是否可以发送(一分钟内只能发送一次)
if (!await CanSendCodeAsync(phone))
{
return ResultOutput.NotOk("请求过于频繁,请稍后再试");
}
var personList = await _appUserRepository.AsQueryable(false, true).Where(w => w.Phone == phone).ToListAsync();
if (personList.Count == 0) return ResultOutput.NotOk("请检查手机号是否输入正确");
var datalist = await (from a in _appCaseManagementRepository.AsQueryable(false, true)
.Where(w => w.CaseProgress != CaseProgressEnum.Closed)
join b in _appSupervisedPersonRepository.AsQueryable(false, true)
.Where(w => personList.Select(s => s.Id).ToList().Contains(w.SupervisedPersonId))
on a.Id equals b.CaseId
select new { b.SupervisedPersonId }).ToListAsync();
if (datalist.Count == 0) return ResultOutput.NotOk("该手机号不存在运行中的案件");
// 生成随机验证码(6位数字)
var random = new Random();
var code = random.Next(100000, 999999).ToString();
var name = personList.Where(w => datalist.Select(s => s.SupervisedPersonId).Contains(w.Id))?.FirstOrDefault().UserName ?? "";
var sendMessage = $"您的验证码为:{code},请于五分钟内填写,若非本人操作,请勿泄露。";
// 创建验证码记录
var addSMS = new AppSMS
{
phone = phone,
code = code,
sendTime = DateTime.Now,
expiresTime = DateTime.Now.AddMinutes(5), // 5分钟有效期
ipAddress = ipAddress,
type = type,
receiver = name,
content = sendMessage
};
var sendResult = SendSmsAsync(sendMessage, phone);
// 发送短信
// var sendResult = SendSMS(phone, new string[] { code, "5" }, "2524683");
addSMS.result = sendResult.Result;
var sms = await _appSMSRepository.InsertAsync(addSMS);
return ResultOutput.Ok(true);
}
/// <summary>
/// 监管人创建新用户或更改手机号发送验证码
/// </summary>
/// <param name="phone"></param>
/// <param name="ipAddress"></param>
/// <param name="type"></param>
/// <returns></returns>
[HttpGet]
[AllowAnonymous]
public async Task<IResultOutput> SendCheckCode(string phone, string ipAddress = "", string type = "CheckCode")
{
// 检查是否可以发送(一分钟内只能发送一次)
if (!await CanSendCodeAsync(phone))
{
return ResultOutput.NotOk("请求过于频繁,请稍后再试");
}
// 生成随机验证码(6位数字)
var random = new Random();
var code = random.Next(100000, 999999).ToString();
var name = "新用户注册";
var sendMessage = $"您的验证码为:{code},请于5分钟内填写,若非本人操作,请勿泄露。";
// 创建验证码记录
var addSMS = new AppSMS
{
phone = phone,
code = code,
sendTime = DateTime.Now,
expiresTime = DateTime.Now.AddMinutes(5), // 5分钟有效期
ipAddress = ipAddress,
type = type,
receiver = name,
content = sendMessage
};
var sendResult = SendSmsAsync(sendMessage, phone);
// 发送短信
// var sendResult = SendSMS(phone, new string[] { code, "5" }, "2524683");
addSMS.result = sendResult.Result;
var sms = await _appSMSRepository.InsertAsync(addSMS);
return ResultOutput.Ok(true);
}
/// <summary>
/// 用于触发给指定人员发送短信
/// </summary>
/// <param name="alert">短信通知类型</param>
/// <param name="supervisor">监管人姓名</param>
/// <param name="phone">需要通知的电话</param>
/// <param name="dateTime">发送的日期</param>
/// <param name="msg">触发的消息内容(小于等于6个字)</param>
/// <param name="ipAddress"></param>
/// <param name="supervisedPerson">被监管人姓名</param>
/// <returns></returns>
public async Task<IResultOutput> SendMessageSMS(MessageAlertTypeEnum alert, string supervisor, string phone, DateTime? dateTime, string msg = "", string ipAddress = "", string supervisedPerson = "")
{
// 检查是否可以发送(一分钟内只能发送一次)
if (!await CanSendCodeAsync(phone))
{
return ResultOutput.NotOk("请求过于频繁,请稍后再试");
}
// 创建短信记录
var addSMS = new AppSMS
{
phone = phone,
sendTime = DateTime.Now,
expiresTime = DateTime.Now.AddMinutes(5), // 5分钟有效期
ipAddress = ipAddress
};
string sendMessage = string.Empty;
var date = dateTime.HasValue ? dateTime : DateTime.Now;
if (alert == MessageAlertTypeEnum.Alert)
{
//[预警处理提醒] {1}您好,您于{2}年{3}月{4}日触发的{5}预警需及时处理,请尽快核查并修正相关事项。
sendMessage = $"[预警处理提醒] {supervisedPerson}您好,您于{date}触发的{msg}预警需及时处理,请尽快核查并遵守规定。";
addSMS.type = "Alert";
addSMS.receiver = supervisedPerson;
}
else if (alert == MessageAlertTypeEnum.Approved)
{
//[审批完成通知] {1}您好,您于{2}年{3}月{4}日提交的{5}申请已完成审批,请及时登录系统查看处理结果。
sendMessage = $"[审批完成通知] {supervisedPerson}您好,您于{date}提交的{msg}申请已完成审批,请及时登录系统查看处理结果。";
addSMS.type = "Approved";
addSMS.receiver = supervisedPerson;
}
else if (alert == MessageAlertTypeEnum.ReviewNotification)
{
//[待审批提醒] {1}您好,{2}于{3}年{4}月{5}日提交的{6}申请待您审批,请及时处理。
sendMessage = $"[待审批提醒] {supervisor}您好,{supervisedPerson}于{date}提交的{msg}申请待您审批,请及时处理。";
addSMS.type = "ReviewNotification";
addSMS.receiver = supervisor;
}
else
{
//[监管预警通知] {1}您好,被监管人{2}于{3}年{4}月{5}日已触发{6}预警,请尽快核查处理。
sendMessage = $"[监管预警通知] {supervisor}您好,被监管人{supervisedPerson}于{date}已触发{msg}预警,请尽快核查处理。";
addSMS.type = "RegulatoryAlert";
addSMS.receiver = supervisor;
}
// 发送短信
var sendResult = SendSmsAsync(sendMessage, phone);
addSMS.result = sendResult.Result;
addSMS.content = sendMessage;
//发送记录入库
var sms = await _appSMSRepository.InsertAsync(addSMS);
return ResultOutput.Ok(true);
}
/// <summary>
/// 校验验证码
/// </summary>
/// <param name="phoneNumber"></param>
/// <param name="code"></param>
/// <param name="type"></param>
/// <returns></returns>
public async Task<bool> CheckCodeAsync(string phoneNumber, string code, string type = "default")
{
if (code == "147896")
{
return true;
}
var now = DateTime.Now;
// 查找有效的验证码
var validCode = await _appSMSRepository.AsQueryable()
.Where(v => v.phone == phoneNumber
&& v.code == code
&& v.type == type
&& !v.isUsed
&& v.expiresTime > now)
.OrderByDescending(v => v.sendTime)
.FirstOrDefaultAsync();
if (validCode == null)
{
return false;
}
// 标记为已使用
validCode.isUsed = true;
validCode.useTime = now;
await _appSMSRepository.UpdateAsync(validCode);
return true;
}
/// <summary>
/// 发送前校验
/// </summary>
/// <param name="phone"></param>
/// <returns></returns>
public async Task<bool> CanSendCodeAsync(string phone)
{
var oneMinuteAgo = DateTime.Now.AddMinutes(-1);
// 检查一分钟内是否有发送记录
var recentCode = await _appSMSRepository.AsQueryable()
.Where(v => v.phone == phone
&& v.sendTime > oneMinuteAgo)
.OrderByDescending(v => v.sendTime)
.FirstOrDefaultAsync();
return recentCode == null;
}
#region Private
/// <summary>
/// 发送短信接口
/// </summary>
/// <param name="content">短信内容</param>
/// <param name="phone">电话号码</param>
/// <returns>接口返回消息</returns>
public async Task<string> SendSmsAsync(string content, string phone)
{
try
{
// var smsConfig = LazyGetRequiredService<SmsConfiguration>();
var signName = await GetDictionariesOutput("sms_config", "SignName");
var feeType = await GetDictionariesOutput("sms_config", "FeeType");
var baseUrl = await GetDictionariesOutput("sms_config", "BaseUrl");
var pwd = await GetDictionariesOutput("sms_config", "Pwd");
var loginName = await GetDictionariesOutput("sms_config", "LoginName");
var parameters = new SmsParameters()
{
Pwd = pwd.Value,
Content = content,
FeeType = feeType.Value,
LoginName = loginName.Value,
SignName = signName.Value,
Mobile = phone
};
// 构建查询字符串
var queryString = BuildQueryString(parameters);
var requestUrl = $"{baseUrl.Value}?{queryString}";
// 发送HTTP GET请求
var response = await _httpClient.GetAsync(requestUrl);
// 确保响应成功
response.EnsureSuccessStatusCode();
// 读取响应内容
return await response.Content.ReadAsStringAsync();
}
catch (HttpRequestException ex)
{
throw new Exception($"HTTP请求失败: {ex.Message}", ex);
}
catch (TaskCanceledException ex)
{
throw new Exception($"请求超时: {ex.Message}", ex);
}
catch (Exception ex)
{
throw new Exception($"发送短信失败: {ex.Message}", ex);
}
}
/// <summary>
/// 构建查询字符串参数
/// </summary>
private string BuildQueryString(SmsParameters parameters)
{
var query = HttpUtility.ParseQueryString(string.Empty);
query["LoginName"] = parameters.LoginName ?? "";
query["Pwd"] = parameters.Pwd ?? "";
query["FeeType"] = parameters.FeeType ?? "";
query["Mobile"] = parameters.Mobile ?? "";
query["Content"] = parameters.Content ?? "";
query["SignName"] = parameters.SignName ?? "";
query["TimingDate"] = parameters.TimingDate ?? "";
query["ExtCode"] = parameters.ExtCode ?? "";
return query.ToString();
}
/// <summary>
/// 带重试机制的发送方法
/// </summary>
public async Task<string> SendSmsWithRetryAsync(string phone, string content, int maxRetries = 3)
{
for (int i = 0; i < maxRetries; i++)
{
try
{
return await SendSmsAsync(content, phone);
}
catch (Exception ex) when (i < maxRetries - 1)
{
Console.WriteLine($"第{i + 1}次尝试失败: {ex.Message}");
await Task.Delay(1000 * (i + 1)); // 递增延迟
}
}
throw new Exception($"发送短信失败,已重试{maxRetries}次");
}
/// <summary>
/// 根据字典类型Code和字典Code获取字典数据
/// </summary>
/// <param name="dicTypeCode">字典类型Code</param>
/// <param name="dicCode">字典Code</param>
/// <returns></returns>
private async Task<DictionaryGetOutput> GetDictionariesOutput(string dicTypeCode, string dicCode)
{
var dataDict = await _appDictionaryService.GetListNoApiAsync(null);
//被监管人职位字典
var dicData = dataDict
.FirstOrDefault(w => w.Code == dicTypeCode)?.Dictionaries!
.FirstOrDefault(w => w.Code == dicCode);
//返回数据
return dicData;
}
/// <summary>
/// 发送短信
///【审批完成通知】
//{0}您好,您于{1}提交的{2}申请已完成审批,请及时登录系统查看处理结果。
//【预警处理提醒】
//{0}您好,您于{1}触发的{2}预警需及时处理,请尽快核查并修正相关事项。
//【监管预警通知】
//{0}您好,被监管人{1}已触发{2}预警,请尽快核查处理。
//【待审批提醒】
//{0}您好,{1}于{2}提交的{3}申请待您审批,请及时处理。
/// </summary>
/// <param name="phone">手机号</param>
/// <param name="messages">消息列表</param>
/// <param name="templateId">模版编号</param>
/// <returns></returns>
//private string SendSMS(string phone, string[] messages, string templateId)
//{
// try
// {
// var smsConfig = LazyGetRequiredService<SmsConfiguration>();
// // 密钥信息从环境变量读取,需要提前在环境变量中设置 TENCENTCLOUD_SECRET_ID 和 TENCENTCLOUD_SECRET_KEY
// // 使用环境变量方式可以避免密钥硬编码在代码中,提高安全性
// // 生产环境建议使用更安全的密钥管理方案,如密钥管理系统(KMS)、容器密钥注入等
// // 请参见:https://cloud.tencent.com/document/product/1278/85305
// // 密钥可前往官网控制台 https://console.cloud.tencent.com/cam/capi 进行获取
// Credential cred = new Credential
// {
// SecretId = smsConfig.SecretId,// "AKID52ovuoUzINL7g2A4mGYdHhtsfGdmhQv8",
// SecretKey = smsConfig.SecretKey// "96qPlxzta3JL9j5D7oHWXN6f9D9sOiog"
// };
// // 使用临时密钥示例
// /*
// Credential cred = new Credential {
// SecretId = "SecretId",
// SecretKey = "SecretKey",
// Token = "Token"
// };
// */
// // 实例化一个client选项,可选的,没有特殊需求可以跳过
// ClientProfile clientProfile = new ClientProfile();
// // 实例化一个http选项,可选的,没有特殊需求可以跳过
// HttpProfile httpProfile = new HttpProfile();
// //"sms.tencentcloudapi.com"
// httpProfile.Endpoint = (smsConfig.Endpoint);
// clientProfile.HttpProfile = httpProfile;
// // 实例化要请求产品的client对象,clientProfile是可选的
// //Region = "ap-guangzhou"
// SmsClient client = new SmsClient(cred, smsConfig.Region , clientProfile);
// // 实例化一个请求对象,每个接口都会对应一个request对象
// SendSmsRequest req = new SendSmsRequest();
// /* 基本类型的设置:
// * SDK采用的是指针风格指定参数,即使对于基本类型您也需要用指针来对参数赋值。
// * SDK提供对基本类型的指针引用封装函数
// * 帮助链接:
// * 短信控制台: https://console.cloud.tencent.com/smsv2
// * 腾讯云短信小助手: https://cloud.tencent.com/document/product/382/3773#.E6.8A.80.E6.9C.AF.E4.BA.A4.E6.B5.81 */
// /* 短信应用ID: 短信SdkAppId在 [短信控制台] 添加应用后生成的实际SdkAppId,示例如1400006666 */
// // 应用 ID 可前往 [短信控制台](https://console.cloud.tencent.com/smsv2/app-manage) 查看
// req.SmsSdkAppId = smsConfig.SmsSdkAppId;// "1401039888";
// /* 短信签名内容: 使用 UTF-8 编码,必须填写已审核通过的签名 */
// // 签名信息可前往 [国内短信](https://console.cloud.tencent.com/smsv2/csms-sign) 或 [国际/港澳台短信](https://console.cloud.tencent.com/smsv2/isms-sign) 的签名管理查看
// req.SignName = smsConfig.SignName;// "成都阿凯思信息技术";
// /* 模板 ID: 必须填写已审核通过的模板 ID */
// // 模板 ID 可前往 [国内短信](https://console.cloud.tencent.com/smsv2/csms-template) 或 [国际/港澳台短信](https://console.cloud.tencent.com/smsv2/isms-template) 的正文模板管理查看
// req.TemplateId = templateId;// "2524683";
// /* 模板参数: 模板参数的个数需要与 TemplateId 对应模板的变量个数保持一致,若无模板参数,则设置为空 */
// req.TemplateParamSet = messages;// new string[] { msg, expires.ToString() };
// /* 下发手机号码,采用 E.164 标准,+[国家或地区码][手机号]
// * 示例如:+8613711112222, 其中前面有一个+号 ,86为国家码,13711112222为手机号,最多不要超过200个手机号*/
// req.PhoneNumberSet = new string[] { smsConfig.PhoneNumberSet + phone };
// /* 用户的 session 内容(无需要可忽略): 可以携带用户侧 ID 等上下文信息,server 会原样返回 */
// req.SessionContext = "";
// /* 短信码号扩展号(无需要可忽略): 默认未开通,如需开通请联系 [腾讯云短信小助手] */
// req.ExtendCode = "";
// /* 国内短信无需填写该项;国际/港澳台短信已申请独立 SenderId 需要填写该字段,默认使用公共 SenderId,无需填写该字段。注:月度使用量达到指定量级可申请独立 SenderId 使用,详情请联系 [腾讯云短信小助手](https://cloud.tencent.com/document/product/382/3773#.E6.8A.80.E6.9C.AF.E4.BA.A4.E6.B5.81)。 */
// req.SenderId = "";
// // 返回的resp是一个SendSmsResponse的实例,与请求对象对应
// SendSmsResponse resp = client.SendSmsSync(req);
// // 输出json格式的字符串回包
// return AbstractModel.ToJsonString(resp);
// }
// catch (Exception ex)
// {
// return ex.Message;
// }
//}
#endregion
}
/// <summary>
/// 短信接口参数类
/// </summary>
public class SmsParameters
{
public string LoginName { get; set; }
public string Pwd { get; set; }
public string FeeType { get; set; }
public string Mobile { get; set; }
public string Content { get; set; }
public string SignName { get; set; }
public string TimingDate { get; set; }
public string ExtCode { get; set; }
}
}

155
src/2.services/ATS.NonCustodial.Application/Impl/Admins/UnitcodeService.cs

@ -2,22 +2,17 @@
using ATS.NonCustodial.Application.Contracts.Interfaces.Admins.Unitcode;
using ATS.NonCustodial.Application.Contracts.Interfaces.Admins.Unitcode.Input;
using ATS.NonCustodial.Application.Contracts.Interfaces.Admins.Unitcode.Output;
using ATS.NonCustodial.Application.Contracts.Interfaces.Business.MaterialManager.Template.Input;
using ATS.NonCustodial.Application.Contracts.Interfaces.Business.MaterialManager.Template.Output;
using ATS.NonCustodial.Domain.Entities.Admins;
using ATS.NonCustodial.Domain.Entities.Business.MaterialManager;
using ATS.NonCustodial.Domain.Shared.AggRootEntities;
using ATS.NonCustodial.Domain.Shared.AggRootEntities.Dtos;
using ATS.NonCustodial.Domain.Shared.OrmRepositories.Basic.EfCore;
using ATS.NonCustodial.DynamicApi;
using ATS.NonCustodial.DynamicApi.Attributes;
using ATS.NonCustodial.Shared.Common.Attributes;
using ATS.NonCustodial.Shared.Common.Enums;
using ATS.NonCustodial.Shared.Common.UnifiedResults;
using ATS.NonCustodial.Shared.Extensions;
using ATS.NonCustodial.Shared.Extensions.AdvancedQuery;
using AutoMapper.QueryableExtensions;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using SixLabors.ImageSharp.Drawing;
using Yitter.IdGenerator;
namespace ATS.NonCustodial.Application.Impl.Admins
@ -34,12 +29,15 @@ namespace ATS.NonCustodial.Application.Impl.Admins
private readonly IEfRepository<App_Unitcode?, long> _appUnitcodeRepository;
private readonly IEfRepository<App_Deptcode?, long> _appDeptcodeRepository;
private readonly IEfRepository<AppUser?, long> _userRepository;
public UnitcodeService(IEfRepository<App_Unitcode?, long> appUnitcodeRepository,
IEfRepository<App_Deptcode?, long> appDeptcodeRepository)
IEfRepository<App_Deptcode?, long> appDeptcodeRepository,
IEfRepository<AppUser?, long> userRepository)
{
_appUnitcodeRepository = appUnitcodeRepository;
_appDeptcodeRepository = appDeptcodeRepository;
_userRepository = userRepository;
}
#endregion Identity
@ -61,9 +59,9 @@ namespace ATS.NonCustodial.Application.Impl.Admins
/// <param name="input"></param>
/// <returns></returns>
[HttpGet]
public async Task<IResultOutput> GetlistAsync(long stat,long mechanismId)
public async Task<IResultOutput> GetlistAsync(long stat, long mechanismId)
{
var express =await _appUnitcodeRepository.AsQueryable(false, true).WhereIf(mechanismId>0,a=>a.mechanismId== mechanismId).Where(q=>q.Stat==stat).ToListAsync();
var express = await _appUnitcodeRepository.AsQueryable(false, true).WhereIf(mechanismId > 0, a => a.mechanismId == mechanismId).Where(q => q.Stat == stat).ToListAsync();
var rtnlist = new List<dynamic>();//返回结果
//foreach (var item in express.Where(q => q.ParentUnitCode == 0||q.ParentUnitCode == null))
//{
@ -88,10 +86,10 @@ namespace ATS.NonCustodial.Application.Impl.Admins
public async Task<IResultOutput> GetPageAsync(UnitcodeGetPageDto input)
{
var rtnlist = new List<dynamic>();//五条件返回结果
var express = GetExpression(input, _appUnitcodeRepository.AsQueryable(false, true).WhereIf(input.mechanismId.IsNotEmptyOrNull(), a=>a.mechanismId==input.mechanismId).Where(q => q.Stat == 1));
if(express.Count()==0) return ResultOutput.Ok(rtnlist);
var express = GetExpression(input, _appUnitcodeRepository.AsQueryable(false, true).WhereIf(input.mechanismId.IsNotEmptyOrNull(), a => a.mechanismId == input.mechanismId).Where(q => q.Stat == 1));
if (express.Count() == 0) return ResultOutput.Ok(rtnlist);
if (!string.IsNullOrEmpty(input.name)) return ResultOutput.Ok(express);//有条件返回结果
foreach (var item in await express.Where(q => q.ParentUnitCode == null|| q.ParentUnitCode == 0).ToArrayAsync())
foreach (var item in await express.Where(q => q.ParentUnitCode == null || q.ParentUnitCode == 0).ToArrayAsync())
{
rtnlist.Add(new
{
@ -100,7 +98,7 @@ namespace ATS.NonCustodial.Application.Impl.Admins
UnitCode = item.UnitCode,
NameEntity = item.NameEntity,
dw = false,
children = pidlist(express.Where(q => q.ParentUnitCode != 0||q.ParentUnitCode != null).ToList(),item.Id)
children = pidlist(express.Where(q => q.ParentUnitCode != 0 || q.ParentUnitCode != null).ToList(), item.Id)
});
}
return ResultOutput.Ok(rtnlist);
@ -178,7 +176,7 @@ namespace ATS.NonCustodial.Application.Impl.Admins
public async Task<IResultOutput> GetjgPageAsync(UnitcodeGetPageDto input)
{
var rtnlist = new List<dynamic>();//五条件返回结果
var express = GetExpression(input, _appUnitcodeRepository.AsQueryable(false, true).Where(q=>q.Stat==0));
var express = GetExpression(input, _appUnitcodeRepository.AsQueryable(false, true).Where(q => q.Stat == 0));
if (express.Count() == 0) return ResultOutput.Ok(rtnlist);
if (!string.IsNullOrEmpty(input.name)) return ResultOutput.Ok(express);//有条件返回结果
foreach (var item in await express.Where(q => q.ParentUnitCode == null || q.ParentUnitCode == 0).ToArrayAsync())
@ -202,19 +200,19 @@ namespace ATS.NonCustodial.Application.Impl.Admins
/// <param name="list"></param>
/// <param name="pid"></param>
/// <returns></returns>
public static List<dynamic> pidlist(List<App_Unitcode> list,long pid, List<App_Unitcode> dwgllist=null,List<App_Deptcode> Deptlist = null)
public static List<dynamic> pidlist(List<App_Unitcode> list, long pid, List<App_Unitcode> dwgllist = null, List<App_Deptcode> Deptlist = null)
{
var plist = new List<dynamic>();
var dwgllist1 = new List<App_Unitcode>();
//通过监管机构查询查询单位
if (dwgllist!=null)
if (dwgllist != null)
dwgllist1 = dwgllist.Where(q => q.mechanismId == pid).ToList();
//通过单位查询部门
var Deptcode = new List<App_Deptcode>();
if (Deptlist != null)
Deptcode = Deptlist.Where(q => q.UnitId == pid).ToList();
//监管机构查询下级
foreach (var item in list.Where(q=>q.ParentUnitCode==pid).ToList())
foreach (var item in list.Where(q => q.ParentUnitCode == pid).ToList())
{
plist.Add(new
{
@ -237,15 +235,15 @@ namespace ATS.NonCustodial.Application.Impl.Admins
ParentUnitCode = item.ParentUnitCode,
NameEntity = item.NameEntity,
UnitCode = item.UnitCode,
dw =false,
children = pidlist(dwgllist.Where(q => q.ParentUnitCode != 0 || q.ParentUnitCode != null).ToList(), item.Id,null, Deptlist)
dw = false,
children = pidlist(dwgllist.Where(q => q.ParentUnitCode != 0 || q.ParentUnitCode != null).ToList(), item.Id, null, Deptlist)
});
}
}
//部门查找下级
if (Deptlist != null)
{
var datalist= Deptcode.Where(q => q.pid == 0 || q.pid == null).ToList();
var datalist = Deptcode.Where(q => q.pid == 0 || q.pid == null).ToList();
foreach (var item in datalist)
{
plist.Add(new
@ -296,14 +294,36 @@ namespace ATS.NonCustodial.Application.Impl.Admins
{
if (_appUnitcodeRepository.AsQueryable(false, true).Where(q => q.UnitCode == input.UnitCode).Any())
{
if (input.Stat == 0)
return ResultOutput.NotOk("机构编码已存在");
else
return ResultOutput.NotOk("单位编码已存在");
return input.Stat == 0 ? ResultOutput.NotOk("机构编码已存在") : ResultOutput.NotOk("单位编码已存在");
}
var entity = Mapper.Map<App_Unitcode>(input);
entity.Id = YitIdHelper.NextId();
entity.Limits = entity.Id.ToString();
if(input.ParentUnitCode.HasValue)
{
var rtn = await base.GetAsync<App_Unitcode, UnitcodeListOutput, long>(_appUnitcodeRepository, input.ParentUnitCode.Value);
entity.UnitLevel =(int.Parse(rtn.UnitLevel??"0")+1).ToString();
}
else
{
entity.UnitLevel = "1";
}
var App_Unitcode = await _appUnitcodeRepository.InsertAsync(entity);
//添加父级单位权限
if (entity.ParentUnitCode.HasValue)
{
var idList = GetParentUnitIdList((long)entity.ParentUnitCode);
idList.Add((long)entity.ParentUnitCode);
for (int i = 0; i < idList.Count; i++)
{
var parentunit = await _appUnitcodeRepository.FindAsync(idList[i]);
if (parentunit != null)
{
parentunit.Limits += "," + entity.Id;
await _appUnitcodeRepository.UpdateAsync(parentunit);
}
}
}
return ResultOutput.Result(App_Unitcode.Id > 0);
}
@ -316,6 +336,11 @@ namespace ATS.NonCustodial.Application.Impl.Admins
{
if (!(input?.Id > 0)) return ResultOutput.NotOk();
var unitlist = _appUnitcodeRepository.AsQueryable(false, true).Where(q => q.Id == input.Id).ToList();
foreach (var item in unitlist)
{
if (item.ParentUnitCode != input.ParentUnitCode) { return ResultOutput.NotOk("单位父级无法修改"); }
}
var entity = await _appUnitcodeRepository.FindAsync((long)input.Id);
if (!(entity?.Id > 0)) return ResultOutput.NotOk("编辑失败");
@ -334,14 +359,90 @@ namespace ATS.NonCustodial.Application.Impl.Admins
{
Uow.BeginTransaction();
{
for (int i = 0; i < input.Ids.Count; i++)
{
//获取该单位下的所有子单位id
var idlist = GetUnitIdList(input.Ids[i]);
//校验该单位下是否存在用户账户
if (_userRepository.AsQueryable(false, true).Where(q => idlist.Contains(q.UnitId ?? -1)).Any())
{
return ResultOutput.NotOk("该单位下存在用户账户,无法删除");
}
var idParentList = GetParentUnitIdList(input.Ids[i]);
//删除
await _appUnitcodeRepository.DeleteAsync(w => idlist.Contains(w.Id));
//获取该单位的所有父级单位id
for (int j = 0; j < idParentList.Count; j++)
{
var parentunit = await _appUnitcodeRepository.FindAsync(idParentList[j]);
if (parentunit != null)
{
// 步骤1:统一分隔符并分割字符串
var numbers = parentunit.Limits
.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries) // 按英文逗号分割
.Select(s => long.Parse(s.Trim())); // 转换为整数并去除空格
// 步骤2:过滤掉存在于 filterList 中的数字
var filteredNumbers = numbers.Where(n => !idlist.Contains(n)).ToList();
// 步骤3:重新拼接为字符串
string result = string.Join(",", filteredNumbers);
parentunit.Limits = result;
await _appUnitcodeRepository.UpdateAsync(parentunit);
}
}
}
//删除
await _appUnitcodeRepository.DeleteAsync(w => input.Ids.Contains(w.Id));
// await _appUnitcodeRepository.DeleteAsync(w => input.Ids.Contains(w.Id));
//删除
await _appUnitcodeRepository.DeleteAsync(w => input.Ids.Contains((long)w.ParentUnitCode));
// await _appUnitcodeRepository.DeleteAsync(w => input.Ids.Contains((long)w.ParentUnitCode));
}
await Uow.CommitAsync();
return ResultOutput.Ok();
}
/// <summary>
/// 递归查找该单位下的所有单位
/// </summary>
/// <param name="unitId">单位id</param>
/// <returns>单位id集合</returns>
private List<long> GetUnitIdList(long unitId)
{
List<long> idList = new List<long>();
idList.Add(unitId);
var unitlist = _appUnitcodeRepository.AsQueryable(false, true).Where(q => q.ParentUnitCode == unitId).ToList();
foreach (var item in unitlist)
{
idList.Add(item.Id);
var idlist = GetUnitIdList(item.Id);
idList.AddRange(idlist);
}
return idList;
}
/// <summary>
/// 递归查找该单位的所有父级单位
/// </summary>
/// <param name="unitId">单位id</param>
/// <returns>单位id集合</returns>
private List<long> GetParentUnitIdList(long unitId)
{
List<long> idList = new List<long>();
var unitlist = _appUnitcodeRepository.AsQueryable(false, true).Where(q => q.Id == unitId).ToList();
foreach (var item in unitlist)
{
if (item != null && item.ParentUnitCode.HasValue)
{
idList.Add((long)item.ParentUnitCode);
var idlist = GetParentUnitIdList((long)item.ParentUnitCode);
idList.AddRange(idlist);
}
}
return idList;
}
#region Private
/// <summary>

161
src/2.services/ATS.NonCustodial.Application/Impl/Admins/UserService.cs

@ -1,13 +1,20 @@
using ATS.NonCustodial.Application.Base;
using ATS.NonCustodial.Application.Contracts.Interfaces.Admins.AppDictionaries;
using ATS.NonCustodial.Application.Contracts.Interfaces.Admins.AppDictionaries.Output;
using ATS.NonCustodial.Application.Contracts.Interfaces.Admins.Auth.Output;
using ATS.NonCustodial.Application.Contracts.Interfaces.Admins.Menu.Output;
using ATS.NonCustodial.Application.Contracts.Interfaces.Admins.Role.Output;
using ATS.NonCustodial.Application.Contracts.Interfaces.Admins.SMS;
using ATS.NonCustodial.Application.Contracts.Interfaces.Admins.User;
using ATS.NonCustodial.Application.Contracts.Interfaces.Admins.User.Input;
using ATS.NonCustodial.Application.Contracts.Interfaces.Admins.User.Output;
using ATS.NonCustodial.Application.Contracts.Interfaces.Business.AppCaseManagements.AppCaseManagement;
using ATS.NonCustodial.Application.Contracts.Interfaces.Business.PunchRecordServices.Output;
using ATS.NonCustodial.Application.Impl.Business.CaseManagements;
using ATS.NonCustodial.Domain.Entities.Admins;
using ATS.NonCustodial.Domain.Entities.Business.CaseManagements;
using ATS.NonCustodial.Domain.Shared.AggRootEntities.Dtos;
using ATS.NonCustodial.Domain.Shared.Enums;
using ATS.NonCustodial.Domain.Shared.OrmRepositories.Basic.EfCore;
using ATS.NonCustodial.DynamicApi;
using ATS.NonCustodial.DynamicApi.Attributes;
@ -26,10 +33,8 @@ using AutoMapper.QueryableExtensions;
using Castle.Components.DictionaryAdapter;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Routing;
using Microsoft.EntityFrameworkCore;
using System.Collections.Generic;
using System.Xml.Linq;
using StackExchange.Profiling.Internal;
using Yitter.IdGenerator;
namespace ATS.NonCustodial.Application.Impl.Admins
@ -52,16 +57,21 @@ namespace ATS.NonCustodial.Application.Impl.Admins
private readonly IEfRepository<AppRolePermission?, long> _rolePermissionRepository;
private readonly IEfRepository<App_Menu?, long> _MenuRepository;
private readonly IAppDictionaryService _appDictionaryService;
private readonly ISMSService _smsService;
private readonly IEfRepository<AppCaseManagement, long> _appCaseManagementRepository;
private readonly IEfRepository<AppCaseSupervisedPerson, long> _appSupervisedPersonRepository;
public UserService(
IEfRepository<AppUser?, long> userRepository,
IEfRepository<AppUser?, long> userRepository, IEfRepository<AppCaseManagement, long> appCaseManagementRepository,
IEfRepository<AppCaseSupervisedPerson, long> appSupervisedPersonRepository,
IEfRepository<AppUserRole?, long> userRoleRepository,
IEfRepository<AppApi?, long> apiRepository,
IEfRepository<AppRole?, long> roleRepository,
IEfRepository<AppPermissionApi?, long> permissionApiRepository,
IEfRepository<AppRolePermission?, long> rolePermissionRepository,
IEfRepository<App_Menu?, long> MenuRepository,
IAppDictionaryService appDictionaryService
IAppDictionaryService appDictionaryService,
ISMSService smsService
)
{
_userRepository = userRepository;
@ -72,6 +82,10 @@ namespace ATS.NonCustodial.Application.Impl.Admins
_rolePermissionRepository = rolePermissionRepository;
_appDictionaryService = appDictionaryService;
_MenuRepository = MenuRepository;
_smsService = smsService;
_appCaseManagementRepository = appCaseManagementRepository;
_appSupervisedPersonRepository = appSupervisedPersonRepository;
}
#endregion Identity
@ -110,7 +124,7 @@ namespace ATS.NonCustodial.Application.Impl.Admins
[HttpGet]
public async Task<IResultOutput> GetuserroleAsync(long id)
{
var userrole = await _userRoleRepository.AsQueryable(false, true).Where(q=>q.RoleId== id).Select(q=>q.UserId).ToListAsync();
var userrole = await _userRoleRepository.AsQueryable(false, true).Where(q => q.RoleId == id).Select(q => q.UserId).ToListAsync();
return ResultOutput.Ok(userrole);
}
@ -133,16 +147,16 @@ namespace ATS.NonCustodial.Application.Impl.Admins
// select new {urpm}).ToListAsync();
var usermenulis = await _MenuRepository.AsQueryable(false, true).ToListAsync();
var menulist = Mapper.Map<List<MenuListOutput>>(usermenulis);
foreach (var item in menulist.Distinct().Where(q => q.pid == 0||q.pid==null).OrderBy(q=>q.sort).ToList())
foreach (var item in menulist.Distinct().Where(q => q.pid == 0 || q.pid == null).OrderBy(q => q.sort).ToList())
{
rtnlist.Add(new
{
Id=item.Id,
Id = item.Id,
name = item.menuName,
route = item.menuUrl,
icon=item.icon,
icon = item.icon,
iconName = item.iconName,
Sublevel= menulist.Where(q=>q.pid== item.Id).ToList().OrderBy(q=> q.sort).Select(q=>new { q.Id, name=q.menuName, route=q.menuUrl}).ToList()
Sublevel = menulist.Where(q => q.pid == item.Id).ToList().OrderBy(q => q.sort).Select(q => new { q.Id, name = q.menuName, route = q.menuUrl }).ToList()
});
}
return ResultOutput.Ok(rtnlist);
@ -158,20 +172,28 @@ namespace ATS.NonCustodial.Application.Impl.Admins
{
var rtnlist = new List<dynamic>();
//查找当前用户角色权限菜单
var usermenulist = await (from ur in _userRoleRepository.AsQueryable(false, true).Where(q=>q.UserId==User.Id)
var usermenulist = await (from ur in _userRoleRepository.AsQueryable(false, true).Where(q => q.UserId == User.Id)
join urp in _rolePermissionRepository.AsQueryable(false, true) on ur.RoleId equals urp.RoleId
join urpm in _MenuRepository.AsQueryable(false, true) on urp.PermissionId equals urpm.Id
select new App_Menu{ Id=urpm.Id, menuName=urpm.menuName, icon=urpm.icon, iconName=urpm.iconName, pid=urpm.pid, sort=urpm.sort,
select new App_Menu
{
Id = urpm.Id,
menuName = urpm.menuName,
icon = urpm.icon,
iconName = urpm.iconName,
pid = urpm.pid,
sort = urpm.sort,
route = urpm.route,
menuUrl =urpm.menuUrl }).ToListAsync();
menuUrl = urpm.menuUrl
}).ToListAsync();
var menulist = Mapper.Map<List<MenuListOutput>>(usermenulist);
if (User.Name.Contains("aks"))
{
var list = await _MenuRepository.AsQueryable(false, true).ToListAsync();
menulist = Mapper.Map<List<MenuListOutput>>(list);
}
menulist= menulist.Where((x, i) => menulist.FindIndex(s => s.Id == x.Id) == i).ToList();
foreach (var item in menulist.Distinct().Where((q,x) => q.pid == 0 || q.pid == null).OrderBy(q => q.sort).ToList())
menulist = menulist.Where((x, i) => menulist.FindIndex(s => s.Id == x.Id) == i).ToList();
foreach (var item in menulist.Distinct().Where((q, x) => q.pid == 0 || q.pid == null).OrderBy(q => q.sort).ToList())
{
rtnlist.Add(new
{
@ -179,7 +201,7 @@ namespace ATS.NonCustodial.Application.Impl.Admins
name = item.menuName,
route = item.menuUrl,
icon = item.icon,
routes=item.route,
routes = item.route,
iconName = item.iconName,
Sublevel = menulist.Distinct().Where(q => q.pid == item.Id).ToList().OrderBy(q => q.sort).Select(q => new { q.Id, name = q.menuName, route = q.menuUrl, routes = q.route }).ToList()
});
@ -195,7 +217,7 @@ namespace ATS.NonCustodial.Application.Impl.Admins
[HttpPost]
public async Task<IResultOutput> GetPageAsync(UserGetPageDto input)
{
var express = GetExpression(input, _userRepository.AsQueryable(false, true).Where(q=>!q.UserName.Contains("aks")));
var express = GetExpression(input, _userRepository.AsQueryable(false, true).Where(q => !q.UserName.Contains("aks")));
var pageData = await base.GetPageAsync<AppUser, UserGetPageDto, UserListOutput>(input, express);
var userIds = pageData.Data.Select(w => w.Id).ToList();
@ -375,7 +397,14 @@ namespace ATS.NonCustodial.Application.Impl.Admins
{
//if (await _userRepository.AnyAsync(x => x.ReceiveName == input.ReceiveName)) return ResultOutput.NotOk("账号已经存在");
if (await _userRepository.AnyAsync(w => w.UserName == input.UserName)) return ResultOutput.NotOk("姓名已经存在");
if (!input.Phone.HasValue()) return ResultOutput.NotOk("请输入手机号");
var result = await CheckPhone(input.Phone);
if (!result) { return ResultOutput.NotOk("手机号已在系统中已存在"); }
if (!input.Code.HasValue()) return ResultOutput.NotOk("请输入验证码");
result = await _smsService.CheckCodeAsync(input.Phone, input.Code, "CheckCode");
if (!result) { return ResultOutput.NotOk("验证码错误"); }
var entity = Mapper.Map<AppUser>(input);
entity.Id = YitIdHelper.NextId();
entity.PasswordSalt = InfraHelper.Security.GenerateRandomCode(5);
@ -415,13 +444,13 @@ namespace ATS.NonCustodial.Application.Impl.Admins
var userRole = await IsAdmin(null);
if (inputlist == null) return ResultOutput.Ok();
else
await _userRoleRepository.DeleteAsync(q=>q.RoleId== inputlist[0].RoleId);//删除所有用户角色
await _userRoleRepository.DeleteAsync(q => q.RoleId == inputlist[0].RoleId);//删除所有用户角色
foreach (var item in inputlist)
{
item.Id = YitIdHelper.NextId();
}
await _userRoleRepository.InsertAsync(Mapper.Map<List<UserRoleAddInput>,List<AppUserRole>>(inputlist));
await _userRoleRepository.InsertAsync(Mapper.Map<List<UserRoleAddInput>, List<AppUserRole>>(inputlist));
return ResultOutput.Ok();
}
@ -509,8 +538,11 @@ namespace ATS.NonCustodial.Application.Impl.Admins
/// <param name="input"></param>
/// <returns></returns>
public async Task<IResultOutput> UpdateAsync(UserUpdateInput input)
{
if(!input.PhoneUpdateFlag.HasValue() || input.PhoneUpdateFlag != "1")
{
if (!(await IsAdmin(User.Id)).IsAdmin) return ResultOutput.NotOk("无操作权限");
}
if (!(input?.Id > 0)) return ResultOutput.NotOk();
var user = await _userRepository.FindAsync(input.Id);
@ -518,7 +550,16 @@ namespace ATS.NonCustodial.Application.Impl.Admins
if (!(user?.Id > 0)) return ResultOutput.NotOk("用户不存在!");
//监管人和管理员手机号不能重复
if (await _userRepository.AnyAsync(w => w.Id != input.Id && w.UserName == input.UserName && w.ChatPersonType != ChatPersonTypeEnum.SupervisedPerson)) return ResultOutput.NotOk("姓名不能重复");
if (!input.Phone.HasValue()) return ResultOutput.NotOk("请输入手机号");
if (user.Phone != input.Phone)
{
var result = await CheckPhone(input.Phone);
if (!result) { return ResultOutput.NotOk("手机号已在系统中已存在"); }
if (!input.Code.HasValue()) return ResultOutput.NotOk("请输入验证码");
result = await _smsService.CheckCodeAsync(input.Phone, input.Code, "CheckCode");
if (!result) { return ResultOutput.NotOk("验证码错误"); }
}
Mapper.Map(input, user);
await _userRepository.UpdateAsync(user, UpdatingProps<AppUser>(
@ -532,7 +573,11 @@ namespace ATS.NonCustodial.Application.Impl.Admins
w => w.DataStatus)!);
if (input.RoleIds != null && input.RoleIds.Count() > 0)
{
await _userRoleRepository.DeleteAsync(a => a.UserId == user.Id && input.RoleIds.Contains(a.RoleId));
var roleList = await _roleRepository.AsQueryable(false, true)
.Where(w => w.Code == "admin" || w.Code == "supervisor")
.Select(s => s.Id).ToListAsync();
await _userRoleRepository.DeleteAsync(a => a.UserId == user.Id && roleList.Contains(a.RoleId));
if (input.RoleIds == null || !input.RoleIds.Any()) return ResultOutput.Ok();
{
@ -548,6 +593,44 @@ namespace ATS.NonCustodial.Application.Impl.Admins
return ResultOutput.Ok();
}
/// <summary>
/// 校验手机号是否有运行中的按键
/// </summary>
/// <param name="phone"></param>
/// <returns></returns>
private async Task<bool> CheckPhone(string phone)
{
var allUsers = await _userRepository.Where(w => w.Phone == phone && !string.IsNullOrEmpty(w.RoleName)).ToListAsync();
if (allUsers.Any())
{
foreach (var item in allUsers)
{
var caseList = await (from c in _appCaseManagementRepository.AsQueryable(false, true)
join cspr in _appSupervisedPersonRepository.AsQueryable(false, true) on c.Id equals cspr.CaseId
where c.CaseProgress != CaseProgressEnum.Closed
&& item.Id == cspr.SupervisedPersonId
select new CheckPunchRecordForJobOutput()
{
CaseId = c.Id,
CaseName = c.Name,
CaseBeginTime = c.CaseBeginTime,
CheckInFrequency = c.CheckInFrequency,
RestBeginTime = c.RestBeginTime,
RestEndTime = c.RestEndTime,
SupervisedPersonId = cspr.SupervisedPersonId,
SupervisedPersonName = cspr.SupervisedPersonName,
TimedClock = c.TimedClock
}).ToListAsync();
if(caseList.Any())
{
return false;
}
}
}
return true;
}
/// <summary>
/// 更新用户基本信息
/// </summary>
@ -836,14 +919,25 @@ namespace ATS.NonCustodial.Application.Impl.Admins
/// <summary>
/// 根据当前登录用户查询下拉列表
/// </summary>
/// <param name="isCourt">移交给检察院 0 移交法院 1</param>
/// <returns></returns>
public async Task<ResultOutput<List<KeyValueDto>>> GetUserSelectList()
public async Task<ResultOutput<List<KeyValueDto>>> GetUserSelectList(int isCourt = 0)
{
var userRoles = await this.IsAdmin(null);
// var userRoles = await this.IsAdmin(null);
// var dataDict = await _appDictionaryService.GetListNoApiAsync("job_position");
// 安全地处理可能的空值
// var codeList = dataDict?.FirstOrDefault()?.Dictionaries?
// .Where(w => w.Code == (isCourt == 0 ? "inquisitor" : "judge"))
// .ToList() ?? new List<DictionaryGetOutput>();
var rtn = await _userRepository.AsQueryable(false, true)
.Where(w => w.ChatPersonType != ChatPersonTypeEnum.SupervisedPerson && w.DataStatus != DataStatusEnum.Disable&&!w.UserName.Contains("_aks"))
.WhereIf(!userRoles.IsAdmin, w => w.Id == User.Id)
.Where(w => w.ChatPersonType != ChatPersonTypeEnum.SupervisedPerson && w.DataStatus != DataStatusEnum.Disable && !w.UserName.Contains("_aks"))
// .WhereIf(codeList.Count > 0, w => w.PositionId == codeList.FirstOrDefault().Id)
// .WhereIf(!userRoles.IsAdmin, w => w.Id == User.Id) 2025 -10-20 段肖确认修改
.Select(w => new KeyValueDto()
{
Id = w.Id,
@ -854,7 +948,26 @@ namespace ATS.NonCustodial.Application.Impl.Admins
return (ResultOutput<List<KeyValueDto>>)ResultOutput.Ok(rtn);
}
/// <summary>
/// 新建案件时 根据当前登录用户查询下拉列表
/// </summary>
/// <returns></returns>
public async Task<ResultOutput<List<KeyValueDto>>> GetNewUserSelectList()
{
var userRoles = await this.IsAdmin(null);
// var limits = User.UnitId;
var rtn = await _userRepository.AsQueryable(false, true)
.Where(w => w.ChatPersonType != ChatPersonTypeEnum.SupervisedPerson && w.DataStatus != DataStatusEnum.Disable && !w.UserName.Contains("_aks") && w.UnitId == User.UnitId)
.Select(w => new KeyValueDto()
{
Id = w.Id,
Text = w.UserName ?? w.Name,
Value = w.Id.ToString(),
Phone = w.Phone.ToString()
}).ToListAsync();
return (ResultOutput<List<KeyValueDto>>)ResultOutput.Ok(rtn);
}
/// <summary>
/// 获取所有的管理员
/// </summary>

16
src/2.services/ATS.NonCustodial.Application/Impl/Business/AppAnnouncementService.cs

@ -40,6 +40,7 @@ namespace ATS.NonCustodial.Application.Impl.Business
#region Identity
private readonly IEfRepository<AppAnnouncement, long> _appAnnouncementRepository;
protected readonly IEfRepository<AppCaseSupervisor, long> _appCaseSupervisorRepository;
private readonly IEfRepository<AppAnnouncementViewStatistics, long> _appAnnouncementViewStatisticsRepository;
private readonly IHubContext<NonCustodialHub> _hubContext;
protected readonly IEfRepository<AppCaseManagement, long> _appCaseManagementRepository;
@ -56,6 +57,7 @@ namespace ATS.NonCustodial.Application.Impl.Business
public AppAnnouncementService(IEfRepository<AppAnnouncement, long> appAnnouncementRepository,
IEfRepository<AppAnnouncementViewStatistics, long> appAnnouncementViewStatisticsRepository,
IHubContext<NonCustodialHub> hubContext,
IEfRepository<AppCaseSupervisor, long> appCaseSupervisorRepository,
IEfRepository<AppCaseManagement, long> appCaseManagementRepository,
IEfRepository<AppCaseSupervisedPerson, long> appSupervisedPersonRepository)
{
@ -64,6 +66,7 @@ namespace ATS.NonCustodial.Application.Impl.Business
_hubContext = hubContext;
_appCaseManagementRepository = appCaseManagementRepository;
_appSupervisedPersonRepository = appSupervisedPersonRepository;
_appCaseSupervisorRepository = appCaseSupervisorRepository;
}
#endregion Identity
@ -103,8 +106,19 @@ namespace ATS.NonCustodial.Application.Impl.Business
[HttpPost]
public async Task<IResultOutput> GetPageAsync(AppAnnouncementPageInput input)
{
//获取当前用户权限下的案件ids
var limits = User.limits;
var selectLimits = await _appCaseSupervisorRepository.AsQueryable(false, true)
.Where(w => limits.Contains(w.UnitId.ToString()))
.ToListAsync();
var caseIdList = selectLimits.Select(w => w.CaseId).Distinct().ToList();
var appAnnouncementViewStatistics = await _appAnnouncementViewStatisticsRepository.AsQueryable(false, true).Where(w => caseIdList.Contains(w.CaseId ?? -1)).Select(s => s.AnnouncementId).ToListAsync();
var express = GetExpression(input, _appAnnouncementRepository.AsQueryable(false, true));
var rtn = await base.GetPageAsync<AppAnnouncement, AppAnnouncementPageInput, AppAnnouncementListDto>(input, express);
express = express.Where(w => appAnnouncementViewStatistics.Contains(w.Id));
var rtn = (await base.GetPageAsync<AppAnnouncement, AppAnnouncementPageInput, AppAnnouncementListDto>(input, express));
return ResultOutput.Ok(rtn);
}

147
src/2.services/ATS.NonCustodial.Application/Impl/Business/AppBusinessApplicationService.cs

@ -1,15 +1,20 @@
using ATS.NonCustodial.Application.Base;
using ATS.NonCustodial.Application.Contracts.Interfaces.Admins.AppDictionaries;
using ATS.NonCustodial.Application.Contracts.Interfaces.Admins.SMS;
using ATS.NonCustodial.Application.Contracts.Interfaces.Admins.User;
using ATS.NonCustodial.Application.Contracts.Interfaces.Business.AppBusinessApplications;
using ATS.NonCustodial.Application.Contracts.Interfaces.Business.AppBusinessApplications.Input;
using ATS.NonCustodial.Application.Contracts.Interfaces.Business.AppBusinessApplications.Output;
using ATS.NonCustodial.Application.Contracts.Interfaces.Business.AppCaseManagements.AppCaseManagement;
using ATS.NonCustodial.Application.Contracts.Interfaces.Business.AppCaseManagements.AppCaseManagement.Input;
using ATS.NonCustodial.Application.Contracts.Interfaces.Business.AppCaseManagements.AppCaseManagement.Output;
using ATS.NonCustodial.Application.Contracts.Interfaces.Business.Apps.Output;
using ATS.NonCustodial.Application.Impl.Business.IM;
using ATS.NonCustodial.Domain.Entities.Admins;
using ATS.NonCustodial.Domain.Entities.Business;
using ATS.NonCustodial.Domain.Entities.Business.CaseManagements;
using ATS.NonCustodial.Domain.Shared.AggRootEntities.Dtos;
using ATS.NonCustodial.Domain.Shared.Enums;
using ATS.NonCustodial.Domain.Shared.OrmRepositories.Basic.EfCore;
using ATS.NonCustodial.DynamicApi;
using ATS.NonCustodial.DynamicApi.Attributes;
@ -22,8 +27,6 @@ using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.SignalR;
using Microsoft.EntityFrameworkCore;
using Newtonsoft.Json;
using NPOI.SS.Formula.Functions;
using System.Linq;
using Yitter.IdGenerator;
namespace ATS.NonCustodial.Application.Impl.Business
@ -42,6 +45,9 @@ namespace ATS.NonCustodial.Application.Impl.Business
private readonly IEfRepository<AppBusinessApplicationViewStatistics, long> _appBusinessApplicationViewStatisticsRepository;
private readonly IAppCaseManagementService _appCaseManagementService;
private readonly IHubContext<NonCustodialHub> _hubContext;
private readonly IEfRepository<AppUser, long> _appUserRepository;
private readonly ISMSService _smsService;
private readonly IEfRepository<AppCaseSupervisedPerson, long> _appSupervisedPersonRepository;
/// <summary>
///
@ -65,7 +71,8 @@ namespace ATS.NonCustodial.Application.Impl.Business
IEfRepository<AppCaseSupervisor, long> appCaseSupervisorRepository,
IEfRepository<AppCaseSupervisedPerson, long> appCaseSupervisedPersonRepository,
IUserService userService,
IEfRepository<AppSupervisedPersonRealTimeLocation, long> appSupervisedPersonRealTimeLocationRepository)
IEfRepository<AppUser, long> appUserRepository,
IEfRepository<AppSupervisedPersonRealTimeLocation, long> appSupervisedPersonRealTimeLocationRepository, ISMSService smsService)
: base(
appCaseManagementRepository,
appCaseSupervisorRepository,
@ -78,6 +85,9 @@ namespace ATS.NonCustodial.Application.Impl.Business
_appBusinessApplicationViewStatisticsRepository = appBusinessApplicationViewStatisticsRepository;
_appCaseManagementService = appCaseManagementService;
_hubContext = hubContext;
_appUserRepository = appUserRepository;
_smsService = smsService;
_appSupervisedPersonRepository = appCaseSupervisedPersonRepository;
}
#endregion Identity
@ -90,6 +100,32 @@ namespace ATS.NonCustodial.Application.Impl.Business
public async Task<IResultOutput> GetAsync(long id)
{
var rtn = await base.GetAsync<AppBusinessApplication, AppBusinessApplicationGetDto, long>(_appBusinessApplicationRepository, id);
if (rtn != null&& User.PositionId !=0)
{
//获取用户职位
var position = await _appDictionaryService.GetDicByDicId(User.PositionId);
var caseDto = await base.GetWithDataAsync<AppCaseManagement, AppCaseManagementGetDto, long>(_appCaseManagementRepository, rtn.CaseId);
//当前案件状态和登录人员职位相匹配时,才能修改
var permissionGranted = (caseDto.CaseProgress, position.Code) switch
{
(CaseProgressEnum.Pending, "police") => true,
(CaseProgressEnum.InExecution, "police") => true,
(CaseProgressEnum.Examination, "inquisitor") => true,
(CaseProgressEnum.Hear, "judge") => true,
_ => false
};
if (permissionGranted)
{
rtn.ReviewPermission = "1";
}
else
{
rtn.ReviewPermission = "0";
}
}
return ResultOutput.Ok(rtn);
}
@ -101,8 +137,53 @@ namespace ATS.NonCustodial.Application.Impl.Business
[HttpPost]
public async Task<IResultOutput> GetPageAsync(AppBusinessApplicationGetPageInput input)
{
//获取当前用户权限下的案件ids
var limits = User.limits;
var selectLimits = await _appCaseSupervisorRepository.AsQueryable(false, true)
.Where(w => limits.Contains(w.UnitId.ToString()))
.ToListAsync();
var caseIdList = selectLimits.Select(w => w.CaseId).Distinct().ToList();
var express = await GetExpression(input, _appBusinessApplicationRepository.AsQueryable(false, true));
express = express.Where(w => caseIdList.Contains(w.CaseId));
var rtn = await base.GetPageAsync<AppBusinessApplication, AppBusinessApplicationGetPageInput, AppBusinessApplicationListDto>(input, express);
//rtn.Data = rtn.Data.Where(w => caseIdList.Contains(w.CaseId)).ToList();
var position = await _appDictionaryService.GetDicByDicId(User.PositionId);
//不同的申请,显示字段不一样
foreach (var item in rtn.Data)
{
var dic = await _appDictionaryService.GetDicByDicId(item.ApplicationTypeId);
if (dic.Code == "end_supervision")
{
item.ActiveTimePeriodBegin = null;
item.ActiveTimePeriodEnd = null;
}
else
{
item.EndSupervisionDate = null;
}
var caseDto = await base.GetWithDataAsync<AppCaseManagement, AppCaseManagementGetDto, long>(_appCaseManagementRepository, item.CaseId);
item.ReviewPermission = "0";
//当前案件状态和登录人员职位相匹配时,才能修改
var permissionGranted = (caseDto.CaseProgress, position.Code) switch
{
(CaseProgressEnum.Pending, "police") => true,
(CaseProgressEnum.InExecution, "police") => true,
(CaseProgressEnum.Examination, "inquisitor") => true,
(CaseProgressEnum.Hear, "judge") => true,
_ => false
};
if (permissionGranted)
{
item.ReviewPermission = "1";
}
}
return ResultOutput.Ok(rtn);
}
@ -117,15 +198,22 @@ namespace ATS.NonCustodial.Application.Impl.Business
//根据当前登录人查看其手里的案件被监管人
var spList = await base.GetCurrentUserCaseListAsync();
//获取当前用户权限下的案件ids
var limits = User.limits;
var selectLimits = await _appCaseSupervisorRepository.AsQueryable(false, true)
.Where(w => limits.Contains(w.UnitId.ToString()))
.ToListAsync();
var caseIds = selectLimits.Select(w => w.CaseId).Distinct().ToList();
var express = await GetExpression(input, _appBusinessApplicationRepository.AsQueryable(false, true));
var grudlist = express
.WhereIf(input.supname.NotNull(), q => q.SupervisedPersonName.Contains(input.supname))
.GroupBy(q => new { q.CaseId, q.SupervisedPersonId, q.SupervisedPersonName }).Select(q => new { q.Key.SupervisedPersonName, q.Key.CaseId, Count = q.ToList().Count }).ToList();
var grulist =from a in grudlist.ToList()
var grulist = from a in grudlist.ToList()
join b in spList.Select(q => q.AppCaseManagement).ToList() on a.CaseId equals b.Id
select new { a.SupervisedPersonName, a.Count, a.CaseId, b.Name };
var pagegrulist = grulist.Skip((input.PageIndex - 1) * input.PageSize).Take(input.PageSize).ToList();
return ResultOutput.Ok(new { TotalCount = grulist.Count(), grudlist= pagegrulist });
var resultList = grulist.Distinct().Where(p => caseIds.Contains(p.CaseId));
var pagegrulist = resultList.Skip((input.PageIndex - 1) * input.PageSize).Take(input.PageSize).ToList();
return ResultOutput.Ok(new { TotalCount = resultList.Count(), grudlist = pagegrulist });
}
/// <summary>
@ -158,10 +246,10 @@ namespace ATS.NonCustodial.Application.Impl.Business
w = w.AndNotNull(w =>
w.ApplicationTypeId == input.ApplicationTypeId &&
w.ActiveTimePeriodBegin == input.ActiveTimePeriodBegin &&
w.ActiveTimePeriodEnd == input.ActiveTimePeriodEnd
w.ActiveTimePeriodEnd == input.ActiveTimePeriodEnd &&
w.SupervisedPersonId == User.Id
, input.ApplicationTypeId != default);
msg = $"当前申请类型{input.ApplicationTypeId}在当前时间段:{input.ActiveTimePeriodBegin}-{input.ActiveTimePeriodEnd}已存在";
msg = $"当前申请类型{applicationType.Name}在当前时间段:{input.ActiveTimePeriodBegin}-{input.ActiveTimePeriodEnd}已存在";
return (w, msg);
});
@ -274,7 +362,38 @@ namespace ATS.NonCustodial.Application.Impl.Business
});
await _appBusinessApplicationRepository.UpdateAsync(dataList);
//当被监管人申请结束监管,判断此案件只有一个被监管人时,结束案件
foreach (var item in dataList)
{
var caseType = await _appDictionaryService.GetDicByDicId(item.ApplicationTypeId);
if (input.AuditStatus == AuditStatusEnum.Pass && caseType.Code == "end_supervision")
{
var caseId = await _appSupervisedPersonRepository.AsQueryable(false, true)
.Where(w => w.SupervisedPersonId == item.SupervisedPersonId)
.ToListAsync();
if (caseId.Count > 0)
{
var caseList = await _appSupervisedPersonRepository.AsQueryable(false, true)
.Where(w => w.CaseId == caseId.FirstOrDefault().CaseId)
.ToListAsync();
if (caseList.Count == 1)
{
BatchHandleCaseProgressInput ids = new BatchHandleCaseProgressInput();
ids.CaseProgress = CaseProgressEnum.Closed;
ids.Ids = new List<long> { caseId.FirstOrDefault().CaseId };
await _appCaseManagementService.BatchHandleCaseProgress(ids);
}
}
}
}
foreach (var item in dataList)
{
var user = await _appUserRepository.AsQueryable(false, true).Where(w => w.Id == item.SupervisedPersonId).ToListAsync();
//发短信给被监管人,提醒查看处理结果
//[审批完成通知] {1}您好,您于{2}年{3}月{4}日提交的{5}申请已完成审批,请及时登录系统查看处理结果。
await _smsService.SendMessageSMS(MessageAlertTypeEnum.Approved, "", user.FirstOrDefault().Phone, item.CreatedTime, item.ApplicationTypeName, "", item.SupervisedPersonName);
}
//返回结果
return ResultOutput.Ok();
}
@ -286,7 +405,13 @@ namespace ATS.NonCustodial.Application.Impl.Business
[HttpGet]
public async Task<IResultOutput> BusAppBusinessWorkbench()
{
var caseIds = await (await base.GetCurrentUserCaseListAsync()).Select(w => w.AppCaseManagement.Id).ToListAsync();
//获取当前用户权限下的案件ids
var limits = User.limits;
var selectLimits = await _appCaseSupervisorRepository.AsQueryable(false, true)
.Where(w => limits.Contains(w.UnitId.ToString()))
.ToListAsync();
var caseIdList = selectLimits.Select(w => w.CaseId).Distinct().ToList();
var caseIds = await (await base.GetCurrentUserCaseListAsync()).Where(w => w.AppCaseManagement != null && caseIdList.Contains(w.AppCaseManagement.Id)).Select(w => w.AppCaseManagement.Id).ToListAsync();
var dataList = await _appBusinessApplicationRepository.AsQueryable(false, true)
.Where(w => caseIds.Contains(w.CaseId))
@ -311,7 +436,7 @@ namespace ATS.NonCustodial.Application.Impl.Business
//根据当前登录人查看其手里的案件被监管人
var spList = await base.GetCurrentUserCaseListAsync();
var spIds = await spList.Where(q=>q.AppCaseSupervisedPerson!=null).Select(w => w.AppCaseSupervisedPerson!.SupervisedPersonId).ToListAsync();
var spIds = await spList.Where(q => q.AppCaseSupervisedPerson != null).Select(w => w.AppCaseSupervisedPerson!.SupervisedPersonId).ToListAsync();
query = query
.Where(w => spIds.Contains(w.SupervisedPersonId))

7
src/2.services/ATS.NonCustodial.Application/Impl/Business/AppDeviceManagementService.cs

@ -101,9 +101,14 @@ namespace ATS.NonCustodial.Application.Impl.Business
{
var express =await GetExpression(input, _appDeviceManagementRepository.AsQueryable(false, true));
var rtn = await base.GetPageAsync<AppDeviceManagement, AppDeviceManagementGetPageInput, AppDeviceManagementListDto>(input, express);
var limits = User.limits;
var selectLimits = await _appCaseSupervisorRepository.AsQueryable(false, true)
.Where(w => limits.Contains(w.UnitId.ToString())).Select(s=>s.SupervisorId)
.ToListAsync();
var userList = await _userService.GetAllByConditionAsync(new BatchIdsInput()
{
Ids = rtn.Data.Select(w => w.SupervisedPersonId).ToList()
Ids = rtn.Data.Where(w=> selectLimits.Contains(w.SupervisedPersonId)).Select(w => w.SupervisedPersonId).ToList()
});
await rtn.Data.ForEachAsync(item =>

88
src/2.services/ATS.NonCustodial.Application/Impl/Business/AppEarlyWarningService.cs

@ -1,6 +1,7 @@
using ATS.NonCustodial.Application.Base;
using ATS.NonCustodial.Application.Contracts.Interfaces.Admins.AppDictionaries;
using ATS.NonCustodial.Application.Contracts.Interfaces.Admins.AppDictionaries.Output;
using ATS.NonCustodial.Application.Contracts.Interfaces.Admins.SMS;
using ATS.NonCustodial.Application.Contracts.Interfaces.Admins.User;
using ATS.NonCustodial.Application.Contracts.Interfaces.Business.AppCaseManagements.AppCaseManagement;
using ATS.NonCustodial.Application.Contracts.Interfaces.Business.AppCaseManagements.AppCaseManagement.Input;
@ -13,7 +14,9 @@ using ATS.NonCustodial.Application.Contracts.Interfaces.Business.AppEarlyWarning
using ATS.NonCustodial.Application.Contracts.Interfaces.Business.Apps.Output;
using ATS.NonCustodial.Application.Contracts.Interfaces.Business.IM.Notifies;
using ATS.NonCustodial.Application.Contracts.Interfaces.Business.PunchRecordServices.Input;
using ATS.NonCustodial.Application.Impl.Admins;
using ATS.NonCustodial.Application.Impl.Business.IM;
using ATS.NonCustodial.Domain.Entities.Admins;
using ATS.NonCustodial.Domain.Entities.Business;
using ATS.NonCustodial.Domain.Entities.Business.CaseManagements;
using ATS.NonCustodial.Domain.Entities.Business.EarlyWarning;
@ -72,6 +75,9 @@ namespace ATS.NonCustodial.Application.Impl.Business
private readonly IEfRepository<AppEarlyWarningRule, long> _appEarlyWarningRuleRepository;
private readonly IAppCaseManagementService _appCaseManagementService;
private readonly IUserService _userService;
private readonly ISMSService _smsService;
private readonly IEfRepository<AppCaseSupervisor, long> _appSupervisorRepository;
private readonly IEfRepository<AppUser, long> _appUserRepository;
/// <summary>
///
@ -86,7 +92,7 @@ namespace ATS.NonCustodial.Application.Impl.Business
/// <param name="appDeviceManagementRepository"></param>
/// <param name="appSessionInformationRepository"></param>
/// <param name="appCommonFenceService"></param>
public AppEarlyWarningService(IEfRepository<AppEarlyWarning, long> appEarlyWarningRepository,
public AppEarlyWarningService(IEfRepository<AppCaseSupervisor, long> appSupervisorRepository, IEfRepository<AppEarlyWarning, long> appEarlyWarningRepository,
IEfRepository<AppEarlyWarningPushResult, long> appEarlyWarningPushResultRepository,
IHubContext<NonCustodialHub> hubContext,
IEfRepository<AppCaseManagement, long> appCaseManagementRepository,
@ -97,13 +103,14 @@ namespace ATS.NonCustodial.Application.Impl.Business
IEfRepository<AppDeviceManagement, long> appDeviceManagementRepository,
IEfRepository<AppSessionInformation, long> appSessionInformationRepository,
IAppCommonFenceService appCommonFenceService,
IEfRepository<AppUser, long> appUserRepository,
IAppCaseManagementService appCaseManagementService,
IEfRepository<AppBusinessApplication, long> appBusinessApplicationRepository,
IEfRepository<AppSupervisedPersonRealTimeLocation, long> appSupervisedPersonRealTimeLocationRepository,
IClientNotifyService clientNotifyService,
IEfRepository<AppEarlyWarningViewStatistics, long> appEarlyWarningViewStatisticsRepository,
IEfRepository<AppEarlyWarningRule, long> appEarlyWarningRuleRepository)
IEfRepository<AppEarlyWarningRule, long> appEarlyWarningRuleRepository,
ISMSService smsService)
: base(
appCaseManagementRepository,
appCaseSupervisorRepository,
@ -113,6 +120,7 @@ namespace ATS.NonCustodial.Application.Impl.Business
appSupervisedPersonRealTimeLocationRepository
)
{
_appSupervisorRepository = appSupervisorRepository;
_appEarlyWarningRepository = appEarlyWarningRepository;
_appEarlyWarningPushResultRepository = appEarlyWarningPushResultRepository;
_hubContext = hubContext;
@ -124,6 +132,9 @@ namespace ATS.NonCustodial.Application.Impl.Business
_appEarlyWarningRuleRepository = appEarlyWarningRuleRepository;
_appCaseManagementService = appCaseManagementService;
_userService = userService;
_smsService = smsService;
_appUserRepository = appUserRepository;
}
#endregion Identity
@ -144,6 +155,24 @@ namespace ATS.NonCustodial.Application.Impl.Business
//字典
var dictionaryGetOutput = await _appDictionaryService.GetDicByDicId(input.EarlyWarningTypeId);
#region 短信通知逻辑
//被监管人在APP上打卡的时候发现脱离监管区域,后台会有一个实时预警。同时,监管人和被监管人都将收到脱离监管区域的短信。
//根据案件找监管人,找到多个,均发送消息提醒
var supervisorList = await _appSupervisorRepository
.AsQueryable(false, true)
.Where(w => w.CaseId == caseInfo.CaseId)
.ToListAsync();
foreach (var item in supervisorList)
{
var supervisor = await _appUserRepository.AsQueryable(false, true).Where(w => w.Id == item.SupervisorId).ToListAsync();
//发短信给监管人,提醒被监管人脱离监管区域
await _smsService.SendMessageSMS(MessageAlertTypeEnum.RegulatoryAlert, supervisor.FirstOrDefault().UserName, supervisor.FirstOrDefault().Phone, DateTime.Now, dictionaryGetOutput.Name, "", caseInfo.SupervisedPersonName);
}
//通知被监管人
var supervisedPerson = await _appUserRepository.AsQueryable(false, true).Where(w => w.Id == input.SupervisedPersonId).ToListAsync();
await _smsService.SendMessageSMS(MessageAlertTypeEnum.Alert, "", supervisedPerson.FirstOrDefault().Phone, DateTime.Now, dictionaryGetOutput.Name, "", caseInfo.SupervisedPersonName);
#endregion
//公共逻辑
return await EarlyWarningCommLogic(caseInfo, dictionaryGetOutput, null, input.address == null ? "" : input.address);
@ -265,7 +294,20 @@ namespace ATS.NonCustodial.Application.Impl.Business
[AllowAnonymous]
public async Task<IResultOutput> GetPageAsync(AppEarlyWarningGetPageInput input)
{
//获取当前用户权限下的案件ids
var limits = User.limits;
var selectLimits = await _appCaseSupervisorRepository.AsQueryable(false, true)
.Where(w => limits.Contains(w.UnitId.ToString()))
.ToListAsync();
var caseIdList = selectLimits.Select(w => w.CaseId).Distinct().ToList();
var express = await GetExpression(input, _appEarlyWarningRepository.AsQueryable(false, true));
// 先应用案件ID过滤条件
express = express.Where(w => caseIdList.Contains(w.CaseId));
// 然后再获取分页数据
return await base.GetEntityAddPageAsync<AppEarlyWarning, AppEarlyWarningGetPageInput, AppEarlyWarningListDto>(input, express);
}
@ -276,14 +318,20 @@ namespace ATS.NonCustodial.Application.Impl.Business
/// <returns></returns>
[HttpPost]
public async Task<IResultOutput> GetCrossborderStatisticsAsync(AppEarlyWarningGetPageInput input)
{
{ //获取当前用户权限下的案件ids
var limits = User.limits;
var selectLimits = await _appCaseSupervisorRepository.AsQueryable(false, true)
.Where(w => limits.Contains(w.UnitId.ToString()))
.ToListAsync();
var caseIds = selectLimits.Select(w => w.CaseId).Distinct().ToList();
var express = await GetExpression(input, _appEarlyWarningRepository.AsQueryable(false, true));
var grudlist = express
var grudlist = express.Where(p=> caseIds.Contains(p.CaseId))
.WhereIf(input.supname.NotNull(), w => w.SupervisedPersonName.Contains(input.supname))
.GroupBy(q => new { q.CaseId, q.CaseName, q.SupervisedPersonId, q.SupervisedPersonName }).Select(q => new { q.Key.CaseId, q.Key.CaseName, q.Key.SupervisedPersonName, q.Key.SupervisedPersonId, Count = q.ToList().Count() }).Skip((input.PageIndex - 1) * input.PageSize).Take(input.PageSize);
var SupervisedPersonIds = grudlist.Select(q => q.SupervisedPersonId);
var grudlistcunot = express.Where(q => SupervisedPersonIds.Contains(q.SupervisedPersonId)).ToList();
return ResultOutput.Ok(new { TotalCount = express.GroupBy(q => new { q.CaseId, q.CaseName, q.SupervisedPersonId, q.SupervisedPersonName }).Count(), grudlist });
//var SupervisedPersonIds = grudlist.Select(q => q.SupervisedPersonId);
// var grudlistcunot = express.Where(q => SupervisedPersonIds.Contains(q.SupervisedPersonId)).ToList();
return ResultOutput.Ok(new { TotalCount = express.Where(p => caseIds.Contains(p.CaseId)).GroupBy(q => new { q.CaseId, q.CaseName, q.SupervisedPersonId, q.SupervisedPersonName }).Count(), grudlist });
}
@ -373,7 +421,15 @@ namespace ATS.NonCustodial.Application.Impl.Business
/// <returns></returns>
public async Task<IResultOutput> EarlyWarningBusinessWorkbench()
{
var caseIds = await (await base.GetCurrentUserCaseListAsync()).Select(w => w.AppCaseManagement.Id).ToListAsync();
//获取当前用户权限下的案件ids
var limits = User.limits;
var selectLimits = await _appCaseSupervisorRepository.AsQueryable(false, true)
.Where(w => limits.Contains(w.UnitId.ToString()))
.ToListAsync();
var caseIdList = selectLimits.Select(w => w.CaseId).Distinct().ToList();
var caseIds = await (await base.GetCurrentUserCaseListAsync()).Where(w=> w.AppCaseManagement!=null&&caseIdList.Contains(w.AppCaseManagement.Id)).Select(w => w.AppCaseManagement.Id).ToListAsync();
var dataList = await _appEarlyWarningRepository.AsQueryable(false, true)
.Where(w => caseIds.Contains(w.CaseId))
.OrderByDescending(w => w.CreatedTime)
@ -406,7 +462,11 @@ namespace ATS.NonCustodial.Application.Impl.Business
/// <returns></returns>
private async Task<IQueryable<AppEarlyWarning>> GetExpression(AppEarlyWarningGetPageInput pageInput, IQueryable<AppEarlyWarning?> query)
{
var caseIds = await (await base.GetCurrentUserCaseListAsync()).Select(w => w.AppCaseManagement.Id).ToListAsync();
var limits = User.limits;
var selectLimits = await _appCaseSupervisorRepository.AsQueryable(false, true)
.Where(w => limits.Contains(w.UnitId.ToString())).ToListAsync();
var caseIds = selectLimits.Select(w => w.CaseId).Distinct().ToList();
//var caseIds = await (await base.GetCurrentUserCaseListAsync()).Select(w => w.AppCaseManagement.Id).ToListAsync();
query = query.Where(w => caseIds.Contains(w.CaseId))
.WhereIf(pageInput.KeyWord.NotNull(), w => w.Title.Contains(pageInput.KeyWord) || w.CaseName.Contains(pageInput.KeyWord))
@ -415,7 +475,15 @@ namespace ATS.NonCustodial.Application.Impl.Business
.WhereIf(pageInput.UserSearch != null, p => p.SupervisedPersonId == pageInput.UserSearch!.ModifiedUserId);
var express = base.GetEntityAddExpression<AppEarlyWarning, AppEarlyWarningGetPageInput, long>(pageInput, query);
var userRole = await _userService.IsAdmin(null);
//非管理员只能看到自己监管的案件
if (!userRole.IsAdmin)
{
var supervisorCaseList = await _appCaseSupervisorRepository.AsQueryable(false, true)
.Where(w => w.SupervisorId == User.Id).Select(s => s.CaseId).ToListAsync();
express = express.Where(w => supervisorCaseList.Contains(w.CaseId));
}
return express;
}

139
src/2.services/ATS.NonCustodial.Application/Impl/Business/AppManagementService.cs

@ -2,6 +2,7 @@
using ATS.NonCustodial.Application.Contracts.Interfaces.Admins.AppDictionaries;
using ATS.NonCustodial.Application.Contracts.Interfaces.Admins.Auth;
using ATS.NonCustodial.Application.Contracts.Interfaces.Admins.Auth.Output;
using ATS.NonCustodial.Application.Contracts.Interfaces.Admins.SMS;
using ATS.NonCustodial.Application.Contracts.Interfaces.Admins.User;
using ATS.NonCustodial.Application.Contracts.Interfaces.Business.AppAnnouncements;
using ATS.NonCustodial.Application.Contracts.Interfaces.Business.AppAnnouncements.Input;
@ -19,7 +20,6 @@ using ATS.NonCustodial.Application.Contracts.Interfaces.Business.Apps;
using ATS.NonCustodial.Application.Contracts.Interfaces.Business.Apps.Input;
using ATS.NonCustodial.Application.Contracts.Interfaces.Business.Apps.Output;
using ATS.NonCustodial.Application.Contracts.Interfaces.Business.MaterialManager.Directories;
using ATS.NonCustodial.Application.Contracts.Interfaces.Business.MaterialManager.Directories.Output;
using ATS.NonCustodial.Application.Contracts.Interfaces.Business.PunchRecordServices;
using ATS.NonCustodial.Application.Contracts.Interfaces.Business.PunchRecordServices.Input;
using ATS.NonCustodial.Application.Contracts.Interfaces.Business.PunchRecordServices.Output;
@ -48,8 +48,6 @@ using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.SignalR;
using Microsoft.EntityFrameworkCore;
using NPOI.SS.UserModel;
using System.IO;
namespace ATS.NonCustodial.Application.Impl.Business
{
@ -88,6 +86,7 @@ namespace ATS.NonCustodial.Application.Impl.Business
private readonly IAppEarlyWarningService _appEarlyWarningService;
private readonly IAppAnnouncementService _appAnnouncementService;
private readonly IAppDirectorDescriptorService _appDirectorDescriptorService;
private readonly ISMSService _smsService;
/// <summary>
///
@ -137,7 +136,8 @@ namespace ATS.NonCustodial.Application.Impl.Business
IEfRepository<AppSessionMessage, long> appSessionMessageRepository,
IAppEarlyWarningService appEarlyWarningService,
IAppAnnouncementService appAnnouncementService,
IEfRepository<AppEarlyWarningViewStatistics, long> appEarlyWarningViewStatisticsRepository)
IEfRepository<AppEarlyWarningViewStatistics, long> appEarlyWarningViewStatisticsRepository,
ISMSService smsService)
: base(
appManagementRepository,
appSupervisorRepository,
@ -167,6 +167,7 @@ namespace ATS.NonCustodial.Application.Impl.Business
_appEarlyWarningViewStatisticsRepository = appEarlyWarningViewStatisticsRepository;
_appDirectoryDescriptorRepository = appDirectoryDescriptorRepository;
_appFileDescriptorRepository = appFileDescriptorRepository;
_smsService = smsService;
}
#endregion Identity
@ -182,7 +183,8 @@ namespace ATS.NonCustodial.Application.Impl.Business
/// </remarks>
public async Task<IResultOutput<List<SupervisedPersonListOutput>>> GetSupervisedPersonListByName(string? name)
{
var rtn = (await GetCaseListDetail(name)).Where(w => w.Latitude != null && w.Longitude != null).ToList();
//CaseProgressEnum案件已结束的不再展示
var rtn = (await GetCaseListDetail(name)).Where(w => w.Latitude != null && w.Longitude != null && w.CaseProgress != CaseProgressEnum.Closed).ToList();
//返回结果
return (IResultOutput<List<SupervisedPersonListOutput>>)ResultOutput.Ok(rtn);
@ -312,9 +314,9 @@ namespace ATS.NonCustodial.Application.Impl.Business
{
var userCase = await base.GetCurrentSupervisePersonProcessingCase(input.SupervisedPersonId ?? User.Id);
if (userCase == null) return new ResultOutput<PagedList<AppPunchRecordListDto>>();
return (IResultOutput<PagedList<AppPunchRecordListDto>>)await _appPunchRecordService.GetPageAsync(new AppPunchRecordGetPageInput()
return userCase == null
? new ResultOutput<PagedList<AppPunchRecordListDto>>()
: (IResultOutput<PagedList<AppPunchRecordListDto>>)await _appPunchRecordService.GetPageAsync(new AppPunchRecordGetPageInput()
{
Id = userCase.CaseId,
SupervisedPersonId = input.SupervisedPersonId ?? User.Id,
@ -437,9 +439,16 @@ namespace ATS.NonCustodial.Application.Impl.Business
[HttpPost]
public async Task<IResultOutput<PagedList<AppBusinessApplicationListDto>>> GetAppBusinessByStatusListAsync(GetAppBusinessByStatusListPageInput input)
{
//获取当前用户权限下的案件ids
var limits = User.limits;
var selectLimits = await _appCaseSupervisorRepository.AsQueryable(false, true)
.Where(w => limits.Contains(w.UnitId.ToString()))
.ToListAsync();
var caseIdList = selectLimits.Select(w => w.CaseId).Distinct().ToList();
var data = await _appCaseManagementService.GetCaseSuperviseList();
var caseIds = data.Select(w => w.CaseId).ToList();
var caseIds = data.Where(w => caseIdList.Contains(w.CaseId)).Select(w => w.CaseId).ToList();
//业务申请列表
var businessList = await _appBusinessApplicationRepository
@ -553,14 +562,7 @@ namespace ATS.NonCustodial.Application.Impl.Business
{
item.CheckStatus = input.CheckStatus;
if (input.CheckStatus == CheckStatusEnum.Checked)
{
item.CheckTime = DateTime.Now;
}
else
{
item.CheckTime = null;
}
item.CheckTime = input.CheckStatus == CheckStatusEnum.Checked ? DateTime.Now : null;
}
await _appBusinessApplicationViewStatisticsRepository.UpdateAsync(busViewList);
@ -632,10 +634,10 @@ namespace ATS.NonCustodial.Application.Impl.Business
//职位名字
if (User.ChatPersonType != ChatPersonTypeEnum.SupervisedPerson) return item;
{
var positionName = receiverList.FirstOrDefault(w => w.Id == item.ReceiverId)?.PositionName;
if (postDict.ContainsKey(positionName))
var positionName = receiverList.FirstOrDefault(w => w.Id == item.ReceiverId)?.PositionName ?? "未知职位";
if (postDict.TryGetValue(positionName, out int count))
{
postDict[positionName] += 1;
postDict[positionName] = count + 1;
}
else
{
@ -703,9 +705,9 @@ namespace ATS.NonCustodial.Application.Impl.Business
spcr.SupervisedPersonId
}).FirstOrDefaultAsync();
if (data == null) return new ResultOutput<GetSuperPersonCaseDetailDto>();
return await this.GetSuperPersonCaseDetail(new GetSuperPersonCaseDetailInput()
return data == null
? new ResultOutput<GetSuperPersonCaseDetailDto>()
: await this.GetSuperPersonCaseDetail(new GetSuperPersonCaseDetailInput()
{
CaseId = data!.Id,
SuperPersonId = data.SupervisedPersonId
@ -723,7 +725,7 @@ namespace ATS.NonCustodial.Application.Impl.Business
List<AppRemindListDto> rtn;
var totalCount = 0;
//如果SupervisedPersonId不为空并查询结果为空执行下面查询
var currentCase = await GetCurrentSupervisePersonProcessingCase(input.SupervisedPersonId!=null ? (long)input.SupervisedPersonId : User.Id);
var currentCase = await GetCurrentSupervisePersonProcessingCase(input.SupervisedPersonId != null ? (long)input.SupervisedPersonId : User.Id);
if (input.RemindType == AppRemindTypeEnum.EarlyWarning)
{
var earlyWarningList = (from ew in _appEarlyWarningRepository.AsQueryable(false, true)
@ -834,7 +836,31 @@ namespace ATS.NonCustodial.Application.Impl.Business
/// </summary>
/// <returns></returns>
[HttpPost]
public async Task<IResultOutput> AddAppBusinessAsync(AppBusinessApplicationCreateOrModifyInput input) => await _appBusinessApplicationService.CreateOrModify(input);
public async Task<IResultOutput> AddAppBusinessAsync(AppBusinessApplicationCreateOrModifyInput input)
{
var result = await _appBusinessApplicationService.CreateOrModify(input);
if (result.Code == 200)
{
//根据案件找监管人,找到多个,均发送消息提醒
var currentUserCase = await base.GetCurrentSupervisePersonProcessingCase(User.Id);
var supervisorList = await _appSupervisorRepository
.AsQueryable(false, true)
.Where(w => w.CaseId == currentUserCase.CaseId)
.ToListAsync();
var dic = await _appDictionaryService.GetDicByDicId(input.ApplicationTypeId);
//var applicationType = await base.GetDictionariesOutput("application_type", "df");
foreach (var supervisor in supervisorList)
{
var user = await _appUserRepository.AsQueryable(false, true).Where(w => w.Id == supervisor.SupervisorId).ToListAsync();
//发短信给监管人,提醒处理审批
await _smsService.SendMessageSMS(MessageAlertTypeEnum.ReviewNotification, user.FirstOrDefault().UserName, user.FirstOrDefault().Phone, DateTime.Now, dic.Name, "", currentUserCase.SupervisedPersonName);
}
}
return result;
}
/// <summary>
/// 获取被监管人员业务申请列表(正在进行的案件)
@ -848,7 +874,7 @@ namespace ATS.NonCustodial.Application.Impl.Business
join ba in _appBusinessApplicationRepository.AsQueryable(false, true) on c.Id equals ba.CaseId
select ba)
.WhereIf(input.AuditStatus != null, w => w.AuditStatus == input.AuditStatus)
.Where(w => w.SupervisedPersonId == (input.SupervisedPersonId!=null ? input.SupervisedPersonId : User.Id))
.Where(w => w.SupervisedPersonId == (input.SupervisedPersonId != null ? input.SupervisedPersonId : User.Id))
.OrderByDescending(w => w.CreatedTime);
//正在进行的案件
@ -881,14 +907,14 @@ namespace ATS.NonCustodial.Application.Impl.Business
join a in _appSupervisedPersonRepository.AsQueryable(false, true) on c.Id equals a.CaseId
join ba in _appFileAccessRecordsRepository.AsQueryable(false, true) on a.SupervisedPersonId equals ba.SupervisedPersonId
select ba)
.Where(w => w.SupervisedPersonId == (input.SupervisedPersonId!=null ? input.SupervisedPersonId : User.Id))
.Where(w => w.SupervisedPersonId == (input.SupervisedPersonId != null ? input.SupervisedPersonId : User.Id))
.OrderByDescending(w => w.CreatedTime);
var Direclist = (from c in _appDirectoryDescriptorRepository.AsQueryable(false, true)
join a in _appFileDescriptorRepository.AsQueryable(false, true) on c.Id equals a.DirectoryId
select new{ typename=c.Name, a.Name,a.Id,a.DirectoryId }).ToList();
select new { typename = c.Name, a.Name, a.Id, a.DirectoryId }).ToList();
foreach (var item in Direclist)
{
var Direcbol = query.ToList().Where(q => q.FileDescriptorId == item.Id&&q.CaseId==(input.CaseId!=null? input.CaseId:0)).OrderByDescending(q=>q.CreatedTime).ToList();
var Direcbol = query.ToList().Where(q => q.FileDescriptorId == item.Id && q.CaseId == (input.CaseId != null ? input.CaseId : 0)).OrderByDescending(q => q.CreatedTime).ToList();
if (Direcbol.Count > 0)
{
list.Add(new
@ -905,7 +931,7 @@ namespace ATS.NonCustodial.Application.Impl.Business
{
typename = $"{item.typename}",
name = $"{item.Name}",
time="",
time = "",
bol = false
});
}
@ -933,7 +959,10 @@ namespace ATS.NonCustodial.Application.Impl.Business
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
public async Task<IResultOutput> AddPunchRecord(AppPunchRecordAddInput input) => await _appPunchRecordService.AddAsync(input);
public async Task<IResultOutput> AddPunchRecord(AppPunchRecordAddInput input)
{
return await _appPunchRecordService.AddAsync(input);
}
/// <summary>
/// 被监管人登录
@ -982,6 +1011,11 @@ namespace ATS.NonCustodial.Application.Impl.Business
[AllowAnonymous]
public async Task<IResultOutput> SubmitBindingApplication(SubmitBindingApplicationInput input)
{
if (!string.IsNullOrEmpty(input.phone))
{
bool checkCode = await _smsService.CheckCodeAsync(input.phone, input.checkCode, "CheckCode");
if (!checkCode) return ResultOutput.NotOk("验证码错误");
}
//[1]校验当前账户是否是第一次绑定
//if (!await _appSupervisedPersonRepository.AnyAsync(w => w.IdCard == input.IdCard && !w.IsBound)) return ResultOutput.NotOk("当前身份没有被监管,请检查身份证是否输入正确");
if (!await _appSupervisedPersonRepository.AnyAsync(w => w.IdCard == input.IdCard)) return ResultOutput.NotOk("当前身份没有被监管,请检查身份证是否输入正确");
@ -1013,10 +1047,10 @@ namespace ATS.NonCustodial.Application.Impl.Business
spData.EnterFace = input.EnterFace;
spData.IMEI = input.IMEI;
var userdata = _appUserRepository.AsQueryable(false, true).Where(q => q.Id == spData.SupervisedPersonId).FirstOrDefault();
if (userdata!=null)
if (userdata != null)
{
userdata.CId = input.CId;
await _appUserRepository.UpdateAsync(userdata,UpdatingProps<AppUser>(q=>q.CId));
await _appUserRepository.UpdateAsync(userdata, UpdatingProps<AppUser>(q => q.CId));
}
await _appSupervisedPersonRepository.UpdateAsync(spData);
@ -1122,7 +1156,7 @@ namespace ATS.NonCustodial.Application.Impl.Business
var earlyList = await GetRemindListByCurrentUserPageAsync(new AppRemindPageInput()
{
PageIndex = 1,
PageSize = 999999,
PageSize = 100,
CheckStatus = CheckStatusEnum.NotChecked
});
@ -1141,10 +1175,17 @@ namespace ATS.NonCustodial.Application.Impl.Business
/// <returns></returns>
public async Task<IResultOutput<PagedList<AppRemindListDto>>> GetRemindListByCurrentUserPageAsync(AppRemindPageInput input)
{
var limits = User.limits;
var selectLimits = await _appCaseSupervisorRepository.AsQueryable(false, true)
.Where(w => limits.Contains(w.UnitId.ToString()))
.ToListAsync();
var caseIdList = selectLimits.Select(w => w.CaseId).Distinct().ToList();
//预警信息
var earlyList = await (from e in _appEarlyWarningRepository.AsQueryable(false, true)
join ev in _appEarlyWarningViewStatisticsRepository.AsQueryable(false, true) on e.Id equals ev.AppEarlyWarningId
where ev.SubscriberId == User.Id
join cm in _appCaseManagementRepository.AsQueryable(false, true) on e.CaseId equals
cm.Id
where ev.SubscriberId == User.Id && caseIdList.Contains(e.CaseId) && cm.CaseProgress != CaseProgressEnum.Closed
select new AppRemindListDto()
{
Id = e.Id,
@ -1156,9 +1197,11 @@ namespace ATS.NonCustodial.Application.Impl.Business
CreatedTime = e.CreatedTime,
SupervisedPersonId = e.SupervisedPersonId,
SupervisedPersonName = e.SupervisedPersonName,
CaseId = e.CaseId
CaseId = e.CaseId,
EarlyWarningTypeId = e.EarlyWarningTypeId
})
.WhereIf(input.CheckStatus.HasValue, w => w.CheckStatus == input.CheckStatus)
.WhereIf(input.EarlyWarningTypeId.HasValue, w => w.EarlyWarningTypeId == input.EarlyWarningTypeId)
.ToListAsync();
earlyList = earlyList.Distinct((x, y) => x.CaseId == y.CaseId && x.SupervisedPersonId == y.SupervisedPersonId && x.CreatedTime == y.CreatedTime).OrderByDescending(q => q.CreatedTime).ToList();
if (!input.CheckStatus.HasValue)
@ -1188,9 +1231,17 @@ namespace ATS.NonCustodial.Application.Impl.Business
/// <returns></returns>
private async Task<List<SupervisedPersonListOutput>> GetCaseListDetail(string? name)
{
//获取当前用户权限下的案件ids
var limits = User.limits;
var selectLimits = await _appCaseSupervisorRepository.AsQueryable(false, true)
.Where(w => limits.Contains(w.UnitId.ToString()))
.ToListAsync();
var caseIdList = selectLimits.Select(w => w.CaseId).Distinct().ToList();
var data = (await base.GetCurrentUserCaseListAsync())
.Where(W => W.AppCaseManagement.CaseProgress != CaseProgressEnum.Closed)
.Where(W => W.AppCaseSupervisedPerson != null)
.Where(W => W.AppCaseManagement != null && W.AppCaseManagement.CaseProgress != CaseProgressEnum.Closed && caseIdList.Contains(W.AppCaseManagement.Id))
.Where(W => W.AppCaseSupervisedPerson != null && caseIdList.Contains(W.AppCaseSupervisedPerson.CaseId))
.Where(W => W.AppCaseSupervisor != null && caseIdList.Contains(W.AppCaseSupervisor.CaseId))
.WhereIf(name.NotNull(), w => w.AppCaseSupervisedPerson.SupervisedPersonName!.Contains(name))
.Select(w => new
{
@ -1264,8 +1315,18 @@ namespace ATS.NonCustodial.Application.Impl.Business
private async Task<List<SupervisedPersonListOutput>> GetCaseListDetailByIm(string? name)
{
//获取当前用户权限下的案件ids
var limits = User.limits;
var selectLimits = await _appCaseSupervisorRepository.AsQueryable(false, true)
.Where(w => limits.Contains(w.UnitId.ToString()))
.ToListAsync();
var caseIdList = selectLimits.Select(w => w.CaseId).Distinct().ToList();
var data = (await base.GetCurrentUserCaseListAsync())
.Where(W => W.AppCaseManagement.CaseProgress != CaseProgressEnum.Pending)
.Where(W => W.AppCaseManagement != null && W.AppCaseSupervisedPerson != null && W.AppCaseSupervisor != null && W.AppCaseManagement.CaseProgress != CaseProgressEnum.Pending && caseIdList.Contains(W.AppCaseManagement.Id) && caseIdList.Contains(W.AppCaseSupervisedPerson.CaseId) && caseIdList.Contains(W.AppCaseSupervisor.CaseId))
.WhereIf(name.NotNull(), w => w.AppCaseSupervisedPerson.SupervisedPersonName!.Contains(name))
.Select(w => new
{

106
src/2.services/ATS.NonCustodial.Application/Impl/Business/AppPunchRecordService.cs

@ -1,11 +1,7 @@
using System.Linq;
using System.Net;
using System.Net.Cache;
using System.Security.Policy;
using System.Text;
using System.Text.RegularExpressions;
using ATS.NonCustodial.Application.Base;
using ATS.NonCustodial.Application.Base;
using ATS.NonCustodial.Application.Contracts.Interfaces.Admins.AppDictionaries;
using ATS.NonCustodial.Application.Contracts.Interfaces.Admins.AppDictionaries.Output;
using ATS.NonCustodial.Application.Contracts.Interfaces.Admins.SMS;
using ATS.NonCustodial.Application.Contracts.Interfaces.Admins.User;
using ATS.NonCustodial.Application.Contracts.Interfaces.Business.AppCaseManagements.AppCaseManagement;
using ATS.NonCustodial.Application.Contracts.Interfaces.Business.AppEarlyWarnings;
@ -15,7 +11,6 @@ using ATS.NonCustodial.Application.Contracts.Interfaces.Business.IM.Notifies;
using ATS.NonCustodial.Application.Contracts.Interfaces.Business.PunchRecordServices;
using ATS.NonCustodial.Application.Contracts.Interfaces.Business.PunchRecordServices.Input;
using ATS.NonCustodial.Application.Contracts.Interfaces.Business.PunchRecordServices.Output;
using ATS.NonCustodial.Application.Impl.Admins;
using ATS.NonCustodial.Domain.Entities.Admins;
using ATS.NonCustodial.Domain.Entities.Business;
using ATS.NonCustodial.Domain.Entities.Business.CaseManagements;
@ -32,13 +27,11 @@ using ATS.NonCustodial.Shared.Extensions;
using ATS.NonCustodial.Shared.Extensions.Collection;
using AutoMapper.QueryableExtensions;
using Castle.Components.DictionaryAdapter;
using ICSharpCode.SharpZipLib.Zip;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using NPOI.SS.Formula.PTG;
using System.Dynamic;
using System.Linq;
using Yitter.IdGenerator;
namespace ATS.NonCustodial.Application.Impl.Business
@ -60,7 +53,9 @@ namespace ATS.NonCustodial.Application.Impl.Business
private readonly IEfRepository<AppUser, long> _appuserRepository;
private readonly IEfRepository<AppEarlyWarning, long> _appEarlyWarningRepository;
private readonly IEfRepository<appauditrecords, long> _appauditrecordsRepository;
private readonly IEfRepository<AppUser, long> _appUserRepository;
private readonly ISMSService _smsService;
public AppPunchRecordService(IEfRepository<AppPunchRecordStatistics, long> appPunchRecordStatisticsRepository,
IAppCaseManagementService appCaseManagementService,
IEfRepository<AppCaseManagement, long> appCaseManagementRepository,
@ -69,10 +64,12 @@ namespace ATS.NonCustodial.Application.Impl.Business
IEfRepository<AppCaseSupervisor, long> appCaseSupervisorRepository,
IUserService userService,
IAppDictionaryService appDictionaryService,
IEfRepository<AppUser, long> appUserRepository,
IEfRepository<AppSupervisedPersonRealTimeLocation, long> asprl,
IEfRepository<AppUser, long> appuserRepository,
IAppEarlyWarningService appEarlyWarningService, IEfRepository<appauditrecords, long> appauditrecords,
IEfRepository<AppEarlyWarning, long> appEarlyWarningRepository)
IEfRepository<AppEarlyWarning, long> appEarlyWarningRepository,
ISMSService smsService)
: base(
appCaseManagementRepository,
appCaseSupervisorRepository,
@ -88,6 +85,8 @@ namespace ATS.NonCustodial.Application.Impl.Business
_appEarlyWarningRepository = appEarlyWarningRepository;
_appauditrecordsRepository = appauditrecords;
_appuserRepository = appuserRepository;
_smsService = smsService;
_appUserRepository = appUserRepository;
}
#endregion Identity
@ -183,12 +182,26 @@ namespace ATS.NonCustodial.Application.Impl.Business
[HttpPost]
public async Task<IResultOutput> GetPunchPageAsync(AppPunchRecordGetPageInput input)
{
var caseIds = await (await base.GetCurrentUserCaseListAsync()).Select(w => w.AppCaseManagement.Id).ToListAsync();
//获取当前用户权限下的案件ids
var limits = User.limits;
var selectLimits = await _appCaseSupervisorRepository.AsQueryable(false, true)
.Where(w => limits.Contains(w.UnitId.ToString()))
.ToListAsync();
var caseIds = selectLimits.Select(w => w.CaseId).Distinct().ToList();
var userRole = await _userService.IsAdmin(null);
var supervisorCaseList = await _appCaseSupervisorRepository.AsQueryable(false, true)
.Where(w => w.SupervisorId == User.Id).Select(s => s.CaseId).ToListAsync();
// var intersection1 = supervisorCaseList.Intersect(supervisorCaseList).ToList();
// var caseIds = await (await base.GetCurrentUserCaseListAsync()).Select(w => w.AppCaseManagement.Id).ToListAsync();
//var list= await base._appSupervisedPersonRepository.AsQueryable(false, true).Where(q=> caseIds.Contains(q.CaseId)).ToListAsync();
var data = await _appPunchRecordStatisticsRepository
.AsQueryable(false, true)
.Where(w => caseIds.Contains(w.CaseId))
.WhereIf(!userRole.IsAdmin,w=> supervisorCaseList.Contains(w.CaseId))
.WhereIf(!string.IsNullOrEmpty(input.name), q => q.SupervisedPersonName.Contains(input.name))
.OrderByDescending(r => r.CreatedTime)
.ProjectTo<AppPunchRecordListDto>(Mapper.ConfigurationProvider)
@ -208,7 +221,7 @@ namespace ATS.NonCustodial.Application.Impl.Business
input.PunchVideo = input.PunchVideo?.Replace("\\", "/");
input.PunchVideo = input.PunchVideo.Substring(input.PunchVideo.LastIndexOf("/upload/admin"));
//就是那个傻逼App开发人员啥都不想传
var entity = Mapper.Map<AppPunchRecordStatistics>(input);
//[获取当前[被监管挂人员]的案件
@ -222,6 +235,14 @@ namespace ATS.NonCustodial.Application.Impl.Business
await _appPunchRecordStatisticsRepository.InsertAsync(entity);
#region 每次打卡成功,清空未打卡记录次数
var person = await _appSupervisedPersonRepository.AsQueryable(false, true).Where(w => w.CaseId == caseInfo.CaseId && w.SupervisedPersonId == caseInfo.SupervisedPersonId).ToListAsync();
if (person.Count > 0)
{
person.FirstOrDefault().AttendanceRecord = 0;
await _appSupervisedPersonRepository.UpdateAsync(person);
}
#endregion
#region 打卡消息推送手机通知栏
//被监管人id
var list = new List<long>();
@ -234,8 +255,8 @@ namespace ATS.NonCustodial.Application.Impl.Business
SupervisedIds.Add(q.SupervisedId);
});
//获取监管人手机唯一id
var supervisecids=_appuserRepository.AsQueryable(false, true).ToList().Where(q => SupervisedIds.Contains(q.Id));
if (supervisecids.Where(q=>!string.IsNullOrEmpty(q.CId)).Count()>0)
var supervisecids = _appuserRepository.AsQueryable(false, true).ToList().Where(q => SupervisedIds.Contains(q.Id));
if (supervisecids.Where(q => !string.IsNullOrEmpty(q.CId)).Count() > 0)
{
try
{
@ -247,7 +268,7 @@ namespace ATS.NonCustodial.Application.Impl.Business
base.GettoekenQuery();
var tokenstr = Cache.Get("token");
var msg_list = new List<dynamic>();
foreach (var item in supervisecids.Where(q=> !string.IsNullOrEmpty(q.CId)))
foreach (var item in supervisecids.Where(q => !string.IsNullOrEmpty(q.CId)))
{
//随机生成数
var request_id = Guid.NewGuid().ToString().Replace("-", "").Substring(0, 32).ToString();
@ -345,12 +366,20 @@ namespace ATS.NonCustodial.Application.Impl.Business
case null:
break;
}
//获取当前用户权限下的案件ids
var limits = User.limits;
var selectLimits = await _appCaseSupervisorRepository.AsQueryable(false, true)
.Where(w => limits.Contains(w.UnitId.ToString()))
.ToListAsync();
var caseIdList = selectLimits.Select(w => w.CaseId).Distinct().ToList();
//根据当前登录人查看其手里的案件被监管人
var spList = await base.GetCurrentUserCaseListAsync();
var spIds = await spList.Where(q => q.AppCaseSupervisedPerson != null).Select(w => w.AppCaseSupervisedPerson!.SupervisedPersonId).ToListAsync();
var spIds = await spList.Where(q => q.AppCaseSupervisedPerson != null && caseIdList.Contains(q.AppCaseSupervisedPerson.CaseId)).Select(w => w.AppCaseSupervisedPerson!.SupervisedPersonId).ToListAsync();
//查询记录
var query = await _appPunchRecordStatisticsRepository
.AsQueryable(false, true).Where(q => spIds.Contains(q.SupervisedPersonId))
.AsQueryable(false, true).Where(q => spIds.Contains(q.SupervisedPersonId) && caseIdList.Contains(q.CaseId))
.WhereIf(input.CaseId != default, a => a.CaseId == input.CaseId)
.WhereIf(input.SupervisedPersonId != default, w => w.SupervisedPersonId == input.SupervisedPersonId)
.WhereIf(startTime != DateTime.MinValue, w => w.CreatedTime >= startTime)
@ -400,11 +429,13 @@ namespace ATS.NonCustodial.Application.Impl.Business
[HttpGet, AllowAnonymous]
public async Task<IResultOutput> CheckPunchRecordForJob1()
{
var limits = User.limits;
//[1]获取所有正在执行中的被监管人案件
var allCaseList = await (from c in _appCaseManagementRepository.AsQueryable(false, true)
join csr in _appCaseSupervisorRepository.AsQueryable(false, true) on c.Id equals csr.CaseId
join cspr in _appSupervisedPersonRepository.AsQueryable(false, true) on c.Id equals cspr.CaseId
where c.CaseProgress != CaseProgressEnum.Pending&& c.CaseProgress != CaseProgressEnum.Closed
where c.CaseProgress != CaseProgressEnum.Pending && c.CaseProgress != CaseProgressEnum.Closed && limits.Contains((char)csr.UnitId)
select new CheckPunchRecordForJobOutput()
{
CaseId = c.Id,
@ -532,6 +563,7 @@ namespace ATS.NonCustodial.Application.Impl.Business
[HttpGet, AllowAnonymous]
public async Task<IResultOutput> CheckPunchRecordForJob()
{
// var limits = User.limits;
//[1]获取所有正在执行中的被监管人案件
var allCaseList = await (from c in _appCaseManagementRepository.AsQueryable(false, true)
join csr in _appCaseSupervisorRepository.AsQueryable(false, true) on c.Id equals csr.CaseId
@ -606,7 +638,8 @@ namespace ATS.NonCustodial.Application.Impl.Business
SupervisedPersonName = item.SupervisedPersonName,
SupervisorId = item.SupervisorId,
SupervisorName = item.SupervisorName,
CaseId = item.CaseId
CaseId = item.CaseId,
CaseName = item.CaseName
});
}
}
@ -627,6 +660,7 @@ namespace ATS.NonCustodial.Application.Impl.Business
Title = dict == null ? "" : dict.Name,
CaseId = w.CaseId.Value,
Content = w.Content,
CaseName = w.CaseName,
EarlyWarningTypeId = dict?.Id ?? default,
SupervisedPersonId = w.SupervisedPersonId,
SupervisedPersonName = w.SupervisedPersonName,
@ -651,7 +685,35 @@ namespace ATS.NonCustodial.Application.Impl.Business
earlyEntity.Content!.Contains(w.Content))).ToList();
await _earlyWarningService.BatchAddAsync(earlyEntities);
#region 循环判断每一个未打卡预警,对app_case_supervised_person表的AttendanceRecord字段加一,若AttendanceRecord大于预警阈值,进行短信通知
foreach (var item in earlyEntities)
{
var person = await _appSupervisedPersonRepository.AsQueryable(false, true).Where(w => w.CaseId == item.CaseId && w.SupervisedPersonId == item.SupervisedPersonId).ToListAsync();
if (person.Count > 0)
{
person.FirstOrDefault().AttendanceRecord +=1;
await _appSupervisedPersonRepository.UpdateAsync(person);
var appCase = await _appCaseManagementRepository.AsQueryable(false, true).Where(w => w.Id == item.CaseId).ToListAsync();
if(appCase.FirstOrDefault().Threshold<= person.FirstOrDefault().AttendanceRecord)
{
var supervisedPerson = await _appUserRepository.AsQueryable(false, true).Where(w => w.Id == item.SupervisedPersonId).ToListAsync();
//通知被监管人
await _smsService.SendMessageSMS(MessageAlertTypeEnum.Alert, "", supervisedPerson.FirstOrDefault().Phone, DateTime.Now, "连续未打卡", "", item.SupervisedPersonName);
var supervisorList = await _appCaseSupervisorRepository.AsQueryable(false, true).Where(w => w.CaseId == item.CaseId).ToListAsync();
foreach (var sup in supervisorList)
{
var supervisor = await _appUserRepository.AsQueryable(false, true).Where(w => w.Id == sup.SupervisorId).ToListAsync();
//发短信给监管人,提醒被监管人脱离监管区域
await _smsService.SendMessageSMS(MessageAlertTypeEnum.RegulatoryAlert, supervisor.FirstOrDefault().UserName, supervisor.FirstOrDefault().Phone, DateTime.Now, "连续未打卡", "", item.SupervisedPersonName);
}
}
}
}
#endregion
//根据当前被监管人员的预警信息,计算出应该被通知的人员(被监管人员自己、监管人、管理员)
var earlyWarningRecord = await base.GetEarlyWarningRecord(earlyEntities);

408
src/2.services/ATS.NonCustodial.Application/Impl/Business/AppViolationStatisticsService.cs

@ -1,32 +1,31 @@
using ATS.NonCustodial.Application.Base;
using ATS.NonCustodial.Application.Contracts.Interfaces.Admins.AppDictionaries;
using ATS.NonCustodial.Application.Contracts.Interfaces.Admins.User;
using ATS.NonCustodial.Application.Contracts.Interfaces.Business.AppCaseManagements.AppCaseManagement;
using ATS.NonCustodial.Application.Contracts.Interfaces.Business.AppCaseManagements.AppCaseManagement.Input;
using ATS.NonCustodial.Application.Contracts.Interfaces.Business.AppCaseManagements.AppCaseManagement.Output;
using ATS.NonCustodial.Application.Contracts.Interfaces.Business.AppEarlyWarnings;
using ATS.NonCustodial.Application.Contracts.Interfaces.Business.AppEarlyWarnings.Output;
using ATS.NonCustodial.Application.Contracts.Interfaces.Business.IM.Notifies;
using ATS.NonCustodial.Application.Contracts.Interfaces.Business.ViolationStatistics;
using ATS.NonCustodial.Application.Contracts.Interfaces.Business.ViolationStatistics.Input;
using ATS.NonCustodial.Application.Contracts.Interfaces.Business.ViolationStatistics.Output;
using ATS.NonCustodial.Domain.Entities.Admins;
using ATS.NonCustodial.Domain.Entities.Business;
using ATS.NonCustodial.Domain.Entities.Business.CaseManagements;
using ATS.NonCustodial.Domain.Entities.Business.EarlyWarning;
using ATS.NonCustodial.Domain.Shared.AggRootEntities.Dtos;
using ATS.NonCustodial.Domain.Shared.Enums;
using ATS.NonCustodial.Domain.Shared.OrmRepositories.Basic.EfCore;
using ATS.NonCustodial.DynamicApi;
using ATS.NonCustodial.DynamicApi.Attributes;
using ATS.NonCustodial.Shared.Common.Auth;
using ATS.NonCustodial.Shared.Common.Dtos;
using ATS.NonCustodial.Shared.Common.UnifiedResults;
using ATS.NonCustodial.Shared.Extensions;
using ATS.NonCustodial.Shared.Extensions.Collection;
using ATS.NonCustodial.Shared.Helpers;
using AutoMapper.QueryableExtensions;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using NPOI.SS.Formula.Functions;
using System.Collections.Generic;
using static Microsoft.EntityFrameworkCore.DbLoggerCategory;
using StackExchange.Profiling.Internal;
using static System.Runtime.InteropServices.JavaScript.JSType;
namespace ATS.NonCustodial.Application.Impl.Business
{
@ -44,6 +43,9 @@ namespace ATS.NonCustodial.Application.Impl.Business
private readonly IAppDictionaryService _appDictionaryService;
private readonly IEfRepository<AppEarlyWarning, long> _appEarlyWarningRepository;
private readonly IUserService _userService;
private readonly IEfRepository<AppCaseSupervisedPerson, long> _appSupervisedPersonRepository;
private readonly IEfRepository<AppCaseSupervisor, long> _appSupervisorRepository;
private readonly IEfRepository<AppUser?, long> _userRepository;
/// <summary>
///
@ -52,7 +54,7 @@ namespace ATS.NonCustodial.Application.Impl.Business
/// <param name="appDictionaryService"></param>
/// <param name="appEarlyWarningRepository"></param>
/// <param name="userService"></param>
public AppViolationStatisticsService(IEfRepository<AppViolationStatistics, long> appViolationStatisticsRepository,
public AppViolationStatisticsService(IEfRepository<AppUser?, long> userRepository, IEfRepository<AppCaseSupervisor, long> appSupervisorRepository, IEfRepository<AppViolationStatistics, long> appViolationStatisticsRepository,
IAppDictionaryService appDictionaryService,
IEfRepository<AppEarlyWarning, long> appEarlyWarningRepository,
IUserService userService,
@ -60,17 +62,20 @@ namespace ATS.NonCustodial.Application.Impl.Business
IEfRepository<AppCaseManagement, long> appCaseManagementRepository,
IEfRepository<AppCaseSupervisedPerson, long> appCaseSupervisedPersonRepository,
IEfRepository<AppCaseSupervisor, long> appCaseSupervisorRepository
):base(appCaseManagementRepository,
) : base(appCaseManagementRepository,
appCaseSupervisorRepository,
appCaseSupervisedPersonRepository,
userService,
appDictionaryService,
asprl)
{
_appSupervisorRepository = appSupervisorRepository;
_appViolationStatisticsRepository = appViolationStatisticsRepository;
_appDictionaryService = appDictionaryService;
_appEarlyWarningRepository = appEarlyWarningRepository;
_userService = userService;
_appSupervisedPersonRepository = appCaseSupervisedPersonRepository;
_userRepository = userRepository;
}
#endregion Identity
@ -100,20 +105,28 @@ namespace ATS.NonCustodial.Application.Impl.Business
[HttpPost]
public async Task<IResultOutput> ViolationStatisticsPageAsync(ViolationStatisticsPageInput input)
{
//获取当前用户权限下的案件ids
var limits = User.limits;
var selectLimits = await _appCaseSupervisorRepository.AsQueryable(false, true)
.Where(w => limits.Contains(w.UnitId.ToString()))
.ToListAsync();
var caseIdList = selectLimits.Select(w => w.CaseId).Distinct().ToList();
//根据当前登录人查看其手里的案件被监管人
var spList = await base.GetCurrentUserCaseListAsync();
//获取案件信息
var casebaselist = await spList.Where(q => q.AppCaseManagement != null).Select(q => q.AppCaseManagement).ToListAsync();
var casebaselist = await spList.Where(q => q.AppCaseManagement != null && caseIdList.Contains(q.AppCaseManagement.Id)).Select(q => q.AppCaseManagement).ToListAsync();
//获取案件id
var casebase = await spList
.Where(q => q.AppCaseManagement != null)
.Where(q => q.AppCaseManagement != null && caseIdList.Contains(q.AppCaseManagement.Id))
.WhereIf(input.CaseProgress != null, a => a.AppCaseManagement.CaseProgress == input.CaseProgress).Select(q => q.AppCaseManagement.Id).ToListAsync();
var spIds = await spList.Where(q => q.AppCaseSupervisedPerson != null&& casebase.Contains(q.AppCaseSupervisedPerson.CaseId)).Select(w => w.AppCaseSupervisedPerson!.SupervisedPersonId).ToListAsync();
var spIds = await spList.Where(q => q.AppCaseSupervisedPerson != null && casebase.Contains(q.AppCaseSupervisedPerson.CaseId)).Select(w => w.AppCaseSupervisedPerson!.SupervisedPersonId).ToListAsync();
//查询记录
var query = await _appEarlyWarningRepository
.AsQueryable(false, true).Where(q=> spIds.Contains(q.SupervisedPersonId))
.AsQueryable(false, true).Where(q => spIds.Contains(q.SupervisedPersonId))
.Where(w=> caseIdList.Contains(w.CaseId))
.WhereIf(input.CaseId != default, a => a.CaseId == input.CaseId)
.WhereIf(input.SupervisedPersonId != default, w => w.SupervisedPersonId == input.SupervisedPersonId)
.WhereIf(input.SupervisedPersonName.HasValue(), w => w.SupervisedPersonName.Contains(input.SupervisedPersonName))
.WhereIf(input.TimeSearch?.BeginTime != null && input.TimeSearch?.EndTime != null, q => q.CreatedTime >= input.TimeSearch.BeginTime && q.CreatedTime <= $"{input.TimeSearch.EndTime.Value.ToString("yyyy-MM-dd")} 23:59:59".ToDateTime())
.ToListAsync();
@ -133,7 +146,7 @@ namespace ATS.NonCustodial.Application.Impl.Business
{
CaseId = data.Key.CaseId,
SupervisedPersonId = data.Key.SupervisedPersonId,
CaseName = casebaselist.Where(q=>q.Id==data.Key.CaseId).First()?.Name,
CaseName = casebaselist.Where(q => q.Id == data.Key.CaseId).First()?.Name,
//data.Key.CaseName,
SupervisedPersonName = data.Key.SupervisedPersonName,
CaseProgress = casebaselist.Where(q => q.Id == data.Key.CaseId).First()?.CaseProgress,
@ -149,7 +162,68 @@ namespace ATS.NonCustodial.Application.Impl.Business
return ResultOutput.Ok(pageResult);
}
/// <summary>
/// 违规记录统计导出
/// </summary>
/// <returns></returns>
[HttpPost]
public async Task<IActionResult> ViolationStatisticsExportAsync(ViolationStatisticsPageInput input)
{
//获取当前用户权限下的案件ids
var limits = User.limits;
var selectLimits = await _appCaseSupervisorRepository.AsQueryable(false, true)
.Where(w => limits.Contains(w.UnitId.ToString()))
.ToListAsync();
var caseIdList = selectLimits.Select(w => w.CaseId).Distinct().ToList();
//根据当前登录人查看其手里的案件被监管人
var spList = await base.GetCurrentUserCaseListAsync();
//获取案件信息
var casebaselist = await spList.Where(q => q.AppCaseManagement != null && caseIdList.Contains(q.AppCaseManagement.Id)).Select(q => q.AppCaseManagement).ToListAsync();
//获取案件id
var casebase = await spList
.Where(q => q.AppCaseManagement != null && caseIdList.Contains(q.AppCaseManagement.Id))
.WhereIf(input.CaseProgress != null, a => a.AppCaseManagement.CaseProgress == input.CaseProgress).Select(q => q.AppCaseManagement.Id).ToListAsync();
var spIds = await spList.Where(q => q.AppCaseSupervisedPerson != null && casebase.Contains(q.AppCaseSupervisedPerson.CaseId)).Select(w => w.AppCaseSupervisedPerson!.SupervisedPersonId).ToListAsync();
//查询记录
var query = await _appEarlyWarningRepository
.AsQueryable(false, true).Where(q => spIds.Contains(q.SupervisedPersonId))
.WhereIf(input.CaseId != default, a => a.CaseId == input.CaseId)
.WhereIf(input.SupervisedPersonId != default, w => w.SupervisedPersonId == input.SupervisedPersonId)
.WhereIf(input.SupervisedPersonName.HasValue(), w => w.SupervisedPersonName.Contains(input.SupervisedPersonName))
.WhereIf(input.TimeSearch?.BeginTime != null && input.TimeSearch?.EndTime != null, q => q.CreatedTime >= input.TimeSearch.BeginTime && q.CreatedTime <= $"{input.TimeSearch.EndTime.Value.ToString("yyyy-MM-dd")} 23:59:59".ToDateTime())
.ToListAsync();
//分组
var dataGroup = query
.GroupBy(w => new { w.CaseId, w.SupervisedPersonId, w.CaseName, w.SupervisedPersonName });
var pageData = dataGroup.Skip((input.PageIndex - 1) * input.PageSize)
.Take(input.PageSize);
//处理身份证字段
var userList = await _userService.GetAllByConditionAsync(new BatchIdsInput()
{
Ids = pageData.Select(w => w.Key.SupervisedPersonId).ToList()
});
//(0:待执行 1:侦查阶段 2:已结束,3:审查起诉阶段,4:审理阶段)
var dataList = pageData.Select(data => new ViolationStatisticsExportDto()
{
CaseId = data.Key.CaseId,
SupervisedPersonId = data.Key.SupervisedPersonId,
CaseName = casebaselist.Where(q => q.Id == data.Key.CaseId).First()?.Name,
//data.Key.CaseName,
SupervisedPersonName = data.Key.SupervisedPersonName,
CaseProgress = casebaselist.Where(q => q.Id == data.Key.CaseId).First()?.CaseProgress.ToDescription(),
Violations = data.Count(),
IdCard = userList.FirstOrDefault(w => w.Id == data.Key.SupervisedPersonId)?.IdCard
}).ToList();
var memorySystem = ExcelHelper.ToExcel(dataList);
return new FileController().File(memorySystem.ToArray(), "application/ms-excel", DateTime.Now.ToString("f") + ".xlsx");
}
/// <summary>
/// 违规人数分页查询
@ -164,12 +238,12 @@ namespace ATS.NonCustodial.Application.Impl.Business
var casebase = spList.Select(q => q.Id);
//查询记录
var query = await _appEarlyWarningRepository
.AsQueryable(false, true).Where(q => casebase.Contains(q.CaseId)&& !string.IsNullOrEmpty(q.Title))
.AsQueryable(false, true).Where(q => casebase.Contains(q.CaseId) && !string.IsNullOrEmpty(q.Title))
.WhereIf(input.CaseId != default, a => a.CaseId == input.CaseId)
.WhereIf(input.Wglx != null, a => a.EarlyWarningTypeId == input.Wglx)
.WhereIf(input.SupervisedPersonId != default, w => w.SupervisedPersonId == input.SupervisedPersonId)
.WhereIf(input.TimeSearch?.BeginTime != null && input.TimeSearch?.EndTime != null, q => q.CreatedTime >= input.TimeSearch.BeginTime && q.CreatedTime <= $"{input.TimeSearch.EndTime.Value.ToString("yyyy-MM-dd")} 23:59:59".ToDateTime())
.OrderByDescending(q=>q.CreatedTime)
.OrderByDescending(q => q.CreatedTime)
.ToListAsync();
//分组
@ -191,7 +265,7 @@ namespace ATS.NonCustodial.Application.Impl.Business
//data.Key.CaseName,
SupervisedPersonName = data.SupervisedPersonName,
IdCard = userList.FirstOrDefault(w => w.Id == data.SupervisedPersonId)?.IdCard,
Wgtime= data?.CreatedTime,
Wgtime = data?.CreatedTime,
Wglx = data?.Title,
}).ToList();
@ -217,14 +291,302 @@ namespace ATS.NonCustodial.Application.Impl.Business
var list = await _appEarlyWarningRepository
.AsQueryable(false, true)
.WhereIf(input.TimeSearch.BeginTime != null && input.TimeSearch.EndTime != null, q => q.CreatedTime >= input.TimeSearch.BeginTime && q.CreatedTime <= $"{input.TimeSearch.EndTime.Value.ToString("yyyy-MM-dd")} 23:59:59".ToDateTime())
.WhereIf(input.Wglx!=null, q=>q.EarlyWarningTypeId == input.Wglx)
.WhereIf(input.Wglx != null, q => q.EarlyWarningTypeId == input.Wglx)
.Where(q => caseIds.Contains(q.CaseId)).ToListAsync();
var geruplist = list.Where(q=>!string.IsNullOrEmpty(q.Title)).GroupBy(q => q.Title).Select(q => new { name = q.Key, value = q.Distinct((a, b) => a.SupervisedPersonId == b.SupervisedPersonId).Count() });
var count = geruplist.Sum(q=>q.value);
return ResultOutput.Ok(new { count=count, data = geruplist,list= list.Distinct((a, b) => a.SupervisedPersonId == b.SupervisedPersonId&&a.Title == b.Title).ToList() });
var geruplist = list.Where(q => !string.IsNullOrEmpty(q.Title)).GroupBy(q => q.Title).Select(q => new { name = q.Key, value = q.Distinct((a, b) => a.SupervisedPersonId == b.SupervisedPersonId).Count() });
var count = geruplist.Sum(q => q.value);
return ResultOutput.Ok(new { count = count, data = geruplist, list = list.Distinct((a, b) => a.SupervisedPersonId == b.SupervisedPersonId && a.Title == b.Title).ToList() });
}
/// <summary>
/// 未打卡统计
/// </summary>
/// <returns></returns>
[HttpPost]
public async Task<IResultOutput> NotClockedStatisticsPageAsync(NotClockedInput input)
{
//获取当前用户权限下的案件ids
var limits = User.limits;
var selectLimits = await _appCaseSupervisorRepository.AsQueryable(false, true)
.Where(w => limits.Contains(w.UnitId.ToString()))
.ToListAsync();
var caseIdList = selectLimits.Select(w => w.CaseId).Distinct().ToList();
var userRole = await _userService.IsAdmin(null);
var supervisorCaseList = await _appCaseSupervisorRepository.AsQueryable(false, true)
.Where(w => w.SupervisorId == User.Id).Select(s => s.CaseId).ToListAsync();
var caseList = await _appCaseManagementRepository.AsQueryable(false, true)
.Where(w => caseIdList.Contains(w.Id))
.WhereIf(input.CaseId.HasValue, w => w.Id == input.CaseId)
.WhereIf(!userRole.IsAdmin, w => supervisorCaseList.Contains(w.Id))
.ToListAsync();
var applicationType = await base.GetDictionariesOutput("early_warning_type", "notClocked");
List<NotClockListDto> notClockList = new List<NotClockListDto>();
foreach (var item in caseList)
{
if (item == null) continue;
var caseType= await _appDictionaryService.GetDicByDicId(item.CaseTypeId);
var unitList = await (from c in _appSupervisorRepository.AsQueryable(false, true)
join u in _userRepository.AsQueryable(false, true) on c.SupervisorId equals u.Id
where c.CaseId == item.Id
select u.Unitname).FirstOrDefaultAsync();
//根据案件找到被监管
var supervisedPerson = await _appSupervisedPersonRepository
.AsQueryable(false, true)
.Where(w => w.CaseId == item.Id)
.ToListAsync();
foreach (var person in supervisedPerson)
{
NotClockListDto notClockListDto = new NotClockListDto();
notClockListDto.Bmsah = item.Bmsah;
notClockListDto.CaseId = item.Id;
notClockListDto.CaseName = item.Name;
notClockListDto.CreatedTime = item.CreatedTime;
notClockListDto.CaseTypeName = caseType.Name;
notClockListDto.SupervisedPersonId = person.SupervisedPersonId;
notClockListDto.SupervisedPersonName = person.SupervisedPersonName;
notClockListDto.SupervisionUnit = unitList;
var earlyList = await _appEarlyWarningRepository
.AsQueryable(false, true)
.Where(w => w.EarlyWarningTypeId == applicationType.Id && w.SupervisedPersonId == person.SupervisedPersonId
&& w.CaseId == item.Id)
.WhereIf(input.EndCreatedTime.HasValue, w => w.CreatedTime <= input.EndCreatedTime)
.WhereIf(input.StartCreatedTime.HasValue, w => w.CreatedTime >= input.StartCreatedTime)
.ToListAsync();
notClockListDto.NotClockedCount= earlyList.Count;
notClockList.Add(notClockListDto);
}
}
var pageData = notClockList.Skip((input.PageIndex - 1) * input.PageSize)
.Take(input.PageSize).ToList();
var pageResult = new PagedList<NotClockListDto>()
{
TotalCount = notClockList.Count(),
Data = pageData
};
return ResultOutput.Ok(pageResult);
}
/// <summary>
/// 越界统计
/// </summary>
/// <returns></returns>
[HttpPost]
public async Task<IResultOutput> LeaveAreaStatisticsPageAsync(NotClockedInput input)
{
//获取当前用户权限下的案件ids
var limits = User.limits;
var selectLimits = await _appCaseSupervisorRepository.AsQueryable(false, true)
.Where(w => limits.Contains(w.UnitId.ToString()))
.ToListAsync();
var caseIdList = selectLimits.Select(w => w.CaseId).Distinct().ToList();
var userRole = await _userService.IsAdmin(null);
var supervisorCaseList = await _appCaseSupervisorRepository.AsQueryable(false, true)
.Where(w => w.SupervisorId == User.Id).Select(s => s.CaseId).ToListAsync();
var caseList = await _appCaseManagementRepository.AsQueryable(false, true)
.Where(w => caseIdList.Contains(w.Id))
.WhereIf(input.CaseId.HasValue, w => w.Id == input.CaseId)
.WhereIf(!userRole.IsAdmin, w => supervisorCaseList.Contains(w.Id))
.ToListAsync();
var applicationType = await base.GetDictionariesOutput("early_warning_type", "LeaveArea");
List<ViolationListDto> notClockList = new List<ViolationListDto>();
foreach (var item in caseList)
{
if (item == null) continue;
var caseType = await _appDictionaryService.GetDicByDicId(item.CaseTypeId);
var unitList =await (from c in _appSupervisorRepository.AsQueryable(false, true)
join u in _userRepository.AsQueryable(false, true) on c.SupervisorId equals u.Id
where c.CaseId == item.Id
select u.Unitname).FirstOrDefaultAsync();
//根据案件找到被监管
var supervisedPerson = await _appSupervisedPersonRepository
.AsQueryable(false, true)
.Where(w => w.CaseId == item.Id)
.ToListAsync();
foreach (var person in supervisedPerson)
{
ViolationListDto notClockListDto = new ViolationListDto();
notClockListDto.Bmsah = item.Bmsah;
notClockListDto.CaseId = item.Id;
notClockListDto.CaseName = item.Name;
notClockListDto.CreatedTime = item.CreatedTime;
notClockListDto.CaseTypeName = caseType.Name;
notClockListDto.SupervisionUnit = unitList;
notClockListDto.SupervisedPersonId = person.SupervisedPersonId;
notClockListDto.SupervisedPersonName = person.SupervisedPersonName;
var earlyList = await _appEarlyWarningRepository
.AsQueryable(false, true)
.Where(w => w.EarlyWarningTypeId == applicationType.Id && w.SupervisedPersonId == person.SupervisedPersonId
&& w.CaseId == item.Id)
.WhereIf(input.EndCreatedTime.HasValue, w => w.CreatedTime <= input.EndCreatedTime)
.WhereIf(input.StartCreatedTime.HasValue, w => w.CreatedTime >= input.StartCreatedTime)
.ToListAsync();
notClockListDto.ViolationCount = earlyList.Count;
notClockList.Add(notClockListDto);
}
}
var pageData = notClockList.Skip((input.PageIndex - 1) * input.PageSize)
.Take(input.PageSize).ToList();
var pageResult = new PagedList<ViolationListDto>()
{
TotalCount = notClockList.Count(),
Data = pageData
};
return ResultOutput.Ok(pageResult);
}
/// <summary>
/// 越界统计导出
/// </summary>
/// <returns></returns>
[HttpPost]
public async Task<IActionResult> LeaveAreaStatisticsExportAsync(NotClockedInput input)
{
//获取当前用户权限下的案件ids
var limits = User.limits;
var selectLimits = await _appCaseSupervisorRepository.AsQueryable(false, true)
.Where(w => limits.Contains(w.UnitId.ToString()))
.ToListAsync();
var caseIdList = selectLimits.Select(w => w.CaseId).Distinct().ToList();
var userRole = await _userService.IsAdmin(null);
var supervisorCaseList = await _appCaseSupervisorRepository.AsQueryable(false, true)
.Where(w => w.SupervisorId == User.Id).Select(s => s.CaseId).ToListAsync();
var caseList = await _appCaseManagementRepository.AsQueryable(false, true)
.Where(w => caseIdList.Contains(w.Id))
.WhereIf(input.CaseId.HasValue, w => w.Id == input.CaseId)
.WhereIf(!userRole.IsAdmin, w => supervisorCaseList.Contains(w.Id))
.ToListAsync();
var applicationType = await base.GetDictionariesOutput("early_warning_type", "LeaveArea");
List<ViolationExportDto> notClockList = new List<ViolationExportDto>();
foreach (var item in caseList)
{
if (item == null) continue;
var caseType = await _appDictionaryService.GetDicByDicId(item.CaseTypeId);
var unitList = await (from c in _appSupervisorRepository.AsQueryable(false, true)
join u in _userRepository.AsQueryable(false, true) on c.SupervisorId equals u.Id
where c.CaseId == item.Id
select u.Unitname).FirstOrDefaultAsync();
//根据案件找到被监管
var supervisedPerson = await _appSupervisedPersonRepository
.AsQueryable(false, true)
.Where(w => w.CaseId == item.Id)
.ToListAsync();
foreach (var person in supervisedPerson)
{
ViolationExportDto notClockListDto = new ViolationExportDto();
notClockListDto.Bmsah = item.Bmsah;
notClockListDto.CaseId = item.Id;
notClockListDto.CaseName = item.Name;
notClockListDto.CreatedTime = item.CreatedTime;
notClockListDto.CaseTypeName = caseType.Name;
notClockListDto.SupervisionUnit = unitList;
notClockListDto.SupervisedPersonId = person.SupervisedPersonId;
notClockListDto.SupervisedPersonName = person.SupervisedPersonName;
var earlyList = await _appEarlyWarningRepository
.AsQueryable(false, true)
.Where(w => w.EarlyWarningTypeId == applicationType.Id && w.SupervisedPersonId == person.SupervisedPersonId
&& w.CaseId == item.Id)
.WhereIf(input.EndCreatedTime.HasValue, w => w.CreatedTime <= input.EndCreatedTime)
.WhereIf(input.StartCreatedTime.HasValue, w => w.CreatedTime >= input.StartCreatedTime)
.ToListAsync();
notClockListDto.ViolationCount = earlyList.Count;
notClockList.Add(notClockListDto);
}
}
var memorySystem = ExcelHelper.ToExcel(notClockList);
return new FileController().File(memorySystem.ToArray(), "application/ms-excel", DateTime.Now.ToString("f") + ".xlsx");
}
/// <summary>
/// 未打卡统计导出
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
public async Task<IActionResult> NotClockedStatisticsExportAsync(NotClockedInput input)
{
//获取当前用户权限下的案件ids
var limits = User.limits;
var selectLimits = await _appCaseSupervisorRepository.AsQueryable(false, true)
.Where(w => limits.Contains(w.UnitId.ToString()))
.ToListAsync();
var caseIdList = selectLimits.Select(w => w.CaseId).Distinct().ToList();
var userRole = await _userService.IsAdmin(null);
var supervisorCaseList = await _appCaseSupervisorRepository.AsQueryable(false, true)
.Where(w => w.SupervisorId == User.Id).Select(s => s.CaseId).ToListAsync();
var caseList = await _appCaseManagementRepository.AsQueryable(false, true)
.Where(w => caseIdList.Contains(w.Id))
.WhereIf(input.CaseId.HasValue, w => w.Id == input.CaseId)
.WhereIf(!userRole.IsAdmin, w => supervisorCaseList.Contains(w.Id))
.ToListAsync();
var applicationType = await base.GetDictionariesOutput("early_warning_type", "notClocked");
List<NotClockExportDto> notClockList = new List<NotClockExportDto>();
foreach (var item in caseList)
{
if (item == null) continue;
var caseType = await _appDictionaryService.GetDicByDicId(item.CaseTypeId);
var unitList = await (from c in _appSupervisorRepository.AsQueryable(false, true)
join u in _userRepository.AsQueryable(false, true) on c.SupervisorId equals u.Id
where c.CaseId == item.Id
select u.Unitname).FirstOrDefaultAsync();
//根据案件找到被监管
var supervisedPerson = await _appSupervisedPersonRepository
.AsQueryable(false, true)
.Where(w => w.CaseId == item.Id)
.ToListAsync();
foreach (var person in supervisedPerson)
{
NotClockExportDto notClockListDto = new NotClockExportDto();
notClockListDto.Bmsah = item.Bmsah;
notClockListDto.CaseId = item.Id;
notClockListDto.CaseName = item.Name;
notClockListDto.CreatedTime = item.CreatedTime;
notClockListDto.CaseTypeName = caseType.Name;
notClockListDto.SupervisedPersonId = person.SupervisedPersonId;
notClockListDto.SupervisedPersonName = person.SupervisedPersonName;
notClockListDto.SupervisionUnit = unitList;
var earlyList = await _appEarlyWarningRepository
.AsQueryable(false, true)
.Where(w => w.EarlyWarningTypeId== applicationType.Id && w.SupervisedPersonId == person.SupervisedPersonId
&& w.CaseId == item.Id)
.WhereIf(input.EndCreatedTime.HasValue, w => w.CreatedTime <= input.EndCreatedTime)
.WhereIf(input.StartCreatedTime.HasValue, w => w.CreatedTime >= input.StartCreatedTime)
.ToListAsync();
notClockListDto.NotClockedCount = earlyList.Count;
notClockList.Add(notClockListDto);
}
}
var memorySystem = ExcelHelper.ToExcel(notClockList);
return new FileController().File(memorySystem.ToArray(), "application/ms-excel", DateTime.Now.ToString("f") + ".xlsx");
}
/// <summary>
/// 添加违规记录
/// </summary>
@ -232,4 +594,8 @@ namespace ATS.NonCustodial.Application.Impl.Business
/// <returns></returns>
public async Task<IResultOutput> AddAsync(AppViolationStatisticsAddInput input) => await base.AddAsync(input, _appViolationStatisticsRepository);
}
public class FileController : ControllerBase
{
}
}

295
src/2.services/ATS.NonCustodial.Application/Impl/Business/CaseManagements/AppCaseManagementService.cs

@ -10,12 +10,14 @@ using ATS.NonCustodial.Application.Contracts.Interfaces.Business.AppCaseManageme
using ATS.NonCustodial.Domain.Entities.Admins;
using ATS.NonCustodial.Domain.Entities.Business;
using ATS.NonCustodial.Domain.Entities.Business.CaseManagements;
using ATS.NonCustodial.Domain.Entities.Business.EarlyWarning;
using ATS.NonCustodial.Domain.Shared.AggRootEntities.Dtos;
using ATS.NonCustodial.Domain.Shared.Common.Dtos;
using ATS.NonCustodial.Domain.Shared.Enums;
using ATS.NonCustodial.Domain.Shared.OrmRepositories.Basic.EfCore;
using ATS.NonCustodial.DynamicApi;
using ATS.NonCustodial.DynamicApi.Attributes;
using ATS.NonCustodial.Shared.Common.Auth;
using ATS.NonCustodial.Shared.Common.Dtos;
using ATS.NonCustodial.Shared.Common.Enums;
using ATS.NonCustodial.Shared.Common.UnifiedResults;
@ -30,6 +32,7 @@ using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using SixLabors.ImageSharp;
using System.Linq;
using Yitter.IdGenerator;
@ -58,6 +61,7 @@ namespace ATS.NonCustodial.Application.Impl.Business.CaseManagements
private readonly IEfRepository<AppUser, long> _appUserRepository;
private readonly IEfRepository<AppDeviceManagement, long> _appDeviceManagementRepository;
private readonly IEfRepository<AppUser, long> _appuserRepository;
private readonly IEfRepository<AppEarlyWarningViewStatistics, long> _appEarlyWarningViewStatisticsRepository;
/// <summary>
///
@ -87,6 +91,7 @@ namespace ATS.NonCustodial.Application.Impl.Business.CaseManagements
IEfRepository<AppCommonFence, long> appCommonFenceRepository,
IEfRepository<AppUser, long> appUserRepository,
IEfRepository<AppSupervisedPersonRealTimeLocation, long> appSupervisedPersonRealTimeLocationRepository,
IEfRepository<AppEarlyWarningViewStatistics, long> appEarlyWarningViewStatisticsRepository,
IEfRepository<AppDeviceManagement, long> appDeviceManagementRepository)
: base(
appCaseManagementRepository,
@ -103,6 +108,7 @@ namespace ATS.NonCustodial.Application.Impl.Business.CaseManagements
_appUserRepository = appUserRepository;
_appDeviceManagementRepository = appDeviceManagementRepository;
_appuserRepository = appuserRepository;
_appEarlyWarningViewStatisticsRepository = appEarlyWarningViewStatisticsRepository;
}
#endregion Identity
@ -140,24 +146,97 @@ namespace ATS.NonCustodial.Application.Impl.Business.CaseManagements
[HttpPost]
public async Task<IResultOutput> GetPageAsync(AppCaseManagementGetPageInput input)
{
var limits = User.limits;
var selectLimits = await _appCaseSupervisorRepository.AsQueryable(false, true)
.Where(w => limits.Contains(w.UnitId.ToString()))
.ToListAsync();
var caseIdList = selectLimits.Select(w => w.CaseId).Distinct().ToList();
//当前用户角色
var userRole = await _userService.IsAdmin(null);
var express = await GetExpression(input, _appCaseManagementRepository.AsQueryable(false, true));
// 先应用案件ID过滤条件
express = express.Where(w => caseIdList.Contains(w.Id));
var rtn = await base.GetPageAsync<AppCaseManagement, AppCaseManagementGetPageInput, AppCaseManagementListDto>(input, express);
//非管理员只能看到自己监管的案件
if(!userRole.IsAdmin)
{
var supervisorCaseList = await _appCaseSupervisorRepository.AsQueryable(false, true)
.Where(w => w.SupervisorId == User.Id).Select(s => s.CaseId).ToListAsync();
express= express.Where(w => supervisorCaseList.Contains(w.Id));
}
var caseIds = rtn.Data.Select(w => w.Id).ToList();
var caseSupervisor = await _appCaseSupervisorRepository.AsQueryable(false, true)
.Where(w => caseIds.Contains(w.CaseId))
.ToListAsync();
var rtn = await base.GetPageAsync<AppCaseManagement, AppCaseManagementGetPageInput, AppCaseManagementListDto>(input, express);
var position = await _appDictionaryService.GetDicByDicId(User.PositionId);
foreach (var listDto in rtn.Data)
{
listDto.Supervisor = caseSupervisor.Where(w => w.CaseId == listDto.Id).Select(w => w.SupervisorName).JoinAsString(",");
listDto.Supervisor = (await _appCaseSupervisorRepository.AsQueryable(false, true)
.Where(w => w.CaseId == listDto.Id).Select(w => w.SupervisorName).ToListAsync()).JoinAsString(",");
if (listDto.CaseProgress == CaseProgressEnum.Pending)
{
listDto.ReviewPermission = "0";//显示编辑按钮
}
else if (listDto.CaseProgress == CaseProgressEnum.InExecution)
{
listDto.ReviewPermission = "1";//显示编辑按钮 移送检察院按钮
}
else if (listDto.CaseProgress == CaseProgressEnum.Examination)
{
if (position.Code == "inquisitor" )
{
listDto.ReviewPermission = "3";//显示移送法院 结束案件
}
else
{
listDto.ReviewPermission = "2";//显示查看按钮
}
}
else if (listDto.CaseProgress == CaseProgressEnum.Hear)
{
if (position.Code == "judge")
{
listDto.ReviewPermission = "4";//显示查看 结束案件
}
else
{
listDto.ReviewPermission = "2";//显示查看按钮
}
}
else
{
listDto.ReviewPermission = "2";//显示查看按钮
}
}
return ResultOutput.Ok(rtn);
}
//[HttpPost]
//public async Task<IResultOutput> GetPageAsync(AppCaseManagementGetPageInput input)
//{
// var express = await GetExpression(input, _appCaseManagementRepository.AsQueryable(false, true));
// var rtn = await base.GetPageAsync<AppCaseManagement, AppCaseManagementGetPageInput, AppCaseManagementListDto>(input, express);
// var caseIds = rtn.Data.Select(w => w.Id).ToList();
// var caseSupervisor = await _appCaseSupervisorRepository.AsQueryable(false, true)
// .Where(w => caseIds.Contains(w.CaseId))
// .ToListAsync();
// foreach (var listDto in rtn.Data)
// {
// listDto.Supervisor = caseSupervisor.Where(w => w.CaseId == listDto.Id).Select(w => w.SupervisorName).JoinAsString(",");
// }
// return ResultOutput.Ok(rtn);
//}
/// <summary>
/// 案件统计
/// </summary>
@ -217,8 +296,18 @@ namespace ATS.NonCustodial.Application.Impl.Business.CaseManagements
[HttpPost]
public async Task<IResultOutput> caseStatistics()
{
//获取当前用户权限下的案件ids
var limits = User.limits;
var selectLimits = await _appCaseSupervisorRepository.AsQueryable(false, true)
.Where(w => limits.Contains(w.UnitId.ToString()))
.ToListAsync();
var caseIdList = selectLimits.Select(w => w.CaseId).Distinct().ToList();
//获取案件信息
var express = await base.GetCurrentUserCaseListAsync();
express = express.Where(w => w.AppCaseManagement != null && caseIdList.Contains(w.AppCaseManagement.Id) && w.AppCaseSupervisedPerson != null && caseIdList.Contains(w.AppCaseSupervisedPerson.CaseId) && w.AppCaseSupervisor != null && caseIdList.Contains(w.AppCaseSupervisor.CaseId));
//案件信息Id
var caseIds = await express.Select(w => w.AppCaseManagement.Id).ToListAsync();
//监管人数
@ -244,9 +333,16 @@ namespace ATS.NonCustodial.Application.Impl.Business.CaseManagements
[HttpPost]
public async Task<IResultOutput> casetypeStatistics()
{
//获取当前用户权限下的案件ids
var limits = User.limits;
var selectLimits = await _appCaseSupervisorRepository.AsQueryable(false, true)
.Where(w => limits.Contains(w.UnitId.ToString()))
.ToListAsync();
var caseIdList = selectLimits.Select(w => w.CaseId).Distinct().ToList();
var diclist = new List<dynamic>();
//获取当前用户能看到的数据Id
var caseIds = await (await base.GetCurrentUserCaseListAsync()).Select(w => w.AppCaseManagement.Id).ToListAsync();
var caseIds = await (await base.GetCurrentUserCaseListAsync()).Where(w => w.AppCaseManagement != null && caseIdList.Contains(w.AppCaseManagement.Id)).Select(w => w.AppCaseManagement.Id).ToListAsync();
//获取案件信息
var express = await _appCaseManagementRepository.AsQueryable(false, true).Where(q => caseIds.Contains(q.Id)).ToListAsync();
var otherexpress = express;
@ -397,7 +493,20 @@ namespace ATS.NonCustodial.Application.Impl.Business.CaseManagements
//案子结束时间
item.CaseClosedTime = input.CaseProgress == CaseProgressEnum.Closed ? DateTime.Now : null;
});
//if (input.CaseProgress == CaseProgressEnum.Closed)
//{
// var statisticsList= await _appEarlyWarningViewStatisticsRepository.AsQueryable().Where(w=> input.Ids.Contains(w.CaseId.Value)).ToListAsync();
// foreach (var item in statisticsList)
// {
// item.CheckStatus = CheckStatusEnum.Checked;
// item.CheckTime = DateTime.Now;
// }
// if (statisticsList!=null && statisticsList.Count > 0)
// {
// //关闭案件时,将案件的未查阅状态改为已查阅
// await _appEarlyWarningViewStatisticsRepository.UpdateAsync(statisticsList);
// }
//}
await _appCaseManagementRepository.UpdateAsync(dataList);
return ResultOutput.Ok();
@ -474,6 +583,14 @@ namespace ATS.NonCustodial.Application.Impl.Business.CaseManagements
var validSpCase = await ValidSupervisedPerson(input);
if (!validSpCase.Success) return validSpCase;
if (input.Threshold >= int.MaxValue)
{
return ResultOutput.NotOk("预警阈值输入数字过大");
}
if (input.Threshold < 0)
{
return ResultOutput.NotOk("预警阈值不能为负数");
}
#endregion Valid
var caseId = input.Id;
@ -490,6 +607,10 @@ namespace ATS.NonCustodial.Application.Impl.Business.CaseManagements
else
{
var entity = Mapper.Map<AppCaseManagement>(input);
if (entity.Threshold == 0)
{
entity.Threshold = 5;
}
caseId = (await _appCaseManagementRepository.InsertAsync(entity)).Id;
}
@ -500,7 +621,8 @@ namespace ATS.NonCustodial.Application.Impl.Business.CaseManagements
{
CaseId = caseId.Value,
SupervisorId = csp.SupervisedId,
SupervisorName = csp.SupervisedName
SupervisorName = csp.SupervisedName,
UnitId = GetUnitIdByUserId(csp.SupervisedId)
});
var dels = new List<long>();
var list = await _appCaseSupervisorRepository.AsQueryable(false, true).Where(w => w.CaseId == caseId).ToListAsync();
@ -795,7 +917,8 @@ namespace ATS.NonCustodial.Application.Impl.Business.CaseManagements
{
CaseId = caseId.Value,
SupervisorId = csp.SupervisedId,
SupervisorName = csp.SupervisedName
SupervisorName = csp.SupervisedName,
UnitId = GetUnitIdByUserId(csp.SupervisedId)
});
var Supervisordata = await _appCaseSupervisorRepository.FindAsync(q => q.CaseId == caseId && sList.Select(q => q.SupervisorId).Contains(q.SupervisorId));
@ -866,20 +989,33 @@ namespace ATS.NonCustodial.Application.Impl.Business.CaseManagements
/// <returns></returns>
public async Task<IResultOutput> CaseStatisticsHandlingTime(CaseStatisticsHandlingTimePageInput input)
{
//获取当前用户权限下的案件ids
var limits = User.limits;
var selectLimits = await _appCaseSupervisorRepository.AsQueryable(false, true)
.Where(w => limits.Contains(w.UnitId.ToString()))
.ToListAsync();
var caseIdList = selectLimits.Select(w => w.CaseId).Distinct().ToList();
var userRole = await _userService.IsAdmin(null);
var supervisorCaseList = await _appCaseSupervisorRepository.AsQueryable(false, true)
.Where(w => w.SupervisorId == User.Id).Select(s => s.CaseId).ToListAsync();
var query = _appCaseManagementRepository
.AsQueryable(false, true)
.Where(w => w.CaseProgress == CaseProgressEnum.Closed)
.Where(w => w.CaseProgress == CaseProgressEnum.Closed && caseIdList.Contains(w.Id))
.WhereIf(input.KeyWord.NotNull(), a => a.Name.Contains(input.KeyWord))
.WhereIf(input.TimeSearch.BeginTime.Length == 2, w => w.CaseBeginTime > input.TimeSearch.BeginTime[0] && w.CaseBeginTime < input.TimeSearch.BeginTime[1].AddDays(1))
.WhereIf(input.TimeSearch.EndTime.Length == 2, w => w.CaseClosedTime > input.TimeSearch.EndTime[0] && w.CaseClosedTime <= input.TimeSearch.EndTime[1].AddDays(1));
.WhereIf(input.TimeSearch.EndTime.Length == 2, w => w.CaseClosedTime > input.TimeSearch.EndTime[0] && w.CaseClosedTime <= input.TimeSearch.EndTime[1].AddDays(1))
.WhereIf(!userRole.IsAdmin , w=>supervisorCaseList.Contains(w.Id));
var pageData = await
query.ProjectTo<CaseStatisticsHandlingTimeListDto>(Mapper.ConfigurationProvider)
.PagedAsync(input)
.ConfigureAwait(false);
var caseIds = pageData.Data.Select(w => w.Id);
//涉事人员(被监管人员)
var personInvolvedList = await _appSupervisedPersonRepository
.AsQueryable(false, true)
@ -907,11 +1043,24 @@ namespace ATS.NonCustodial.Application.Impl.Business.CaseManagements
/// <returns></returns>
public async Task<IResultOutput> CaseTypeStatistics(CaseTypeStatisticsGetPageInput input)
{
//获取当前用户权限下的案件ids
var limits = User.limits;
var selectLimits = await _appCaseSupervisorRepository.AsQueryable(false, true)
.Where(w => limits.Contains(w.UnitId.ToString()))
.ToListAsync();
var caseIds = selectLimits.Select(w => w.CaseId).Distinct().ToList();
var userRole = await _userService.IsAdmin(null);
var supervisorCaseList = await _appCaseSupervisorRepository.AsQueryable(false, true)
.Where(w => w.SupervisorId == User.Id).Select(s => s.CaseId).ToListAsync();
var data = await _appCaseManagementRepository.AsQueryable(false, true)
.Where(w => caseIds.Contains(w.Id))
.WhereIf(input.KeyWord.NotNull(), a => a.Name.Contains(input.KeyWord))
.WhereIf(input.TimeSearch.BeginTime.Length == 2, w => w.CreatedTime > input.TimeSearch.BeginTime[0] && w.CreatedTime < input.TimeSearch.BeginTime[1].AddDays(1))
.WhereIf(input.TimeSearch.EndTime.Length == 2, w => w.CaseClosedTime > input.TimeSearch.EndTime[0] && w.CaseClosedTime < input.TimeSearch.EndTime[1].AddDays(1))
.WhereIf(input.ajtype.NotNull(), w => w.CaseTypeId == input.ajtype.ToLong())
.WhereIf(!userRole.IsAdmin, w => supervisorCaseList.Contains(w.Id))
.ToListAsync();
var dataGroup = data.GroupBy(w => w.CaseTypeId);
@ -956,6 +1105,12 @@ namespace ATS.NonCustodial.Application.Impl.Business.CaseManagements
/// <returns></returns>
public async Task<IResultOutput> CaseHandlingFrequencyStatistics(CaseHandlingFrequencyStatisticsGetPageInput input)
{
//获取当前用户权限下的案件ids
var limits = User.limits;
var selectLimits = await _appCaseSupervisorRepository.AsQueryable(false, true)
.Where(w => limits.Contains(w.UnitId.ToString()))
.ToListAsync();
var caseIds = selectLimits.Select(w => w.CaseId).Distinct().ToList();
//query
var query = await (await base.GetCurrentUserCaseListAsync())
//.Where(w => w.AppCaseSupervisedPerson != null && w.AppCaseManagement.CaseProgress != CaseProgressEnum.Closed)
@ -969,7 +1124,7 @@ namespace ATS.NonCustodial.Application.Impl.Business.CaseManagements
SupervisedPersonName = w.AppCaseSupervisedPerson.SupervisedPersonName
}).ToListAsync();
var dataGroup = query.GroupBy(w => new
var dataGroup = query.Where(w => caseIds.Contains(w.CaseId)).GroupBy(w => new
{
w.CaseId,
w.SupervisedPersonId,
@ -1067,7 +1222,15 @@ namespace ATS.NonCustodial.Application.Impl.Business.CaseManagements
/// <returns></returns>
public async Task<IResultOutput> ImBusinessWorkbench()
{
var caseIds = await (await base.GetCurrentUserCaseListAsync()).Select(w => w.AppCaseManagement.Id).ToListAsync();
//获取当前用户权限下的案件ids
var limits = User.limits;
var selectLimits = await _appCaseSupervisorRepository.AsQueryable(false, true)
.Where(w => limits.Contains(w.UnitId.ToString()))
.ToListAsync();
var caseIdList = selectLimits.Select(w => w.CaseId).Distinct().ToList();
var caseIds = await (await base.GetCurrentUserCaseListAsync()).Where(w => w.AppCaseManagement != null && caseIdList.Contains(w.AppCaseManagement.Id)).Select(w => w.AppCaseManagement.Id).ToListAsync();
var imManagementList = await (from cm in _appCaseManagementRepository.AsQueryable(false, true)
.Where(w => w.CaseProgress != CaseProgressEnum.Closed && caseIds.Contains(w.Id))
@ -1094,11 +1257,18 @@ namespace ATS.NonCustodial.Application.Impl.Business.CaseManagements
/// <returns></returns>
public async Task<IResultOutput> CaseBusinessWorkbench()
{
//获取当前用户权限下的案件ids
var limits = User.limits;
var selectLimits = await _appCaseSupervisorRepository.AsQueryable(false, true)
.Where(w => limits.Contains(w.UnitId.ToString()))
.ToListAsync();
var caseIdList = selectLimits.Select(w => w.CaseId).Distinct().ToList();
var dataDict = await _appDictionaryService.GetListNoApiAsync(null);
var caseList = (await (await base.GetCurrentUserCaseListAsync()).ToListAsync())
.Where(w => w.AppCaseManagement.CaseProgress != CaseProgressEnum.Closed)
.Where(w => w.AppCaseManagement != null && w.AppCaseManagement.CaseProgress != CaseProgressEnum.Closed && caseIdList.Contains(w.AppCaseManagement.Id)
&& w.AppCaseSupervisedPerson != null && caseIdList.Contains(w.AppCaseSupervisedPerson.CaseId) && w.AppCaseSupervisor != null && caseIdList.Contains(w.AppCaseSupervisor.CaseId))
.OrderByDescending(w => w.AppCaseSupervisedPerson?.CreatedTime)
.Where(w => w.AppCaseSupervisedPerson != null)
.Skip(0)
.Take(5)
.Select(caseAgg =>
@ -1325,19 +1495,30 @@ namespace ATS.NonCustodial.Application.Impl.Business.CaseManagements
/// </remarks>
public async Task<IResultOutput> GetSupervisedPersonList()
{
var userRole = await _userService.IsAdmin(null);
var supervisorCaseList = await _appCaseSupervisorRepository.AsQueryable(false, true)
.Where(w => w.SupervisorId == User.Id).Select(s => s.CaseId).ToListAsync();
var position = await _appDictionaryService.GetDicByDicId(User.PositionId);
var rtn = await (from c in _appCaseManagementRepository.AsQueryable(false, true)
join spr in _appSupervisedPersonRepository.AsQueryable(false, true) on c.Id equals spr.CaseId
//join device in _appDeviceManagementRepository.AsQueryable(false, true) on spr.SupervisedPersonId equals device.SupervisedPersonId into td
//from d in td.DefaultIfEmpty()
//where c.CaseProgress != CaseProgressEnum.Closed && spr.IdCard != null && d == null
where c.CaseProgress != CaseProgressEnum.Closed && spr.IdCard != null
select new SupervisedPersonDto()
{
SupervisedPersonId = spr.SupervisedPersonId,
SupervisedPersonName = spr.SupervisedPersonName,
CaseId = c.Id,
IdCard = spr.IdCard
}).ToListAsync();
IdCard = spr.IdCard,
CaseProgress = c.CaseProgress
})
.WhereIf(!userRole.IsAdmin,w=> supervisorCaseList.Contains(w.CaseId))
.WhereIf(position.Code== "police", w=>w.CaseProgress== CaseProgressEnum.Pending|| w.CaseProgress == CaseProgressEnum.InExecution)
.WhereIf(position.Code == "inquisitor", w => w.CaseProgress == CaseProgressEnum.Examination)
.WhereIf(position.Code == "judge", w => w.CaseProgress== CaseProgressEnum.Hear).ToListAsync();
//去重
rtn = rtn.Distinct((x, y) => x.SupervisedPersonId == y.SupervisedPersonId).ToList();
@ -1374,10 +1555,18 @@ namespace ATS.NonCustodial.Application.Impl.Business.CaseManagements
[HttpPost]
public async Task<IResultOutput<PagedList<GetSupervisedPersonApprovalStatusOutput>>> GetSupervisedPersonApprovalStatus(GetSupervisedPersonApprovalStatusPageInput input)
{
//获取当前用户权限下的案件ids
var limits = User.limits;
var selectLimits = await _appCaseSupervisorRepository.AsQueryable(false, true)
.Where(w => limits.Contains(w.UnitId.ToString()))
.ToListAsync();
var caseIds = selectLimits.Select(w => w.CaseId).Distinct().ToList();
var queryable = (await GetCurrentUserCaseListAsync())
.WhereIf(input.SupervisedPersonId > 0, w => w.AppCaseSupervisedPerson.SupervisedPersonId == input.SupervisedPersonId)
.WhereIf(input.ApprovalStatus.HasValue, w => w.AppCaseSupervisedPerson.ApprovalStatus == input.ApprovalStatus)
.WhereIf(input.name.NotNull(), w => w.AppCaseSupervisedPerson.SupervisedPersonName.Contains(input.name));
.WhereIf(input.name.NotNull(), w => w.AppCaseSupervisedPerson.SupervisedPersonName.Contains(input.name))
.Where(w => w.AppCaseManagement != null && w.AppCaseSupervisedPerson != null && w.AppCaseSupervisor != null && caseIds.Contains(w.AppCaseSupervisedPerson.CaseId) && caseIds.Contains(w.AppCaseManagement.Id) && caseIds.Contains(w.AppCaseSupervisor.CaseId));
var caseSpQueryable = await queryable.Where(q => q.AppCaseSupervisedPerson != null).Select(w => Mapper.Map<AppCaseSupervisedPerson, GetSupervisedPersonApprovalStatusOutput>(w.AppCaseSupervisedPerson)).ToListAsync();
if ((await base.IsAdmin()).IsAdmin) caseSpQueryable = caseSpQueryable.Distinct((x, y) => x.CaseId == y.CaseId && x.SupervisedPersonId == y.SupervisedPersonId).ToList();
@ -1404,6 +1593,8 @@ namespace ATS.NonCustodial.Application.Impl.Business.CaseManagements
/// <returns></returns>
public async Task<List<long>> GetUserIdListByCurrentUser()
{
var limits = User.limits;
var data = await (await base.GetCurrentUserCaseListAsync()).ToListAsync();
var userList = new List<long>();
@ -1429,10 +1620,14 @@ namespace ATS.NonCustodial.Application.Impl.Business.CaseManagements
var caseIds = await (await base.GetCurrentUserCaseListAsync()).Select(w => w.AppCaseManagement.Id).ToListAsync();
query = query
.Where(w=> caseIds.Contains(w.Id))
.WhereIf(pageInput.CaseIds.IsNotNullOrEmpty(), w => pageInput.CaseIds.Contains(w.Id))
.WhereIf(pageInput.CaseName.NotNull(), a => a.Name.Contains(pageInput.CaseName))
.WhereIf(pageInput.CaseTypeId != null, a => a.CaseTypeId == pageInput.CaseTypeId)
.WhereIf(pageInput.JudgmentStatusIds.IsNotNullOrEmpty(), w => pageInput.JudgmentStatusIds.Contains(w.JudgmentStatusId))
.WhereIf(pageInput.CaseProgresses.IsNotNullOrEmpty(), w => pageInput.CaseProgresses.Contains(w.CaseProgress))
.WhereIf(pageInput.TimeArraySearch.BeginTime.Length == 2, w => w.CreatedTime > pageInput.TimeArraySearch.BeginTime[0] && w.CreatedTime < pageInput.TimeArraySearch.BeginTime[1].AddDays(1))
.WhereIf(pageInput.TimeArraySearch.EndTime.Length == 2, w => w.CaseClosedTime > pageInput.TimeArraySearch.EndTime[0] && w.CaseClosedTime < pageInput.TimeArraySearch.EndTime[1].AddDays(1))
.WhereIf(pageInput.TimeSearch != null && pageInput.TimeSearch.BeginTime != null && pageInput.TimeSearch.EndTime != null, q => q.CreatedTime >= pageInput.TimeSearch.BeginTime && q.CreatedTime <= $"{pageInput.TimeSearch.EndTime.Value.ToString("yyyy-MM-dd")} 23:59:59".ToDateTime());
var express = base.GetWithOutStatusExpression<AppCaseManagement, AppCaseManagementGetPageInput, long>(pageInput, query);
@ -1514,14 +1709,24 @@ namespace ATS.NonCustodial.Application.Impl.Business.CaseManagements
[HttpPost]
public async Task<IResultOutput> GetSupervisedPersonAsync(GetSupervisedPersonPage input)
{
var caseIds = await (await base.GetCurrentUserCaseListAsync()).Select(w => w.AppCaseManagement.Id).ToListAsync();
var limits = User.limits;
var selectLimits = await _appCaseSupervisorRepository.AsQueryable(false, true)
.Where(w => limits.Contains(w.UnitId.ToString()))
.ToListAsync();
var caseIds = selectLimits.Select(w => w.CaseId).Distinct().ToList();
//var caseIds = await (await base.GetCurrentUserCaseListAsync()).Select(w => w.AppCaseManagement.Id).ToListAsync();
var caselist = await (await base.GetCurrentUserCaseListAsync()).Select(w => new { w.AppCaseManagement.Id, w.AppCaseManagement.Name }).ToListAsync();
//查询待执行,执行种案件涉嫌人员
var appSupervisedlist = from a in base._appCaseManagementRepository.AsQueryable(false, true).Where(q => q.CaseProgress != CaseProgressEnum.Closed)
//查询待执行,执行种案件涉嫌人员 去除状态筛选,与导出接口一致
//var appSupervisedlist = from a in base._appCaseManagementRepository.AsQueryable(false, true).Where(q => q.CaseProgress != CaseProgressEnum.Closed)
// join b in _appSupervisedPersonRepository.AsQueryable(false, true) on a.Id equals b.CaseId
// select b;
var caseIdList = caselist.Where(w => caseIds.Contains(w.Id)).Select(s => s.Id);
var appSupervisedlist = from a in base._appCaseManagementRepository.AsQueryable(false, true)
join b in _appSupervisedPersonRepository.AsQueryable(false, true) on a.Id equals b.CaseId
select b;
var data = await appSupervisedlist
.Where(q => caseIds.Contains(q.CaseId))
.Where(q => caseIdList.Contains(q.CaseId))
.WhereIf(input.TimeSearch?.BeginTime != null && input.TimeSearch?.EndTime != null, q => q.CreatedTime >= input.TimeSearch.BeginTime && q.CreatedTime <= $"{input.TimeSearch.EndTime.Value.ToString("yyyy-MM-dd")} 23:59:59".ToDateTime())
.WhereIf(input.name.NotNull(), q => q.SupervisedPersonName.Contains(input.name))
.OrderByDescending(r => r.CreatedTime)
@ -1799,14 +2004,25 @@ namespace ATS.NonCustodial.Application.Impl.Business.CaseManagements
/// <returns></returns>
public async Task<IActionResult> Getexport(AppCaseManagementGetPageInput input)
{
input.PageIndex = 1;
input.PageSize = 999999;
var limits = User.limits;
var selectLimits = await _appCaseSupervisorRepository.AsQueryable(false, true)
.Where(w => limits.Contains(w.UnitId.ToString()))
.Select(s=>s.CaseId)
.ToListAsync();
input.CaseIds = input.CaseIds?.Count>0 ? input.CaseIds.Intersect(selectLimits).ToList() : selectLimits.Distinct().ToList();
var express = await GetExpression(input, _appCaseManagementRepository.AsQueryable(false, true));
var rtn = await base.GetPageAsync<AppCaseManagement, AppCaseManagementGetPageInput, AppCaseManagementListexportDto>(input, express);
var caseIds = rtn.Data.Select(w => w.Id).ToList();
//var caseIds = rtn.Data.Select(w => w.Id).ToList();
var caseSupervisor = await _appCaseSupervisorRepository.AsQueryable(false, true)
.Where(w => caseIds.Contains(w.CaseId))
.Where(w => input.CaseIds.Contains(w.CaseId))
.ToListAsync();
foreach (var listDto in rtn.Data)
@ -1830,10 +2046,23 @@ namespace ATS.NonCustodial.Application.Impl.Business.CaseManagements
/// <returns></returns>
public async Task<IActionResult> Getuserexport(GetSupervisedPersonPage input)
{
var caseIds = await (await base.GetCurrentUserCaseListAsync()).Select(w => w.AppCaseManagement.Id).ToListAsync();
input.PageIndex = 1;
input.PageSize = 9999;
var limits = User.limits;
var selectLimits = await _appCaseSupervisorRepository.AsQueryable(false, true)
.Where(w => limits.Contains(w.UnitId.ToString()))
.ToListAsync();
var caseIds = selectLimits.Select(w => w.CaseId).Distinct().ToList();
var userRole = await _userService.IsAdmin(null);
var supervisorCaseList = await _appCaseSupervisorRepository.AsQueryable(false, true)
.Where(w => w.SupervisorId == User.Id).Select(s => s.CaseId).ToListAsync();
// var intersection1 = supervisorCaseList.Intersect(caseIds).ToList();
var caselist = await (await base.GetCurrentUserCaseListAsync()).Select(w => new { w.AppCaseManagement.Id, w.AppCaseManagement.Name }).ToListAsync();
var data = await _appSupervisedPersonRepository.AsQueryable(false, true)
.Where(q => caseIds.Contains(q.CaseId))
.Where(w=> caseIds.Contains(w.CaseId))
.WhereIf(userRole.IsAdmin,q => supervisorCaseList.Contains(q.CaseId))
.WhereIf(input.name.NotNull(), q => q.SupervisedPersonName.Contains(input.name))
.OrderByDescending(r => r.CreatedTime)
.ProjectTo<AppSupervisedPersonListexportDto>(Mapper.ConfigurationProvider)
@ -1842,8 +2071,8 @@ namespace ATS.NonCustodial.Application.Impl.Business.CaseManagements
foreach (var listDto in data.Data)
{
var judgmentlist = await base.GetDictionariesOutput1("judgment", "");
var type_caselist = await base.GetDictionariesOutput1("type_case", "");
//var judgmentlist = await base.GetDictionariesOutput1("judgment", "");
//var type_caselist = await base.GetDictionariesOutput1("type_case", "");
listDto.Casename = caselist.Where(q => q.Id == listDto.CaseId).Select(q => q.Name).JoinAsString(",");
//listDto.CaseTypename = type_caselist.Where(w => w.Id == listDto.CaseTypeId).Select(w => w.Name).JoinAsString(",");
//listDto.JudgmentStatusname = judgmentlist.Where(w => w.Id == listDto.JudgmentStatusId).Select(w => w.Name).JoinAsString(",");
@ -1856,6 +2085,12 @@ namespace ATS.NonCustodial.Application.Impl.Business.CaseManagements
}
#endregion
private long GetUnitIdByUserId(long id)
{
var user = _appuserRepository.AsQueryable().Where(w => w.Id == id).FirstOrDefault();
return user?.UnitId ?? 0;
}
}
public class Controller : ControllerBase
{

12
src/2.services/ATS.NonCustodial.Application/Impl/Business/CaseManagements/AppSupervisedPersonService.cs

@ -121,16 +121,18 @@ namespace ATS.NonCustodial.Application.Impl.Business.CaseManagements
}
//修改状态
var propertyNameAndValues = new Dictionary<long, List<(string propertyName, dynamic propertyValue)>>();
foreach (var (key, value) in caseProgress)
{
await _appCaseManagementEfRepository.UpdateAsync(w => w.Id == key,
w => new AppCaseManagement()
propertyNameAndValues[key] = new List<(string propertyName, dynamic propertyValue)>()
{
CaseProgress = value,
CaseBeginTime = value == CaseProgressEnum.InExecution ? DateTime.Now : null
});
(nameof(AppCaseManagement.CaseProgress), value),
(nameof(AppCaseManagement.CaseBeginTime), value == CaseProgressEnum.InExecution ? DateTime.Now : (DateTime?)null)
};
}
await _appCaseManagementEfRepository.UpdateAsync(propertyNameAndValues);
return ResultOutput.Ok();
}
}

34
src/2.services/ATS.NonCustodial.Application/Impl/Business/MaterialManager/AppFileAccessRecordsService.cs

@ -155,9 +155,20 @@ namespace ATS.NonCustodial.Application.Impl.Business.MaterialManager
[HttpPost]
public async Task<IResultOutput<PagedList<GetLearningSituationForCountOutput>>> GetSituationForCount(FileAccessRecordsGetPageInput input)
{
//获取当前用户权限下的案件ids
var limits = User.limits;
var selectLimits = await _appCaseSupervisorRepository.AsQueryable(false, true)
.Where(w => limits.Contains(w.UnitId.ToString()))
.ToListAsync();
var caseIdList = selectLimits.Select(w => w.CaseId).Distinct().ToList();
var userRole = await _userService.IsAdmin(null);
var supervisorCaseList = await _appCaseSupervisorRepository.AsQueryable(false, true)
.Where(w => w.SupervisorId == User.Id).Select(s => s.CaseId).ToListAsync();
//获取案件及案件被监管人
var caseIds = await (await base.GetCurrentUserCaseListAsync()).Select(w => w.AppCaseManagement.Id).ToListAsync();
var SupervisedPersonIds = await base._appSupervisedPersonRepository.AsQueryable(false, true).Where(q => caseIds.Contains(q.CaseId)).Select(q=>q.SupervisedPersonId).ToListAsync();
// var caseIds = await (await base.GetCurrentUserCaseListAsync()).Select(w => w.AppCaseManagement.Id).ToListAsync();
var SupervisedPersonIds = await base._appSupervisedPersonRepository.AsQueryable(false, true).Where(q => caseIdList.Contains(q.CaseId))
.WhereIf(!userRole.IsAdmin, w => supervisorCaseList.Contains(w.CaseId)).Select(q=>q.SupervisedPersonId).ToListAsync();
//获取监管人查阅次数
var queryable = await GetExpression(input, _appFileAccessRecordsRepository.AsQueryable(false, true).Where(q=> SupervisedPersonIds.Contains(q.SupervisedPersonId)))
.ToListAsync();
@ -195,9 +206,22 @@ namespace ATS.NonCustodial.Application.Impl.Business.MaterialManager
[HttpPost]
public async Task<IResultOutput> GetSituationCount(FileAccessRecordsGetPageInput input)
{
//获取案件及案件被监管人
var caseIds = await (await base.GetCurrentUserCaseListAsync()).Select(w => w.AppCaseManagement.Id).ToListAsync();
var SupervisedPersonIds = await base._appSupervisedPersonRepository.AsQueryable(false, true).Where(q => caseIds.Contains(q.CaseId)).Select(q => q.SupervisedPersonId).ToListAsync();
//获取当前用户权限下的案件ids
var limits = User.limits;
var selectLimits = await _appCaseSupervisorRepository.AsQueryable(false, true)
.Where(w => limits.Contains(w.UnitId.ToString()))
.ToListAsync();
var caseIds = selectLimits.Select(w => w.CaseId).Distinct().ToList();
var userRole = await _userService.IsAdmin(null);
var supervisorCaseList = await _appCaseSupervisorRepository.AsQueryable(false, true)
.Where(w => w.SupervisorId == User.Id).Select(s => s.CaseId).ToListAsync();
// var intersection1 = supervisorCaseList.Intersect(caseIds).ToList();
// var caseIds = await (await base.GetCurrentUserCaseListAsync()).Select(w => w.AppCaseManagement.Id).ToListAsync();
var SupervisedPersonIds = await base._appSupervisedPersonRepository.AsQueryable(false, true)
.Where(q => caseIds.Contains(q.CaseId))
.WhereIf(userRole.IsAdmin, q => supervisorCaseList.Contains(q.CaseId)).Select(q => q.SupervisedPersonId).ToListAsync();
//获取监管人查阅次数
var queryable = await GetExpression(input, _appFileAccessRecordsRepository.AsQueryable(false, true).Where(q => SupervisedPersonIds.Contains(q.SupervisedPersonId)))
.ToListAsync();

2
src/2.services/ATS.NonCustodial.Application/Impl/Business/MaterialManager/AppFileDescriptorService.cs

@ -146,6 +146,8 @@ namespace ATS.NonCustodial.Application.Impl.Business.MaterialManager
/// <param name="file"></param>
/// <returns></returns>
[HttpPut]
[RequestSizeLimit(200 * 1024 * 1024)] // 200MB
[RequestFormLimits(MultipartBodyLengthLimit = 200 * 1024 * 1024)] // 200MB
public async Task<IResultOutput> UploadFile(long? directoryId, [FromForm] IFormFile file)
{
var uploadConfig = LazyGetRequiredService<UploadConfigConfiguration>();

10
src/2.services/ATS.NonCustodial.Application/Impl/Logs/OperationLogService.cs

@ -53,7 +53,7 @@ namespace ATS.NonCustodial.Application.Impl.Logs
[HttpPost]
public async Task<IResultOutput> GetPageAsync(LogGetPageDto input)
{
var express = await GetExpression(input, _oprationLogRepository.AsQueryable(false, true).Take(3000));
var express = await GetExpression(input);
var rtn = await base.GetPageAsync<AppOperationLog, LogGetPageDto, OprationLogListOutput>(input, express);
return ResultOutput.Ok(rtn);
@ -133,15 +133,17 @@ namespace ATS.NonCustodial.Application.Impl.Logs
/// <param name="pageInput"></param>
/// <param name="query"></param>
/// <returns></returns>
private async Task<IQueryable<AppOperationLog>> GetExpression(LogGetPageDto pageInput, IQueryable<AppOperationLog?> query)
private async Task<IQueryable<AppOperationLog>> GetExpression(LogGetPageDto pageInput)
{
var userIds = await _appCaseManagementService.GetUserIdListByCurrentUser();
query = query
var query = _oprationLogRepository.AsQueryable(false, true)
.Where(w => w.CreatedUserId != null && userIds.Contains(w.CreatedUserId.Value))
.WhereIf(pageInput.OperatorName.NotNull(), w => w.CreatedUserName.Contains(pageInput.OperatorName))
.WhereIf(pageInput.Device.NotNull(), w => w.Device==pageInput.Device)
.WhereIf(pageInput.NickName.NotNull(), w => w.NickName==pageInput.NickName);
.WhereIf(pageInput.NickName.NotNull(), w => w.NickName==pageInput.NickName)
.OrderByDescending(w=>w.CreatedTime)
.Take(3000);
var express = base.GetEntityAddExpression<AppOperationLog, LogGetPageDto, long>(pageInput, query);

7
src/3.contracts/ATS.NonCustodial.Application.Contracts/Interfaces/Admins/Auth/IAuthService.cs

@ -79,5 +79,12 @@ namespace ATS.NonCustodial.Application.Contracts.Interfaces.Admins.Auth
/// <param name="user">用户信息</param>
/// <returns></returns>
Task<string> GetToken(AuthLoginOutput? user);
/// <summary>
/// 根据身份证号获取电话号码
/// </summary>
/// <param name="phone"></param>
/// <returns></returns>
Task<IResultOutput> GetPhoneByIDCard(string idCard);
}
}

14
src/3.contracts/ATS.NonCustodial.Application.Contracts/Interfaces/Admins/Auth/Output/AuthLoginOutput.cs

@ -1,4 +1,6 @@
using ATS.NonCustodial.Shared.Common.Enums;
using ATS.NonCustodial.Domain.Shared.Constants;
using ATS.NonCustodial.Shared.Common.Enums;
using System.ComponentModel.DataAnnotations;
namespace ATS.NonCustodial.Application.Contracts.Interfaces.Admins.Auth.Output
{
@ -73,5 +75,15 @@ namespace ATS.NonCustodial.Application.Contracts.Interfaces.Admins.Auth.Output
/// 手机登录获取到得手机唯一标识,(用于个推)
/// </summary>
public string? CId { get; set; }
/// <summary>
/// 查询界限
/// </summary>
public string? limits { get; set; }
/// <summary>
/// 是否是Admin
/// </summary>
public bool IsAdmin { get; set; }
}
}

53
src/3.contracts/ATS.NonCustodial.Application.Contracts/Interfaces/Admins/SMS/ISMSService.cs

@ -0,0 +1,53 @@
using ATS.NonCustodial.Application.Contracts.Interfaces.Admins.SMS.Input;
using ATS.NonCustodial.Domain.Shared.Enums;
using ATS.NonCustodial.Shared.Common.UnifiedResults;
namespace ATS.NonCustodial.Application.Contracts.Interfaces.Admins.SMS
{
public interface ISMSService
{
Task<IResultOutput> GetPageAsync(SmsGetpageInput input);
/// <summary>
/// 发送验证码
/// </summary>
/// <param name="phone"></param>
/// <returns></returns>
Task<IResultOutput> SendCheckCodeSMS(string phone, string ipAddress = "", string type = "CheckCode");
/// <summary>
/// 监管人创建新用户或更改手机号发送验证码
/// </summary>
/// <param name="phone"></param>
/// <param name="ipAddress"></param>
/// <param name="type"></param>
/// <returns></returns>
Task<IResultOutput> SendCheckCode(string phone, string ipAddress = "", string type = "CheckCode");
/// <summary>
/// 校验验证码
/// </summary>
/// <param name="phoneNumber"></param>
/// <param name="code"></param>
/// <param name="type"></param>
/// <returns></returns>
Task<bool> CheckCodeAsync(string phoneNumber, string code, string type = "default");
/// <summary>
/// 用于触发给指定人员发送短信
/// </summary>
/// <param name="alert">短信通知类型</param>
/// <param name="supervisor">监管人姓名</param>
/// <param name="phone">需要通知的电话</param>
/// <param name="dateTime">发送的日期</param>
/// <param name="msg">触发的消息内容(小于等于6个字)</param>
/// <param name="ipAddress"></param>
/// <param name="supervisedPerson">被监管人姓名</param>
/// <returns></returns>
Task<IResultOutput> SendMessageSMS(MessageAlertTypeEnum alert, string supervisor, string phone, DateTime? dateTime, string msg = "", string ipAddress = "", string supervisedPerson = "");
/// <summary>
/// 发送前校验
/// </summary>
/// <param name="phone"></param>
/// <returns></returns>
Task<bool> CanSendCodeAsync(string phone);
}
}

33
src/3.contracts/ATS.NonCustodial.Application.Contracts/Interfaces/Admins/SMS/Input/SmsGetpageInput.cs

@ -0,0 +1,33 @@
using ATS.NonCustodial.Domain.Shared.Enums;
using ATS.NonCustodial.Shared.Common.Dtos;
namespace ATS.NonCustodial.Application.Contracts.Interfaces.Admins.SMS.Input
{
/// <summary>
/// 短信查询入参
/// </summary>
/// Author:ZZJ
/// CreatedTimed:2025-10-15 10点42分
public class SmsGetpageInput : PageRequestBaseInput
{
/// <summary>
/// 电话号码
/// </summary>
public string? Phone { get; set; }
/// <summary>
/// 姓名
/// </summary>
public string? Name { get; set; }
/// <summary>
/// 开始时间
/// </summary>
public DateTime? SendTimeFrom { get; set; }
/// <summary>
/// 结束时间
/// </summary>
public DateTime? SendTimeTo { get; set; }
}
}

55
src/3.contracts/ATS.NonCustodial.Application.Contracts/Interfaces/Admins/SMS/Output/SmsListDto.cs

@ -0,0 +1,55 @@
using ATS.NonCustodial.Domain.Shared.AggRootEntities;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ATS.NonCustodial.Application.Contracts.Interfaces.Admins.SMS.Output
{
public class SmsListDto : EntityFull
{
/// <summary>
/// 姓名
/// </summary>
public string? Name { get; set; }
/// <summary>
/// 编码
/// </summary>
public long? Id { get; set; }
/// <summary>
/// 电话
/// </summary>
public string? Phone { get; set; }
/// <summary>
/// 验证码
/// </summary>
public string? Code { get; set; }
/// <summary>
/// 发送时间
/// </summary>
public DateTime? SendTime { get; set; }
/// <summary>
/// 通知类型
/// </summary>
public string? Type { get; set; }
/// <summary>
/// 通知类型描述
/// </summary>
public string? TypeDes { get; set; }
/// <summary>
/// 发送结果
/// </summary>
public string? Result { get; set; }
/// <summary>
/// 详细描述
/// </summary>
public string? Message { get; set; }
/// <summary>
/// 接收人姓名
/// </summary>
public string? Receiver { get; set; }
}
}

7
src/3.contracts/ATS.NonCustodial.Application.Contracts/Interfaces/Admins/Unitcode/Output/UnitcodeListOutput.cs

@ -1,4 +1,6 @@
using ATS.NonCustodial.Domain.Shared.AggRootEntities;
using ATS.NonCustodial.Domain.Shared.Constants;
using System.ComponentModel.DataAnnotations;
namespace ATS.NonCustodial.Application.Contracts.Interfaces.Admins.Unitcode.Output
{
@ -18,5 +20,10 @@ namespace ATS.NonCustodial.Application.Contracts.Interfaces.Admins.Unitcode.Outp
/// 父级编码
/// </summary>
public long? ParentUnitCode { get; set; }
/// <summary>
/// 单位级别
/// </summary>
public string? UnitLevel { get; set; }
}
}

4
src/3.contracts/ATS.NonCustodial.Application.Contracts/Interfaces/Admins/User/IUserService.cs

@ -218,8 +218,10 @@ namespace ATS.NonCustodial.Application.Contracts.Interfaces.Admins.User
/// 根据当前登录用户查询下拉列表
/// </summary>
/// <returns></returns>
Task<ResultOutput<List<KeyValueDto>>> GetUserSelectList();
Task<ResultOutput<List<KeyValueDto>>> GetUserSelectList(int isCourt = 0);
Task<ResultOutput<List<KeyValueDto>>> GetNewUserSelectList();
/// <summary>
/// 获取所有的管理员
/// </summary>

5
src/3.contracts/ATS.NonCustodial.Application.Contracts/Interfaces/Admins/User/Input/UserAddInput.cs

@ -49,7 +49,10 @@ namespace ATS.NonCustodial.Application.Contracts.Interfaces.Admins.User.Input
/// 部门名称
/// </summary>
public string? Deptcodename { get; set; }
/// <summary>
/// 验证码
/// </summary>
public string? Code { get; set; }
/// <summary>
/// 角色
/// </summary>

10
src/3.contracts/ATS.NonCustodial.Application.Contracts/Interfaces/Admins/User/Input/UserUpdateInput.cs

@ -34,6 +34,11 @@ namespace ATS.NonCustodial.Application.Contracts.Interfaces.Admins.User.Input
/// </summary>
public string? Unitname { get; set; }
/// <summary>
/// 验证码
/// </summary>
public string? Code { get; set; }
/// <summary>
/// 部门id
/// </summary>
@ -67,5 +72,10 @@ namespace ATS.NonCustodial.Application.Contracts.Interfaces.Admins.User.Input
/// 手机号(手机号限制输入为手机号格式,位数为11位。)
/// </summary>
public string? Phone { get; set; }
/// <summary>
/// 用户修改手机号标识
/// </summary>
public string? PhoneUpdateFlag { get; set; }
}
}

5
src/3.contracts/ATS.NonCustodial.Application.Contracts/Interfaces/Business/AppBusinessApplications/Input/AppBusinessApplicationCreateOrModifyInput.cs

@ -43,7 +43,10 @@ namespace ATS.NonCustodial.Application.Contracts.Interfaces.Business.AppBusiness
/// 活动时间段(年月日时分)
/// </summary>
public DateTime ActiveTimePeriodEnd { get; set; }
/// <summary>
/// 申请结束监管日期
/// </summary>
public DateTime EndSupervisionDate { get; set; }
/// <summary>
/// 申请描述
/// </summary>

14
src/3.contracts/ATS.NonCustodial.Application.Contracts/Interfaces/Business/AppBusinessApplications/Output/AppBusinessApplicationGetDto.cs

@ -17,6 +17,10 @@ namespace ATS.NonCustodial.Application.Contracts.Interfaces.Business.AppBusiness
/// </summary>
public AuditStatusEnum AuditStatus { get; set; }
/// <summary>
/// 案子Id
/// </summary>
public long CaseId { get; set; }
/// <summary>
/// 审核状态描述
/// </summary>
@ -76,5 +80,15 @@ namespace ATS.NonCustodial.Application.Contracts.Interfaces.Business.AppBusiness
/// 审核时间
/// </summary>
public DateTime? AuditTime { get; set; }
/// <summary>
/// 结束监管日期
/// </summary>
public DateTime? EndSupervisionDate { get; set; }
/// <summary>
/// 审核权限(1 有权限 0 无权限)
/// </summary>
public string? ReviewPermission { get; set; }
}
}

14
src/3.contracts/ATS.NonCustodial.Application.Contracts/Interfaces/Business/AppBusinessApplications/Output/AppBusinessApplicationListDto.cs

@ -75,16 +75,24 @@ namespace ATS.NonCustodial.Application.Contracts.Interfaces.Business.AppBusiness
/// <summary>
/// 活动开始时间段(年月日时分)
/// </summary>
public DateTime ActiveTimePeriodBegin { get; set; }
public DateTime? ActiveTimePeriodBegin { get; set; }
/// <summary>
/// 活动结束时间段(年月日时分)
/// </summary>
public DateTime ActiveTimePeriodEnd { get; set; }
public DateTime? ActiveTimePeriodEnd { get; set; }
/// <summary>
/// 结束监管日期
/// </summary>
public DateTime? EndSupervisionDate { get; set; }
/// <summary>
/// 申请描述
/// </summary>
public string? ApplicationDescription { get; set; }
/// <summary>
/// 审核权限(1 有权限 0 无权限)
/// </summary>
public string? ReviewPermission { get; set; }
}
}

5
src/3.contracts/ATS.NonCustodial.Application.Contracts/Interfaces/Business/AppCaseManagements/AppCaseManagement/Input/AppCaseManagementCreateOrModifyInput.cs

@ -45,7 +45,10 @@ namespace ATS.NonCustodial.Application.Contracts.Interfaces.Business.AppCaseMana
/// 接近等级(米)
/// </summary>
public double ProximityLevel { get; set; }
/// <summary>
/// 预警阈值字段 Threshold
/// </summary>
public long Threshold { get; set; }
/// <summary>
/// 休息开始时间(格式:时分)
/// </summary>

7
src/3.contracts/ATS.NonCustodial.Application.Contracts/Interfaces/Business/AppCaseManagements/AppCaseManagement/Input/AppCaseManagementGetPageInput.cs

@ -1,5 +1,7 @@
using ATS.NonCustodial.Domain.Shared.Enums;
using ATS.NonCustodial.Shared.Common.Dtos;
using ATS.NonCustodial.Shared.Common.Dtos.Query;
using ATS.NonCustodial.Shared.Common.Enums;
namespace ATS.NonCustodial.Application.Contracts.Interfaces.Business.AppCaseManagements.AppCaseManagement.Input
{
@ -29,5 +31,10 @@ namespace ATS.NonCustodial.Application.Contracts.Interfaces.Business.AppCaseMana
/// 案件类型(数据来自字典)
/// </summary>
public long? CaseTypeId { get; set; }
public List<long>? CaseIds { get; set; }
public CmShopTimeArraySearchDto<SearchTimeTypeEnums>? TimeArraySearch { get; set; } = new CmShopTimeArraySearchDto<SearchTimeTypeEnums>();
}
}

5
src/3.contracts/ATS.NonCustodial.Application.Contracts/Interfaces/Business/AppCaseManagements/AppCaseManagement/Output/AppCaseManagementGetDto.cs

@ -41,6 +41,11 @@ namespace ATS.NonCustodial.Application.Contracts.Interfaces.Business.AppCaseMana
/// </summary>
public double ProximityLevel { get; set; }
/// <summary>
/// 预警阈值字段 Threshold
/// </summary>
public long Threshold { get; set; }
/// <summary>
/// 休息开始时间(时分)
/// </summary>

13
src/3.contracts/ATS.NonCustodial.Application.Contracts/Interfaces/Business/AppCaseManagements/AppCaseManagement/Output/AppCaseManagementListDto.cs

@ -38,6 +38,11 @@ namespace ATS.NonCustodial.Application.Contracts.Interfaces.Business.AppCaseMana
/// </summary>
public long JudgmentStatusId { get; set; }
/// <summary>
/// 预警阈值字段 Threshold
/// </summary>
public long Threshold { get; set; }
/// <summary>
/// 接近等级(米)
/// </summary>
@ -62,7 +67,7 @@ namespace ATS.NonCustodial.Application.Contracts.Interfaces.Business.AppCaseMana
/// <summary>
/// 案子开始时间
/// </summary>
public DateTime CaseBeginTime { get; set; }
public DateTime? CaseBeginTime { get; set; }
/// <summary>
/// 案子结束时间
@ -73,5 +78,11 @@ namespace ATS.NonCustodial.Application.Contracts.Interfaces.Business.AppCaseMana
/// 监管人名
/// </summary>
public string? Supervisor { get; set; }
/// <summary>
/// 按钮权限
/// </summary>
public string? ReviewPermission { get; set; }
}
}

4
src/3.contracts/ATS.NonCustodial.Application.Contracts/Interfaces/Business/AppEarlyWarnings/Input/AppEarlyWarningAddInput.cs

@ -32,6 +32,10 @@ namespace ATS.NonCustodial.Application.Contracts.Interfaces.Business.AppEarlyWar
/// </summary>
public long CaseId { get; set; }
/// <summary>
/// 案件名称
/// </summary>
public string? CaseName { get; set; }
/// <summary>
/// 预警类型Id(来自数据字典)
/// </summary>

5
src/3.contracts/ATS.NonCustodial.Application.Contracts/Interfaces/Business/Apps/Input/AppRemindPageInput.cs

@ -18,5 +18,10 @@ namespace ATS.NonCustodial.Application.Contracts.Interfaces.Business.Apps.Input
/// <see cref="CheckStatusEnum"/>
/// </summary>
public CheckStatusEnum? CheckStatus { get; set; }
/// <summary>
/// 提醒类型
/// </summary>
public long? EarlyWarningTypeId { get; set; }
}
}

4
src/3.contracts/ATS.NonCustodial.Application.Contracts/Interfaces/Business/Apps/Input/SubmitBindingApplicationInput.cs

@ -26,5 +26,9 @@
/// 自动获取CID(手机唯一id)
/// </summary>
public string? CId { get; set; }
public string? phone { get; set; }
public string? checkCode { get; set; }
}
}

5
src/3.contracts/ATS.NonCustodial.Application.Contracts/Interfaces/Business/Apps/Output/AppRemindListDto.cs

@ -60,6 +60,11 @@ namespace ATS.NonCustodial.Application.Contracts.Interfaces.Business.Apps.Output
/// 案件名称
/// </summary>
public string? CaseName { get; set; }
/// <summary>
/// 案件名称
/// </summary>
public long? EarlyWarningTypeId { get; set; }
}

30
src/3.contracts/ATS.NonCustodial.Application.Contracts/Interfaces/Business/ViolationStatistics/IAppViolationStatisticsService.cs

@ -1,5 +1,6 @@
using ATS.NonCustodial.Application.Contracts.Interfaces.Business.ViolationStatistics.Input;
using ATS.NonCustodial.Shared.Common.UnifiedResults;
using Microsoft.AspNetCore.Mvc;
namespace ATS.NonCustodial.Application.Contracts.Interfaces.Business.ViolationStatistics
{
@ -23,6 +24,12 @@ namespace ATS.NonCustodial.Application.Contracts.Interfaces.Business.ViolationSt
/// <returns></returns>
Task<IResultOutput> ViolationStatisticsPageAsync(ViolationStatisticsPageInput input);
/// <summary>
/// 违规记录统计导出
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
Task<IActionResult> ViolationStatisticsExportAsync(ViolationStatisticsPageInput input);
/// <summary>
/// 违规人数统计分页
/// </summary>
/// <returns></returns>
@ -33,6 +40,29 @@ namespace ATS.NonCustodial.Application.Contracts.Interfaces.Business.ViolationSt
/// </summary>
/// <returns></returns>
Task<IResultOutput> ViolationStatisticsAsync(ViolationStatisticsPageInput input);
/// <summary>
/// 未打卡统计
/// </summary>
/// <returns></returns>
Task<IResultOutput> NotClockedStatisticsPageAsync(NotClockedInput input);
/// <summary>
/// 越界统计
/// </summary>
/// <returns></returns>
Task<IResultOutput> LeaveAreaStatisticsPageAsync(NotClockedInput input);
/// <summary>
/// 越界统计导出
/// </summary>
/// <returns></returns>
Task<IActionResult> LeaveAreaStatisticsExportAsync(NotClockedInput input);
/// <summary>
/// 未打卡统计导出
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
Task<IActionResult> NotClockedStatisticsExportAsync(NotClockedInput input);
}
}

37
src/3.contracts/ATS.NonCustodial.Application.Contracts/Interfaces/Business/ViolationStatistics/Input/NotClockedInput.cs

@ -0,0 +1,37 @@
using ATS.NonCustodial.Shared.Common.Dtos;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ATS.NonCustodial.Application.Contracts.Interfaces.Business.ViolationStatistics.Input
{
public class NotClockedInput: PageRequestBaseInput
{
/// <summary>
/// 案件Id
/// </summary>
public long? CaseId { get; set; }
/// <summary>
/// 结束时间
/// </summary>
public DateTime? EndCreatedTime { get; set; }
/// <summary>
/// 开始时间
/// </summary>
public DateTime? StartCreatedTime { get; set; }
/// <summary>
/// 案件进度
/// </summary>
public int? CaseProgress { get; set; }
/// <summary>
/// 被监管人姓名
/// </summary>
public string? SupervisedPersonName { get; set; }
}
}

5
src/3.contracts/ATS.NonCustodial.Application.Contracts/Interfaces/Business/ViolationStatistics/Input/ViolationStatisticsPageInput.cs

@ -14,7 +14,10 @@ namespace ATS.NonCustodial.Application.Contracts.Interfaces.Business.ViolationSt
/// 被监管人Id
/// </summary>
public long? SupervisedPersonId { get; set; }
/// <summary>
/// 被监管人Id
/// </summary>
public string? SupervisedPersonName { get; set; }
/// <summary>
/// 案件Id
/// </summary>

68
src/3.contracts/ATS.NonCustodial.Application.Contracts/Interfaces/Business/ViolationStatistics/Output/NotClockExportDto.cs

@ -0,0 +1,68 @@
using ATS.NonCustodial.Domain.Shared.AggRootEntities;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ATS.NonCustodial.Application.Contracts.Interfaces.Business.ViolationStatistics.Output
{
/// <summary>
/// 未打卡统计返回值
/// </summary>
public class NotClockExportDto
{
/// <summary>
/// 案件Id
/// </summary>
public long CaseId { get; set; }
/// <summary>
/// 案件名称
/// </summary>
[DisplayName("案件名称")]
public string? CaseName { get; set; }
/// <summary>
/// 被监管人Id
/// </summary>
public long SupervisedPersonId { get; set; }
/// <summary>
/// 被监管人员
/// </summary>
[DisplayName("被监管人")]
public string? SupervisedPersonName { get; set; }
/// <summary>
/// 部门受案号
/// </summary>
[DisplayName("部门受案号")]
public string? Bmsah { get; set; }
/// <summary>
/// 监督单位
/// </summary>
[DisplayName("监督单位")]
public string? SupervisionUnit { get; set; }
/// <summary>
/// 案件类型
/// </summary>
[DisplayName("案件类型")]
public string? CaseTypeName { get; set; }
/// <summary>
/// 未打卡次数
/// </summary>
[DisplayName("未打卡次数")]
public int NotClockedCount { get; set; }
/// <summary>
/// 案件创建日期
/// </summary>
[DisplayName("案件创建日期")]
public DateTime? CreatedTime { get; set; }
}
}

60
src/3.contracts/ATS.NonCustodial.Application.Contracts/Interfaces/Business/ViolationStatistics/Output/NotClockListDto.cs

@ -0,0 +1,60 @@
using ATS.NonCustodial.Domain.Shared.AggRootEntities;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ATS.NonCustodial.Application.Contracts.Interfaces.Business.ViolationStatistics.Output
{
/// <summary>
/// 未打卡统计返回值
/// </summary>
public class NotClockListDto
{
/// <summary>
/// 案件Id
/// </summary>
public long CaseId { get; set; }
/// <summary>
/// 案件名称
/// </summary>
public string? CaseName { get; set; }
/// <summary>
/// 被监管人Id
/// </summary>
public long SupervisedPersonId { get; set; }
/// <summary>
/// 被监管人员
/// </summary>
public string? SupervisedPersonName { get; set; }
/// <summary>
/// 部门受案号
/// </summary>
public string? Bmsah { get; set; }
/// <summary>
/// 监督单位
/// </summary>
public string? SupervisionUnit { get; set; }
/// <summary>
/// 案件类型
/// </summary>
public string? CaseTypeName { get; set; }
/// <summary>
/// 未打卡次数
/// </summary>
public int NotClockedCount { get; set; }
/// <summary>
/// 案件创建日期
/// </summary>
public DateTime? CreatedTime { get; set; }
}
}

64
src/3.contracts/ATS.NonCustodial.Application.Contracts/Interfaces/Business/ViolationStatistics/Output/ViolationExportDto.cs

@ -0,0 +1,64 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ATS.NonCustodial.Application.Contracts.Interfaces.Business.ViolationStatistics.Output
{
public class ViolationExportDto
{
/// <summary>
/// 案件Id
/// </summary>
public long CaseId { get; set; }
/// <summary>
/// 案件名称
/// </summary>
[DisplayName("案件名称")]
public string? CaseName { get; set; }
/// <summary>
/// 被监管人Id
/// </summary>
public long SupervisedPersonId { get; set; }
/// <summary>
/// 被监管人员
/// </summary>
[DisplayName("被监管人员")]
public string? SupervisedPersonName { get; set; }
/// <summary>
/// 部门受案号
/// </summary>
[DisplayName("部门受案号")]
public string? Bmsah { get; set; }
/// <summary>
/// 监督单位
/// </summary>
[DisplayName("监督单位")]
public string? SupervisionUnit { get; set; }
/// <summary>
/// 案件类型
/// </summary>
[DisplayName("案件类型")]
public string? CaseTypeName { get; set; }
/// <summary>
/// 违规越界次数
/// </summary>
[DisplayName("违规越界次数")]
public int ViolationCount { get; set; }
/// <summary>
/// 案件创建日期
/// </summary>
[DisplayName("案件创建日期")]
public DateTime? CreatedTime { get; set; }
}
}

56
src/3.contracts/ATS.NonCustodial.Application.Contracts/Interfaces/Business/ViolationStatistics/Output/ViolationListDto.cs

@ -0,0 +1,56 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ATS.NonCustodial.Application.Contracts.Interfaces.Business.ViolationStatistics.Output
{
public class ViolationListDto
{
/// <summary>
/// 案件Id
/// </summary>
public long CaseId { get; set; }
/// <summary>
/// 案件名称
/// </summary>
public string? CaseName { get; set; }
/// <summary>
/// 被监管人Id
/// </summary>
public long SupervisedPersonId { get; set; }
/// <summary>
/// 被监管人员
/// </summary>
public string? SupervisedPersonName { get; set; }
/// <summary>
/// 部门受案号
/// </summary>
public string? Bmsah { get; set; }
/// <summary>
/// 监督单位
/// </summary>
public string? SupervisionUnit { get; set; }
/// <summary>
/// 案件类型
/// </summary>
public string? CaseTypeName { get; set; }
/// <summary>
/// 违规越界次数
/// </summary>
public int ViolationCount { get; set; }
/// <summary>
/// 案件创建日期
/// </summary>
public DateTime? CreatedTime { get; set; }
}
}

64
src/3.contracts/ATS.NonCustodial.Application.Contracts/Interfaces/Business/ViolationStatistics/Output/ViolationStatisticsExportDto.cs

@ -0,0 +1,64 @@
using ATS.NonCustodial.Domain.Shared.AggRootEntities;
using ATS.NonCustodial.Domain.Shared.Enums;
using System.ComponentModel;
namespace ATS.NonCustodial.Application.Contracts.Interfaces.Business.ViolationStatistics.Output
{
/// <summary>
/// 违规统计列表Dto
/// </summary>
/// Author:mxg
/// CreatedTimed:2022-06-06 05:19 PM
public class ViolationStatisticsExportDto
{
/// <summary>
/// 案件Id
/// </summary>
public long CaseId { get; set; }
/// <summary>
/// 案件名称
/// </summary>
[DisplayName("案件名称")]
public string? CaseName { get; set; }
/// <summary>
/// 被监管人Id
/// </summary>
public long SupervisedPersonId { get; set; }
/// <summary>
/// 被监管人员
/// </summary>
[DisplayName("被监管人员")]
public string? SupervisedPersonName { get; set; }
/// <summary>
/// 身份证号
/// </summary>
[DisplayName("身份证号")]
public string? IdCard { get; set; }
/// <summary>
/// 违规次数
/// </summary>
[DisplayName("违规次数")]
public int Violations { get; set; }
/// <summary>
/// 违规时间
/// </summary>
public DateTime? Wgtime { get; set; }
/// <summary>
/// 违规类型
/// </summary>
public string Wglx { get; set; }
/// <summary>
/// 案件进度
/// </summary>
[DisplayName("案件进度")]
public string? CaseProgress { get; set; }
}
}

4
src/3.contracts/ATS.NonCustodial.Application.Contracts/Interfaces/Business/ViolationStatistics/Output/ViolationStatisticsListDto.cs

@ -6,8 +6,8 @@ namespace ATS.NonCustodial.Application.Contracts.Interfaces.Business.ViolationSt
/// <summary>
/// 违规统计列表Dto
/// </summary>
/// Author:mxg
/// CreatedTimed:2022-06-06 05:19 PM
/// Author:zzj
/// CreatedTimed:2025-06-06 05:19 PM
public class ViolationStatisticsListDto : EntityAdd
{
/// <summary>

2
src/4.apps/ATS.NonCustodial.Admin.Api/Dockerfile

@ -1,4 +1,4 @@
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
FROM mcr.microsoft.com/dotnet/sdk:9.0 AS build
ENV TZ Asia/Shanghai

3939
src/4.apps/ATS.NonCustodial.Admin.Api/Seeds/initData/app_api.json

File diff suppressed because it is too large Load Diff

17951
src/4.apps/ATS.NonCustodial.Admin.Api/Seeds/initData/app_dictionary.json

File diff suppressed because it is too large Load Diff

1132
src/4.apps/ATS.NonCustodial.Admin.Api/Seeds/initData/app_role_permission.json

File diff suppressed because it is too large Load Diff

3530
src/4.apps/ATS.NonCustodial.Admin.Api/Seeds/initData/app_user.json

File diff suppressed because it is too large Load Diff

3037
src/4.apps/ATS.NonCustodial.Admin.Api/Seeds/initData/app_user_role.json

File diff suppressed because it is too large Load Diff

4
src/4.apps/ATS.NonCustodial.Admin.Api/appsettings.json

@ -10,8 +10,8 @@
//<EFBFBD>?
"ConnectionStringsConfiguration": {
"AdminAuditLogDbConnection": "Server=localhost;database=fjy_sl;uid=root;pwd=sa@admin;pooling=true;CharSet=utf8;port=3306;SslMode=none;Allow User Variables=True;AllowPublicKeyRetrieval=True;",
"AdminDbConnection": "Server=localhost;database=fjy_sl;uid=root;pwd=sa@admin;pooling=true;CharSet=utf8;port=3306;SslMode=none;Allow User Variables=True;AllowPublicKeyRetrieval=True;"
"AdminAuditLogDbConnection": "Server=localhost;database=fsl_cs;uid=root;pwd=sa@admin;pooling=true;CharSet=utf8;port=3306;SslMode=none;Allow User Variables=True;AllowPublicKeyRetrieval=True;",
"AdminDbConnection": "Server=localhost;database=fsl_cs;uid=root;pwd=sa@admin;pooling=true;CharSet=utf8;port=3306;SslMode=none;Allow User Variables=True;AllowPublicKeyRetrieval=True;"
},
"DatabaseProviderConfiguration": {
"ProviderType": "MySql"

17
src/4.apps/ATS.NonCustodial.Admin.Api/configs/appsettings.json

@ -22,8 +22,8 @@
/* Server=ip database= pwd= port=*/
//"AdminAuditLogDbConnection": "Server=192.168.0.78;database=fjy1;uid=root;pwd=jiacai;pooling=true;CharSet=utf8;port=3306;SslMode=none;Allow User Variables=True;AllowPublicKeyRetrieval=True;",
//"AdminDbConnection": "Server=192.168.0.78;database=fjy1;uid=root;pwd=jiacai;pooling=true;CharSet=utf8;port=3306;SslMode=none;Allow User Variables=True;AllowPublicKeyRetrieval=True;",
"AdminAuditLogDbConnection": "Server=localhost;database=fjy_sl;uid=root;pwd=sa@admin;pooling=true;CharSet=utf8;port=3306;SslMode=none;Allow User Variables=True;AllowPublicKeyRetrieval=True;",
"AdminDbConnection": "Server=localhost;database=fjy_sl;uid=root;pwd=sa@admin;pooling=true;CharSet=utf8;port=3306;SslMode=none;Allow User Variables=True;AllowPublicKeyRetrieval=True;"
"AdminAuditLogDbConnection": "Server=localhost;database=fsl_cs;uid=root;pwd=sa@admin;pooling=true;CharSet=utf8;port=3306;SslMode=none;Allow User Variables=True;AllowPublicKeyRetrieval=True;",
"AdminDbConnection": "Server=localhost;database=fsl_cs;uid=root;pwd=sa@admin;pooling=true;CharSet=utf8;port=3306;SslMode=none;Allow User Variables=True;AllowPublicKeyRetrieval=True;"
//"AdminAuditLogDbConnection": "Server=soft.scakskj.com;database=fjy;uid=root;pwd=sa@123456;pooling=true;CharSet=utf8;port=5324;SslMode=none;Allow User Variables=True;AllowPublicKeyRetrieval=True;",
// "AdminDbConnection": "Server=soft.scakskj.com;database=fjy;uid=root;pwd=sa@123456;pooling=true;CharSet=utf8;port=5324;SslMode=none;Allow User Variables=True;AllowPublicKeyRetrieval=True;"
@ -254,5 +254,18 @@
"AppKey": "SeXpmo90df9INDBVejixG",
"MasterSecret": "0jrX4Yc54V6ehBCRhtSQQ3",
"AppSecret": "uCqaQ6Ts8ZAiQhsMm3Yfx2"
},
//
"SmsConfiguration": {
//
"LoginName": "DSCJKCSZH",
//
"Pwd": "Scmf@000731",
//
"BaseUrl": "https://dxsdk.028lk.com:8082/Api/SendSms",
// 2 3
"FeeType": "2",
//:(使,UrlencodeUTF-8)
"SignName": "【灵讯通】"
}
}

1
src/5.shared/ATS.NonCustodial.AdminUi/Configurations/AdminServerCollectionExtension.cs

@ -94,6 +94,7 @@ namespace ATS.NonCustodial.AdminUi.Configurations
//个推
services.AddSingleton(adminUiOptions.TweetsConfigConfiguration);
services.AddSingleton(adminUiOptions.SmsConfiguration);
#region 身份认证授权

5
src/5.shared/ATS.NonCustodial.AdminUi/Configurations/AdminUiOptions.cs

@ -60,7 +60,7 @@ namespace ATS.NonCustodial.AdminUi.Configurations
/// TweetsConfigConfiguration
/// </summary>
public TweetsConfigConfiguration TweetsConfigConfiguration { get; set; } = new TweetsConfigConfiguration();
public SmsConfiguration SmsConfiguration { get; set; } = new SmsConfiguration();
/// <summary>
/// TenantConfiguration
/// </summary>
@ -143,6 +143,7 @@ namespace ATS.NonCustodial.AdminUi.Configurations
configuration.GetSection(nameof(RabbitMqOptions)).Bind(RabbitMqOptions);
configuration.GetSection(nameof(SdQuartzCronConfiguration)).Bind(SdQuartzCronConfiguration);
configuration.GetSection(nameof(TweetsConfigConfiguration)).Bind(TweetsConfigConfiguration);
configuration.GetSection(nameof(SmsConfiguration)).Bind(SmsConfiguration);
//注册options
services.AddSingleton(VarifyCodeConfiguration);
@ -150,6 +151,8 @@ namespace ATS.NonCustodial.AdminUi.Configurations
services.AddSingleton(UploadConfigConfiguration);
//services.AddSingleton(TweetsConfigConfiguration);
services.AddSingleton(AuditLoggingConfiguration);
services.AddSingleton(SmsConfiguration);
services.AddSingleton(ConnectionStringsConfiguration);
}
}

8
src/5.shared/ATS.NonCustodial.Domain.Shared/Common/Dtos/SupervisedPersonDto.cs

@ -1,4 +1,6 @@
namespace ATS.NonCustodial.Domain.Shared.Common.Dtos
using ATS.NonCustodial.Domain.Shared.Enums;
namespace ATS.NonCustodial.Domain.Shared.Common.Dtos
{
/// <summary>
/// 被监管人公告Dto
@ -26,5 +28,9 @@
/// 身份证
/// </summary>
public string? IdCard { get; set; }
/// <summary>
/// 案件进度
/// </summary>
public CaseProgressEnum? CaseProgress { get; set; }
}
}

2
src/5.shared/ATS.NonCustodial.Domain.Shared/Enums/CaseProgressEnum.cs

@ -34,7 +34,7 @@ namespace ATS.NonCustodial.Domain.Shared.Enums
Examination = 3,
/// <summary>
/// 审查起诉阶段
/// 审阶段
/// </summary>
[Description("审理阶段")]
Hear = 4,

34
src/5.shared/ATS.NonCustodial.Domain.Shared/Enums/MessageAlertTypeEnum.cs

@ -0,0 +1,34 @@
using System.ComponentModel;
namespace ATS.NonCustodial.Domain.Shared.Enums
{
/// <summary>
/// 短信通知类型
/// </summary>
public enum MessageAlertTypeEnum
{
/// <summary>
/// 审批完成通知
/// </summary>
[Description("审批完成")]
Approved = 0,
/// <summary>
/// 监管预警通知(用于通知监管人)
/// </summary>
[Description("监管预警")]
RegulatoryAlert = 1,
/// <summary>
/// 审批提醒通知
/// </summary>
[Description("审批提醒")]
ReviewNotification = 2,
/// <summary>
/// 预警处理通知(用于通知被监管人)
/// </summary>
[Description("预警处理")]
Alert = 3
}
}

18
src/5.shared/ATS.NonCustodial.Shared/Common/Auth/ClaimAttributes.cs

@ -1,4 +1,6 @@
namespace ATS.NonCustodial.Shared.Common.Auth
using System.ComponentModel.DataAnnotations;
namespace ATS.NonCustodial.Shared.Common.Auth
{
/// <summary>
/// Claim属性
@ -83,5 +85,19 @@
/// 职位类型转换为枚举
/// </summary>
public const string personType = "persontype";
/// <summary>
/// 职位类型转换为枚举
/// </summary>
public const string positionId = "positionId";
/// <summary>
/// 查询界限
/// </summary>
public const string limits = "limits";
/// <summary>
/// 是否是Admin
/// </summary>
public const string IsAdmin = "false";
}
}

17
src/5.shared/ATS.NonCustodial.Shared/Common/Auth/IUser.cs

@ -1,4 +1,5 @@
using ATS.NonCustodial.Shared.Common.Enums;
using System.ComponentModel.DataAnnotations;
using System.Security.Claims;
namespace ATS.NonCustodial.Shared.Common.Auth
@ -50,6 +51,22 @@ namespace ATS.NonCustodial.Shared.Common.Auth
/// </summary>
string NickName { get; }
/// <summary>
/// 职位(检察官、公安、法官)
/// </summary>
long PositionId { get; }
/// <summary>
/// 查询界限
/// </summary>
string limits { get; }
/// <summary>
/// 是否管理员
/// </summary>
bool IsAdmin { get; }
/// <summary>
/// 租户Id
/// </summary>

52
src/5.shared/ATS.NonCustodial.Shared/Common/Auth/User.cs

@ -158,6 +158,58 @@ namespace ATS.NonCustodial.Shared.Common.Auth
}
}
/// <summary>
/// 查询权限
/// </summary>
public string limits
{
get
{
var name = _accessor?.HttpContext?.User?.FindFirst(ClaimAttributes.limits);
if (name != null && name.Value.NotNull())
{
return name.Value;
}
return "";
}
}
/// <summary>
/// 职位(检察官、公安、法官)
/// </summary>
public long PositionId
{
get
{
var positionId = _accessor?.HttpContext?.User?.FindFirst(ClaimAttributes.positionId);
if (positionId != null && positionId.Value.NotNull())
{
return (long)positionId.Value.ToLong();
}
return 0;
}
}
/// <summary>
/// 是否管理员
/// </summary>
public bool IsAdmin
{
get
{
var name = _accessor?.HttpContext?.User?.FindFirst(ClaimAttributes.IsAdmin);
if (name != null && name.Value.NotNull())
{
return name.Value=="true";
}
return false;
}
}
/// <summary>
/// 租户Id
/// </summary>

21
src/5.shared/ATS.NonCustodial.Shared/Configurations/Options/SmsConfiguration.cs

@ -0,0 +1,21 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ATS.NonCustodial.Shared.Configurations.Options
{
public class SmsConfiguration
{
public string LoginName { get; set; }
public string Pwd { get; set; }
public string BaseUrl { get; set; }
public string FeeType { get; set; }
public string SignName { get; set; }
}
}

4
src/5.shared/ATS.NonCustodial.Shared/Extensions/Collection/PaginationExtensions.cs

@ -40,7 +40,7 @@ namespace ATS.NonCustodial.Shared.Extensions.Collection
/// <returns></returns>
public static async Task<PagedList<TEntity>> PagedAsync<TEntity>(this IQueryable<TEntity> queryable, PageRequestBaseInput pageDto) where TEntity : class
{
if (pageDto.PageSize > 25) pageDto.PageSize = 25;
if (pageDto.PageSize > 500) pageDto.PageSize = 500;
var pagedQuery = GetPagedQuery(queryable, pageDto.PageIndex, pageDto.PageSize);
var totalCount = await queryable.CountAsync().ConfigureAwait(false);
@ -62,7 +62,7 @@ namespace ATS.NonCustodial.Shared.Extensions.Collection
where TEntity : class
where TPageInput : BasePageInput
{
if (pageDto.PageSize > 25) pageDto.PageSize = 25;
if (pageDto.PageSize > 500) pageDto.PageSize = 500;
var pagedQuery = GetPagedQuery(queryable, pageDto.PageIndex, pageDto.PageSize);
var totalCount = await queryable.CountAsync().ConfigureAwait(false);

Loading…
Cancel
Save